pi-pier 0.2.7 → 0.3.1

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 (85) hide show
  1. package/README.md +26 -12
  2. package/package.json +8 -3
  3. package/schemas/efficiency-config.schema.json +77 -0
  4. package/schemas/role-manifest.schema.json +7 -1
  5. package/skills/pi-herdr-workflow/SKILL.md +11 -0
  6. package/src/ansi-text.ts +134 -0
  7. package/src/ask-dialog.ts +308 -0
  8. package/src/ask-user.ts +139 -88
  9. package/src/bootstrap.ts +13 -14
  10. package/src/compact-coordinator.ts +471 -0
  11. package/src/compact-economics-core.ts +328 -0
  12. package/src/config-catalog-core.ts +332 -0
  13. package/src/config-command.ts +388 -0
  14. package/src/dashboard-command.ts +108 -0
  15. package/src/efficiency-config-core.ts +464 -0
  16. package/src/efficiency-store.ts +299 -0
  17. package/src/focus-poller.ts +223 -0
  18. package/src/gc-core.ts +77 -18
  19. package/src/herdr-client.ts +284 -154
  20. package/src/history-store.ts +36 -23
  21. package/src/index-gates.ts +124 -0
  22. package/src/index-locks.ts +29 -16
  23. package/src/index-master.ts +29 -19
  24. package/src/index-notices.ts +35 -11
  25. package/src/index-pipe.ts +17 -7
  26. package/src/index-roles.ts +306 -0
  27. package/src/index-runtime.ts +2 -6
  28. package/src/index-worker.ts +7 -9
  29. package/src/index.ts +425 -388
  30. package/src/jev-client.ts +141 -0
  31. package/src/jev-core.ts +431 -0
  32. package/src/ledger.ts +13 -21
  33. package/src/lock-core.ts +98 -37
  34. package/src/manifest-compose.ts +35 -20
  35. package/src/observation-core.ts +200 -0
  36. package/src/pane-title.ts +19 -38
  37. package/src/pi-surface.ts +34 -22
  38. package/src/pier-options.ts +100 -0
  39. package/src/pipe-channel.ts +65 -52
  40. package/src/platform-paths.ts +19 -52
  41. package/src/{core → plugins}/grid-shape.ts +12 -12
  42. package/src/plugins/heat-plan.ts +158 -0
  43. package/src/plugins/observation.ts +475 -0
  44. package/src/plugins/subagent.ts +728 -0
  45. package/src/{core → plugins}/terminal.ts +237 -123
  46. package/src/{core → plugins}/todo.ts +75 -100
  47. package/src/progress-core.ts +16 -53
  48. package/src/reconcile-core.ts +24 -33
  49. package/src/reducer-core.ts +322 -0
  50. package/src/reducer-invoker.ts +419 -0
  51. package/src/renderers.ts +187 -0
  52. package/src/role-loader.ts +35 -29
  53. package/src/role-manifest.ts +23 -32
  54. package/src/role-state.ts +119 -0
  55. package/src/routing-telemetry.ts +136 -0
  56. package/src/runtime-policy.ts +25 -43
  57. package/src/session-tail.ts +102 -23
  58. package/src/settle-wake-core.ts +55 -22
  59. package/src/slim-frame.ts +29 -124
  60. package/src/stale-core.ts +17 -24
  61. package/src/storage-layout.ts +24 -30
  62. package/src/subagent-core.ts +256 -119
  63. package/src/subagent-gc.ts +131 -69
  64. package/src/subagent-poller.ts +401 -12
  65. package/src/subagent-session.ts +516 -0
  66. package/src/subagent-spawn.ts +651 -28
  67. package/src/swallow.ts +65 -0
  68. package/src/terminal-core.ts +160 -69
  69. package/src/todo-core.ts +62 -113
  70. package/src/todo-read-hook.ts +23 -39
  71. package/src/todo-reminder-core.ts +30 -48
  72. package/src/todo-window.ts +11 -12
  73. package/src/todos-service.ts +27 -35
  74. package/src/tool-error.ts +19 -0
  75. package/src/tool-gate.ts +38 -21
  76. package/src/vocab.ts +55 -25
  77. package/src/core/subagent.ts +0 -839
  78. package/src/git-adapter.ts +0 -104
  79. package/src/notice-buffer.ts +0 -23
  80. package/src/subagent-git-io.ts +0 -80
  81. package/src/subagent-launch.ts +0 -110
  82. package/src/subagent-poll-loop.ts +0 -285
  83. package/src/subagent-port.ts +0 -27
  84. package/src/subagent-scope.ts +0 -39
  85. package/src/subagent-session-io.ts +0 -147
@@ -1,32 +1,20 @@
1
1
  /**
2
- * Storage path layout (history, session dirs, role dirs).
2
+ * Storage path layout (history, session dirs, role dirs) — the single owner of the session-dir
3
+ * encoding, so history-store / session-tail / role-loader cannot drift apart.
3
4
  *
4
- * Why: sessionDirName / historyFilePath / userRolesDir were duplicated across
5
- * history-store, session-tail, and role-loader. One module owns the encoding
6
- * so path conventions cannot drift.
7
- *
8
- * Writes use a collision-resistant encoding (`a/b` ≠ `a-b`). Reads prefer the
9
- * new name, then the legacy flattened name, so existing history/session dirs
10
- * stay reachable. If only the legacy dir exists, writes keep appending there
11
- * instead of splitting the ledger.
5
+ * Writes use a collision-resistant encoding (`a/b` ≠ `a-b`); reads try the new name, then the legacy
6
+ * flattened name, and when only the legacy dir exists writes keep appending there (no split ledger).
12
7
  */
13
8
  import { existsSync } from 'node:fs';
14
9
  import { homedir } from 'node:os';
15
10
  import { join } from 'node:path';
16
11
 
17
- /**
18
- * Legacy flattening (`--F--herdr-pi--`).
19
- * Why kept: `a/b` and `a-b` collide, but on-disk dirs already use this form.
20
- */
12
+ /** Legacy flattening (`--F--herdr-pi--`): `a/b` and `a-b` collide, but on-disk dirs use this form. */
21
13
  export function sessionDirNameLegacy(cwd: string): string {
22
- const flat = cwd.replace(/[\\/]/g, '-').replace(/:/g, '-');
23
- return `--${flat}--`;
14
+ return `--${cwd.replace(/[\\/]/g, '-').replace(/:/g, '-')}--`;
24
15
  }
25
16
 
26
- /**
27
- * Collision-resistant session directory name.
28
- * `%` is escaped first so `/` `\` `:` round-trip: `a/b` → `--a%2Fb--`, `a-b` → `--a-b--`.
29
- */
17
+ /** Collision-resistant name: `%` is escaped first so `/` `\` `:` round-trip (`a/b` → `--a%2Fb--`). */
30
18
  export function sessionDirName(cwd: string): string {
31
19
  const encoded = cwd
32
20
  .replace(/%/g, '%25')
@@ -36,7 +24,6 @@ export function sessionDirName(cwd: string): string {
36
24
  return `--${encoded}--`;
37
25
  }
38
26
 
39
- /** New encoding first, then legacy when they differ. */
40
27
  export function sessionDirCandidates(cwd: string): readonly string[] {
41
28
  const next = sessionDirName(cwd);
42
29
  const prev = sessionDirNameLegacy(cwd);
@@ -44,16 +31,26 @@ export function sessionDirCandidates(cwd: string): readonly string[] {
44
31
  }
45
32
 
46
33
  /**
47
- * Directory to read/write under `parent`.
48
- * Existing legacy dirs win over a missing new dir so history is not split.
34
+ * pi core's own session-directory encoding, byte-for-byte: strip ONE leading separator, then flatten
35
+ * `/` `\` `:` — it does NOT escape `%` like `sessionDirName`. `<agentDir>/sessions/` is pi core's
36
+ * directory, so reading pi sessions must match it exactly.
49
37
  */
38
+ export function piCoreSessionDirName(cwd: string): string {
39
+ return `--${cwd.replace(/^[/\\]/, '').replace(/[/\\:]/g, '-')}--`;
40
+ }
41
+
42
+ /**
43
+ * pi core's exact name first, then pier's own encodings (they may hold stray dirs from earlier
44
+ * versions). Read-only: writes to `<agentDir>/sessions/` are pi core's business.
45
+ */
46
+ export function piSessionDirCandidates(cwd: string): readonly string[] {
47
+ return [...new Set([piCoreSessionDirName(cwd), ...sessionDirCandidates(cwd)])];
48
+ }
49
+
50
+ /** Directory to read/write under `parent`: an existing legacy dir wins so history is not split. */
50
51
  export function preferredSessionDir(parent: string, cwd: string): string {
51
52
  const names = sessionDirCandidates(cwd);
52
- for (const name of names) {
53
- const dir = join(parent, name);
54
- if (existsSync(dir)) return dir;
55
- }
56
- return join(parent, names[0]);
53
+ return names.map((name) => join(parent, name)).find(existsSync) ?? join(parent, names[0]!);
57
54
  }
58
55
 
59
56
  export function historyFilePath(agentRoot: string, cwd: string): string {
@@ -64,17 +61,14 @@ export function historyFilePathLegacy(agentRoot: string, cwd: string): string {
64
61
  return join(agentRoot, 'herdr-pi', 'history', sessionDirNameLegacy(cwd), 'history.jsonl');
65
62
  }
66
63
 
67
- /** Dual-read history path: existing ledger (legacy or new) else canonical new file. */
68
64
  export function preferredHistoryFile(agentRoot: string, cwd: string): string {
69
65
  return join(preferredSessionDir(join(agentRoot, 'herdr-pi', 'history'), cwd), 'history.jsonl');
70
66
  }
71
67
 
72
- /** User-global roles directory (`~/.pi/agent/herdr-pi/roles/`). */
73
68
  export function userRolesDir(): string {
74
69
  return join(homedir(), '.pi', 'agent', 'herdr-pi', 'roles');
75
70
  }
76
71
 
77
- /** Workspace-level roles directory (`<base>/.pi-herdr/roles/`). */
78
72
  export function workspaceRolesDir(baseDir: string): string {
79
73
  return join(baseDir, '.pi-herdr', 'roles');
80
74
  }