@fractalsynapse/dsh-chapters 0.0.0-stage → 0.2.21

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 -3
package/lib/index.d.ts ADDED
@@ -0,0 +1,241 @@
1
+ import Schema from '@deepseek-ai/schemastery';
2
+ import { type PresetRegistryLike } from './preset.ts';
3
+ import { type SyncScheduler } from './sync.ts';
4
+ /** The cordis surface this entry touches; widened in later stages. */
5
+ interface HostCtx {
6
+ logger?: {
7
+ info?: (message: string) => void;
8
+ warn?: (message: string) => void;
9
+ };
10
+ get?: (name: string) => unknown;
11
+ /** Cordis event subscription — door 5 registers the subagent-end listener here. */
12
+ on?: (name: string, fn: (info: never) => void) => unknown;
13
+ effect?: (fn: () => void, label?: string) => void;
14
+ agents?: unknown;
15
+ tools?: {
16
+ register(def: unknown): () => void;
17
+ };
18
+ sessionProjections?: {
19
+ stateOf(session: unknown, key: string): unknown;
20
+ };
21
+ llm?: {
22
+ resolveModelInfo(provider: string, model: string, signal?: AbortSignal): Promise<{
23
+ context?: {
24
+ contextWindow?: number;
25
+ };
26
+ } | undefined>;
27
+ stream?: (opts: unknown) => AsyncIterable<unknown>;
28
+ /** #173 catalog discovery — host-shaped: listProviders is SYNC (the host's own
29
+ * list_subagent_models tool consumes it that way), listModels is the advisory catalog. */
30
+ listProviders?: () => readonly {
31
+ id: string;
32
+ name: string;
33
+ }[];
34
+ listModels?: (provider: string) => Promise<readonly {
35
+ provider: string;
36
+ id: string;
37
+ name: string;
38
+ description?: string;
39
+ }[]>;
40
+ };
41
+ }
42
+ export interface Config {
43
+ /** @deprecated the preset is a declaration row now (`preset-chapters` in
44
+ * cordis.patch.yml); `disabled: true` on that row is the switch, and the engine
45
+ * threshold is `thresholdRatio` on its realm row. Accepted so an old profile patch
46
+ * keeps parsing — nothing reads it. */
47
+ installChaptersPreset: boolean;
48
+ /** @deprecated see above; row config, not host config. */
49
+ compactionThresholdRatio: number;
50
+ artifactStoreRoot: string;
51
+ chapterTokenTarget: number;
52
+ toolResultDeferFloorTokens: number;
53
+ continuationBudgetRatio: number;
54
+ fallbackPreset: string;
55
+ mergeThreshold: number;
56
+ /**
57
+ * Door 5 (issue #47): archive a chapters-preset subagent's completed turns when
58
+ * its run settles (`subagent/end`). Save-only — no session, no compaction,
59
+ * enrichment queued never run. false = the listener never registers.
60
+ */
61
+ subagentAutoSave: boolean;
62
+ chapterLimit: number;
63
+ /** Past `chapterTokenTarget × this` a door refuses the archive (#59). ≥1; 2 by default. */
64
+ chapterOversizeFactor: number;
65
+ /**
66
+ * #61 loudness. How many warning TEXTS a door prints before switching to `…and M more`. The field
67
+ * failure was delivery, not detection: 86 warnings — naming a hollow chapter and an unarchived
68
+ * 0-4082 hole — reached a human as `(86 warning(s))`.
69
+ */
70
+ warningsDisplayCap: number;
71
+ /**
72
+ * #61: token ceiling on the oversized-result candidate list `chapters_segment` returns. Measured at
73
+ * 49,932 chars emitted while ALSO reporting `Omitted 275266 bytes`, ≈81K est tokens into a 32K-class
74
+ * window — the model was asked to judge a list it never received.
75
+ */
76
+ segmentCandidateCapTokens: number;
77
+ /**
78
+ * #61: where door/child failures are appended. Empty (the default) resolves to
79
+ * `<store-root>/diagnostics.log`; the literal `off` disables the file sink, and
80
+ * `DSH_CHAPTERS_ENGINE_ERRORS` overrides everything. Before this, unset meant NO TRACE ON DISK.
81
+ */
82
+ diagnosticsLog: string;
83
+ diagnosticsMaxBytes: number;
84
+ /** Plans (docs/plans-carriage.md § 7): verbatim plan chars shown in a chapter,
85
+ * the tool-call-argument artifact floor (0 = off), and whether the notice
86
+ * carries the `## Plans on this path` block. */
87
+ planInlineChars: number;
88
+ callArgArtifactTokens: number;
89
+ plansInNotice: boolean;
90
+ /** Teach the child its lookup verbs (read / chapters_artifact / chapters_search). */
91
+ retrievalHints: boolean;
92
+ /** Seed plan mode into continuation children (plans-carriage § 10). */
93
+ planSeedMode: boolean;
94
+ /** Carry the operative plan into every in-place checkpoint (§ 9). */
95
+ plansInCheckpoint: boolean;
96
+ planCheckpointChars: number;
97
+ harnessId: string;
98
+ /** §12: the project's knowledge repo URL ('' = rely on /chapters-link). */
99
+ knowledgeRemote: string;
100
+ /** §12: wins over the §2.3 derivation. */
101
+ projectKeyOverride: string;
102
+ /** §12: coalesce window for post-archive pushes. */
103
+ syncDebounceMs: number;
104
+ /** §12: default pack size for chapters_search. */
105
+ searchDefaultMaxTokens: number;
106
+ /** P2 §12: enrichment kill switch (auto triggers live on the realm plane;
107
+ * the host plane's queue is manual-only so nothing ever double-runs). */
108
+ enrichmentEnabled: boolean;
109
+ /** 'provider/model' or '' = conversation/stored route (record §6). */
110
+ enrichmentModel: string;
111
+ enrichmentIdleMs: number;
112
+ /** One auxiliary completion budget: annotation+mining and the conflicts report.
113
+ * Must cover reasoning tokens, not just the visible JSON (record §6.1, #50). */
114
+ enrichmentMaxTokens: number;
115
+ enrichmentBatchCap: number;
116
+ /** P2 §6.3 vocabulary pass (shadow by default). */
117
+ vocabApply: boolean;
118
+ vocabCoMin: number;
119
+ vocabOverlapMin: number;
120
+ /** P3 §7.3: budget for the notice's core-rules section (refuse, never clip). */
121
+ coreRulesBudgetTokens: number;
122
+ /** P3 §8: search bonus for effective-core rules (per-machine status). */
123
+ rulesCoreBonus: number;
124
+ /** #50 §7.5: deterministic `ADD RULE:` capture into the local session tier. */
125
+ sessionRulesEnabled: boolean;
126
+ /** #50 §7.5: the capture marker, matched at line start of human messages. */
127
+ rulesMarkerPrefix: string;
128
+ /** #50 §7.4: per-tier count caps on rules rendered into a rebuilt head. */
129
+ projectRulesDisplayCap: number;
130
+ /** #50 §7.4: session-tier display cap. */
131
+ sessionRulesDisplayCap: number;
132
+ /** #50 §7.4: topic-overlap selection on; off ⇒ deterministic category→id order. */
133
+ rulesRelevance: boolean;
134
+ /** #50 §7.5: mine standing orders during enrichment. Default ON — background
135
+ * capture is the whole point; the verbatim-quote gate (not a click) is what
136
+ * keeps a guess from steering a session. */
137
+ rulesEnrichment: boolean;
138
+ /** #50 §7.5: per-chapter cap on mined rules. */
139
+ rulesMinedPerChapter: number;
140
+ /** #50 §7.5: mined rules govern on arrival (default true); false holds them for review. */
141
+ rulesAutoActivate: boolean;
142
+ /** #50 §7.5: 'provider/model' for a dedicated mining call; '' ⇒ the annotation pass. */
143
+ rulesModel: string;
144
+ /** #71 site §28: the model that DEFINES the next work. '' ⇒ the feature does
145
+ * not exist; setting one (here or `/chapters-prompt model …`) IS the enable —
146
+ * one knob, no second boolean that could drift against it. */
147
+ promptModel: string;
148
+ /** #71: hard total budget on the assembled suggest input. */
149
+ promptContextChars: number;
150
+ /** #71: cap on the recommendation itself; over-cap ⇒ retry once ⇒ refuse (never truncate). */
151
+ promptMaxChars: number;
152
+ /** #188: share of the prompt model's context window the derived input budget takes. */
153
+ promptContextRatio: number;
154
+ /** #229: seconds between ambient state pulls while the bar is idle — the heartbeat that produced a
155
+ * durable command pair per tick (measured: exact 60.0s gaps on the maintainer's live log). Default
156
+ * ZERO: no ambient clock exists; sanctioned moments (mount discovery, turn-end pulse, visibility)
157
+ * remain. A nonzero value re-arms the heartbeat for hosts that want freshness over silence. */
158
+ promptQuietHeartbeatSec: number;
159
+ /** #113: how many turns an armed autorun may start before it stops and says so. Re-arming does NOT
160
+ * refresh it, so arming cannot become an infinite loop; the budget is per process, like the flag. */
161
+ promptMaxRounds: number;
162
+ /** #117: cap on the printed `/chapters-repair` report, so one dry-run cannot emit 300 KB into a 32K window. */
163
+ repairReportMaxLines: number;
164
+ /** §15 amendment: transport policy — 'auto' dispatches on the remote
165
+ * scheme (treedx+ → TreeDX, anything else → git); an explicit value must
166
+ * match the scheme or the link refuses (never a silent fallback). */
167
+ knowledgeProvider: 'auto' | 'git' | 'treedx';
168
+ /** TreeDX transport tunables (record §12 register: no hardcoded numbers). */
169
+ treedxFetchTimeoutMs: number;
170
+ treedxWorkspaceTtlSeconds: number;
171
+ treedxLeaseRetries: number;
172
+ treedxLeaseRetryDelayMs: number;
173
+ /** Optional CodeGraph integration: auto-detect the CLI on PATH and enrich
174
+ * signatures, search scoring, and enrichment input with structural code
175
+ * intelligence. The integration is invisible to the model — it makes
176
+ * chapters_search return better results, not a competing tool surface.
177
+ * false = hard off. */
178
+ codegraphEnabled: boolean;
179
+ /** Add CodeGraph structural context to enrichment slices. */
180
+ codegraphEnrich: boolean;
181
+ /** Per-symbol search score bonus for chapters with matching codegraphSymbols. */
182
+ codegraphSearchBonus: number;
183
+ }
184
+ export declare const Config: Schema<Config>;
185
+ export declare const name = "@fractalsynapse/dsh-chapters";
186
+ export declare const inject: string[];
187
+ export declare function apply(ctx: HostCtx, config: Config): Promise<void>;
188
+ /**
189
+ * The §5 sync loop for the host plane. Auto-link (when `knowledgeRemote` is
190
+ * configured) happens lazily inside resolveProject: a workspace's first
191
+ * archive event finds a project record, so nothing network-shaped runs
192
+ * before anything archives.
193
+ */
194
+ export declare function createScheduler(store: import('./store.ts').RegistryStore, domain: import('./store.ts').DomainLike, config: Config, debounceOverride?: number, onSyncDone?: (cwd: string, ok: boolean) => void, warn?: (m: string) => void): SyncScheduler;
195
+ /**
196
+ * Why delivery is a `register()` call and not a file, in one incident: hosts from
197
+ * 0.1.7-alpha.1 stopped reading `$DSH_HOME/.agent-presets/` — a preset is an
198
+ * `@deepseek-ai/dsh-agent-preset` declaration row — while the plugin kept copying,
199
+ * kept logging that it had mounted, and the preset was simply GONE. That is worse
200
+ * than a crash, because `resume` resolves the preset id recorded in the session's
201
+ * own log and throws `agent-preset/not-found`, so every chapters session became
202
+ * unopenable while its durable log sat there intact and uncorrupted.
203
+ *
204
+ * Shipping the row as a patch layer instead is what a reader will reach for, and it
205
+ * is a boot-breaking choice on the hosts this plugin used to support: `dsh.bundle.patch`
206
+ * as an array throws `ERR_INVALID_ARG_TYPE` at legacy `dsh-app-boot/lib/index.js:853`,
207
+ * an unresolvable row aborts a legacy plugin tree, and `disabled: !!js` cannot gate the
208
+ * row because the Loader evaluates `disabled` before any service is mounted (all three
209
+ * measured). Support floor is 0.2.0 now, so the row is registered here through the
210
+ * host's own `agentPresets.register()` — the same call its declaration-row plugin makes.
211
+ */
212
+ /** What the host roster says about our preset. */
213
+ export type RosterVerdict = {
214
+ state: 'present';
215
+ broken?: string;
216
+ } | {
217
+ state: 'absent';
218
+ rows: string[];
219
+ } | {
220
+ state: 'unknown';
221
+ error: string;
222
+ };
223
+ /** Ask the host which presets exist. Tolerates both shapes the service has
224
+ * offered: the bare row array (`list()`) and the remote envelope (`{presets}`). */
225
+ export declare function readRosterVerdict(presets: {
226
+ list?: () => Promise<unknown>;
227
+ } | undefined, presetId: string): Promise<RosterVerdict>;
228
+ /**
229
+ * The remedy for an absent preset. It is a configuration fact about someone else's tree —
230
+ * a patch layer can be overridden or disabled by a profile we do not own — so the job is to
231
+ * name where to look, never to retry behind the operator's back.
232
+ */
233
+ export declare function rosterRemediation(presetId: string): string;
234
+ /** Deferred boot check: one truthful line about the preset, plus the verdict for the witness.
235
+ * Exported so the four arms of that line are tested without booting a host — the line IS the
236
+ * health signal a user reads, and an untested health signal is how the silent case survived. */
237
+ export declare function reportPresetRoster(ctx: HostCtx, presetId: string): Promise<RosterVerdict>;
238
+ /** One phrase describing what the host's inventory says about the preset's own rows.
239
+ * Never throws: an unavailable inventory must degrade the line, not the boot check. */
240
+ export declare function describeMountedRows(presets: PresetRegistryLike | undefined, presetId: string): Promise<string>;
241
+ export {};