rig-constellation 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +201 -0
  2. package/LICENSE-CODEGRAPH.txt +27 -0
  3. package/NOTICE +15 -0
  4. package/README.md +121 -0
  5. package/dist/chunk-8sqjbsgt.js +42 -0
  6. package/dist/chunk-9754b9t6.js +70 -0
  7. package/dist/chunk-arpj39jd.js +10 -0
  8. package/dist/chunk-bnz0drs2.js +10 -0
  9. package/dist/chunk-hk4h7yej.js +71 -0
  10. package/dist/rig.js +11708 -0
  11. package/generated/.manifest +57 -0
  12. package/generated/core/anchors-registry.ts +70 -0
  13. package/generated/core/migrations.ts +79 -0
  14. package/generated/core/schema.sql +241 -0
  15. package/generated/installer/claude.instructions.md +345 -0
  16. package/generated/installer/claude.permissions.json +44 -0
  17. package/generated/installer/codex.instructions.md +345 -0
  18. package/generated/installer/codex.permissions.json +44 -0
  19. package/generated/installer/cursor.instructions.md +345 -0
  20. package/generated/installer/cursor.permissions.json +44 -0
  21. package/generated/installer/opencode.instructions.md +345 -0
  22. package/generated/installer/opencode.permissions.json +44 -0
  23. package/generated/installer/openrouter.instructions.md +345 -0
  24. package/generated/installer/openrouter.permissions.json +44 -0
  25. package/generated/mcp/handlers/rig_add_alias.handler.ts +34 -0
  26. package/generated/mcp/handlers/rig_add_node.handler.ts +34 -0
  27. package/generated/mcp/handlers/rig_aliases.handler.ts +25 -0
  28. package/generated/mcp/handlers/rig_annotate.handler.ts +34 -0
  29. package/generated/mcp/handlers/rig_callees.handler.ts +25 -0
  30. package/generated/mcp/handlers/rig_callers.handler.ts +25 -0
  31. package/generated/mcp/handlers/rig_chain.handler.ts +25 -0
  32. package/generated/mcp/handlers/rig_cluster.handler.ts +34 -0
  33. package/generated/mcp/handlers/rig_cold.handler.ts +25 -0
  34. package/generated/mcp/handlers/rig_context.handler.ts +29 -0
  35. package/generated/mcp/handlers/rig_critical_path.handler.ts +25 -0
  36. package/generated/mcp/handlers/rig_dep_conflicts.handler.ts +25 -0
  37. package/generated/mcp/handlers/rig_deps.handler.ts +25 -0
  38. package/generated/mcp/handlers/rig_drill.handler.ts +25 -0
  39. package/generated/mcp/handlers/rig_drop_waypoint.handler.ts +34 -0
  40. package/generated/mcp/handlers/rig_explore.handler.ts +29 -0
  41. package/generated/mcp/handlers/rig_files.handler.ts +25 -0
  42. package/generated/mcp/handlers/rig_focus.handler.ts +29 -0
  43. package/generated/mcp/handlers/rig_hotspots.handler.ts +25 -0
  44. package/generated/mcp/handlers/rig_hub_of.handler.ts +25 -0
  45. package/generated/mcp/handlers/rig_hubs.handler.ts +25 -0
  46. package/generated/mcp/handlers/rig_impact.handler.ts +25 -0
  47. package/generated/mcp/handlers/rig_neighbors.handler.ts +25 -0
  48. package/generated/mcp/handlers/rig_node.handler.ts +25 -0
  49. package/generated/mcp/handlers/rig_phantom_imports.handler.ts +25 -0
  50. package/generated/mcp/handlers/rig_promote.handler.ts +34 -0
  51. package/generated/mcp/handlers/rig_propose_edge.handler.ts +34 -0
  52. package/generated/mcp/handlers/rig_pull.handler.ts +25 -0
  53. package/generated/mcp/handlers/rig_relevant_skills.handler.ts +25 -0
  54. package/generated/mcp/handlers/rig_search.handler.ts +25 -0
  55. package/generated/mcp/handlers/rig_session_token.handler.ts +25 -0
  56. package/generated/mcp/handlers/rig_status.handler.ts +25 -0
  57. package/generated/mcp/handlers/rig_subscribe.handler.ts +25 -0
  58. package/generated/mcp/handlers/rig_undo.handler.ts +29 -0
  59. package/generated/mcp/handlers/rig_unused_deps.handler.ts +25 -0
  60. package/generated/mcp/handlers/rig_waypoints.handler.ts +25 -0
  61. package/generated/mcp/handlers-index.ts +40 -0
  62. package/generated/mcp/tools-manifest.json +2958 -0
  63. package/generated/web/ws-events.ts +237 -0
  64. package/package.json +77 -0
  65. package/packages/web/dist/assets/index-VRO-sxc2.js +54 -0
  66. package/packages/web/dist/index.html +35 -0
@@ -0,0 +1,345 @@
1
+ <!-- GENERATED FILE — DO NOT EDIT.
2
+ Source: .contracts/targets/openrouter.contract.ts
3
+ Edit the .contract.ts file(s), then run `bun run gen`. -->
4
+
5
+ # Rig — OpenRouter instructions
6
+
7
+ Rig exposes these MCP tools. Always prefer them over file reads for graph questions.
8
+
9
+ ## light tools
10
+
11
+ ### `rig_aliases`
12
+
13
+ Return every alias name pointing at a given canonical anchor. Aliases are
14
+ alternate names (e.g. `pd` for `pandas`, `useState` for `React.useState`)
15
+ that resolve to the same node via FTS5 search. Each carries the actor that
16
+ registered it.
17
+
18
+ ### `rig_callees`
19
+
20
+ Return the set of anchors directly called by the given function/method.
21
+ One-hop, structural edges only. Output is NodeRef[].
22
+
23
+ Use to answer "what does this depend on" or "what does this function
24
+ touch". For transitive reach use rig_impact; for general relatedness
25
+ use rig_pull.
26
+
27
+ ### `rig_callers`
28
+
29
+ Return the set of anchors that directly call the given function/method.
30
+ One-hop, structural edges only. Output is NodeRef[].
31
+
32
+ Use to answer "who uses this" or "what will break if I change this".
33
+ For transitive impact use rig_impact; for general relatedness use
34
+ rig_pull.
35
+
36
+ ### `rig_chain`
37
+
38
+ Starting at a given waypoint, walk the waypoint_succeeds edges backward
39
+ through history up to maxDepth hops. Returns the seed at index 0 followed
40
+ by its predecessors in order. Use to reconstruct the reasoning thread
41
+ that led to a decision.
42
+
43
+ ### `rig_cold`
44
+
45
+ Return the anchors that have not been activated within the stale-after
46
+ window. last_ts is null when the node has never been touched. Useful for
47
+ pruning candidates and identifying dead-weight in the graph.
48
+
49
+ Default stale-after is 90 days, limit 20.
50
+
51
+ ### `rig_critical_path`
52
+
53
+ Greedy walk outward from the root anchor, picking the highest-scoring outbound
54
+ edge at each step. Score = w_hubness × destination.hubness + w_activation ×
55
+ normalized_activation_count + w_kind × edge_kind_weight (contains > references
56
+ > calls > imports). Returns an ordered chain — the "main thread" through the
57
+ subsystem rooted at this anchor.
58
+
59
+ Use as a one-shot architecture tour: "what's the spine of this code path"
60
+ or "which chain of anchors carries the most traffic from X". For one-hop
61
+ neighbors use rig_neighbors; for ranked similarity use rig_pull.
62
+
63
+ ### `rig_dep_conflicts`
64
+
65
+ Return every dependency name (scoped per ecosystem source) that appears in
66
+ two or more manifests with different version specs. Same-name-different-source
67
+ (e.g. an npm package and a PyPI package that happen to share a name) is not a
68
+ conflict — only intra-ecosystem disagreement is flagged.
69
+
70
+ Use to spot drift before it bites: pandas at 2.1.4 in requirements.txt and
71
+ 2.2.0 in pyproject.toml is the classic case.
72
+
73
+ ### `rig_deps`
74
+
75
+ List the dependencies a project declares in its package manifests (currently
76
+ package.json; more formats coming). Each entry has {name, spec, source,
77
+ manifest_path, is_dev, is_optional, is_peer}.
78
+
79
+ Use for "what does this project depend on" and "what version of X does it
80
+ declare" questions. For symbol-level lookup of how a package is imported
81
+ in code, use rig_search with the package name.
82
+
83
+ ### `rig_drill`
84
+
85
+ Walk outward from a hub via structural edges (contains > references > calls >
86
+ imports), rank descendants by magnetic pull from the hub. Optional name query
87
+ filters the returned set. Use after rig_hubs to drill into one part of the
88
+ graph instead of dumping the whole neighborhood.
89
+
90
+ ### `rig_files`
91
+
92
+ List files known to the rig index, optionally filtered by a substring of
93
+ the file path. Each entry has {path, language?, node_count,
94
+ last_indexed_ts?}.
95
+
96
+ Use for "what does rig know about" sanity checks and to discover entry
97
+ points before searching. For symbol lookup inside a file use rig_search
98
+ with a kind filter.
99
+
100
+ ### `rig_hotspots`
101
+
102
+ Return the anchors that have been activated (queried, expanded, AI-touched)
103
+ most often within a sliding window. Count-based ranking — for decay-weighted
104
+ relevance use rig_pull.
105
+
106
+ Use to discover the parts of the graph you have been working in lately,
107
+ or to seed a cache-warming pass. Default window is 7 days, limit 20.
108
+
109
+ ### `rig_hub_of`
110
+
111
+ Walk outward from an anchor via structural edges, return the first hub layer
112
+ reached (up to maxDepth hops). Use to answer "what part of the system does
113
+ this belong to" without traversing the full graph.
114
+
115
+ ### `rig_hubs`
116
+
117
+ Return the most "hub-like" anchors in the graph, ranked by hubness. Hubs are
118
+ high-fanout structural concentrations (top 5% per anchor type) plus any node
119
+ explicitly promoted via rig_promote.
120
+
121
+ Use as the entry point when navigating a large graph — pick a hub, then call
122
+ rig_drill to explore its sub-tree.
123
+
124
+ ### `rig_impact`
125
+
126
+ Return all anchors reachable as transitive callers of the given anchor
127
+ up to the requested depth. Useful for change-impact analysis: "if I
128
+ change this function, what tests/callers might break".
129
+
130
+ Defaults to depth 3. Depth is capped at 6 to keep the result bounded.
131
+ For one-hop callers use rig_callers.
132
+
133
+ ### `rig_neighbors`
134
+
135
+ Return edges incident to the given anchor in both directions, from both
136
+ the structural and semantic edge tables. Output is a flat EdgeRef list
137
+ with {src, dst, kind, weight?, table}.
138
+
139
+ Use when you want the raw graph view ("what does this connect to") rather
140
+ than a ranked similarity view. For "what's most related" use rig_pull —
141
+ it scores by structural distance + semantic similarity + recency.
142
+
143
+ ### `rig_node`
144
+
145
+ Return metadata for a single anchor: id, name, kind, file_path, qualified
146
+ name, signature, docstring, and neighbor counts by edge kind. Does NOT
147
+ return the source body — use rig_explore (heavy tier) for full source.
148
+
149
+ Use as a cheap inspection step after rig_search to decide whether a node
150
+ is worth pulling neighbors or callers for.
151
+
152
+ ### `rig_phantom_imports`
153
+
154
+ Mirror of rig_unused_deps: returns import sites whose target package name
155
+ has no matching declared dependency in any manifest. Common causes are a
156
+ missing entry in package.json / requirements.txt, a typo, or reliance on a
157
+ transitive dep that should be declared directly.
158
+
159
+ Subpath imports normalize to the parent package (`lodash/get` → `lodash`);
160
+ relative + absolute paths are not counted as phantoms.
161
+
162
+ ### `rig_pull`
163
+
164
+ Rank the top-k anchors most "magnetically attracted" to the given node.
165
+ Score combines graph distance (structural), embedding cosine similarity
166
+ (semantic), recent activation decay (recency), and a hub-bias boost so
167
+ high-fanout anchors surface first by default. Returns PullResult[] with
168
+ {nodeId, score, components: {structural, semantic, recency, hub}}.
169
+
170
+ Use this for "what's related to X" or "what else should I look at" —
171
+ it is strictly better than rig_neighbors when you want a ranked list.
172
+ Use rig_neighbors only when you need the raw edge view. To disable the
173
+ hub bias (raw neighborhood ranking), pass hub_bias=0.
174
+
175
+ ### `rig_relevant_skills`
176
+
177
+ Rank the agent's own MCP tools (seeded as 'skill' anchors at startup) by
178
+ relevance to a free-text intent. Useful when the agent itself wants to
179
+ discover which of its tools to call — "I need to validate this externally"
180
+ ranks browser/web tools high; "what is connected to X" ranks
181
+ rig_pull/rig_neighbors high.
182
+
183
+ Same retrieval substrate as rig_search; this just narrows to skill anchors
184
+ and returns the tier+description so the agent has enough to pick.
185
+
186
+ ### `rig_search`
187
+
188
+ Find anchors by name or qualified name via SQLite FTS5. Returns
189
+ {id, name, kind, file_path?} matches ranked by FTS relevance.
190
+
191
+ Use this for "where is X defined" or "find a symbol named Y" questions.
192
+ For "what's related to this node" use rig_pull instead — search does not
193
+ score by graph proximity or semantic similarity.
194
+
195
+ ### `rig_session_token`
196
+
197
+ Read the per-server bearer token from .rig/.runtime and return both the raw
198
+ token and a clickable URL the user can paste into their browser to log into
199
+ the map. Used when "open the rig map" comes up in chat — the agent fetches the
200
+ token (because it has filesystem access to .rig/), the user clicks the URL,
201
+ and the cookie gets set.
202
+
203
+ Returns 'no_runtime_token' in errors when the server isn't running with auth
204
+ enabled (loopback dev mode skips the token by default).
205
+
206
+ ### `rig_status`
207
+
208
+ Returns counts of nodes, edges, files, and the last sync timestamp.
209
+ Use as a smoke test before any other rig_* call to confirm the index is initialized.
210
+
211
+ ### `rig_unused_deps`
212
+
213
+ Heuristic: a declared dependency is flagged when its package name never
214
+ appears as the target of a bare-specifier import anywhere in the indexed
215
+ source. Handles scoped packages (`@types/node`) and subpath imports
216
+ (`lodash/get` counts as a use of `lodash`).
217
+
218
+ Possible false positives: JSX runtimes, bundler-only deps, runtime configs.
219
+ Treat the result as "likely removable, verify before deleting", not as an
220
+ authoritative dead-code report.
221
+
222
+ ### `rig_waypoints`
223
+
224
+ List waypoints in newest-first order. Optional filters: session_id (pass
225
+ "last" to auto-resolve to the most-recently-active session — useful at
226
+ session start to rehydrate the previous thread), kind (decision /
227
+ observation / constraint / open-question / principle).
228
+
229
+ Call this on session start, before the first user turn, with
230
+ session_id="last" limit=20 to pick up where the previous session ended.
231
+
232
+ ## heavy tools
233
+
234
+ ### `rig_context`
235
+
236
+ Build a context bundle of the top-K anchors most relevant to a task,
237
+ formatted for direct LLM consumption (markdown by default; JSON
238
+ available). Uses search + magnetic-pull ranking.
239
+
240
+ Heavy tier — must be invoked from a sub-agent, not the main session.
241
+ Use rig_explore for raw exploration; use rig_context when you want a
242
+ single ready-to-prompt block.
243
+
244
+ ### `rig_explore`
245
+
246
+ Search the index for a question and return the top-K anchors with their
247
+ source bodies and one-hop related anchors. Returns full file slices, so
248
+ this is token-heavy.
249
+
250
+ NEVER call this in the main agent session — spawn a sub-agent. The
251
+ two-tier gate is enforced by the dispatcher (MAIN_SESSION_FORBIDDEN).
252
+ For lightweight metadata-only navigation use rig_pull or rig_neighbors.
253
+
254
+ ## write tools
255
+
256
+ ### `rig_add_alias`
257
+
258
+ Add an alternate name for an anchor so searches for the alias return the
259
+ canonical node. Use for AI-discovered or user-asserted alternate names
260
+ (e.g. `pd` → `pandas`, `useState` → `React.useState`).
261
+
262
+ The alias is registered with the caller's provenance. Re-adding the same
263
+ (node, alias) pair is a no-op; the second call returns added=false.
264
+
265
+ ### `rig_add_node`
266
+
267
+ Create a new anchor immediately (nodes are cheaper to add than edges).
268
+ Use only when the user has explicitly named a new concept in
269
+ conversation; do not invent anchors from inference alone.
270
+
271
+ ### `rig_annotate`
272
+
273
+ Append a free-text note to a node's data.annotations array. Useful for
274
+ the AI to leave a breadcrumb on a node ("this is the auth boundary",
275
+ "renamed from FooBar in commit abc1234").
276
+
277
+ ### `rig_cluster`
278
+
279
+ Create a new node of type 'cluster' with 'contains' edges to each member.
280
+ The cluster becomes its own searchable anchor. Use when you spot a
281
+ group of related anchors that deserves a name.
282
+
283
+ ### `rig_drop_waypoint`
284
+
285
+ Record a discrete marker the AI considers worth preserving across context
286
+ compaction or session boundaries — a decision, a constraint stated by the
287
+ user, a recurring observation, an open question, or a principle. The
288
+ waypoint becomes a graph anchor with structured payload; predecessor ids
289
+ form a `waypoint_succeeds` chain; constellation refs form
290
+ `waypoint_references` edges to other anchors.
291
+
292
+ Use sparingly. Typical floor: at most one per ~5 turns. Drop one when a
293
+ real decision is locked, not as a running summary.
294
+
295
+ ### `rig_focus`
296
+
297
+ Emit a focus:requested event over WebSocket so the map UI pans and
298
+ zooms to the given anchors. No graph mutation; logged in mutation_log
299
+ for audit.
300
+
301
+ ### `rig_promote`
302
+
303
+ Promote any node to hub status regardless of its fanout score. Used when the
304
+ user or AI has identified a concept-level anchor that the structural heuristic
305
+ missed (a "principle" waypoint, a domain entity, a documentation root).
306
+
307
+ Hubs surface in rig_hubs results and bias rig_pull rankings.
308
+
309
+ ### `rig_propose_edge`
310
+
311
+ Write a pending semantic edge that the user must accept before it becomes
312
+ canonical. Rationale is shown in the accept popover and stored in the
313
+ mutation_log forever.
314
+
315
+ Prefer rig_propose_edge to creating edges directly — the user accepts
316
+ the connection before it solidifies.
317
+
318
+ ### `rig_undo`
319
+
320
+ Walk back the most recent mutation in the current MCP session — propose
321
+ becomes deleted, accept becomes pending again, reject becomes pending,
322
+ add_node deletes the node. Undos are themselves logged; the chain is
323
+ auditable.
324
+
325
+ ## live tools
326
+
327
+ ### `rig_subscribe`
328
+
329
+ Long-poll endpoint for following the user's UI activity from an agent
330
+ session. Pass the last next_cursor value you saw; receive every
331
+ mutation_log row since then (selections, edges proposed/accepted/
332
+ rejected, nodes added). Polling every 2s is a good default.
333
+
334
+ Use this to inject "user is now looking at <anchor>" context into your
335
+ next agent turn without the user typing.
336
+
337
+ ## Two-tier gate
338
+
339
+ NEVER call `rig_explore` or `rig_context` directly in the main session — spawn a sub-agent for these.
340
+
341
+ ## Session bootstrap
342
+
343
+ At the start of a new conversation, before responding to the user, call `rig_waypoints` with `session_id="last"` and `limit=20`. The returned waypoints are the prior session's structured decision/observation markers — read them to reorient on what was decided, what constraints are in play, and what open questions remain. Do not re-derive context the prior session already settled.
344
+
345
+ Drop a waypoint via `rig_drop_waypoint` when: a real decision is locked, the user states a hard constraint, an observation recurs across turns, or an open question emerges that should outlive context compaction. Aim for at most one waypoint per ~5 turns — they are not a running summary.
@@ -0,0 +1,44 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "mcp__rig__rig_add_alias",
5
+ "mcp__rig__rig_add_node",
6
+ "mcp__rig__rig_aliases",
7
+ "mcp__rig__rig_annotate",
8
+ "mcp__rig__rig_callees",
9
+ "mcp__rig__rig_callers",
10
+ "mcp__rig__rig_chain",
11
+ "mcp__rig__rig_cluster",
12
+ "mcp__rig__rig_cold",
13
+ "mcp__rig__rig_critical_path",
14
+ "mcp__rig__rig_dep_conflicts",
15
+ "mcp__rig__rig_deps",
16
+ "mcp__rig__rig_drill",
17
+ "mcp__rig__rig_drop_waypoint",
18
+ "mcp__rig__rig_files",
19
+ "mcp__rig__rig_focus",
20
+ "mcp__rig__rig_hotspots",
21
+ "mcp__rig__rig_hub_of",
22
+ "mcp__rig__rig_hubs",
23
+ "mcp__rig__rig_impact",
24
+ "mcp__rig__rig_neighbors",
25
+ "mcp__rig__rig_node",
26
+ "mcp__rig__rig_phantom_imports",
27
+ "mcp__rig__rig_promote",
28
+ "mcp__rig__rig_propose_edge",
29
+ "mcp__rig__rig_pull",
30
+ "mcp__rig__rig_relevant_skills",
31
+ "mcp__rig__rig_search",
32
+ "mcp__rig__rig_session_token",
33
+ "mcp__rig__rig_status",
34
+ "mcp__rig__rig_subscribe",
35
+ "mcp__rig__rig_undo",
36
+ "mcp__rig__rig_unused_deps",
37
+ "mcp__rig__rig_waypoints"
38
+ ],
39
+ "ask": [
40
+ "mcp__rig__rig_context",
41
+ "mcp__rig__rig_explore"
42
+ ]
43
+ }
44
+ }
@@ -0,0 +1,34 @@
1
+ // GENERATED FILE — DO NOT EDIT.
2
+ // Source: .contracts/tools/rig_add_alias.contract.ts
3
+ // Edit the .contract.ts file(s), then run `bun run gen`.
4
+
5
+ import type { ToolHandler } from '@rig/mcp/dispatch.ts';
6
+ import { ToolError } from '@rig/mcp/dispatch.ts';
7
+ import contract from '../../../.contracts/tools/rig_add_alias.contract.ts';
8
+ import { run as impl } from '@rig/mcp/tool-impls/rig_add_alias.ts';
9
+
10
+ export const rigAddAliasHandler: ToolHandler = {
11
+ name: 'rig_add_alias',
12
+ tier: 'write',
13
+ provenanceRequired: true,
14
+ requiresRationale: true,
15
+ run: async (args, ctx) => {
16
+ if (!ctx.provenance) {
17
+ throw new ToolError('PROVENANCE_REQUIRED', 'rig_add_alias requires provenance');
18
+ }
19
+ const parsedIn = contract.input.safeParse(args);
20
+ if (!parsedIn.success) {
21
+ throw new ToolError('INPUT_INVALID', parsedIn.error.message);
22
+ }
23
+ const rationale = (parsedIn.data as { rationale?: unknown }).rationale;
24
+ if (typeof rationale !== 'string' || rationale.trim().length === 0) {
25
+ throw new ToolError('RATIONALE_REQUIRED', 'rig_add_alias requires a non-empty rationale');
26
+ }
27
+ const out = await impl(parsedIn.data, ctx);
28
+ const parsedOut = contract.output.safeParse(out);
29
+ if (!parsedOut.success) {
30
+ throw new ToolError('OUTPUT_INVALID', parsedOut.error.message);
31
+ }
32
+ return parsedOut.data;
33
+ },
34
+ };
@@ -0,0 +1,34 @@
1
+ // GENERATED FILE — DO NOT EDIT.
2
+ // Source: .contracts/tools/rig_add_node.contract.ts
3
+ // Edit the .contract.ts file(s), then run `bun run gen`.
4
+
5
+ import type { ToolHandler } from '@rig/mcp/dispatch.ts';
6
+ import { ToolError } from '@rig/mcp/dispatch.ts';
7
+ import contract from '../../../.contracts/tools/rig_add_node.contract.ts';
8
+ import { run as impl } from '@rig/mcp/tool-impls/rig_add_node.ts';
9
+
10
+ export const rigAddNodeHandler: ToolHandler = {
11
+ name: 'rig_add_node',
12
+ tier: 'write',
13
+ provenanceRequired: true,
14
+ requiresRationale: true,
15
+ run: async (args, ctx) => {
16
+ if (!ctx.provenance) {
17
+ throw new ToolError('PROVENANCE_REQUIRED', 'rig_add_node requires provenance');
18
+ }
19
+ const parsedIn = contract.input.safeParse(args);
20
+ if (!parsedIn.success) {
21
+ throw new ToolError('INPUT_INVALID', parsedIn.error.message);
22
+ }
23
+ const rationale = (parsedIn.data as { rationale?: unknown }).rationale;
24
+ if (typeof rationale !== 'string' || rationale.trim().length === 0) {
25
+ throw new ToolError('RATIONALE_REQUIRED', 'rig_add_node requires a non-empty rationale');
26
+ }
27
+ const out = await impl(parsedIn.data, ctx);
28
+ const parsedOut = contract.output.safeParse(out);
29
+ if (!parsedOut.success) {
30
+ throw new ToolError('OUTPUT_INVALID', parsedOut.error.message);
31
+ }
32
+ return parsedOut.data;
33
+ },
34
+ };
@@ -0,0 +1,25 @@
1
+ // GENERATED FILE — DO NOT EDIT.
2
+ // Source: .contracts/tools/rig_aliases.contract.ts
3
+ // Edit the .contract.ts file(s), then run `bun run gen`.
4
+
5
+ import type { ToolHandler } from '@rig/mcp/dispatch.ts';
6
+ import { ToolError } from '@rig/mcp/dispatch.ts';
7
+ import contract from '../../../.contracts/tools/rig_aliases.contract.ts';
8
+ import { run as impl } from '@rig/mcp/tool-impls/rig_aliases.ts';
9
+
10
+ export const rigAliasesHandler: ToolHandler = {
11
+ name: 'rig_aliases',
12
+ tier: 'light',
13
+ run: async (args, ctx) => {
14
+ const parsedIn = contract.input.safeParse(args);
15
+ if (!parsedIn.success) {
16
+ throw new ToolError('INPUT_INVALID', parsedIn.error.message);
17
+ }
18
+ const out = await impl(parsedIn.data, ctx);
19
+ const parsedOut = contract.output.safeParse(out);
20
+ if (!parsedOut.success) {
21
+ throw new ToolError('OUTPUT_INVALID', parsedOut.error.message);
22
+ }
23
+ return parsedOut.data;
24
+ },
25
+ };
@@ -0,0 +1,34 @@
1
+ // GENERATED FILE — DO NOT EDIT.
2
+ // Source: .contracts/tools/rig_annotate.contract.ts
3
+ // Edit the .contract.ts file(s), then run `bun run gen`.
4
+
5
+ import type { ToolHandler } from '@rig/mcp/dispatch.ts';
6
+ import { ToolError } from '@rig/mcp/dispatch.ts';
7
+ import contract from '../../../.contracts/tools/rig_annotate.contract.ts';
8
+ import { run as impl } from '@rig/mcp/tool-impls/rig_annotate.ts';
9
+
10
+ export const rigAnnotateHandler: ToolHandler = {
11
+ name: 'rig_annotate',
12
+ tier: 'write',
13
+ provenanceRequired: true,
14
+ requiresRationale: true,
15
+ run: async (args, ctx) => {
16
+ if (!ctx.provenance) {
17
+ throw new ToolError('PROVENANCE_REQUIRED', 'rig_annotate requires provenance');
18
+ }
19
+ const parsedIn = contract.input.safeParse(args);
20
+ if (!parsedIn.success) {
21
+ throw new ToolError('INPUT_INVALID', parsedIn.error.message);
22
+ }
23
+ const rationale = (parsedIn.data as { rationale?: unknown }).rationale;
24
+ if (typeof rationale !== 'string' || rationale.trim().length === 0) {
25
+ throw new ToolError('RATIONALE_REQUIRED', 'rig_annotate requires a non-empty rationale');
26
+ }
27
+ const out = await impl(parsedIn.data, ctx);
28
+ const parsedOut = contract.output.safeParse(out);
29
+ if (!parsedOut.success) {
30
+ throw new ToolError('OUTPUT_INVALID', parsedOut.error.message);
31
+ }
32
+ return parsedOut.data;
33
+ },
34
+ };
@@ -0,0 +1,25 @@
1
+ // GENERATED FILE — DO NOT EDIT.
2
+ // Source: .contracts/tools/rig_callees.contract.ts
3
+ // Edit the .contract.ts file(s), then run `bun run gen`.
4
+
5
+ import type { ToolHandler } from '@rig/mcp/dispatch.ts';
6
+ import { ToolError } from '@rig/mcp/dispatch.ts';
7
+ import contract from '../../../.contracts/tools/rig_callees.contract.ts';
8
+ import { run as impl } from '@rig/mcp/tool-impls/rig_callees.ts';
9
+
10
+ export const rigCalleesHandler: ToolHandler = {
11
+ name: 'rig_callees',
12
+ tier: 'light',
13
+ run: async (args, ctx) => {
14
+ const parsedIn = contract.input.safeParse(args);
15
+ if (!parsedIn.success) {
16
+ throw new ToolError('INPUT_INVALID', parsedIn.error.message);
17
+ }
18
+ const out = await impl(parsedIn.data, ctx);
19
+ const parsedOut = contract.output.safeParse(out);
20
+ if (!parsedOut.success) {
21
+ throw new ToolError('OUTPUT_INVALID', parsedOut.error.message);
22
+ }
23
+ return parsedOut.data;
24
+ },
25
+ };
@@ -0,0 +1,25 @@
1
+ // GENERATED FILE — DO NOT EDIT.
2
+ // Source: .contracts/tools/rig_callers.contract.ts
3
+ // Edit the .contract.ts file(s), then run `bun run gen`.
4
+
5
+ import type { ToolHandler } from '@rig/mcp/dispatch.ts';
6
+ import { ToolError } from '@rig/mcp/dispatch.ts';
7
+ import contract from '../../../.contracts/tools/rig_callers.contract.ts';
8
+ import { run as impl } from '@rig/mcp/tool-impls/rig_callers.ts';
9
+
10
+ export const rigCallersHandler: ToolHandler = {
11
+ name: 'rig_callers',
12
+ tier: 'light',
13
+ run: async (args, ctx) => {
14
+ const parsedIn = contract.input.safeParse(args);
15
+ if (!parsedIn.success) {
16
+ throw new ToolError('INPUT_INVALID', parsedIn.error.message);
17
+ }
18
+ const out = await impl(parsedIn.data, ctx);
19
+ const parsedOut = contract.output.safeParse(out);
20
+ if (!parsedOut.success) {
21
+ throw new ToolError('OUTPUT_INVALID', parsedOut.error.message);
22
+ }
23
+ return parsedOut.data;
24
+ },
25
+ };
@@ -0,0 +1,25 @@
1
+ // GENERATED FILE — DO NOT EDIT.
2
+ // Source: .contracts/tools/rig_chain.contract.ts
3
+ // Edit the .contract.ts file(s), then run `bun run gen`.
4
+
5
+ import type { ToolHandler } from '@rig/mcp/dispatch.ts';
6
+ import { ToolError } from '@rig/mcp/dispatch.ts';
7
+ import contract from '../../../.contracts/tools/rig_chain.contract.ts';
8
+ import { run as impl } from '@rig/mcp/tool-impls/rig_chain.ts';
9
+
10
+ export const rigChainHandler: ToolHandler = {
11
+ name: 'rig_chain',
12
+ tier: 'light',
13
+ run: async (args, ctx) => {
14
+ const parsedIn = contract.input.safeParse(args);
15
+ if (!parsedIn.success) {
16
+ throw new ToolError('INPUT_INVALID', parsedIn.error.message);
17
+ }
18
+ const out = await impl(parsedIn.data, ctx);
19
+ const parsedOut = contract.output.safeParse(out);
20
+ if (!parsedOut.success) {
21
+ throw new ToolError('OUTPUT_INVALID', parsedOut.error.message);
22
+ }
23
+ return parsedOut.data;
24
+ },
25
+ };
@@ -0,0 +1,34 @@
1
+ // GENERATED FILE — DO NOT EDIT.
2
+ // Source: .contracts/tools/rig_cluster.contract.ts
3
+ // Edit the .contract.ts file(s), then run `bun run gen`.
4
+
5
+ import type { ToolHandler } from '@rig/mcp/dispatch.ts';
6
+ import { ToolError } from '@rig/mcp/dispatch.ts';
7
+ import contract from '../../../.contracts/tools/rig_cluster.contract.ts';
8
+ import { run as impl } from '@rig/mcp/tool-impls/rig_cluster.ts';
9
+
10
+ export const rigClusterHandler: ToolHandler = {
11
+ name: 'rig_cluster',
12
+ tier: 'write',
13
+ provenanceRequired: true,
14
+ requiresRationale: true,
15
+ run: async (args, ctx) => {
16
+ if (!ctx.provenance) {
17
+ throw new ToolError('PROVENANCE_REQUIRED', 'rig_cluster requires provenance');
18
+ }
19
+ const parsedIn = contract.input.safeParse(args);
20
+ if (!parsedIn.success) {
21
+ throw new ToolError('INPUT_INVALID', parsedIn.error.message);
22
+ }
23
+ const rationale = (parsedIn.data as { rationale?: unknown }).rationale;
24
+ if (typeof rationale !== 'string' || rationale.trim().length === 0) {
25
+ throw new ToolError('RATIONALE_REQUIRED', 'rig_cluster requires a non-empty rationale');
26
+ }
27
+ const out = await impl(parsedIn.data, ctx);
28
+ const parsedOut = contract.output.safeParse(out);
29
+ if (!parsedOut.success) {
30
+ throw new ToolError('OUTPUT_INVALID', parsedOut.error.message);
31
+ }
32
+ return parsedOut.data;
33
+ },
34
+ };
@@ -0,0 +1,25 @@
1
+ // GENERATED FILE — DO NOT EDIT.
2
+ // Source: .contracts/tools/rig_cold.contract.ts
3
+ // Edit the .contract.ts file(s), then run `bun run gen`.
4
+
5
+ import type { ToolHandler } from '@rig/mcp/dispatch.ts';
6
+ import { ToolError } from '@rig/mcp/dispatch.ts';
7
+ import contract from '../../../.contracts/tools/rig_cold.contract.ts';
8
+ import { run as impl } from '@rig/mcp/tool-impls/rig_cold.ts';
9
+
10
+ export const rigColdHandler: ToolHandler = {
11
+ name: 'rig_cold',
12
+ tier: 'light',
13
+ run: async (args, ctx) => {
14
+ const parsedIn = contract.input.safeParse(args);
15
+ if (!parsedIn.success) {
16
+ throw new ToolError('INPUT_INVALID', parsedIn.error.message);
17
+ }
18
+ const out = await impl(parsedIn.data, ctx);
19
+ const parsedOut = contract.output.safeParse(out);
20
+ if (!parsedOut.success) {
21
+ throw new ToolError('OUTPUT_INVALID', parsedOut.error.message);
22
+ }
23
+ return parsedOut.data;
24
+ },
25
+ };