opensquid 0.5.441 → 0.5.449
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/functions/recall_pre_inject.d.ts.map +1 -1
- package/dist/functions/recall_pre_inject.js +12 -0
- package/dist/functions/recall_pre_inject.js.map +1 -1
- package/dist/rag/store_git.d.ts +23 -0
- package/dist/rag/store_git.d.ts.map +1 -0
- package/dist/rag/store_git.js +57 -0
- package/dist/rag/store_git.js.map +1 -0
- 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-end.js +11 -0
- package/dist/runtime/hooks/session-end.js.map +1 -1
- 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/docs/pack-runtime.md +15 -12
- package/docs/skill-grammar-guide.md +4 -4
- 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
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflow gate — engine-backed commit-blocking check (v0.6.1).
|
|
3
|
-
*
|
|
4
|
-
* Wired into the PreToolUse hook when the planned tool call is
|
|
5
|
-
* `git commit` (without `--amend`). Checks that the active task's
|
|
6
|
-
* phase ledger has the required workflow phases logged; blocks the
|
|
7
|
-
* commit with an actionable stderr message if not.
|
|
8
|
-
*
|
|
9
|
-
* The required-phase policy is fixed for now (per user direction):
|
|
10
|
-
* `audit` + `post_research` must be logged. These are the phases
|
|
11
|
-
* empirically skipped under "ship fast" pressure. The other phases
|
|
12
|
-
* (pre_research, learn, code, test, fix) are either obvious from the
|
|
13
|
-
* commit itself or naturally happen — gating them too creates
|
|
14
|
-
* paperwork friction without catching real drift.
|
|
15
|
-
*
|
|
16
|
-
* Fail-open invariant: any error reaching the engine, parsing the
|
|
17
|
-
* transcript, or detecting the active task → return non-blocking
|
|
18
|
-
* with a stderr warning. The gate is best-effort drift protection,
|
|
19
|
-
* not a hard safety wall (mirrors the honesty-ledger precedent at
|
|
20
|
-
* pre-tool-use.ts).
|
|
21
|
-
*/
|
|
22
|
-
/**
|
|
23
|
-
* Resolve the set of phases that must be logged before `git commit`
|
|
24
|
-
* is allowed.
|
|
25
|
-
*
|
|
26
|
-
* 0.7.16 (drift-as-codex chunk 3a): the required-phase list now comes
|
|
27
|
-
* from `bundled-default/codex.yaml`'s `default_workflow_id` workflow,
|
|
28
|
-
* filtered to phases with `required: true`. Previously this was a
|
|
29
|
-
* hard-coded `REQUIRED_PHASES` array; the codex is now the single
|
|
30
|
-
* source of truth, which is what drift-as-codex was for.
|
|
31
|
-
*
|
|
32
|
-
* Fail-open: if the codex can't be loaded (missing file, parse error,
|
|
33
|
-
* missing workflow id), the gate disables itself with a stderr
|
|
34
|
-
* warning rather than blocking every commit. The codex is bundled
|
|
35
|
-
* in the npm package so this should be unreachable in normal use.
|
|
36
|
-
*/
|
|
37
|
-
export declare function getRequiredPhasesFromCodex(): readonly string[];
|
|
38
|
-
export interface WorkflowGateInput {
|
|
39
|
-
/** Path to the session's JSONL transcript. Optional — gate falls
|
|
40
|
-
* back to allow-commit when absent (can't detect active task). */
|
|
41
|
-
transcriptPath?: string;
|
|
42
|
-
}
|
|
43
|
-
export interface WorkflowGateResult {
|
|
44
|
-
/** True when the commit should be blocked. */
|
|
45
|
-
block: boolean;
|
|
46
|
-
/** Stderr message (always present when stderr should be written;
|
|
47
|
-
* non-blocking warnings also use this). */
|
|
48
|
-
stderr: string;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Evaluate whether the planned `git commit` should be blocked.
|
|
52
|
-
* Pure function over its inputs + an engine RPC; safe to call from
|
|
53
|
-
* the hook handler.
|
|
54
|
-
*/
|
|
55
|
-
export declare function evaluateWorkflowGate(input: WorkflowGateInput): Promise<WorkflowGateResult>;
|
|
56
|
-
/**
|
|
57
|
-
* Emergency-override env var. Lets the user bypass the gate when they
|
|
58
|
-
* know what they're doing. Logged loudly to stderr so the bypass is
|
|
59
|
-
* always visible in scrollback / CI logs.
|
|
60
|
-
*
|
|
61
|
-
* Exported for the test suite.
|
|
62
|
-
*/
|
|
63
|
-
export declare function checkOverrideEnv(): boolean;
|
|
64
|
-
//# sourceMappingURL=workflow-gate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-gate.d.ts","sourceRoot":"","sources":["../../src.legacy/hooks/workflow-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,IAAI,SAAS,MAAM,EAAE,CAW9D;AAED,MAAM,WAAW,iBAAiB;IAChC;sEACkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,KAAK,EAAE,OAAO,CAAC;IACf;+CAC2C;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4EhG;AAiBD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflow gate — engine-backed commit-blocking check (v0.6.1).
|
|
3
|
-
*
|
|
4
|
-
* Wired into the PreToolUse hook when the planned tool call is
|
|
5
|
-
* `git commit` (without `--amend`). Checks that the active task's
|
|
6
|
-
* phase ledger has the required workflow phases logged; blocks the
|
|
7
|
-
* commit with an actionable stderr message if not.
|
|
8
|
-
*
|
|
9
|
-
* The required-phase policy is fixed for now (per user direction):
|
|
10
|
-
* `audit` + `post_research` must be logged. These are the phases
|
|
11
|
-
* empirically skipped under "ship fast" pressure. The other phases
|
|
12
|
-
* (pre_research, learn, code, test, fix) are either obvious from the
|
|
13
|
-
* commit itself or naturally happen — gating them too creates
|
|
14
|
-
* paperwork friction without catching real drift.
|
|
15
|
-
*
|
|
16
|
-
* Fail-open invariant: any error reaching the engine, parsing the
|
|
17
|
-
* transcript, or detecting the active task → return non-blocking
|
|
18
|
-
* with a stderr warning. The gate is best-effort drift protection,
|
|
19
|
-
* not a hard safety wall (mirrors the honesty-ledger precedent at
|
|
20
|
-
* pre-tool-use.ts).
|
|
21
|
-
*/
|
|
22
|
-
import { loadBundledDefaultCodex } from "../codex/loader.js";
|
|
23
|
-
import { OpenSquidEngine } from "../engine-client.js";
|
|
24
|
-
import { readActiveTaskId } from "./transcript.js";
|
|
25
|
-
/**
|
|
26
|
-
* Resolve the set of phases that must be logged before `git commit`
|
|
27
|
-
* is allowed.
|
|
28
|
-
*
|
|
29
|
-
* 0.7.16 (drift-as-codex chunk 3a): the required-phase list now comes
|
|
30
|
-
* from `bundled-default/codex.yaml`'s `default_workflow_id` workflow,
|
|
31
|
-
* filtered to phases with `required: true`. Previously this was a
|
|
32
|
-
* hard-coded `REQUIRED_PHASES` array; the codex is now the single
|
|
33
|
-
* source of truth, which is what drift-as-codex was for.
|
|
34
|
-
*
|
|
35
|
-
* Fail-open: if the codex can't be loaded (missing file, parse error,
|
|
36
|
-
* missing workflow id), the gate disables itself with a stderr
|
|
37
|
-
* warning rather than blocking every commit. The codex is bundled
|
|
38
|
-
* in the npm package so this should be unreachable in normal use.
|
|
39
|
-
*/
|
|
40
|
-
export function getRequiredPhasesFromCodex() {
|
|
41
|
-
const codex = loadBundledDefaultCodex();
|
|
42
|
-
const workflowId = codex.default_workflow_id;
|
|
43
|
-
if (!workflowId) {
|
|
44
|
-
throw new Error("bundled-default codex has no default_workflow_id");
|
|
45
|
-
}
|
|
46
|
-
const workflow = (codex.workflows ?? []).find((w) => w.id === workflowId);
|
|
47
|
-
if (!workflow) {
|
|
48
|
-
throw new Error(`bundled-default codex has no workflow with id=${workflowId}`);
|
|
49
|
-
}
|
|
50
|
-
return workflow.phases.filter((p) => p.required).map((p) => p.name);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Evaluate whether the planned `git commit` should be blocked.
|
|
54
|
-
* Pure function over its inputs + an engine RPC; safe to call from
|
|
55
|
-
* the hook handler.
|
|
56
|
-
*/
|
|
57
|
-
export async function evaluateWorkflowGate(input) {
|
|
58
|
-
// Emergency override — explicit env var bypass with loud warning.
|
|
59
|
-
if (checkOverrideEnv()) {
|
|
60
|
-
return {
|
|
61
|
-
block: false,
|
|
62
|
-
stderr: "🦑 [opensquid workflow-gate] BYPASSED via OPENSQUID_SKIP_WORKFLOW_GATE=1\n",
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
if (!input.transcriptPath) {
|
|
66
|
-
// Can't detect active task. Allow with a debug-level warn so the
|
|
67
|
-
// gate's absence is observable.
|
|
68
|
-
return {
|
|
69
|
-
block: false,
|
|
70
|
-
stderr: "[opensquid workflow-gate] no transcript_path — gate skipped\n",
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
let taskId = null;
|
|
74
|
-
try {
|
|
75
|
-
taskId = await readActiveTaskId(input.transcriptPath);
|
|
76
|
-
}
|
|
77
|
-
catch (err) {
|
|
78
|
-
return {
|
|
79
|
-
block: false,
|
|
80
|
-
stderr: `[opensquid workflow-gate] transcript read failed (proceeding): ${err instanceof Error ? err.message : err}\n`,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
if (!taskId) {
|
|
84
|
-
// No active task — nothing to gate. Common case: ad-hoc commits
|
|
85
|
-
// outside any TaskCreate flow. Allow silently.
|
|
86
|
-
return { block: false, stderr: "" };
|
|
87
|
-
}
|
|
88
|
-
let requiredPhases;
|
|
89
|
-
try {
|
|
90
|
-
requiredPhases = getRequiredPhasesFromCodex();
|
|
91
|
-
}
|
|
92
|
-
catch (err) {
|
|
93
|
-
// Codex unloadable (missing bundled YAML, parse error, etc.).
|
|
94
|
-
// Fail-open consistent with the gate's other failure modes.
|
|
95
|
-
return {
|
|
96
|
-
block: false,
|
|
97
|
-
stderr: `[opensquid workflow-gate] codex unloadable (proceeding): ${err instanceof Error ? err.message : err}\n`,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
const engine = new OpenSquidEngine();
|
|
101
|
-
let ledger = null;
|
|
102
|
-
try {
|
|
103
|
-
ledger = await engine.getTaskLedger({
|
|
104
|
-
task_id: taskId,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
catch (err) {
|
|
108
|
-
// Engine unreachable, binary missing, RPC error. Fail-open.
|
|
109
|
-
return {
|
|
110
|
-
block: false,
|
|
111
|
-
stderr: `[opensquid workflow-gate] engine unreachable (proceeding): ${err instanceof Error ? err.message : err}\n`,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
finally {
|
|
115
|
-
// The OpenSquidEngine wrapper spawns a subprocess; shut it down
|
|
116
|
-
// so the hook process can exit cleanly.
|
|
117
|
-
try {
|
|
118
|
-
engine.shutdown();
|
|
119
|
-
}
|
|
120
|
-
catch {
|
|
121
|
-
/* best-effort */
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
const logged = new Set(ledger.phases_logged);
|
|
125
|
-
const missing = requiredPhases.filter((p) => !logged.has(p));
|
|
126
|
-
if (missing.length === 0) {
|
|
127
|
-
return { block: false, stderr: "" };
|
|
128
|
-
}
|
|
129
|
-
return {
|
|
130
|
-
block: true,
|
|
131
|
-
stderr: buildBlockMessage(taskId, missing, ledger.phases_logged),
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
function buildBlockMessage(taskId, missing, loggedPhases) {
|
|
135
|
-
const loggedList = loggedPhases.length === 0 ? "(none)" : loggedPhases.join(", ");
|
|
136
|
-
return (`🦑 [opensquid workflow-gate] commit blocked for task ${taskId}\n` +
|
|
137
|
-
` missing phases: ${missing.join(", ")}\n` +
|
|
138
|
-
` logged phases: ${loggedList}\n` +
|
|
139
|
-
` Log the missing phases via the \`log_phase\` MCP tool, then retry the commit.\n` +
|
|
140
|
-
` Override (genuine emergency): set OPENSQUID_SKIP_WORKFLOW_GATE=1 for this command.\n`);
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Emergency-override env var. Lets the user bypass the gate when they
|
|
144
|
-
* know what they're doing. Logged loudly to stderr so the bypass is
|
|
145
|
-
* always visible in scrollback / CI logs.
|
|
146
|
-
*
|
|
147
|
-
* Exported for the test suite.
|
|
148
|
-
*/
|
|
149
|
-
export function checkOverrideEnv() {
|
|
150
|
-
return process.env.OPENSQUID_SKIP_WORKFLOW_GATE === "1";
|
|
151
|
-
}
|
|
152
|
-
//# sourceMappingURL=workflow-gate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-gate.js","sourceRoot":"","sources":["../../src.legacy/hooks/workflow-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflow-gate tests — covers the pure evaluator (no engine subprocess
|
|
3
|
-
* spawned). We mock the OpenSquidEngine.getTaskLedger to assert the
|
|
4
|
-
* gate behavior without standing up a real engine binary. The hook
|
|
5
|
-
* test wires the gate into the actual PreToolUse flow.
|
|
6
|
-
*/
|
|
7
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
8
|
-
import * as crypto from "node:crypto";
|
|
9
|
-
import { promises as fs } from "node:fs";
|
|
10
|
-
import * as os from "node:os";
|
|
11
|
-
import * as path from "node:path";
|
|
12
|
-
import * as engineClient from "../engine-client.js";
|
|
13
|
-
import { checkOverrideEnv, evaluateWorkflowGate, getRequiredPhasesFromCodex, } from "./workflow-gate.js";
|
|
14
|
-
// ---------------------------------------------------------------------
|
|
15
|
-
// Helpers
|
|
16
|
-
// ---------------------------------------------------------------------
|
|
17
|
-
let tmpDir;
|
|
18
|
-
let transcriptPath;
|
|
19
|
-
beforeEach(async () => {
|
|
20
|
-
tmpDir = path.join(os.tmpdir(), `opensquid-gate-${crypto.randomUUID()}`);
|
|
21
|
-
await fs.mkdir(tmpDir, { recursive: true });
|
|
22
|
-
transcriptPath = path.join(tmpDir, "transcript.jsonl");
|
|
23
|
-
});
|
|
24
|
-
afterEach(async () => {
|
|
25
|
-
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
26
|
-
delete process.env.OPENSQUID_SKIP_WORKFLOW_GATE;
|
|
27
|
-
vi.restoreAllMocks();
|
|
28
|
-
});
|
|
29
|
-
async function writeTranscriptWithActiveTask(taskId) {
|
|
30
|
-
// Single assistant tool_use event with a TodoWrite block. Matches
|
|
31
|
-
// the shape readActiveTaskId scans for.
|
|
32
|
-
const event = {
|
|
33
|
-
type: "assistant",
|
|
34
|
-
message: {
|
|
35
|
-
role: "assistant",
|
|
36
|
-
content: [
|
|
37
|
-
{
|
|
38
|
-
type: "tool_use",
|
|
39
|
-
name: "TodoWrite",
|
|
40
|
-
input: {
|
|
41
|
-
todos: [
|
|
42
|
-
{ id: "999", status: "completed", content: "done thing" },
|
|
43
|
-
{ id: taskId, status: "in_progress", content: "active thing" },
|
|
44
|
-
],
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
await fs.writeFile(transcriptPath, JSON.stringify(event) + "\n", "utf8");
|
|
51
|
-
}
|
|
52
|
-
/** Mock OpenSquidEngine.getTaskLedger to return a specific phase set. */
|
|
53
|
-
function mockLedger(phasesLogged) {
|
|
54
|
-
vi.spyOn(engineClient.OpenSquidEngine.prototype, "getTaskLedger").mockResolvedValue({
|
|
55
|
-
task_id: "127",
|
|
56
|
-
phases_logged: phasesLogged,
|
|
57
|
-
entries: phasesLogged.map((p) => ({
|
|
58
|
-
phase: p,
|
|
59
|
-
logged_at: "2026-05-16T08:00:00.000Z",
|
|
60
|
-
note: null,
|
|
61
|
-
})),
|
|
62
|
-
});
|
|
63
|
-
// shutdown() is called in the finally block of evaluateWorkflowGate.
|
|
64
|
-
vi.spyOn(engineClient.OpenSquidEngine.prototype, "shutdown").mockImplementation(() => { });
|
|
65
|
-
}
|
|
66
|
-
/** Mock the engine call to throw — simulates engine unreachable. */
|
|
67
|
-
function mockLedgerError(message) {
|
|
68
|
-
vi.spyOn(engineClient.OpenSquidEngine.prototype, "getTaskLedger").mockRejectedValue(new Error(message));
|
|
69
|
-
vi.spyOn(engineClient.OpenSquidEngine.prototype, "shutdown").mockImplementation(() => { });
|
|
70
|
-
}
|
|
71
|
-
// ---------------------------------------------------------------------
|
|
72
|
-
// Fail-open input scenarios — no block, no engine call
|
|
73
|
-
// ---------------------------------------------------------------------
|
|
74
|
-
describe("evaluateWorkflowGate — fail-open inputs", () => {
|
|
75
|
-
it("returns allow with warning when transcriptPath is missing", async () => {
|
|
76
|
-
const result = await evaluateWorkflowGate({});
|
|
77
|
-
expect(result.block).toBe(false);
|
|
78
|
-
expect(result.stderr).toContain("no transcript_path");
|
|
79
|
-
});
|
|
80
|
-
it("returns allow when transcript has no in_progress task", async () => {
|
|
81
|
-
await fs.writeFile(transcriptPath, "", "utf8");
|
|
82
|
-
const result = await evaluateWorkflowGate({ transcriptPath });
|
|
83
|
-
expect(result.block).toBe(false);
|
|
84
|
-
expect(result.stderr).toBe("");
|
|
85
|
-
});
|
|
86
|
-
it("returns allow with warning when transcript path doesn't exist", async () => {
|
|
87
|
-
const result = await evaluateWorkflowGate({
|
|
88
|
-
transcriptPath: path.join(tmpDir, "nonexistent.jsonl"),
|
|
89
|
-
});
|
|
90
|
-
expect(result.block).toBe(false);
|
|
91
|
-
// readActiveTaskId swallows the read error → returns null → allow silently.
|
|
92
|
-
expect(result.stderr).toBe("");
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
// ---------------------------------------------------------------------
|
|
96
|
-
// Active task detected → engine RPC drives decision
|
|
97
|
-
// ---------------------------------------------------------------------
|
|
98
|
-
describe("evaluateWorkflowGate — with active task", () => {
|
|
99
|
-
// 0.7.6 (#150): REQUIRED_PHASES expanded from ["audit",
|
|
100
|
-
// "post_research"] to all 6 required (fix stays soft). Tests
|
|
101
|
-
// updated accordingly. The 2-phase variant used to allow #132 to
|
|
102
|
-
// ship with most of its workflow unlogged.
|
|
103
|
-
it("BLOCKS when most required phases are missing", async () => {
|
|
104
|
-
await writeTranscriptWithActiveTask("127");
|
|
105
|
-
mockLedger(["code", "test"]);
|
|
106
|
-
const result = await evaluateWorkflowGate({ transcriptPath });
|
|
107
|
-
expect(result.block).toBe(true);
|
|
108
|
-
expect(result.stderr).toContain("commit blocked");
|
|
109
|
-
expect(result.stderr).toContain("pre_research");
|
|
110
|
-
expect(result.stderr).toContain("audit");
|
|
111
|
-
expect(result.stderr).toContain("post_research");
|
|
112
|
-
expect(result.stderr).toContain("127");
|
|
113
|
-
});
|
|
114
|
-
it("BLOCKS when only audit is missing (6-of-6 expansion)", async () => {
|
|
115
|
-
await writeTranscriptWithActiveTask("127");
|
|
116
|
-
mockLedger(["pre_research", "learn", "code", "test", "post_research"]);
|
|
117
|
-
const result = await evaluateWorkflowGate({ transcriptPath });
|
|
118
|
-
expect(result.block).toBe(true);
|
|
119
|
-
expect(result.stderr).toContain("missing phases: audit");
|
|
120
|
-
});
|
|
121
|
-
it("BLOCKS when only post_research is missing", async () => {
|
|
122
|
-
await writeTranscriptWithActiveTask("127");
|
|
123
|
-
mockLedger(["pre_research", "learn", "code", "test", "audit"]);
|
|
124
|
-
const result = await evaluateWorkflowGate({ transcriptPath });
|
|
125
|
-
expect(result.block).toBe(true);
|
|
126
|
-
expect(result.stderr).toContain("missing phases: post_research");
|
|
127
|
-
});
|
|
128
|
-
it("BLOCKS when only pre_research is missing (catches #132's shape)", async () => {
|
|
129
|
-
// #132 shipped today with only audit + post_research logged.
|
|
130
|
-
// The pre-#150 gate let it through. New gate catches it.
|
|
131
|
-
await writeTranscriptWithActiveTask("132");
|
|
132
|
-
mockLedger(["learn", "code", "test", "audit", "post_research"]);
|
|
133
|
-
const result = await evaluateWorkflowGate({ transcriptPath });
|
|
134
|
-
expect(result.block).toBe(true);
|
|
135
|
-
expect(result.stderr).toContain("missing phases: pre_research");
|
|
136
|
-
});
|
|
137
|
-
it("ALLOWS when all 6 required phases are logged (fix stays optional)", async () => {
|
|
138
|
-
await writeTranscriptWithActiveTask("127");
|
|
139
|
-
mockLedger(["pre_research", "learn", "code", "test", "audit", "post_research"]);
|
|
140
|
-
const result = await evaluateWorkflowGate({ transcriptPath });
|
|
141
|
-
expect(result.block).toBe(false);
|
|
142
|
-
expect(result.stderr).toBe("");
|
|
143
|
-
});
|
|
144
|
-
it("ALLOWS when more than the required phases are logged (extra is fine)", async () => {
|
|
145
|
-
await writeTranscriptWithActiveTask("127");
|
|
146
|
-
mockLedger(["pre_research", "learn", "code", "test", "audit", "post_research", "fix"]);
|
|
147
|
-
const result = await evaluateWorkflowGate({ transcriptPath });
|
|
148
|
-
expect(result.block).toBe(false);
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
// ---------------------------------------------------------------------
|
|
152
|
-
// Fail-open on engine error
|
|
153
|
-
// ---------------------------------------------------------------------
|
|
154
|
-
describe("evaluateWorkflowGate — fail-open invariant", () => {
|
|
155
|
-
it("ALLOWS with stderr warning when engine RPC throws", async () => {
|
|
156
|
-
await writeTranscriptWithActiveTask("127");
|
|
157
|
-
mockLedgerError("ECONNREFUSED: engine not running");
|
|
158
|
-
const result = await evaluateWorkflowGate({ transcriptPath });
|
|
159
|
-
expect(result.block).toBe(false);
|
|
160
|
-
expect(result.stderr).toContain("engine unreachable");
|
|
161
|
-
expect(result.stderr).toContain("ECONNREFUSED");
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
// ---------------------------------------------------------------------
|
|
165
|
-
// Emergency override
|
|
166
|
-
// ---------------------------------------------------------------------
|
|
167
|
-
// ---------------------------------------------------------------------
|
|
168
|
-
// Codex-driven required-phases (drift-as-codex chunk 3a, 0.7.16)
|
|
169
|
-
// ---------------------------------------------------------------------
|
|
170
|
-
describe("getRequiredPhasesFromCodex", () => {
|
|
171
|
-
it("returns the 6 required phases from the bundled-default codex's standard-7-phase workflow", () => {
|
|
172
|
-
const phases = getRequiredPhasesFromCodex();
|
|
173
|
-
expect(phases).toEqual(["pre_research", "learn", "code", "test", "audit", "post_research"]);
|
|
174
|
-
});
|
|
175
|
-
it("excludes the `fix` phase (required: false in the codex)", () => {
|
|
176
|
-
const phases = getRequiredPhasesFromCodex();
|
|
177
|
-
expect(phases).not.toContain("fix");
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
describe("evaluateWorkflowGate — emergency override", () => {
|
|
181
|
-
it("ALLOWS with bypass warning when OPENSQUID_SKIP_WORKFLOW_GATE=1", async () => {
|
|
182
|
-
process.env.OPENSQUID_SKIP_WORKFLOW_GATE = "1";
|
|
183
|
-
expect(checkOverrideEnv()).toBe(true);
|
|
184
|
-
// Should bypass even if all the other signals say block.
|
|
185
|
-
await writeTranscriptWithActiveTask("127");
|
|
186
|
-
mockLedger(["code"]); // would otherwise block
|
|
187
|
-
const result = await evaluateWorkflowGate({ transcriptPath });
|
|
188
|
-
expect(result.block).toBe(false);
|
|
189
|
-
expect(result.stderr).toContain("BYPASSED");
|
|
190
|
-
});
|
|
191
|
-
it("respects the env var only when EXACTLY '1' (not 'true', not 'yes')", async () => {
|
|
192
|
-
process.env.OPENSQUID_SKIP_WORKFLOW_GATE = "true";
|
|
193
|
-
expect(checkOverrideEnv()).toBe(false);
|
|
194
|
-
process.env.OPENSQUID_SKIP_WORKFLOW_GATE = "1";
|
|
195
|
-
expect(checkOverrideEnv()).toBe(true);
|
|
196
|
-
});
|
|
197
|
-
});
|
package/dist/hooks-cli.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export declare class HooksCliError extends Error {
|
|
2
|
-
readonly hint?: string | undefined;
|
|
3
|
-
constructor(message: string, hint?: string | undefined);
|
|
4
|
-
}
|
|
5
|
-
interface ClaudeCommandHook {
|
|
6
|
-
type: "command";
|
|
7
|
-
command: string;
|
|
8
|
-
/** Custom non-standard marker so we can find our own hook later. */
|
|
9
|
-
_id?: string;
|
|
10
|
-
}
|
|
11
|
-
interface ClaudePromptHook {
|
|
12
|
-
type: "prompt";
|
|
13
|
-
prompt: string;
|
|
14
|
-
model?: string;
|
|
15
|
-
/** Optional timeout in seconds — Claude Code default is 30s for prompt hooks. */
|
|
16
|
-
timeout?: number;
|
|
17
|
-
_id?: string;
|
|
18
|
-
}
|
|
19
|
-
type ClaudeHook = ClaudeCommandHook | ClaudePromptHook;
|
|
20
|
-
/** True when a hook entry is recognizably opensquid's. */
|
|
21
|
-
export declare function isOurHook(h: ClaudeHook): boolean;
|
|
22
|
-
export type HooksCliCmd = "install" | "uninstall" | "doctor";
|
|
23
|
-
export declare function runHooksCli(cmd: HooksCliCmd, _argv: string[]): Promise<void>;
|
|
24
|
-
export {};
|
|
25
|
-
//# sourceMappingURL=hooks-cli.d.ts.map
|
package/dist/hooks-cli.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-cli.d.ts","sourceRoot":"","sources":["../src.legacy/hooks-cli.ts"],"names":[],"mappings":"AAsBA,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,CAAC,EAAE,MAAM;gBAD7B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAKhC;AA2DD,UAAU,iBAAiB;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,KAAK,UAAU,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAsDvD,0DAA0D;AAC1D,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAoBhD;AAkJD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE7D,wBAAsB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAYlF"}
|