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
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared transcript-JSONL helpers for hooks that need to read what the
|
|
3
|
-
* last user or assistant message was.
|
|
4
|
-
*
|
|
5
|
-
* Claude Code writes one event per line. Schema is duck-typed because
|
|
6
|
-
* the official shape isn't documented as stable — fields we don't
|
|
7
|
-
* recognize are ignored.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Walk the transcript JSONL backwards and return the most recent USER
|
|
11
|
-
* message text. Tool-result events (which also have `type: "user"`
|
|
12
|
-
* but carry an array `content` of tool_result blocks) are skipped — we
|
|
13
|
-
* only return user-typed plain-string utterances.
|
|
14
|
-
*
|
|
15
|
-
* Returns "" on any error or if no plain-string user message exists.
|
|
16
|
-
*/
|
|
17
|
-
export declare function readLastUserText(transcriptPath: string): Promise<string>;
|
|
18
|
-
/**
|
|
19
|
-
* Walk the transcript JSONL backwards and return the most recent
|
|
20
|
-
* ASSISTANT message text. Concatenates text blocks if content is an
|
|
21
|
-
* array of typed blocks.
|
|
22
|
-
*/
|
|
23
|
-
export declare function readLastAssistantText(transcriptPath: string): Promise<string>;
|
|
24
|
-
export declare function readActiveTaskId(transcriptPath: string): Promise<string | null>;
|
|
25
|
-
export declare function readTranscriptLines(transcriptPath: string): Promise<string[]>;
|
|
26
|
-
//# sourceMappingURL=transcript.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src.legacy/hooks/transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW9E;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASnF;AA0CD,wBAAsB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0JrF;AAED,wBAAsB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOnF"}
|
package/dist/hooks/transcript.js
DELETED
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared transcript-JSONL helpers for hooks that need to read what the
|
|
3
|
-
* last user or assistant message was.
|
|
4
|
-
*
|
|
5
|
-
* Claude Code writes one event per line. Schema is duck-typed because
|
|
6
|
-
* the official shape isn't documented as stable — fields we don't
|
|
7
|
-
* recognize are ignored.
|
|
8
|
-
*/
|
|
9
|
-
import { promises as fs } from "node:fs";
|
|
10
|
-
/**
|
|
11
|
-
* Walk the transcript JSONL backwards and return the most recent USER
|
|
12
|
-
* message text. Tool-result events (which also have `type: "user"`
|
|
13
|
-
* but carry an array `content` of tool_result blocks) are skipped — we
|
|
14
|
-
* only return user-typed plain-string utterances.
|
|
15
|
-
*
|
|
16
|
-
* Returns "" on any error or if no plain-string user message exists.
|
|
17
|
-
*/
|
|
18
|
-
export async function readLastUserText(transcriptPath) {
|
|
19
|
-
const lines = await readTranscriptLines(transcriptPath);
|
|
20
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
21
|
-
const event = safeParseLine(lines[i]);
|
|
22
|
-
if (!event || event.type !== "user")
|
|
23
|
-
continue;
|
|
24
|
-
const content = event.message?.content;
|
|
25
|
-
// Only accept plain string utterances. Tool-result events carry
|
|
26
|
-
// an array `content` and aren't real user speech.
|
|
27
|
-
if (typeof content === "string" && content.trim())
|
|
28
|
-
return content;
|
|
29
|
-
}
|
|
30
|
-
return "";
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Walk the transcript JSONL backwards and return the most recent
|
|
34
|
-
* ASSISTANT message text. Concatenates text blocks if content is an
|
|
35
|
-
* array of typed blocks.
|
|
36
|
-
*/
|
|
37
|
-
export async function readLastAssistantText(transcriptPath) {
|
|
38
|
-
const lines = await readTranscriptLines(transcriptPath);
|
|
39
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
40
|
-
const event = safeParseLine(lines[i]);
|
|
41
|
-
if (!event || event.type !== "assistant")
|
|
42
|
-
continue;
|
|
43
|
-
const text = extractAssistantText(event);
|
|
44
|
-
if (text)
|
|
45
|
-
return text;
|
|
46
|
-
}
|
|
47
|
-
return "";
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* v0.6.2 — find the most-recently-marked in_progress task id from the
|
|
51
|
-
* transcript. Used by the pre-tool-use hook to figure out which task's
|
|
52
|
-
* phase ledger to gate `git commit` against.
|
|
53
|
-
*
|
|
54
|
-
* Claude Code exposes three task-tracking surfaces; all are recognized:
|
|
55
|
-
*
|
|
56
|
-
* 1. **TodoWrite** (snapshot semantic) — `input.todos[]` is the full
|
|
57
|
-
* list with explicit ids + statuses. Each todo's status is applied
|
|
58
|
-
* at the snapshot's line index.
|
|
59
|
-
*
|
|
60
|
-
* 2. **TaskCreate** (delta) — `input.{subject,description,...}`. The
|
|
61
|
-
* assigned id comes back in the matching tool_result text
|
|
62
|
-
* ("Task #N created successfully"). Default status = pending.
|
|
63
|
-
* Active-task detection looks up tool_use_id → tool_result content.
|
|
64
|
-
*
|
|
65
|
-
* 3. **TaskUpdate** (delta) — `input.taskId` (string or number) +
|
|
66
|
-
* `input.status` ("in_progress"|"completed"|...). Direct mutation.
|
|
67
|
-
*
|
|
68
|
-
* Implementation: single forward pass over the transcript building a
|
|
69
|
-
* `{task_id → {status, lastTouchedIdx}}` map. The forward pass means
|
|
70
|
-
* chronology IS the sort key — latest write per id naturally wins,
|
|
71
|
-
* no extra ordering logic needed. Returns the id with status =
|
|
72
|
-
* "in_progress" and the highest lastTouchedIdx.
|
|
73
|
-
*
|
|
74
|
-
* v0.6.1 only recognized #1; my own session today used #2 + #3
|
|
75
|
-
* exclusively, so the workflow gate silent-allowed every commit
|
|
76
|
-
* (active task = null → no gate fires). This is the v0.6.2 fix.
|
|
77
|
-
*
|
|
78
|
-
* Returns null when no in_progress task is detected (graceful —
|
|
79
|
-
* hook falls back to allow, per the fail-open invariant).
|
|
80
|
-
*/
|
|
81
|
-
/**
|
|
82
|
-
* 0.7.9 (#163): how stale an `in_progress` task can be before it's
|
|
83
|
-
* demoted as the active-task pick. Captures the "I forgot to mark
|
|
84
|
-
* yesterday's task completed, but I'm working on a new one now"
|
|
85
|
-
* scenario observed in #160's resume-drift investigation.
|
|
86
|
-
*/
|
|
87
|
-
const STALE_TASK_MS = 60 * 60 * 1000; // 1 hour
|
|
88
|
-
export async function readActiveTaskId(transcriptPath) {
|
|
89
|
-
const lines = await readTranscriptLines(transcriptPath);
|
|
90
|
-
const stateByTask = new Map();
|
|
91
|
-
let latestTimestampMs = 0;
|
|
92
|
-
// Pre-index user events by tool_use_id so TaskCreate's id-extraction
|
|
93
|
-
// doesn't N-squared scan. The tool_result block lives in a later
|
|
94
|
-
// user event referencing the tool_use's id.
|
|
95
|
-
const toolResultText = new Map();
|
|
96
|
-
for (let i = 0; i < lines.length; i++) {
|
|
97
|
-
const event = safeParseLine(lines[i]);
|
|
98
|
-
if (!event || event.type !== "user")
|
|
99
|
-
continue;
|
|
100
|
-
const content = event.message?.content;
|
|
101
|
-
if (!Array.isArray(content))
|
|
102
|
-
continue;
|
|
103
|
-
for (const block of content) {
|
|
104
|
-
if (!block ||
|
|
105
|
-
typeof block !== "object" ||
|
|
106
|
-
block.type !== "tool_result") {
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
const tuId = block.tool_use_id;
|
|
110
|
-
const c = block.content;
|
|
111
|
-
if (typeof tuId === "string" && typeof c === "string") {
|
|
112
|
-
toolResultText.set(tuId, c);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
// Single forward pass — chronological order is the line index, so
|
|
117
|
-
// "latest write per id wins" is enforced naturally.
|
|
118
|
-
for (let i = 0; i < lines.length; i++) {
|
|
119
|
-
const event = safeParseLine(lines[i]);
|
|
120
|
-
if (!event)
|
|
121
|
-
continue;
|
|
122
|
-
// 0.7.9 (#163): track the latest event timestamp across ANY event
|
|
123
|
-
// type (not just assistant tool_use). Used to decide if the most
|
|
124
|
-
// recent in_progress task pick is stale relative to current
|
|
125
|
-
// session activity.
|
|
126
|
-
const tsStr = event.timestamp;
|
|
127
|
-
if (typeof tsStr === "string") {
|
|
128
|
-
const ms = Date.parse(tsStr);
|
|
129
|
-
if (Number.isFinite(ms) && ms > latestTimestampMs)
|
|
130
|
-
latestTimestampMs = ms;
|
|
131
|
-
}
|
|
132
|
-
if (event.type !== "assistant")
|
|
133
|
-
continue;
|
|
134
|
-
const content = event.message?.content;
|
|
135
|
-
if (!Array.isArray(content))
|
|
136
|
-
continue;
|
|
137
|
-
// Capture this event's timestamp once for the task-touch logic
|
|
138
|
-
// below.
|
|
139
|
-
const eventTs = typeof tsStr === "string" ? Date.parse(tsStr) : Number.NaN;
|
|
140
|
-
const eventTsMs = Number.isFinite(eventTs) ? eventTs : 0;
|
|
141
|
-
for (const block of content) {
|
|
142
|
-
if (!block || typeof block !== "object" || block.type !== "tool_use") {
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
const name = block.name;
|
|
146
|
-
const input = block.input;
|
|
147
|
-
if (!input || typeof input !== "object")
|
|
148
|
-
continue;
|
|
149
|
-
if (name === "TaskUpdate") {
|
|
150
|
-
const taskId = input.taskId;
|
|
151
|
-
const status = input.status;
|
|
152
|
-
const idStr = typeof taskId === "string" ? taskId : typeof taskId === "number" ? String(taskId) : "";
|
|
153
|
-
if (idStr && typeof status === "string") {
|
|
154
|
-
stateByTask.set(idStr, { status, lastTouchedIdx: i, lastTouchedAt: eventTsMs });
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
else if (name === "TaskCreate") {
|
|
158
|
-
// Extract assigned id from the matching tool_result. The regex
|
|
159
|
-
// is intentionally loose — Claude Code's exact wording has
|
|
160
|
-
// varied across versions ("Task #131 created", "Task 131 created",
|
|
161
|
-
// future UUIDs?). We accept optional `#`, any word-char id.
|
|
162
|
-
// If the wording changes more drastically, the regression test
|
|
163
|
-
// against the real-transcript fixture will fail first instead
|
|
164
|
-
// of the gate silently regressing in production.
|
|
165
|
-
const blockId = block.id;
|
|
166
|
-
if (typeof blockId !== "string")
|
|
167
|
-
continue;
|
|
168
|
-
const resultText = toolResultText.get(blockId);
|
|
169
|
-
if (!resultText)
|
|
170
|
-
continue;
|
|
171
|
-
const m = resultText.match(/Task\s+#?([\w-]+)/i);
|
|
172
|
-
if (m) {
|
|
173
|
-
// Default status for newly-created tasks is "pending".
|
|
174
|
-
stateByTask.set(m[1], { status: "pending", lastTouchedIdx: i, lastTouchedAt: eventTsMs });
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
else if (name === "TodoWrite") {
|
|
178
|
-
// Snapshot semantic — apply each todo's status at this chrono idx.
|
|
179
|
-
// The list IS canonical for the ids it mentions, but only at
|
|
180
|
-
// this point in time; a later TaskUpdate against the same id
|
|
181
|
-
// would override (it'd happen at a higher idx, so naturally wins).
|
|
182
|
-
const todos = input.todos;
|
|
183
|
-
if (!Array.isArray(todos))
|
|
184
|
-
continue;
|
|
185
|
-
for (const todo of todos) {
|
|
186
|
-
if (!todo || typeof todo !== "object")
|
|
187
|
-
continue;
|
|
188
|
-
const todoId = todo.id;
|
|
189
|
-
const todoStatus = todo.status;
|
|
190
|
-
const idStr = typeof todoId === "string" ? todoId : typeof todoId === "number" ? String(todoId) : "";
|
|
191
|
-
if (idStr && typeof todoStatus === "string") {
|
|
192
|
-
stateByTask.set(idStr, {
|
|
193
|
-
status: todoStatus,
|
|
194
|
-
lastTouchedIdx: i,
|
|
195
|
-
lastTouchedAt: eventTsMs,
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
// Find the most-recently-touched in_progress task. Ties broken by
|
|
203
|
-
// higher line index = more recent.
|
|
204
|
-
let bestId = null;
|
|
205
|
-
let bestIdx = -1;
|
|
206
|
-
let bestAt = 0;
|
|
207
|
-
for (const [id, s] of stateByTask) {
|
|
208
|
-
if (s.status === "in_progress" && s.lastTouchedIdx > bestIdx) {
|
|
209
|
-
bestId = id;
|
|
210
|
-
bestIdx = s.lastTouchedIdx;
|
|
211
|
-
bestAt = s.lastTouchedAt;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
// 0.7.9 (#163): demote stale in_progress picks. If the best
|
|
215
|
-
// in_progress task was last touched more than STALE_TASK_MS before
|
|
216
|
-
// the latest transcript activity, assume the agent forgot to mark
|
|
217
|
-
// it completed; return null so the workflow-gate doesn't enforce
|
|
218
|
-
// against the wrong task. The fail-open invariant keeps the gate
|
|
219
|
-
// permissive in this case — better than enforcing wrongly.
|
|
220
|
-
//
|
|
221
|
-
// Only applies when BOTH timestamps are available. If either is 0
|
|
222
|
-
// (events lacked timestamps), fall back to the line-idx-based
|
|
223
|
-
// pick like pre-0.7.9.
|
|
224
|
-
if (bestId !== null && bestAt > 0 && latestTimestampMs > 0) {
|
|
225
|
-
const ageMs = latestTimestampMs - bestAt;
|
|
226
|
-
if (ageMs > STALE_TASK_MS)
|
|
227
|
-
return null;
|
|
228
|
-
}
|
|
229
|
-
return bestId;
|
|
230
|
-
}
|
|
231
|
-
export async function readTranscriptLines(transcriptPath) {
|
|
232
|
-
try {
|
|
233
|
-
const raw = await fs.readFile(transcriptPath, "utf8");
|
|
234
|
-
return raw.split("\n").filter((l) => l.trim());
|
|
235
|
-
}
|
|
236
|
-
catch {
|
|
237
|
-
return [];
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
function safeParseLine(line) {
|
|
241
|
-
try {
|
|
242
|
-
return JSON.parse(line);
|
|
243
|
-
}
|
|
244
|
-
catch {
|
|
245
|
-
return null;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
function extractAssistantText(event) {
|
|
249
|
-
const content = event.message?.content;
|
|
250
|
-
if (typeof content === "string")
|
|
251
|
-
return content;
|
|
252
|
-
if (!Array.isArray(content))
|
|
253
|
-
return "";
|
|
254
|
-
const parts = [];
|
|
255
|
-
for (const block of content) {
|
|
256
|
-
if (block &&
|
|
257
|
-
typeof block === "object" &&
|
|
258
|
-
"type" in block &&
|
|
259
|
-
block.type === "text" &&
|
|
260
|
-
typeof block.text === "string") {
|
|
261
|
-
parts.push(block.text);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return parts.join("\n");
|
|
265
|
-
}
|
|
266
|
-
//# sourceMappingURL=transcript.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src.legacy/hooks/transcript.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,103 +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 { readLastAssistantText, readLastUserText } from "./transcript.js";
|
|
7
|
-
let tmpRoot;
|
|
8
|
-
beforeEach(async () => {
|
|
9
|
-
tmpRoot = path.join(os.tmpdir(), `oscli-transcript-${crypto.randomUUID()}`);
|
|
10
|
-
await fs.mkdir(tmpRoot, { recursive: true });
|
|
11
|
-
});
|
|
12
|
-
afterEach(async () => {
|
|
13
|
-
await fs.rm(tmpRoot, { recursive: true, force: true });
|
|
14
|
-
});
|
|
15
|
-
async function writeTranscript(events) {
|
|
16
|
-
const p = path.join(tmpRoot, "transcript.jsonl");
|
|
17
|
-
await fs.writeFile(p, events.map((e) => JSON.stringify(e)).join("\n") + "\n");
|
|
18
|
-
return p;
|
|
19
|
-
}
|
|
20
|
-
describe("readLastUserText", () => {
|
|
21
|
-
it("returns '' when the file does not exist", async () => {
|
|
22
|
-
const r = await readLastUserText(path.join(tmpRoot, "missing.jsonl"));
|
|
23
|
-
expect(r).toBe("");
|
|
24
|
-
});
|
|
25
|
-
it("returns the most recent plain-string user message", async () => {
|
|
26
|
-
const p = await writeTranscript([
|
|
27
|
-
{ type: "user", message: { role: "user", content: "first thing" } },
|
|
28
|
-
{ type: "assistant", message: { content: [{ type: "text", text: "ok" }] } },
|
|
29
|
-
{ type: "user", message: { role: "user", content: "second thing" } },
|
|
30
|
-
]);
|
|
31
|
-
const r = await readLastUserText(p);
|
|
32
|
-
expect(r).toBe("second thing");
|
|
33
|
-
});
|
|
34
|
-
it("skips user events with array content (tool_result events)", async () => {
|
|
35
|
-
const p = await writeTranscript([
|
|
36
|
-
{ type: "user", message: { role: "user", content: "real prompt" } },
|
|
37
|
-
{ type: "assistant", message: { content: [{ type: "text", text: "ok" }] } },
|
|
38
|
-
{
|
|
39
|
-
type: "user",
|
|
40
|
-
message: {
|
|
41
|
-
role: "user",
|
|
42
|
-
content: [{ tool_use_id: "abc", type: "tool_result", content: "tool result text" }],
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
]);
|
|
46
|
-
const r = await readLastUserText(p);
|
|
47
|
-
expect(r).toBe("real prompt");
|
|
48
|
-
});
|
|
49
|
-
it("returns '' when no plain-string user message exists", async () => {
|
|
50
|
-
const p = await writeTranscript([
|
|
51
|
-
{ type: "assistant", message: { content: [{ type: "text", text: "hi" }] } },
|
|
52
|
-
{
|
|
53
|
-
type: "user",
|
|
54
|
-
message: {
|
|
55
|
-
role: "user",
|
|
56
|
-
content: [{ tool_use_id: "x", type: "tool_result", content: "y" }],
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
]);
|
|
60
|
-
const r = await readLastUserText(p);
|
|
61
|
-
expect(r).toBe("");
|
|
62
|
-
});
|
|
63
|
-
it("ignores malformed lines", async () => {
|
|
64
|
-
const p = path.join(tmpRoot, "mixed.jsonl");
|
|
65
|
-
await fs.writeFile(p, [
|
|
66
|
-
JSON.stringify({ type: "user", message: { role: "user", content: "hello" } }),
|
|
67
|
-
"{ malformed",
|
|
68
|
-
JSON.stringify({ type: "user", message: { role: "user", content: "world" } }),
|
|
69
|
-
].join("\n"));
|
|
70
|
-
const r = await readLastUserText(p);
|
|
71
|
-
expect(r).toBe("world");
|
|
72
|
-
});
|
|
73
|
-
it("returns '' when content is whitespace only", async () => {
|
|
74
|
-
const p = await writeTranscript([
|
|
75
|
-
{ type: "user", message: { role: "user", content: " \n\t" } },
|
|
76
|
-
]);
|
|
77
|
-
const r = await readLastUserText(p);
|
|
78
|
-
expect(r).toBe("");
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
describe("readLastAssistantText (back-compat)", () => {
|
|
82
|
-
it("returns the most recent assistant text from array content", async () => {
|
|
83
|
-
const p = await writeTranscript([
|
|
84
|
-
{ type: "user", message: { role: "user", content: "hi" } },
|
|
85
|
-
{
|
|
86
|
-
type: "assistant",
|
|
87
|
-
message: {
|
|
88
|
-
content: [
|
|
89
|
-
{ type: "text", text: "first chunk" },
|
|
90
|
-
{ type: "text", text: "second chunk" },
|
|
91
|
-
],
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
]);
|
|
95
|
-
const r = await readLastAssistantText(p);
|
|
96
|
-
expect(r).toBe("first chunk\nsecond chunk");
|
|
97
|
-
});
|
|
98
|
-
it("returns string content directly when used", async () => {
|
|
99
|
-
const p = await writeTranscript([{ type: "assistant", message: { content: "direct string" } }]);
|
|
100
|
-
const r = await readLastAssistantText(p);
|
|
101
|
-
expect(r).toBe("direct string");
|
|
102
|
-
});
|
|
103
|
-
});
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `opensquid hook user-prompt-submit` — Claude Code UserPromptSubmit
|
|
3
|
-
* hook handler.
|
|
4
|
-
*
|
|
5
|
-
* Fires when the user submits a prompt (start of every new turn).
|
|
6
|
-
* Surfaces TWO accumulator surfaces via stdout so the agent sees them
|
|
7
|
-
* in its system context:
|
|
8
|
-
*
|
|
9
|
-
* 1. broken-promises.jsonl — claims from the prior assistant turn
|
|
10
|
-
* that the honesty ledger flagged as unfulfilled.
|
|
11
|
-
* 2. heartbeat-pending.txt — token-threshold re-anchor nudge written
|
|
12
|
-
* by the Stop hook when the transcript grew past the configured
|
|
13
|
-
* threshold (default 20K tokens, OPENSQUID_HEARTBEAT_TOKENS).
|
|
14
|
-
*
|
|
15
|
-
* Both surfaces are CLEARED after surfacing — one chance per item per
|
|
16
|
-
* session, no infinite nagging.
|
|
17
|
-
*
|
|
18
|
-
* Exit 0 always — UserPromptSubmit is observational.
|
|
19
|
-
*
|
|
20
|
-
* Pre-#124: this hook also surfaced auto-classify-candidates.jsonl
|
|
21
|
-
* written by a detached LLM subprocess. Removed alongside the auto-
|
|
22
|
-
* classifier deletion — the agent classifies utterances inline per
|
|
23
|
-
* CLAUDE.md, and the heartbeat reminds it to re-anchor periodically.
|
|
24
|
-
*/
|
|
25
|
-
export declare function runUserPromptSubmitHook(): Promise<void>;
|
|
26
|
-
/**
|
|
27
|
-
* 0.7.27 / D8 — detect a multi-task directive in the user's prompt
|
|
28
|
-
* and return a "mirror back your parsed plan" reminder message.
|
|
29
|
-
*
|
|
30
|
-
* Trigger patterns (case-insensitive):
|
|
31
|
-
* - "<num1> then <num2>" — bare-number sequencing (the D8 incident
|
|
32
|
-
* shape: user said "166 then 168" — agent did 166 + deferred 168)
|
|
33
|
-
* - "first <ref> then <ref>"
|
|
34
|
-
* - "after <ref> do <ref>" / "after X then Y"
|
|
35
|
-
* - Two or more `#<num>` references
|
|
36
|
-
*
|
|
37
|
-
* Returns the surface message when a match fires, null otherwise.
|
|
38
|
-
* Exported for direct testing.
|
|
39
|
-
*/
|
|
40
|
-
export declare function detectMultiTaskDirective(prompt: string): string | null;
|
|
41
|
-
/**
|
|
42
|
-
* Extract probable task references from a user prompt. Returns the
|
|
43
|
-
* distinct references in document order, capped at 10.
|
|
44
|
-
*
|
|
45
|
-
* Heuristics (intentionally narrow to keep false-positives low):
|
|
46
|
-
* - `#\d+` shapes always count
|
|
47
|
-
* - bare 2-4-digit numbers count IF they're connected by a
|
|
48
|
-
* sequencing word ("then" / "after" / "first" / "and then")
|
|
49
|
-
*
|
|
50
|
-
* Exported for testing.
|
|
51
|
-
*/
|
|
52
|
-
export declare function extractTaskRefs(prompt: string): string[];
|
|
53
|
-
/**
|
|
54
|
-
* 0.7.10 (#164): detect resumed sessions by tracking the wall-clock
|
|
55
|
-
* gap between consecutive UPS firings. Returns a re-anchor message
|
|
56
|
-
* when a gap exceeds RESUME_GAP_MS, OR null when continuous /
|
|
57
|
-
* first-ever firing.
|
|
58
|
-
*
|
|
59
|
-
* Marker file: ~/.opensquid/sessions/<sid>/ups-last-at.txt
|
|
60
|
-
* Contents: ISO 8601 timestamp of the last UPS firing.
|
|
61
|
-
*
|
|
62
|
-
* On EVERY call: read prior timestamp → write current timestamp.
|
|
63
|
-
* First call: marker missing → write current; return null (no resume
|
|
64
|
-
* happened, just the session starting).
|
|
65
|
-
* Subsequent call: gap < RESUME_GAP_MS → continuous (return null).
|
|
66
|
-
* Subsequent call: gap >= RESUME_GAP_MS → resumed (return message).
|
|
67
|
-
*
|
|
68
|
-
* Exported for direct testing.
|
|
69
|
-
*/
|
|
70
|
-
export declare function detectResumeAndUpdateMarker(sessionId: string, options?: {
|
|
71
|
-
dataRoot?: string;
|
|
72
|
-
now?: number;
|
|
73
|
-
}): Promise<string | null>;
|
|
74
|
-
//# sourceMappingURL=user-prompt-submit.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"user-prompt-submit.d.ts","sourceRoot":"","sources":["../../src.legacy/hooks/user-prompt-submit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAuBH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgF7D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAStE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBxD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAChD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6BxB"}
|