@llblab/pi-actors 0.31.0 → 0.33.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.
package/AGENTS.md CHANGED
@@ -20,7 +20,7 @@ Pi host
20
20
  -> index.ts composition root
21
21
  -> lib/tools.ts / prompts.ts public tool + injected prompt surface
22
22
  -> lib/runtime.ts / registry.ts active user recipe tools
23
- -> lib/recipe-*.ts packaged/user/candidate recipe discovery
23
+ -> lib/recipe-*.ts packaged/user/draft recipe discovery
24
24
  -> lib/async-runs.ts spawn lifecycle and run state
25
25
  -> lib/actor-rooms.ts room, roster, mailbox, communication log
26
26
  -> scripts/*.mjs thin process entrypoints
@@ -45,8 +45,8 @@ Pi host
45
45
 
46
46
  ## Repo Surfaces
47
47
 
48
- - `/scripts/*.mjs`: Stable executable shims for detached/helper processes.
49
- - `/lib/*.ts`: Compiled domain and script-entrypoint logic. Keep `scripts/*.mjs` lightweight and move substantive behavior into named domain modules so `dist/lib` is the JS-only runtime surface. This intentionally grows a standard library: script-born behavior should gain a clear domain name when reuse is plausible. Exception: self-contained application/build scripts with no expected second consumer, such as `music-player.mjs` or `build-dist.mjs`, may remain standalone `.mjs` files.
48
+ - `/scripts/*.mjs`: Stable executables for detached/helper processes. Keep script-only release/build/glue behavior standalone when it has no plausible second consumer.
49
+ - `/lib/*.ts`: Compiled domains and shared script-entrypoint logic. Move substantive script behavior into named domain modules only when reuse, tests, packaged JS-only execution, or clear ownership justifies it. Do not create a lib domain solely to keep a tiny script shim thin.
50
50
  - `/recipes/*.json`: Packaged standard recipe library. Keep recipes optional, composable, policy-light, and caller-configurable.
51
51
  - `/skills/actors/SKILL.md`: Dense practical reference for operating pi-actors itself.
52
52
  - `/skills/swarm/SKILL.md`: Bundled methodology skill for multi-agent standards, strategies, and portable examples.
@@ -61,6 +61,8 @@ Pi host
61
61
  - Prefer explicit operator action over silent user-config rewrites.
62
62
  - Keep published documentation portable: use `~`, `<repo>`, or relative paths instead of machine-local absolute paths.
63
63
  - Preserve runtime output discipline because tool output flows directly into agent context.
64
+ - Optimize every actor-facing surface for signal over volume: prefer compact state-backed hints and fewer concepts over broad explanatory prose or speculative guidance.
65
+ - Until a stable release greater than `1.x.x`, favor context compression over compatibility shims: do not preserve legacy actor-facing names, aliases, fields, env vars, paths, or docs solely for backward compatibility when a clearer current term exists. Remove compatibility layers in the same slice that renames a concept, and record the break in `CHANGELOG.md`.
64
66
  - Keep the project lens local-first and cybernetic: agents wrap durable local capabilities as actors, then use semantic tools and messages instead of repeatedly reconstructing shell commands.
65
67
  - Design recipes as agent-callable tools: make prompts, scopes, paths, models, and policy knobs public args/defaults when the caller should decide them at invocation time.
66
68
  - Decompose oversized bullets into sublists or hierarchy; long flat list items are a context-smell.
@@ -80,6 +82,7 @@ Pi host
80
82
  ## Public Actor Model
81
83
 
82
84
  - Preserve the public verbs: `spawn`, `message`, `inspect`.
85
+ - Keep the model-facing concept ladder minimal: core is run actors, typed messages, intentional inspection, artifacts, and recipe/tool memory; group messaging, roster, branches, sessions, and diagnostics are advanced surfaces.
83
86
  - Prefer one typed actor-message envelope for upward, downward, lateral, parent/branch, and branch/parent messages.
84
87
  - Prefer actor addresses and inspect views over exposing FIFO, outbox, or status mechanics as public concepts.
85
88
  - Keep route and semantic type separate: delivery behavior comes from `to`, while `type` describes intent.
@@ -116,6 +119,7 @@ Pi host
116
119
  ## State, IO, And Safety
117
120
 
118
121
  - Tool stdout and temp state must stay bounded and local.
122
+ - Feedback hints must be evidence-backed, bounded, and action-shaped; prefer `next_actions` pointing to existing verbs over prose, and avoid hints when no concrete next step is justified.
119
123
  - Keep tail truncation, full-output temp files, failure formatting, and centralized limits intact.
120
124
  - Published docs must not include machine-local absolute paths.
121
125
  - Any view scanning run directories must apply coordinator/session ownership filters before exposing summaries or previews.
package/BACKLOG.md CHANGED
@@ -47,25 +47,12 @@ No open hotfix items.
47
47
  - File length alone is not a domain-split trigger: ~1000-line cohesive domain files are acceptable when ownership is clear.
48
48
  - Consider splitting only when a file crosses roughly 2000 lines, mixes real ownership zones, or hides a clearer domain boundary.
49
49
  - Prefer semantic compression before file splitting: fewer public nouns, consistent outcomes, compact diagnostics, and domain-owned constants/helpers.
50
+ - Preserve signal/noise balance: feedback should be state-backed, compact, and action-shaped; do not add advisory prose just because a surface exists.
50
51
 
51
52
  ## Minor Backlog
52
53
 
53
54
  The backlog is intentionally pruned to the 20% of work most likely to deliver 80% of value for `pi-actors` as a local actor kernel. Bias toward consolidation, smaller public surface area, and reliability over new feature breadth.
54
55
 
55
- ### M-14 Session Mismatch Follow-through
56
-
57
- - Priority: Medium.
58
- - Status: Planned.
59
- - Goal: Extend 0.27 structured session diagnostics consistently across room, branch, run, coordinator, and session workflows.
60
- - Why now: M-12 established the shape; dogfood should now make every ownership denial equally actionable without relaxing ownership gates.
61
- - Direction:
62
- - Audit all session mismatch errors for consistent `reason`, owner/current session fields, and inspect-session hints.
63
- - Keep read/write ownership policy unchanged.
64
- - Update docs with session mismatch examples and recovery inspection paths.
65
- - Acceptance:
66
- - Room, branch, run, coordinator, and session denials share the same compact/verbose shape.
67
- - Tests cover representative inspect and message paths.
68
-
69
56
  ### M-15 Worker Stale-Claim Dogfood
70
57
 
71
58
  - Priority: Medium.
@@ -80,20 +67,6 @@ The backlog is intentionally pruned to the 20% of work most likely to deliver 80
80
67
  - Stale claims are reproducible and visible in worker status.
81
68
  - Tests cover stale-claim counting without adding scheduler/broker policy.
82
69
 
83
- ### M-23 Tool Boundary Type Tightening
84
-
85
- - Priority: Low.
86
- - Status: Planned.
87
- - Goal: Remove avoidable `any` at the Pi/tool boundary where a narrow local type can express the real contract without broad rewiring.
88
- - Why now: `index.ts` still keeps runtime tool definitions in a `Map<string, any>`; this is small but visible in the composition root.
89
- - Direction:
90
- - Add or reuse a narrow exported tool-definition type from the Pi adapter or tools domain.
91
- - Keep SDK details behind `lib/pi.ts`.
92
- - Do not introduce a broad type-modeling pass across every schema helper.
93
- - Acceptance:
94
- - `index.ts` no longer uses `Map<string, any>` for actor tool definitions.
95
- - TypeScript validation still passes without weakening public tool schemas.
96
-
97
70
  ### M-17 Message Delivery Outcome Contract
98
71
 
99
72
  - Priority: High.
@@ -111,37 +84,23 @@ The backlog is intentionally pruned to the 20% of work most likely to deliver 80
111
84
  - Room messages distinguish timeline append success from forwarded branch-targeted copies.
112
85
  - Tests cover at least run, branch, room, coordinator, and ownership-denied outcomes.
113
86
 
114
- ### M-18 Candidate Recipe Promotion UX
87
+ ### M-18 Draft Recipe Promotion UX
115
88
 
116
89
  - Priority: High.
117
90
  - Status: Planned.
118
- - Goal: Make successful ad hoc actor patterns easy to promote manually from candidate memory into active user recipe memory.
119
- - Why now: Candidate recipes under `~/.pi/agent/recipes/candidates` are replayable but intentionally not active tools; the two-stage memory model now needs an explicit operator-gated promotion path.
91
+ - Goal: Make successful ad hoc actor patterns easy to promote manually from draft memory into active user recipe memory.
92
+ - Why now: Draft recipes under `~/.pi/agent/recipes/drafts` are replayable but intentionally not active tools, and the two-stage memory model needs an explicit operator-gated promotion path.
120
93
  - Direction:
121
- - List candidate recipes with source run, timestamp, fingerprint, description/template preview, and validation status.
122
- - Promote a selected candidate to `~/.pi/agent/recipes/<name>.json` only through an explicit action or explicit tool argument.
94
+ - List draft recipes with source run, timestamp, fingerprint, description/template preview, and validation status.
95
+ - Promote a selected draft to `~/.pi/agent/recipes/<name>.json` only through an explicit action or explicit tool argument.
123
96
  - Run recipe validation/doctor before writing and expose collision/shadowing diagnostics.
124
- - Preserve candidate files unless deletion is explicitly requested.
97
+ - Preserve draft files unless deletion is explicitly requested.
125
98
  - Prefer extending existing registry/tool surfaces over adding a new public noun.
126
99
  - Acceptance:
127
- - Candidate recipes remain non-tools until promotion.
100
+ - Draft recipes remain non-tools until promotion.
128
101
  - Promotion writes atomically and never auto-promotes.
129
- - Tests cover valid promotion, invalid candidate, name collision, and packaged-recipe shadowing.
130
- - Docs explain candidate memory vs active tool memory in one compact section.
131
-
132
- ### M-24 Registry Path Naming Cleanup
133
-
134
- - Priority: Low.
135
- - Status: Planned.
136
- - Goal: Reduce legacy-storage naming noise without changing the persistent file path.
137
- - Why now: `legacy-tool-registry.json` is still a compatibility storage path, but helper names and tests should make clear that the stable path is retained intentionally.
138
- - Direction:
139
- - Prefer neutral helper/test wording such as registry path or retained registry storage path.
140
- - Keep the on-disk filename unchanged unless a separate migration is justified.
141
- - Do not reintroduce legacy migration code.
142
- - Acceptance:
143
- - Path helpers and tests no longer imply an unfinished migration.
144
- - Existing registry storage compatibility remains unchanged.
102
+ - Tests cover valid promotion, invalid draft, name collision, and packaged-recipe shadowing.
103
+ - Docs explain draft memory vs active tool memory in one compact section.
145
104
 
146
105
  ### M-19 Recipe Doctor Risk Labels v2
147
106
 
@@ -166,10 +125,10 @@ The backlog is intentionally pruned to the 20% of work most likely to deliver 80
166
125
  - Priority: Medium.
167
126
  - Status: Planned.
168
127
  - Goal: Add one compact operator triage view that answers what needs attention right now without performing repairs.
169
- - Why now: Runtime status, recipe doctor, candidates, stale claims, session mismatches, failed runs, and other-session counts are currently separate bounded surfaces.
128
+ - Why now: Runtime status, recipe doctor, drafts, stale claims, session mismatches, failed runs, and other-session counts are currently separate bounded surfaces.
170
129
  - Direction:
171
130
  - Add `inspect target=tool:pi-actors view=triage` or an equivalent existing inspect surface.
172
- - Summarize runtime version/mode, active runs, other-session runs, invalid or blocking recipes, high-risk recipes, candidate recipes, stale worker claims, recent failed runs, attention messages, and suggested next inspect actions.
131
+ - Summarize runtime version/mode, active runs, other-session runs, invalid or blocking recipes, high-risk recipes, draft recipes, stale worker claims, recent failed runs, attention messages, and suggested next inspect actions.
173
132
  - Keep every warning tied to a next inspect/action hint.
174
133
  - Do not auto-repair, auto-prune, relax ownership, or hide detailed source-of-truth views.
175
134
  - Acceptance:
@@ -226,7 +185,7 @@ These are valid ideas but not current focus. Reintroduce only with concrete evid
226
185
  ## Suggested Milestone Order
227
186
 
228
187
  ```text
229
- Next milestone: M-14 Session Mismatch Follow-through.
230
- Then: M-15 Worker Stale-Claim Dogfood → M-17 Message Delivery Outcome Contract → M-18 Candidate Recipe Promotion UX.
188
+ Next milestone: M-15 Worker Stale-Claim Dogfood.
189
+ Then: M-17 Message Delivery Outcome Contract → M-18 Draft Recipe Promotion UX.
231
190
  Small cleanup lane: M-23 Tool Boundary Type Tightening → M-24 Registry Path Naming Cleanup.
232
191
  ```
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.33.0: Signal-First Compatibility Pruning
6
+
7
+ - `[Breaking]` Removed pre-1.x compatibility shims for draft recipe terminology: draft captures now live under `~/.pi/agent/recipes/drafts`, recipe inspection no longer emits `candidates`, spawn details no longer emit `candidate_recipe`, and shadow diagnostics use `blocked_fallback` instead of `blocked_candidate`.
8
+ - `[Context]` Documented the pre-stable policy that context compression wins over compatibility aliases until after a stable release greater than `1.x.x`; rename slices should remove legacy actor-facing names, fields, env vars, paths, and docs instead of carrying shims.
9
+ - `[Breaking]` Renamed retained registry storage from `legacy-tool-registry.json` to `tool-registry.json`, removing the stale compatibility noun from runtime path helpers and tests.
10
+ - `[Types]` Added a narrow actor tool-definition type and removed the remaining `Map<string, any>` from the composition root without expanding SDK type exposure.
11
+ - `[Scripts]` Collapsed the conformance runner back into a standalone script and removed its one-off lib domain, documenting that script-only glue should stay self-contained unless reuse or packaged runtime constraints justify a domain.
12
+
13
+ ## 0.32.0: Actor Surface Minimization
14
+
15
+ - `[Context]` Added durable signal/noise guidance for actor-facing surfaces: keep the model-facing concept ladder minimal, make feedback hints state-backed and action-shaped, and avoid speculative advisory prose.
16
+ - `[Backlog]` Added critical concept-surface compression and actor feedback-loop strengthening tracks to guide the next minimization-focused development cycle.
17
+ - `[Concepts]` Compressed model-facing language by presenting captured inline-spawn recipes as drafts, treating `room:<run>` as advanced group messaging plus roster, demoting coordinator/session/debug views from golden-path guidance, and keeping compatibility names/paths as storage details rather than core onboarding nouns.
18
+ - `[Feedback]` Added bounded next-action hints to recipe registry/doctor inspection, artifact inspection, delivery-fallback message results, and terminal run follow-ups so state-backed surfaces point back to `inspect`, `message`, `spawn`, or draft promotion without polling or auto-repair.
19
+ - `[Sessions]` Normalized session-directed message ownership failures onto the same structured `reason=session_mismatch`, owner/current session, and inspect-session hint shape used by run, branch, room, and coordinator ownership denials.
20
+
5
21
  ## 0.31.0: Agent Adoption Ergonomics
6
22
 
7
23
  - `[Adoption]` Added a compact actor-mode trigger rule to the injected prompt, actors skill, README, and async-run docs so models prefer `spawn → message → inspect` for long-lived, stateful, follow-up, artifact, service, fanout, and resumable work while keeping short foreground checks as ordinary tools.
package/README.md CHANGED
@@ -66,16 +66,21 @@ The npm package is dist-first for JavaScript-only runtimes: default Pi metadata
66
66
 
67
67
  ## Address Surface
68
68
 
69
- Actors and coordination endpoints are addressed with compact route strings:
69
+ Core actor addresses stay small:
70
70
 
71
71
  ```text
72
- run:<id> one detached actor run
73
- branch:<run>/<branch> branch-local actor endpoint
74
- room:<run> shared run-local task room
75
- coordinator launching coordinator attention path
72
+ run:<id> one detached actor run
73
+ tool:<name> executable registered tool actor
74
+ ```
75
+
76
+ Advanced coordination/debug addresses are available when a recipe or workflow needs them:
77
+
78
+ ```text
79
+ branch:<run>/<branch> branch-local worker endpoint
80
+ room:<run> group-message timeline plus roster for one run
81
+ coordinator compatibility alias for the current session coordination path
76
82
  session: current session actor surface
77
- session:all cross-session inventory surface
78
- tool:<name> executable registered tool
83
+ session:all cross-session inventory surface for diagnostics
79
84
  ```
80
85
 
81
86
  Actor messages use one envelope shape:
@@ -140,9 +145,9 @@ message to=run:docs_review type=control.continue body=continue
140
145
  message to=run:docs_review type=control.kill body=stop
141
146
  ```
142
147
 
143
- ## Actor Rooms
148
+ ## Group Messaging And Roster
144
149
 
145
- Every spawned run can have a shared room at `room:<run>`. A room is not a broker and not a chat app. It is a run-local coordination surface: append-only timeline, compact roster, member discovery, and previews.
150
+ Every spawned run can have advanced group messaging at `room:<run>`. Treat this as a run-local timeline plus roster for coordinated actors, not as a core chat/broker concept.
146
151
 
147
152
  Actors can join, post, leave, and discover peers:
148
153
 
@@ -155,7 +160,7 @@ message \
155
160
  body='{"role":"reviewer","caps":["security-review"],"claim":"Review auth boundary risks"}'
156
161
  ```
157
162
 
158
- Inspect the room intentionally:
163
+ Inspect group messages and roster intentionally:
159
164
 
160
165
  ```text
161
166
  inspect target=room:review view=status
@@ -165,7 +170,7 @@ inspect target=room:review view=contacts
165
170
  inspect target=room:review view=messages
166
171
  ```
167
172
 
168
- Room posts require a same-run sender, so unrelated runs do not pollute the roster. Direct messages and room messages use the same envelope; only the address changes. Direct `branch:<run>/<branch>` messages are private: they are forwarded through the parent run mailbox and recorded in the recipient branch inbox for worker protocols that consume queued branch work. For selected-recipient multicast, send to `room:<run>` with `metadata.recipients` set to same-run `branch:<run>/<branch>` addresses; this keeps one room transcript entry while forwarding branch-targeted copies.
173
+ Group posts require a same-run sender, so unrelated runs do not pollute the roster. Direct messages and group messages use the same envelope; only the address changes. Direct `branch:<run>/<branch>` messages are private: they are forwarded through the parent run mailbox and recorded in the recipient branch inbox for worker protocols that consume queued branch work. For selected-recipient multicast, send to `room:<run>` with `metadata.recipients` set to same-run `branch:<run>/<branch>` addresses; this keeps one visible transcript entry while forwarding branch-targeted copies.
169
174
 
170
175
  ## Actor Inspector
171
176
 
@@ -721,19 +721,30 @@ function formatRecipePersistenceSuggestion(transition) {
721
721
  }
722
722
  return `\nAgent note: this actor was spawned directly and completed successfully. If this pattern fits this machine's recurring workflow, ask the operator whether to save it as a durable recipe/tool under ~/.pi/agent/recipes with register_tool. Do not auto-save without confirmation.`;
723
723
  }
724
+ function formatTransitionNextActions(transition) {
725
+ const actions = [
726
+ `inspect target=run:${transition.run} view=status`,
727
+ transition.to === "done" && Object.keys(transition.artifacts ?? {}).length > 0
728
+ ? `inspect target=run:${transition.run} view=artifacts`
729
+ : `inspect target=run:${transition.run} view=tail`,
730
+ `inspect target=run:${transition.run} view=messages`,
731
+ ].filter(Boolean);
732
+ return `\nNext actions: ${actions.join(" | ")}`;
733
+ }
724
734
  export function formatRunTransitionMessage(transition) {
725
735
  const artifacts = formatNamedArtifacts(transition.artifacts);
726
736
  const runFiles = formatRunFileList(getRunArtifacts(transition));
727
737
  const persistenceSuggestion = formatRecipePersistenceSuggestion(transition);
738
+ const nextActions = formatTransitionNextActions(transition);
728
739
  if (transition.to === "done")
729
- return `Run ${transition.run} completed successfully.${artifacts}${runFiles}\nUse inspect target=run:${transition.run} view=status or view=tail if the result needs inspection.${persistenceSuggestion}`;
740
+ return `Run ${transition.run} completed successfully.${artifacts}${runFiles}${nextActions}${persistenceSuggestion}`;
730
741
  if (transition.to === "failed")
731
- return `Run ${transition.run} failed.${artifacts}${runFiles}\nUse inspect target=run:${transition.run} view=status or view=tail for details.`;
742
+ return `Run ${transition.run} failed.${artifacts}${runFiles}${nextActions}`;
732
743
  if (transition.to === "cancelled")
733
- return `Run ${transition.run} was cancelled. Use inspect target=run:${transition.run} view=status or view=tail if analysis is needed.`;
744
+ return `Run ${transition.run} was cancelled.${nextActions}`;
734
745
  if (transition.to === "killed")
735
- return `Run ${transition.run} was force-killed. Use inspect target=run:${transition.run} view=status or view=tail if analysis is needed.`;
746
+ return `Run ${transition.run} was force-killed.${nextActions}`;
736
747
  if (transition.to === "exited")
737
- return `Run ${transition.run} exited before writing a result. Use inspect target=run:${transition.run} view=status or view=tail if analysis is needed.`;
738
- return `Run ${transition.run} finished with status ${transition.to}. Use inspect target=run:${transition.run} view=status or view=tail if analysis is needed.`;
748
+ return `Run ${transition.run} exited before writing a result.${nextActions}`;
749
+ return `Run ${transition.run} finished with status ${transition.to}.${nextActions}`;
739
750
  }
@@ -17,5 +17,5 @@ export declare const EXTENSION_RUNTIME_PATHS: ExtensionRuntimePaths;
17
17
  export declare function getExtensionSkillsDir(extensionUrl: string): string;
18
18
  export declare function getExistingExtensionSkillPaths(extensionUrl: string): string[];
19
19
  export declare function getRecipeRoot(agentDir?: string): string;
20
- export declare function getRecipeCandidateRoot(agentDir?: string): string;
20
+ export declare function getRecipeDraftRoot(agentDir?: string): string;
21
21
  export declare function getPackagedRecipeRoot(): string;
package/dist/lib/paths.js CHANGED
@@ -13,7 +13,7 @@ export function getAgentDir(env = process.env) {
13
13
  : join(homedir(), ".pi", "agent");
14
14
  }
15
15
  export function getConfigPath(agentDir = getAgentDir()) {
16
- return join(agentDir, "legacy-tool-registry.json");
16
+ return join(agentDir, "tool-registry.json");
17
17
  }
18
18
  export function getExtensionTmpDir(agentDir = getAgentDir(), extensionName = "pi-actors") {
19
19
  return join(agentDir, "tmp", extensionName);
@@ -39,8 +39,8 @@ export function getExistingExtensionSkillPaths(extensionUrl) {
39
39
  export function getRecipeRoot(agentDir = getAgentDir()) {
40
40
  return join(agentDir, "recipes");
41
41
  }
42
- export function getRecipeCandidateRoot(agentDir = getAgentDir()) {
43
- return join(getRecipeRoot(agentDir), "candidates");
42
+ export function getRecipeDraftRoot(agentDir = getAgentDir()) {
43
+ return join(getRecipeRoot(agentDir), "drafts");
44
44
  }
45
45
  export function getPackagedRecipeRoot() {
46
46
  const here = dirname(fileURLToPath(import.meta.url));
@@ -47,6 +47,6 @@ export declare function discoverRecipeSources(sources: RecipeDiscoverySource[]):
47
47
  export declare function discoverRecipes(roots: string[]): RecipeDiscoveryResult;
48
48
  export declare function createRecipeIntegrityManifest(result: RecipeDiscoveryResult): RecipeIntegrityManifestEntry[];
49
49
  export declare function getShadowedLaunchDiagnostic(result: RecipeDiscoveryResult, id: string): Record<string, unknown> | undefined;
50
- export declare function listCandidateRecipes(root: string): Array<Record<string, unknown>>;
50
+ export declare function listDraftRecipes(root: string): Array<Record<string, unknown>>;
51
51
  export declare function summarizeDiscovery(result: RecipeDiscoveryResult): Record<string, unknown>;
52
52
  export declare function toRegisteredTool(entry: DiscoveredRecipe): RegisteredTool | undefined;
@@ -324,16 +324,16 @@ function diagnosticDetails(result) {
324
324
  }
325
325
  function remediationForEntry(entry, activePath) {
326
326
  const riskyDiagnostics = entry.diagnostics.filter((message) => diagnosticSeverity(message) === "warning");
327
- const blockedCandidate = entry.shadows[0];
327
+ const blockedFallback = entry.shadows[0];
328
328
  if (entry.invalid) {
329
329
  return {
330
330
  id: entry.id,
331
- kind: blockedCandidate ? "blocking_invalid" : "invalid",
331
+ kind: blockedFallback ? "blocking_invalid" : "invalid",
332
332
  severity: "error",
333
333
  path: entry.path,
334
- ...(blockedCandidate ? { blocked_candidate: blockedCandidate } : {}),
335
- reason: blockedCandidate
336
- ? "invalid higher-priority recipe blocks a lower-priority candidate"
334
+ ...(blockedFallback ? { blocked_fallback: blockedFallback } : {}),
335
+ reason: blockedFallback
336
+ ? "invalid higher-priority recipe blocks a lower-priority fallback"
337
337
  : "recipe is invalid and cannot be exposed as a tool",
338
338
  action: "fix recipe syntax/config, or disable/delete/archive it to restore fallback",
339
339
  };
@@ -341,12 +341,12 @@ function remediationForEntry(entry, activePath) {
341
341
  if (entry.disabled && entry.active) {
342
342
  return {
343
343
  id: entry.id,
344
- kind: blockedCandidate ? "blocking_disabled" : "disabled",
344
+ kind: blockedFallback ? "blocking_disabled" : "disabled",
345
345
  severity: "warning",
346
346
  path: entry.path,
347
- ...(blockedCandidate ? { blocked_candidate: blockedCandidate } : {}),
348
- reason: blockedCandidate
349
- ? "disabled higher-priority recipe intentionally blocks a lower-priority candidate"
347
+ ...(blockedFallback ? { blocked_fallback: blockedFallback } : {}),
348
+ reason: blockedFallback
349
+ ? "disabled higher-priority recipe intentionally blocks a lower-priority fallback"
350
350
  : "recipe is disabled and not exposed as a tool",
351
351
  action: "keep disabled intentionally, re-enable, or delete/archive the file",
352
352
  };
@@ -420,12 +420,12 @@ export function getShadowedLaunchDiagnostic(result, id) {
420
420
  return undefined;
421
421
  return {
422
422
  active_path: active.path,
423
- blocked_candidate: active.shadows[0],
423
+ blocked_fallback: active.shadows[0],
424
424
  hint: "inspect_recipes_doctor",
425
425
  reason: active.invalid ? "shadowed_invalid" : "shadowed_disabled",
426
426
  };
427
427
  }
428
- export function listCandidateRecipes(root) {
428
+ export function listDraftRecipes(root) {
429
429
  return listRecipeFiles(root).map((path) => {
430
430
  const id = RecipeReferences.getRecipeIdFromPath(path);
431
431
  const config = RecipeReferences.readRawRecipeConfig(path);
@@ -8,6 +8,11 @@ import * as Execution from "./execution.ts";
8
8
  import * as Registry from "./registry.ts";
9
9
  export type RegisterToolInput = Registry.RegisterToolInput;
10
10
  export type RegisterToolRuntimeDeps<TContext> = Registry.RegisterToolRuntimeDeps<TContext>;
11
+ export interface ActorToolDefinition {
12
+ name: string;
13
+ execute?: (...args: never[]) => unknown;
14
+ [key: string]: unknown;
15
+ }
11
16
  export interface CoreActorToolDefinitionDeps<TContext extends AsyncRunToolContext> {
12
17
  configPath: string;
13
18
  getActiveTools: () => string[];
@@ -43,6 +48,6 @@ export interface ActorMessageToolDeps<TContext = unknown> {
43
48
  getTool?: (name: string) => any | undefined;
44
49
  }
45
50
  export declare function createActorMessageToolDefinition<TContext = unknown>(deps?: ActorMessageToolDeps<TContext>): any;
46
- export declare function createCoreActorToolDefinitions<TContext extends AsyncRunToolContext>(deps: CoreActorToolDefinitionDeps<TContext>): any[];
51
+ export declare function createCoreActorToolDefinitions<TContext extends AsyncRunToolContext>(deps: CoreActorToolDefinitionDeps<TContext>): ActorToolDefinition[];
47
52
  export declare function createRuntimeToolDefinition(cfg: RegisteredTool, exec: Execution.RegisteredToolExec): any;
48
53
  export {};