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/claude-md.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLAUDE.md sentinel-block management.
|
|
3
|
-
*
|
|
4
|
-
* Two managed blocks live inside `~/.claude/CLAUDE.md`:
|
|
5
|
-
*
|
|
6
|
-
* 1. `opensquid-automation:start vX.Y.Z` ... `opensquid-automation:end`
|
|
7
|
-
* — the outer behavioral instructions block, written by
|
|
8
|
-
* `opensquid install` (src/cli.ts).
|
|
9
|
-
*
|
|
10
|
-
* 2. `opensquid-rules:start (auto-managed)` ... `opensquid-rules:end`
|
|
11
|
-
* — an inner block nested INSIDE the automation block, holding
|
|
12
|
-
* one-line summaries of promoted lessons. Auto-managed at
|
|
13
|
-
* runtime: every `lesson.promote` success appends an entry here
|
|
14
|
-
* so the agent reads promoted rules at session start with no
|
|
15
|
-
* recall lag.
|
|
16
|
-
*
|
|
17
|
-
* This module exposes the runtime updater for the inner rules block.
|
|
18
|
-
* The CLAUDE.md installer / uninstaller (src/cli.ts) owns the outer
|
|
19
|
-
* block; this module ONLY touches what's between the inner sentinels.
|
|
20
|
-
*/
|
|
21
|
-
import { promises as fs } from "node:fs";
|
|
22
|
-
import * as os from "node:os";
|
|
23
|
-
import * as path from "node:path";
|
|
24
|
-
const RULES_START = "<!-- opensquid-rules:start (auto-managed) -->";
|
|
25
|
-
const RULES_END = "<!-- opensquid-rules:end -->";
|
|
26
|
-
const PLACEHOLDER = "(no promoted lessons yet";
|
|
27
|
-
/** Resolved path to the user's global CLAUDE.md. */
|
|
28
|
-
export function defaultClaudeMdPath() {
|
|
29
|
-
return path.join(os.homedir(), ".claude", "CLAUDE.md");
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Append a one-line entry for a newly promoted lesson into the
|
|
33
|
-
* CLAUDE.md rules sub-block. Idempotent — if an entry for `id` already
|
|
34
|
-
* exists, the line is left untouched. Returns the path written + the
|
|
35
|
-
* new content of the rules block (without sentinels).
|
|
36
|
-
*
|
|
37
|
-
* No-op (silent) when:
|
|
38
|
-
* - CLAUDE.md doesn't exist
|
|
39
|
-
* - The rules sub-block isn't installed yet (user hasn't run
|
|
40
|
-
* `opensquid install` against this CLAUDE.md)
|
|
41
|
-
*
|
|
42
|
-
* Failure is intentionally non-fatal: lesson promotion is the
|
|
43
|
-
* authoritative event; CLAUDE.md is downstream display. We never block
|
|
44
|
-
* the promote on a CLAUDE.md write failure.
|
|
45
|
-
*/
|
|
46
|
-
export async function appendPromotedLessonToClaudeMd(entry, options = {}) {
|
|
47
|
-
const target = options.target ?? defaultClaudeMdPath();
|
|
48
|
-
let content;
|
|
49
|
-
try {
|
|
50
|
-
content = await fs.readFile(target, "utf8");
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
const block = findRulesBlock(content);
|
|
56
|
-
if (!block)
|
|
57
|
-
return null;
|
|
58
|
-
// Idempotency: skip if this lesson id already appears in the block.
|
|
59
|
-
const idMarker = `(lesson:${entry.id})`;
|
|
60
|
-
if (block.inner.includes(idMarker)) {
|
|
61
|
-
return { target, appended: false };
|
|
62
|
-
}
|
|
63
|
-
// Strip the placeholder if it's the only thing in the block.
|
|
64
|
-
const cleaned = block.inner.includes(PLACEHOLDER) ? "" : block.inner.trimEnd();
|
|
65
|
-
const newLine = `- ${entry.description.trim()} ${idMarker} — promoted ${entry.promoted_at}`;
|
|
66
|
-
const nextInner = cleaned.length === 0 ? `\n${newLine}\n` : `${cleaned}\n${newLine}\n`;
|
|
67
|
-
const nextContent = content.slice(0, block.innerStart) + nextInner + content.slice(block.innerEnd);
|
|
68
|
-
await fs.writeFile(target, nextContent, "utf8");
|
|
69
|
-
return { target, appended: true };
|
|
70
|
-
}
|
|
71
|
-
function findRulesBlock(content) {
|
|
72
|
-
const startIdx = content.indexOf(RULES_START);
|
|
73
|
-
if (startIdx === -1)
|
|
74
|
-
return null;
|
|
75
|
-
const endIdx = content.indexOf(RULES_END, startIdx + RULES_START.length);
|
|
76
|
-
if (endIdx === -1)
|
|
77
|
-
return null;
|
|
78
|
-
// inner starts right after the start sentinel (allowing a trailing newline).
|
|
79
|
-
let innerStart = startIdx + RULES_START.length;
|
|
80
|
-
if (content[innerStart] === "\n")
|
|
81
|
-
innerStart++;
|
|
82
|
-
// inner ends at the start of the end sentinel.
|
|
83
|
-
const innerEnd = endIdx;
|
|
84
|
-
return {
|
|
85
|
-
inner: content.slice(innerStart, innerEnd),
|
|
86
|
-
innerStart,
|
|
87
|
-
innerEnd,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* For tests + diagnostics: list the lesson ids currently appearing in
|
|
92
|
-
* the rules sub-block of a given CLAUDE.md.
|
|
93
|
-
*/
|
|
94
|
-
export async function listRulesBlockLessonIds(options = {}) {
|
|
95
|
-
const target = options.target ?? defaultClaudeMdPath();
|
|
96
|
-
let content;
|
|
97
|
-
try {
|
|
98
|
-
content = await fs.readFile(target, "utf8");
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
const block = findRulesBlock(content);
|
|
104
|
-
if (!block)
|
|
105
|
-
return [];
|
|
106
|
-
const ids = [];
|
|
107
|
-
const re = /\(lesson:([a-z0-9-]+)\)/g;
|
|
108
|
-
for (const m of block.inner.matchAll(re)) {
|
|
109
|
-
ids.push(m[1]);
|
|
110
|
-
}
|
|
111
|
-
return ids;
|
|
112
|
-
}
|
|
113
|
-
//# sourceMappingURL=claude-md.js.map
|
package/dist/claude-md.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"claude-md.js","sourceRoot":"","sources":["../src.legacy/claude-md.ts"],"names":[],"mappings":"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"}
|
package/dist/claude-md.test.js
DELETED
|
@@ -1,91 +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 { appendPromotedLessonToClaudeMd, listRulesBlockLessonIds } from "./claude-md.js";
|
|
7
|
-
let tmpFile;
|
|
8
|
-
beforeEach(async () => {
|
|
9
|
-
tmpFile = path.join(os.tmpdir(), `oscli-claude-md-${crypto.randomUUID()}.md`);
|
|
10
|
-
});
|
|
11
|
-
afterEach(async () => {
|
|
12
|
-
await fs.rm(tmpFile, { force: true });
|
|
13
|
-
});
|
|
14
|
-
const INSTALLED_BLOCK = `<!-- opensquid-automation:start v0.4.0 -->
|
|
15
|
-
## opensquid
|
|
16
|
-
|
|
17
|
-
Use recall before substantive answers.
|
|
18
|
-
|
|
19
|
-
### Active lessons (auto-managed — do not edit by hand)
|
|
20
|
-
|
|
21
|
-
<!-- opensquid-rules:start (auto-managed) -->
|
|
22
|
-
(no promoted lessons yet — this block populates as \`lesson.promote\`
|
|
23
|
-
succeeds for user-endorsed candidates)
|
|
24
|
-
<!-- opensquid-rules:end -->
|
|
25
|
-
<!-- opensquid-automation:end -->
|
|
26
|
-
`;
|
|
27
|
-
describe("appendPromotedLessonToClaudeMd", () => {
|
|
28
|
-
it("returns null when CLAUDE.md doesn't exist", async () => {
|
|
29
|
-
const res = await appendPromotedLessonToClaudeMd({ id: "les-x", description: "anything", promoted_at: "2026-05-15T00:00:00Z" }, { target: tmpFile });
|
|
30
|
-
expect(res).toBeNull();
|
|
31
|
-
});
|
|
32
|
-
it("returns null when the rules block isn't installed", async () => {
|
|
33
|
-
await fs.writeFile(tmpFile, "# Just a regular CLAUDE.md\nNothing fancy.\n", "utf8");
|
|
34
|
-
const res = await appendPromotedLessonToClaudeMd({ id: "les-x", description: "anything", promoted_at: "now" }, { target: tmpFile });
|
|
35
|
-
expect(res).toBeNull();
|
|
36
|
-
});
|
|
37
|
-
it("replaces the placeholder with the first promoted lesson", async () => {
|
|
38
|
-
await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
|
|
39
|
-
const res = await appendPromotedLessonToClaudeMd({
|
|
40
|
-
id: "les-abc12345",
|
|
41
|
-
description: "before any git push or release",
|
|
42
|
-
promoted_at: "2026-05-15T19:00:00Z",
|
|
43
|
-
}, { target: tmpFile });
|
|
44
|
-
expect(res?.appended).toBe(true);
|
|
45
|
-
const content = await fs.readFile(tmpFile, "utf8");
|
|
46
|
-
expect(content).not.toContain("(no promoted lessons yet");
|
|
47
|
-
expect(content).toContain("(lesson:les-abc12345)");
|
|
48
|
-
expect(content).toContain("before any git push or release");
|
|
49
|
-
expect(content).toContain("promoted 2026-05-15T19:00:00Z");
|
|
50
|
-
});
|
|
51
|
-
it("appends subsequent lessons without removing prior ones", async () => {
|
|
52
|
-
await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
|
|
53
|
-
await appendPromotedLessonToClaudeMd({ id: "les-1", description: "first rule", promoted_at: "2026-05-15T19:00:00Z" }, { target: tmpFile });
|
|
54
|
-
await appendPromotedLessonToClaudeMd({ id: "les-2", description: "second rule", promoted_at: "2026-05-15T19:01:00Z" }, { target: tmpFile });
|
|
55
|
-
const content = await fs.readFile(tmpFile, "utf8");
|
|
56
|
-
expect(content).toContain("(lesson:les-1)");
|
|
57
|
-
expect(content).toContain("(lesson:les-2)");
|
|
58
|
-
expect(content).toContain("first rule");
|
|
59
|
-
expect(content).toContain("second rule");
|
|
60
|
-
});
|
|
61
|
-
it("is idempotent — re-promoting the same id is a no-op", async () => {
|
|
62
|
-
await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
|
|
63
|
-
await appendPromotedLessonToClaudeMd({ id: "les-1", description: "rule one", promoted_at: "2026-05-15T19:00:00Z" }, { target: tmpFile });
|
|
64
|
-
const before = await fs.readFile(tmpFile, "utf8");
|
|
65
|
-
const res = await appendPromotedLessonToClaudeMd({ id: "les-1", description: "rule one", promoted_at: "2026-05-15T19:30:00Z" }, { target: tmpFile });
|
|
66
|
-
expect(res?.appended).toBe(false);
|
|
67
|
-
const after = await fs.readFile(tmpFile, "utf8");
|
|
68
|
-
expect(after).toBe(before);
|
|
69
|
-
});
|
|
70
|
-
it("preserves the outer automation block sentinels", async () => {
|
|
71
|
-
await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
|
|
72
|
-
await appendPromotedLessonToClaudeMd({ id: "les-x", description: "anything", promoted_at: "2026-05-15T00:00:00Z" }, { target: tmpFile });
|
|
73
|
-
const content = await fs.readFile(tmpFile, "utf8");
|
|
74
|
-
expect(content).toContain("<!-- opensquid-automation:start v0.4.0 -->");
|
|
75
|
-
expect(content).toContain("<!-- opensquid-automation:end -->");
|
|
76
|
-
expect(content).toContain("<!-- opensquid-rules:start (auto-managed) -->");
|
|
77
|
-
expect(content).toContain("<!-- opensquid-rules:end -->");
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
describe("listRulesBlockLessonIds", () => {
|
|
81
|
-
it("returns [] when no rules block", async () => {
|
|
82
|
-
await fs.writeFile(tmpFile, "# plain\n", "utf8");
|
|
83
|
-
expect(await listRulesBlockLessonIds({ target: tmpFile })).toEqual([]);
|
|
84
|
-
});
|
|
85
|
-
it("returns ids in append order", async () => {
|
|
86
|
-
await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
|
|
87
|
-
await appendPromotedLessonToClaudeMd({ id: "les-aaa", description: "a", promoted_at: "t1" }, { target: tmpFile });
|
|
88
|
-
await appendPromotedLessonToClaudeMd({ id: "les-bbb", description: "b", promoted_at: "t2" }, { target: tmpFile });
|
|
89
|
-
expect(await listRulesBlockLessonIds({ target: tmpFile })).toEqual(["les-aaa", "les-bbb"]);
|
|
90
|
-
});
|
|
91
|
-
});
|
package/dist/codex/activate.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Codex activation evaluation — decide whether a codex's `detected_by`
|
|
3
|
-
* matches the current project context (typically `process.cwd()`).
|
|
4
|
-
*
|
|
5
|
-
* Used by the recall handler to filter out lessons from codexes that
|
|
6
|
-
* don't apply to the active project. Without this, recall would
|
|
7
|
-
* surface React-specific lessons inside a Rust project (cross-codex
|
|
8
|
-
* contamination).
|
|
9
|
-
*
|
|
10
|
-
* Coverage:
|
|
11
|
-
* - file_exists / dir_exists / file_match / file_glob → filesystem-evaluated
|
|
12
|
-
* - user_pinned → always true (codex was explicitly installed)
|
|
13
|
-
* - all_of / any_of → recursive combinators
|
|
14
|
-
* - memory_match / conversation_signal → default true (need runtime
|
|
15
|
-
* context the recall handler doesn't carry; orchestrator (O3) is
|
|
16
|
-
* the proper place for these)
|
|
17
|
-
*/
|
|
18
|
-
import type { Codex, CodexDetection } from "./types.js";
|
|
19
|
-
/**
|
|
20
|
-
* Evaluate a codex's activation against a project context.
|
|
21
|
-
*
|
|
22
|
-
* - Composite codexes are not directly activatable; treat as inactive
|
|
23
|
-
* here (their `includes` activate independently via their own
|
|
24
|
-
* `detected_by`).
|
|
25
|
-
* - Focused codex with no `detected_by`: defaults to active (the codex
|
|
26
|
-
* author wanted always-on).
|
|
27
|
-
* - `activation_scope: user` + `user_pinned`: always active.
|
|
28
|
-
* - Otherwise: evaluate the `detected_by` list (any-of semantics —
|
|
29
|
-
* matching ANY listed signal activates).
|
|
30
|
-
*/
|
|
31
|
-
export declare function isCodexActive(codex: Codex, cwd: string): Promise<boolean>;
|
|
32
|
-
/**
|
|
33
|
-
* Evaluate a single detection signal against a project context.
|
|
34
|
-
*
|
|
35
|
-
* Returns false on unknown kinds (forward-compat — future engine
|
|
36
|
-
* versions could add detection kinds opensquid doesn't recognize yet;
|
|
37
|
-
* fail closed rather than over-activate).
|
|
38
|
-
*/
|
|
39
|
-
export declare function evaluateDetection(detection: CodexDetection, cwd: string): Promise<boolean>;
|
|
40
|
-
/**
|
|
41
|
-
* Caches codex activation decisions for one project context.
|
|
42
|
-
*
|
|
43
|
-
* Reuse across multiple recall calls in the same session — avoids
|
|
44
|
-
* re-reading codex.yaml files on every recall. Per-cwd because the
|
|
45
|
-
* answer depends on the project being worked in.
|
|
46
|
-
*/
|
|
47
|
-
export declare class CodexActivationCache {
|
|
48
|
-
private readonly cwd;
|
|
49
|
-
private readonly rootDir?;
|
|
50
|
-
private decisions;
|
|
51
|
-
constructor(cwd: string, rootDir?: string | undefined);
|
|
52
|
-
/** Returns true iff the codex's `detected_by` matches this cwd. */
|
|
53
|
-
isActive(codexId: string): Promise<boolean>;
|
|
54
|
-
private evaluate;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Extract the codex id from a lesson description.
|
|
58
|
-
*
|
|
59
|
-
* opensquid's codex CLI seeds lessons with descriptions like:
|
|
60
|
-
* "before any git push or release (codex:loop-engineering-workflow)"
|
|
61
|
-
*
|
|
62
|
-
* Returns null for lessons not seeded from a codex (the pre-codex
|
|
63
|
-
* lessons created by `lesson.create` without `pack_id`).
|
|
64
|
-
*/
|
|
65
|
-
export declare function extractCodexId(description: string): string | null;
|
|
66
|
-
//# sourceMappingURL=activate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"activate.d.ts","sourceRoot":"","sources":["../../src.legacy/codex/activate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAgB,MAAM,YAAY,CAAC;AAOtE;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI/E;AAYD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAuChG;AAMD;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAJ3B,OAAO,CAAC,SAAS,CAAuC;gBAGrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,YAAA;IAGnC,mEAAmE;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YASnC,QAAQ;CAWvB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjE"}
|
package/dist/codex/activate.js
DELETED
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Codex activation evaluation — decide whether a codex's `detected_by`
|
|
3
|
-
* matches the current project context (typically `process.cwd()`).
|
|
4
|
-
*
|
|
5
|
-
* Used by the recall handler to filter out lessons from codexes that
|
|
6
|
-
* don't apply to the active project. Without this, recall would
|
|
7
|
-
* surface React-specific lessons inside a Rust project (cross-codex
|
|
8
|
-
* contamination).
|
|
9
|
-
*
|
|
10
|
-
* Coverage:
|
|
11
|
-
* - file_exists / dir_exists / file_match / file_glob → filesystem-evaluated
|
|
12
|
-
* - user_pinned → always true (codex was explicitly installed)
|
|
13
|
-
* - all_of / any_of → recursive combinators
|
|
14
|
-
* - memory_match / conversation_signal → default true (need runtime
|
|
15
|
-
* context the recall handler doesn't carry; orchestrator (O3) is
|
|
16
|
-
* the proper place for these)
|
|
17
|
-
*/
|
|
18
|
-
import { promises as fs } from "node:fs";
|
|
19
|
-
import * as path from "node:path";
|
|
20
|
-
import { getCodex } from "./store.js";
|
|
21
|
-
import { isCompositeCodex, isFocusedCodex } from "./types.js";
|
|
22
|
-
// ---------------------------------------------------------------------
|
|
23
|
-
// Public API
|
|
24
|
-
// ---------------------------------------------------------------------
|
|
25
|
-
/**
|
|
26
|
-
* Evaluate a codex's activation against a project context.
|
|
27
|
-
*
|
|
28
|
-
* - Composite codexes are not directly activatable; treat as inactive
|
|
29
|
-
* here (their `includes` activate independently via their own
|
|
30
|
-
* `detected_by`).
|
|
31
|
-
* - Focused codex with no `detected_by`: defaults to active (the codex
|
|
32
|
-
* author wanted always-on).
|
|
33
|
-
* - `activation_scope: user` + `user_pinned`: always active.
|
|
34
|
-
* - Otherwise: evaluate the `detected_by` list (any-of semantics —
|
|
35
|
-
* matching ANY listed signal activates).
|
|
36
|
-
*/
|
|
37
|
-
export async function isCodexActive(codex, cwd) {
|
|
38
|
-
if (isCompositeCodex(codex))
|
|
39
|
-
return false;
|
|
40
|
-
if (!isFocusedCodex(codex))
|
|
41
|
-
return false;
|
|
42
|
-
return isFocusedCodexActive(codex, cwd);
|
|
43
|
-
}
|
|
44
|
-
async function isFocusedCodexActive(codex, cwd) {
|
|
45
|
-
// No detection signals declared → activate (author wanted always-on).
|
|
46
|
-
if (!codex.detected_by || codex.detected_by.length === 0)
|
|
47
|
-
return true;
|
|
48
|
-
// Top-level list = OR — any matching signal activates.
|
|
49
|
-
for (const detection of codex.detected_by) {
|
|
50
|
-
if (await evaluateDetection(detection, cwd))
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Evaluate a single detection signal against a project context.
|
|
57
|
-
*
|
|
58
|
-
* Returns false on unknown kinds (forward-compat — future engine
|
|
59
|
-
* versions could add detection kinds opensquid doesn't recognize yet;
|
|
60
|
-
* fail closed rather than over-activate).
|
|
61
|
-
*/
|
|
62
|
-
export async function evaluateDetection(detection, cwd) {
|
|
63
|
-
switch (detection.kind) {
|
|
64
|
-
case "user_pinned":
|
|
65
|
-
return true;
|
|
66
|
-
case "file_exists":
|
|
67
|
-
return fileExistsAt(path.resolve(cwd, detection.path));
|
|
68
|
-
case "dir_exists":
|
|
69
|
-
return dirExistsAt(path.resolve(cwd, detection.path));
|
|
70
|
-
case "file_match":
|
|
71
|
-
return fileMatches(path.resolve(cwd, detection.path), detection.matches);
|
|
72
|
-
case "file_glob":
|
|
73
|
-
return globAtLeast(cwd, detection.pattern, detection.min_count ?? 1);
|
|
74
|
-
case "all_of": {
|
|
75
|
-
for (const c of detection.conditions) {
|
|
76
|
-
if (!(await evaluateDetection(c, cwd)))
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
81
|
-
case "any_of": {
|
|
82
|
-
for (const c of detection.conditions) {
|
|
83
|
-
if (await evaluateDetection(c, cwd))
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
case "memory_match":
|
|
89
|
-
case "conversation_signal":
|
|
90
|
-
// These need runtime context the recall handler doesn't carry.
|
|
91
|
-
// Defaulting to true is the conservative choice: don't filter
|
|
92
|
-
// lessons out solely because we can't evaluate these signals here.
|
|
93
|
-
// Orchestrator (O3) will evaluate them properly.
|
|
94
|
-
return true;
|
|
95
|
-
default: {
|
|
96
|
-
// Forward-compat: unknown kinds → fail closed.
|
|
97
|
-
// Exhaustiveness check at compile time via the `never` cast.
|
|
98
|
-
const _exhaustive = detection;
|
|
99
|
-
void _exhaustive;
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
// ---------------------------------------------------------------------
|
|
105
|
-
// Activation cache (per-cwd, per-recall-handler-session)
|
|
106
|
-
// ---------------------------------------------------------------------
|
|
107
|
-
/**
|
|
108
|
-
* Caches codex activation decisions for one project context.
|
|
109
|
-
*
|
|
110
|
-
* Reuse across multiple recall calls in the same session — avoids
|
|
111
|
-
* re-reading codex.yaml files on every recall. Per-cwd because the
|
|
112
|
-
* answer depends on the project being worked in.
|
|
113
|
-
*/
|
|
114
|
-
export class CodexActivationCache {
|
|
115
|
-
cwd;
|
|
116
|
-
rootDir;
|
|
117
|
-
decisions = new Map();
|
|
118
|
-
constructor(cwd, rootDir) {
|
|
119
|
-
this.cwd = cwd;
|
|
120
|
-
this.rootDir = rootDir;
|
|
121
|
-
}
|
|
122
|
-
/** Returns true iff the codex's `detected_by` matches this cwd. */
|
|
123
|
-
async isActive(codexId) {
|
|
124
|
-
let pending = this.decisions.get(codexId);
|
|
125
|
-
if (!pending) {
|
|
126
|
-
pending = this.evaluate(codexId);
|
|
127
|
-
this.decisions.set(codexId, pending);
|
|
128
|
-
}
|
|
129
|
-
return pending;
|
|
130
|
-
}
|
|
131
|
-
async evaluate(codexId) {
|
|
132
|
-
try {
|
|
133
|
-
const codex = await getCodex(codexId, { rootDir: this.rootDir });
|
|
134
|
-
return isCodexActive(codex, this.cwd);
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
// Missing or malformed codex → treat as inactive. Lessons from
|
|
138
|
-
// an uninstalled codex shouldn't surface even if they're still
|
|
139
|
-
// in the lesson store (stale state).
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// ---------------------------------------------------------------------
|
|
145
|
-
// Lesson → codex id extraction
|
|
146
|
-
// ---------------------------------------------------------------------
|
|
147
|
-
/**
|
|
148
|
-
* Extract the codex id from a lesson description.
|
|
149
|
-
*
|
|
150
|
-
* opensquid's codex CLI seeds lessons with descriptions like:
|
|
151
|
-
* "before any git push or release (codex:loop-engineering-workflow)"
|
|
152
|
-
*
|
|
153
|
-
* Returns null for lessons not seeded from a codex (the pre-codex
|
|
154
|
-
* lessons created by `lesson.create` without `pack_id`).
|
|
155
|
-
*/
|
|
156
|
-
export function extractCodexId(description) {
|
|
157
|
-
const m = description.match(/\(codex:([a-z0-9][a-z0-9._-]{0,127})\)\s*$/);
|
|
158
|
-
return m ? m[1] : null;
|
|
159
|
-
}
|
|
160
|
-
// ---------------------------------------------------------------------
|
|
161
|
-
// Filesystem primitives
|
|
162
|
-
// ---------------------------------------------------------------------
|
|
163
|
-
async function fileExistsAt(p) {
|
|
164
|
-
try {
|
|
165
|
-
const stat = await fs.stat(p);
|
|
166
|
-
return stat.isFile();
|
|
167
|
-
}
|
|
168
|
-
catch {
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
async function dirExistsAt(p) {
|
|
173
|
-
try {
|
|
174
|
-
const stat = await fs.stat(p);
|
|
175
|
-
return stat.isDirectory();
|
|
176
|
-
}
|
|
177
|
-
catch {
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
async function fileMatches(filePath, matches) {
|
|
182
|
-
let content;
|
|
183
|
-
try {
|
|
184
|
-
content = await fs.readFile(filePath, "utf8");
|
|
185
|
-
}
|
|
186
|
-
catch {
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
// Try JSON first (the most common manifest format). Fall back to
|
|
190
|
-
// tolerant key-presence check for non-JSON files.
|
|
191
|
-
let parsed;
|
|
192
|
-
try {
|
|
193
|
-
parsed = JSON.parse(content);
|
|
194
|
-
}
|
|
195
|
-
catch {
|
|
196
|
-
// Non-JSON: do a substring check on the dotted-path key. Coarse
|
|
197
|
-
// but correct for the "contains" use case.
|
|
198
|
-
for (const key of Object.keys(matches)) {
|
|
199
|
-
if (!content.includes(key))
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
return true;
|
|
203
|
-
}
|
|
204
|
-
for (const [keyPath, _expected] of Object.entries(matches)) {
|
|
205
|
-
const value = walkPath(parsed, keyPath);
|
|
206
|
-
// MVP semantics: a key being PRESENT (truthy + non-null) at the
|
|
207
|
-
// path means "match." Full semver-range matching is future work;
|
|
208
|
-
// for activation gating, key-presence is sufficient — a project
|
|
209
|
-
// with `dependencies.react` defined IS a React project.
|
|
210
|
-
if (value === undefined || value === null || value === "")
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
return true;
|
|
214
|
-
}
|
|
215
|
-
function walkPath(obj, dottedPath) {
|
|
216
|
-
const parts = dottedPath.split(".");
|
|
217
|
-
let cur = obj;
|
|
218
|
-
for (const part of parts) {
|
|
219
|
-
if (cur === null || cur === undefined)
|
|
220
|
-
return undefined;
|
|
221
|
-
if (typeof cur !== "object")
|
|
222
|
-
return undefined;
|
|
223
|
-
cur = cur[part];
|
|
224
|
-
}
|
|
225
|
-
return cur;
|
|
226
|
-
}
|
|
227
|
-
async function globAtLeast(cwd, pattern, minCount) {
|
|
228
|
-
// Lightweight glob — supports `**/*.ext` and `dir/**/*.{a,b}` patterns.
|
|
229
|
-
// Avoids pulling in a full glob dependency for one detection kind.
|
|
230
|
-
const matches = await collectGlobMatches(cwd, pattern);
|
|
231
|
-
return matches.length >= minCount;
|
|
232
|
-
}
|
|
233
|
-
async function collectGlobMatches(cwd, pattern) {
|
|
234
|
-
// Split into a fixed-prefix and the matchable tail. Walk only what
|
|
235
|
-
// the tail says.
|
|
236
|
-
const segments = pattern.split("/");
|
|
237
|
-
let prefix = cwd;
|
|
238
|
-
let firstWildcard = -1;
|
|
239
|
-
for (let i = 0; i < segments.length; i++) {
|
|
240
|
-
if (segments[i].includes("*")) {
|
|
241
|
-
firstWildcard = i;
|
|
242
|
-
break;
|
|
243
|
-
}
|
|
244
|
-
prefix = path.join(prefix, segments[i]);
|
|
245
|
-
}
|
|
246
|
-
if (firstWildcard === -1) {
|
|
247
|
-
// No wildcards — the pattern is literal; check existence directly.
|
|
248
|
-
try {
|
|
249
|
-
await fs.access(prefix);
|
|
250
|
-
return [prefix];
|
|
251
|
-
}
|
|
252
|
-
catch {
|
|
253
|
-
return [];
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
const tail = segments.slice(firstWildcard).join("/");
|
|
257
|
-
const fileRegex = globTailToRegex(tail);
|
|
258
|
-
const results = [];
|
|
259
|
-
await walkDir(prefix, "", fileRegex, results);
|
|
260
|
-
return results;
|
|
261
|
-
}
|
|
262
|
-
async function walkDir(rootAbs, relPath, fileRegex, out) {
|
|
263
|
-
let entries;
|
|
264
|
-
try {
|
|
265
|
-
entries = await fs.readdir(path.join(rootAbs, relPath), {
|
|
266
|
-
withFileTypes: true,
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
catch {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
for (const entry of entries) {
|
|
273
|
-
const childRel = relPath ? `${relPath}/${entry.name}` : entry.name;
|
|
274
|
-
if (entry.isDirectory()) {
|
|
275
|
-
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
276
|
-
continue;
|
|
277
|
-
await walkDir(rootAbs, childRel, fileRegex, out);
|
|
278
|
-
}
|
|
279
|
-
else if (entry.isFile() && fileRegex.test(childRel)) {
|
|
280
|
-
out.push(path.join(rootAbs, childRel));
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
function globTailToRegex(tail) {
|
|
285
|
-
// Translate a glob tail (supports `**`, `*`, `{a,b}`) into a regex.
|
|
286
|
-
let re = "";
|
|
287
|
-
let i = 0;
|
|
288
|
-
while (i < tail.length) {
|
|
289
|
-
const c = tail[i];
|
|
290
|
-
if (c === "*" && tail[i + 1] === "*") {
|
|
291
|
-
re += ".*";
|
|
292
|
-
i += 2;
|
|
293
|
-
if (tail[i] === "/")
|
|
294
|
-
i++;
|
|
295
|
-
}
|
|
296
|
-
else if (c === "*") {
|
|
297
|
-
re += "[^/]*";
|
|
298
|
-
i++;
|
|
299
|
-
}
|
|
300
|
-
else if (c === "?") {
|
|
301
|
-
re += "[^/]";
|
|
302
|
-
i++;
|
|
303
|
-
}
|
|
304
|
-
else if (c === "{") {
|
|
305
|
-
const end = tail.indexOf("}", i);
|
|
306
|
-
if (end === -1) {
|
|
307
|
-
re += "\\{";
|
|
308
|
-
i++;
|
|
309
|
-
continue;
|
|
310
|
-
}
|
|
311
|
-
const opts = tail.slice(i + 1, end).split(",");
|
|
312
|
-
re += `(?:${opts.map(escapeRegexLiteral).join("|")})`;
|
|
313
|
-
i = end + 1;
|
|
314
|
-
}
|
|
315
|
-
else if (".+^$()|\\".includes(c)) {
|
|
316
|
-
re += "\\" + c;
|
|
317
|
-
i++;
|
|
318
|
-
}
|
|
319
|
-
else {
|
|
320
|
-
re += c;
|
|
321
|
-
i++;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
return new RegExp(`^${re}$`);
|
|
325
|
-
}
|
|
326
|
-
function escapeRegexLiteral(s) {
|
|
327
|
-
return s.replace(/[.+*?^$()|[\]\\{}]/g, "\\$&");
|
|
328
|
-
}
|
|
329
|
-
//# sourceMappingURL=activate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"activate.js","sourceRoot":"","sources":["../../src.legacy/codex/activate.ts"],"names":[],"mappings":"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"}
|