@shardworks/spider-apparatus 0.1.130 → 0.1.132

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/README.md ADDED
@@ -0,0 +1,289 @@
1
+ # `@shardworks/spider-apparatus`
2
+
3
+ The Spider is the guild's rig execution engine. It spawns rigs for ready writs, drives engine pipelines to completion, and transitions writs via the Clerk when rigs finish. Each rig is an ordered pipeline of engine instances; the Spider's `crawl()` loop advances that pipeline one step at a time.
4
+
5
+ Depends on `@shardworks/stacks-apparatus` for rig persistence, `@shardworks/fabricator-apparatus` to look up engine designs, `@shardworks/clerk-apparatus` to transition writs, and `@shardworks/animator-apparatus` to launch quick-engine sessions.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```json
12
+ {
13
+ "dependencies": {
14
+ "@shardworks/spider-apparatus": "workspace:*"
15
+ }
16
+ }
17
+ ```
18
+
19
+ ## API
20
+
21
+ The Spider exposes its API via `guild().apparatus<SpiderApi>('spider')`:
22
+
23
+ ```typescript
24
+ import { guild } from '@shardworks/nexus-core';
25
+ import type { SpiderApi } from '@shardworks/spider-apparatus';
26
+
27
+ const spider = guild().apparatus<SpiderApi>('spider');
28
+ ```
29
+
30
+ ### `crawl(): Promise<CrawlResult | null>`
31
+
32
+ Execute one step of the crawl loop. The Spider evaluates pending work in priority order — collect > checkBlocked > run > spawn — and returns a description of the action taken, or `null` if no work was available.
33
+
34
+ ```typescript
35
+ const result = await spider.crawl();
36
+ if (result) {
37
+ console.log(result.action); // 'rig-spawned' | 'engine-started' | 'engine-completed' | ...
38
+ }
39
+ ```
40
+
41
+ CrawlResult variants:
42
+
43
+ | Action | Description |
44
+ |---|---|
45
+ | `'rig-spawned'` | Created a new rig for a ready writ |
46
+ | `'engine-started'` | Launched a quick engine's session |
47
+ | `'engine-completed'` | An engine finished; rig still running |
48
+ | `'engine-blocked'` | Engine entered blocked status |
49
+ | `'engine-unblocked'` | A blocked engine's condition cleared |
50
+ | `'engine-skipped'` | Engine (and any downstream-only dependents) was skipped due to `when` condition |
51
+ | `'engine-grafted'` | Engine injected additional engines into the pipeline |
52
+ | `'rig-completed'` | Rig reached terminal state (completed or failed) |
53
+ | `'rig-blocked'` | All forward progress stalled; rig entered blocked status |
54
+
55
+ ### `show(id): Promise<RigDoc>`
56
+
57
+ Show a rig by ID. Throws if not found.
58
+
59
+ ### `list(filters?): Promise<RigDoc[]>`
60
+
61
+ List rigs, ordered by `createdAt` descending.
62
+
63
+ ```typescript
64
+ const running = await spider.list({ status: 'running', limit: 10 });
65
+ ```
66
+
67
+ ### `forWrit(writId): Promise<RigDoc | null>`
68
+
69
+ Find the rig for a given writ. Returns `null` if no rig exists.
70
+
71
+ ### `resume(rigId, engineId): Promise<void>`
72
+
73
+ Manually clear a block on a specific engine, bypassing the block type's checker. Throws if the engine is not currently blocked.
74
+
75
+ ### `getBlockType(id): BlockType | undefined`
76
+
77
+ Look up a registered block type by ID.
78
+
79
+ ### `listBlockTypes(): BlockTypeInfo[]`
80
+
81
+ List all registered block types with summary info.
82
+
83
+ ### `listTemplates(): RigTemplateInfo[]`
84
+
85
+ List all registered rig templates with provenance info (config-defined or kit-contributed).
86
+
87
+ ### `listTemplateMappings(): Record<string, string>`
88
+
89
+ Return the merged effective writ-type → template-name mapping. Config mappings override kit mappings for the same writ type.
90
+
91
+ ## Configuration
92
+
93
+ The Spider reads its config from `guild.json["spider"]`:
94
+
95
+ ```json
96
+ {
97
+ "spider": {
98
+ "pollIntervalMs": 5000,
99
+ "variables": {
100
+ "plannerRole": "planner",
101
+ "buildCommand": "pnpm build"
102
+ },
103
+ "rigTemplates": {
104
+ "default": {
105
+ "engines": [
106
+ {
107
+ "id": "draft",
108
+ "designId": "anima-session",
109
+ "givens": {
110
+ "role": "${vars.plannerRole}",
111
+ "prompt": "Draft the implementation plan."
112
+ }
113
+ },
114
+ {
115
+ "id": "implement",
116
+ "designId": "anima-session",
117
+ "upstream": ["draft"],
118
+ "givens": {
119
+ "role": "artificer",
120
+ "conversationId": "${yields.draft.conversationId}",
121
+ "prompt": "Implement the plan from the draft."
122
+ }
123
+ }
124
+ ]
125
+ }
126
+ },
127
+ "rigTemplateMappings": {
128
+ "feature": "default"
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ | Field | Type | Default | Description |
135
+ |---|---|---|---|
136
+ | `pollIntervalMs` | `number` | `5000` | Polling interval for the `crawl-continual` tool (ms). |
137
+ | `buildCommand` | `string` | — | Build command forwarded to quick engines. |
138
+ | `testCommand` | `string` | — | Test command forwarded to quick engines. |
139
+ | `variables` | `Record<string, unknown>` | — | Named values available in rig template givens via `${vars.<path>}`. |
140
+ | `rigTemplates` | `Record<string, RigTemplate>` | — | Named rig template definitions. |
141
+ | `rigTemplateMappings` | `Record<string, string>` | — | Writ type → template name. `'default'` is the fallback. |
142
+
143
+ ## Rig Templates
144
+
145
+ A rig template defines the engine pipeline for a class of writs. Each engine in the pipeline is an `id`/`designId` pair with optional `upstream`, `givens`, and `when`.
146
+
147
+ ### Engine Givens
148
+
149
+ The `givens` object passes values to the engine at run time. String values may contain `${...}` template expressions that are resolved when the rig is spawned (for `writ` and `vars` references) or when the engine runs (for `yields` references):
150
+
151
+ | Expression | Resolved | Value |
152
+ |---|---|---|
153
+ | `${writ}` | Spawn time | Full `WritDoc` for this rig's writ |
154
+ | `${writ.<path>}` | Spawn time | A field of the `WritDoc` (dot-path) |
155
+ | `${vars.<path>}` | Spawn time | A value from `spider.variables` config (dot-path) |
156
+ | `${yields.<engineId>.<path>}` | Run time | A property from an upstream engine's yields (dot-path) |
157
+
158
+ **Type preservation:** When a string is exactly one `${...}` expression (e.g. `"${writ}"`), the resolved value keeps its original type. When expressions are embedded in larger text (e.g. `"Hello ${writ.title}"`), the result is always a string.
159
+
160
+ **Undefined handling:** A whole-value expression that resolves to `undefined` causes the givens key to be omitted. An inline expression that resolves to `undefined` is replaced with empty string.
161
+
162
+ **Escaping:** Use `\${` to produce a literal `${` in the output without interpolation.
163
+
164
+ ```json
165
+ {
166
+ "givens": {
167
+ "writ": "${writ}",
168
+ "title": "${writ.title}",
169
+ "role": "${vars.plannerRole}",
170
+ "prevConversation": "${yields.draft.conversationId}",
171
+ "greeting": "Hello ${writ.author}, your writ is ready.",
172
+ "literal": "Use \\${vars.key} syntax in your template."
173
+ }
174
+ }
175
+ ```
176
+
177
+ ### Conditional Activation (`when`)
178
+
179
+ The `when` field controls whether an engine runs or is skipped. It takes a `${yields.<engineId>.<property>}` expression (with optional `!` negation prefix), evaluated after the engine's upstream completes:
180
+
181
+ ```json
182
+ {
183
+ "id": "fix",
184
+ "designId": "anima-session",
185
+ "upstream": ["review"],
186
+ "when": "!${yields.review.passed}",
187
+ "givens": { "prompt": "Fix the review failures." }
188
+ }
189
+ ```
190
+
191
+ When the condition is falsy, the engine (and any engines that have no other upstream) is set to `skipped` status and the pipeline continues.
192
+
193
+ ### Upstream and Ordering
194
+
195
+ `upstream` lists engine IDs within this template that must complete before this engine can run. The Spider validates that upstream references are acyclic and that `${yields.*}` givens only reference upstream engines.
196
+
197
+ ## Rig Template Kit Interface
198
+
199
+ Apparatus plugins can contribute rig templates and block types via their kit:
200
+
201
+ ```typescript
202
+ import type { SpiderKit } from '@shardworks/spider-apparatus';
203
+
204
+ const myPlugin = {
205
+ apparatus: {
206
+ provides: { /* ... */ },
207
+ kit: {
208
+ spider: {
209
+ rigTemplates: {
210
+ 'my-template': {
211
+ engines: [
212
+ { id: 'work', designId: 'anima-session', givens: { role: 'artificer' } }
213
+ ]
214
+ }
215
+ },
216
+ rigTemplateMappings: {
217
+ 'my-writ-type': 'my-template'
218
+ },
219
+ blockTypes: [
220
+ {
221
+ id: 'my-block',
222
+ conditionSchema: z.object({ /* ... */ }),
223
+ check: async (condition) => ({ status: 'cleared' }),
224
+ }
225
+ ]
226
+ }
227
+ }
228
+ }
229
+ };
230
+ ```
231
+
232
+ Config-defined templates and mappings override kit-contributed ones with the same name.
233
+
234
+ ## Support Kit
235
+
236
+ The Spider contributes books and tools for rig inspection and control.
237
+
238
+ ### Books
239
+
240
+ | Book | Indexes | Description |
241
+ |---|---|---|
242
+ | `spider/rigs` | `writId`, `status`, `createdAt` | Rig documents — one per spawned writ. |
243
+
244
+ ### Tools
245
+
246
+ | Tool | Permission | Description |
247
+ |---|---|---|
248
+ | `rig-list` | `read` | List rigs with optional status/limit filters |
249
+ | `rig-show` | `read` | Show full detail for a rig by id |
250
+ | `rig-resume` | `write` | Manually clear a block on a specific engine |
251
+ | `crawl` | `write` | Execute a single crawl step |
252
+ | `crawl-continual` | `write` | Poll `crawl()` in a loop until no work remains |
253
+
254
+ ## Types
255
+
256
+ ```typescript
257
+ import type {
258
+ SpiderApi,
259
+ SpiderConfig,
260
+ RigDoc,
261
+ RigTemplate,
262
+ RigTemplateEngine,
263
+ RigTemplateInfo,
264
+ RigFilters,
265
+ RigStatus,
266
+ EngineInstance,
267
+ EngineStatus,
268
+ CrawlResult,
269
+ BlockType,
270
+ BlockRecord,
271
+ BlockTypeInfo,
272
+ CheckResult,
273
+ DraftYields,
274
+ SealYields,
275
+ SpiderEngineRunResult,
276
+ SpiderCollectResult,
277
+ InputRequestDoc,
278
+ InputRequestStatus,
279
+ QuestionSpec,
280
+ AnswerValue,
281
+ } from '@shardworks/spider-apparatus';
282
+ ```
283
+
284
+ The default export is a pre-created apparatus plugin instance:
285
+
286
+ ```typescript
287
+ import spider from '@shardworks/spider-apparatus';
288
+ // spider is { apparatus: { requires: ['stacks', 'fabricator', 'clerk'], provides: SpiderApi, ... } }
289
+ ```
@@ -1 +1 @@
1
- {"version":3,"file":"spider.d.ts","sourceRoot":"","sources":["../src/spider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAwD,MAAM,wBAAwB,CAAC;AAO3G,OAAO,KAAK,EAWV,WAAW,EAIZ,MAAM,YAAY,CAAC;AAwCpB,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,oFAAoF;IACpF,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C;AAijCD,wBAAgB,YAAY,IAAI,MAAM,CA8xBrC"}
1
+ {"version":3,"file":"spider.d.ts","sourceRoot":"","sources":["../src/spider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAwD,MAAM,wBAAwB,CAAC;AAO3G,OAAO,KAAK,EAWV,WAAW,EAIZ,MAAM,YAAY,CAAC;AA+CpB,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,oFAAoF;IACpF,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C;AAojCD,wBAAgB,YAAY,IAAI,MAAM,CA8xBrC"}