@llblab/pi-actors 0.29.1 → 0.29.2

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
@@ -45,7 +45,7 @@ Treat this extension as an experimental self-evolution membrane for the agent ha
45
45
 
46
46
  ## Operating Principles
47
47
 
48
- - Prefer explicit migration boundaries over silent user-config rewrites.
48
+ - Prefer explicit operator action over silent user-config rewrites.
49
49
  - Keep published documentation portable: use `~`, `<repo>`, or relative paths instead of machine-local absolute paths.
50
50
  - Preserve runtime output discipline because tool output flows directly into agent context.
51
51
  - 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.
@@ -82,7 +82,7 @@ Treat this extension as an experimental self-evolution membrane for the agent ha
82
82
  ## Recipes And Registry
83
83
 
84
84
  - `~/.pi/agent/recipes/*.json` is executable muscle memory: recipes there become persistent tools by location.
85
- - Preserve filename identity, atomic writes, explicit operator-gated migration paths, and local transportability.
85
+ - Preserve filename identity, atomic writes, explicit operator-gated changes, and local transportability.
86
86
  - Packaged/ad hoc recipes outside the agent root are components, not user tools.
87
87
  - Tool definitions use `template`, not `script`, and built-in/core tool names must not be shadowed.
88
88
  - Packaged recipe growth is demand-driven: prefer reusable components over speculative scenario catalogs.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.29.2: Legacy Migration Removal Hotfix
6
+
7
+ - `[Registry]` Removed the old legacy tool-registry migration path now that recipe-file storage is the only maintained persistence surface.
8
+
5
9
  ## 0.29.1: Subagent TTL Kill Hotfix
6
10
 
7
11
  - `[Coordinator]` Added `subagent_ttl_ms` / `--subagent-ttl-ms` to the room-swarm adapter so timed-out subagent `pi -p` processes are terminated instead of only awaited.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Persistent tool registry config helpers
3
- * Zones: registry config, persistence, migration boundary
3
+ * Zones: registry config, persistence, normalization
4
4
  * Owns registered-tool config loading, normalization, unsupported-shape rejection, and serialization
5
5
  */
6
6
  import type { CommandTemplateValue } from "./command-templates.ts";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Persistent tool registry config helpers
3
- * Zones: registry config, persistence, migration boundary
3
+ * Zones: registry config, persistence, normalization
4
4
  * Owns registered-tool config loading, normalization, unsupported-shape rejection, and serialization
5
5
  */
6
6
  import { existsSync, readFileSync } from "node:fs";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * File-discovered recipe registry helpers
3
- * Zones: recipe discovery, tool exposure, migration diagnostics
3
+ * Zones: recipe discovery, tool exposure, registry diagnostics
4
4
  * Owns filename identity discovery across prioritized recipe roots
5
5
  */
6
6
  import type { RegisteredTool } from "./config.ts";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * File-discovered recipe registry helpers
3
- * Zones: recipe discovery, tool exposure, migration diagnostics
3
+ * Zones: recipe discovery, tool exposure, registry diagnostics
4
4
  * Owns filename identity discovery across prioritized recipe roots
5
5
  */
6
6
  import { createHash } from "node:crypto";
@@ -38,8 +38,7 @@ function listRecipeFiles(root) {
38
38
  return [];
39
39
  return readdirSync(root, { withFileTypes: true })
40
40
  .filter((entry) => entry.isFile() &&
41
- (entry.name.endsWith(".json") || entry.name.endsWith(".md")) &&
42
- entry.name !== "legacy-tool-registry-migration-report.json")
41
+ (entry.name.endsWith(".json") || entry.name.endsWith(".md")))
43
42
  .map((entry) => join(root, entry.name))
44
43
  .sort((a, b) => a
45
44
  .replace(/\.md$/, ".json")
@@ -5,7 +5,6 @@
5
5
  */
6
6
  import * as Paths from "./paths.js";
7
7
  import * as RecipeDiscovery from "./recipe-discovery.js";
8
- import * as RecipeMigration from "./recipe-migration.js";
9
8
  import * as Tools from "./tools.js";
10
9
  export function createAutoToolsRuntime(deps) {
11
10
  const tools = new Map();
@@ -86,16 +85,6 @@ export function createAutoToolsRuntime(deps) {
86
85
  const warnings = [];
87
86
  const recipeRoot = deps.recipeRoot ?? Paths.getRecipeRoot();
88
87
  const packagedRecipeRoot = deps.packagedRecipeRoot ?? Paths.getPackagedRecipeRoot();
89
- const migration = RecipeMigration.migrateLegacyToolRegistry({
90
- configPath: deps.configPath,
91
- recipeRoot,
92
- reservedToolNames: deps.reservedToolNames,
93
- });
94
- warnings.push(...migration.warnings);
95
- if (migration.conflicts.length > 0)
96
- warnings.push(`Recipe migration conflicts: ${migration.conflicts.join(", ")}`);
97
- if (migration.invalid.length > 0)
98
- warnings.push(`Recipe migration invalid entries: ${migration.invalid.join(", ")}`);
99
88
  const discovered = RecipeDiscovery.discoverRecipeSources([
100
89
  { root: recipeRoot, defaultTool: true, mutableUsage: true },
101
90
  { root: packagedRecipeRoot },
@@ -2,7 +2,7 @@
2
2
  name: actors
3
3
  description: Highest-density practical guide for pi-actors. Read this skill whenever prompt and tools are not enough for spawn, message, inspect, actor runs, tools, recipes, command templates, async lifecycle, mailboxes, artifacts, and local orchestration mechanics.
4
4
  metadata:
5
- version: 0.29.1
5
+ version: 0.29.2
6
6
  ---
7
7
 
8
8
  # Actors (pi-actors)
@@ -2,7 +2,7 @@
2
2
  name: swarm
3
3
  description: Subagent orchestration with scoped locks and quorum consensus. Use for multi-model review, parallel scoped work, delegated audit, and coordinated subagent execution.
4
4
  metadata:
5
- version: 0.29.1
5
+ version: 0.29.2
6
6
  ---
7
7
 
8
8
  # Swarm
package/lib/config.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Persistent tool registry config helpers
3
- * Zones: registry config, persistence, migration boundary
3
+ * Zones: registry config, persistence, normalization
4
4
  * Owns registered-tool config loading, normalization, unsupported-shape rejection, and serialization
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * File-discovered recipe registry helpers
3
- * Zones: recipe discovery, tool exposure, migration diagnostics
3
+ * Zones: recipe discovery, tool exposure, registry diagnostics
4
4
  * Owns filename identity discovery across prioritized recipe roots
5
5
  */
6
6
 
@@ -98,8 +98,7 @@ function listRecipeFiles(root: string): string[] {
98
98
  .filter(
99
99
  (entry) =>
100
100
  entry.isFile() &&
101
- (entry.name.endsWith(".json") || entry.name.endsWith(".md")) &&
102
- entry.name !== "legacy-tool-registry-migration-report.json",
101
+ (entry.name.endsWith(".json") || entry.name.endsWith(".md")),
103
102
  )
104
103
  .map((entry) => join(root, entry.name))
105
104
  .sort(
package/lib/runtime.ts CHANGED
@@ -8,7 +8,6 @@ import * as Config from "./config.ts";
8
8
  import type { RegisteredToolExec } from "./execution.ts";
9
9
  import * as Paths from "./paths.ts";
10
10
  import * as RecipeDiscovery from "./recipe-discovery.ts";
11
- import * as RecipeMigration from "./recipe-migration.ts";
12
11
  import * as Tools from "./tools.ts";
13
12
 
14
13
  export interface RuntimeContext {
@@ -142,20 +141,6 @@ export function createAutoToolsRuntime(
142
141
  const recipeRoot = deps.recipeRoot ?? Paths.getRecipeRoot();
143
142
  const packagedRecipeRoot =
144
143
  deps.packagedRecipeRoot ?? Paths.getPackagedRecipeRoot();
145
- const migration = RecipeMigration.migrateLegacyToolRegistry({
146
- configPath: deps.configPath,
147
- recipeRoot,
148
- reservedToolNames: deps.reservedToolNames,
149
- });
150
- warnings.push(...migration.warnings);
151
- if (migration.conflicts.length > 0)
152
- warnings.push(
153
- `Recipe migration conflicts: ${migration.conflicts.join(", ")}`,
154
- );
155
- if (migration.invalid.length > 0)
156
- warnings.push(
157
- `Recipe migration invalid entries: ${migration.invalid.join(", ")}`,
158
- );
159
144
  const discovered = RecipeDiscovery.discoverRecipeSources([
160
145
  { root: recipeRoot, defaultTool: true, mutableUsage: true },
161
146
  { root: packagedRecipeRoot },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-actors",
3
- "version": "0.29.1",
3
+ "version": "0.29.2",
4
4
  "private": false,
5
5
  "description": "Local Actor Kernel for Pi",
6
6
  "keywords": [
@@ -2,7 +2,7 @@
2
2
  name: actors
3
3
  description: Highest-density practical guide for pi-actors. Read this skill whenever prompt and tools are not enough for spawn, message, inspect, actor runs, tools, recipes, command templates, async lifecycle, mailboxes, artifacts, and local orchestration mechanics.
4
4
  metadata:
5
- version: 0.29.1
5
+ version: 0.29.2
6
6
  ---
7
7
 
8
8
  # Actors (pi-actors)
@@ -2,7 +2,7 @@
2
2
  name: swarm
3
3
  description: Subagent orchestration with scoped locks and quorum consensus. Use for multi-model review, parallel scoped work, delegated audit, and coordinated subagent execution.
4
4
  metadata:
5
- version: 0.29.1
5
+ version: 0.29.2
6
6
  ---
7
7
 
8
8
  # Swarm
@@ -1,21 +0,0 @@
1
- /**
2
- * Legacy tool-registry to recipe-file migration helpers
3
- * Zones: registry migration, recipe persistence, compatibility diagnostics
4
- * Owns one-way migration from legacy tool registry entries into user recipe files
5
- */
6
- export interface LegacyRegistryMigrationResult {
7
- migrated: string[];
8
- skipped: string[];
9
- conflicts: string[];
10
- invalid: string[];
11
- archive?: string;
12
- report?: string;
13
- warnings: string[];
14
- }
15
- export interface LegacyRegistryMigrationOptions {
16
- configPath: string;
17
- recipeRoot: string;
18
- reservedToolNames: Set<string>;
19
- archive?: boolean;
20
- }
21
- export declare function migrateLegacyToolRegistry(options: LegacyRegistryMigrationOptions): LegacyRegistryMigrationResult;
@@ -1,90 +0,0 @@
1
- /**
2
- * Legacy tool-registry to recipe-file migration helpers
3
- * Zones: registry migration, recipe persistence, compatibility diagnostics
4
- * Owns one-way migration from legacy tool registry entries into user recipe files
5
- */
6
- import { existsSync, mkdirSync, renameSync } from "node:fs";
7
- import { basename, join } from "node:path";
8
- import * as Config from "./config.js";
9
- import { writeJsonAtomic } from "./file-state.js";
10
- import * as RecipeReferences from "./recipe-references.js";
11
- function recipePathForTool(recipeRoot, name) {
12
- return join(recipeRoot, `${name}.json`);
13
- }
14
- function toRecipeConfig(tool) {
15
- return {
16
- description: tool.description,
17
- ...(tool.recipe?.async !== undefined ? { async: tool.recipe.async } : {}),
18
- ...(tool.recipe?.state_dir ? { state_dir: tool.recipe.state_dir } : {}),
19
- ...(tool.storedArgs ? { args: tool.storedArgs } : {}),
20
- ...(tool.storedDefaults ? { defaults: tool.storedDefaults } : {}),
21
- template: tool.template,
22
- ...(tool.recipe?.values ? { values: tool.recipe.values } : {}),
23
- };
24
- }
25
- function nextArchivePath(configPath) {
26
- const base = `${configPath}.migrated`;
27
- if (!existsSync(base))
28
- return base;
29
- for (let index = 1; index < 1000; index += 1) {
30
- const path = `${base}.${index}`;
31
- if (!existsSync(path))
32
- return path;
33
- }
34
- return `${base}.${Date.now()}`;
35
- }
36
- export function migrateLegacyToolRegistry(options) {
37
- const { configPath, recipeRoot, reservedToolNames } = options;
38
- const result = {
39
- migrated: [],
40
- skipped: [],
41
- conflicts: [],
42
- invalid: [],
43
- warnings: [],
44
- };
45
- if (!existsSync(configPath))
46
- return result;
47
- const loaded = Config.loadToolConfig(configPath, reservedToolNames);
48
- result.warnings.push(...loaded.warnings);
49
- mkdirSync(recipeRoot, { recursive: true });
50
- for (const [name, tool] of loaded.tools) {
51
- const path = recipePathForTool(recipeRoot, name);
52
- if (existsSync(path)) {
53
- result.conflicts.push(name);
54
- continue;
55
- }
56
- const recipe = toRecipeConfig(tool);
57
- try {
58
- writeJsonAtomic(path, recipe);
59
- const parsed = RecipeReferences.readResolvedRecipeConfig(path);
60
- if (!parsed) {
61
- result.invalid.push(name);
62
- continue;
63
- }
64
- result.migrated.push(name);
65
- }
66
- catch (error) {
67
- result.invalid.push(`${name}: ${error instanceof Error ? error.message : String(error)}`);
68
- }
69
- }
70
- if (loaded.tools.size === 0)
71
- result.skipped.push(basename(configPath));
72
- const reportPath = join(recipeRoot, "legacy-tool-registry-migration-report.json");
73
- writeJsonAtomic(reportPath, {
74
- source: configPath,
75
- migrated: result.migrated,
76
- skipped: result.skipped,
77
- conflicts: result.conflicts,
78
- invalid: result.invalid,
79
- warnings: result.warnings,
80
- });
81
- result.report = reportPath;
82
- if (options.archive !== false &&
83
- result.conflicts.length === 0 &&
84
- result.invalid.length === 0) {
85
- const archive = nextArchivePath(configPath);
86
- renameSync(configPath, archive);
87
- result.archive = archive;
88
- }
89
- return result;
90
- }
@@ -1,121 +0,0 @@
1
- /**
2
- * Legacy tool-registry to recipe-file migration helpers
3
- * Zones: registry migration, recipe persistence, compatibility diagnostics
4
- * Owns one-way migration from legacy tool registry entries into user recipe files
5
- */
6
-
7
- import { existsSync, mkdirSync, renameSync } from "node:fs";
8
- import { basename, join } from "node:path";
9
-
10
- import * as Config from "./config.ts";
11
- import { writeJsonAtomic } from "./file-state.ts";
12
- import type { TemplateRecipeConfig } from "./recipe-references.ts";
13
- import * as RecipeReferences from "./recipe-references.ts";
14
-
15
- export interface LegacyRegistryMigrationResult {
16
- migrated: string[];
17
- skipped: string[];
18
- conflicts: string[];
19
- invalid: string[];
20
- archive?: string;
21
- report?: string;
22
- warnings: string[];
23
- }
24
-
25
- export interface LegacyRegistryMigrationOptions {
26
- configPath: string;
27
- recipeRoot: string;
28
- reservedToolNames: Set<string>;
29
- archive?: boolean;
30
- }
31
-
32
- function recipePathForTool(recipeRoot: string, name: string): string {
33
- return join(recipeRoot, `${name}.json`);
34
- }
35
-
36
- function toRecipeConfig(tool: Config.RegisteredTool): TemplateRecipeConfig {
37
- return {
38
- description: tool.description,
39
- ...(tool.recipe?.async !== undefined ? { async: tool.recipe.async } : {}),
40
- ...(tool.recipe?.state_dir ? { state_dir: tool.recipe.state_dir } : {}),
41
- ...(tool.storedArgs ? { args: tool.storedArgs } : {}),
42
- ...(tool.storedDefaults ? { defaults: tool.storedDefaults } : {}),
43
- template: tool.template!,
44
- ...(tool.recipe?.values ? { values: tool.recipe.values } : {}),
45
- };
46
- }
47
-
48
- function nextArchivePath(configPath: string): string {
49
- const base = `${configPath}.migrated`;
50
- if (!existsSync(base)) return base;
51
- for (let index = 1; index < 1000; index += 1) {
52
- const path = `${base}.${index}`;
53
- if (!existsSync(path)) return path;
54
- }
55
- return `${base}.${Date.now()}`;
56
- }
57
-
58
- export function migrateLegacyToolRegistry(
59
- options: LegacyRegistryMigrationOptions,
60
- ): LegacyRegistryMigrationResult {
61
- const { configPath, recipeRoot, reservedToolNames } = options;
62
- const result: LegacyRegistryMigrationResult = {
63
- migrated: [],
64
- skipped: [],
65
- conflicts: [],
66
- invalid: [],
67
- warnings: [],
68
- };
69
- if (!existsSync(configPath)) return result;
70
-
71
- const loaded = Config.loadToolConfig(configPath, reservedToolNames);
72
- result.warnings.push(...loaded.warnings);
73
- mkdirSync(recipeRoot, { recursive: true });
74
-
75
- for (const [name, tool] of loaded.tools) {
76
- const path = recipePathForTool(recipeRoot, name);
77
- if (existsSync(path)) {
78
- result.conflicts.push(name);
79
- continue;
80
- }
81
- const recipe = toRecipeConfig(tool);
82
- try {
83
- writeJsonAtomic(path, recipe);
84
- const parsed = RecipeReferences.readResolvedRecipeConfig(path);
85
- if (!parsed) {
86
- result.invalid.push(name);
87
- continue;
88
- }
89
- result.migrated.push(name);
90
- } catch (error) {
91
- result.invalid.push(
92
- `${name}: ${error instanceof Error ? error.message : String(error)}`,
93
- );
94
- }
95
- }
96
-
97
- if (loaded.tools.size === 0) result.skipped.push(basename(configPath));
98
-
99
- const reportPath = join(recipeRoot, "legacy-tool-registry-migration-report.json");
100
- writeJsonAtomic(reportPath, {
101
- source: configPath,
102
- migrated: result.migrated,
103
- skipped: result.skipped,
104
- conflicts: result.conflicts,
105
- invalid: result.invalid,
106
- warnings: result.warnings,
107
- });
108
- result.report = reportPath;
109
-
110
- if (
111
- options.archive !== false &&
112
- result.conflicts.length === 0 &&
113
- result.invalid.length === 0
114
- ) {
115
- const archive = nextArchivePath(configPath);
116
- renameSync(configPath, archive);
117
- result.archive = archive;
118
- }
119
-
120
- return result;
121
- }