@shardworks/codexes-apparatus 0.1.101

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 (63) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +278 -0
  3. package/dist/git.d.ts +39 -0
  4. package/dist/git.d.ts.map +1 -0
  5. package/dist/git.js +66 -0
  6. package/dist/git.js.map +1 -0
  7. package/dist/index.d.ts +14 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +15 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/scriptorium-core.d.ts +68 -0
  12. package/dist/scriptorium-core.d.ts.map +1 -0
  13. package/dist/scriptorium-core.js +488 -0
  14. package/dist/scriptorium-core.js.map +1 -0
  15. package/dist/scriptorium.d.ts +12 -0
  16. package/dist/scriptorium.d.ts.map +1 -0
  17. package/dist/scriptorium.js +41 -0
  18. package/dist/scriptorium.js.map +1 -0
  19. package/dist/tools/codex-add.d.ts +13 -0
  20. package/dist/tools/codex-add.d.ts.map +1 -0
  21. package/dist/tools/codex-add.js +23 -0
  22. package/dist/tools/codex-add.js.map +1 -0
  23. package/dist/tools/codex-list.d.ts +6 -0
  24. package/dist/tools/codex-list.d.ts.map +1 -0
  25. package/dist/tools/codex-list.js +17 -0
  26. package/dist/tools/codex-list.js.map +1 -0
  27. package/dist/tools/codex-push.d.ts +10 -0
  28. package/dist/tools/codex-push.d.ts.map +1 -0
  29. package/dist/tools/codex-push.js +20 -0
  30. package/dist/tools/codex-push.js.map +1 -0
  31. package/dist/tools/codex-remove.d.ts +12 -0
  32. package/dist/tools/codex-remove.d.ts.map +1 -0
  33. package/dist/tools/codex-remove.js +22 -0
  34. package/dist/tools/codex-remove.js.map +1 -0
  35. package/dist/tools/codex-show.d.ts +9 -0
  36. package/dist/tools/codex-show.d.ts.map +1 -0
  37. package/dist/tools/codex-show.js +19 -0
  38. package/dist/tools/codex-show.js.map +1 -0
  39. package/dist/tools/draft-abandon.d.ts +14 -0
  40. package/dist/tools/draft-abandon.d.ts.map +1 -0
  41. package/dist/tools/draft-abandon.js +24 -0
  42. package/dist/tools/draft-abandon.js.map +1 -0
  43. package/dist/tools/draft-list.d.ts +9 -0
  44. package/dist/tools/draft-list.d.ts.map +1 -0
  45. package/dist/tools/draft-list.js +19 -0
  46. package/dist/tools/draft-list.js.map +1 -0
  47. package/dist/tools/draft-open.d.ts +15 -0
  48. package/dist/tools/draft-open.d.ts.map +1 -0
  49. package/dist/tools/draft-open.js +25 -0
  50. package/dist/tools/draft-open.js.map +1 -0
  51. package/dist/tools/draft-seal.d.ts +17 -0
  52. package/dist/tools/draft-seal.d.ts.map +1 -0
  53. package/dist/tools/draft-seal.js +27 -0
  54. package/dist/tools/draft-seal.js.map +1 -0
  55. package/dist/tools/index.d.ts +13 -0
  56. package/dist/tools/index.d.ts.map +1 -0
  57. package/dist/tools/index.js +13 -0
  58. package/dist/tools/index.js.map +1 -0
  59. package/dist/types.d.ts +180 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +11 -0
  62. package/dist/types.js.map +1 -0
  63. package/package.json +34 -0
@@ -0,0 +1,488 @@
1
+ /**
2
+ * The Scriptorium — core logic.
3
+ *
4
+ * Manages the codex registry (bare clones), draft binding lifecycle
5
+ * (worktrees), and sealing (ff-only merge or rebase+ff). All git
6
+ * operations go through the git helper for safety.
7
+ *
8
+ * Draft tracking is in-memory — drafts are reconstructed from
9
+ * filesystem state at startup and maintained in memory during the
10
+ * process lifetime.
11
+ *
12
+ * See: docs/architecture/apparatus/scriptorium.md
13
+ */
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+ import { guild, generateId } from '@shardworks/nexus-core';
17
+ import { git, resolveDefaultBranch, resolveRef, commitsAhead, GitError } from "./git.js";
18
+ // ── Core class ──────────────────────────────────────────────────────
19
+ export class ScriptoriumCore {
20
+ codexes = new Map();
21
+ drafts = new Map(); // keyed by `${codexName}/${branch}`
22
+ maxMergeRetries = 3;
23
+ draftRoot = '.nexus/worktrees';
24
+ // ── Paths ───────────────────────────────────────────────────────
25
+ get home() {
26
+ return guild().home;
27
+ }
28
+ codexesDir() {
29
+ return path.join(this.home, '.nexus', 'codexes');
30
+ }
31
+ bareClonePath(name) {
32
+ return path.join(this.codexesDir(), `${name}.git`);
33
+ }
34
+ draftWorktreePath(codexName, branch) {
35
+ return path.join(this.home, this.draftRoot, codexName, branch);
36
+ }
37
+ // ── Startup ─────────────────────────────────────────────────────
38
+ start() {
39
+ const config = guild().config('codexes');
40
+ // Apply settings
41
+ this.maxMergeRetries = config.settings?.maxMergeRetries ?? 3;
42
+ this.draftRoot = config.settings?.draftRoot ?? '.nexus/worktrees';
43
+ // Ensure infrastructure directories exist
44
+ fs.mkdirSync(this.codexesDir(), { recursive: true });
45
+ // Load registered codexes from config
46
+ const registered = config.registered ?? {};
47
+ for (const [name, entry] of Object.entries(registered)) {
48
+ this.loadCodex(name, entry);
49
+ }
50
+ // Reconcile drafts from filesystem
51
+ this.reconcileDrafts();
52
+ }
53
+ /**
54
+ * Load a codex from config. Checks for existing bare clone;
55
+ * initiates background clone if missing.
56
+ */
57
+ loadCodex(name, entry) {
58
+ const clonePath = this.bareClonePath(name);
59
+ const exists = fs.existsSync(clonePath);
60
+ const state = {
61
+ name,
62
+ remoteUrl: entry.remoteUrl,
63
+ cloneStatus: exists ? 'ready' : 'cloning',
64
+ lastFetched: null,
65
+ };
66
+ if (!exists) {
67
+ // Background clone — doesn't block startup
68
+ state.clonePromise = this.performClone(name, entry.remoteUrl)
69
+ .then(() => { state.cloneStatus = 'ready'; })
70
+ .catch((err) => {
71
+ state.cloneStatus = 'error';
72
+ console.warn(`[scriptorium] Background clone of "${name}" failed: ${err instanceof Error ? err.message : err}`);
73
+ });
74
+ }
75
+ this.codexes.set(name, state);
76
+ }
77
+ /**
78
+ * Reconcile in-memory draft tracking with filesystem state.
79
+ * Scans the worktree directories and rebuilds the draft map.
80
+ */
81
+ reconcileDrafts() {
82
+ const worktreeRoot = path.join(this.home, this.draftRoot);
83
+ if (!fs.existsSync(worktreeRoot))
84
+ return;
85
+ for (const codexDir of fs.readdirSync(worktreeRoot, { withFileTypes: true })) {
86
+ if (!codexDir.isDirectory())
87
+ continue;
88
+ const codexName = codexDir.name;
89
+ // Only reconcile drafts for known codexes
90
+ if (!this.codexes.has(codexName))
91
+ continue;
92
+ const codexWorktreeDir = path.join(worktreeRoot, codexName);
93
+ for (const draftDir of fs.readdirSync(codexWorktreeDir, { withFileTypes: true })) {
94
+ if (!draftDir.isDirectory())
95
+ continue;
96
+ const branch = draftDir.name;
97
+ const draftPath = path.join(codexWorktreeDir, branch);
98
+ // Verify it's actually a git worktree (has .git file)
99
+ if (!fs.existsSync(path.join(draftPath, '.git')))
100
+ continue;
101
+ const key = `${codexName}/${branch}`;
102
+ if (!this.drafts.has(key)) {
103
+ this.drafts.set(key, {
104
+ id: generateId('draft', 4),
105
+ codexName,
106
+ branch,
107
+ path: draftPath,
108
+ createdAt: new Date().toISOString(), // approximate — we don't know the real time
109
+ });
110
+ }
111
+ }
112
+ }
113
+ }
114
+ // ── Clone readiness ─────────────────────────────────────────────
115
+ /**
116
+ * Ensure a codex's bare clone is ready. Blocks if a background
117
+ * clone is in progress. Throws if the codex is unknown or clone failed.
118
+ */
119
+ async ensureReady(name) {
120
+ const state = this.codexes.get(name);
121
+ if (!state) {
122
+ throw new Error(`Codex "${name}" is not registered. Use codex-add to register it.`);
123
+ }
124
+ if (state.clonePromise) {
125
+ await state.clonePromise;
126
+ state.clonePromise = undefined;
127
+ }
128
+ if (state.cloneStatus === 'error') {
129
+ throw new Error(`Codex "${name}" bare clone failed. Remove and re-add the codex, or check the remote URL.`);
130
+ }
131
+ return state;
132
+ }
133
+ // ── Git operations ──────────────────────────────────────────────
134
+ async performClone(name, remoteUrl) {
135
+ const clonePath = this.bareClonePath(name);
136
+ fs.mkdirSync(path.dirname(clonePath), { recursive: true });
137
+ await git(['clone', '--bare', remoteUrl, clonePath]);
138
+ }
139
+ /**
140
+ * Advance refs/heads/<branch> to the remote's position if the remote is
141
+ * strictly ahead of the local sealed binding.
142
+ *
143
+ * This handles commits pushed to the remote outside the Scriptorium:
144
+ * if the remote has advanced past the local sealed binding, sealing must
145
+ * rebase the draft onto the remote position — not the stale local one.
146
+ *
147
+ * If the local sealed binding is already ahead of (or equal to) the remote
148
+ * (e.g. contains unpushed seals from contention scenarios), it is kept.
149
+ */
150
+ async advanceToRemote(codexName, branch) {
151
+ const clonePath = this.bareClonePath(codexName);
152
+ let remoteRef;
153
+ try {
154
+ remoteRef = await resolveRef(clonePath, `refs/remotes/origin/${branch}`);
155
+ }
156
+ catch {
157
+ return; // No remote tracking ref (branch may not exist on remote yet)
158
+ }
159
+ const localRef = await resolveRef(clonePath, branch);
160
+ if (remoteRef === localRef)
161
+ return;
162
+ const { stdout: mergeBase } = await git(['merge-base', localRef, remoteRef], clonePath);
163
+ if (mergeBase === localRef) {
164
+ // Local is an ancestor of remote → remote is ahead → advance local
165
+ await git(['update-ref', `refs/heads/${branch}`, remoteRef], clonePath);
166
+ }
167
+ // If local is ahead of or diverged from remote: keep the local sealed binding
168
+ }
169
+ async performFetch(name) {
170
+ const clonePath = this.bareClonePath(name);
171
+ // Explicit refspec is required: git clone --bare does not configure a
172
+ // fetch refspec, so plain `git fetch origin` only updates FETCH_HEAD and
173
+ // leaves refs/heads/* stale.
174
+ //
175
+ // We fetch into refs/remotes/origin/* rather than refs/heads/* for two
176
+ // reasons:
177
+ // 1. It avoids force-overwriting local draft branches (which live in
178
+ // refs/heads/* but do not exist on the remote).
179
+ // 2. It separates the "remote position" (refs/remotes/origin/*) from
180
+ // the "local sealed binding" (refs/heads/*), letting seal() advance
181
+ // refs/heads/* only when the remote is strictly ahead.
182
+ await git(['fetch', '--prune', 'origin', '+refs/heads/*:refs/remotes/origin/*'], clonePath);
183
+ const state = this.codexes.get(name);
184
+ if (state) {
185
+ state.lastFetched = new Date().toISOString();
186
+ }
187
+ }
188
+ // ── API Implementation ────────────────────────────────────────
189
+ createApi() {
190
+ return {
191
+ add: (name, remoteUrl) => this.add(name, remoteUrl),
192
+ list: () => this.list(),
193
+ show: (name) => this.show(name),
194
+ remove: (name) => this.remove(name),
195
+ fetch: (name) => this.fetchCodex(name),
196
+ push: (request) => this.push(request),
197
+ openDraft: (request) => this.openDraft(request),
198
+ listDrafts: (codexName) => this.listDrafts(codexName),
199
+ abandonDraft: (request) => this.abandonDraft(request),
200
+ seal: (request) => this.seal(request),
201
+ };
202
+ }
203
+ // ── Codex Registry ──────────────────────────────────────────────
204
+ async add(name, remoteUrl) {
205
+ if (this.codexes.has(name)) {
206
+ throw new Error(`Codex "${name}" is already registered.`);
207
+ }
208
+ // Clone bare repo (blocking)
209
+ const state = {
210
+ name,
211
+ remoteUrl,
212
+ cloneStatus: 'cloning',
213
+ lastFetched: null,
214
+ };
215
+ this.codexes.set(name, state);
216
+ try {
217
+ await this.performClone(name, remoteUrl);
218
+ state.cloneStatus = 'ready';
219
+ }
220
+ catch (err) {
221
+ state.cloneStatus = 'error';
222
+ this.codexes.delete(name);
223
+ throw new Error(`Failed to clone "${remoteUrl}" for codex "${name}": ${err instanceof Error ? err.message : err}`);
224
+ }
225
+ // Persist to guild.json
226
+ const config = guild().config('codexes');
227
+ const registered = config.registered ?? {};
228
+ registered[name] = { remoteUrl };
229
+ guild().writeConfig('codexes', { ...config, registered });
230
+ return this.toCodexRecord(state);
231
+ }
232
+ async list() {
233
+ const records = [];
234
+ for (const state of this.codexes.values()) {
235
+ records.push(this.toCodexRecord(state));
236
+ }
237
+ return records;
238
+ }
239
+ async show(name) {
240
+ const state = await this.ensureReady(name);
241
+ const clonePath = this.bareClonePath(name);
242
+ const defaultBranch = await resolveDefaultBranch(clonePath);
243
+ const drafts = this.draftsForCodex(name);
244
+ return {
245
+ name: state.name,
246
+ remoteUrl: state.remoteUrl,
247
+ cloneStatus: state.cloneStatus,
248
+ activeDrafts: drafts.length,
249
+ defaultBranch,
250
+ lastFetched: state.lastFetched,
251
+ drafts,
252
+ };
253
+ }
254
+ async remove(name) {
255
+ const state = this.codexes.get(name);
256
+ if (!state) {
257
+ throw new Error(`Codex "${name}" is not registered.`);
258
+ }
259
+ // Abandon all drafts for this codex
260
+ const drafts = this.draftsForCodex(name);
261
+ for (const draft of drafts) {
262
+ await this.abandonDraft({ codexName: name, branch: draft.branch, force: true });
263
+ }
264
+ // Remove bare clone
265
+ const clonePath = this.bareClonePath(name);
266
+ if (fs.existsSync(clonePath)) {
267
+ fs.rmSync(clonePath, { recursive: true, force: true });
268
+ }
269
+ // Remove from in-memory state
270
+ this.codexes.delete(name);
271
+ // Remove from guild.json
272
+ const config = guild().config('codexes');
273
+ const registered = { ...(config.registered ?? {}) };
274
+ delete registered[name];
275
+ guild().writeConfig('codexes', { ...config, registered });
276
+ }
277
+ async fetchCodex(name) {
278
+ await this.ensureReady(name);
279
+ await this.performFetch(name);
280
+ }
281
+ async push(request) {
282
+ const state = await this.ensureReady(request.codexName);
283
+ const clonePath = this.bareClonePath(state.name);
284
+ const branch = request.branch ?? await resolveDefaultBranch(clonePath);
285
+ await git(['push', 'origin', branch], clonePath);
286
+ }
287
+ // ── Draft Binding Lifecycle ─────────────────────────────────────
288
+ async openDraft(request) {
289
+ const state = await this.ensureReady(request.codexName);
290
+ const clonePath = this.bareClonePath(state.name);
291
+ // Fetch before branching for freshness
292
+ await this.performFetch(state.name);
293
+ const branch = request.branch ?? generateId('draft', 4);
294
+ const key = `${request.codexName}/${branch}`;
295
+ // Reject if draft already exists
296
+ if (this.drafts.has(key)) {
297
+ throw new Error(`Draft with branch "${branch}" already exists for codex "${request.codexName}". ` +
298
+ `Choose a different branch name or abandon the existing draft.`);
299
+ }
300
+ const defaultBranch = await resolveDefaultBranch(clonePath);
301
+ const startPoint = request.startPoint ?? defaultBranch;
302
+ // Advance the start-point branch to the remote position if the remote
303
+ // has moved ahead. Ensures the draft branches from the latest state.
304
+ await this.advanceToRemote(state.name, startPoint);
305
+ const worktreePath = this.draftWorktreePath(request.codexName, branch);
306
+ fs.mkdirSync(path.dirname(worktreePath), { recursive: true });
307
+ // Create worktree with new branch from start point
308
+ await git(['worktree', 'add', worktreePath, '-b', branch, startPoint], clonePath);
309
+ const draft = {
310
+ id: generateId('draft', 4),
311
+ codexName: request.codexName,
312
+ branch,
313
+ path: worktreePath,
314
+ createdAt: new Date().toISOString(),
315
+ associatedWith: request.associatedWith,
316
+ };
317
+ this.drafts.set(key, draft);
318
+ return draft;
319
+ }
320
+ async listDrafts(codexName) {
321
+ if (codexName) {
322
+ return this.draftsForCodex(codexName);
323
+ }
324
+ return [...this.drafts.values()];
325
+ }
326
+ async abandonDraft(request) {
327
+ const key = `${request.codexName}/${request.branch}`;
328
+ const draft = this.drafts.get(key);
329
+ if (!draft) {
330
+ throw new Error(`No active draft with branch "${request.branch}" for codex "${request.codexName}".`);
331
+ }
332
+ // Check for unsealed inscriptions (commits ahead of the sealed binding)
333
+ if (!request.force) {
334
+ const state = await this.ensureReady(request.codexName);
335
+ const clonePath = this.bareClonePath(state.name);
336
+ try {
337
+ const defaultBranch = await resolveDefaultBranch(clonePath);
338
+ const ahead = await commitsAhead(clonePath, request.branch, defaultBranch);
339
+ if (ahead > 0) {
340
+ throw new Error(`Draft "${request.branch}" has ${ahead} unsealed inscription(s). ` +
341
+ `Use force: true to abandon anyway, or seal the draft first.`);
342
+ }
343
+ }
344
+ catch (err) {
345
+ // If the branch doesn't exist in the bare clone (already cleaned up),
346
+ // that's fine — proceed with cleanup
347
+ if (err instanceof GitError && err.stderr.includes('unknown revision')) {
348
+ // Branch already gone — proceed with cleanup
349
+ }
350
+ else if (err instanceof Error && err.message.includes('unsealed inscription')) {
351
+ throw err;
352
+ }
353
+ // Other git errors during the check are non-fatal — proceed with cleanup
354
+ }
355
+ }
356
+ // Remove worktree
357
+ const clonePath = this.bareClonePath(request.codexName);
358
+ try {
359
+ await git(['worktree', 'remove', '--force', draft.path], clonePath);
360
+ }
361
+ catch {
362
+ // If worktree removal fails (e.g. already gone), try manual cleanup
363
+ if (fs.existsSync(draft.path)) {
364
+ fs.rmSync(draft.path, { recursive: true, force: true });
365
+ }
366
+ // Prune stale worktree references
367
+ try {
368
+ await git(['worktree', 'prune'], clonePath);
369
+ }
370
+ catch { /* best effort */ }
371
+ }
372
+ // Delete the branch from the bare clone
373
+ try {
374
+ await git(['branch', '-D', request.branch], clonePath);
375
+ }
376
+ catch {
377
+ // Branch may already be gone — that's fine
378
+ }
379
+ // Remove from in-memory tracking
380
+ this.drafts.delete(key);
381
+ }
382
+ async seal(request) {
383
+ const state = await this.ensureReady(request.codexName);
384
+ const clonePath = this.bareClonePath(state.name);
385
+ const maxRetries = request.maxRetries ?? this.maxMergeRetries;
386
+ const defaultBranch = await resolveDefaultBranch(clonePath);
387
+ const targetBranch = request.targetBranch ?? defaultBranch;
388
+ let strategy = 'fast-forward';
389
+ let retries = 0;
390
+ // Fetch before sealing for freshness
391
+ await this.performFetch(state.name);
392
+ // Advance the local sealed binding to the remote position if the remote
393
+ // has moved ahead (e.g. commits pushed outside the Scriptorium).
394
+ // This ensures seal compares against the latest remote ref, not a
395
+ // potentially stale local one — preventing push failures.
396
+ await this.advanceToRemote(state.name, targetBranch);
397
+ // Attempt ff-only merge, with rebase retry loop
398
+ while (retries <= maxRetries) {
399
+ try {
400
+ // Try fast-forward merge: update the target branch ref to point at the source
401
+ // In a bare repo, we use `git merge --ff-only` with the branch checked out,
402
+ // but bare repos don't have a checkout. Instead, we verify ancestry and
403
+ // update the ref directly.
404
+ const targetRef = await resolveRef(clonePath, targetBranch);
405
+ const sourceRef = await resolveRef(clonePath, request.sourceBranch);
406
+ // Check if source is already at target (nothing to seal)
407
+ if (targetRef === sourceRef) {
408
+ // Clean up draft unless keepDraft
409
+ if (!request.keepDraft) {
410
+ await this.abandonDraft({
411
+ codexName: request.codexName,
412
+ branch: request.sourceBranch,
413
+ force: true,
414
+ });
415
+ }
416
+ return { success: true, strategy, retries, sealedCommit: targetRef, inscriptionsSealed: 0 };
417
+ }
418
+ // Check if target is an ancestor of source (ff is possible)
419
+ const { stdout: mergeBase } = await git(['merge-base', targetBranch, request.sourceBranch], clonePath);
420
+ if (mergeBase === targetRef) {
421
+ // Fast-forward is possible — count and incorporate inscriptions
422
+ const inscriptionsSealed = await commitsAhead(clonePath, request.sourceBranch, targetBranch);
423
+ await git(['update-ref', `refs/heads/${targetBranch}`, sourceRef], clonePath);
424
+ // Clean up draft unless keepDraft
425
+ if (!request.keepDraft) {
426
+ await this.abandonDraft({
427
+ codexName: request.codexName,
428
+ branch: request.sourceBranch,
429
+ force: true,
430
+ });
431
+ }
432
+ return { success: true, strategy, retries, sealedCommit: sourceRef, inscriptionsSealed };
433
+ }
434
+ // FF not possible — rebase the source branch onto the target
435
+ strategy = 'rebase';
436
+ // Rebase needs a worktree (can't rebase in a bare repo).
437
+ // Use the draft's existing worktree.
438
+ const key = `${request.codexName}/${request.sourceBranch}`;
439
+ const draft = this.drafts.get(key);
440
+ if (!draft) {
441
+ throw new Error(`Cannot rebase: no active draft for branch "${request.sourceBranch}". ` +
442
+ `The draft worktree is needed for rebase operations.`);
443
+ }
444
+ try {
445
+ await git(['rebase', targetBranch], draft.path);
446
+ }
447
+ catch (err) {
448
+ // Rebase conflict — abort and fail
449
+ try {
450
+ await git(['rebase', '--abort'], draft.path);
451
+ }
452
+ catch { /* best effort */ }
453
+ throw new Error(`Sealing seized: rebase of "${request.sourceBranch}" onto "${targetBranch}" ` +
454
+ `produced conflicts. Manual reconciliation is needed.`);
455
+ }
456
+ // Rebase succeeded — re-fetch and retry the ff merge
457
+ retries++;
458
+ await this.performFetch(state.name);
459
+ continue;
460
+ }
461
+ catch (err) {
462
+ if (err instanceof Error && err.message.includes('Sealing seized')) {
463
+ throw err;
464
+ }
465
+ if (err instanceof Error && err.message.includes('Cannot rebase')) {
466
+ throw err;
467
+ }
468
+ // Unexpected error — don't retry
469
+ throw err;
470
+ }
471
+ }
472
+ throw new Error(`Sealing failed after ${maxRetries} retries. Codex "${request.codexName}", ` +
473
+ `branch "${request.sourceBranch}" → "${targetBranch}".`);
474
+ }
475
+ // ── Helpers ───────────────────────────────────────────────────────
476
+ draftsForCodex(codexName) {
477
+ return [...this.drafts.values()].filter((d) => d.codexName === codexName);
478
+ }
479
+ toCodexRecord(state) {
480
+ return {
481
+ name: state.name,
482
+ remoteUrl: state.remoteUrl,
483
+ cloneStatus: state.cloneStatus,
484
+ activeDrafts: this.draftsForCodex(state.name).length,
485
+ };
486
+ }
487
+ }
488
+ //# sourceMappingURL=scriptorium-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scriptorium-core.js","sourceRoot":"","sources":["../src/scriptorium-core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The Scriptorium — apparatus implementation.
3
+ *
4
+ * Wires together the ScriptoriumCore (git operations, draft lifecycle)
5
+ * and exposes the ScriptoriumApi as the `provides` object. Tools are
6
+ * contributed via supportKit.
7
+ *
8
+ * See: docs/architecture/apparatus/scriptorium.md
9
+ */
10
+ import type { Plugin } from '@shardworks/nexus-core';
11
+ export declare function createScriptorium(): Plugin;
12
+ //# sourceMappingURL=scriptorium.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scriptorium.d.ts","sourceRoot":"","sources":["../src/scriptorium.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,MAAM,EAEP,MAAM,wBAAwB,CAAC;AAmBhC,wBAAgB,iBAAiB,IAAI,MAAM,CA+B1C"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The Scriptorium — apparatus implementation.
3
+ *
4
+ * Wires together the ScriptoriumCore (git operations, draft lifecycle)
5
+ * and exposes the ScriptoriumApi as the `provides` object. Tools are
6
+ * contributed via supportKit.
7
+ *
8
+ * See: docs/architecture/apparatus/scriptorium.md
9
+ */
10
+ import { ScriptoriumCore } from "./scriptorium-core.js";
11
+ import { codexAdd, codexList, codexShow, codexRemove, codexPush, draftOpen, draftList, draftAbandon, draftSeal, } from "./tools/index.js";
12
+ // ── Apparatus export ──────────────────────────────────────────────────
13
+ export function createScriptorium() {
14
+ const core = new ScriptoriumCore();
15
+ let api;
16
+ return {
17
+ apparatus: {
18
+ requires: [],
19
+ consumes: [],
20
+ get provides() { return api; },
21
+ supportKit: {
22
+ tools: [
23
+ codexAdd,
24
+ codexList,
25
+ codexShow,
26
+ codexRemove,
27
+ codexPush,
28
+ draftOpen,
29
+ draftList,
30
+ draftAbandon,
31
+ draftSeal,
32
+ ],
33
+ },
34
+ start(_ctx) {
35
+ core.start();
36
+ api = core.createApi();
37
+ },
38
+ },
39
+ };
40
+ }
41
+ //# sourceMappingURL=scriptorium.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scriptorium.js","sourceRoot":"","sources":["../src/scriptorium.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EACL,QAAQ,EACR,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,SAAS,GACV,MAAM,kBAAkB,CAAC;AAE1B,yEAAyE;AAEzE,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,IAAI,GAAmB,CAAC;IAExB,OAAO;QACL,SAAS,EAAE;YACT,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,EAAE;YAEZ,IAAI,QAAQ,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC;YAE9B,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,QAAQ;oBACR,SAAS;oBACT,SAAS;oBACT,WAAW;oBACX,SAAS;oBACT,SAAS;oBACT,SAAS;oBACT,YAAY;oBACZ,SAAS;iBACV;aACF;YAED,KAAK,CAAC,IAAoB;gBACxB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACzB,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * codex-add tool — register an existing git repository as a guild codex.
3
+ *
4
+ * Clones a bare copy to `.nexus/codexes/<name>.git` and adds the entry
5
+ * to guild.json. Blocks until the clone completes.
6
+ */
7
+ import { z } from 'zod';
8
+ declare const _default: import("@shardworks/tools-apparatus").ToolDefinition<{
9
+ name: z.ZodString;
10
+ remoteUrl: z.ZodString;
11
+ }>;
12
+ export default _default;
13
+ //# sourceMappingURL=codex-add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-add.d.ts","sourceRoot":"","sources":["../../src/tools/codex-add.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;;;;;AAGxB,wBAYG"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * codex-add tool — register an existing git repository as a guild codex.
3
+ *
4
+ * Clones a bare copy to `.nexus/codexes/<name>.git` and adds the entry
5
+ * to guild.json. Blocks until the clone completes.
6
+ */
7
+ import { tool } from '@shardworks/tools-apparatus';
8
+ import { guild } from '@shardworks/nexus-core';
9
+ import { z } from 'zod';
10
+ export default tool({
11
+ name: 'codex-add',
12
+ description: 'Register an existing git repository as a guild codex',
13
+ permission: 'write',
14
+ params: {
15
+ name: z.string().describe('Name for the codex (unique within the guild)'),
16
+ remoteUrl: z.string().describe('Git remote URL of the repository'),
17
+ },
18
+ handler: async ({ name, remoteUrl }) => {
19
+ const api = guild().apparatus('codexes');
20
+ return api.add(name, remoteUrl);
21
+ },
22
+ });
23
+ //# sourceMappingURL=codex-add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-add.js","sourceRoot":"","sources":["../../src/tools/codex-add.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAe,IAAI,CAAC;IAClB,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,sDAAsD;IACnE,UAAU,EAAE,OAAO;IACnB,MAAM,EAAE;QACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;QACzE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;KACnE;IACD,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC,SAAS,CAAiB,SAAS,CAAC,CAAC;QACzD,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAClC,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * codex-list tool — list all registered codexes.
3
+ */
4
+ declare const _default: import("@shardworks/tools-apparatus").ToolDefinition<{}>;
5
+ export default _default;
6
+ //# sourceMappingURL=codex-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-list.d.ts","sourceRoot":"","sources":["../../src/tools/codex-list.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAOH,wBASG"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * codex-list tool — list all registered codexes.
3
+ */
4
+ import { tool } from '@shardworks/tools-apparatus';
5
+ import { guild } from '@shardworks/nexus-core';
6
+ import { z } from 'zod';
7
+ export default tool({
8
+ name: 'codex-list',
9
+ description: 'List all codexes registered with the guild',
10
+ permission: 'read',
11
+ params: {},
12
+ handler: async () => {
13
+ const api = guild().apparatus('codexes');
14
+ return api.list();
15
+ },
16
+ });
17
+ //# sourceMappingURL=codex-list.js.map