@treeseed/dsh-chapters 0.1.0

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 (119) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +644 -0
  3. package/cordis.patch.yml +88 -0
  4. package/docs/architecture.md +460 -0
  5. package/docs/contract.md +375 -0
  6. package/docs/development.md +437 -0
  7. package/docs/host-compaction-seam.md +117 -0
  8. package/docs/knowledge-repo.md +730 -0
  9. package/docs/provider.md +98 -0
  10. package/docs/verify.md +200 -0
  11. package/lib/archive.d.ts +88 -0
  12. package/lib/archive.js +114 -0
  13. package/lib/archive.js.map +1 -0
  14. package/lib/arrival.d.ts +23 -0
  15. package/lib/arrival.js +86 -0
  16. package/lib/arrival.js.map +1 -0
  17. package/lib/artifact-query.d.ts +53 -0
  18. package/lib/artifact-query.js +130 -0
  19. package/lib/artifact-query.js.map +1 -0
  20. package/lib/client.js +234 -0
  21. package/lib/client.js.map +1 -0
  22. package/lib/commands.d.ts +28 -0
  23. package/lib/commands.js +305 -0
  24. package/lib/commands.js.map +1 -0
  25. package/lib/compose.d.ts +30 -0
  26. package/lib/compose.js +131 -0
  27. package/lib/compose.js.map +1 -0
  28. package/lib/continue-core.d.ts +153 -0
  29. package/lib/continue-core.js +252 -0
  30. package/lib/continue-core.js.map +1 -0
  31. package/lib/engine-core.d.ts +219 -0
  32. package/lib/engine-core.js +405 -0
  33. package/lib/engine-core.js.map +1 -0
  34. package/lib/engine.d.ts +211 -0
  35. package/lib/engine.js +571 -0
  36. package/lib/engine.js.map +1 -0
  37. package/lib/enrich-queue.d.ts +66 -0
  38. package/lib/enrich-queue.js +100 -0
  39. package/lib/enrich-queue.js.map +1 -0
  40. package/lib/enrich-store.d.ts +31 -0
  41. package/lib/enrich-store.js +103 -0
  42. package/lib/enrich-store.js.map +1 -0
  43. package/lib/enrich-wire.d.ts +73 -0
  44. package/lib/enrich-wire.js +209 -0
  45. package/lib/enrich-wire.js.map +1 -0
  46. package/lib/enrich.d.ts +73 -0
  47. package/lib/enrich.js +150 -0
  48. package/lib/enrich.js.map +1 -0
  49. package/lib/gitops.d.ts +107 -0
  50. package/lib/gitops.js +539 -0
  51. package/lib/gitops.js.map +1 -0
  52. package/lib/index.d.ts +81 -0
  53. package/lib/index.js +305 -0
  54. package/lib/index.js.map +1 -0
  55. package/lib/indexing.d.ts +85 -0
  56. package/lib/indexing.js +212 -0
  57. package/lib/indexing.js.map +1 -0
  58. package/lib/injections.d.ts +66 -0
  59. package/lib/injections.js +83 -0
  60. package/lib/injections.js.map +1 -0
  61. package/lib/notice.d.ts +60 -0
  62. package/lib/notice.js +84 -0
  63. package/lib/notice.js.map +1 -0
  64. package/lib/provider.d.ts +44 -0
  65. package/lib/provider.js +66 -0
  66. package/lib/provider.js.map +1 -0
  67. package/lib/redact.d.ts +24 -0
  68. package/lib/redact.js +85 -0
  69. package/lib/redact.js.map +1 -0
  70. package/lib/registry.d.ts +120 -0
  71. package/lib/registry.js +130 -0
  72. package/lib/registry.js.map +1 -0
  73. package/lib/render.d.ts +40 -0
  74. package/lib/render.js +280 -0
  75. package/lib/render.js.map +1 -0
  76. package/lib/repo.d.ts +78 -0
  77. package/lib/repo.js +184 -0
  78. package/lib/repo.js.map +1 -0
  79. package/lib/rules-commands.d.ts +24 -0
  80. package/lib/rules-commands.js +138 -0
  81. package/lib/rules-commands.js.map +1 -0
  82. package/lib/rules.d.ts +90 -0
  83. package/lib/rules.js +185 -0
  84. package/lib/rules.js.map +1 -0
  85. package/lib/search.d.ts +48 -0
  86. package/lib/search.js +152 -0
  87. package/lib/search.js.map +1 -0
  88. package/lib/signature.d.ts +28 -0
  89. package/lib/signature.js +149 -0
  90. package/lib/signature.js.map +1 -0
  91. package/lib/store.d.ts +130 -0
  92. package/lib/store.js +235 -0
  93. package/lib/store.js.map +1 -0
  94. package/lib/sync.d.ts +183 -0
  95. package/lib/sync.js +719 -0
  96. package/lib/sync.js.map +1 -0
  97. package/lib/tools.d.ts +84 -0
  98. package/lib/tools.js +581 -0
  99. package/lib/tools.js.map +1 -0
  100. package/lib/treedx/client.d.ts +57 -0
  101. package/lib/treedx/client.js +82 -0
  102. package/lib/treedx/client.js.map +1 -0
  103. package/lib/treedx/provider.d.ts +39 -0
  104. package/lib/treedx/provider.js +479 -0
  105. package/lib/treedx/provider.js.map +1 -0
  106. package/lib/treedx/state.d.ts +27 -0
  107. package/lib/treedx/state.js +65 -0
  108. package/lib/treedx/state.js.map +1 -0
  109. package/lib/types.d.ts +100 -0
  110. package/lib/types.js +19 -0
  111. package/lib/types.js.map +1 -0
  112. package/lib/vocabulary.d.ts +41 -0
  113. package/lib/vocabulary.js +118 -0
  114. package/lib/vocabulary.js.map +1 -0
  115. package/package.json +132 -0
  116. package/presets/chapters/agent.cordis.yml +272 -0
  117. package/presets/chapters/preset.yml +3 -0
  118. package/presets/probe-roots/agent.cordis.yml +11 -0
  119. package/presets/probe-roots/preset.yml +3 -0
package/lib/index.d.ts ADDED
@@ -0,0 +1,81 @@
1
+ import Schema from '@deepseek-ai/schemastery';
2
+ import { type SyncScheduler } from './sync.ts';
3
+ /** The cordis surface this entry touches; widened in later stages. */
4
+ interface HostCtx {
5
+ logger?: {
6
+ info?: (message: string) => void;
7
+ warn?: (message: string) => void;
8
+ };
9
+ get?: (name: string) => unknown;
10
+ effect?: (fn: () => void, label?: string) => void;
11
+ agents?: unknown;
12
+ tools?: {
13
+ register(def: unknown): () => void;
14
+ };
15
+ sessionProjections?: {
16
+ stateOf(session: unknown, key: string): unknown;
17
+ };
18
+ llm?: {
19
+ resolveModelInfo(provider: string, model: string, signal?: AbortSignal): Promise<{
20
+ context?: {
21
+ contextWindow?: number;
22
+ };
23
+ } | undefined>;
24
+ stream?: (opts: unknown) => AsyncIterable<unknown>;
25
+ };
26
+ }
27
+ export interface Config {
28
+ installChaptersPreset: boolean;
29
+ artifactStoreRoot: string;
30
+ chapterTokenTarget: number;
31
+ toolResultDeferFloorTokens: number;
32
+ continuationBudgetRatio: number;
33
+ fallbackPreset: string;
34
+ mergeThreshold: number;
35
+ chapterLimit: number;
36
+ harnessId: string;
37
+ /** §12: the project's knowledge repo URL ('' = rely on /chapters-link). */
38
+ knowledgeRemote: string;
39
+ /** §12: wins over the §2.3 derivation. */
40
+ projectKeyOverride: string;
41
+ /** §12: coalesce window for post-archive pushes. */
42
+ syncDebounceMs: number;
43
+ /** §12: default pack size for chapters_search. */
44
+ searchDefaultMaxTokens: number;
45
+ /** P2 §12: enrichment kill switch (auto triggers live on the realm plane;
46
+ * the host plane's queue is manual-only so nothing ever double-runs). */
47
+ enrichmentEnabled: boolean;
48
+ /** 'provider/model' or '' = conversation/stored route (record §6). */
49
+ enrichmentModel: string;
50
+ enrichmentIdleMs: number;
51
+ enrichmentBatchCap: number;
52
+ /** P2 §6.3 vocabulary pass (shadow by default). */
53
+ vocabApply: boolean;
54
+ vocabCoMin: number;
55
+ vocabOverlapMin: number;
56
+ /** P3 §7.3: budget for the notice's core-rules section (refuse, never clip). */
57
+ coreRulesBudgetTokens: number;
58
+ /** P3 §8: search bonus for effective-core rules (per-machine status). */
59
+ rulesCoreBonus: number;
60
+ /** §15 amendment: transport policy — 'auto' dispatches on the remote
61
+ * scheme (treedx+ → TreeDX, anything else → git); an explicit value must
62
+ * match the scheme or the link refuses (never a silent fallback). */
63
+ knowledgeProvider: 'auto' | 'git' | 'treedx';
64
+ /** TreeDX transport tunables (record §12 register: no hardcoded numbers). */
65
+ treedxFetchTimeoutMs: number;
66
+ treedxWorkspaceTtlSeconds: number;
67
+ treedxLeaseRetries: number;
68
+ treedxLeaseRetryDelayMs: number;
69
+ }
70
+ export declare const Config: Schema<Config>;
71
+ export declare const name = "@treeseed/dsh-chapters";
72
+ export declare const inject: string[];
73
+ export declare function apply(ctx: HostCtx, config: Config): Promise<void>;
74
+ /**
75
+ * The §5 sync loop for the host plane. Auto-link (when `knowledgeRemote` is
76
+ * configured) happens lazily inside resolveProject: a workspace's first
77
+ * archive event finds a project record, so nothing network-shaped runs
78
+ * before anything archives.
79
+ */
80
+ 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;
81
+ export {};
package/lib/index.js ADDED
@@ -0,0 +1,305 @@
1
+ /**
2
+ * dsh-chapters — cordis entry point (host plane). The ONLY host-facing function
3
+ * plugin; engine logic lives in engine.ts (mounted per preset realm), every
4
+ * decision in the pure modules (docs/development.md § L0).
5
+ *
6
+ * Responsibilities:
7
+ * 1. Install the `chapters` preset into `$DSH_HOME/.agent-presets/` on boot
8
+ * (write-if-missing; user edits are never overwritten). Profile `!!js` has
9
+ * no `require` (measured r20), so copying is the delivery mechanism.
10
+ * 2. Open the dsh_chapters storage domain and register chapters_segment /
11
+ * chapters_continue (src/tools.ts adapts them to the pure core).
12
+ * 3. Witness/dev diagnostics.
13
+ *
14
+ * Protocol notes (each measured, docs/contract.md):
15
+ * - function plugin: named exports `name` / `inject` / `Config` / `apply`;
16
+ * NO default export (mixing forms makes the Loader discard the namespace).
17
+ * - Config uses schemastery (default import) — plain specs are for tool
18
+ * parameters, zod for domain records; never mix.
19
+ */
20
+ import { writeFileSync, mkdirSync, existsSync, cpSync } from 'node:fs';
21
+ import { dirname, join } from 'node:path';
22
+ import { hostname } from 'node:os';
23
+ import { fileURLToPath } from 'node:url';
24
+ import Schema from '@deepseek-ai/schemastery';
25
+ import { dshHomePath } from '@deepseek-ai/dsh-home-paths';
26
+ import { appendChapters, reserve } from "./registry.js";
27
+ import { acquireChapterStore, makeDomainStore } from "./store.js";
28
+ import { registerChaptersTools } from "./tools.js";
29
+ import { registerHostCommands } from "./commands.js";
30
+ import { createEnrichWiring } from "./enrich-wire.js";
31
+ import { rulesCommand } from "./rules-commands.js";
32
+ import { BlockAssembler, createUserMessage } from '@deepseek-ai/dsh-llm';
33
+ import { createSyncScheduler, makeCollectionsReader, projectForCwd, readToken, DEFAULT_CLONE_DIR } from "./sync.js";
34
+ import { parseKnowledgeRemote, projectKeyForTarget, resolveProject } from "./repo.js";
35
+ import { providerKindFor, registerProvider } from "./provider.js";
36
+ import { createTreedxProvider } from "./treedx/provider.js";
37
+ export const Config = Schema.object({
38
+ // The preset is how the engine reaches real sessions (preset realm mount);
39
+ // turning this off means opting into manual preset authoring instead.
40
+ installChaptersPreset: Schema.boolean().default(true),
41
+ artifactStoreRoot: Schema.string().default('.dsh-chapters'),
42
+ chapterTokenTarget: Schema.number().default(8000),
43
+ toolResultDeferFloorTokens: Schema.number().default(200),
44
+ // Share of the window REMAINING after the header bound — never of the
45
+ // whole window (docs/architecture.md § Budgets).
46
+ continuationBudgetRatio: Schema.number().default(0.25),
47
+ fallbackPreset: Schema.string().default('chapters'),
48
+ // Topic-sequential composition (record §4.2) for the model-free fork path.
49
+ mergeThreshold: Schema.number().default(0.3),
50
+ chapterLimit: Schema.number().default(8000),
51
+ // Per-machine identity for the knowledge repo (commit author + per-harness
52
+ // token scoping, record §2.1). The hostname is the honest default; override
53
+ // per machine when two sessions on one box must be told apart.
54
+ harnessId: Schema.string().default(hostname()),
55
+ // Knowledge repo (record §12): '' leaves linking to /chapters-link; a URL
56
+ // auto-links every workspace on its first archive event.
57
+ knowledgeRemote: Schema.string().default(''),
58
+ projectKeyOverride: Schema.string().default(''),
59
+ syncDebounceMs: Schema.number().default(30000),
60
+ searchDefaultMaxTokens: Schema.number().default(400),
61
+ enrichmentEnabled: Schema.boolean().default(true),
62
+ enrichmentModel: Schema.string().default(''),
63
+ enrichmentIdleMs: Schema.number().default(60000),
64
+ enrichmentBatchCap: Schema.number().default(5),
65
+ vocabApply: Schema.boolean().default(false),
66
+ vocabCoMin: Schema.number().default(3),
67
+ vocabOverlapMin: Schema.number().default(0.5),
68
+ coreRulesBudgetTokens: Schema.number().default(1200),
69
+ rulesCoreBonus: Schema.number().default(0.15),
70
+ // enum-style string (same register as `fallbackPreset`): 'auto' | 'git' |
71
+ // 'treedx', validated at use — schemastery has no literal schema.
72
+ knowledgeProvider: Schema.string().default('auto'),
73
+ treedxFetchTimeoutMs: Schema.number().default(15000),
74
+ treedxWorkspaceTtlSeconds: Schema.number().default(900),
75
+ treedxLeaseRetries: Schema.number().default(3),
76
+ treedxLeaseRetryDelayMs: Schema.number().default(1000),
77
+ });
78
+ export const name = '@treeseed/dsh-chapters';
79
+ export const inject = ['storageDomain', 'tools', 'agents', 'llm', 'sessionProjections'];
80
+ const HERE = dirname(fileURLToPath(import.meta.url));
81
+ const PKG_ROOT = join(HERE, '..');
82
+ export async function apply(ctx, config) {
83
+ if (config.installChaptersPreset)
84
+ installChaptersPreset(ctx);
85
+ let domain;
86
+ try {
87
+ const storageDomain = ctx.get?.('storageDomain');
88
+ if (storageDomain === undefined)
89
+ throw new Error('storageDomain absent');
90
+ const handle = await acquireChapterStore(storageDomain);
91
+ domain = handle.domain;
92
+ const store = handle.store;
93
+ // No close effect here: the facility's own disposer closes domains still
94
+ // open at facility unmount (its documented teardown), and a close effect
95
+ // on the apply fiber fires when THAT fiber is disposed — mid-run, which
96
+ // closed the domain under later commands (r35 caught it). One opener, and
97
+ // the closer is the facility's unmount, not our fiber.
98
+ void handle.owner;
99
+ // §15 amendment: the TreeDX transport, configured and registered in THIS
100
+ // module instance (host plane). The realm engine registers its own copy
101
+ // (separate module instances under isolation) — same code, per-plane.
102
+ registerProvider(createTreedxProvider({
103
+ fetchTimeoutMs: config.treedxFetchTimeoutMs,
104
+ workspaceTtlSeconds: config.treedxWorkspaceTtlSeconds,
105
+ leaseRetries: config.treedxLeaseRetries,
106
+ leaseRetryDelayMs: config.treedxLeaseRetryDelayMs,
107
+ }));
108
+ // P2: host-plane enrichment wiring — command surface + status only
109
+ // (trigger forced manual; the realm engine owns auto drains).
110
+ // The routed model of the last real tool-carrying session on this plane:
111
+ // the host has no live agent, so without this a fork-only flow (never any
112
+ // in-place compaction => realm never captures lastRoute) leaves
113
+ // /chapters-enrich run with no route to call. Persisted immediately so
114
+ // the realm's resolver sees it via the shared settings table too.
115
+ let hostRoute = null;
116
+ const enrich = createEnrichWiring({
117
+ store,
118
+ cwd: () => undefined,
119
+ config: {
120
+ enabled: config.enrichmentEnabled,
121
+ model: config.enrichmentModel,
122
+ trigger: 'manual',
123
+ idleMs: config.enrichmentIdleMs,
124
+ batchCap: config.enrichmentBatchCap,
125
+ },
126
+ fetch: async (prompt, route) => {
127
+ if (route === null)
128
+ throw new Error('no enrichment route resolvable (set /chapters-enrich model … or run a turn first)');
129
+ const llm = ctx.llm;
130
+ if (llm?.stream === undefined)
131
+ throw new Error('llm.stream absent');
132
+ const assembler = new BlockAssembler();
133
+ for await (const chunk of llm.stream({
134
+ provider: route.provider, model: route.model,
135
+ messages: [createUserMessage({ content: [{ type: 'text', text: prompt }], source: { kind: 'plugin', plugin: 'dsh-chapters' } })],
136
+ maxTokens: 900,
137
+ purpose: 'compaction',
138
+ }))
139
+ assembler.push(chunk);
140
+ return assembler.blocks().filter((b) => b.type === 'text').map((b) => b.text ?? '').join('');
141
+ },
142
+ conversationRoute: () => hostRoute,
143
+ log: (m) => ctx.logger?.info?.(`dsh-chapters: ${m}`),
144
+ warn: (m) => ctx.logger?.warn?.(`dsh-chapters: ${m}`),
145
+ });
146
+ const scheduler = createScheduler(store, domain, config, undefined, (cwd, ok) => {
147
+ enrich.rememberCwd(cwd);
148
+ if (ok)
149
+ enrich.queue.onSyncDone('afterPush');
150
+ }, (m) => ctx.logger?.warn?.(m));
151
+ registerChaptersTools(ctx, store, {
152
+ artifactStoreRoot: config.artifactStoreRoot,
153
+ chapterTokenTarget: config.chapterTokenTarget,
154
+ toolResultDeferFloorTokens: config.toolResultDeferFloorTokens,
155
+ continuationBudgetRatio: config.continuationBudgetRatio,
156
+ fallbackPreset: config.fallbackPreset,
157
+ mergeThreshold: config.mergeThreshold,
158
+ chapterLimit: config.chapterLimit,
159
+ searchMaxTokens: config.searchDefaultMaxTokens,
160
+ harnessId: config.harnessId,
161
+ coreRulesBudgetTokens: config.coreRulesBudgetTokens,
162
+ rulesCoreBonus: config.rulesCoreBonus,
163
+ scheduler,
164
+ noteRoute: (r) => {
165
+ hostRoute = r;
166
+ void store.putSetting('enrichment.route', `${r.provider}/${r.model}`).catch(() => undefined);
167
+ },
168
+ });
169
+ registerHostCommands(ctx, domain, {
170
+ artifactStoreRoot: config.artifactStoreRoot,
171
+ harnessId: config.harnessId,
172
+ scheduler,
173
+ enrich,
174
+ rules: (cwd, args) => rulesCommand({
175
+ cwd: () => cwd,
176
+ storeRoot: config.artifactStoreRoot,
177
+ harnessId: config.harnessId,
178
+ store,
179
+ projectFor: (c) => projectForCwd(store.projects(), c),
180
+ mirrorDir: (c) => join(c, DEFAULT_CLONE_DIR),
181
+ syncNow: async (c) => { try {
182
+ await scheduler.run(c, 'rules');
183
+ }
184
+ catch { /* status file records it */ } },
185
+ now: () => new Date(),
186
+ }, args),
187
+ });
188
+ }
189
+ catch (error) {
190
+ // Tools are the whole user-facing surface short of the engine: a failure
191
+ // here is loud, never a silently missing tool. Loud means the operator
192
+ // actually sees it — the realm logger routes to boot stdout (r19/r35 twice
193
+ // burned by a warn nobody could read; the DSH_CHAPTERS_ERRORS sink env is
194
+ // the engine's precedent).
195
+ const message = `dsh-chapters: tool/command registration FAILED (${String(error)})`;
196
+ ctx.logger?.warn?.(message);
197
+ console.error(message);
198
+ }
199
+ ctx.logger?.info?.('dsh-chapters: mounted (preset install + tools registered)');
200
+ const marker = process.env.DSH_CHAPTERS_WITNESS;
201
+ if (marker === undefined)
202
+ return;
203
+ setTimeout(() => { witness(ctx, marker, domain); }, 500).unref?.();
204
+ }
205
+ /**
206
+ * The §5 sync loop for the host plane. Auto-link (when `knowledgeRemote` is
207
+ * configured) happens lazily inside resolveProject: a workspace's first
208
+ * archive event finds a project record, so nothing network-shaped runs
209
+ * before anything archives.
210
+ */
211
+ export function createScheduler(store, domain, config, debounceOverride, onSyncDone, warn) {
212
+ return createSyncScheduler({
213
+ storeRoot: config.artifactStoreRoot,
214
+ cloneDir: DEFAULT_CLONE_DIR,
215
+ debounceMs: debounceOverride ?? config.syncDebounceMs,
216
+ vocab: { apply: config.vocabApply, coMin: config.vocabCoMin, overlapMin: config.vocabOverlapMin },
217
+ ...(onSyncDone !== undefined ? { onSyncDone } : {}),
218
+ resolveProject: (cwd) => {
219
+ const found = projectForCwd(store.projects(), cwd);
220
+ if (found !== undefined)
221
+ return found;
222
+ if (config.knowledgeRemote === '')
223
+ return undefined;
224
+ try {
225
+ const target = parseKnowledgeRemote(config.knowledgeRemote);
226
+ const kind = providerKindFor(target.kind, config.knowledgeProvider);
227
+ const resolved = resolveProject(cwd, config.projectKeyOverride !== '' ? config.projectKeyOverride : undefined, config.knowledgeRemote);
228
+ const rec = {
229
+ // Identity via projectKeyForTarget: §2.3 canonicalization, plus the
230
+ // treedx/ namespace for TreeDX targets (keyed per-machine-stable by
231
+ // construction — that is the whole point of §2.3). The override wins
232
+ // exactly as before.
233
+ projectKey: config.projectKeyOverride !== '' ? resolved.projectKey : projectKeyForTarget(target),
234
+ slug: target.treedx?.repoName ?? (resolved.remote ?? config.knowledgeRemote).split('/').pop().replace(/\.git$/, ''),
235
+ remote: config.knowledgeRemote,
236
+ kind,
237
+ harnessId: config.harnessId,
238
+ linkedAt: new Date().toISOString(),
239
+ cwd,
240
+ };
241
+ domain.table('projects').put(rec.projectKey, rec);
242
+ return rec;
243
+ }
244
+ catch (error) {
245
+ // A policy contradiction (knowledgeProvider vs the remote scheme) is
246
+ // LOUD in the log but never throws into the archive path (§5.3 shape).
247
+ warn?.(`dsh-chapters: knowledgeRemote auto-link refused: ${String(error?.message ?? error)}`);
248
+ return undefined;
249
+ }
250
+ },
251
+ tokenFor: (cwd, projectKey) => readToken(cwd, config.artifactStoreRoot, projectKey),
252
+ collectionsFor: makeCollectionsReader(store.sessions.bind(store), config.artifactStoreRoot),
253
+ });
254
+ }
255
+ // ---------------------------------------------------------------- preset install
256
+ const PRESET_ID = 'chapters';
257
+ const USER_PRESET_DIR = '.agent-presets'; // kernel constant: presets/agent-presets/src/discovery.ts
258
+ function installChaptersPreset(ctx) {
259
+ const srcDir = join(PKG_ROOT, 'presets', PRESET_ID);
260
+ if (!existsSync(srcDir))
261
+ return;
262
+ const dstDir = dshHomePath(USER_PRESET_DIR, PRESET_ID);
263
+ if (existsSync(join(dstDir, 'preset.yml')))
264
+ return; // user-owned from here on; never clobber
265
+ try {
266
+ mkdirSync(join(dshHomePath(), USER_PRESET_DIR), { recursive: true });
267
+ cpSync(srcDir, dstDir, { recursive: true });
268
+ ctx.logger?.info?.(`dsh-chapters: installed the "${PRESET_ID}" preset to ${dstDir} — pick it in the preset menu for chapter-form compaction (standard keeps LLM summaries)`);
269
+ }
270
+ catch (error) {
271
+ ctx.logger?.info?.(`dsh-chapters: preset install FAILED (${String(error)})`);
272
+ }
273
+ }
274
+ // ---------------------------------------------------------------- dev witness
275
+ async function witness(ctx, marker, preopened) {
276
+ const WITNESS_SESSION = 'dsh-chapters-witness';
277
+ const out = { at: new Date().toISOString() };
278
+ try {
279
+ out.storageDomainPresent = ctx.get?.('storageDomain') !== undefined;
280
+ out.presetsInstalled = existsSync(dshHomePath(USER_PRESET_DIR, PRESET_ID, 'preset.yml'));
281
+ const storageDomain = ctx.get?.('storageDomain');
282
+ const store = preopened !== undefined ? makeDomainStore(preopened) : (await acquireChapterStore(storageDomain)).store;
283
+ const prior = await store.get(WITNESS_SESSION);
284
+ out.priorChapters = prior.chapters.length;
285
+ if (prior.chapters.length === 0) {
286
+ const reserved = reserve(prior, 'witness@1', 1);
287
+ const record = {
288
+ number: reserved.numbers[0] ?? 1,
289
+ path: `.dsh-chapters/${WITNESS_SESSION}/chapters/001-witness.md`,
290
+ title: 'witness', summary: `first boot ${new Date().toISOString()}`,
291
+ startSeq: 0, endSeq: 0, topics: [], messages: 0, sha256: '0'.repeat(64), estimatedTokens: 0, artifacts: [],
292
+ };
293
+ await store.put(WITNESS_SESSION, appendChapters(reserved.state, [record]));
294
+ }
295
+ else {
296
+ await store.put(WITNESS_SESSION, prior);
297
+ }
298
+ out.storedChapters = (await store.get(WITNESS_SESSION)).chapters.length;
299
+ }
300
+ catch (error) {
301
+ out.error = String(error);
302
+ }
303
+ writeFileSync(marker, JSON.stringify(out, null, 2));
304
+ }
305
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Layer 2 of the two-layer index (knowledge-repo.md §10.2): the compressed,
3
+ * searchable, sharded index derived from chapter frontmatter + Layer-1
4
+ * curation facts. PURE + DETERMINISTIC: same inputs → same shards, and an
5
+ * empty manifest rebuilds the whole index identically (the recovery path).
6
+ *
7
+ * Shards are one file per canonical topic (alphabetical — bounded files,
8
+ * writes from different chapters usually touch different shards). Layer 1
9
+ * (`edits/<harness>/curation.jsonl`) is where humans and the plugin inject
10
+ * aliases, weights, pins, and group facts; this module applies them.
11
+ */
12
+ export interface IndexEntry {
13
+ /** Repo-relative chapter path (chapters/<key>/<session>/<file>). */
14
+ path: string;
15
+ title: string;
16
+ topics: string[];
17
+ kind: 'chapter' | 'rule';
18
+ /** P3: rule category (chapters omit). */
19
+ category?: string;
20
+ /** Milliseconds; missing → sorts first within its topic shard. */
21
+ mtime?: number;
22
+ /** S5 stitch view: additional member paths (this entry's `path` is the
23
+ * canonical first member). Single-file entries omit it. */
24
+ paths?: string[];
25
+ }
26
+ export declare function stitchFragments(entries: readonly IndexEntry[]): IndexEntry[];
27
+ export type CurationFact = {
28
+ type: 'topic-alias';
29
+ from: string;
30
+ to: string;
31
+ at: string;
32
+ } | {
33
+ type: 'topic-pin';
34
+ topic: string;
35
+ at: string;
36
+ } | {
37
+ type: 'topic-weight';
38
+ topic: string;
39
+ weight: number;
40
+ at: string;
41
+ } | {
42
+ type: 'group';
43
+ topics: string[];
44
+ at: string;
45
+ } | {
46
+ type: 'note';
47
+ topic: string;
48
+ text: string;
49
+ at: string;
50
+ }
51
+ /** P3 §15 amendment: per-machine rule status; index layers ignore it (only rules.ts + the scorer consume it) */
52
+ | {
53
+ type: 'rule-status';
54
+ rule: string;
55
+ status: string;
56
+ at: string;
57
+ };
58
+ export interface IndexManifest {
59
+ [inputPath: string]: {
60
+ hash: string;
61
+ at: string;
62
+ };
63
+ }
64
+ export interface IndexBuild {
65
+ /** topic → shard file content */
66
+ shards: Map<string, string>;
67
+ manifest: IndexManifest;
68
+ /** True when any shard content changed (commit only when true). */
69
+ changed: boolean;
70
+ topics: string[];
71
+ }
72
+ export declare const hashEntry: (e: IndexEntry) => string;
73
+ /** Minimal frontmatter reader for the `key: value` lines render.ts writes. */
74
+ export declare function parseFrontmatter(text: string): Record<string, string | string[]>;
75
+ /** A chapter file's text → IndexEntry (topics from frontmatter, kind from `kind:`). */
76
+ export declare function entryFromChapter(path: string, text: string, mtime?: number): IndexEntry;
77
+ /** Layer-1 parse: one JSON fact per line; malformed lines are skipped (logged by the caller). */
78
+ export declare function parseCuration(text: string): CurationFact[];
79
+ /**
80
+ * Build the sharded index. Aliases canonicalize topics (from→to, transitive),
81
+ * pinned topics sort first inside their position, weights scale the sort
82
+ * within a topic, and the manifest tracks per-entry hashes for the
83
+ * incremental fast path (an empty manifest = full rebuild = identical output).
84
+ */
85
+ export declare function buildIndexShards(entries: readonly IndexEntry[], curation: readonly CurationFact[], manifest?: IndexManifest): IndexBuild;