@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.
- package/LICENSE +14 -0
- package/README.md +644 -0
- package/cordis.patch.yml +88 -0
- package/docs/architecture.md +460 -0
- package/docs/contract.md +375 -0
- package/docs/development.md +437 -0
- package/docs/host-compaction-seam.md +117 -0
- package/docs/knowledge-repo.md +730 -0
- package/docs/provider.md +98 -0
- package/docs/verify.md +200 -0
- package/lib/archive.d.ts +88 -0
- package/lib/archive.js +114 -0
- package/lib/archive.js.map +1 -0
- package/lib/arrival.d.ts +23 -0
- package/lib/arrival.js +86 -0
- package/lib/arrival.js.map +1 -0
- package/lib/artifact-query.d.ts +53 -0
- package/lib/artifact-query.js +130 -0
- package/lib/artifact-query.js.map +1 -0
- package/lib/client.js +234 -0
- package/lib/client.js.map +1 -0
- package/lib/commands.d.ts +28 -0
- package/lib/commands.js +305 -0
- package/lib/commands.js.map +1 -0
- package/lib/compose.d.ts +30 -0
- package/lib/compose.js +131 -0
- package/lib/compose.js.map +1 -0
- package/lib/continue-core.d.ts +153 -0
- package/lib/continue-core.js +252 -0
- package/lib/continue-core.js.map +1 -0
- package/lib/engine-core.d.ts +219 -0
- package/lib/engine-core.js +405 -0
- package/lib/engine-core.js.map +1 -0
- package/lib/engine.d.ts +211 -0
- package/lib/engine.js +571 -0
- package/lib/engine.js.map +1 -0
- package/lib/enrich-queue.d.ts +66 -0
- package/lib/enrich-queue.js +100 -0
- package/lib/enrich-queue.js.map +1 -0
- package/lib/enrich-store.d.ts +31 -0
- package/lib/enrich-store.js +103 -0
- package/lib/enrich-store.js.map +1 -0
- package/lib/enrich-wire.d.ts +73 -0
- package/lib/enrich-wire.js +209 -0
- package/lib/enrich-wire.js.map +1 -0
- package/lib/enrich.d.ts +73 -0
- package/lib/enrich.js +150 -0
- package/lib/enrich.js.map +1 -0
- package/lib/gitops.d.ts +107 -0
- package/lib/gitops.js +539 -0
- package/lib/gitops.js.map +1 -0
- package/lib/index.d.ts +81 -0
- package/lib/index.js +305 -0
- package/lib/index.js.map +1 -0
- package/lib/indexing.d.ts +85 -0
- package/lib/indexing.js +212 -0
- package/lib/indexing.js.map +1 -0
- package/lib/injections.d.ts +66 -0
- package/lib/injections.js +83 -0
- package/lib/injections.js.map +1 -0
- package/lib/notice.d.ts +60 -0
- package/lib/notice.js +84 -0
- package/lib/notice.js.map +1 -0
- package/lib/provider.d.ts +44 -0
- package/lib/provider.js +66 -0
- package/lib/provider.js.map +1 -0
- package/lib/redact.d.ts +24 -0
- package/lib/redact.js +85 -0
- package/lib/redact.js.map +1 -0
- package/lib/registry.d.ts +120 -0
- package/lib/registry.js +130 -0
- package/lib/registry.js.map +1 -0
- package/lib/render.d.ts +40 -0
- package/lib/render.js +280 -0
- package/lib/render.js.map +1 -0
- package/lib/repo.d.ts +78 -0
- package/lib/repo.js +184 -0
- package/lib/repo.js.map +1 -0
- package/lib/rules-commands.d.ts +24 -0
- package/lib/rules-commands.js +138 -0
- package/lib/rules-commands.js.map +1 -0
- package/lib/rules.d.ts +90 -0
- package/lib/rules.js +185 -0
- package/lib/rules.js.map +1 -0
- package/lib/search.d.ts +48 -0
- package/lib/search.js +152 -0
- package/lib/search.js.map +1 -0
- package/lib/signature.d.ts +28 -0
- package/lib/signature.js +149 -0
- package/lib/signature.js.map +1 -0
- package/lib/store.d.ts +130 -0
- package/lib/store.js +235 -0
- package/lib/store.js.map +1 -0
- package/lib/sync.d.ts +183 -0
- package/lib/sync.js +719 -0
- package/lib/sync.js.map +1 -0
- package/lib/tools.d.ts +84 -0
- package/lib/tools.js +581 -0
- package/lib/tools.js.map +1 -0
- package/lib/treedx/client.d.ts +57 -0
- package/lib/treedx/client.js +82 -0
- package/lib/treedx/client.js.map +1 -0
- package/lib/treedx/provider.d.ts +39 -0
- package/lib/treedx/provider.js +479 -0
- package/lib/treedx/provider.js.map +1 -0
- package/lib/treedx/state.d.ts +27 -0
- package/lib/treedx/state.js +65 -0
- package/lib/treedx/state.js.map +1 -0
- package/lib/types.d.ts +100 -0
- package/lib/types.js +19 -0
- package/lib/types.js.map +1 -0
- package/lib/vocabulary.d.ts +41 -0
- package/lib/vocabulary.js +118 -0
- package/lib/vocabulary.js.map +1 -0
- package/package.json +132 -0
- package/presets/chapters/agent.cordis.yml +272 -0
- package/presets/chapters/preset.yml +3 -0
- package/presets/probe-roots/agent.cordis.yml +11 -0
- 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
|
package/lib/index.js.map
ADDED
|
@@ -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;
|