@fractalsynapse/dsh-chapters 0.0.0-stage → 0.2.20

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.
Files changed (195) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +76 -2
  3. package/cordis.patch.yml +363 -0
  4. package/docs/architecture.md +692 -0
  5. package/docs/autorun-guide.md +248 -0
  6. package/docs/backlog.md +2022 -0
  7. package/docs/contract.md +938 -0
  8. package/docs/development.md +990 -0
  9. package/docs/host-compaction-seam.md +225 -0
  10. package/docs/host-protected-head-ask.md +80 -0
  11. package/docs/knowledge-repo.md +1332 -0
  12. package/docs/plans-carriage.md +571 -0
  13. package/docs/project-state.md +642 -0
  14. package/docs/provider.md +98 -0
  15. package/docs/superpowers/plans/2026-10-17-chapters-save.md +198 -0
  16. package/docs/superpowers/plans/2026-11-02-chapter-removal.md +151 -0
  17. package/docs/superpowers/specs/2026-11-02-chapter-removal-design.md +115 -0
  18. package/docs/verify.md +561 -0
  19. package/lib/archive.d.ts +161 -0
  20. package/lib/archive.js +229 -0
  21. package/lib/archive.js.map +1 -0
  22. package/lib/arrival.d.ts +23 -0
  23. package/lib/arrival.js +125 -0
  24. package/lib/arrival.js.map +1 -0
  25. package/lib/artifact-query.d.ts +62 -0
  26. package/lib/artifact-query.js +187 -0
  27. package/lib/artifact-query.js.map +1 -0
  28. package/lib/attach.d.ts +46 -0
  29. package/lib/attach.js +120 -0
  30. package/lib/attach.js.map +1 -0
  31. package/lib/auto-save.d.ts +145 -0
  32. package/lib/auto-save.js +334 -0
  33. package/lib/auto-save.js.map +1 -0
  34. package/lib/aux-message.d.ts +17 -0
  35. package/lib/aux-message.js +20 -0
  36. package/lib/aux-message.js.map +1 -0
  37. package/lib/client.js +1419 -0
  38. package/lib/client.js.map +1 -0
  39. package/lib/codegraph.d.ts +76 -0
  40. package/lib/codegraph.js +190 -0
  41. package/lib/codegraph.js.map +1 -0
  42. package/lib/commands.d.ts +52 -0
  43. package/lib/commands.js +946 -0
  44. package/lib/commands.js.map +1 -0
  45. package/lib/compose.d.ts +30 -0
  46. package/lib/compose.js +185 -0
  47. package/lib/compose.js.map +1 -0
  48. package/lib/continue-core.d.ts +245 -0
  49. package/lib/continue-core.js +405 -0
  50. package/lib/continue-core.js.map +1 -0
  51. package/lib/diag.d.ts +55 -0
  52. package/lib/diag.js +186 -0
  53. package/lib/diag.js.map +1 -0
  54. package/lib/engine-core.d.ts +301 -0
  55. package/lib/engine-core.js +531 -0
  56. package/lib/engine-core.js.map +1 -0
  57. package/lib/engine-note.d.ts +35 -0
  58. package/lib/engine-note.js +32 -0
  59. package/lib/engine-note.js.map +1 -0
  60. package/lib/engine.d.ts +329 -0
  61. package/lib/engine.js +1179 -0
  62. package/lib/engine.js.map +1 -0
  63. package/lib/enrich-queue.d.ts +66 -0
  64. package/lib/enrich-queue.js +126 -0
  65. package/lib/enrich-queue.js.map +1 -0
  66. package/lib/enrich-store.d.ts +31 -0
  67. package/lib/enrich-store.js +103 -0
  68. package/lib/enrich-store.js.map +1 -0
  69. package/lib/enrich-wire.d.ts +163 -0
  70. package/lib/enrich-wire.js +353 -0
  71. package/lib/enrich-wire.js.map +1 -0
  72. package/lib/enrich.d.ts +102 -0
  73. package/lib/enrich.js +267 -0
  74. package/lib/enrich.js.map +1 -0
  75. package/lib/gitops.d.ts +107 -0
  76. package/lib/gitops.js +539 -0
  77. package/lib/gitops.js.map +1 -0
  78. package/lib/index.d.ts +241 -0
  79. package/lib/index.js +1162 -0
  80. package/lib/index.js.map +1 -0
  81. package/lib/indexing.d.ts +98 -0
  82. package/lib/indexing.js +223 -0
  83. package/lib/indexing.js.map +1 -0
  84. package/lib/injections.d.ts +90 -0
  85. package/lib/injections.js +165 -0
  86. package/lib/injections.js.map +1 -0
  87. package/lib/last-resort.d.ts +24 -0
  88. package/lib/last-resort.js +27 -0
  89. package/lib/last-resort.js.map +1 -0
  90. package/lib/log-shape.d.ts +38 -0
  91. package/lib/log-shape.js +93 -0
  92. package/lib/log-shape.js.map +1 -0
  93. package/lib/models-command.d.ts +74 -0
  94. package/lib/models-command.js +100 -0
  95. package/lib/models-command.js.map +1 -0
  96. package/lib/notice.d.ts +74 -0
  97. package/lib/notice.js +92 -0
  98. package/lib/notice.js.map +1 -0
  99. package/lib/plans.d.ts +154 -0
  100. package/lib/plans.js +315 -0
  101. package/lib/plans.js.map +1 -0
  102. package/lib/preset.d.ts +186 -0
  103. package/lib/preset.js +212 -0
  104. package/lib/preset.js.map +1 -0
  105. package/lib/prompt-keys.d.ts +7 -0
  106. package/lib/prompt-keys.js +8 -0
  107. package/lib/prompt-keys.js.map +1 -0
  108. package/lib/prompt-loop.d.ts +73 -0
  109. package/lib/prompt-loop.js +147 -0
  110. package/lib/prompt-loop.js.map +1 -0
  111. package/lib/prompt-push.d.ts +47 -0
  112. package/lib/prompt-push.js +115 -0
  113. package/lib/prompt-push.js.map +1 -0
  114. package/lib/prompt-runner.d.ts +48 -0
  115. package/lib/prompt-runner.js +90 -0
  116. package/lib/prompt-runner.js.map +1 -0
  117. package/lib/prompt-state.d.ts +142 -0
  118. package/lib/prompt-state.js +101 -0
  119. package/lib/prompt-state.js.map +1 -0
  120. package/lib/prompt.d.ts +270 -0
  121. package/lib/prompt.js +408 -0
  122. package/lib/prompt.js.map +1 -0
  123. package/lib/provider.d.ts +44 -0
  124. package/lib/provider.js +66 -0
  125. package/lib/provider.js.map +1 -0
  126. package/lib/redact.d.ts +24 -0
  127. package/lib/redact.js +85 -0
  128. package/lib/redact.js.map +1 -0
  129. package/lib/registry.d.ts +187 -0
  130. package/lib/registry.js +235 -0
  131. package/lib/registry.js.map +1 -0
  132. package/lib/removal.d.ts +159 -0
  133. package/lib/removal.js +556 -0
  134. package/lib/removal.js.map +1 -0
  135. package/lib/render.d.ts +97 -0
  136. package/lib/render.js +530 -0
  137. package/lib/render.js.map +1 -0
  138. package/lib/repair-run.d.ts +76 -0
  139. package/lib/repair-run.js +506 -0
  140. package/lib/repair-run.js.map +1 -0
  141. package/lib/repair.d.ts +208 -0
  142. package/lib/repair.js +357 -0
  143. package/lib/repair.js.map +1 -0
  144. package/lib/repo.d.ts +78 -0
  145. package/lib/repo.js +184 -0
  146. package/lib/repo.js.map +1 -0
  147. package/lib/rules-commands.d.ts +46 -0
  148. package/lib/rules-commands.js +379 -0
  149. package/lib/rules-commands.js.map +1 -0
  150. package/lib/rules.d.ts +267 -0
  151. package/lib/rules.js +478 -0
  152. package/lib/rules.js.map +1 -0
  153. package/lib/save-core.d.ts +72 -0
  154. package/lib/save-core.js +220 -0
  155. package/lib/save-core.js.map +1 -0
  156. package/lib/search.d.ts +112 -0
  157. package/lib/search.js +282 -0
  158. package/lib/search.js.map +1 -0
  159. package/lib/session-rules.d.ts +222 -0
  160. package/lib/session-rules.js +454 -0
  161. package/lib/session-rules.js.map +1 -0
  162. package/lib/signature.d.ts +45 -0
  163. package/lib/signature.js +199 -0
  164. package/lib/signature.js.map +1 -0
  165. package/lib/store.d.ts +156 -0
  166. package/lib/store.js +368 -0
  167. package/lib/store.js.map +1 -0
  168. package/lib/sync.d.ts +220 -0
  169. package/lib/sync.js +810 -0
  170. package/lib/sync.js.map +1 -0
  171. package/lib/tools.d.ts +113 -0
  172. package/lib/tools.js +1090 -0
  173. package/lib/tools.js.map +1 -0
  174. package/lib/treedx/client.d.ts +57 -0
  175. package/lib/treedx/client.js +82 -0
  176. package/lib/treedx/client.js.map +1 -0
  177. package/lib/treedx/provider.d.ts +39 -0
  178. package/lib/treedx/provider.js +479 -0
  179. package/lib/treedx/provider.js.map +1 -0
  180. package/lib/treedx/state.d.ts +27 -0
  181. package/lib/treedx/state.js +65 -0
  182. package/lib/treedx/state.js.map +1 -0
  183. package/lib/types.d.ts +210 -0
  184. package/lib/types.js +31 -0
  185. package/lib/types.js.map +1 -0
  186. package/lib/version.d.ts +9 -0
  187. package/lib/version.js +10 -0
  188. package/lib/version.js.map +1 -0
  189. package/lib/vocabulary.d.ts +41 -0
  190. package/lib/vocabulary.js +118 -0
  191. package/lib/vocabulary.js.map +1 -0
  192. package/lib/warnings.d.ts +10 -0
  193. package/lib/warnings.js +18 -0
  194. package/lib/warnings.js.map +1 -0
  195. package/package.json +151 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-loop.js","sourceRoot":"","sources":["../src/prompt-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /** The record grammar: lowercase segments, each starting with a letter or digit (host grammar). */
2
+ export declare const PROMPT_RECORD_TYPE = "plugin:dsh-chapters/prompt";
3
+ /** Projection key — shared with the client through ONE module (src/prompt-keys.ts), never retyped. */
4
+ export { PROMPT_PROJECTION_KEY } from './prompt-keys.ts';
5
+ /** The bar's durable facts, versioned. `v` rides along so a future shape never folds into a lie. */
6
+ export interface PromptPushPayload {
7
+ v: 1;
8
+ status: 'off' | 'analyzing' | 'ready' | 'failed';
9
+ text: string;
10
+ turnSeq: number | null;
11
+ error: string;
12
+ intent: 'worker-step' | 'goal-edit';
13
+ goalRevision: number | null;
14
+ autorun: 'armed' | 'disarmed';
15
+ at: string;
16
+ }
17
+ export declare function promptRecordPayload(facts: Omit<PromptPushPayload, 'v'>): PromptPushPayload;
18
+ /** Projection fold: ours last-wins (each record carries the WHOLE state), anything else is not ours. */
19
+ export declare function foldPromptRecord(state: PromptPushPayload | null, event: {
20
+ type?: unknown;
21
+ data?: unknown;
22
+ } | null | undefined): PromptPushPayload | null;
23
+ /**
24
+ * #218: REAL zod schemas, like the goal projection — the duck-typed `{parse}` shapes passed the
25
+ * server-side fold (the probe measured `stateOf` working) but the CLIENT delivery validates
26
+ * through `wire.viewSchema`, and an object that is not a real schema can fail that validation
27
+ * silently — killing the one hop this transport exists to provide. Same shape as the goal
28
+ * definition: stateSchema, init, apply, wire, stateVersion.
29
+ */
30
+ export declare function promptProjectionDefinition(): unknown;
31
+ export interface PushWriter {
32
+ append(session: unknown, payload: PromptPushPayload): boolean;
33
+ }
34
+ /**
35
+ * Resolve the host's own `appendPluginRecord`, or nothing. The anchor is the host binary
36
+ * (`process.argv[1]`), NOT this module's resolution scope — the probe measured every alternative
37
+ * failing (own copy: foreign class; bare import: realpath into the source tree). Injectable seams
38
+ * for tests; a production call passes nothing and reads the process.
39
+ */
40
+ export declare function resolvePushWriter(seams?: {
41
+ anchor?: string;
42
+ requireFn?: (anchor: string) => {
43
+ resolve(spec: string): string;
44
+ };
45
+ importFn?: (resolved: string) => Promise<Record<string, unknown>>;
46
+ log?: (message: string) => void;
47
+ }): Promise<PushWriter | null>;
@@ -0,0 +1,115 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ /**
10
+ * The push transport (#194): the bar's state as a durable plugin record + a projection fold.
11
+ *
12
+ * Probe-verified on host 0.2.1-rc.5 (spikes/push-probe/FINDINGS.md — four real boots):
13
+ * - `appendPluginRecord` commits `ignorable: true` records; unknown `plugin:` types are skipped by
14
+ * readers and rendered by nothing, so the steady state writes ZERO history nodes.
15
+ * - The function MUST come from the host's own module instance: the plugin's own copy at the
16
+ * IDENTICAL version throws `Receiver must be an instance of class Session` against a host
17
+ * session, and a bare import from a `link:` install resolves by realpath into the source tree
18
+ * (on a dev machine: a different host checkout than the running server). Hence the host-anchored
19
+ * createRequire recipe below, one try behind try/catch, failure = pull fallback for the process.
20
+ * - The projection is registered ONLY when the writer resolved — registration is the feature
21
+ * signal the client reads through the standard `useProjection` seat (undefined ⇒ pull schedule).
22
+ */
23
+ import { createRequire } from 'node:module';
24
+ import { z } from 'zod';
25
+ /** The record grammar: lowercase segments, each starting with a letter or digit (host grammar). */
26
+ export const PROMPT_RECORD_TYPE = 'plugin:dsh-chapters/prompt';
27
+ /** Projection key — shared with the client through ONE module (src/prompt-keys.ts), never retyped. */
28
+ export { PROMPT_PROJECTION_KEY } from "./prompt-keys.js";
29
+ import { PROMPT_PROJECTION_KEY } from "./prompt-keys.js";
30
+ export function promptRecordPayload(facts) {
31
+ return { v: 1, ...facts };
32
+ }
33
+ /** Projection fold: ours last-wins (each record carries the WHOLE state), anything else is not ours. */
34
+ export function foldPromptRecord(state, event) {
35
+ if (event === null || event === undefined)
36
+ return state;
37
+ if (event.type !== PROMPT_RECORD_TYPE)
38
+ return state;
39
+ const d = event.data;
40
+ if (d === undefined || d === null || d.v !== 1 || typeof d.status !== 'string')
41
+ return state;
42
+ return d;
43
+ }
44
+ /**
45
+ * The projection definition, duck-typed schemas included (the probe measured that the host's
46
+ * register accepts `{parse}` shapes; zod is not required and would be a second schema system here).
47
+ * Kept a value builder so the wiring can register it only when the writer resolved.
48
+ */
49
+ const promptPayloadSchema = z.object({
50
+ v: z.literal(1),
51
+ status: z.enum(['off', 'analyzing', 'ready', 'failed']),
52
+ text: z.string(),
53
+ turnSeq: z.number().nullable(),
54
+ error: z.string(),
55
+ intent: z.enum(['worker-step', 'goal-edit']),
56
+ goalRevision: z.number().nullable(),
57
+ autorun: z.enum(['armed', 'disarmed']),
58
+ at: z.string(),
59
+ });
60
+ /**
61
+ * #218: REAL zod schemas, like the goal projection — the duck-typed `{parse}` shapes passed the
62
+ * server-side fold (the probe measured `stateOf` working) but the CLIENT delivery validates
63
+ * through `wire.viewSchema`, and an object that is not a real schema can fail that validation
64
+ * silently — killing the one hop this transport exists to provide. Same shape as the goal
65
+ * definition: stateSchema, init, apply, wire, stateVersion.
66
+ */
67
+ export function promptProjectionDefinition() {
68
+ return {
69
+ key: PROMPT_PROJECTION_KEY,
70
+ stateSchema: promptPayloadSchema.nullable(),
71
+ init: () => null,
72
+ apply: (state, event) => foldPromptRecord(state, event),
73
+ wire: { viewSchema: promptPayloadSchema.nullable(), view: (s) => s },
74
+ stateVersion: 2,
75
+ };
76
+ }
77
+ /**
78
+ * Resolve the host's own `appendPluginRecord`, or nothing. The anchor is the host binary
79
+ * (`process.argv[1]`), NOT this module's resolution scope — the probe measured every alternative
80
+ * failing (own copy: foreign class; bare import: realpath into the source tree). Injectable seams
81
+ * for tests; a production call passes nothing and reads the process.
82
+ */
83
+ export async function resolvePushWriter(seams) {
84
+ const anchor = seams?.anchor ?? process.argv[1] ?? process.execPath;
85
+ try {
86
+ const req = seams?.requireFn ?? ((a) => createRequire(a));
87
+ const resolved = req(anchor).resolve('@deepseek-ai/dsh-session');
88
+ const mod = await (seams?.importFn ?? ((r) => import(__rewriteRelativeImportExtension(r))))(resolved);
89
+ const fn = mod.appendPluginRecord ?? mod.default?.appendPluginRecord;
90
+ if (typeof fn !== 'function') {
91
+ seams?.log?.(`prompt push: host module resolved but appendPluginRecord is absent (${resolved}) — pull transport stands`);
92
+ return null;
93
+ }
94
+ const append = fn;
95
+ return {
96
+ append(session, payload) {
97
+ try {
98
+ append(session, PROMPT_RECORD_TYPE, payload);
99
+ return true;
100
+ }
101
+ catch (error) {
102
+ // A failed append is a degraded push, never a crashed bar: the row write already happened,
103
+ // the client's staleness-confirm pull covers the gap, and the reason is logged (#61).
104
+ seams?.log?.(`prompt push: append failed (${String(error?.message ?? error).slice(0, 140)}) — the pull schedule covers this session`);
105
+ return false;
106
+ }
107
+ },
108
+ };
109
+ }
110
+ catch (error) {
111
+ seams?.log?.(`prompt push: unavailable on this host (${String(error?.message ?? error).slice(0, 140)}) — pull transport stands`);
112
+ return null;
113
+ }
114
+ }
115
+ //# sourceMappingURL=prompt-push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-push.js","sourceRoot":"","sources":["../src/prompt-push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { type PromptSuggestionState } from './prompt-state.ts';
2
+ import type { SessionState } from './registry.ts';
3
+ export interface GenerateOutcome {
4
+ ok: boolean;
5
+ text?: string;
6
+ /** #113: the goal revision this offer was generated against (null = no goal). A later edit bumps it, and
7
+ * an outstanding offer made under the OLD revision must not run — that is how a re-cut objective interrupts
8
+ * the loop instead of being bulldozed by last cycle's directive. */
9
+ goalRevision?: number | null;
10
+ /** Present when !ok && !quiet: what actually went wrong. */
11
+ reason?: string;
12
+ /** True for "there is nothing to recommend yet" — stored as `off`, never as an error. */
13
+ quiet?: boolean;
14
+ }
15
+ export interface PromptRunnerDeps {
16
+ /** The model IS the switch: false ⇒ the door is inert and writes nothing at all. */
17
+ enabled: () => boolean;
18
+ /** Session eligibility: root, interactive, preset-mounted. Headless children never pay the call. */
19
+ eligible: (session: {
20
+ id: string;
21
+ header?: Record<string, unknown>;
22
+ }) => boolean;
23
+ store: {
24
+ mutate(sessionId: string, fn: (state: SessionState) => SessionState): Promise<unknown>;
25
+ };
26
+ generate: (session: {
27
+ id: string;
28
+ header?: Record<string, unknown>;
29
+ }, turnSeq: number) => Promise<GenerateOutcome>;
30
+ /**
31
+ * Called after a `ready` offer is durably written, with the state as written. The autorun loop rides this
32
+ * rather than polling the row: firing on a persisted offer is what makes "the offer the human would have
33
+ * seen" and "the offer that ran" the same fact, and a loop that fires from its own memory can outrun the
34
+ * row it is supposed to be showing.
35
+ */
36
+ onReady?: (sessionId: string, state: PromptSuggestionState) => void;
37
+ /** #194: mirror every durable row write to the push transport. The wiring owns payload assembly
38
+ * and ordering; the runner only reports (session, id) at each write. Failures here must never
39
+ * affect the round — the pull schedule and its staleness confirm cover a dead push. */
40
+ pushRow?: (session: unknown, sessionId: string) => void;
41
+ now: () => string;
42
+ log?: (message: string) => void;
43
+ warn?: (message: string) => void;
44
+ }
45
+ export declare function makePromptRoundRunner(deps: PromptRunnerDeps): (session: {
46
+ id: string;
47
+ header?: Record<string, unknown>;
48
+ }, event: unknown) => void;
@@ -0,0 +1,90 @@
1
+ import { classifyOffer, noSuggestion } from "./prompt-state.js";
2
+ export function makePromptRoundRunner(deps) {
3
+ const chains = new Map();
4
+ const section = (id, job) => {
5
+ const prev = chains.get(id) ?? Promise.resolve();
6
+ const next = prev.then(job, job);
7
+ chains.set(id, next.then(() => undefined, () => undefined));
8
+ };
9
+ const write = async (id, next) => {
10
+ await deps.store.mutate(id, (row) => ({ ...row, promptSuggestion: next }));
11
+ };
12
+ return (session, event) => {
13
+ try {
14
+ const ev = event;
15
+ if (ev?.type !== 'turn/end' || typeof ev.seq !== 'number')
16
+ return;
17
+ // Each early return NAMED, because "the bar never updates" has three different causes and only one of
18
+ // them is a switch the human set. Silent guards are how tonight took a day.
19
+ if (!deps.enabled()) {
20
+ deps.log?.('prompt: not enabled (no defining model) — round skipped');
21
+ return;
22
+ }
23
+ if (!deps.eligible(session)) {
24
+ deps.log?.(`prompt: session ${String(session.id)} not eligible — round skipped`);
25
+ return;
26
+ }
27
+ const id = session.id;
28
+ const turnSeq = ev.seq;
29
+ section(id, async () => {
30
+ // Claim the turn inside the mutate: the row is the only place "have I already done this turn?" can
31
+ // be answered after a restart, and the decision must see the LIVE row, not a snapshot.
32
+ let claimed = false;
33
+ await deps.store.mutate(id, (row) => {
34
+ const cur = row.promptSuggestion ?? noSuggestion;
35
+ const inFlightForThisTurn = cur.turnSeq === turnSeq && (cur.status === 'analyzing' || cur.status === 'ready' || cur.status === 'failed');
36
+ if (inFlightForThisTurn) {
37
+ claimed = false;
38
+ return row;
39
+ }
40
+ claimed = true;
41
+ return { ...row, promptSuggestion: { ...noSuggestion, status: 'analyzing', turnSeq, at: deps.now() } };
42
+ });
43
+ if (!claimed) {
44
+ deps.log?.(`prompt: turn ${String(turnSeq)} already claimed for ${id}`);
45
+ return;
46
+ }
47
+ deps.pushRow?.(session, id);
48
+ try {
49
+ const out = await deps.generate(session, turnSeq);
50
+ if (out.ok && typeof out.text === 'string' && out.text !== '') {
51
+ // Classified HERE, at the moment of authorship: intent is a property of the durable offer, so the
52
+ // bar, the `state` verb and the loop read the same fact instead of re-parsing the text three ways
53
+ // (one predicate per decision, #59). The `GOAL:` prefix is stripped — the worker must never be
54
+ // handed protocol scaffolding as if it were the human's own words.
55
+ const offer = classifyOffer(out.text);
56
+ const ready = {
57
+ status: 'ready', text: offer.text, turnSeq, error: '', at: deps.now(),
58
+ intent: offer.intent, goalRevision: out.goalRevision ?? null,
59
+ };
60
+ await write(id, ready);
61
+ deps.pushRow?.(session, id);
62
+ deps.log?.(`prompt: recommended next step ready for ${id} (turn ${String(turnSeq)}, ${offer.intent})`);
63
+ deps.onReady?.(id, ready);
64
+ return;
65
+ }
66
+ if (out.quiet === true) {
67
+ await write(id, { ...noSuggestion, turnSeq: null });
68
+ deps.pushRow?.(session, id);
69
+ deps.log?.(`prompt: nothing to recommend for ${id} — bar stays silent`);
70
+ return;
71
+ }
72
+ await write(id, { ...noSuggestion, status: 'failed', turnSeq, error: out.reason ?? 'the suggestion call returned nothing', at: deps.now() });
73
+ deps.pushRow?.(session, id);
74
+ deps.warn?.(`prompt: generation failed for ${id}: ${out.reason ?? 'unknown'}`);
75
+ }
76
+ catch (error) {
77
+ // A failed generation is a DELIVERED failure (#61): the bar shows it, it does not vanish.
78
+ const message = String(error?.message ?? error).slice(0, 200);
79
+ await write(id, { ...noSuggestion, status: 'failed', turnSeq, error: message, at: deps.now() }).catch(() => undefined);
80
+ deps.pushRow?.(session, id);
81
+ deps.warn?.(`prompt: generation threw for ${id}: ${message}`);
82
+ }
83
+ });
84
+ }
85
+ catch (error) {
86
+ deps.warn?.(`prompt: turn listener failed: ${String(error?.message ?? error).slice(0, 160)}`);
87
+ }
88
+ };
89
+ }
90
+ //# sourceMappingURL=prompt-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-runner.js","sourceRoot":"","sources":["../src/prompt-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Reading the session's goal, so a suggestion can serve it (#113).
3
+ *
4
+ * The durable-log shape is measured, not assumed — from a live session's own `goal/change` events:
5
+ * { kind:'goal/change', version:1, operation:'create'|'resume'|'pause'|…,
6
+ * goal:{ id, revision, objective, phase:'active'|'paused'|…, maxGoalRounds } }
7
+ * and goal rounds themselves arrive as `user/message` with `source.kind:'goal'` carrying
8
+ * `{goalId, revision, round}`. So the goal is readable from the log with no service dependency, which is how
9
+ * this plugin works everywhere else (durable reads, never a guessed API).
10
+ *
11
+ * Why it matters: a suggested next step that ignores an active goal is noise. The maintainer's rule is that
12
+ * the two compose — the suggestion runs alongside the goal and the loop yields when the purpose ends.
13
+ */
14
+ import type { SessionEventLike } from './types.ts';
15
+ export type GoalPhaseView = 'none' | 'active' | 'paused' | 'blocked' | 'complete';
16
+ export interface ActiveGoal {
17
+ id: string;
18
+ revision: number;
19
+ objective: string;
20
+ phase: GoalPhaseView;
21
+ maxGoalRounds: number | null;
22
+ }
23
+ /**
24
+ * The newest goal declaration in the events, or null when the session has no goal.
25
+ *
26
+ * A malformed or partial row is SKIPPED rather than thrown on: this is host-authored data crossing a plugin
27
+ * boundary, and one unexpected row must not take the bar (or the archive) down with it.
28
+ *
29
+ * The operation vocabulary is now established from the shipped types — `GoalOperation =
30
+ * 'create'|'edit'|'pause'|'resume'|'complete'|'block'|'clear'` (`dsh-goal/lib/types/domain.d.ts:12`) — so
31
+ * `clear` (which carries `cleared: GoalRef`, not `goal`) is the real terminal removal. `delete`/`remove` are
32
+ * still accepted defensively: when I first wrote this I could not see the type, and a reader should not have
33
+ * to trust that a host rename would not silently resurrect a finished goal.
34
+ *
35
+ * LIVE reads should prefer the host's own accessors over this fold — `ctx.get('goals').get(agent)` for a
36
+ * `GoalView` (which also carries `roundsStarted` and the process-local `activation`), or
37
+ * `ctx.sessionProjections.stateOf(session,'goal')` the way `tools.ts` already reads `agentPreset`. This
38
+ * function exists for the paths that have only the log: repair, distill, and tests.
39
+ */
40
+ export declare function readActiveGoal(events: readonly SessionEventLike[]): ActiveGoal | null;
41
+ /** Whether the autorun loop still has a purpose to serve: armed means run on, anything else means stand down. */
42
+ export declare function goalAuthorizesAutorun(goal: ActiveGoal | null): boolean;
43
+ /**
44
+ * The goal block folded into the suggestion input. Written as a constraint on the NEXT step, not a restated
45
+ * objective: the model already has the conversation, and what it cannot see is that a goal governs this one.
46
+ */
47
+ export declare function goalDirectiveOf(goal: ActiveGoal | null): string;
48
+ /**
49
+ * The bar's durable facts, as stored on the session row (#113). `turnSeq` is the identity of an offer:
50
+ * it is the `turn/end` seq the suggestion was generated FOR, which is what makes "one generation per
51
+ * turn" idempotent across a re-delivered event, a restart, or a second pull by the client.
52
+ *
53
+ * Deliberately absent: `autorun` and `expanded`. Those are the client's process-local intent — the goal
54
+ * bar's `activation` in everything but name — and persisting them would let a loop resume itself across a
55
+ * restart, which is the property the host's goal driver explicitly does NOT have.
56
+ */
57
+ export interface PromptSuggestionState {
58
+ status: 'off' | 'analyzing' | 'ready' | 'failed';
59
+ text: string;
60
+ turnSeq: number | null;
61
+ error: string;
62
+ at: string;
63
+ /** #113: what kind of step this is. `goal-edit` re-cuts the standing objective, which the host reserves for
64
+ * a human turn, so autorun must never act on it. Measured: `dsh-tool-goal`'s `requireDirectHuman` gates
65
+ * create/edit/pause/resume on `source.kind === 'user'` in the open turn. */
66
+ intent: 'worker-step' | 'goal-edit';
67
+ /** The goal `revision` this offer was generated against, or null when no goal was active. A revision bump
68
+ * invalidates an outstanding offer rather than pushing last cycle's directive into a re-cut objective. */
69
+ goalRevision: number | null;
70
+ }
71
+ export declare const noSuggestion: PromptSuggestionState;
72
+ /** What the loop needs to know about the goal RIGHT NOW, from the service (activation is process-local and
73
+ * is not in the log, so this is the only honest source). */
74
+ export interface GoalSignal {
75
+ phase: GoalPhaseView;
76
+ activation: 'armed' | 'disarmed';
77
+ revision: number;
78
+ }
79
+ /**
80
+ * Split the protocol prefix off a suggestion. `GOAL:` means "this step changes the objective" and the human
81
+ * must be the one to send it; anything else is worker execution and may auto-run.
82
+ *
83
+ * Deliberately a PREFIX rule on the model's own one-line answer rather than a second structured call: the
84
+ * suggestion surface already validates one bounded string, and a protocol the model can see in the rules
85
+ * (see `prompt.ts`) costs 5 characters of `promptMaxChars` instead of another auxiliary request.
86
+ */
87
+ export declare function classifyOffer(raw: string): {
88
+ intent: 'worker-step' | 'goal-edit';
89
+ text: string;
90
+ };
91
+ /**
92
+ * Does the host goal driver intend to start the next turn itself? Measured rule (`dsh-goal-round-driver`):
93
+ * it queues a round on idle when `phase === 'active' && activation === 'armed'`. Two loops starting turns at
94
+ * one boundary is a race against the driver's own reservation fence, so when this says yes we yield.
95
+ */
96
+ export declare function goalDriverOwnsTheTurn(goal: GoalSignal | null): boolean;
97
+ /**
98
+ * What the Suggested Next Step bar can ask the server for (#113), and the single shape the command plane
99
+ * exposes to the client. Kept next to `PromptSuggestionState` rather than in the loop module because the bar
100
+ * and the row are the same contract — a client that can read it can render it.
101
+ */
102
+ export interface PromptBarAccess {
103
+ read(sessionId: string): Promise<PromptSuggestionState & {
104
+ autorun: 'armed' | 'disarmed';
105
+ fired: number;
106
+ }>;
107
+ /** #231: the DURABLE row alone, no loop status, no side effects — the state verb answers from this
108
+ * whenever a row exists. Null when the session has never been served (the mirror-worthy moment). */
109
+ peekRow(sessionId: string): Promise<(PromptSuggestionState & {
110
+ autorun: 'armed' | 'disarmed';
111
+ fired: number;
112
+ }) | null>;
113
+ /** #229: the heartbeat the SERVER has configured, carried on every state reply so the client's
114
+ * schedule matches the operator's setting without a second channel. Absent ⇒ the client treats
115
+ * it as zero (no ambient clock). */
116
+ quietHeartbeatSec?: number;
117
+ /** #218: mirror a just-served state read into the push transport, so the NEXT mount reads the
118
+ * projection instead of pulling again — discovery self-extinguishes. Optional: a pull-only
119
+ * surface (no writer) simply does not implement it, and the caller's feature check makes that a
120
+ * no-op rather than an error. */
121
+ mirror?: (sessionId: string, session: unknown) => void;
122
+ /** `displaced` is the answer to "who starts the next turn": true when arming this loop also disarmed the
123
+ * goal driver's continuation, so the human is told which engine they just opted into. */
124
+ setAutorun(sessionId: string, on: boolean, session?: unknown): {
125
+ autorun: 'armed' | 'disarmed';
126
+ fired: number;
127
+ displaced: boolean;
128
+ };
129
+ /** #113: the bar's Run. Submits the offer on screen as a HUMAN-authored user turn, through the same
130
+ * follow-up path autorun uses — one behavior for "run it", whether a keystroke or the loop came first. */
131
+ runNow(sessionId: string, session?: unknown): Promise<{
132
+ ok: boolean;
133
+ text?: string;
134
+ reason?: string;
135
+ }>;
136
+ /** #225: `/chapters-prompt suggest` writes its answer INTO the row (and mirrors the record where
137
+ * push exists), so an explicit request lands on the bar instead of a fenced block to copy by hand. */
138
+ setSuggested?(sessionId: string, text: string, session?: unknown): Promise<void>;
139
+ disarmHuman(sessionId: string, session?: unknown): void;
140
+ setOff(sessionId: string, session?: unknown): Promise<void>;
141
+ setOn(sessionId: string, session?: unknown): Promise<void>;
142
+ }
@@ -0,0 +1,101 @@
1
+ const isStr = (v) => typeof v === 'string' && v.length > 0;
2
+ /**
3
+ * The newest goal declaration in the events, or null when the session has no goal.
4
+ *
5
+ * A malformed or partial row is SKIPPED rather than thrown on: this is host-authored data crossing a plugin
6
+ * boundary, and one unexpected row must not take the bar (or the archive) down with it.
7
+ *
8
+ * The operation vocabulary is now established from the shipped types — `GoalOperation =
9
+ * 'create'|'edit'|'pause'|'resume'|'complete'|'block'|'clear'` (`dsh-goal/lib/types/domain.d.ts:12`) — so
10
+ * `clear` (which carries `cleared: GoalRef`, not `goal`) is the real terminal removal. `delete`/`remove` are
11
+ * still accepted defensively: when I first wrote this I could not see the type, and a reader should not have
12
+ * to trust that a host rename would not silently resurrect a finished goal.
13
+ *
14
+ * LIVE reads should prefer the host's own accessors over this fold — `ctx.get('goals').get(agent)` for a
15
+ * `GoalView` (which also carries `roundsStarted` and the process-local `activation`), or
16
+ * `ctx.sessionProjections.stateOf(session,'goal')` the way `tools.ts` already reads `agentPreset`. This
17
+ * function exists for the paths that have only the log: repair, distill, and tests.
18
+ */
19
+ export function readActiveGoal(events) {
20
+ let current = null;
21
+ for (const ev of events) {
22
+ if (ev.type !== 'goal/change')
23
+ continue;
24
+ const data = (ev.data ?? {});
25
+ const operation = isStr(data.operation) ? data.operation : '';
26
+ if (operation === 'clear' || operation === 'delete' || operation === 'remove') {
27
+ current = null;
28
+ continue;
29
+ }
30
+ const goal = (data.goal ?? {});
31
+ if (!isStr(goal.id) || !isStr(goal.objective))
32
+ continue;
33
+ const rawPhase = isStr(goal.phase) ? goal.phase : 'active';
34
+ const phase = rawPhase === 'paused' ? 'paused'
35
+ : rawPhase === 'blocked' ? 'blocked'
36
+ : rawPhase === 'complete' ? 'complete'
37
+ : 'active';
38
+ const merged = {
39
+ id: goal.id,
40
+ revision: Number.isFinite(goal.revision) ? goal.revision : (current?.revision ?? 0),
41
+ objective: goal.objective,
42
+ // A later terminal phase must not be resurrected by an unrelated row: complete is sticky per id.
43
+ phase: current !== null && current.id === goal.id && current.phase === 'complete' ? 'complete' : phase,
44
+ maxGoalRounds: Number.isFinite(goal.maxGoalRounds) ? goal.maxGoalRounds : null,
45
+ };
46
+ current = operation === 'complete' ? { ...merged, phase: 'complete' } : merged;
47
+ }
48
+ return current === null || current.phase === 'complete' ? null : current;
49
+ }
50
+ /** Whether the autorun loop still has a purpose to serve: armed means run on, anything else means stand down. */
51
+ export function goalAuthorizesAutorun(goal) {
52
+ return goal !== null && goal.phase === 'active';
53
+ }
54
+ /**
55
+ * The goal block folded into the suggestion input. Written as a constraint on the NEXT step, not a restated
56
+ * objective: the model already has the conversation, and what it cannot see is that a goal governs this one.
57
+ */
58
+ export function goalDirectiveOf(goal) {
59
+ if (goal === null)
60
+ return 'No goal is active for this session. Recommend the next step the work itself calls for.';
61
+ return [
62
+ // #188 invariant: the objective rides WHOLE. The slice(0, 600) that stood here was itself the
63
+ // truncation the contract forbids — real objectives exceed 600 chars (the one this repo's own
64
+ // session ran under was ~1,200), and a director steering against half an objective is the exact
65
+ // hallucination invite zero-truncation exists to forbid. The assembly's budget handles size:
66
+ // the goal block is protected, and a protected set that cannot fit refuses with the numbers.
67
+ `An ACTIVE GOAL governs this session (revision ${String(goal.revision)}): ${goal.objective}`,
68
+ 'The recommended next step MUST advance that goal — a step that merely continues current work does not count.',
69
+ 'If the goal is already accomplished, recommend the step that closes it out (mark it complete) rather than another round.',
70
+ ].join('\n');
71
+ }
72
+ export const noSuggestion = { status: 'off', text: '', turnSeq: null, error: '', at: '', intent: 'worker-step', goalRevision: null };
73
+ /**
74
+ * Split the protocol prefix off a suggestion. `GOAL:` means "this step changes the objective" and the human
75
+ * must be the one to send it; anything else is worker execution and may auto-run.
76
+ *
77
+ * Deliberately a PREFIX rule on the model's own one-line answer rather than a second structured call: the
78
+ * suggestion surface already validates one bounded string, and a protocol the model can see in the rules
79
+ * (see `prompt.ts`) costs 5 characters of `promptMaxChars` instead of another auxiliary request.
80
+ */
81
+ export function classifyOffer(raw) {
82
+ const t = raw.trim();
83
+ const m = /^GOAL\s*:\s*/i.exec(t);
84
+ if (m === null)
85
+ return { intent: 'worker-step', text: t };
86
+ const rest = t.slice(m[0].length).trim();
87
+ // `GOAL:` with nothing after it is not a re-cut; treat it as a worker step so an empty protocol never
88
+ // blocks the loop with a phantom "needs you" offer.
89
+ if (rest === '')
90
+ return { intent: 'worker-step', text: t };
91
+ return { intent: 'goal-edit', text: rest };
92
+ }
93
+ /**
94
+ * Does the host goal driver intend to start the next turn itself? Measured rule (`dsh-goal-round-driver`):
95
+ * it queues a round on idle when `phase === 'active' && activation === 'armed'`. Two loops starting turns at
96
+ * one boundary is a race against the driver's own reservation fence, so when this says yes we yield.
97
+ */
98
+ export function goalDriverOwnsTheTurn(goal) {
99
+ return goal !== null && goal.phase === 'active' && goal.activation === 'armed';
100
+ }
101
+ //# sourceMappingURL=prompt-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-state.js","sourceRoot":"","sources":["../src/prompt-state.ts"],"names":[],"mappings":"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"}