@shardworks/dispatch-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.
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Sean Boots
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # `@shardworks/dispatch-apparatus`
2
+
3
+ > **⚠️ Temporary rigging.** The Dispatch is a stand-in for the full rigging system (Walker, Formulary, Executor). When that system exists, this apparatus is retired.
4
+
5
+ The Dispatch is the guild's interim work runner. It bridges the gap between the Clerk (which tracks obligations) and the session machinery (which runs animas). It does one thing: find the oldest ready writ and execute it.
6
+
7
+ The Dispatch sits downstream of the Clerk and Animator:
8
+ `clerk ← dispatch → animator → (codexes)`
9
+
10
+ ---
11
+
12
+ ## Installation
13
+
14
+ Add to your package's dependencies:
15
+
16
+ ```json
17
+ {
18
+ "@shardworks/dispatch-apparatus": "workspace:*"
19
+ }
20
+ ```
21
+
22
+ The Dispatch requires the Clerk, Scriptorium (codexes), and Animator to be installed in the guild. The Loom is recommended (used indirectly via `Animator.summon()`). The Stacks is used internally by the Clerk but is not a direct dependency of the Dispatch.
23
+
24
+ ---
25
+
26
+ ## API
27
+
28
+ The Dispatch exposes a `DispatchApi` via its `provides` interface, retrieved at runtime:
29
+
30
+ ```typescript
31
+ import type { DispatchApi } from '@shardworks/dispatch-apparatus';
32
+
33
+ const dispatch = guild().apparatus<DispatchApi>('dispatch');
34
+ ```
35
+
36
+ ### `next(request?): Promise<DispatchResult | null>`
37
+
38
+ Find the oldest ready writ and execute it.
39
+
40
+ ```typescript
41
+ // Dispatch with defaults (role: 'artificer')
42
+ const result = await dispatch.next();
43
+
44
+ // Dispatch with a specific role
45
+ const result = await dispatch.next({ role: 'scribe' });
46
+
47
+ // Dry run — preview without dispatching
48
+ const result = await dispatch.next({ dryRun: true });
49
+
50
+ if (!result) {
51
+ console.log('No ready writs.');
52
+ } else {
53
+ console.log(result.outcome); // 'completed' | 'failed' | undefined (dryRun)
54
+ }
55
+ ```
56
+
57
+ | Parameter | Type | Description |
58
+ |---|---|---|
59
+ | `role` | `string` | Role to summon (default: `"artificer"`) |
60
+ | `dryRun` | `boolean` | If true, find and report the writ but don't dispatch |
61
+
62
+ Returns `null` if no ready writs exist.
63
+
64
+ ---
65
+
66
+ ## Dispatch Lifecycle
67
+
68
+ ```
69
+ next({ role: 'artificer' })
70
+
71
+ ├─ 1. Query Clerk: clerk.list({ status: 'ready' }), take oldest (last in desc list)
72
+ │ → if none found, return null
73
+
74
+ ├─ 2. Clerk: transition writ ready → active
75
+
76
+ ├─ 3. [if writ.codex] Scriptorium: openDraft({ codexName: writ.codex })
77
+ │ → draftRecord (worktree path = session cwd)
78
+ │ → if no codex on writ, cwd = guild home
79
+
80
+ ├─ 4. Animator: summon({ role, prompt, cwd, metadata: { writId, trigger: 'dispatch' } })
81
+ │ → { chunks, result }
82
+
83
+ ├─ 5. Await result
84
+
85
+ ├─ 6a. [success] Session completed normally
86
+ │ ├─ [if codex] Scriptorium: seal({ codexName, sourceBranch: draft.branch })
87
+ │ ├─ [if codex] Scriptorium: push({ codexName })
88
+ │ ├─ Clerk: transition writ active → completed
89
+ │ └─ return DispatchResult { outcome: 'completed' }
90
+
91
+ └─ 6b. [failure] Session failed or timed out
92
+ ├─ [if codex] Scriptorium: abandonDraft({ codexName, branch, force: true })
93
+ ├─ Clerk: transition writ active → failed
94
+ └─ return DispatchResult { outcome: 'failed' }
95
+ ```
96
+
97
+ ### Error Handling
98
+
99
+ | Failure | Writ transition | Draft |
100
+ |---|---|---|
101
+ | No ready writs | none | n/a |
102
+ | Draft open fails | → `failed` | n/a (never opened) |
103
+ | Session fails | → `failed` | abandoned (force) |
104
+ | Seal fails | → `failed` | **preserved** (for recovery) |
105
+ | Push fails | → `failed` | **preserved** (for recovery) |
106
+
107
+ The Dispatch owns writ transitions — the anima does **not** call `writ-complete` or `writ-fail`. This keeps writ lifecycle management out of anima instructions.
108
+
109
+ ---
110
+
111
+ ## Support Kit
112
+
113
+ The Dispatch contributes one tool:
114
+
115
+ ### Tools
116
+
117
+ | Tool | Permission | Callable by | Description |
118
+ |---|---|---|---|
119
+ | `dispatch-next` | `dispatch:write` | `cli` | Find and dispatch the oldest ready writ |
120
+
121
+ ---
122
+
123
+ ## Key Types
124
+
125
+ ```typescript
126
+ interface DispatchApi {
127
+ next(request?: DispatchRequest): Promise<DispatchResult | null>;
128
+ }
129
+
130
+ interface DispatchRequest {
131
+ role?: string; // default: 'artificer'
132
+ dryRun?: boolean;
133
+ }
134
+
135
+ interface DispatchResult {
136
+ writId: string;
137
+ sessionId?: string; // absent if dryRun
138
+ outcome?: 'completed' | 'failed'; // absent if dryRun
139
+ resolution?: string; // absent if dryRun
140
+ dryRun: boolean;
141
+ }
142
+ ```
143
+
144
+ See `src/types.ts` for the complete type definitions.
145
+
146
+ ---
147
+
148
+ ## Configuration
149
+
150
+ No configuration. The Dispatch reads writs from the Clerk and uses default behaviors for all apparatus calls. The role is specified per dispatch via the tool parameter.
151
+
152
+ ---
153
+
154
+ ## Exports
155
+
156
+ The package exports all public types and the `createDispatch()` factory:
157
+
158
+ ```typescript
159
+ import dispatchPlugin, { createDispatch, type DispatchApi } from '@shardworks/dispatch-apparatus';
160
+ ```
161
+
162
+ The default export is a pre-built plugin instance, ready for guild installation.
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The Dispatch — interim work runner.
3
+ *
4
+ * Bridges the Clerk (which tracks obligations) and the session machinery
5
+ * (which runs animas). Finds the oldest ready writ and executes it:
6
+ * opens a draft binding, composes context, launches a session, and handles
7
+ * the aftermath (seal the draft, transition the writ).
8
+ *
9
+ * This apparatus is temporary rigging — designed to be retired when the
10
+ * full rigging system (Walker, Formulary, Executor) is implemented.
11
+ *
12
+ * See: docs/architecture/apparatus/dispatch.md
13
+ */
14
+ import type { Plugin } from '@shardworks/nexus-core';
15
+ /**
16
+ * Create the Dispatch apparatus plugin.
17
+ *
18
+ * Returns a Plugin with:
19
+ * - `requires: ['clerk', 'codexes', 'animator']`
20
+ * - `recommends: ['loom']` — used indirectly via Animator.summon()
21
+ * - `provides: DispatchApi` — the dispatch API
22
+ * - `supportKit` — contributes the `dispatch-next` tool
23
+ */
24
+ export declare function createDispatch(): Plugin;
25
+ //# sourceMappingURL=dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AA+BrD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAqHvC"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * The Dispatch — interim work runner.
3
+ *
4
+ * Bridges the Clerk (which tracks obligations) and the session machinery
5
+ * (which runs animas). Finds the oldest ready writ and executes it:
6
+ * opens a draft binding, composes context, launches a session, and handles
7
+ * the aftermath (seal the draft, transition the writ).
8
+ *
9
+ * This apparatus is temporary rigging — designed to be retired when the
10
+ * full rigging system (Walker, Formulary, Executor) is implemented.
11
+ *
12
+ * See: docs/architecture/apparatus/dispatch.md
13
+ */
14
+ import { guild } from '@shardworks/nexus-core';
15
+ import { dispatchNext } from "./tools/index.js";
16
+ // ── Prompt assembly ──────────────────────────────────────────────────
17
+ function assemblePrompt(writ) {
18
+ const lines = [
19
+ 'You have been dispatched to fulfill a commission.',
20
+ '',
21
+ '## Assignment',
22
+ '',
23
+ `**Title:** ${writ.title}`,
24
+ '',
25
+ `**Writ ID:** ${writ.id}`,
26
+ ];
27
+ if (writ.body) {
28
+ lines.push('', writ.body);
29
+ }
30
+ return lines.join('\n');
31
+ }
32
+ // ── Apparatus factory ────────────────────────────────────────────────
33
+ /**
34
+ * Create the Dispatch apparatus plugin.
35
+ *
36
+ * Returns a Plugin with:
37
+ * - `requires: ['clerk', 'codexes', 'animator']`
38
+ * - `recommends: ['loom']` — used indirectly via Animator.summon()
39
+ * - `provides: DispatchApi` — the dispatch API
40
+ * - `supportKit` — contributes the `dispatch-next` tool
41
+ */
42
+ export function createDispatch() {
43
+ const api = {
44
+ async next(request) {
45
+ const role = request?.role ?? 'artificer';
46
+ const dryRun = request?.dryRun ?? false;
47
+ const clerk = guild().apparatus('clerk');
48
+ // 1. Find oldest ready writ (FIFO — list returns desc by createdAt, take last)
49
+ const readyWrits = await clerk.list({ status: 'ready' });
50
+ const writ = readyWrits[readyWrits.length - 1] ?? null;
51
+ if (!writ)
52
+ return null;
53
+ if (dryRun) {
54
+ return { writId: writ.id, dryRun: true };
55
+ }
56
+ const scriptorium = guild().apparatus('codexes');
57
+ const animator = guild().apparatus('animator');
58
+ // 2. Transition writ ready → active
59
+ await clerk.transition(writ.id, 'active');
60
+ // 3. Open draft if writ has a codex
61
+ const codexName = typeof writ.codex === 'string' ? writ.codex : undefined;
62
+ let draft;
63
+ if (codexName) {
64
+ try {
65
+ draft = await scriptorium.openDraft({ codexName, associatedWith: writ.id });
66
+ }
67
+ catch (err) {
68
+ const reason = `Draft open failed: ${String(err)}`;
69
+ await clerk.transition(writ.id, 'failed', { resolution: reason });
70
+ return { writId: writ.id, outcome: 'failed', resolution: reason, dryRun: false };
71
+ }
72
+ }
73
+ // Session cwd: draft worktree path if codex, otherwise guild home
74
+ const cwd = draft?.path ?? guild().home;
75
+ // 4. Assemble prompt and summon anima
76
+ const prompt = assemblePrompt(writ);
77
+ const handle = animator.summon({
78
+ role,
79
+ prompt,
80
+ cwd,
81
+ metadata: { writId: writ.id, trigger: 'dispatch' },
82
+ });
83
+ // 5. Await session result
84
+ let session;
85
+ try {
86
+ session = await handle.result;
87
+ }
88
+ catch (err) {
89
+ // Unexpected rejection (summon normally resolves with a failed status)
90
+ const reason = `Session error: ${String(err)}`;
91
+ if (codexName && draft) {
92
+ await scriptorium.abandonDraft({ codexName, branch: draft.branch, force: true });
93
+ }
94
+ await clerk.transition(writ.id, 'failed', { resolution: reason });
95
+ return { writId: writ.id, outcome: 'failed', resolution: reason, dryRun: false };
96
+ }
97
+ // 6a. Success path
98
+ if (session.status === 'completed') {
99
+ if (codexName && draft) {
100
+ // Seal the draft — fail writ if seal fails but preserve draft for recovery
101
+ try {
102
+ await scriptorium.seal({ codexName, sourceBranch: draft.branch });
103
+ }
104
+ catch (err) {
105
+ const reason = `Seal failed: ${String(err)}`;
106
+ await clerk.transition(writ.id, 'failed', { resolution: reason });
107
+ return { writId: writ.id, sessionId: session.id, outcome: 'failed', resolution: reason, dryRun: false };
108
+ }
109
+ // Push — same treatment as seal failure
110
+ try {
111
+ await scriptorium.push({ codexName });
112
+ }
113
+ catch (err) {
114
+ const reason = `Push failed: ${String(err)}`;
115
+ await clerk.transition(writ.id, 'failed', { resolution: reason });
116
+ return { writId: writ.id, sessionId: session.id, outcome: 'failed', resolution: reason, dryRun: false };
117
+ }
118
+ }
119
+ const resolution = `Session ${session.id} completed`;
120
+ await clerk.transition(writ.id, 'completed', { resolution });
121
+ return { writId: writ.id, sessionId: session.id, outcome: 'completed', resolution, dryRun: false };
122
+ }
123
+ // 6b. Failure path (status: 'failed' | 'timeout')
124
+ if (codexName && draft) {
125
+ await scriptorium.abandonDraft({ codexName, branch: draft.branch, force: true });
126
+ }
127
+ const reason = session.error ?? `Session ${session.status}`;
128
+ await clerk.transition(writ.id, 'failed', { resolution: reason });
129
+ return { writId: writ.id, sessionId: session.id, outcome: 'failed', resolution: reason, dryRun: false };
130
+ },
131
+ };
132
+ return {
133
+ apparatus: {
134
+ requires: ['clerk', 'codexes', 'animator'],
135
+ recommends: ['loom'],
136
+ supportKit: {
137
+ tools: [dispatchNext],
138
+ },
139
+ provides: api,
140
+ start() {
141
+ // No initialization needed — clerk is resolved at call time in next().
142
+ },
143
+ },
144
+ };
145
+ }
146
+ //# sourceMappingURL=dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @shardworks/dispatch-apparatus — The Dispatch.
3
+ *
4
+ * Interim work runner: finds the oldest ready writ and executes it through
5
+ * the guild's session machinery. Opens a draft binding on the target codex,
6
+ * summons an anima via The Animator, and handles the aftermath (seal the
7
+ * draft, transition the writ). Disposable — retired when the full rigging
8
+ * system (Walker, Formulary, Executor) is implemented.
9
+ *
10
+ * See: docs/architecture/apparatus/dispatch.md
11
+ */
12
+ export { type DispatchApi, type DispatchRequest, type DispatchResult, } from './types.ts';
13
+ export { createDispatch } from './dispatch.ts';
14
+ declare const _default: import("@shardworks/nexus-core").Plugin;
15
+ export default _default;
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;;AAI/C,wBAAgC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @shardworks/dispatch-apparatus — The Dispatch.
3
+ *
4
+ * Interim work runner: finds the oldest ready writ and executes it through
5
+ * the guild's session machinery. Opens a draft binding on the target codex,
6
+ * summons an anima via The Animator, and handles the aftermath (seal the
7
+ * draft, transition the writ). Disposable — retired when the full rigging
8
+ * system (Walker, Formulary, Executor) is implemented.
9
+ *
10
+ * See: docs/architecture/apparatus/dispatch.md
11
+ */
12
+ import { createDispatch } from "./dispatch.js";
13
+ // ── Dispatch API ──────────────────────────────────────────────────────
14
+ export {} from "./types.js";
15
+ export { createDispatch } from "./dispatch.js";
16
+ // ── Default export: the apparatus plugin ──────────────────────────────
17
+ export default createDispatch();
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,yEAAyE;AAEzE,OAAO,EAIN,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,yEAAyE;AAEzE,eAAe,cAAc,EAAE,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * dispatch-next tool — find the oldest ready writ and dispatch it.
3
+ *
4
+ * The primary entry point for running guild work. Picks the oldest ready
5
+ * writ (FIFO order), opens a draft on its codex (if any), summons an anima
6
+ * to fulfill it, and transitions the writ to completed or failed based on
7
+ * the session outcome.
8
+ *
9
+ * Usage:
10
+ * nsg dispatch-next
11
+ * nsg dispatch-next --role scribe
12
+ * nsg dispatch-next --dry-run
13
+ *
14
+ * See: docs/architecture/apparatus/dispatch.md
15
+ */
16
+ import { z } from 'zod';
17
+ declare const _default: import("@shardworks/tools-apparatus").ToolDefinition<{
18
+ role: z.ZodOptional<z.ZodString>;
19
+ dryRun: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
20
+ }>;
21
+ export default _default;
22
+ //# sourceMappingURL=dispatch-next.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch-next.d.ts","sourceRoot":"","sources":["../../src/tools/dispatch-next.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;;;;;AAGxB,wBA6BG"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * dispatch-next tool — find the oldest ready writ and dispatch it.
3
+ *
4
+ * The primary entry point for running guild work. Picks the oldest ready
5
+ * writ (FIFO order), opens a draft on its codex (if any), summons an anima
6
+ * to fulfill it, and transitions the writ to completed or failed based on
7
+ * the session outcome.
8
+ *
9
+ * Usage:
10
+ * nsg dispatch-next
11
+ * nsg dispatch-next --role scribe
12
+ * nsg dispatch-next --dry-run
13
+ *
14
+ * See: docs/architecture/apparatus/dispatch.md
15
+ */
16
+ import { tool } from '@shardworks/tools-apparatus';
17
+ import { guild } from '@shardworks/nexus-core';
18
+ import { z } from 'zod';
19
+ export default tool({
20
+ name: 'dispatch-next',
21
+ description: 'Find the oldest ready writ and dispatch it',
22
+ instructions: 'Finds the oldest ready writ (FIFO order), opens a draft binding on its codex ' +
23
+ 'if specified, summons an anima to fulfill the commission, and transitions the ' +
24
+ 'writ to completed or failed based on the session outcome. Returns null if no ' +
25
+ 'ready writs exist. Use dryRun to preview which writ would be dispatched.',
26
+ params: {
27
+ role: z.string().optional()
28
+ .describe('Role to summon (default: "artificer")'),
29
+ dryRun: z.boolean().optional().default(false)
30
+ .describe('If true, find and report the writ but do not dispatch'),
31
+ },
32
+ callableBy: 'cli',
33
+ permission: 'dispatch:write',
34
+ handler: async (params) => {
35
+ const dispatch = guild().apparatus('dispatch');
36
+ const result = await dispatch.next({
37
+ role: params.role,
38
+ dryRun: params.dryRun,
39
+ });
40
+ if (!result) {
41
+ return { status: 'idle', message: 'No ready writs found.' };
42
+ }
43
+ return result;
44
+ },
45
+ });
46
+ //# sourceMappingURL=dispatch-next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch-next.js","sourceRoot":"","sources":["../../src/tools/dispatch-next.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;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,eAAe;IACrB,WAAW,EAAE,4CAA4C;IACzD,YAAY,EACV,+EAA+E;QAC/E,gFAAgF;QAChF,+EAA+E;QAC/E,0EAA0E;IAC5E,MAAM,EAAE;QACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;aACxB,QAAQ,CAAC,uCAAuC,CAAC;QACpD,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;aAC1C,QAAQ,CAAC,uDAAuD,CAAC;KACrE;IACD,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,gBAAgB;IAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACxB,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC,SAAS,CAAc,UAAU,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC;YACjC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;QAC9D,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Dispatch tool re-exports.
3
+ */
4
+ export { default as dispatchNext } from './dispatch-next.ts';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Dispatch tool re-exports.
3
+ */
4
+ export { default as dispatchNext } from "./dispatch-next.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The Dispatch — public types.
3
+ *
4
+ * These types form the contract between The Dispatch apparatus and all
5
+ * callers (CLI, clockworks). No implementation details.
6
+ *
7
+ * See: docs/architecture/apparatus/dispatch.md
8
+ */
9
+ export interface DispatchApi {
10
+ /**
11
+ * Find the oldest ready writ and execute it.
12
+ *
13
+ * The full dispatch lifecycle:
14
+ * 1. Query the Clerk for the oldest ready writ
15
+ * 2. Transition the writ to active
16
+ * 3. Open a draft binding on the writ's codex (if specified)
17
+ * 4. Summon an anima session with the writ context as prompt
18
+ * 5. Wait for session completion
19
+ * 6. On success: seal the draft, push, transition writ to completed
20
+ * 7. On failure: abandon the draft, transition writ to failed
21
+ *
22
+ * Returns null if no ready writs exist.
23
+ *
24
+ * If the writ has no codex, steps 3/6/7 (draft lifecycle) are
25
+ * skipped — the session runs in the guild home directory with
26
+ * no codex binding.
27
+ */
28
+ next(request?: DispatchRequest): Promise<DispatchResult | null>;
29
+ }
30
+ export interface DispatchRequest {
31
+ /** Role to summon. Default: 'artificer'. */
32
+ role?: string;
33
+ /** If true, find and report the writ but don't dispatch. */
34
+ dryRun?: boolean;
35
+ }
36
+ export interface DispatchResult {
37
+ /** The writ that was dispatched. */
38
+ writId: string;
39
+ /** The session id (from the Animator). Absent if dryRun. */
40
+ sessionId?: string;
41
+ /** Terminal writ status after dispatch. Absent if dryRun. */
42
+ outcome?: 'completed' | 'failed';
43
+ /** Resolution text set on the writ. Absent if dryRun. */
44
+ resolution?: string;
45
+ /** Whether this was a dry run. */
46
+ dryRun: boolean;
47
+ }
48
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACjE;AAID,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;IACjC,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,MAAM,EAAE,OAAO,CAAC;CACjB"}
package/dist/types.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The Dispatch — public types.
3
+ *
4
+ * These types form the contract between The Dispatch apparatus and all
5
+ * callers (CLI, clockworks). No implementation details.
6
+ *
7
+ * See: docs/architecture/apparatus/dispatch.md
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@shardworks/dispatch-apparatus",
3
+ "version": "0.1.101",
4
+ "license": "ISC",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/shardworks/nexus",
8
+ "directory": "packages/plugins/dispatch"
9
+ },
10
+ "description": "The Dispatch — interim work runner: find the oldest ready writ and execute it",
11
+ "type": "module",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "dependencies": {
19
+ "zod": "4.3.6",
20
+ "@shardworks/clerk-apparatus": "0.1.101",
21
+ "@shardworks/animator-apparatus": "0.1.101",
22
+ "@shardworks/loom-apparatus": "0.1.101",
23
+ "@shardworks/codexes-apparatus": "0.1.101",
24
+ "@shardworks/nexus-core": "0.1.101",
25
+ "@shardworks/tools-apparatus": "0.1.101"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "25.5.0",
29
+ "@shardworks/stacks-apparatus": "0.1.101"
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsc",
36
+ "test": "node --disable-warning=ExperimentalWarning --experimental-transform-types --test 'src/**/*.test.ts'",
37
+ "typecheck": "tsc --noEmit"
38
+ }
39
+ }