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/project.js
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Project identity — decouple project scope from filesystem path.
|
|
3
|
-
*
|
|
4
|
-
* Two artifacts work together:
|
|
5
|
-
*
|
|
6
|
-
* 1. **Local ID card** at `<project-root>/.opensquid/project.json` —
|
|
7
|
-
* stable identity that travels with the project across moves /
|
|
8
|
-
* renames. Contains `id` (human-friendly), `uuid` (machine-stable),
|
|
9
|
-
* `created_at`.
|
|
10
|
-
*
|
|
11
|
-
* 2. **Global registry** at `~/.opensquid/projects.json` — index of
|
|
12
|
-
* all known projects by uuid. Tracks `last_seen_path`,
|
|
13
|
-
* `last_seen_at`, `status` (active|deleted) so we can detect
|
|
14
|
-
* moves and prune deletes.
|
|
15
|
-
*
|
|
16
|
-
* State machine on `resolveProject(cwd)`:
|
|
17
|
-
*
|
|
18
|
-
* - card present, registry agrees on path → **known**
|
|
19
|
-
* - card present, registry has different path for this uuid → **moved**
|
|
20
|
-
* (registry's old path may or may not still exist; we update both)
|
|
21
|
-
* - card absent → **new** (caller decides whether to auto-create)
|
|
22
|
-
*
|
|
23
|
-
* `pruneDeleted()` sweeps the registry: for each active entry whose
|
|
24
|
-
* `last_seen_path` no longer exists on disk, flip status to "deleted".
|
|
25
|
-
*/
|
|
26
|
-
import * as crypto from "node:crypto";
|
|
27
|
-
import { promises as fs } from "node:fs";
|
|
28
|
-
import * as os from "node:os";
|
|
29
|
-
import * as path from "node:path";
|
|
30
|
-
import { resolveDataRoot } from "./codex/store.js";
|
|
31
|
-
// ---------------------------------------------------------------------
|
|
32
|
-
// Paths
|
|
33
|
-
// ---------------------------------------------------------------------
|
|
34
|
-
const CARD_DIR = ".opensquid";
|
|
35
|
-
const CARD_FILE = "project.json";
|
|
36
|
-
const REGISTRY_FILE = "projects.json";
|
|
37
|
-
/** Path to the registry file. */
|
|
38
|
-
export function registryPath(dataRoot) {
|
|
39
|
-
return path.join(resolveDataRoot(dataRoot), REGISTRY_FILE);
|
|
40
|
-
}
|
|
41
|
-
/** Path the ID card WOULD live at for a given project root. */
|
|
42
|
-
export function cardPathForRoot(projectRoot) {
|
|
43
|
-
return path.join(projectRoot, CARD_DIR, CARD_FILE);
|
|
44
|
-
}
|
|
45
|
-
// ---------------------------------------------------------------------
|
|
46
|
-
// Card load / save
|
|
47
|
-
// ---------------------------------------------------------------------
|
|
48
|
-
/**
|
|
49
|
-
* Walk up from `cwd` looking for a `.opensquid/project.json` card.
|
|
50
|
-
* Stops at the filesystem root. Returns the card + the path the
|
|
51
|
-
* card was found at, or null if no card exists in any ancestor.
|
|
52
|
-
*/
|
|
53
|
-
export async function findProjectCard(cwd) {
|
|
54
|
-
let dir = path.resolve(cwd);
|
|
55
|
-
while (true) {
|
|
56
|
-
const candidate = path.join(dir, CARD_DIR, CARD_FILE);
|
|
57
|
-
try {
|
|
58
|
-
const raw = await fs.readFile(candidate, "utf8");
|
|
59
|
-
const parsed = JSON.parse(raw);
|
|
60
|
-
if (parsed && parsed.version === 1 && parsed.uuid && parsed.id) {
|
|
61
|
-
return { card: parsed, cardPath: candidate };
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
// ignore — keep walking up
|
|
66
|
-
}
|
|
67
|
-
const parent = path.dirname(dir);
|
|
68
|
-
if (parent === dir)
|
|
69
|
-
return null;
|
|
70
|
-
dir = parent;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Write a project card at `<projectRoot>/.opensquid/project.json`.
|
|
75
|
-
* Refuses to overwrite an existing card unless `force` is set —
|
|
76
|
-
* overwriting is a manual operation, not an accidental one.
|
|
77
|
-
*/
|
|
78
|
-
export async function writeProjectCard(projectRoot, card, options = {}) {
|
|
79
|
-
const cardPath = cardPathForRoot(projectRoot);
|
|
80
|
-
try {
|
|
81
|
-
await fs.access(cardPath);
|
|
82
|
-
if (!options.force) {
|
|
83
|
-
throw new Error(`project card already exists at ${cardPath} (use force to overwrite)`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
catch (err) {
|
|
87
|
-
// Re-throw real errors; ENOENT means we proceed.
|
|
88
|
-
if (err.code !== "ENOENT" &&
|
|
89
|
-
!(err instanceof Error && err.message.includes("already exists"))) {
|
|
90
|
-
throw err;
|
|
91
|
-
}
|
|
92
|
-
if (err instanceof Error && err.message.includes("already exists"))
|
|
93
|
-
throw err;
|
|
94
|
-
}
|
|
95
|
-
await fs.mkdir(path.dirname(cardPath), { recursive: true });
|
|
96
|
-
await fs.writeFile(cardPath, JSON.stringify(card, null, 2) + "\n", "utf8");
|
|
97
|
-
return { cardPath };
|
|
98
|
-
}
|
|
99
|
-
// ---------------------------------------------------------------------
|
|
100
|
-
// Registry load / save
|
|
101
|
-
// ---------------------------------------------------------------------
|
|
102
|
-
export async function loadRegistry(dataRoot) {
|
|
103
|
-
const p = registryPath(dataRoot);
|
|
104
|
-
try {
|
|
105
|
-
const raw = await fs.readFile(p, "utf8");
|
|
106
|
-
const parsed = JSON.parse(raw);
|
|
107
|
-
if (parsed && parsed.version === 1 && parsed.projects)
|
|
108
|
-
return parsed;
|
|
109
|
-
}
|
|
110
|
-
catch {
|
|
111
|
-
// missing or malformed — return a fresh registry
|
|
112
|
-
}
|
|
113
|
-
return { version: 1, projects: {} };
|
|
114
|
-
}
|
|
115
|
-
export async function saveRegistry(reg, dataRoot) {
|
|
116
|
-
const p = registryPath(dataRoot);
|
|
117
|
-
await fs.mkdir(path.dirname(p), { recursive: true });
|
|
118
|
-
await fs.writeFile(p, JSON.stringify(reg, null, 2) + "\n", "utf8");
|
|
119
|
-
}
|
|
120
|
-
// ---------------------------------------------------------------------
|
|
121
|
-
// Resolve project state
|
|
122
|
-
// ---------------------------------------------------------------------
|
|
123
|
-
/**
|
|
124
|
-
* Determine the project state for a given cwd.
|
|
125
|
-
*
|
|
126
|
-
* - Walks up from cwd for a card.
|
|
127
|
-
* - Cross-references with the registry.
|
|
128
|
-
* - Returns the state without mutating either file.
|
|
129
|
-
*
|
|
130
|
-
* `applyResolution` is the side-effect step: it updates the registry
|
|
131
|
-
* based on the resolved state (and creates a card for `new` IF the
|
|
132
|
-
* caller asks it to).
|
|
133
|
-
*/
|
|
134
|
-
export async function resolveProject(cwd, options = {}) {
|
|
135
|
-
const found = await findProjectCard(cwd);
|
|
136
|
-
if (!found) {
|
|
137
|
-
const suggested = await suggestedIdForCwd(cwd);
|
|
138
|
-
return { kind: "new", project_root: null, suggested_id: suggested };
|
|
139
|
-
}
|
|
140
|
-
const reg = await loadRegistry(options.dataRoot);
|
|
141
|
-
const projectRoot = path.dirname(path.dirname(found.cardPath));
|
|
142
|
-
const entry = reg.projects[found.card.uuid];
|
|
143
|
-
if (!entry || entry.last_seen_path === projectRoot) {
|
|
144
|
-
return { kind: "known", card: found.card, cardPath: found.cardPath };
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
kind: "moved",
|
|
148
|
-
card: found.card,
|
|
149
|
-
cardPath: found.cardPath,
|
|
150
|
-
from_path: entry.last_seen_path,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Side-effecting companion to `resolveProject`. Updates the registry
|
|
155
|
-
* (creating the card if asked for `new`). Idempotent.
|
|
156
|
-
*
|
|
157
|
-
* - `known`: bump `last_seen_at` only.
|
|
158
|
-
* - `moved`: update `last_seen_path` + `last_seen_at`.
|
|
159
|
-
* - `new`: if `autoCreate` is true, create a card at `cwd` + register
|
|
160
|
-
* it. Otherwise return null.
|
|
161
|
-
*/
|
|
162
|
-
export async function applyResolution(cwd, resolved, options = {}) {
|
|
163
|
-
const dataRoot = options.dataRoot;
|
|
164
|
-
const now = new Date().toISOString();
|
|
165
|
-
const reg = await loadRegistry(dataRoot);
|
|
166
|
-
if (resolved.kind === "known") {
|
|
167
|
-
const entry = reg.projects[resolved.card.uuid];
|
|
168
|
-
if (entry) {
|
|
169
|
-
entry.last_seen_at = now;
|
|
170
|
-
entry.status = "active";
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
const projectRoot = path.dirname(path.dirname(resolved.cardPath));
|
|
174
|
-
reg.projects[resolved.card.uuid] = {
|
|
175
|
-
id: resolved.card.id,
|
|
176
|
-
last_seen_path: projectRoot,
|
|
177
|
-
last_seen_at: now,
|
|
178
|
-
created_at: resolved.card.created_at,
|
|
179
|
-
status: "active",
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
await saveRegistry(reg, dataRoot);
|
|
183
|
-
return resolved.card;
|
|
184
|
-
}
|
|
185
|
-
if (resolved.kind === "moved") {
|
|
186
|
-
const projectRoot = path.dirname(path.dirname(resolved.cardPath));
|
|
187
|
-
reg.projects[resolved.card.uuid] = {
|
|
188
|
-
id: resolved.card.id,
|
|
189
|
-
last_seen_path: projectRoot,
|
|
190
|
-
last_seen_at: now,
|
|
191
|
-
created_at: reg.projects[resolved.card.uuid]?.created_at ?? resolved.card.created_at,
|
|
192
|
-
status: "active",
|
|
193
|
-
};
|
|
194
|
-
await saveRegistry(reg, dataRoot);
|
|
195
|
-
return resolved.card;
|
|
196
|
-
}
|
|
197
|
-
// kind === "new"
|
|
198
|
-
if (!options.autoCreate)
|
|
199
|
-
return null;
|
|
200
|
-
const id = options.id ?? resolved.suggested_id;
|
|
201
|
-
const uuid = crypto.randomUUID();
|
|
202
|
-
const created_at = now;
|
|
203
|
-
const card = { version: 1, id, uuid, created_at };
|
|
204
|
-
await writeProjectCard(path.resolve(cwd), card);
|
|
205
|
-
reg.projects[uuid] = {
|
|
206
|
-
id,
|
|
207
|
-
last_seen_path: path.resolve(cwd),
|
|
208
|
-
last_seen_at: now,
|
|
209
|
-
created_at,
|
|
210
|
-
status: "active",
|
|
211
|
-
};
|
|
212
|
-
await saveRegistry(reg, dataRoot);
|
|
213
|
-
return card;
|
|
214
|
-
}
|
|
215
|
-
// ---------------------------------------------------------------------
|
|
216
|
-
// Registry maintenance
|
|
217
|
-
// ---------------------------------------------------------------------
|
|
218
|
-
/**
|
|
219
|
-
* Mark registry entries as "deleted" when their `last_seen_path` no
|
|
220
|
-
* longer exists on disk. Does NOT actually remove the entry — kept
|
|
221
|
-
* for historical reference and so the user can see what they had.
|
|
222
|
-
*
|
|
223
|
-
* Returns the count of entries that flipped from active → deleted.
|
|
224
|
-
*/
|
|
225
|
-
export async function pruneDeleted(dataRoot) {
|
|
226
|
-
const reg = await loadRegistry(dataRoot);
|
|
227
|
-
let swept = 0;
|
|
228
|
-
const removed_ids = [];
|
|
229
|
-
for (const [uuid, entry] of Object.entries(reg.projects)) {
|
|
230
|
-
if (entry.status !== "active")
|
|
231
|
-
continue;
|
|
232
|
-
try {
|
|
233
|
-
await fs.access(entry.last_seen_path);
|
|
234
|
-
}
|
|
235
|
-
catch {
|
|
236
|
-
entry.status = "deleted";
|
|
237
|
-
swept++;
|
|
238
|
-
removed_ids.push(entry.id);
|
|
239
|
-
void uuid;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
if (swept > 0)
|
|
243
|
-
await saveRegistry(reg, dataRoot);
|
|
244
|
-
return { swept, removed_ids };
|
|
245
|
-
}
|
|
246
|
-
// ---------------------------------------------------------------------
|
|
247
|
-
// Helpers
|
|
248
|
-
// ---------------------------------------------------------------------
|
|
249
|
-
/**
|
|
250
|
-
* Default-id heuristic: git toplevel basename if available, else cwd
|
|
251
|
-
* basename, else "project".
|
|
252
|
-
*/
|
|
253
|
-
async function suggestedIdForCwd(cwd) {
|
|
254
|
-
const gitTop = await gitToplevel(cwd);
|
|
255
|
-
if (gitTop)
|
|
256
|
-
return path.basename(gitTop);
|
|
257
|
-
const cwdName = path.basename(path.resolve(cwd));
|
|
258
|
-
return cwdName || "project";
|
|
259
|
-
}
|
|
260
|
-
async function gitToplevel(cwd) {
|
|
261
|
-
// Walk up looking for a `.git` directory.
|
|
262
|
-
let dir = path.resolve(cwd);
|
|
263
|
-
while (true) {
|
|
264
|
-
try {
|
|
265
|
-
const stat = await fs.stat(path.join(dir, ".git"));
|
|
266
|
-
if (stat.isDirectory())
|
|
267
|
-
return dir;
|
|
268
|
-
}
|
|
269
|
-
catch {
|
|
270
|
-
// keep walking
|
|
271
|
-
}
|
|
272
|
-
const parent = path.dirname(dir);
|
|
273
|
-
if (parent === dir) {
|
|
274
|
-
// tilde-fallback only used for tests where HOME might point at /
|
|
275
|
-
void os.homedir;
|
|
276
|
-
return null;
|
|
277
|
-
}
|
|
278
|
-
dir = parent;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
//# sourceMappingURL=project.js.map
|
package/dist/project.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src.legacy/project.ts"],"names":[],"mappings":"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"}
|
package/dist/project.test.js
DELETED
|
@@ -1,287 +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 { applyResolution, cardPathForRoot, findProjectCard, loadRegistry, pruneDeleted, resolveProject, saveRegistry, writeProjectCard, } from "./project.js";
|
|
7
|
-
let tmpRoot;
|
|
8
|
-
let tmpHome;
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
const uniq = crypto.randomUUID();
|
|
11
|
-
tmpRoot = path.join(os.tmpdir(), `oscli-project-cwd-${uniq}`);
|
|
12
|
-
tmpHome = path.join(os.tmpdir(), `oscli-project-home-${uniq}`);
|
|
13
|
-
await fs.mkdir(tmpRoot, { recursive: true });
|
|
14
|
-
await fs.mkdir(tmpHome, { recursive: true });
|
|
15
|
-
});
|
|
16
|
-
afterEach(async () => {
|
|
17
|
-
await fs.rm(tmpRoot, { recursive: true, force: true });
|
|
18
|
-
await fs.rm(tmpHome, { recursive: true, force: true });
|
|
19
|
-
});
|
|
20
|
-
// ---------------------------------------------------------------------
|
|
21
|
-
// findProjectCard
|
|
22
|
-
// ---------------------------------------------------------------------
|
|
23
|
-
describe("findProjectCard", () => {
|
|
24
|
-
it("returns null when no card in any ancestor", async () => {
|
|
25
|
-
expect(await findProjectCard(tmpRoot)).toBeNull();
|
|
26
|
-
});
|
|
27
|
-
it("finds a card at cwd", async () => {
|
|
28
|
-
const card = {
|
|
29
|
-
version: 1,
|
|
30
|
-
id: "x",
|
|
31
|
-
uuid: "u-1",
|
|
32
|
-
created_at: "2026-05-15T00:00:00Z",
|
|
33
|
-
};
|
|
34
|
-
await writeProjectCard(tmpRoot, card);
|
|
35
|
-
const found = await findProjectCard(tmpRoot);
|
|
36
|
-
expect(found?.card.uuid).toBe("u-1");
|
|
37
|
-
});
|
|
38
|
-
it("walks up to find a card at an ancestor", async () => {
|
|
39
|
-
const card = {
|
|
40
|
-
version: 1,
|
|
41
|
-
id: "x",
|
|
42
|
-
uuid: "u-1",
|
|
43
|
-
created_at: "2026-05-15T00:00:00Z",
|
|
44
|
-
};
|
|
45
|
-
await writeProjectCard(tmpRoot, card);
|
|
46
|
-
const deep = path.join(tmpRoot, "src", "nested", "deep");
|
|
47
|
-
await fs.mkdir(deep, { recursive: true });
|
|
48
|
-
const found = await findProjectCard(deep);
|
|
49
|
-
expect(found?.card.uuid).toBe("u-1");
|
|
50
|
-
expect(found?.cardPath).toBe(cardPathForRoot(tmpRoot));
|
|
51
|
-
});
|
|
52
|
-
it("ignores malformed card files", async () => {
|
|
53
|
-
await fs.mkdir(path.join(tmpRoot, ".opensquid"), { recursive: true });
|
|
54
|
-
await fs.writeFile(cardPathForRoot(tmpRoot), "{not valid json", "utf8");
|
|
55
|
-
expect(await findProjectCard(tmpRoot)).toBeNull();
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
// ---------------------------------------------------------------------
|
|
59
|
-
// writeProjectCard
|
|
60
|
-
// ---------------------------------------------------------------------
|
|
61
|
-
describe("writeProjectCard", () => {
|
|
62
|
-
it("creates the .opensquid/project.json file", async () => {
|
|
63
|
-
const card = {
|
|
64
|
-
version: 1,
|
|
65
|
-
id: "x",
|
|
66
|
-
uuid: "u-1",
|
|
67
|
-
created_at: "now",
|
|
68
|
-
};
|
|
69
|
-
const res = await writeProjectCard(tmpRoot, card);
|
|
70
|
-
expect(res.cardPath).toBe(cardPathForRoot(tmpRoot));
|
|
71
|
-
const read = await fs.readFile(res.cardPath, "utf8");
|
|
72
|
-
expect(JSON.parse(read).uuid).toBe("u-1");
|
|
73
|
-
});
|
|
74
|
-
it("refuses to overwrite without force", async () => {
|
|
75
|
-
const card = {
|
|
76
|
-
version: 1,
|
|
77
|
-
id: "x",
|
|
78
|
-
uuid: "u-1",
|
|
79
|
-
created_at: "now",
|
|
80
|
-
};
|
|
81
|
-
await writeProjectCard(tmpRoot, card);
|
|
82
|
-
await expect(writeProjectCard(tmpRoot, card)).rejects.toThrow(/already exists/);
|
|
83
|
-
});
|
|
84
|
-
it("overwrites with force=true", async () => {
|
|
85
|
-
const v1 = {
|
|
86
|
-
version: 1,
|
|
87
|
-
id: "x",
|
|
88
|
-
uuid: "u-1",
|
|
89
|
-
created_at: "now",
|
|
90
|
-
};
|
|
91
|
-
await writeProjectCard(tmpRoot, v1);
|
|
92
|
-
const v2 = { ...v1, id: "y" };
|
|
93
|
-
await writeProjectCard(tmpRoot, v2, { force: true });
|
|
94
|
-
const found = await findProjectCard(tmpRoot);
|
|
95
|
-
expect(found?.card.id).toBe("y");
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
// ---------------------------------------------------------------------
|
|
99
|
-
// resolveProject — state machine
|
|
100
|
-
// ---------------------------------------------------------------------
|
|
101
|
-
describe("resolveProject state machine", () => {
|
|
102
|
-
it("returns 'new' when no card exists", async () => {
|
|
103
|
-
const r = await resolveProject(tmpRoot, { dataRoot: tmpHome });
|
|
104
|
-
expect(r.kind).toBe("new");
|
|
105
|
-
if (r.kind === "new") {
|
|
106
|
-
expect(r.suggested_id).toBe(path.basename(tmpRoot));
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
it("returns 'known' when card exists at path that matches registry", async () => {
|
|
110
|
-
const card = {
|
|
111
|
-
version: 1,
|
|
112
|
-
id: "x",
|
|
113
|
-
uuid: "u-1",
|
|
114
|
-
created_at: "now",
|
|
115
|
-
};
|
|
116
|
-
await writeProjectCard(tmpRoot, card);
|
|
117
|
-
// Apply once so registry knows the path.
|
|
118
|
-
await applyResolution(tmpRoot, await resolveProject(tmpRoot, { dataRoot: tmpHome }), {
|
|
119
|
-
dataRoot: tmpHome,
|
|
120
|
-
});
|
|
121
|
-
const r = await resolveProject(tmpRoot, { dataRoot: tmpHome });
|
|
122
|
-
expect(r.kind).toBe("known");
|
|
123
|
-
});
|
|
124
|
-
it("returns 'moved' when card exists at NEW path but registry has DIFFERENT path", async () => {
|
|
125
|
-
// Create card at tmpRoot, register it there.
|
|
126
|
-
const card = {
|
|
127
|
-
version: 1,
|
|
128
|
-
id: "x",
|
|
129
|
-
uuid: "u-1",
|
|
130
|
-
created_at: "now",
|
|
131
|
-
};
|
|
132
|
-
await writeProjectCard(tmpRoot, card);
|
|
133
|
-
await applyResolution(tmpRoot, await resolveProject(tmpRoot, { dataRoot: tmpHome }), {
|
|
134
|
-
dataRoot: tmpHome,
|
|
135
|
-
});
|
|
136
|
-
// Simulate move: write the same card at a new path, leave registry as-is.
|
|
137
|
-
const newRoot = path.join(os.tmpdir(), `oscli-moved-${crypto.randomUUID()}`);
|
|
138
|
-
await fs.mkdir(newRoot, { recursive: true });
|
|
139
|
-
try {
|
|
140
|
-
await writeProjectCard(newRoot, card);
|
|
141
|
-
const r = await resolveProject(newRoot, { dataRoot: tmpHome });
|
|
142
|
-
expect(r.kind).toBe("moved");
|
|
143
|
-
if (r.kind === "moved") {
|
|
144
|
-
expect(r.from_path).toBe(tmpRoot);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
finally {
|
|
148
|
-
await fs.rm(newRoot, { recursive: true, force: true });
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
// ---------------------------------------------------------------------
|
|
153
|
-
// applyResolution
|
|
154
|
-
// ---------------------------------------------------------------------
|
|
155
|
-
describe("applyResolution", () => {
|
|
156
|
-
it("auto-creates card on 'new' when autoCreate=true", async () => {
|
|
157
|
-
const r = await resolveProject(tmpRoot, { dataRoot: tmpHome });
|
|
158
|
-
expect(r.kind).toBe("new");
|
|
159
|
-
const card = await applyResolution(tmpRoot, r, {
|
|
160
|
-
dataRoot: tmpHome,
|
|
161
|
-
autoCreate: true,
|
|
162
|
-
});
|
|
163
|
-
expect(card).not.toBeNull();
|
|
164
|
-
expect(card?.id).toBe(path.basename(tmpRoot));
|
|
165
|
-
// Card persisted on disk.
|
|
166
|
-
const found = await findProjectCard(tmpRoot);
|
|
167
|
-
expect(found?.card.uuid).toBe(card?.uuid);
|
|
168
|
-
// Registry has it.
|
|
169
|
-
const reg = await loadRegistry(tmpHome);
|
|
170
|
-
expect(reg.projects[card.uuid].last_seen_path).toBe(tmpRoot);
|
|
171
|
-
});
|
|
172
|
-
it("returns null on 'new' when autoCreate=false (default)", async () => {
|
|
173
|
-
const r = await resolveProject(tmpRoot, { dataRoot: tmpHome });
|
|
174
|
-
const card = await applyResolution(tmpRoot, r, { dataRoot: tmpHome });
|
|
175
|
-
expect(card).toBeNull();
|
|
176
|
-
expect(await findProjectCard(tmpRoot)).toBeNull();
|
|
177
|
-
});
|
|
178
|
-
it("custom --id overrides the suggested default on auto-create", async () => {
|
|
179
|
-
const r = await resolveProject(tmpRoot, { dataRoot: tmpHome });
|
|
180
|
-
const card = await applyResolution(tmpRoot, r, {
|
|
181
|
-
dataRoot: tmpHome,
|
|
182
|
-
autoCreate: true,
|
|
183
|
-
id: "custom-name",
|
|
184
|
-
});
|
|
185
|
-
expect(card?.id).toBe("custom-name");
|
|
186
|
-
});
|
|
187
|
-
it("updates registry path on 'moved'", async () => {
|
|
188
|
-
// Create card + register at tmpRoot.
|
|
189
|
-
const card = {
|
|
190
|
-
version: 1,
|
|
191
|
-
id: "x",
|
|
192
|
-
uuid: "u-mov",
|
|
193
|
-
created_at: "now",
|
|
194
|
-
};
|
|
195
|
-
await writeProjectCard(tmpRoot, card);
|
|
196
|
-
await applyResolution(tmpRoot, await resolveProject(tmpRoot, { dataRoot: tmpHome }), {
|
|
197
|
-
dataRoot: tmpHome,
|
|
198
|
-
});
|
|
199
|
-
// Move: same card at a new path.
|
|
200
|
-
const newRoot = path.join(os.tmpdir(), `oscli-moved-${crypto.randomUUID()}`);
|
|
201
|
-
await fs.mkdir(newRoot, { recursive: true });
|
|
202
|
-
try {
|
|
203
|
-
await writeProjectCard(newRoot, card);
|
|
204
|
-
const r = await resolveProject(newRoot, { dataRoot: tmpHome });
|
|
205
|
-
expect(r.kind).toBe("moved");
|
|
206
|
-
await applyResolution(newRoot, r, { dataRoot: tmpHome });
|
|
207
|
-
const reg = await loadRegistry(tmpHome);
|
|
208
|
-
expect(reg.projects["u-mov"].last_seen_path).toBe(newRoot);
|
|
209
|
-
}
|
|
210
|
-
finally {
|
|
211
|
-
await fs.rm(newRoot, { recursive: true, force: true });
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
it("preserves created_at across registry updates", async () => {
|
|
215
|
-
const card = {
|
|
216
|
-
version: 1,
|
|
217
|
-
id: "x",
|
|
218
|
-
uuid: "u-1",
|
|
219
|
-
created_at: "2020-01-01T00:00:00Z",
|
|
220
|
-
};
|
|
221
|
-
await writeProjectCard(tmpRoot, card);
|
|
222
|
-
await applyResolution(tmpRoot, await resolveProject(tmpRoot, { dataRoot: tmpHome }), {
|
|
223
|
-
dataRoot: tmpHome,
|
|
224
|
-
});
|
|
225
|
-
const reg1 = await loadRegistry(tmpHome);
|
|
226
|
-
const firstCreatedAt = reg1.projects["u-1"].created_at;
|
|
227
|
-
// Second invocation shouldn't change created_at even when last_seen_at moves.
|
|
228
|
-
await applyResolution(tmpRoot, await resolveProject(tmpRoot, { dataRoot: tmpHome }), {
|
|
229
|
-
dataRoot: tmpHome,
|
|
230
|
-
});
|
|
231
|
-
const reg2 = await loadRegistry(tmpHome);
|
|
232
|
-
expect(reg2.projects["u-1"].created_at).toBe(firstCreatedAt);
|
|
233
|
-
});
|
|
234
|
-
});
|
|
235
|
-
// ---------------------------------------------------------------------
|
|
236
|
-
// pruneDeleted
|
|
237
|
-
// ---------------------------------------------------------------------
|
|
238
|
-
describe("pruneDeleted", () => {
|
|
239
|
-
it("flips entries whose last_seen_path no longer exists", async () => {
|
|
240
|
-
// Set up two entries: one path exists, one doesn't.
|
|
241
|
-
const goneRoot = path.join(os.tmpdir(), `oscli-gone-${crypto.randomUUID()}`);
|
|
242
|
-
await fs.mkdir(goneRoot);
|
|
243
|
-
await saveRegistry({
|
|
244
|
-
version: 1,
|
|
245
|
-
projects: {
|
|
246
|
-
alive: {
|
|
247
|
-
id: "alive",
|
|
248
|
-
last_seen_path: tmpRoot,
|
|
249
|
-
last_seen_at: "2026-05-15T00:00:00Z",
|
|
250
|
-
created_at: "2026-05-15T00:00:00Z",
|
|
251
|
-
status: "active",
|
|
252
|
-
},
|
|
253
|
-
gone: {
|
|
254
|
-
id: "gone",
|
|
255
|
-
last_seen_path: goneRoot,
|
|
256
|
-
last_seen_at: "2026-05-15T00:00:00Z",
|
|
257
|
-
created_at: "2026-05-15T00:00:00Z",
|
|
258
|
-
status: "active",
|
|
259
|
-
},
|
|
260
|
-
},
|
|
261
|
-
}, tmpHome);
|
|
262
|
-
// Delete the path for "gone" so it'll be flagged.
|
|
263
|
-
await fs.rm(goneRoot, { recursive: true, force: true });
|
|
264
|
-
const res = await pruneDeleted(tmpHome);
|
|
265
|
-
expect(res.swept).toBe(1);
|
|
266
|
-
expect(res.removed_ids).toEqual(["gone"]);
|
|
267
|
-
const reg = await loadRegistry(tmpHome);
|
|
268
|
-
expect(reg.projects.alive.status).toBe("active");
|
|
269
|
-
expect(reg.projects.gone.status).toBe("deleted");
|
|
270
|
-
});
|
|
271
|
-
it("does not touch already-deleted entries", async () => {
|
|
272
|
-
await saveRegistry({
|
|
273
|
-
version: 1,
|
|
274
|
-
projects: {
|
|
275
|
-
ghost: {
|
|
276
|
-
id: "ghost",
|
|
277
|
-
last_seen_path: "/nonexistent/path",
|
|
278
|
-
last_seen_at: "2026-05-15T00:00:00Z",
|
|
279
|
-
created_at: "2026-05-15T00:00:00Z",
|
|
280
|
-
status: "deleted",
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
}, tmpHome);
|
|
284
|
-
const res = await pruneDeleted(tmpHome);
|
|
285
|
-
expect(res.swept).toBe(0);
|
|
286
|
-
});
|
|
287
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loop-engine RAG backend — routes RagBackend through the engine daemon's
|
|
3
|
-
* JSON-RPC API (memory.search + memory.create) via the T.4 UDS singleton.
|
|
4
|
-
*
|
|
5
|
-
* Quality: `mode: 'hybrid'` invokes engine-side RRF fusion (K=60, Cormack
|
|
6
|
-
* et al. 2009) — drop-in equivalent to opensquid's `src/rag/rrf.ts:65`
|
|
7
|
-
* per T.1.JJ. No TS-side fusion needed; engine does it server-side over a
|
|
8
|
-
* larger native vector index than libsql's DiskANN.
|
|
9
|
-
*
|
|
10
|
-
* Critical design locks (T.1.B + T.1.#6):
|
|
11
|
-
*
|
|
12
|
-
* 1. **storeLesson → memory.create is INTENTIONAL, not a bug.** Routing
|
|
13
|
-
* here through `lesson.create` would force every recall-pool write
|
|
14
|
-
* through the wedge gate's 24h + applied_count=3 + external_signal
|
|
15
|
-
* promotion requirements (per T.1.F — unsatisfiable in a single
|
|
16
|
-
* write call, breaks unit tests). RagBackend.storeLesson semantically
|
|
17
|
-
* stores a recallable memory, NOT a wedge-gated lesson; lesson
|
|
18
|
-
* lifecycle is a separate surface added in T.6.
|
|
19
|
-
*
|
|
20
|
-
* 2. **Description synthesis is mandatory.** `memory.create` rejects
|
|
21
|
-
* empty `description` (T.1.B INVALID_PARAMS -32602). Synthesized
|
|
22
|
-
* from first sentence → first 80 chars → ultimate fallback. Lesson
|
|
23
|
-
* shape doesn't carry a description field today, so we derive it.
|
|
24
|
-
*
|
|
25
|
-
* 3. **`include_body: true` on every recall.** memory.search's default
|
|
26
|
-
* `body_preview` is truncated to 240 chars (engine serve.rs); without
|
|
27
|
-
* this flag RecallHit.lesson.content gets cut mid-sentence.
|
|
28
|
-
*
|
|
29
|
-
* 4. **Source vocab mapping at the boundary.** Engine speaks
|
|
30
|
-
* `'semantic' | 'text' | 'both'`; RagBackend's RecallHit speaks
|
|
31
|
-
* `'semantic' | 'lexical' | 'fused'`. The adapter table is the
|
|
32
|
-
* single point of translation — DO NOT leak engine vocab past it.
|
|
33
|
-
*
|
|
34
|
-
* 5. **Engine schema gap.** `memory.create` doesn't preserve tags /
|
|
35
|
-
* source / author / createdAt today (T.8 follow-up filed). For v1
|
|
36
|
-
* we send `description` + `content` only; lesson metadata round-trips
|
|
37
|
-
* via the Lesson defaults applied by `src/functions/rag.ts:122-145`.
|
|
38
|
-
*
|
|
39
|
-
* 6. **No daemon lifecycle here.** `EngineClient` connects via the T.4
|
|
40
|
-
* `acquireOrSpawnEngine()` singleton transparently — zero per-call
|
|
41
|
-
* subprocess cost, cross-session shared engine.
|
|
42
|
-
*
|
|
43
|
-
* Imports from: ../../engine/client.js, ../ollama_client.js, ../types.js.
|
|
44
|
-
* Imported by: src/rag/backend_factory.ts.
|
|
45
|
-
*/
|
|
46
|
-
import { EngineClient } from '../../engine/client.js';
|
|
47
|
-
import type { RagBackend } from '../types.js';
|
|
48
|
-
export interface LoopEngineBackendOpts {
|
|
49
|
-
/** Injected client for tests; production uses the singleton-backed default. */
|
|
50
|
-
client?: EngineClient;
|
|
51
|
-
/** Recall mode. 'hybrid' = engine semantic+text+RRF (default, matches
|
|
52
|
-
* libsql-qwen3 quality per T.1.JJ). 'semantic' = vector only. 'text' =
|
|
53
|
-
* pure text-match. */
|
|
54
|
-
mode?: 'semantic' | 'text' | 'hybrid';
|
|
55
|
-
/** Ollama URL for embed() — only used when a rule asks for a raw vector
|
|
56
|
-
* via the `embed` primitive. Engine handles embedding internally for
|
|
57
|
-
* memory.create + memory.search. */
|
|
58
|
-
ollamaUrl?: string;
|
|
59
|
-
}
|
|
60
|
-
export declare function loopEngineBackend(opts?: LoopEngineBackendOpts): RagBackend;
|
|
61
|
-
//# sourceMappingURL=loop_engine.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loop_engine.d.ts","sourceRoot":"","sources":["../../../src/rag/backends/loop_engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,EAAgB,YAAY,EAAY,MAAM,wBAAwB,CAAC;AAK9E,OAAO,KAAK,EAAwB,UAAU,EAAa,MAAM,aAAa,CAAC;AAE/E,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;2BAEuB;IACvB,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;IACtC;;yCAEqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,qBAA0B,GAAG,UAAU,CAgF9E"}
|