@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/sync.d.ts
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { type ProviderKind, type SyncProvider } from './provider.ts';
|
|
2
|
+
import { type VocabOpts } from './vocabulary.ts';
|
|
3
|
+
/** A linked knowledge project (record §2.1, §8): one record per linked
|
|
4
|
+
* workspace cwd; deepest-cwd match resolves the active project. */
|
|
5
|
+
export interface ProjectRecord {
|
|
6
|
+
projectKey: string;
|
|
7
|
+
slug: string;
|
|
8
|
+
remote: string;
|
|
9
|
+
harnessId: string;
|
|
10
|
+
linkedAt: string;
|
|
11
|
+
/** Workspace cwd this record was linked from (deepest-prefix match, record §8). */
|
|
12
|
+
cwd: string;
|
|
13
|
+
/** Transport kind (§15 amendment); absent = 'git' (pre-provider records). */
|
|
14
|
+
kind?: ProviderKind;
|
|
15
|
+
/** TreeDX: the server-assigned repository id (resolved at link time). */
|
|
16
|
+
repoId?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
export interface SyncResult {
|
|
19
|
+
ok: boolean;
|
|
20
|
+
/** What actually happened, for the status command and tests. */
|
|
21
|
+
steps: string[];
|
|
22
|
+
detail: string;
|
|
23
|
+
/** 'synced' only when the remote accepted the push; 'local-only' when the
|
|
24
|
+
* mirror is current but the remote did not take it (record §5.3). */
|
|
25
|
+
mode: 'synced' | 'local-only';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Per-project credentials — stored under the DSH HOME, never the workspace
|
|
29
|
+
* (user directive 2026-09-18: the project tree is the agent's reading room;
|
|
30
|
+
* the plugin is the only accessor). 0600 file per projectKey. Note honestly:
|
|
31
|
+
* same-uid files are a hygiene boundary, not a cryptographic one — the real
|
|
32
|
+
* guarantee is that the plugin never echoes the token anywhere an agent sees.
|
|
33
|
+
*/
|
|
34
|
+
export declare const tokenPath: (projectKey: string) => string;
|
|
35
|
+
export declare function readToken(cwd: string, storeRoot: string, projectKey: string): string | undefined;
|
|
36
|
+
export declare function writeToken(projectKey: string, token: string): void;
|
|
37
|
+
export interface SyncOpts {
|
|
38
|
+
/** Workspace root — the store and the mirror both live under it. */
|
|
39
|
+
cwd: string;
|
|
40
|
+
/** Store root relative to cwd (`.dsh-chapters`). */
|
|
41
|
+
storeRoot: string;
|
|
42
|
+
/** Mirror directory relative to cwd (`.dsh-knowledge`). */
|
|
43
|
+
cloneDir: string;
|
|
44
|
+
project: ProjectRecord;
|
|
45
|
+
/** Per-harness token for this project (record §2.1); undefined for file remotes. */
|
|
46
|
+
token?: string;
|
|
47
|
+
/** Collection files to (re)publish: one JSONL file per session's signatures. */
|
|
48
|
+
collections?: {
|
|
49
|
+
sessionId: string;
|
|
50
|
+
lines: string[];
|
|
51
|
+
}[];
|
|
52
|
+
/** P2 §6.3 vocabulary pass over the mirror's chapters (undefined = off). */
|
|
53
|
+
vocab?: VocabPassOpts;
|
|
54
|
+
/** Force a run even when the lock is held (tests). Default false. */
|
|
55
|
+
force?: boolean;
|
|
56
|
+
/** Transport provider (tests inject a fake; default resolves from the
|
|
57
|
+
* project record's kind via src/provider.ts — 'git' when absent). */
|
|
58
|
+
provider?: SyncProvider;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Deepest-cwd match (record §8): the active knowledge project for a
|
|
62
|
+
* workspace path. Shared by the notice line, the scheduler, and the commands.
|
|
63
|
+
*/
|
|
64
|
+
export declare function projectForCwd(records: Iterable<[string, ProjectRecord]>, cwd: string): ProjectRecord | undefined;
|
|
65
|
+
/** The mirror directory, relative to the workspace (record §3.1). */
|
|
66
|
+
export declare const DEFAULT_CLONE_DIR = ".dsh-knowledge";
|
|
67
|
+
/**
|
|
68
|
+
* File lock around store transactions and clone ops (§5.2): the host-plane
|
|
69
|
+
* plugin and the realm engine may be different module instances in the same
|
|
70
|
+
* process, so an in-process mutex is not safe — a file is the honest lock.
|
|
71
|
+
* Stale locks (>10 min) are stolen; live ones make runSync skip, not block.
|
|
72
|
+
*/
|
|
73
|
+
export declare function syncLockPath(storeDir: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Map workspace-store files to repo paths (record §2.2):
|
|
76
|
+
* <storeRoot>/<rootSession>/chapters/x.md → chapters/<projectKey>/<rootSession>/x.md
|
|
77
|
+
* <storeRoot>/<rootSession>/artifacts/ab/ab….txt → artifacts/<projectKey>/ab/ab….txt
|
|
78
|
+
* Artifacts are content-addressed and shared across sessions, so their
|
|
79
|
+
* per-session prefix is dropped; chapters keep it.
|
|
80
|
+
*/
|
|
81
|
+
export declare function planStoreToRepo(storeDir: string, projectKey: string): {
|
|
82
|
+
abs: string;
|
|
83
|
+
rel: string;
|
|
84
|
+
}[];
|
|
85
|
+
export declare const statusFilePath: (cwd: string, storeRoot: string) => string;
|
|
86
|
+
/**
|
|
87
|
+
* Build the Layer-2 index inside the clone (record §10.2): entries from every
|
|
88
|
+
* chapter/rule file (frontmatter), curation facts from every harness's
|
|
89
|
+
* curation.jsonl, the manifest from the clone's index/manifest.json. Returns
|
|
90
|
+
* true when shards or the manifest changed (the commit step then ships them).
|
|
91
|
+
* Deterministic: the index is a pure function of the clone's corpus, so any
|
|
92
|
+
* machine can rebuild it identically (the recovery path, record §10.2).
|
|
93
|
+
*/
|
|
94
|
+
export declare function buildIndexInClone(cloneDir: string): boolean;
|
|
95
|
+
export interface VocabPassOpts extends VocabOpts {
|
|
96
|
+
/** write applied aliases? false (shadow) = report only — the default */
|
|
97
|
+
apply: boolean;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* One sync pass (record §5): lock → ensure clone (offline init fallback) →
|
|
101
|
+
* publish → commit → pull → push. Failure semantics §5.3: EVERY remote-path
|
|
102
|
+
* failure (clone, pull, push) degrades to local-only mode — the mirror stays
|
|
103
|
+
* current for search and the status file says so with detail; only a local
|
|
104
|
+
* commit failure or lock loss returns without a current mirror. A diverged
|
|
105
|
+
* pull rebuilds the mirror from the remote (safe: the mirror is transport,
|
|
106
|
+
* the store is truth, §3.1). ok=true means the remote accepted the push.
|
|
107
|
+
*/
|
|
108
|
+
export declare function runSync(opts: SyncOpts): Promise<SyncResult>;
|
|
109
|
+
/**
|
|
110
|
+
* Pull-only pass for the pre-fork refresh point (record §5.1): ensure the
|
|
111
|
+
* mirror exists (clone, offline-init fallback) and ff-pull it. Never throws,
|
|
112
|
+
* never pushes, never commits — a read-side refresh.
|
|
113
|
+
*/
|
|
114
|
+
export declare function runPull(opts: Omit<SyncOpts, 'force'>): Promise<{
|
|
115
|
+
ok: boolean;
|
|
116
|
+
detail: string;
|
|
117
|
+
}>;
|
|
118
|
+
/**
|
|
119
|
+
* A workspace-scoped collections reader for the scheduler (§5): only session
|
|
120
|
+
* trees whose store directory lives in THIS workspace publish. Shared by the
|
|
121
|
+
* host plugin and the realm engine (the two schedulers are the same code over
|
|
122
|
+
* different module copies — the file lock keeps them honest).
|
|
123
|
+
*/
|
|
124
|
+
export declare function makeCollectionsReader(sessions: () => IterableIterator<[string, import('./registry.ts').SessionState]>, storeRoot: string): (cwd: string) => {
|
|
125
|
+
sessionId: string;
|
|
126
|
+
lines: string[];
|
|
127
|
+
}[];
|
|
128
|
+
/**
|
|
129
|
+
* The debounced scheduler (§5.2: "consecutive archive events within the
|
|
130
|
+
* configured window coalesce into one push"). Pure wiring — the plane that
|
|
131
|
+
* owns it (host plugin or realm engine) injects how to find the project, the
|
|
132
|
+
* token, and the collection files. Never throws; a failed pass lands in the
|
|
133
|
+
* status file like any other.
|
|
134
|
+
*/
|
|
135
|
+
export interface SyncSchedulerDeps {
|
|
136
|
+
storeRoot: string;
|
|
137
|
+
cloneDir?: string;
|
|
138
|
+
debounceMs: number;
|
|
139
|
+
resolveProject(cwd: string): ProjectRecord | undefined;
|
|
140
|
+
tokenFor(cwd: string, projectKey: string): string | undefined;
|
|
141
|
+
/** Collection JSONL lines per session, read from the registry (may be empty). */
|
|
142
|
+
collectionsFor(cwd: string): {
|
|
143
|
+
sessionId: string;
|
|
144
|
+
lines: string[];
|
|
145
|
+
}[];
|
|
146
|
+
/** P2 §6.3 vocabulary pass options for every scheduled pass (undefined = off). */
|
|
147
|
+
vocab?: VocabPassOpts;
|
|
148
|
+
/** Injectable timer (tests). Defaults to setTimeout/clearTimeout. */
|
|
149
|
+
setTimer?: (fn: () => void, ms: number) => {
|
|
150
|
+
cancel(): void;
|
|
151
|
+
};
|
|
152
|
+
provider?: SyncProvider;
|
|
153
|
+
/** P2: fired after a REAL sync pass completes (success or degraded) — the
|
|
154
|
+
* enrichment queue's natural idle point. Not fired for 'no project
|
|
155
|
+
* linked' early-outs (nothing was published, nothing to enrich). */
|
|
156
|
+
onSyncDone?: (cwd: string, ok: boolean) => void;
|
|
157
|
+
}
|
|
158
|
+
export interface SyncScheduler {
|
|
159
|
+
/** Debounced push after an archive event (compaction/fork). */
|
|
160
|
+
schedule(cwd: string, why: string): void;
|
|
161
|
+
/** Immediate pass (a link, an explicit sync). An explicit project wins
|
|
162
|
+
* over the cwd lookup — a re-link must sync the NEW record, not whichever
|
|
163
|
+
* record the cwd tie-break happens to pick. */
|
|
164
|
+
run(cwd: string, why: string, project?: ProjectRecord): Promise<SyncResult>;
|
|
165
|
+
/** Pre-fork refresh (§5.1): pull-only, bounded, never blocks long. */
|
|
166
|
+
pullFor(cwd: string): Promise<{
|
|
167
|
+
ok: boolean;
|
|
168
|
+
detail: string;
|
|
169
|
+
}>;
|
|
170
|
+
hasPending(cwd: string): boolean;
|
|
171
|
+
/** Await any in-flight/scheduled pass (tests + shutdown). */
|
|
172
|
+
drain(): Promise<void>;
|
|
173
|
+
}
|
|
174
|
+
export declare function createSyncScheduler(deps: SyncSchedulerDeps): SyncScheduler;
|
|
175
|
+
/** Read the last sync status (for /chapters-status). Null when never run. */
|
|
176
|
+
export declare function readSyncStatus(cwd: string, storeRoot: string): {
|
|
177
|
+
at: string;
|
|
178
|
+
projectKey: string;
|
|
179
|
+
lastOk: boolean;
|
|
180
|
+
mode?: string;
|
|
181
|
+
detail: string;
|
|
182
|
+
steps: string[];
|
|
183
|
+
} | null;
|