Repository navigation
Closed
Labels
ffiForeign-function interface boundaries and interopForeign-function interface boundaries and interoprefactorInternal restructuring without an intended feature changeInternal restructuring without an intended feature changespikeTime-boxed investigation needed before implementationTime-boxed investigation needed before implementation
Description
Context
cmd_ffi.mjs runs external processes and CLI tooling through Node child_process.
Current boundary:
src/glendix/cmd_ffi.mjsexecSync/spawnSyncusage behindexec, bridge runners, experimental-native runners, and npm/node shims- warning filters and process-output handling
src/glendix/cmd.gleam- externals
exec,run_with_bridge,run_dev_with_bridge,run_experimental_native*,command_error_message,fail_process, etc.
- externals
Much of this is Glendix-specific build orchestration, but the generic "run a command" primitive may have an ecosystem equivalent.
Proposed package/API (spike)
- Evaluate
shellout(orplinth'schild_processbindings) for the generic command-execution primitive (exec). - Isolate genuinely Glendix-specific tooling (bridge generation, experimental-native environment setup, Rollup/WASM, shim writing) from the generic execution primitive.
- Decide which parts can use a package and which remain intentionally custom, and document the split.
Compatibility and public API impact
- Preserve exit-code and failure semantics currently surfaced through
command_error_message/fail_processand process stdio behavior (inherited stdio, filtered warnings). - Any replacement must preserve synchronous-vs-async behavior relied on by the CLI.
- Confirm the chosen package supports the required stdio and error reporting on the Node target.
Non-goals
- Rewriting bridge generation, experimental-native setup, or Rollup/WASM handling.
- Changing CLI command semantics or output.
Acceptance criteria
- Spike records whether
shellout/child_processbindings can back the genericexecprimitive and the delta in stdio/error handling. - The generic execution primitive is isolated from Glendix-specific tooling; if a package is adopted it backs that primitive.
- Retained custom command tooling is documented as intentional.
- Tests/contract checks cover success and failure exit paths and error-message surfacing.
- FFI contract checks report no stale external declarations or exports.
-
glendix -> mendrawretains its currently declared dependency source form.
Verification
- Local implementation loop:
./scripts/verify.sh inner glendix - If public signatures change:
./scripts/verify.sh shared glendix - Before a release or family-wide compatibility claim:
./scripts/verify.sh final
Metadata
Metadata
Assignees
Labels
ffiForeign-function interface boundaries and interopForeign-function interface boundaries and interoprefactorInternal restructuring without an intended feature changeInternal restructuring without an intended feature changespikeTime-boxed investigation needed before implementationTime-boxed investigation needed before implementation
Activity
GG-O-BP commentedon Sep 7, 2026
분석 결과, generic
exec에는shellout을 채택하고 Glendix 전용 프로세스 코드는 유지하는 하이브리드 분리가 적합합니다.shellout.command는 JavaScript/Node에서 동기식spawnSync기반이며, exit status를Result로 돌려주고LetBeStdout/LetBeStderr로 현재의 inherited stdio 동작을 보존할 수 있습니다.cmd.exec공개 API는 인수 배열이 아니라 shell command string을 받으므로, Unix의/bin/sh -c와 Windows의ComSpec /d /s /c로 변환하는 얇은 플랫폼 경계가 필요합니다.plinth/node/child_process의 현재 API는exec/spawnhandle과stdin/kill만 제공하며, 동기 완료 결과, exit code, stdout/stderr 정책을 typedResult로 제공하지 않아 이 primitive의 대체재로는 부족합니다.gleam ...실행 시 Erlang backend의 알려진 불필요 warning만 제거하는 기존 동작은shellout이 stdout/stderr를 분리해 필터링하는 API를 제공하지 않으므로 작은 custom boundary로 남겨야 합니다. 이는 generic execution이 아니라 Glendix의 Gleam build-output 정책입니다.구현 시 다음 계약을 보존하겠습니다.
cmd.exec(command:) -> Result(Nil, CommandError)공개 signature와 동기 동작Ok(Nil), 실패 시CommandFailed("execute command", reason)Command failed: <command>) surfacingglendix -> mendraw의 현재 Hex dependency source테스트는 generic command 성공/실패, shell-string 처리, 실패 reason surfacing, Gleam filtered-runner 성공/실패를 contract 수준에서 추가하고 FFI declaration/export gate까지 실행하겠습니다.
Merge pull request #34 from glendix-labs/refactor/shellout-command-is…
GG-O-BP commentedon Sep 7, 2026
✅ Resolved via #34, merged into
main(merge commit0bf413d, implementation commit0b1aa55).What shipped
cmd.execnow delegates to the maintainedshellout ~> 1.8.0synchronouscommand, replacing the bespoke shell FFI wrapper while keeping the public contract stable (cmd.exec(command:) -> Result(Nil, CommandError),CommandFailed("execute command", reason))./bin/sh -c, WindowsComSpec /d /s /c).glendix/commandmodule (+ FFI) with a contract test asserting theshellout.LetBeStdoutSIGINT listener is cleaned up after execution.plinth/node/child_processwas evaluated and rejected (no synchronous completion / typed exit status / typed stdio). The remaining small custom FFI (Gleam warning filtering) is retained and documented in the READMEs.Verification
./scripts/verify.sh finalpassed: source/style/FFI/boundary gates, all standalone consumers, all package tests (gleam test142 passed), Glendam browser checks, widget.mpkbuild, and Mendix full E2E (BUILD SUCCEEDED+ post-boot browser smoke).package-gatesCI on the PR passed.glendix -> mendrawremains a Hex requirement; pushed-tip dependency check passed.