@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,gBAAgB,EAAkB,MAAM,aAAa,CAAA;AAW9D,gFAAgF;AAChF,MAAM,CAAC,MAAM,WAAW,GAAiB;IACvC,GAAG,gBAAgB;IACnB,IAAI,EAAE,KAAK;IACX,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,SAAS,OAAO,CAAC,MAAM,EAAE;CACjD,CAAA;AAED,+EAA+E;AAC/E,2EAA2E;AAC3E,yEAAyE;AACzE,0EAA0E;AAC1E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAA6B,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;AAE5E,MAAM,UAAU,gBAAgB,CAAC,QAAsB;IACrD,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAA+C;IAC5E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAAA;IAClC,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,+BAA+B,OAAO,CAAC,MAAM,GAAG,CAAC,CAAA;IAC9F,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,UAAwB,EAAE,MAAc;IACtE,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,UAAU,CAAA;IACxC,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,qCAAqC,CAAC,CAAA;IAC3F,CAAC;IACD,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,sCAAsC,UAAU,oDAAoD,CAAC,CAAA;IAC1J,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
|
package/lib/redact.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface RedactPattern {
|
|
2
|
+
name: string;
|
|
3
|
+
/** Global regex; the secret is the whole match unless `secretGroup` names a capture group. */
|
|
4
|
+
regex: RegExp;
|
|
5
|
+
/** Capture group holding the secret (e.g. keep `token=`, redact the value). Default: whole match. */
|
|
6
|
+
secretGroup?: number;
|
|
7
|
+
}
|
|
8
|
+
/** Built-in set (record §9). New patterns are config additions, not magic. */
|
|
9
|
+
export declare const DEFAULT_REDACTIONS: readonly RedactPattern[];
|
|
10
|
+
export interface RedactionResult {
|
|
11
|
+
text: string;
|
|
12
|
+
/** Number of secret occurrences replaced. */
|
|
13
|
+
count: number;
|
|
14
|
+
/** Distinct markers produced (for tests/audit; order of first appearance). */
|
|
15
|
+
markers: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Replace every pattern match's secret with its stable marker.
|
|
19
|
+
* `secretGroup` semantics: the named group is the LABEL to keep; the secret
|
|
20
|
+
* is the rest of the match (url-credential-param, bearer). Without it, the
|
|
21
|
+
* whole match is the secret. Markers never re-match any pattern (verified by
|
|
22
|
+
* test), so passes compose safely.
|
|
23
|
+
*/
|
|
24
|
+
export declare function redactText(text: string, patterns?: readonly RedactPattern[]): RedactionResult;
|
package/lib/redact.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic credential redaction (knowledge-repo.md §9).
|
|
3
|
+
*
|
|
4
|
+
* The user's position, adopted: credentials only, deterministic patterns only,
|
|
5
|
+
* everything else byte-identical — the character of the conversation is
|
|
6
|
+
* historical value and stays intact. The marker is deliberate and stable:
|
|
7
|
+
* ⟦redacted:credential sha256=8f3a1c2b⟧
|
|
8
|
+
* (a) obviously not a real value to any model reading a chapter,
|
|
9
|
+
* (b) deterministic per secret — same secret, same marker, so diffs and
|
|
10
|
+
* cross-chapter greps stay stable,
|
|
11
|
+
* (c) leaks nothing but an 8-hex prefix hash, which is also what lets a user
|
|
12
|
+
* ask "which secrets touched my sessions" without exposing them.
|
|
13
|
+
*
|
|
14
|
+
* Patterns are conservative by design and config-extensible; redaction is a
|
|
15
|
+
* speed bump, not a guarantee (the record says so, and so does the in-repo
|
|
16
|
+
* notice). Applied once, at the render chokepoint (src/render.ts), so chapters
|
|
17
|
+
* and artifact files are both covered without caller changes.
|
|
18
|
+
*/
|
|
19
|
+
import { createHash } from 'node:crypto';
|
|
20
|
+
/** Built-in set (record §9). New patterns are config additions, not magic. */
|
|
21
|
+
export const DEFAULT_REDACTIONS = [
|
|
22
|
+
{ name: 'pem-private-key', regex: /-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/g },
|
|
23
|
+
{ name: 'aws-access-key-id', regex: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
24
|
+
{ name: 'github-token', regex: /\b(?:ghp|gho|ghs|ghu)_[A-Za-z0-9]{16,}\b/g },
|
|
25
|
+
{ name: 'github-fine-grained', regex: /\bgithub_pat_[A-Za-z0-9_]{16,}\b/g },
|
|
26
|
+
{ name: 'openai-style-key', regex: /\bsk-[A-Za-z0-9_-]{16,}\b/g },
|
|
27
|
+
{ name: 'jwt', regex: /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\b/g },
|
|
28
|
+
{ name: 'bearer-token', regex: /\b(Bearer\s+)[A-Za-z0-9._~+/=-]{16,}/gi, secretGroup: 1 },
|
|
29
|
+
{ name: 'url-credential-param', regex: /([?&](?:token|api[_-]?key|apikey|key|secret|password)=)[^&\s"'`]+/gi, secretGroup: 1 },
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* `Bearer <tok>` → redact the token, keep the `Bearer ` label: the pattern's
|
|
33
|
+
* `secretGroup` names the capture that is NOT the secret; here we invert —
|
|
34
|
+
* the label is group 1, so the secret is the remainder of the match after
|
|
35
|
+
* the group. Implemented via a post-step in redactText (label-aware patterns).
|
|
36
|
+
*/
|
|
37
|
+
function markerFor(secret) {
|
|
38
|
+
const h = createHash('sha256').update(secret, 'utf8').digest('hex').slice(0, 8);
|
|
39
|
+
return `⟦redacted:credential sha256=${h}⟧`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Replace every pattern match's secret with its stable marker.
|
|
43
|
+
* `secretGroup` semantics: the named group is the LABEL to keep; the secret
|
|
44
|
+
* is the rest of the match (url-credential-param, bearer). Without it, the
|
|
45
|
+
* whole match is the secret. Markers never re-match any pattern (verified by
|
|
46
|
+
* test), so passes compose safely.
|
|
47
|
+
*/
|
|
48
|
+
export function redactText(text, patterns = DEFAULT_REDACTIONS) {
|
|
49
|
+
let out = text;
|
|
50
|
+
let count = 0;
|
|
51
|
+
const markers = [];
|
|
52
|
+
for (const p of patterns) {
|
|
53
|
+
const re = new RegExp(p.regex.source, p.regex.flags.includes('g') ? p.regex.flags : p.regex.flags + 'g');
|
|
54
|
+
const matches = Array.from(out.matchAll(re));
|
|
55
|
+
if (matches.length === 0)
|
|
56
|
+
continue;
|
|
57
|
+
// splice back-to-front so earlier indices stay valid
|
|
58
|
+
for (let i = matches.length - 1; i >= 0; i -= 1) {
|
|
59
|
+
const m = matches[i];
|
|
60
|
+
const whole = m[0];
|
|
61
|
+
let keep = '';
|
|
62
|
+
let secret = whole;
|
|
63
|
+
// label-group patterns (bearer, url-credential): the named group is a
|
|
64
|
+
// PREFIX of the match and is kept; the remainder is the secret. Any
|
|
65
|
+
// other shape falls through to whole-match redaction (safe default).
|
|
66
|
+
if (p.secretGroup !== undefined) {
|
|
67
|
+
const label = m[p.secretGroup];
|
|
68
|
+
if (typeof label === 'string' && label.length > 0 && whole.startsWith(label)) {
|
|
69
|
+
keep = label;
|
|
70
|
+
secret = whole.slice(label.length);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (secret.length === 0)
|
|
74
|
+
continue;
|
|
75
|
+
const marker = markerFor(secret);
|
|
76
|
+
const start = m.index + keep.length;
|
|
77
|
+
out = out.slice(0, start) + marker + out.slice(start + secret.length);
|
|
78
|
+
count += 1;
|
|
79
|
+
if (!markers.includes(marker))
|
|
80
|
+
markers.push(marker);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return { text: out, count, markers };
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry — pure ancestry/numbering state. No cordis, no zod, no I/O: this is
|
|
3
|
+
* the L0 layer (docs/development.md § Test Layers); `src/store.ts` is the thin
|
|
4
|
+
* storage-domain adapter over it, deliberately untested because it is glue.
|
|
5
|
+
*
|
|
6
|
+
* The registry is the SOLE authority on ancestry (contract.md § Lineage: the
|
|
7
|
+
* kernel header carries `parentSession` for seed lineage we deliberately do not
|
|
8
|
+
* use; the UI graph will show our children as unrelated roots). Corruptions it
|
|
9
|
+
* must survive: cycles (walk guard throws, never hangs), duplicate chapter ids
|
|
10
|
+
* (append is idempotent), retry-after-crash (reserve is attempt-keyed, so the
|
|
11
|
+
* same `sourceSession@ceiling` reuses its numbers — archive.ts depends on it).
|
|
12
|
+
*
|
|
13
|
+
* Numbering is per-author-session (invariant: chapters keyed by creating
|
|
14
|
+
* session, so siblings cannot collide), and the flat index is built by the
|
|
15
|
+
* PLUGIN walking the ancestor path — the model never traverses a graph.
|
|
16
|
+
*/
|
|
17
|
+
import type { ChapterRecord } from './archive.ts';
|
|
18
|
+
import type { CollectionSignature } from './signature.ts';
|
|
19
|
+
export interface SessionState {
|
|
20
|
+
/** Registry-level parent, set at continuation commit. null until linked. */
|
|
21
|
+
parentSession: string | null;
|
|
22
|
+
/** Root of the ancestry tree; the store directory key. Self for a root session. */
|
|
23
|
+
rootSession: string;
|
|
24
|
+
/** Next unallocated chapter number for THIS author session. */
|
|
25
|
+
nextChapterNumber: number;
|
|
26
|
+
chapters: ChapterRecord[];
|
|
27
|
+
/** attemptKey -> numbers, so an idempotent retry reuses rather than duplicates. */
|
|
28
|
+
reservations: Record<string, number[]>;
|
|
29
|
+
/**
|
|
30
|
+
* compactionId -> the plan summarize() committed to: the TOC text already
|
|
31
|
+
* cited `path`, so finalize (possibly after a crash and process restart)
|
|
32
|
+
* must reproduce it exactly. Rebuilding the title from messages is not
|
|
33
|
+
* available post-commit — this manifest is the durable bridge.
|
|
34
|
+
*/
|
|
35
|
+
plans: Record<string, {
|
|
36
|
+
number: number;
|
|
37
|
+
path: string;
|
|
38
|
+
title: string;
|
|
39
|
+
summary: string;
|
|
40
|
+
chapters?: PlanChapter[] | undefined;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* compactionId -> chapter numbers, written when a compaction's chapter bodies
|
|
44
|
+
* are durably finalized post-commit. Idempotence key for the finalizer and
|
|
45
|
+
* the reconciliation scan (FINDINGS § correlation seam).
|
|
46
|
+
*/
|
|
47
|
+
finalized: Record<string, number[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Per-turn deterministic signatures, appended at turn/end (knowledge-repo
|
|
50
|
+
* §4.1). The composer (§4.2) reads these at archive time; P2 enrichment may
|
|
51
|
+
* relabel later but never rewrites them. Append-only like chapters.
|
|
52
|
+
*/
|
|
53
|
+
collections: CollectionSignature[];
|
|
54
|
+
}
|
|
55
|
+
export declare const freshSession: (sessionId: string) => SessionState;
|
|
56
|
+
/**
|
|
57
|
+
* One composed chapter of a compaction plan (r29): the composer's range,
|
|
58
|
+
* its reserved number and cited path, durable BEFORE the summary text cites
|
|
59
|
+
* them. Legacy single-chapter plans keep the four flat fields and omit this.
|
|
60
|
+
*/
|
|
61
|
+
export interface PlanChapter {
|
|
62
|
+
number: number;
|
|
63
|
+
path: string;
|
|
64
|
+
title: string;
|
|
65
|
+
summary: string;
|
|
66
|
+
startSeq: number;
|
|
67
|
+
endSeq: number;
|
|
68
|
+
}
|
|
69
|
+
/** Persist a summarize-time plan so finalization survives a restart. */
|
|
70
|
+
export declare function rememberPlan(state: SessionState, compactionId: string, plan: {
|
|
71
|
+
number: number;
|
|
72
|
+
path: string;
|
|
73
|
+
title: string;
|
|
74
|
+
summary: string;
|
|
75
|
+
chapters?: PlanChapter[];
|
|
76
|
+
}): SessionState;
|
|
77
|
+
/** Record a post-commit finalization for one compaction. Same write twice is a no-op. */
|
|
78
|
+
export declare function markFinalized(state: SessionState, compactionId: string, numbers: readonly number[]): SessionState;
|
|
79
|
+
/** True when a compaction's chapters are already committed (finalizer + scan use this). */
|
|
80
|
+
export declare const isFinalized: (state: SessionState, compactionId: string) => boolean;
|
|
81
|
+
/** Immutably updated copy with `n` numbers reserved for `attemptId`. */
|
|
82
|
+
export declare function reserve(state: SessionState, attemptId: string, count: number): {
|
|
83
|
+
state: SessionState;
|
|
84
|
+
numbers: number[];
|
|
85
|
+
};
|
|
86
|
+
/** Append verified chapter records. A record with an existing (number) identity is a no-op — retries are safe. */
|
|
87
|
+
export declare function appendChapters(state: SessionState, records: readonly ChapterRecord[]): SessionState;
|
|
88
|
+
/**
|
|
89
|
+
* Commit point for a continuation: the child inherits the PARENT's root and
|
|
90
|
+
* gets its direct parent recorded. Set once, never rewritten — re-pointing a
|
|
91
|
+
* linked session would silently re-home every chapter below it. Same link
|
|
92
|
+
* twice is a no-op (retry safety); a DIFFERENT link is corruption or a bug,
|
|
93
|
+
* and it throws.
|
|
94
|
+
*/
|
|
95
|
+
export declare function linkChild(state: SessionState, parentSessionId: string, parentRootSession: string): SessionState;
|
|
96
|
+
/**
|
|
97
|
+
* Walk parent links root-first. Throws on a cycle or a missing parent — both
|
|
98
|
+
* are registry corruption, and an infinite walk is how a small bad write
|
|
99
|
+
* becomes a hung plugin at the worst moment.
|
|
100
|
+
*/
|
|
101
|
+
export declare function ancestorPath(get: (id: string) => SessionState | undefined, sessionId: string, maxDepth?: number): string[];
|
|
102
|
+
export interface IndexEntry {
|
|
103
|
+
/** Session that authored the chapter, for back-links. */
|
|
104
|
+
authorSession: string;
|
|
105
|
+
number: number;
|
|
106
|
+
path: string;
|
|
107
|
+
title: string;
|
|
108
|
+
summary: string;
|
|
109
|
+
/** Integrity verdict supplied by the caller (verifyChapter via its fs port). */
|
|
110
|
+
status: 'ok' | 'modified' | 'missing';
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The flat, chronological, numbered index the TOC renders — reading order IS
|
|
114
|
+
* causal order (docs/architecture.md § Ancestry). Ancestor sessions first;
|
|
115
|
+
* within a session, by reserved number. Siblings are excluded by construction:
|
|
116
|
+
* the walk never enters them.
|
|
117
|
+
*/
|
|
118
|
+
export declare function buildIndex(path: readonly string[], get: (id: string) => SessionState | undefined, status: (record: ChapterRecord) => IndexEntry['status']): IndexEntry[];
|
|
119
|
+
/** Append one turn's signature. Idempotent per turn (same seqs → no-op), like appendChapters. */
|
|
120
|
+
export declare function appendCollection(state: SessionState, sig: CollectionSignature): SessionState;
|
package/lib/registry.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
export const freshSession = (sessionId) => ({
|
|
2
|
+
parentSession: null,
|
|
3
|
+
rootSession: sessionId,
|
|
4
|
+
nextChapterNumber: 1,
|
|
5
|
+
collections: [],
|
|
6
|
+
chapters: [],
|
|
7
|
+
reservations: {},
|
|
8
|
+
plans: {},
|
|
9
|
+
finalized: {},
|
|
10
|
+
});
|
|
11
|
+
/** Persist a summarize-time plan so finalization survives a restart. */
|
|
12
|
+
export function rememberPlan(state, compactionId, plan) {
|
|
13
|
+
return { ...state, plans: { ...state.plans, [compactionId]: plan } };
|
|
14
|
+
}
|
|
15
|
+
/** Record a post-commit finalization for one compaction. Same write twice is a no-op. */
|
|
16
|
+
export function markFinalized(state, compactionId, numbers) {
|
|
17
|
+
if (state.finalized[compactionId] !== undefined)
|
|
18
|
+
return state;
|
|
19
|
+
return { ...state, finalized: { ...state.finalized, [compactionId]: [...numbers] } };
|
|
20
|
+
}
|
|
21
|
+
/** True when a compaction's chapters are already committed (finalizer + scan use this). */
|
|
22
|
+
export const isFinalized = (state, compactionId) => state.finalized[compactionId] !== undefined;
|
|
23
|
+
/** Immutably updated copy with `n` numbers reserved for `attemptId`. */
|
|
24
|
+
export function reserve(state, attemptId, count) {
|
|
25
|
+
if (count <= 0 || !Number.isInteger(count)) {
|
|
26
|
+
throw new Error(`reserve: count must be a positive integer, got ${count}`);
|
|
27
|
+
}
|
|
28
|
+
const existing = state.reservations[attemptId];
|
|
29
|
+
if (existing !== undefined) {
|
|
30
|
+
if (existing.length !== count) {
|
|
31
|
+
// Same attempt, different size: the caller's chapter set changed under a
|
|
32
|
+
// half-finished attempt. Reusing a shorter list would silently drop
|
|
33
|
+
// chapters; growing would collide. Refuse — never guess.
|
|
34
|
+
throw new Error(`reserve: attempt "${attemptId}" already holds ${existing.length} numbers, requested ${count}`);
|
|
35
|
+
}
|
|
36
|
+
return { state, numbers: [...existing] };
|
|
37
|
+
}
|
|
38
|
+
const numbers = Array.from({ length: count }, (_, i) => state.nextChapterNumber + i);
|
|
39
|
+
return {
|
|
40
|
+
state: {
|
|
41
|
+
...state,
|
|
42
|
+
nextChapterNumber: state.nextChapterNumber + count,
|
|
43
|
+
reservations: { ...state.reservations, [attemptId]: numbers },
|
|
44
|
+
},
|
|
45
|
+
numbers,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Append verified chapter records. A record with an existing (number) identity is a no-op — retries are safe. */
|
|
49
|
+
export function appendChapters(state, records) {
|
|
50
|
+
const known = new Set(state.chapters.map((c) => c.number));
|
|
51
|
+
const fresh = records.filter((r) => !known.has(r.number));
|
|
52
|
+
if (fresh.length === 0)
|
|
53
|
+
return state;
|
|
54
|
+
return { ...state, chapters: [...state.chapters, ...fresh] };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Commit point for a continuation: the child inherits the PARENT's root and
|
|
58
|
+
* gets its direct parent recorded. Set once, never rewritten — re-pointing a
|
|
59
|
+
* linked session would silently re-home every chapter below it. Same link
|
|
60
|
+
* twice is a no-op (retry safety); a DIFFERENT link is corruption or a bug,
|
|
61
|
+
* and it throws.
|
|
62
|
+
*/
|
|
63
|
+
export function linkChild(state, parentSessionId, parentRootSession) {
|
|
64
|
+
if (state.parentSession !== null) {
|
|
65
|
+
if (state.parentSession === parentSessionId && state.rootSession === parentRootSession)
|
|
66
|
+
return state;
|
|
67
|
+
throw new Error(`linkChild: session already linked to parent ${state.parentSession} (root ${state.rootSession});`
|
|
68
|
+
+ ` refusing rewrite to parent ${parentSessionId} (root ${parentRootSession})`);
|
|
69
|
+
}
|
|
70
|
+
return { ...state, parentSession: parentSessionId, rootSession: parentRootSession };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Walk parent links root-first. Throws on a cycle or a missing parent — both
|
|
74
|
+
* are registry corruption, and an infinite walk is how a small bad write
|
|
75
|
+
* becomes a hung plugin at the worst moment.
|
|
76
|
+
*/
|
|
77
|
+
export function ancestorPath(get, sessionId, maxDepth = 1000) {
|
|
78
|
+
const path = [];
|
|
79
|
+
const seen = new Set();
|
|
80
|
+
let cursor = sessionId;
|
|
81
|
+
while (cursor !== undefined) {
|
|
82
|
+
if (seen.has(cursor))
|
|
83
|
+
throw new Error(`ancestorPath: cycle through ${cursor}`);
|
|
84
|
+
if (seen.size >= maxDepth)
|
|
85
|
+
throw new Error(`ancestorPath: exceeded depth ${maxDepth}`);
|
|
86
|
+
seen.add(cursor);
|
|
87
|
+
const state = get(cursor);
|
|
88
|
+
if (state === undefined) {
|
|
89
|
+
if (cursor === sessionId)
|
|
90
|
+
return [cursor]; // unregistered root: itself is the path
|
|
91
|
+
throw new Error(`ancestorPath: missing state for parent ${cursor} (registry corruption)`);
|
|
92
|
+
}
|
|
93
|
+
path.unshift(cursor);
|
|
94
|
+
cursor = state.parentSession ?? undefined;
|
|
95
|
+
}
|
|
96
|
+
return path;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The flat, chronological, numbered index the TOC renders — reading order IS
|
|
100
|
+
* causal order (docs/architecture.md § Ancestry). Ancestor sessions first;
|
|
101
|
+
* within a session, by reserved number. Siblings are excluded by construction:
|
|
102
|
+
* the walk never enters them.
|
|
103
|
+
*/
|
|
104
|
+
export function buildIndex(path, get, status) {
|
|
105
|
+
const entries = [];
|
|
106
|
+
for (const sessionId of path) {
|
|
107
|
+
const state = get(sessionId);
|
|
108
|
+
if (state === undefined)
|
|
109
|
+
continue;
|
|
110
|
+
for (const chapter of [...state.chapters].sort((a, b) => a.number - b.number)) {
|
|
111
|
+
entries.push({
|
|
112
|
+
authorSession: sessionId,
|
|
113
|
+
number: chapter.number,
|
|
114
|
+
path: chapter.path,
|
|
115
|
+
title: chapter.title,
|
|
116
|
+
summary: chapter.summary,
|
|
117
|
+
status: status(chapter),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return entries;
|
|
122
|
+
}
|
|
123
|
+
/** Append one turn's signature. Idempotent per turn (same seqs → no-op), like appendChapters. */
|
|
124
|
+
export function appendCollection(state, sig) {
|
|
125
|
+
const last = state.collections[state.collections.length - 1];
|
|
126
|
+
if (last !== undefined && last.seqs.length === sig.seqs.length && last.seqs.every((q, i) => q === sig.seqs[i]))
|
|
127
|
+
return state;
|
|
128
|
+
return { ...state, collections: [...state.collections, sig] };
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/lib/render.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ArtifactRef, ChapterRange, RenderConfig, RenderedChapter, SessionEventLike, ToolResultCandidate, ToolResultOverride } from './types.ts';
|
|
2
|
+
/** chars/4 until the host tokenMeter is wired in. Labelled an estimate everywhere it surfaces. */
|
|
3
|
+
export declare const estimateTokens: (text: string) => number;
|
|
4
|
+
/**
|
|
5
|
+
* A fence strictly longer than any backtick run inside `body`, so embedded code blocks cannot close it.
|
|
6
|
+
* Markdown requires the closing fence to be at least as long as the opening one.
|
|
7
|
+
*/
|
|
8
|
+
export declare function longerFence(body: string): string;
|
|
9
|
+
/** Wrapped in a fence long enough to survive any content, including nested fences. */
|
|
10
|
+
export declare function fenced(content: string, info?: string): string;
|
|
11
|
+
export declare const sha256: (text: string) => string;
|
|
12
|
+
/** `artifacts/8f/8f3a1c9d….txt` — sharded so one directory never holds the whole subtree. */
|
|
13
|
+
export declare const artifactPath: (hash: string) => string;
|
|
14
|
+
export declare function artifactRef(text: string, opts: {
|
|
15
|
+
toolName: string;
|
|
16
|
+
sourceSeq: number;
|
|
17
|
+
inlined: boolean;
|
|
18
|
+
}): ArtifactRef;
|
|
19
|
+
/**
|
|
20
|
+
* Validate model-supplied ranges. Never trust them (hard rule): an overlap duplicates archived text and a
|
|
21
|
+
* gap silently drops history, so both are errors here rather than data that quietly goes missing.
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateRanges(chapters: ChapterRange[], archiveCeiling: number): ChapterRange[];
|
|
24
|
+
/** Enumerate tool results in a range so the model can decide keep/defer against real sizes. */
|
|
25
|
+
export declare function toolResultCandidates(events: SessionEventLike[], range: ChapterRange): ToolResultCandidate[];
|
|
26
|
+
/**
|
|
27
|
+
* Render one chapter. `overrides` is the model's sparse exception list; anything not named follows the
|
|
28
|
+
* default rule (small results inline, large ones deferred). Either way the artifact is written, so a wrong
|
|
29
|
+
* call costs a `read` and never loses data.
|
|
30
|
+
*/
|
|
31
|
+
export declare function renderChapter(events: SessionEventLike[], range: ChapterRange, config: RenderConfig, overrides?: readonly ToolResultOverride[], topics?: readonly string[]): RenderedChapter;
|
|
32
|
+
/**
|
|
33
|
+
* The cumulative index that replaces compacted history. Built from registry records, never from an LLM —
|
|
34
|
+
* which is the entire latency argument: no summarization call, no tokens, no paraphrase.
|
|
35
|
+
*/
|
|
36
|
+
export declare function renderIndex(entries: readonly {
|
|
37
|
+
path: string;
|
|
38
|
+
title: string;
|
|
39
|
+
summary: string;
|
|
40
|
+
}[]): string;
|