opensquid 0.5.441 → 0.5.447
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/functions/arm_scope.d.ts +27 -0
- package/dist/functions/arm_scope.d.ts.map +1 -0
- package/dist/functions/arm_scope.js +52 -0
- package/dist/functions/arm_scope.js.map +1 -0
- package/dist/functions/index.d.ts +1 -0
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +1 -0
- package/dist/functions/index.js.map +1 -1
- package/dist/runtime/bootstrap.d.ts.map +1 -1
- package/dist/runtime/bootstrap.js +2 -0
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/runtime/handoff/render.d.ts +5 -4
- package/dist/runtime/handoff/render.d.ts.map +1 -1
- package/dist/runtime/handoff/render.js +7 -7
- package/dist/runtime/handoff/render.js.map +1 -1
- package/dist/runtime/hooks/active_task_mirror.js +0 -0
- package/dist/runtime/hooks/apply_patch.js +0 -0
- package/dist/runtime/hooks/dispatch.js +0 -0
- package/dist/runtime/hooks/hook_output.js +0 -0
- package/dist/runtime/hooks/memory_reconcile.js +0 -0
- package/dist/runtime/hooks/new_project_detect.js +0 -0
- package/dist/runtime/hooks/profession_resolver.js +0 -0
- package/dist/runtime/hooks/scope_intent.js +0 -0
- package/dist/runtime/hooks/session_id.js +0 -0
- package/dist/runtime/hooks/session_liveness.js +0 -0
- package/dist/runtime/hooks/stop_drive.js +0 -0
- package/dist/runtime/hooks/stop_stream.js +0 -0
- package/dist/runtime/hooks/subagent_guard.js +0 -0
- package/dist/runtime/hooks/transcript.js +0 -0
- package/dist/runtime/hooks/transcript_tasks.js +0 -0
- package/dist/runtime/ralph/orchestrator.d.ts.map +1 -1
- package/dist/runtime/ralph/orchestrator.js +2 -1
- package/dist/runtime/ralph/orchestrator.js.map +1 -1
- package/dist/setup/cli/limits_state.d.ts.map +1 -1
- package/dist/setup/cli/limits_state.js +6 -40
- package/dist/setup/cli/limits_state.js.map +1 -1
- package/dist/setup/cli/pack_walk.d.ts +32 -0
- package/dist/setup/cli/pack_walk.d.ts.map +1 -0
- package/dist/setup/cli/pack_walk.js +76 -0
- package/dist/setup/cli/pack_walk.js.map +1 -0
- package/dist/setup/cli/permissions_state.d.ts.map +1 -1
- package/dist/setup/cli/permissions_state.js +6 -37
- package/dist/setup/cli/permissions_state.js.map +1 -1
- package/dist/setup/cli/triggers_state.d.ts.map +1 -1
- package/dist/setup/cli/triggers_state.js +3 -29
- package/dist/setup/cli/triggers_state.js.map +1 -1
- package/dist/workgraph/events.d.ts.map +1 -1
- package/dist/workgraph/events.js +10 -0
- package/dist/workgraph/events.js.map +1 -1
- package/dist/workgraph/store.d.ts.map +1 -1
- package/dist/workgraph/store.js +5 -0
- package/dist/workgraph/store.js.map +1 -1
- package/dist/workgraph/types.d.ts +2 -1
- package/dist/workgraph/types.d.ts.map +1 -1
- package/docs/ARCHITECTURE.md +268 -0
- package/package.json +5 -3
- package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +13 -17
- package/dist/anti-drift/evaluator.d.ts +0 -88
- package/dist/anti-drift/evaluator.d.ts.map +0 -1
- package/dist/anti-drift/evaluator.js +0 -417
- package/dist/anti-drift/evaluator.js.map +0 -1
- package/dist/anti-drift/evaluator.test.js +0 -78
- package/dist/anti-drift/rules.d.ts +0 -80
- package/dist/anti-drift/rules.d.ts.map +0 -1
- package/dist/anti-drift/rules.js +0 -368
- package/dist/anti-drift/rules.js.map +0 -1
- package/dist/anti-drift/rules.test.js +0 -213
- package/dist/anti-drift/state.d.ts +0 -107
- package/dist/anti-drift/state.d.ts.map +0 -1
- package/dist/anti-drift/state.js +0 -177
- package/dist/anti-drift/state.js.map +0 -1
- package/dist/anti-drift/state.test.js +0 -120
- package/dist/chat/adapters/discord.d.ts +0 -41
- package/dist/chat/adapters/discord.d.ts.map +0 -1
- package/dist/chat/adapters/discord.js +0 -176
- package/dist/chat/adapters/discord.js.map +0 -1
- package/dist/chat/adapters/discord.test.js +0 -25
- package/dist/chat/adapters/slack.d.ts +0 -43
- package/dist/chat/adapters/slack.d.ts.map +0 -1
- package/dist/chat/adapters/slack.js +0 -172
- package/dist/chat/adapters/slack.js.map +0 -1
- package/dist/chat/adapters/slack.test.js +0 -30
- package/dist/chat/adapters/telegram.d.ts +0 -148
- package/dist/chat/adapters/telegram.d.ts.map +0 -1
- package/dist/chat/adapters/telegram.js +0 -498
- package/dist/chat/adapters/telegram.js.map +0 -1
- package/dist/chat/adapters/telegram.test.js +0 -94
- package/dist/chat/config.d.ts +0 -98
- package/dist/chat/config.d.ts.map +0 -1
- package/dist/chat/config.js +0 -185
- package/dist/chat/config.js.map +0 -1
- package/dist/chat/daemon/active-project.d.ts +0 -17
- package/dist/chat/daemon/active-project.d.ts.map +0 -1
- package/dist/chat/daemon/active-project.js +0 -23
- package/dist/chat/daemon/active-project.js.map +0 -1
- package/dist/chat/daemon/autospawn.d.ts +0 -40
- package/dist/chat/daemon/autospawn.d.ts.map +0 -1
- package/dist/chat/daemon/autospawn.js +0 -129
- package/dist/chat/daemon/autospawn.js.map +0 -1
- package/dist/chat/daemon/autospawn.test.js +0 -112
- package/dist/chat/daemon/cli.d.ts +0 -18
- package/dist/chat/daemon/cli.d.ts.map +0 -1
- package/dist/chat/daemon/cli.js +0 -71
- package/dist/chat/daemon/cli.js.map +0 -1
- package/dist/chat/daemon/collisions.js +0 -384
- package/dist/chat/daemon/health-check.d.ts +0 -69
- package/dist/chat/daemon/health-check.d.ts.map +0 -1
- package/dist/chat/daemon/health-check.js +0 -112
- package/dist/chat/daemon/health-check.js.map +0 -1
- package/dist/chat/daemon/inbox-read.d.ts +0 -35
- package/dist/chat/daemon/inbox-read.d.ts.map +0 -1
- package/dist/chat/daemon/inbox-read.js +0 -75
- package/dist/chat/daemon/inbox-read.js.map +0 -1
- package/dist/chat/daemon/inbox-read.test.js +0 -97
- package/dist/chat/daemon/inbox.d.ts +0 -63
- package/dist/chat/daemon/inbox.d.ts.map +0 -1
- package/dist/chat/daemon/inbox.js +0 -56
- package/dist/chat/daemon/inbox.js.map +0 -1
- package/dist/chat/daemon/inbox.test.js +0 -110
- package/dist/chat/daemon/lifecycle.d.ts +0 -71
- package/dist/chat/daemon/lifecycle.d.ts.map +0 -1
- package/dist/chat/daemon/lifecycle.js +0 -221
- package/dist/chat/daemon/lifecycle.js.map +0 -1
- package/dist/chat/daemon/lifecycle.test.js +0 -163
- package/dist/chat/daemon/protocol.d.ts +0 -107
- package/dist/chat/daemon/protocol.d.ts.map +0 -1
- package/dist/chat/daemon/protocol.js +0 -54
- package/dist/chat/daemon/protocol.js.map +0 -1
- package/dist/chat/daemon/routing.d.ts +0 -140
- package/dist/chat/daemon/routing.d.ts.map +0 -1
- package/dist/chat/daemon/routing.js +0 -198
- package/dist/chat/daemon/routing.js.map +0 -1
- package/dist/chat/daemon/routing.test.js +0 -259
- package/dist/chat/daemon/rpc-client.d.ts +0 -45
- package/dist/chat/daemon/rpc-client.d.ts.map +0 -1
- package/dist/chat/daemon/rpc-client.js +0 -133
- package/dist/chat/daemon/rpc-client.js.map +0 -1
- package/dist/chat/daemon/rpc-server.d.ts +0 -39
- package/dist/chat/daemon/rpc-server.d.ts.map +0 -1
- package/dist/chat/daemon/rpc-server.js +0 -385
- package/dist/chat/daemon/rpc-server.js.map +0 -1
- package/dist/chat/daemon/rpc.test.js +0 -177
- package/dist/chat/daemon/subscribers.js +0 -257
- package/dist/chat/daemon/worker.d.ts +0 -27
- package/dist/chat/daemon/worker.d.ts.map +0 -1
- package/dist/chat/daemon/worker.js +0 -313
- package/dist/chat/daemon/worker.js.map +0 -1
- package/dist/chat/daemon/workspace-topic.js +0 -324
- package/dist/chat/env-token.d.ts +0 -60
- package/dist/chat/env-token.d.ts.map +0 -1
- package/dist/chat/env-token.js +0 -137
- package/dist/chat/env-token.js.map +0 -1
- package/dist/chat/env-token.test.js +0 -160
- package/dist/chat/factory.d.ts +0 -30
- package/dist/chat/factory.d.ts.map +0 -1
- package/dist/chat/factory.js +0 -50
- package/dist/chat/factory.js.map +0 -1
- package/dist/chat/factory.test.js +0 -55
- package/dist/chat/gateway.d.ts +0 -176
- package/dist/chat/gateway.d.ts.map +0 -1
- package/dist/chat/gateway.js +0 -146
- package/dist/chat/gateway.js.map +0 -1
- package/dist/chat/gateway.test.js +0 -192
- package/dist/claude-md.d.ts +0 -39
- package/dist/claude-md.d.ts.map +0 -1
- package/dist/claude-md.js +0 -113
- package/dist/claude-md.js.map +0 -1
- package/dist/claude-md.test.js +0 -91
- package/dist/codex/activate.d.ts +0 -66
- package/dist/codex/activate.d.ts.map +0 -1
- package/dist/codex/activate.js +0 -329
- package/dist/codex/activate.js.map +0 -1
- package/dist/codex/activate.test.js +0 -229
- package/dist/codex/bundled-default/bundled-default.test.js +0 -161
- package/dist/codex/cli-publish.test.js +0 -133
- package/dist/codex/cli.d.ts +0 -35
- package/dist/codex/cli.d.ts.map +0 -1
- package/dist/codex/cli.js +0 -554
- package/dist/codex/cli.js.map +0 -1
- package/dist/codex/cli.test.js +0 -277
- package/dist/codex/import-skill-md.d.ts +0 -53
- package/dist/codex/import-skill-md.d.ts.map +0 -1
- package/dist/codex/import-skill-md.js +0 -236
- package/dist/codex/import-skill-md.js.map +0 -1
- package/dist/codex/import-skill-md.test.js +0 -225
- package/dist/codex/loader.d.ts +0 -27
- package/dist/codex/loader.d.ts.map +0 -1
- package/dist/codex/loader.js +0 -86
- package/dist/codex/loader.js.map +0 -1
- package/dist/codex/loader.test.js +0 -75
- package/dist/codex/parse.d.ts +0 -28
- package/dist/codex/parse.d.ts.map +0 -1
- package/dist/codex/parse.js +0 -309
- package/dist/codex/parse.js.map +0 -1
- package/dist/codex/parse.test.js +0 -241
- package/dist/codex/store.d.ts +0 -87
- package/dist/codex/store.d.ts.map +0 -1
- package/dist/codex/store.js +0 -205
- package/dist/codex/store.js.map +0 -1
- package/dist/codex/store.test.js +0 -242
- package/dist/codex/types.d.ts +0 -398
- package/dist/codex/types.d.ts.map +0 -1
- package/dist/codex/types.js +0 -21
- package/dist/codex/types.js.map +0 -1
- package/dist/config.d.ts +0 -53
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -202
- package/dist/config.js.map +0 -1
- package/dist/config.test.js +0 -117
- package/dist/engine/cli.d.ts +0 -14
- package/dist/engine/cli.d.ts.map +0 -1
- package/dist/engine/cli.js +0 -171
- package/dist/engine/cli.js.map +0 -1
- package/dist/engine/client.d.ts +0 -219
- package/dist/engine/client.d.ts.map +0 -1
- package/dist/engine/client.js +0 -312
- package/dist/engine/client.js.map +0 -1
- package/dist/engine/config.d.ts +0 -62
- package/dist/engine/config.d.ts.map +0 -1
- package/dist/engine/config.js +0 -223
- package/dist/engine/config.js.map +0 -1
- package/dist/engine/index.d.ts +0 -17
- package/dist/engine/index.d.ts.map +0 -1
- package/dist/engine/index.js +0 -16
- package/dist/engine/index.js.map +0 -1
- package/dist/engine/resolver.d.ts +0 -62
- package/dist/engine/resolver.d.ts.map +0 -1
- package/dist/engine/resolver.js +0 -103
- package/dist/engine/resolver.js.map +0 -1
- package/dist/engine/singleton.d.ts +0 -95
- package/dist/engine/singleton.d.ts.map +0 -1
- package/dist/engine/singleton.js +0 -325
- package/dist/engine/singleton.js.map +0 -1
- package/dist/engine/types.d.ts +0 -402
- package/dist/engine/types.d.ts.map +0 -1
- package/dist/engine/types.js +0 -22
- package/dist/engine/types.js.map +0 -1
- package/dist/engine-binary-resolver.js +0 -110
- package/dist/engine-binary-resolver.test.js +0 -61
- package/dist/engine-cli.js +0 -60
- package/dist/engine-client.js +0 -301
- package/dist/engine-client.test.js +0 -118
- package/dist/functions/chain_state.d.ts +0 -51
- package/dist/functions/chain_state.d.ts.map +0 -1
- package/dist/functions/chain_state.js +0 -59
- package/dist/functions/chain_state.js.map +0 -1
- package/dist/hooks/drift-catalog.d.ts +0 -68
- package/dist/hooks/drift-catalog.d.ts.map +0 -1
- package/dist/hooks/drift-catalog.js +0 -184
- package/dist/hooks/drift-catalog.js.map +0 -1
- package/dist/hooks/drift-catalog.test.js +0 -154
- package/dist/hooks/drift-patterns.d.ts +0 -110
- package/dist/hooks/drift-patterns.d.ts.map +0 -1
- package/dist/hooks/drift-patterns.js +0 -289
- package/dist/hooks/drift-patterns.js.map +0 -1
- package/dist/hooks/drift-patterns.test.js +0 -325
- package/dist/hooks/engine-vocab-gate.d.ts +0 -108
- package/dist/hooks/engine-vocab-gate.d.ts.map +0 -1
- package/dist/hooks/engine-vocab-gate.js +0 -225
- package/dist/hooks/engine-vocab-gate.js.map +0 -1
- package/dist/hooks/engine-vocab-gate.test.js +0 -170
- package/dist/hooks/heartbeat.d.ts +0 -107
- package/dist/hooks/heartbeat.d.ts.map +0 -1
- package/dist/hooks/heartbeat.js +0 -316
- package/dist/hooks/heartbeat.js.map +0 -1
- package/dist/hooks/heartbeat.test.js +0 -393
- package/dist/hooks/honesty-ledger-session-scope.test.js +0 -100
- package/dist/hooks/honesty-ledger.d.ts +0 -123
- package/dist/hooks/honesty-ledger.d.ts.map +0 -1
- package/dist/hooks/honesty-ledger.js +0 -226
- package/dist/hooks/honesty-ledger.js.map +0 -1
- package/dist/hooks/honesty-ledger.test.js +0 -466
- package/dist/hooks/inline-report-check.d.ts +0 -63
- package/dist/hooks/inline-report-check.d.ts.map +0 -1
- package/dist/hooks/inline-report-check.js +0 -88
- package/dist/hooks/inline-report-check.js.map +0 -1
- package/dist/hooks/inline-report-check.test.js +0 -96
- package/dist/hooks/pre-tool-use.d.ts +0 -62
- package/dist/hooks/pre-tool-use.d.ts.map +0 -1
- package/dist/hooks/pre-tool-use.js +0 -342
- package/dist/hooks/pre-tool-use.js.map +0 -1
- package/dist/hooks/pre-tool-use.test.js +0 -134
- package/dist/hooks/session-end.d.ts +0 -15
- package/dist/hooks/session-end.d.ts.map +0 -1
- package/dist/hooks/session-end.js +0 -60
- package/dist/hooks/session-end.js.map +0 -1
- package/dist/hooks/session-end.test.js +0 -52
- package/dist/hooks/stop.d.ts +0 -35
- package/dist/hooks/stop.d.ts.map +0 -1
- package/dist/hooks/stop.js +0 -136
- package/dist/hooks/stop.js.map +0 -1
- package/dist/hooks/transcript-active-task.test.js +0 -342
- package/dist/hooks/transcript.d.ts +0 -26
- package/dist/hooks/transcript.d.ts.map +0 -1
- package/dist/hooks/transcript.js +0 -266
- package/dist/hooks/transcript.js.map +0 -1
- package/dist/hooks/transcript.test.js +0 -103
- package/dist/hooks/user-prompt-submit.d.ts +0 -74
- package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
- package/dist/hooks/user-prompt-submit.js +0 -256
- package/dist/hooks/user-prompt-submit.js.map +0 -1
- package/dist/hooks/user-prompt-submit.test.js +0 -118
- package/dist/hooks/versioning-gate.d.ts +0 -101
- package/dist/hooks/versioning-gate.d.ts.map +0 -1
- package/dist/hooks/versioning-gate.js +0 -245
- package/dist/hooks/versioning-gate.js.map +0 -1
- package/dist/hooks/versioning-gate.test.js +0 -368
- package/dist/hooks/workflow-gate.d.ts +0 -64
- package/dist/hooks/workflow-gate.d.ts.map +0 -1
- package/dist/hooks/workflow-gate.js +0 -152
- package/dist/hooks/workflow-gate.js.map +0 -1
- package/dist/hooks/workflow-gate.test.js +0 -197
- package/dist/hooks-cli.d.ts +0 -25
- package/dist/hooks-cli.d.ts.map +0 -1
- package/dist/hooks-cli.js +0 -286
- package/dist/hooks-cli.js.map +0 -1
- package/dist/hooks-cli.test.js +0 -148
- package/dist/origin.d.ts +0 -16
- package/dist/origin.d.ts.map +0 -1
- package/dist/origin.js +0 -92
- package/dist/origin.js.map +0 -1
- package/dist/packs/seed_lessons_ingest.d.ts +0 -30
- package/dist/packs/seed_lessons_ingest.d.ts.map +0 -1
- package/dist/packs/seed_lessons_ingest.js +0 -107
- package/dist/packs/seed_lessons_ingest.js.map +0 -1
- package/dist/project-cli.d.ts +0 -7
- package/dist/project-cli.d.ts.map +0 -1
- package/dist/project-cli.js +0 -145
- package/dist/project-cli.js.map +0 -1
- package/dist/project.d.ts +0 -127
- package/dist/project.d.ts.map +0 -1
- package/dist/project.js +0 -281
- package/dist/project.js.map +0 -1
- package/dist/project.test.js +0 -287
- package/dist/rag/backends/loop_engine.d.ts +0 -61
- package/dist/rag/backends/loop_engine.d.ts.map +0 -1
- package/dist/rag/backends/loop_engine.js +0 -160
- package/dist/rag/backends/loop_engine.js.map +0 -1
- package/dist/recall.d.ts +0 -82
- package/dist/recall.d.ts.map +0 -1
- package/dist/recall.js +0 -81
- package/dist/recall.js.map +0 -1
- package/dist/runtime/agent_bridge/autospawn.d.ts +0 -131
- package/dist/runtime/agent_bridge/autospawn.d.ts.map +0 -1
- package/dist/runtime/agent_bridge/autospawn.js +0 -251
- package/dist/runtime/agent_bridge/autospawn.js.map +0 -1
- package/dist/runtime/chain_state.d.ts +0 -124
- package/dist/runtime/chain_state.d.ts.map +0 -1
- package/dist/runtime/chain_state.js +0 -189
- package/dist/runtime/chain_state.js.map +0 -1
- package/dist/runtime/hooks/permission_decision.d.ts +0 -34
- package/dist/runtime/hooks/permission_decision.d.ts.map +0 -1
- package/dist/runtime/hooks/permission_decision.js +0 -39
- package/dist/runtime/hooks/permission_decision.js.map +0 -1
- package/dist/runtime/workflow_fsm.d.ts +0 -21
- package/dist/runtime/workflow_fsm.d.ts.map +0 -1
- package/dist/runtime/workflow_fsm.js +0 -25
- package/dist/runtime/workflow_fsm.js.map +0 -1
- package/dist/runtime/workflow_map.d.ts +0 -26
- package/dist/runtime/workflow_map.d.ts.map +0 -1
- package/dist/runtime/workflow_map.js +0 -38
- package/dist/runtime/workflow_map.js.map +0 -1
- package/dist/scope.d.ts +0 -48
- package/dist/scope.d.ts.map +0 -1
- package/dist/scope.js +0 -111
- package/dist/scope.js.map +0 -1
- package/dist/setup/cli/topic_create_step.d.ts +0 -84
- package/dist/setup/cli/topic_create_step.d.ts.map +0 -1
- package/dist/setup/cli/topic_create_step.js +0 -213
- package/dist/setup/cli/topic_create_step.js.map +0 -1
- package/dist/system-export.d.ts +0 -65
- package/dist/system-export.d.ts.map +0 -1
- package/dist/system-export.js +0 -194
- package/dist/system-export.js.map +0 -1
- package/dist/utterance/classifier.d.ts +0 -53
- package/dist/utterance/classifier.d.ts.map +0 -1
- package/dist/utterance/classifier.js +0 -184
- package/dist/utterance/classifier.js.map +0 -1
- package/dist/utterance/classifier.test.js +0 -147
package/dist/config.js
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Opensquid host-level config at `<data-root>/config.json`.
|
|
3
|
-
*
|
|
4
|
-
* Persists machine-state that's relevant across sessions but doesn't
|
|
5
|
-
* belong in per-project files or in the engine's lesson store. v0.4
|
|
6
|
-
* uses it to remember the engine binary path so moving the loop-engine
|
|
7
|
-
* checkout doesn't silently break opensquid.
|
|
8
|
-
*
|
|
9
|
-
* Resolution order for the engine binary (v0.6c):
|
|
10
|
-
* 1. `OPENSQUID_ENGINE_BIN` env var — explicit override, always wins
|
|
11
|
-
* 2. `<data-root>/config.json` `engine_bin` field — persisted choice
|
|
12
|
-
* 3. Bundled npm optional dep (`opensquid-engine-<platform>-<arch>`) —
|
|
13
|
-
* shipped with `opensquid` for published installs (v0.6c)
|
|
14
|
-
* 4. Auto-search common dev paths (~/projects/{,*}/{loop/engine,engine}/target/release/loop-engine)
|
|
15
|
-
* 5. `loop-engine` on $PATH (manually-installed binary)
|
|
16
|
-
* 6. `null` — caller surfaces a helpful error
|
|
17
|
-
*
|
|
18
|
-
* The first successful resolution writes itself back to config.json so
|
|
19
|
-
* the next session picks up the same path immediately. Bundled-binary
|
|
20
|
-
* hits are NOT persisted to config because the path is deterministic
|
|
21
|
-
* from the npm install layout — re-resolving is free and stale-safe
|
|
22
|
-
* across opensquid upgrades.
|
|
23
|
-
*/
|
|
24
|
-
import { promises as fs } from "node:fs";
|
|
25
|
-
import * as os from "node:os";
|
|
26
|
-
import * as path from "node:path";
|
|
27
|
-
import { resolveDataRoot } from "./codex/store.js";
|
|
28
|
-
import { resolveBundledEngineBin } from "./engine-binary-resolver.js";
|
|
29
|
-
const DEFAULT_CONFIG = { version: 1 };
|
|
30
|
-
// ---------------------------------------------------------------------
|
|
31
|
-
// Load / save
|
|
32
|
-
// ---------------------------------------------------------------------
|
|
33
|
-
function configPath(dataRoot) {
|
|
34
|
-
return path.join(resolveDataRoot(dataRoot), "config.json");
|
|
35
|
-
}
|
|
36
|
-
export async function loadConfig(dataRoot) {
|
|
37
|
-
try {
|
|
38
|
-
const raw = await fs.readFile(configPath(dataRoot), "utf8");
|
|
39
|
-
const parsed = JSON.parse(raw);
|
|
40
|
-
if (parsed && parsed.version === 1)
|
|
41
|
-
return parsed;
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
// missing or malformed — return default
|
|
45
|
-
}
|
|
46
|
-
return { ...DEFAULT_CONFIG };
|
|
47
|
-
}
|
|
48
|
-
export async function saveConfig(config, dataRoot) {
|
|
49
|
-
const p = configPath(dataRoot);
|
|
50
|
-
await fs.mkdir(path.dirname(p), { recursive: true });
|
|
51
|
-
await fs.writeFile(p, JSON.stringify(config, null, 2) + "\n", "utf8");
|
|
52
|
-
}
|
|
53
|
-
// ---------------------------------------------------------------------
|
|
54
|
-
// Engine binary discovery
|
|
55
|
-
// ---------------------------------------------------------------------
|
|
56
|
-
const ENGINE_BIN_NAME = "loop-engine";
|
|
57
|
-
/**
|
|
58
|
-
* Resolve the engine binary path using the priority chain above.
|
|
59
|
-
* Writes the resolved path back to config when discovered via search
|
|
60
|
-
* so the next session is instant.
|
|
61
|
-
*
|
|
62
|
-
* Returns `null` if no working binary could be located.
|
|
63
|
-
*/
|
|
64
|
-
export async function resolveEngineBin(dataRoot) {
|
|
65
|
-
// 1. Env override always wins. Don't validate — let the spawn fail
|
|
66
|
-
// loudly if the user gave a bad path.
|
|
67
|
-
const fromEnv = process.env.OPENSQUID_ENGINE_BIN?.trim();
|
|
68
|
-
if (fromEnv)
|
|
69
|
-
return fromEnv;
|
|
70
|
-
// 2. Persisted choice.
|
|
71
|
-
const config = await loadConfig(dataRoot);
|
|
72
|
-
if (config.engine_bin && (await isExecutable(config.engine_bin))) {
|
|
73
|
-
return config.engine_bin;
|
|
74
|
-
}
|
|
75
|
-
// 3. v0.6c: bundled npm optional dependency. Only present in npm
|
|
76
|
-
// installs of `opensquid` once we start publishing the engine
|
|
77
|
-
// binary packages. Returns null in local-dev / git-clone setups,
|
|
78
|
-
// so the older discovery branches still cover that case. We
|
|
79
|
-
// intentionally do NOT persist this to config.json — the path is
|
|
80
|
-
// deterministic from the npm layout, and persisting it would
|
|
81
|
-
// point at a stale node_modules path after upgrades.
|
|
82
|
-
const bundled = resolveBundledEngineBin();
|
|
83
|
-
if (bundled && (await isExecutable(bundled))) {
|
|
84
|
-
return bundled;
|
|
85
|
-
}
|
|
86
|
-
// 4. Auto-search common dev paths.
|
|
87
|
-
const found = await searchCommonPaths();
|
|
88
|
-
if (found) {
|
|
89
|
-
config.engine_bin = found;
|
|
90
|
-
config.engine_bin_resolved_at = new Date().toISOString();
|
|
91
|
-
await saveConfig(config, dataRoot);
|
|
92
|
-
return found;
|
|
93
|
-
}
|
|
94
|
-
// 5. $PATH (in case the user installed loop-engine system-wide).
|
|
95
|
-
const onPath = await whichBinary(ENGINE_BIN_NAME);
|
|
96
|
-
if (onPath) {
|
|
97
|
-
config.engine_bin = onPath;
|
|
98
|
-
config.engine_bin_resolved_at = new Date().toISOString();
|
|
99
|
-
await saveConfig(config, dataRoot);
|
|
100
|
-
return onPath;
|
|
101
|
-
}
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Set the engine binary path explicitly and persist. Validates that the
|
|
106
|
-
* path points at an executable file before writing.
|
|
107
|
-
*/
|
|
108
|
-
export async function setEngineBin(binPath, dataRoot) {
|
|
109
|
-
const abs = path.resolve(binPath);
|
|
110
|
-
if (!(await isExecutable(abs))) {
|
|
111
|
-
throw new Error(`not an executable file: ${abs}`);
|
|
112
|
-
}
|
|
113
|
-
const config = await loadConfig(dataRoot);
|
|
114
|
-
config.engine_bin = abs;
|
|
115
|
-
config.engine_bin_resolved_at = new Date().toISOString();
|
|
116
|
-
await saveConfig(config, dataRoot);
|
|
117
|
-
return { resolved: abs };
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Forget the persisted engine binary path. Forces re-discovery on the
|
|
121
|
-
* next `resolveEngineBin` call.
|
|
122
|
-
*/
|
|
123
|
-
export async function forgetEngineBin(dataRoot) {
|
|
124
|
-
const config = await loadConfig(dataRoot);
|
|
125
|
-
delete config.engine_bin;
|
|
126
|
-
delete config.engine_bin_resolved_at;
|
|
127
|
-
await saveConfig(config, dataRoot);
|
|
128
|
-
}
|
|
129
|
-
// ---------------------------------------------------------------------
|
|
130
|
-
// Internals
|
|
131
|
-
// ---------------------------------------------------------------------
|
|
132
|
-
async function isExecutable(p) {
|
|
133
|
-
try {
|
|
134
|
-
const stat = await fs.stat(p);
|
|
135
|
-
if (!stat.isFile())
|
|
136
|
-
return false;
|
|
137
|
-
// Best-effort executable check: mode & 0o111 (any-x bit set).
|
|
138
|
-
return (stat.mode & 0o111) !== 0;
|
|
139
|
-
}
|
|
140
|
-
catch {
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Walk common dev-machine layouts looking for a release binary.
|
|
146
|
-
* Conservative — only checks paths that look like sibling projects of
|
|
147
|
-
* the user's $HOME. Returns the first hit.
|
|
148
|
-
*/
|
|
149
|
-
async function searchCommonPaths() {
|
|
150
|
-
const home = os.homedir();
|
|
151
|
-
const candidates = [];
|
|
152
|
-
// ~/projects/<*>/engine/target/release/loop-engine — checkout of a
|
|
153
|
-
// workspace named anything; engine/ as the substrate subdir.
|
|
154
|
-
// ~/projects/<*>/target/release/loop-engine — standalone engine repo.
|
|
155
|
-
const projectsRoot = path.join(home, "projects");
|
|
156
|
-
try {
|
|
157
|
-
const dirs = await fs.readdir(projectsRoot, { withFileTypes: true });
|
|
158
|
-
for (const entry of dirs) {
|
|
159
|
-
if (!entry.isDirectory())
|
|
160
|
-
continue;
|
|
161
|
-
candidates.push(path.join(projectsRoot, entry.name, "engine", "target", "release", ENGINE_BIN_NAME), path.join(projectsRoot, entry.name, "target", "release", ENGINE_BIN_NAME));
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
// ~/projects doesn't exist — skip.
|
|
166
|
-
}
|
|
167
|
-
// ~/work/<*>/{engine,}/target/release/loop-engine — alternate
|
|
168
|
-
// convention.
|
|
169
|
-
const workRoot = path.join(home, "work");
|
|
170
|
-
try {
|
|
171
|
-
const dirs = await fs.readdir(workRoot, { withFileTypes: true });
|
|
172
|
-
for (const entry of dirs) {
|
|
173
|
-
if (!entry.isDirectory())
|
|
174
|
-
continue;
|
|
175
|
-
candidates.push(path.join(workRoot, entry.name, "engine", "target", "release", ENGINE_BIN_NAME), path.join(workRoot, entry.name, "target", "release", ENGINE_BIN_NAME));
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
catch {
|
|
179
|
-
// ~/work doesn't exist — skip.
|
|
180
|
-
}
|
|
181
|
-
for (const cand of candidates) {
|
|
182
|
-
if (await isExecutable(cand))
|
|
183
|
-
return cand;
|
|
184
|
-
}
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Cross-platform `which` — search $PATH for an executable named `bin`.
|
|
189
|
-
* Returns absolute path or null.
|
|
190
|
-
*/
|
|
191
|
-
async function whichBinary(bin) {
|
|
192
|
-
const pathEnv = process.env.PATH ?? "";
|
|
193
|
-
const sep = process.platform === "win32" ? ";" : ":";
|
|
194
|
-
for (const dir of pathEnv.split(sep)) {
|
|
195
|
-
if (!dir)
|
|
196
|
-
continue;
|
|
197
|
-
const candidate = path.join(dir, bin);
|
|
198
|
-
if (await isExecutable(candidate))
|
|
199
|
-
return candidate;
|
|
200
|
-
}
|
|
201
|
-
return null;
|
|
202
|
-
}
|
package/dist/config.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src.legacy/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.test.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import * as crypto from "node:crypto";
|
|
2
|
-
import { promises as fs } from "node:fs";
|
|
3
|
-
import * as os from "node:os";
|
|
4
|
-
import * as path from "node:path";
|
|
5
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
6
|
-
import { forgetEngineBin, loadConfig, resolveEngineBin, saveConfig, setEngineBin, } from "./config.js";
|
|
7
|
-
let tmpHome;
|
|
8
|
-
let savedEnvBin;
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
tmpHome = path.join(os.tmpdir(), `oscli-config-${crypto.randomUUID()}`);
|
|
11
|
-
await fs.mkdir(tmpHome, { recursive: true });
|
|
12
|
-
savedEnvBin = process.env.OPENSQUID_ENGINE_BIN;
|
|
13
|
-
delete process.env.OPENSQUID_ENGINE_BIN;
|
|
14
|
-
process.env.OPENSQUID_HOME = tmpHome;
|
|
15
|
-
});
|
|
16
|
-
afterEach(async () => {
|
|
17
|
-
await fs.rm(tmpHome, { recursive: true, force: true });
|
|
18
|
-
if (savedEnvBin === undefined)
|
|
19
|
-
delete process.env.OPENSQUID_ENGINE_BIN;
|
|
20
|
-
else
|
|
21
|
-
process.env.OPENSQUID_ENGINE_BIN = savedEnvBin;
|
|
22
|
-
delete process.env.OPENSQUID_HOME;
|
|
23
|
-
});
|
|
24
|
-
// Helper: write a fake executable at a tmp path.
|
|
25
|
-
async function fakeExecAt(dir, name = "loop-engine") {
|
|
26
|
-
await fs.mkdir(dir, { recursive: true });
|
|
27
|
-
const p = path.join(dir, name);
|
|
28
|
-
await fs.writeFile(p, "#!/bin/sh\necho fake\n", "utf8");
|
|
29
|
-
await fs.chmod(p, 0o755);
|
|
30
|
-
return p;
|
|
31
|
-
}
|
|
32
|
-
// ---------------------------------------------------------------------
|
|
33
|
-
// load / save
|
|
34
|
-
// ---------------------------------------------------------------------
|
|
35
|
-
describe("loadConfig + saveConfig", () => {
|
|
36
|
-
it("returns default config when file is missing", async () => {
|
|
37
|
-
const c = await loadConfig();
|
|
38
|
-
expect(c.version).toBe(1);
|
|
39
|
-
expect(c.engine_bin).toBeUndefined();
|
|
40
|
-
});
|
|
41
|
-
it("round-trips a saved config", async () => {
|
|
42
|
-
await saveConfig({ version: 1, engine_bin: "/x/y", engine_bin_resolved_at: "now" });
|
|
43
|
-
const c = await loadConfig();
|
|
44
|
-
expect(c.engine_bin).toBe("/x/y");
|
|
45
|
-
});
|
|
46
|
-
it("returns default on malformed config", async () => {
|
|
47
|
-
await fs.mkdir(tmpHome, { recursive: true });
|
|
48
|
-
await fs.writeFile(path.join(tmpHome, "config.json"), "{not json", "utf8");
|
|
49
|
-
const c = await loadConfig();
|
|
50
|
-
expect(c.version).toBe(1);
|
|
51
|
-
expect(c.engine_bin).toBeUndefined();
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
// ---------------------------------------------------------------------
|
|
55
|
-
// resolveEngineBin
|
|
56
|
-
// ---------------------------------------------------------------------
|
|
57
|
-
describe("resolveEngineBin priority order", () => {
|
|
58
|
-
it("env var wins over everything (no validation)", async () => {
|
|
59
|
-
process.env.OPENSQUID_ENGINE_BIN = "/some/explicit/path";
|
|
60
|
-
expect(await resolveEngineBin()).toBe("/some/explicit/path");
|
|
61
|
-
});
|
|
62
|
-
it("uses persisted config when env is unset and path is executable", async () => {
|
|
63
|
-
const bin = await fakeExecAt(path.join(tmpHome, "tools"));
|
|
64
|
-
await saveConfig({ version: 1, engine_bin: bin });
|
|
65
|
-
expect(await resolveEngineBin()).toBe(bin);
|
|
66
|
-
});
|
|
67
|
-
it("ignores persisted config when its path is no longer executable", async () => {
|
|
68
|
-
// Persist a path that doesn't exist.
|
|
69
|
-
await saveConfig({ version: 1, engine_bin: "/nonexistent/loop-engine" });
|
|
70
|
-
// Auto-search and $PATH likely won't hit on this machine either.
|
|
71
|
-
const result = await resolveEngineBin();
|
|
72
|
-
// We can't assert null universally (CI runners might have something
|
|
73
|
-
// matching), but the bad persisted path must not have been returned.
|
|
74
|
-
expect(result).not.toBe("/nonexistent/loop-engine");
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
// ---------------------------------------------------------------------
|
|
78
|
-
// setEngineBin
|
|
79
|
-
// ---------------------------------------------------------------------
|
|
80
|
-
describe("setEngineBin", () => {
|
|
81
|
-
it("validates the path is executable", async () => {
|
|
82
|
-
await expect(setEngineBin("/nonexistent/bin")).rejects.toThrow(/not an executable/);
|
|
83
|
-
});
|
|
84
|
-
it("persists the path on success", async () => {
|
|
85
|
-
const bin = await fakeExecAt(path.join(tmpHome, "tools"));
|
|
86
|
-
const res = await setEngineBin(bin);
|
|
87
|
-
expect(res.resolved).toBe(bin);
|
|
88
|
-
const config = await loadConfig();
|
|
89
|
-
expect(config.engine_bin).toBe(bin);
|
|
90
|
-
expect(config.engine_bin_resolved_at).toBeDefined();
|
|
91
|
-
});
|
|
92
|
-
it("resolves relative paths to absolute", async () => {
|
|
93
|
-
const bin = await fakeExecAt(path.join(tmpHome, "tools"));
|
|
94
|
-
const rel = path.relative(process.cwd(), bin);
|
|
95
|
-
const res = await setEngineBin(rel);
|
|
96
|
-
expect(path.isAbsolute(res.resolved)).toBe(true);
|
|
97
|
-
expect(res.resolved).toBe(bin);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
// ---------------------------------------------------------------------
|
|
101
|
-
// forgetEngineBin
|
|
102
|
-
// ---------------------------------------------------------------------
|
|
103
|
-
describe("forgetEngineBin", () => {
|
|
104
|
-
it("clears the persisted engine_bin", async () => {
|
|
105
|
-
const bin = await fakeExecAt(path.join(tmpHome, "tools"));
|
|
106
|
-
await setEngineBin(bin);
|
|
107
|
-
expect((await loadConfig()).engine_bin).toBe(bin);
|
|
108
|
-
await forgetEngineBin();
|
|
109
|
-
expect((await loadConfig()).engine_bin).toBeUndefined();
|
|
110
|
-
});
|
|
111
|
-
it("is idempotent on missing config", async () => {
|
|
112
|
-
await forgetEngineBin();
|
|
113
|
-
await forgetEngineBin();
|
|
114
|
-
// No throw — config just stays empty.
|
|
115
|
-
expect((await loadConfig()).engine_bin).toBeUndefined();
|
|
116
|
-
});
|
|
117
|
-
});
|
package/dist/engine/cli.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { Command } from 'commander';
|
|
2
|
-
export declare class EngineCliError extends Error {
|
|
3
|
-
readonly hint?: string;
|
|
4
|
-
constructor(message: string, hint?: string);
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Register the `engine` verb group on a commander program/sub-program.
|
|
8
|
-
*
|
|
9
|
-
* Errors thrown by subcommand handlers surface via the root program's
|
|
10
|
-
* `parseAsync().catch` — registered handlers don't call `process.exit`
|
|
11
|
-
* directly. `EngineCliError.hint` is rendered when present.
|
|
12
|
-
*/
|
|
13
|
-
export declare function registerEngineCli(program: Command): void;
|
|
14
|
-
//# sourceMappingURL=cli.d.ts.map
|
package/dist/engine/cli.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/engine/cli.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;gBAClB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAK3C;AAsHD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8BxD"}
|
package/dist/engine/cli.js
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `opensquid engine <subcommand>` — engine binary management.
|
|
3
|
-
*
|
|
4
|
-
* Subcommands:
|
|
5
|
-
* doctor — show the resolved engine binary + how it was
|
|
6
|
-
* discovered (env / config / search / PATH).
|
|
7
|
-
* Warns when `OPENSQUID_ENGINE_BIN` is set,
|
|
8
|
-
* since the env-var bypass would pin a stale
|
|
9
|
-
* path forever (re-resolution can't override
|
|
10
|
-
* an explicit env override).
|
|
11
|
-
* set-path <path> — persist an explicit engine binary path in
|
|
12
|
-
* ~/.opensquid/engine-config.json
|
|
13
|
-
* forget — clear the persisted path; force re-discovery
|
|
14
|
-
* on next start
|
|
15
|
-
* kill — read `~/.opensquid/loop-engine.pid` (written
|
|
16
|
-
* by `singleton.acquireOrSpawnEngine`), send
|
|
17
|
-
* SIGTERM, wait 2s for graceful shutdown, then
|
|
18
|
-
* best-effort unlink the socket + pidfile.
|
|
19
|
-
* Idempotent — no pidfile + no socket prints a
|
|
20
|
-
* friendly "no engine daemon running" + exit 0.
|
|
21
|
-
*
|
|
22
|
-
* Registered into the root `opensquid` Command via `registerEngineCli`
|
|
23
|
-
* — call from `src/cli.ts`.
|
|
24
|
-
*/
|
|
25
|
-
import { existsSync } from 'node:fs';
|
|
26
|
-
import { readFile, unlink } from 'node:fs/promises';
|
|
27
|
-
import { forgetEngineBin, loadEngineConfig, resolveEngineBin, setEngineBin } from './config.js';
|
|
28
|
-
import { enginePidPath, engineSocketPath } from './singleton.js';
|
|
29
|
-
export class EngineCliError extends Error {
|
|
30
|
-
hint;
|
|
31
|
-
constructor(message, hint) {
|
|
32
|
-
super(message);
|
|
33
|
-
this.name = 'EngineCliError';
|
|
34
|
-
if (hint !== undefined)
|
|
35
|
-
this.hint = hint;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
async function cmdDoctor() {
|
|
39
|
-
process.stdout.write('[opensquid engine doctor]\n');
|
|
40
|
-
const env = process.env.OPENSQUID_ENGINE_BIN?.trim();
|
|
41
|
-
process.stdout.write(` env OPENSQUID_ENGINE_BIN: ${env ?? '(unset)'}\n`);
|
|
42
|
-
const config = await loadEngineConfig();
|
|
43
|
-
process.stdout.write(` config.engine_bin: ${config.engine_bin ?? '(unset)'}\n`);
|
|
44
|
-
if (config.engine_bin_resolved_at) {
|
|
45
|
-
process.stdout.write(` resolved at: ${config.engine_bin_resolved_at}\n`);
|
|
46
|
-
}
|
|
47
|
-
const resolved = await resolveEngineBin();
|
|
48
|
-
process.stdout.write(` resolved binary: ${resolved ?? '(none — not found)'}\n`);
|
|
49
|
-
// T.7: the env-var bypass short-circuits stale-path re-resolution,
|
|
50
|
-
// so a stale `OPENSQUID_ENGINE_BIN` would pin a dead path forever.
|
|
51
|
-
// Surface the override + remind the user re-resolution is disabled.
|
|
52
|
-
if (env) {
|
|
53
|
-
process.stdout.write(' note: env var OPENSQUID_ENGINE_BIN is set — stale-path re-resolution is disabled.\n' +
|
|
54
|
-
' unset it to let opensquid recover automatically.\n');
|
|
55
|
-
}
|
|
56
|
-
if (!resolved) {
|
|
57
|
-
process.stdout.write(' hint: run `opensquid engine set-path <path>` to fix.\n');
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
async function cmdSetPath(target) {
|
|
61
|
-
if (!target) {
|
|
62
|
-
throw new EngineCliError('usage: opensquid engine set-path <path>', 'pass the path to a loop-engine release binary');
|
|
63
|
-
}
|
|
64
|
-
const res = await setEngineBin(target);
|
|
65
|
-
process.stdout.write(`[opensquid engine set-path] persisted: ${res.resolved}\n`);
|
|
66
|
-
}
|
|
67
|
-
async function cmdForget() {
|
|
68
|
-
await forgetEngineBin();
|
|
69
|
-
process.stdout.write('[opensquid engine forget] cleared persisted engine_bin\n');
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Grace period after `SIGTERM` before we clean up the socket + pidfile.
|
|
73
|
-
* The engine's own shutdown handler should unlink both as it exits;
|
|
74
|
-
* cleanup here is defense-in-depth for SIGKILL fallbacks / crashes.
|
|
75
|
-
* 2s is comfortably above engine clean-shutdown time (<200ms typical)
|
|
76
|
-
* without making `engine kill` feel slow on a healthy daemon.
|
|
77
|
-
*/
|
|
78
|
-
const KILL_GRACE_MS = 2_000;
|
|
79
|
-
async function cmdKill() {
|
|
80
|
-
const sockPath = engineSocketPath();
|
|
81
|
-
const pidPath = enginePidPath();
|
|
82
|
-
const sockExists = existsSync(sockPath);
|
|
83
|
-
const pidExists = existsSync(pidPath);
|
|
84
|
-
// Idempotent no-op when nothing is running. Avoids scaring a user
|
|
85
|
-
// who runs `engine kill` defensively before tearing down a project.
|
|
86
|
-
if (!sockExists && !pidExists) {
|
|
87
|
-
process.stdout.write('[opensquid engine kill] no engine daemon running.\n');
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
// Pidfile is the only authoritative pid source — the socket file
|
|
91
|
-
// alone tells us nothing about who's listening. If the pidfile is
|
|
92
|
-
// missing or malformed, skip the signal and fall through to cleanup.
|
|
93
|
-
let pid = null;
|
|
94
|
-
if (pidExists) {
|
|
95
|
-
try {
|
|
96
|
-
const raw = (await readFile(pidPath, 'utf8')).trim();
|
|
97
|
-
const parsed = Number.parseInt(raw, 10);
|
|
98
|
-
if (Number.isFinite(parsed) && parsed > 0) {
|
|
99
|
-
pid = parsed;
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
process.stdout.write(`[opensquid engine kill] warning: pidfile contents not a valid pid (${raw}); skipping SIGTERM.\n`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch (e) {
|
|
106
|
-
process.stdout.write(`[opensquid engine kill] warning: could not read pidfile: ${String(e)}; skipping SIGTERM.\n`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (pid !== null) {
|
|
110
|
-
try {
|
|
111
|
-
process.kill(pid, 'SIGTERM');
|
|
112
|
-
process.stdout.write(`[opensquid engine kill] sent SIGTERM to pid=${String(pid)}.\n`);
|
|
113
|
-
// Give the engine its graceful-shutdown window before we step
|
|
114
|
-
// in for cleanup. The engine SHOULD unlink the socket + pidfile
|
|
115
|
-
// itself; our unlink calls below are best-effort fallbacks.
|
|
116
|
-
await new Promise((resolve) => setTimeout(resolve, KILL_GRACE_MS));
|
|
117
|
-
}
|
|
118
|
-
catch (e) {
|
|
119
|
-
// ESRCH (no such pid) is the common case — pidfile is stale
|
|
120
|
-
// because the engine crashed without cleanup. Log + continue
|
|
121
|
-
// to the unlink step so we don't leave junk behind.
|
|
122
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
123
|
-
process.stdout.write(`[opensquid engine kill] kill(${String(pid)}, SIGTERM) failed: ${msg}; continuing to cleanup.\n`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
// Defense-in-depth cleanup. Either the engine already unlinked
|
|
127
|
-
// these (cleanly handled SIGTERM) or it didn't (crash / SIGKILL).
|
|
128
|
-
// Swallow errors — best-effort.
|
|
129
|
-
if (existsSync(sockPath)) {
|
|
130
|
-
await unlink(sockPath).catch(() => undefined);
|
|
131
|
-
}
|
|
132
|
-
if (existsSync(pidPath)) {
|
|
133
|
-
await unlink(pidPath).catch(() => undefined);
|
|
134
|
-
}
|
|
135
|
-
process.stdout.write('[opensquid engine kill] engine daemon stopped.\n');
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Register the `engine` verb group on a commander program/sub-program.
|
|
139
|
-
*
|
|
140
|
-
* Errors thrown by subcommand handlers surface via the root program's
|
|
141
|
-
* `parseAsync().catch` — registered handlers don't call `process.exit`
|
|
142
|
-
* directly. `EngineCliError.hint` is rendered when present.
|
|
143
|
-
*/
|
|
144
|
-
export function registerEngineCli(program) {
|
|
145
|
-
const engine = program.command('engine').description('loop-engine binary management');
|
|
146
|
-
engine
|
|
147
|
-
.command('doctor')
|
|
148
|
-
.description('Show resolved engine binary + discovery chain.')
|
|
149
|
-
.action(async () => {
|
|
150
|
-
await cmdDoctor();
|
|
151
|
-
});
|
|
152
|
-
engine
|
|
153
|
-
.command('set-path <path>')
|
|
154
|
-
.description('Persist an explicit engine binary path.')
|
|
155
|
-
.action(async (target) => {
|
|
156
|
-
await cmdSetPath(target);
|
|
157
|
-
});
|
|
158
|
-
engine
|
|
159
|
-
.command('forget')
|
|
160
|
-
.description('Clear the persisted engine binary path; force re-discovery.')
|
|
161
|
-
.action(async () => {
|
|
162
|
-
await cmdForget();
|
|
163
|
-
});
|
|
164
|
-
engine
|
|
165
|
-
.command('kill')
|
|
166
|
-
.description('Stop the loop-engine singleton daemon (SIGTERM via pidfile + cleanup).')
|
|
167
|
-
.action(async () => {
|
|
168
|
-
await cmdKill();
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
//# sourceMappingURL=cli.js.map
|
package/dist/engine/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/engine/cli.ts"],"names":[],"mappings":"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"}
|