@fractalsynapse/dsh-chapters 0.0.0-stage → 0.2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +76 -2
  3. package/cordis.patch.yml +363 -0
  4. package/docs/architecture.md +692 -0
  5. package/docs/autorun-guide.md +248 -0
  6. package/docs/backlog.md +2022 -0
  7. package/docs/contract.md +938 -0
  8. package/docs/development.md +990 -0
  9. package/docs/host-compaction-seam.md +225 -0
  10. package/docs/host-protected-head-ask.md +80 -0
  11. package/docs/knowledge-repo.md +1332 -0
  12. package/docs/plans-carriage.md +571 -0
  13. package/docs/project-state.md +642 -0
  14. package/docs/provider.md +98 -0
  15. package/docs/superpowers/plans/2026-10-17-chapters-save.md +198 -0
  16. package/docs/superpowers/plans/2026-11-02-chapter-removal.md +151 -0
  17. package/docs/superpowers/specs/2026-11-02-chapter-removal-design.md +115 -0
  18. package/docs/verify.md +561 -0
  19. package/lib/archive.d.ts +161 -0
  20. package/lib/archive.js +229 -0
  21. package/lib/archive.js.map +1 -0
  22. package/lib/arrival.d.ts +23 -0
  23. package/lib/arrival.js +125 -0
  24. package/lib/arrival.js.map +1 -0
  25. package/lib/artifact-query.d.ts +62 -0
  26. package/lib/artifact-query.js +187 -0
  27. package/lib/artifact-query.js.map +1 -0
  28. package/lib/attach.d.ts +46 -0
  29. package/lib/attach.js +120 -0
  30. package/lib/attach.js.map +1 -0
  31. package/lib/auto-save.d.ts +145 -0
  32. package/lib/auto-save.js +334 -0
  33. package/lib/auto-save.js.map +1 -0
  34. package/lib/aux-message.d.ts +17 -0
  35. package/lib/aux-message.js +20 -0
  36. package/lib/aux-message.js.map +1 -0
  37. package/lib/client.js +1419 -0
  38. package/lib/client.js.map +1 -0
  39. package/lib/codegraph.d.ts +76 -0
  40. package/lib/codegraph.js +190 -0
  41. package/lib/codegraph.js.map +1 -0
  42. package/lib/commands.d.ts +52 -0
  43. package/lib/commands.js +946 -0
  44. package/lib/commands.js.map +1 -0
  45. package/lib/compose.d.ts +30 -0
  46. package/lib/compose.js +185 -0
  47. package/lib/compose.js.map +1 -0
  48. package/lib/continue-core.d.ts +245 -0
  49. package/lib/continue-core.js +405 -0
  50. package/lib/continue-core.js.map +1 -0
  51. package/lib/diag.d.ts +55 -0
  52. package/lib/diag.js +186 -0
  53. package/lib/diag.js.map +1 -0
  54. package/lib/engine-core.d.ts +301 -0
  55. package/lib/engine-core.js +531 -0
  56. package/lib/engine-core.js.map +1 -0
  57. package/lib/engine-note.d.ts +35 -0
  58. package/lib/engine-note.js +32 -0
  59. package/lib/engine-note.js.map +1 -0
  60. package/lib/engine.d.ts +329 -0
  61. package/lib/engine.js +1179 -0
  62. package/lib/engine.js.map +1 -0
  63. package/lib/enrich-queue.d.ts +66 -0
  64. package/lib/enrich-queue.js +126 -0
  65. package/lib/enrich-queue.js.map +1 -0
  66. package/lib/enrich-store.d.ts +31 -0
  67. package/lib/enrich-store.js +103 -0
  68. package/lib/enrich-store.js.map +1 -0
  69. package/lib/enrich-wire.d.ts +163 -0
  70. package/lib/enrich-wire.js +353 -0
  71. package/lib/enrich-wire.js.map +1 -0
  72. package/lib/enrich.d.ts +102 -0
  73. package/lib/enrich.js +267 -0
  74. package/lib/enrich.js.map +1 -0
  75. package/lib/gitops.d.ts +107 -0
  76. package/lib/gitops.js +539 -0
  77. package/lib/gitops.js.map +1 -0
  78. package/lib/index.d.ts +241 -0
  79. package/lib/index.js +1162 -0
  80. package/lib/index.js.map +1 -0
  81. package/lib/indexing.d.ts +98 -0
  82. package/lib/indexing.js +223 -0
  83. package/lib/indexing.js.map +1 -0
  84. package/lib/injections.d.ts +90 -0
  85. package/lib/injections.js +165 -0
  86. package/lib/injections.js.map +1 -0
  87. package/lib/last-resort.d.ts +24 -0
  88. package/lib/last-resort.js +27 -0
  89. package/lib/last-resort.js.map +1 -0
  90. package/lib/log-shape.d.ts +38 -0
  91. package/lib/log-shape.js +93 -0
  92. package/lib/log-shape.js.map +1 -0
  93. package/lib/models-command.d.ts +74 -0
  94. package/lib/models-command.js +100 -0
  95. package/lib/models-command.js.map +1 -0
  96. package/lib/notice.d.ts +74 -0
  97. package/lib/notice.js +92 -0
  98. package/lib/notice.js.map +1 -0
  99. package/lib/plans.d.ts +154 -0
  100. package/lib/plans.js +315 -0
  101. package/lib/plans.js.map +1 -0
  102. package/lib/preset.d.ts +186 -0
  103. package/lib/preset.js +212 -0
  104. package/lib/preset.js.map +1 -0
  105. package/lib/prompt-keys.d.ts +7 -0
  106. package/lib/prompt-keys.js +8 -0
  107. package/lib/prompt-keys.js.map +1 -0
  108. package/lib/prompt-loop.d.ts +73 -0
  109. package/lib/prompt-loop.js +147 -0
  110. package/lib/prompt-loop.js.map +1 -0
  111. package/lib/prompt-push.d.ts +47 -0
  112. package/lib/prompt-push.js +115 -0
  113. package/lib/prompt-push.js.map +1 -0
  114. package/lib/prompt-runner.d.ts +48 -0
  115. package/lib/prompt-runner.js +90 -0
  116. package/lib/prompt-runner.js.map +1 -0
  117. package/lib/prompt-state.d.ts +142 -0
  118. package/lib/prompt-state.js +101 -0
  119. package/lib/prompt-state.js.map +1 -0
  120. package/lib/prompt.d.ts +270 -0
  121. package/lib/prompt.js +408 -0
  122. package/lib/prompt.js.map +1 -0
  123. package/lib/provider.d.ts +44 -0
  124. package/lib/provider.js +66 -0
  125. package/lib/provider.js.map +1 -0
  126. package/lib/redact.d.ts +24 -0
  127. package/lib/redact.js +85 -0
  128. package/lib/redact.js.map +1 -0
  129. package/lib/registry.d.ts +187 -0
  130. package/lib/registry.js +235 -0
  131. package/lib/registry.js.map +1 -0
  132. package/lib/removal.d.ts +159 -0
  133. package/lib/removal.js +556 -0
  134. package/lib/removal.js.map +1 -0
  135. package/lib/render.d.ts +97 -0
  136. package/lib/render.js +530 -0
  137. package/lib/render.js.map +1 -0
  138. package/lib/repair-run.d.ts +76 -0
  139. package/lib/repair-run.js +506 -0
  140. package/lib/repair-run.js.map +1 -0
  141. package/lib/repair.d.ts +208 -0
  142. package/lib/repair.js +357 -0
  143. package/lib/repair.js.map +1 -0
  144. package/lib/repo.d.ts +78 -0
  145. package/lib/repo.js +184 -0
  146. package/lib/repo.js.map +1 -0
  147. package/lib/rules-commands.d.ts +46 -0
  148. package/lib/rules-commands.js +379 -0
  149. package/lib/rules-commands.js.map +1 -0
  150. package/lib/rules.d.ts +267 -0
  151. package/lib/rules.js +478 -0
  152. package/lib/rules.js.map +1 -0
  153. package/lib/save-core.d.ts +72 -0
  154. package/lib/save-core.js +220 -0
  155. package/lib/save-core.js.map +1 -0
  156. package/lib/search.d.ts +112 -0
  157. package/lib/search.js +282 -0
  158. package/lib/search.js.map +1 -0
  159. package/lib/session-rules.d.ts +222 -0
  160. package/lib/session-rules.js +454 -0
  161. package/lib/session-rules.js.map +1 -0
  162. package/lib/signature.d.ts +45 -0
  163. package/lib/signature.js +199 -0
  164. package/lib/signature.js.map +1 -0
  165. package/lib/store.d.ts +156 -0
  166. package/lib/store.js +368 -0
  167. package/lib/store.js.map +1 -0
  168. package/lib/sync.d.ts +220 -0
  169. package/lib/sync.js +810 -0
  170. package/lib/sync.js.map +1 -0
  171. package/lib/tools.d.ts +113 -0
  172. package/lib/tools.js +1090 -0
  173. package/lib/tools.js.map +1 -0
  174. package/lib/treedx/client.d.ts +57 -0
  175. package/lib/treedx/client.js +82 -0
  176. package/lib/treedx/client.js.map +1 -0
  177. package/lib/treedx/provider.d.ts +39 -0
  178. package/lib/treedx/provider.js +479 -0
  179. package/lib/treedx/provider.js.map +1 -0
  180. package/lib/treedx/state.d.ts +27 -0
  181. package/lib/treedx/state.js +65 -0
  182. package/lib/treedx/state.js.map +1 -0
  183. package/lib/types.d.ts +210 -0
  184. package/lib/types.js +31 -0
  185. package/lib/types.js.map +1 -0
  186. package/lib/version.d.ts +9 -0
  187. package/lib/version.js +10 -0
  188. package/lib/version.js.map +1 -0
  189. package/lib/vocabulary.d.ts +41 -0
  190. package/lib/vocabulary.js +118 -0
  191. package/lib/vocabulary.js.map +1 -0
  192. package/lib/warnings.d.ts +10 -0
  193. package/lib/warnings.js +18 -0
  194. package/lib/warnings.js.map +1 -0
  195. package/package.json +151 -3
@@ -0,0 +1,479 @@
1
+ /**
2
+ * The TreeDX transport provider (src/provider.ts seam; design pinned in
3
+ * spikes/treedx/FINDINGS.md). It implements the sync loop's six transport
4
+ * verbs over TreeDX's no-clone HTTP API, mapping them so runSync's proven
5
+ * control flow — publish → commit → pull → push, degraded to local-only on
6
+ * any remote failure, rebuilt from the store on divergence — keeps working
7
+ * UNCHANGED. The mirror directory is still materialized (§3.1: it is the
8
+ * search/rules/index read surface in every mode); only what fills it changes.
9
+ *
10
+ * Verb mapping (the six, in runSync order):
11
+ * - ensureClone resolve the managed repo, fetch head + corpus into the
12
+ * mirror, write the state file (origin, head, baseline).
13
+ * Origin changed ⇒ 'origin-mismatch' (same code, same
14
+ * rebuild behavior as git mode).
15
+ * - stageAllAndCommit LOCAL workdir-vs-baseline diff, recorded as `staged`
16
+ * (mirrors git's local-commit step: no network here).
17
+ * - pullFastForward head compare vs state. Moved while we hold staged
18
+ * work ⇒ 'diverged' (the rebuild path re-publishes from
19
+ * the store and re-derives the index — safer than an
20
+ * ff refetch could ever be: derived files must not go
21
+ * stale against a corpus they predate). Moved with
22
+ * nothing staged ⇒ plain refetch (ff).
23
+ * - push workspace-create (one writable lease per branch) →
24
+ * overlay-write each staged path (UTF-8 file API; binary
25
+ * -safe blob API) → commit. Lease contention ⇒ 'rejected'
26
+ * (runSync's existing pull-and-retry, plus bounded
27
+ * in-provider waits); moved-base commit ⇒ 'diverged'.
28
+ * - initLocal offline state file (publish/commit/index/search keep
29
+ * working; push deferred — §5.3).
30
+ * - removeMirror inherited from the filesystem reality (mirror is
31
+ * transport, the store is truth).
32
+ *
33
+ * Every failure is a VALUE ({ok:false, code}) — never a throw into the
34
+ * conversation path, and never a prose-matched classification (r35).
35
+ */
36
+ import fs from 'node:fs';
37
+ import path from 'node:path';
38
+ import { parseKnowledgeRemote } from "../repo.js";
39
+ import { registerProvider } from "../provider.js";
40
+ import { createTreeDxClient, pick } from "./client.js";
41
+ import { contentHash, isUtf8Safe, readState, walkMirror, writeState } from "./state.js";
42
+ const DEFAULTS = {
43
+ fetchTimeoutMs: 15000,
44
+ workspaceTtlSeconds: 900,
45
+ leaseRetries: 3,
46
+ leaseRetryDelayMs: 1000,
47
+ sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
48
+ now: () => Date.now(),
49
+ };
50
+ const REF = 'refs/heads/main';
51
+ const sleepOf = (cfg) => cfg.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
52
+ /**
53
+ * The live-shaped repository catalog: GET /repos → {ok, repos:[…]} (older
54
+ * docs called it `repositories`); rows carry `repoId` (live-measured) or a
55
+ * bare `id`. One parser for the provider AND the /chapters-link command —
56
+ * this exact shape drift is why the first live run broke.
57
+ */
58
+ export function repoCatalog(data) {
59
+ const rows = Array.isArray(data.repos) ? data.repos
60
+ : Array.isArray(data.repositories) ? data.repositories : [];
61
+ return rows.map((x) => ({
62
+ name: String(x.repositoryName ?? x.name ?? ''),
63
+ repoId: String(x.repoId ?? x.id ?? ''),
64
+ })).filter((x) => x.repoId !== '');
65
+ }
66
+ /** Resolve a repository's catalog id by name ('' = not found). */
67
+ export async function resolveRepoId(client, name) {
68
+ const list = await client.get('/api/v1/repos');
69
+ if (!list.ok)
70
+ return '';
71
+ return repoCatalog(list.data).find((x) => x.name === name)?.repoId ?? '';
72
+ }
73
+ async function resolve(cfg, remote, state) {
74
+ let target;
75
+ try {
76
+ target = parseKnowledgeRemote(remote.url);
77
+ }
78
+ catch (error) {
79
+ return { ok: false, res: { ok: false, detail: `bad treedx remote: ${String(error?.message ?? error)}` } };
80
+ }
81
+ if (target.treedx === undefined) {
82
+ return { ok: false, res: { ok: false, detail: `remote ${remote.url} is not a treedx+ target` } };
83
+ }
84
+ const client = createTreeDxClient({
85
+ baseUrl: target.treedx.baseUrl,
86
+ ...(remote.token !== undefined ? { token: remote.token } : {}),
87
+ fetchTimeoutMs: cfg.fetchTimeoutMs,
88
+ ...(cfg.fetchImpl !== undefined ? { fetchImpl: cfg.fetchImpl } : {}),
89
+ });
90
+ // Repo id: prefer the state-cached id (stable across passes); otherwise
91
+ // resolve by canonical name through the catalog.
92
+ const list = await client.get('/api/v1/repos');
93
+ if (!list.ok) {
94
+ if (list.code === 'authentication_required' || list.code === 'invalid_token' || list.status === 401 || list.status === 403) {
95
+ return { ok: false, res: { ok: false, code: 'auth', detail: `TreeDX auth rejected (${list.detail}) — re-link the token with /chapters-link` } };
96
+ }
97
+ return { ok: false, res: { ok: false, code: 'network', detail: `repos list: ${list.detail}` } };
98
+ }
99
+ const catalog = repoCatalog(list.data);
100
+ const want = target.treedx.repoName;
101
+ const found = catalog.find((x) => x.name === want);
102
+ const repoId = found !== undefined ? found.repoId : '';
103
+ if (repoId === '' && state?.repoId === undefined) {
104
+ return { ok: false, res: { ok: false, code: 'not_found', detail: `TreeDX has no repository '${want}' at ${target.treedx.baseUrl} (create it or re-link)` } };
105
+ }
106
+ return { ok: true, r: { target, client, repoId: repoId !== '' ? repoId : String(state?.repoId ?? '') } };
107
+ }
108
+ /**
109
+ * Head sha of `refs/heads/main`. LIVE-MEASURED (spikes/treedx/FINDINGS.md):
110
+ * refs entries carry `{kind:'branch', name, target}` — the sha key is
111
+ * `target`; and a managed repository is BORN with `refs/heads/main` (a
112
+ * seeding commit holding `.treedxkeep`), so `null` here only means an
113
+ * unexpected listing failure shape, handled tolerantly. Repo routes address
114
+ * by repoId (name 404s).
115
+ */
116
+ async function headOf(client, repoId) {
117
+ const refs = await client.get(`/api/v1/repos/${encodeURIComponent(repoId)}/refs`);
118
+ if (!refs.ok) {
119
+ if (refs.code === 'not_found')
120
+ return { ok: true, head: null };
121
+ return { ok: false, res: { ok: false, code: refs.code === 'auth' ? 'auth' : 'network', detail: `refs: ${refs.detail}` } };
122
+ }
123
+ const list = Array.isArray(refs.data.refs) ? refs.data.refs : [];
124
+ const main = list.find((x) => String(x.name ?? x.ref ?? '') === REF || String(x.name ?? x.ref ?? '') === 'main');
125
+ const sha = main !== undefined ? String(main.target ?? main.objectId ?? main.sha ?? main.commitSha ?? '') : '';
126
+ return { ok: true, head: sha === '' ? null : sha };
127
+ }
128
+ /**
129
+ * Corpus paths at HEAD. LIVE-MEASURED shape: `{ok, ref, entries:[{path,
130
+ * kind:'blob'|'tree', objectId}]}` — entries include tree rows, so filter to
131
+ * blobs. NO extension filter: the mirror must be a faithful cache of
132
+ * everything the pool holds. Dot-prefixed paths (the birth-seeded
133
+ * `.treedxkeep`) are EXCLUDED on purpose: `walkMirror` never stages them, so
134
+ * a baseline containing one would report a phantom deletion every pass and
135
+ * try to delete the service's own bookkeeping file.
136
+ */
137
+ async function corpusPaths(client, repoId) {
138
+ // PAGINATION IS MANDATORY, not an optimization (live finding 2026-09-23):
139
+ // paths/list answers {entries, page:{limit,hasMore,nextCursor}} capped at
140
+ // 100 — reading one page silently truncated the corpus, and a machine whose
141
+ // twin had pushed the 101st file pulled "up to date" while missing real
142
+ // work. The provider must follow nextCursor until hasMore is false.
143
+ const out = [];
144
+ let cursor;
145
+ for (let page = 0; page < 500; page += 1) {
146
+ const res = await client.post(`/api/v1/repos/${encodeURIComponent(repoId)}/paths/list`, {
147
+ ref: REF,
148
+ ...(cursor !== undefined ? { cursor } : {}),
149
+ });
150
+ if (!res.ok)
151
+ return [];
152
+ const raw = Array.isArray(res.data.entries) ? res.data.entries
153
+ : Array.isArray(res.data.paths) ? res.data.paths : [];
154
+ for (const e of raw) {
155
+ const p = String(typeof e === 'string' ? e : e.path ?? '');
156
+ const kind = typeof e === 'string' ? 'blob' : String(e.kind ?? 'blob');
157
+ if (p !== '' && kind === 'blob' && !p.split('/').some((seg) => seg.startsWith('.')))
158
+ out.push(p);
159
+ }
160
+ const pg = res.data.page;
161
+ if (pg?.hasMore !== true || pg.nextCursor === undefined || pg.nextCursor === cursor)
162
+ return out;
163
+ cursor = pg.nextCursor;
164
+ }
165
+ return out;
166
+ }
167
+ /**
168
+ * Read one corpus file at HEAD. UTF-8 document read; base64 blob fallback.
169
+ * LIVE-MEASURED: a binary path answers `files/read` with 415
170
+ * `unsupported_media_type` — `blobs/read` (→ `blob.contentBase64`) is the
171
+ * binary path back.
172
+ */
173
+ async function readCorpusFile(client, repoId, p) {
174
+ const doc = await client.post(`/api/v1/repos/${encodeURIComponent(repoId)}/files/read`, { ref: REF, path: p, parseFrontmatter: false });
175
+ if (doc.ok) {
176
+ const d = pick(doc.data, 'document', 'file') ?? doc.data;
177
+ const content = d.content;
178
+ if (typeof content === 'string') {
179
+ if (String(d.encoding ?? 'utf8') === 'base64')
180
+ return Buffer.from(content, 'base64');
181
+ return Buffer.from(content, 'utf8');
182
+ }
183
+ return null;
184
+ }
185
+ if (doc.code === 'unsupported_media_type' || doc.status === 415) {
186
+ const blob = await client.post(`/api/v1/repos/${encodeURIComponent(repoId)}/blobs/read`, { ref: REF, path: p });
187
+ if (blob.ok) {
188
+ const b = pick(blob.data, 'blob') ?? blob.data;
189
+ const b64 = String(b.contentBase64 ?? b.content ?? '');
190
+ if (b64 !== '')
191
+ return Buffer.from(b64, 'base64');
192
+ }
193
+ }
194
+ return null;
195
+ }
196
+ async function fetchCorpus(r) {
197
+ const out = new Map();
198
+ for (const p of await corpusPaths(r.client, r.repoId)) {
199
+ const bytes = await readCorpusFile(r.client, r.repoId, p);
200
+ if (bytes !== null)
201
+ out.set(p, bytes);
202
+ }
203
+ return out;
204
+ }
205
+ /**
206
+ * Create the provider (registered under kind 'treedx'). One instance per
207
+ * plane (host/engine); the mirror's state file carries everything across
208
+ * calls, so instances remain safe to share across cwds/projects.
209
+ */
210
+ export function createTreedxProvider(cfgIn = {}) {
211
+ const cfg = { ...DEFAULTS, ...cfgIn };
212
+ const provider = {
213
+ kind: 'treedx',
214
+ describe: (project) => {
215
+ const s = readState(path.join(project.cwd, '.dsh-knowledge'));
216
+ const id = s?.repoId ?? project.repoId ?? '';
217
+ return `treedx · ${id !== '' ? `${id} · ` : ''}${s === null ? 'not cloned yet' : s.offline ? 'offline (push deferred)' : `head ${String(s.head ?? '—').slice(0, 10)}`}`;
218
+ },
219
+ async ensureClone(dir, remote) {
220
+ const state = readState(dir);
221
+ if (state !== null) {
222
+ if (state.origin !== remote.url) {
223
+ return { ok: false, code: 'origin-mismatch', detail: `mirror origin is ${state.origin}, the project's remote is ${remote.url}` };
224
+ }
225
+ return { ok: true, detail: 'already synced (state present)' };
226
+ }
227
+ const res = await resolve(cfg, remote, null);
228
+ if (!res.ok)
229
+ return res.res;
230
+ const r = res.r;
231
+ const head = await headOf(r.client, r.repoId);
232
+ if (!head.ok)
233
+ return head.res;
234
+ // Materialize the corpus into the mirror (the same read surface git mode
235
+ // gives: real files the search/rules/index layers — and the read tool's
236
+ // sibling mirror paths — consume unchanged). A dirty non-empty dir with
237
+ // no state file is dead transport (gitops parity): moving it aside
238
+ // prevents its files being re-pushed as "new" content into a fresh pool.
239
+ const corpus = await fetchCorpus(r);
240
+ if (fs.existsSync(dir)) {
241
+ const strays = fs.readdirSync(dir);
242
+ if (strays.length > 0) {
243
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-');
244
+ fs.renameSync(dir, `${dir}.stale-${stamp}`);
245
+ }
246
+ }
247
+ fs.mkdirSync(dir, { recursive: true });
248
+ const baseline = {};
249
+ for (const [p, bytes] of corpus) {
250
+ const abs = path.join(dir, p);
251
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
252
+ fs.writeFileSync(abs, bytes);
253
+ baseline[p] = contentHash(bytes);
254
+ }
255
+ writeState(dir, { origin: remote.url, head: head.head, baseline, staged: null, offline: false, repoId: r.repoId });
256
+ return { ok: true, detail: `cloned from TreeDX (${corpus.size} file(s)${head.head === null ? ', empty repo' : ''})`, changed: true };
257
+ },
258
+ async initLocal(dir, remote) {
259
+ if (readState(dir) !== null)
260
+ return { ok: true, detail: 'already synced (state present)' };
261
+ if (fs.existsSync(dir) && fs.readdirSync(dir).length > 0) {
262
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-');
263
+ fs.renameSync(dir, `${dir}.stale-${stamp}`);
264
+ }
265
+ fs.mkdirSync(dir, { recursive: true });
266
+ writeState(dir, {
267
+ origin: remote?.url ?? '', head: null, baseline: {}, staged: null, offline: true,
268
+ });
269
+ return { ok: true, detail: 'TreeDX offline mirror initialized', changed: true };
270
+ },
271
+ async removeMirror(dir) {
272
+ fs.rmSync(dir, { recursive: true, force: true });
273
+ return { ok: true, detail: 'mirror removed for rebuild' };
274
+ },
275
+ async stageAllAndCommit(dir, message, author) {
276
+ const state = readState(dir);
277
+ if (state === null)
278
+ return { ok: false, detail: 'no TreeDX state — ensureClone/initLocal first' };
279
+ const present = new Set(walkMirror(dir));
280
+ const changed = [];
281
+ for (const p of present) {
282
+ const bytes = fs.readFileSync(path.join(dir, p));
283
+ if (state.baseline[p] !== contentHash(bytes))
284
+ changed.push(p);
285
+ }
286
+ const dropped = Object.keys(state.baseline).filter((p) => !present.has(p));
287
+ if (changed.length === 0 && dropped.length === 0)
288
+ return { ok: true, detail: 'nothing to commit' };
289
+ // git-mode parity: a second stage of identical bytes is 'nothing to
290
+ // commit'. The baseline advances at STAGE time (push success recomputes
291
+ // it wholesale anyway; divergence replaces it), so the staged set is
292
+ // exactly the workdir-vs-last-known delta.
293
+ const baseline = { ...state.baseline };
294
+ for (const p of changed)
295
+ baseline[p] = contentHash(fs.readFileSync(path.join(dir, p)));
296
+ for (const p of dropped)
297
+ delete baseline[p];
298
+ writeState(dir, { ...state, baseline, staged: { message, author, paths: [...changed, ...dropped].sort() } });
299
+ return { ok: true, detail: `staged ${changed.length} path(s)${dropped.length > 0 ? `, ${dropped.length} removal(s)` : ''}`, changed: true };
300
+ },
301
+ async pullFastForward(dir, remote) {
302
+ const state = readState(dir);
303
+ if (state === null)
304
+ return { ok: false, detail: 'no TreeDX state' };
305
+ if (state.offline) {
306
+ // Recovery probe: still down ⇒ degrade again (§5.3). Reachable ⇒ the
307
+ // offline mirror's commits cannot rebase onto the service's history
308
+ // (ours live only in the store, which is the truth), so classify as
309
+ // diverged and let runSync's rebuild republish from the store —
310
+ // exactly the git mode's diverged-offline recovery.
311
+ const probe = await resolve(cfg, remote, state);
312
+ if (!probe.ok)
313
+ return probe.res;
314
+ const head = await headOf(probe.r.client, probe.r.repoId);
315
+ if (!head.ok)
316
+ return head.res;
317
+ return { ok: false, code: 'diverged', detail: 'offline mirror, TreeDX reachable again — rebuilding mirror from remote' };
318
+ }
319
+ const res = await resolve(cfg, remote, state);
320
+ if (!res.ok)
321
+ return res.res;
322
+ const r = res.r;
323
+ const head = await headOf(r.client, r.repoId);
324
+ if (!head.ok)
325
+ return head.res;
326
+ if (head.head === state.head && state.staged === null)
327
+ return { ok: true, detail: 'up to date (nothing to fast-forward)' };
328
+ if (head.head === state.head)
329
+ return { ok: true, detail: 'up to date (local work staged; push will ship it)' };
330
+ // Remote moved since our base. With staged work in hand, a refetch-merge
331
+ // could leave derived files (index/, topics/) built against a stale
332
+ // corpus — divergence REBUILDS from the store (runSync's path), and the
333
+ // rebuild re-publishes + re-derives. Without staged work, a plain ff
334
+ // refetch is all there is.
335
+ if (state.staged !== null) {
336
+ return { ok: false, code: 'diverged', detail: `TreeDX head moved (${String(state.head).slice(0, 10)} → ${String(head.head).slice(0, 10)}) with local work staged — rebuild will recover` };
337
+ }
338
+ const corpus = await fetchCorpus(r);
339
+ const baseline = {};
340
+ for (const [p, bytes] of corpus) {
341
+ const abs = path.join(dir, p);
342
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
343
+ fs.writeFileSync(abs, bytes);
344
+ baseline[p] = contentHash(bytes);
345
+ }
346
+ writeState(dir, { ...state, head: head.head, baseline });
347
+ return { ok: true, detail: `fast-forwarded (TreeDX ${String(head.head).slice(0, 10)}, ${corpus.size} file(s))`, changed: true };
348
+ },
349
+ async push(dir, remote) {
350
+ const state = readState(dir);
351
+ if (state === null)
352
+ return { ok: false, detail: 'no TreeDX state' };
353
+ if (state.staged === null || state.staged.paths.length === 0)
354
+ return { ok: true, detail: 'pushed (nothing new)' };
355
+ const res = await resolve(cfg, remote, state);
356
+ if (!res.ok)
357
+ return res.res;
358
+ const r = res.r;
359
+ let attempt = 0;
360
+ for (;;) {
361
+ const outcome = await onePush(r, dir, state, cfg);
362
+ if (outcome.retryLease === true && attempt < cfg.leaseRetries) {
363
+ attempt += 1;
364
+ await sleepOf(cfg)(cfg.leaseRetryDelayMs * attempt);
365
+ continue;
366
+ }
367
+ return outcome.res;
368
+ }
369
+ },
370
+ };
371
+ return provider;
372
+ }
373
+ /** One push round: workspace → writes → commit. */
374
+ async function onePush(r, dir, state, cfg) {
375
+ const staged = state.staged;
376
+ if (staged === null || staged.paths.length === 0)
377
+ return { res: { ok: true, detail: 'pushed (nothing new)' } };
378
+ // An empty repo has no head to base on (live-gated assumption, FINDINGS):
379
+ // send baseRef only when one exists.
380
+ const createBody = { branchName: REF, mode: 'writable', ttlSeconds: cfg.workspaceTtlSeconds };
381
+ if (state.head !== null)
382
+ createBody.baseRef = REF;
383
+ const wsRes = await r.client.post(`/api/v1/repos/${encodeURIComponent(r.repoId)}/workspaces`, createBody);
384
+ if (!wsRes.ok) {
385
+ if (wsRes.status === 409)
386
+ return { res: { ok: false, code: 'rejected', detail: `workspace lease busy: ${wsRes.detail}` }, retryLease: true };
387
+ if (wsRes.code === 'auth')
388
+ return { res: { ok: false, code: 'auth', detail: wsRes.detail } };
389
+ return { res: { ok: false, code: 'network', detail: `workspace create: ${wsRes.detail}` } };
390
+ }
391
+ const wsData = pick(wsRes.data, 'workspace') ?? wsRes.data;
392
+ const wsId = String(wsData.workspaceId ?? wsData.id ?? '');
393
+ if (wsId === '')
394
+ return { res: { ok: false, detail: 'workspace create returned no id' } };
395
+ // LIVE-MEASURED: a committed workspace releases its lease, but a half-failed
396
+ // one holds it — and the lease survives its TTL until closed (measured:
397
+ // expiresAt passed, create still 409'd, /close released it). Every failure
398
+ // path after create must close, or a broken push poisons the pool's branch
399
+ // for every machine until an operator intervenes.
400
+ const fail = async (res, retryLease) => {
401
+ await r.client.post(`/api/v1/workspaces/${encodeURIComponent(wsId)}/close`, {}).catch(() => undefined);
402
+ return { res, ...(retryLease === true ? { retryLease } : {}) };
403
+ };
404
+ let wrote = 0;
405
+ for (const p of staged.paths) {
406
+ const abs = path.join(dir, p);
407
+ if (!fs.existsSync(abs)) {
408
+ const del = await r.client.del(`/api/v1/workspaces/${encodeURIComponent(wsId)}/files?path=${encodeURIComponent(p)}`);
409
+ if (!del.ok && del.status !== 404)
410
+ return await fail({ ok: false, detail: `overlay delete ${p}: ${del.detail}` });
411
+ wrote += 1;
412
+ continue;
413
+ }
414
+ const bytes = fs.readFileSync(abs);
415
+ if (isUtf8Safe(bytes)) {
416
+ const w = await r.client.put(`/api/v1/workspaces/${encodeURIComponent(wsId)}/files?path=${encodeURIComponent(p)}`, { encoding: 'utf8', content: bytes.toString('utf8') });
417
+ if (!w.ok) {
418
+ if (w.status === 413)
419
+ return await fail({ ok: false, detail: `file ${p} exceeds TreeDX's UTF-8 file limit: ${w.detail}` });
420
+ return await fail({ ok: false, detail: `overlay write ${p}: ${w.detail}` });
421
+ }
422
+ }
423
+ else {
424
+ // live-measured body: `contentBase64` (a `{encoding,content}` body is a 422)
425
+ const b = await r.client.post(`/api/v1/workspaces/${encodeURIComponent(wsId)}/blobs/write`, { path: p, contentBase64: bytes.toString('base64') });
426
+ if (!b.ok) {
427
+ if (b.status === 413)
428
+ return await fail({ ok: false, detail: `blob ${p} exceeds TreeDX's blob limit: ${b.detail}` });
429
+ return await fail({ ok: false, detail: `blob write ${p}: ${b.detail}` });
430
+ }
431
+ }
432
+ wrote += 1;
433
+ }
434
+ const commit = await r.client.post(`/api/v1/workspaces/${encodeURIComponent(wsId)}/commit`, {
435
+ message: staged.message,
436
+ author: staged.author,
437
+ });
438
+ if (!commit.ok) {
439
+ // A 409 here is TreeDX failing closed on a moved ref / revoked lease.
440
+ // Classify by STATUS and CODE only — never by message prose (r35): the
441
+ // head moved underneath us ⇒ diverged-rebuild; lease ⇒ rejected-retry.
442
+ if (commit.status === 409) {
443
+ const head = await headOf(r.client, r.repoId);
444
+ if (head.ok && head.head !== state.head) {
445
+ return await fail({ ok: false, code: 'diverged', detail: `commit refused; TreeDX head moved (${String(state.head).slice(0, 10)} → ${String(head.head).slice(0, 10)}) — rebuild will recover` });
446
+ }
447
+ return await fail({ ok: false, code: 'rejected', detail: `commit conflict: ${commit.detail}` }, true);
448
+ }
449
+ return await fail({ ok: false, code: commit.code === 'auth' ? 'auth' : 'network', detail: `commit: ${commit.detail}` });
450
+ }
451
+ const cData = pick(commit.data, 'commit') ?? commit.data;
452
+ let newHead = (() => {
453
+ const s = cData.commitSha ?? cData.sha;
454
+ return typeof s === 'string' && s !== '' ? s : null;
455
+ })();
456
+ if (newHead === null) {
457
+ const after = await headOf(r.client, r.repoId);
458
+ if (after.ok)
459
+ newHead = after.head;
460
+ }
461
+ const baseline = { ...state.baseline };
462
+ for (const p of staged.paths) {
463
+ const abs = path.join(dir, p);
464
+ if (fs.existsSync(abs))
465
+ baseline[p] = contentHash(fs.readFileSync(abs));
466
+ else
467
+ delete baseline[p];
468
+ }
469
+ writeState(dir, {
470
+ ...state, head: newHead ?? state.head, baseline, staged: null, offline: false,
471
+ });
472
+ return { res: { ok: true, detail: `pushed ${wrote} path(s) to TreeDX`, changed: true } };
473
+ }
474
+ /** The default instance registered at module load with production defaults;
475
+ * both planes re-register with user config at boot (src/index.ts, engine). */
476
+ const defaultProvider = createTreedxProvider();
477
+ registerProvider(defaultProvider);
478
+ export { defaultProvider as treedxProvider };
479
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/treedx/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export declare const STATE_FILE = ".treedx-state.json";
2
+ export interface TreedxState {
3
+ origin: string;
4
+ head: string | null;
5
+ baseline: Record<string, string>;
6
+ staged: {
7
+ message: string;
8
+ author: {
9
+ name: string;
10
+ email: string;
11
+ };
12
+ paths: string[];
13
+ } | null;
14
+ offline: boolean;
15
+ /** Catalog repo id once resolved (stable even if the name list blips). */
16
+ repoId?: string | undefined;
17
+ }
18
+ export declare const statePath: (dir: string) => string;
19
+ export declare function readState(dir: string): TreedxState | null;
20
+ export declare function writeState(dir: string, s: TreedxState): void;
21
+ export declare const contentHash: (bytes: Buffer | string) => string;
22
+ /** True when a buffer round-trips UTF-8 exactly — the file/blob write decision
23
+ * (TreeDX's File API is UTF-8-only; blobs are binary-safe). */
24
+ export declare function isUtf8Safe(buf: Buffer): boolean;
25
+ /** Walk the mirror's content surface — every file except .git-adjacent dot
26
+ * state (the state file itself, and anything dotted, same rule as git mode). */
27
+ export declare function walkMirror(dir: string, rel?: string): string[];
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Mirror state for the TreeDX transport: `.treedx-state.json` inside the
3
+ * mirror dir. The provider verbs are stateless per call; everything they must
4
+ * remember between verbs (which commit we're based on, which content is
5
+ * already synced, what's staged) lives HERE, in the mirror — because the
6
+ * mirror is transport, and its state file is its equivalent of `.git/`
7
+ * (which the TreeDX provider does not write; the hygiene test's dotfile skip
8
+ * keeps the file out of every commit it participates in).
9
+ *
10
+ * Fields:
11
+ * - origin: the bound treedx+ target (origin-mismatch detection, §3.1/§5.2)
12
+ * - head: the commit sha this mirror's baseline describes; null = empty repo
13
+ * - baseline: path → sha256 of synced content (the ff-only comparison surface)
14
+ * - staged: pending commit (paths → {hash, message}) — stageAllAndCommit
15
+ * records, push ships (or the diverged-rebuild discards, republishing from
16
+ * the store, exactly as git mode does)
17
+ * - offline: true after initLocal (push deferred; §5.3)
18
+ */
19
+ import fs from 'node:fs';
20
+ import path from 'node:path';
21
+ import { sha256 } from "../render.js";
22
+ export const STATE_FILE = '.treedx-state.json';
23
+ export const statePath = (dir) => path.join(dir, STATE_FILE);
24
+ export function readState(dir) {
25
+ try {
26
+ const s = JSON.parse(fs.readFileSync(statePath(dir), 'utf8'));
27
+ if (typeof s.origin !== 'string')
28
+ return null;
29
+ return s;
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ export function writeState(dir, s) {
36
+ fs.mkdirSync(dir, { recursive: true });
37
+ fs.writeFileSync(statePath(dir), JSON.stringify(s, null, 1));
38
+ }
39
+ export const contentHash = (bytes) => sha256(typeof bytes === 'string' ? bytes : bytes.toString('base64'));
40
+ /** True when a buffer round-trips UTF-8 exactly — the file/blob write decision
41
+ * (TreeDX's File API is UTF-8-only; blobs are binary-safe). */
42
+ export function isUtf8Safe(buf) {
43
+ if (buf.includes(0))
44
+ return false;
45
+ const t = buf.toString('utf8');
46
+ return Buffer.byteLength(t, 'utf8') === buf.length && Buffer.from(t, 'utf8').equals(buf);
47
+ }
48
+ /** Walk the mirror's content surface — every file except .git-adjacent dot
49
+ * state (the state file itself, and anything dotted, same rule as git mode). */
50
+ export function walkMirror(dir, rel = '') {
51
+ if (!fs.existsSync(dir))
52
+ return [];
53
+ const out = [];
54
+ for (const e of fs.readdirSync(path.join(dir, rel), { withFileTypes: true })) {
55
+ if (e.name.startsWith('.'))
56
+ continue;
57
+ const r = rel === '' ? e.name : path.posix.join(rel, e.name);
58
+ if (e.isDirectory())
59
+ out.push(...walkMirror(dir, r));
60
+ else
61
+ out.push(r);
62
+ }
63
+ return out.sort();
64
+ }
65
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/treedx/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC,MAAM,CAAC,MAAM,UAAU,GAAG,oBAAoB,CAAA;AAY9C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;AAE5E,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAgB,CAAA;QAC5E,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QAC7C,OAAO,CAAC,CAAA;IACV,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,CAAc;IACpD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACtC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAsB,EAAU,EAAE,CAC5D,MAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAA;AAEtE;+DAC+D;AAC/D,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IACjC,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC9B,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;AAC1F,CAAC;AAED;gFACgF;AAChF,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,GAAG,GAAG,EAAE;IAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAClC,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC7E,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QACpC,MAAM,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;QAC5D,IAAI,CAAC,CAAC,WAAW,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;;YAC/C,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAClB,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAA;AACnB,CAAC"}