pi-mono-all 1.0.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 (161) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENCE.md +7 -0
  3. package/node_modules/pi-common/package.json +22 -0
  4. package/node_modules/pi-common/src/auth-config.ts +290 -0
  5. package/node_modules/pi-common/src/auth.ts +63 -0
  6. package/node_modules/pi-common/src/cache.ts +60 -0
  7. package/node_modules/pi-common/src/errors.ts +47 -0
  8. package/node_modules/pi-common/src/http-client.ts +118 -0
  9. package/node_modules/pi-common/src/index.ts +7 -0
  10. package/node_modules/pi-common/src/rate-limiter.ts +32 -0
  11. package/node_modules/pi-common/src/tool-result.ts +27 -0
  12. package/node_modules/pi-mono-ask-user-question/CHANGELOG.md +185 -0
  13. package/node_modules/pi-mono-ask-user-question/README.md +226 -0
  14. package/node_modules/pi-mono-ask-user-question/index.ts +923 -0
  15. package/node_modules/pi-mono-ask-user-question/package.json +29 -0
  16. package/node_modules/pi-mono-auto-fix/CHANGELOG.md +59 -0
  17. package/node_modules/pi-mono-auto-fix/README.md +77 -0
  18. package/node_modules/pi-mono-auto-fix/index.ts +488 -0
  19. package/node_modules/pi-mono-auto-fix/package.json +23 -0
  20. package/node_modules/pi-mono-btw/CHANGELOG.md +180 -0
  21. package/node_modules/pi-mono-btw/README.md +24 -0
  22. package/node_modules/pi-mono-btw/index.ts +499 -0
  23. package/node_modules/pi-mono-btw/package.json +29 -0
  24. package/node_modules/pi-mono-clear/CHANGELOG.md +180 -0
  25. package/node_modules/pi-mono-clear/README.md +40 -0
  26. package/node_modules/pi-mono-clear/index.ts +45 -0
  27. package/node_modules/pi-mono-clear/package.json +29 -0
  28. package/node_modules/pi-mono-context/CHANGELOG.md +12 -0
  29. package/node_modules/pi-mono-context/README.md +74 -0
  30. package/node_modules/pi-mono-context/index.ts +641 -0
  31. package/node_modules/pi-mono-context/package.json +29 -0
  32. package/node_modules/pi-mono-context-guard/CHANGELOG.md +195 -0
  33. package/node_modules/pi-mono-context-guard/README.md +81 -0
  34. package/node_modules/pi-mono-context-guard/index.ts +212 -0
  35. package/node_modules/pi-mono-context-guard/package.json +23 -0
  36. package/node_modules/pi-mono-figma/CHANGELOG.md +59 -0
  37. package/node_modules/pi-mono-figma/README.md +236 -0
  38. package/node_modules/pi-mono-figma/__tests__/code-connect.test.ts +32 -0
  39. package/node_modules/pi-mono-figma/__tests__/figma-assets.test.ts +38 -0
  40. package/node_modules/pi-mono-figma/__tests__/figma-component-hints.test.ts +23 -0
  41. package/node_modules/pi-mono-figma/__tests__/figma-implementation-layout.test.ts +47 -0
  42. package/node_modules/pi-mono-figma/__tests__/figma-search.test.ts +51 -0
  43. package/node_modules/pi-mono-figma/__tests__/figma-summarizer.test.ts +65 -0
  44. package/node_modules/pi-mono-figma/__tests__/fixtures/complex-auto-layout.json +115 -0
  45. package/node_modules/pi-mono-figma/__tests__/fixtures/component-instance.json +50 -0
  46. package/node_modules/pi-mono-figma/__tests__/fixtures/hidden-and-vectors.json +28 -0
  47. package/node_modules/pi-mono-figma/__tests__/fixtures/variables-and-styles.json +40 -0
  48. package/node_modules/pi-mono-figma/docs/live-selection-bridge.md +16 -0
  49. package/node_modules/pi-mono-figma/index.ts +6 -0
  50. package/node_modules/pi-mono-figma/package.json +33 -0
  51. package/node_modules/pi-mono-figma/skills/figma/SKILL.md +143 -0
  52. package/node_modules/pi-mono-figma/src/code-connect.ts +110 -0
  53. package/node_modules/pi-mono-figma/src/figma-assets.ts +146 -0
  54. package/node_modules/pi-mono-figma/src/figma-cache.ts +6 -0
  55. package/node_modules/pi-mono-figma/src/figma-client.ts +471 -0
  56. package/node_modules/pi-mono-figma/src/figma-component-hints.ts +87 -0
  57. package/node_modules/pi-mono-figma/src/figma-implementation.ts +264 -0
  58. package/node_modules/pi-mono-figma/src/figma-schemas.ts +139 -0
  59. package/node_modules/pi-mono-figma/src/figma-search.ts +195 -0
  60. package/node_modules/pi-mono-figma/src/figma-summarizer.ts +673 -0
  61. package/node_modules/pi-mono-figma/src/figma-tokens.ts +57 -0
  62. package/node_modules/pi-mono-figma/src/figma-tools.ts +352 -0
  63. package/node_modules/pi-mono-linear/CHANGELOG.md +44 -0
  64. package/node_modules/pi-mono-linear/README.md +159 -0
  65. package/node_modules/pi-mono-linear/index.ts +6 -0
  66. package/node_modules/pi-mono-linear/package.json +30 -0
  67. package/node_modules/pi-mono-linear/skills/linear/SKILL.md +107 -0
  68. package/node_modules/pi-mono-linear/src/linear-client.ts +339 -0
  69. package/node_modules/pi-mono-linear/src/linear-queries.ts +101 -0
  70. package/node_modules/pi-mono-linear/src/linear-schemas.ts +90 -0
  71. package/node_modules/pi-mono-linear/src/linear-tools.ts +362 -0
  72. package/node_modules/pi-mono-loop/CHANGELOG.md +163 -0
  73. package/node_modules/pi-mono-loop/README.md +54 -0
  74. package/node_modules/pi-mono-loop/index.ts +291 -0
  75. package/node_modules/pi-mono-loop/package.json +26 -0
  76. package/node_modules/pi-mono-multi-edit/CHANGELOG.md +232 -0
  77. package/node_modules/pi-mono-multi-edit/README.md +244 -0
  78. package/node_modules/pi-mono-multi-edit/__tests__/classic.test.ts +277 -0
  79. package/node_modules/pi-mono-multi-edit/__tests__/diff.test.ts +77 -0
  80. package/node_modules/pi-mono-multi-edit/__tests__/patch.test.ts +287 -0
  81. package/node_modules/pi-mono-multi-edit/benchmark-edits.ts +966 -0
  82. package/node_modules/pi-mono-multi-edit/classic.ts +435 -0
  83. package/node_modules/pi-mono-multi-edit/diff.ts +143 -0
  84. package/node_modules/pi-mono-multi-edit/index.ts +266 -0
  85. package/node_modules/pi-mono-multi-edit/package.json +37 -0
  86. package/node_modules/pi-mono-multi-edit/patch.ts +463 -0
  87. package/node_modules/pi-mono-multi-edit/types.ts +53 -0
  88. package/node_modules/pi-mono-multi-edit/workspace.ts +85 -0
  89. package/node_modules/pi-mono-review/CHANGELOG.md +190 -0
  90. package/node_modules/pi-mono-review/README.md +30 -0
  91. package/node_modules/pi-mono-review/common.ts +930 -0
  92. package/node_modules/pi-mono-review/index.ts +8 -0
  93. package/node_modules/pi-mono-review/package.json +29 -0
  94. package/node_modules/pi-mono-review/review-tui.ts +194 -0
  95. package/node_modules/pi-mono-review/review.ts +119 -0
  96. package/node_modules/pi-mono-review/reviewer.ts +339 -0
  97. package/node_modules/pi-mono-sentinel/CHANGELOG.md +158 -0
  98. package/node_modules/pi-mono-sentinel/README.md +87 -0
  99. package/node_modules/pi-mono-sentinel/__tests__/output-scanner.test.ts +109 -0
  100. package/node_modules/pi-mono-sentinel/__tests__/permissions.test.ts +202 -0
  101. package/node_modules/pi-mono-sentinel/__tests__/whitelist.test.ts +59 -0
  102. package/node_modules/pi-mono-sentinel/guards/execution-tracker.ts +281 -0
  103. package/node_modules/pi-mono-sentinel/guards/output-scanner.ts +232 -0
  104. package/node_modules/pi-mono-sentinel/guards/permission-gate.ts +170 -0
  105. package/node_modules/pi-mono-sentinel/index.ts +43 -0
  106. package/node_modules/pi-mono-sentinel/package.json +26 -0
  107. package/node_modules/pi-mono-sentinel/patterns/permissions.ts +175 -0
  108. package/node_modules/pi-mono-sentinel/patterns/read-targets.ts +104 -0
  109. package/node_modules/pi-mono-sentinel/patterns/secrets.ts +143 -0
  110. package/node_modules/pi-mono-sentinel/session.ts +95 -0
  111. package/node_modules/pi-mono-sentinel/specs/2026/04/sentinel/001-permission-gate.md +145 -0
  112. package/node_modules/pi-mono-sentinel/types.ts +39 -0
  113. package/node_modules/pi-mono-sentinel/whitelist.ts +86 -0
  114. package/node_modules/pi-mono-simplify/CHANGELOG.md +163 -0
  115. package/node_modules/pi-mono-simplify/README.md +56 -0
  116. package/node_modules/pi-mono-simplify/index.ts +78 -0
  117. package/node_modules/pi-mono-simplify/package.json +29 -0
  118. package/node_modules/pi-mono-status-line/CHANGELOG.md +180 -0
  119. package/node_modules/pi-mono-status-line/README.md +96 -0
  120. package/node_modules/pi-mono-status-line/basic.ts +89 -0
  121. package/node_modules/pi-mono-status-line/expert.ts +689 -0
  122. package/node_modules/pi-mono-status-line/index.ts +54 -0
  123. package/node_modules/pi-mono-status-line/package.json +29 -0
  124. package/node_modules/pi-mono-team-mode/CHANGELOG.md +278 -0
  125. package/node_modules/pi-mono-team-mode/README.md +246 -0
  126. package/node_modules/pi-mono-team-mode/__tests__/agent-manager-transient.test.ts +75 -0
  127. package/node_modules/pi-mono-team-mode/__tests__/delegation-manager.test.ts +118 -0
  128. package/node_modules/pi-mono-team-mode/__tests__/formatters.test.ts +104 -0
  129. package/node_modules/pi-mono-team-mode/__tests__/model-config.test.ts +272 -0
  130. package/node_modules/pi-mono-team-mode/__tests__/notification-box.test.ts +34 -0
  131. package/node_modules/pi-mono-team-mode/__tests__/parallel-utils.test.ts +32 -0
  132. package/node_modules/pi-mono-team-mode/__tests__/pi-stream-parser.test.ts +64 -0
  133. package/node_modules/pi-mono-team-mode/__tests__/prompts.test.ts +106 -0
  134. package/node_modules/pi-mono-team-mode/__tests__/store.test.ts +164 -0
  135. package/node_modules/pi-mono-team-mode/__tests__/tasks.test.ts +267 -0
  136. package/node_modules/pi-mono-team-mode/__tests__/teammate-specs.test.ts +114 -0
  137. package/node_modules/pi-mono-team-mode/__tests__/widget.test.ts +41 -0
  138. package/node_modules/pi-mono-team-mode/__tests__/worktree.test.ts +78 -0
  139. package/node_modules/pi-mono-team-mode/core/chain-utils.ts +90 -0
  140. package/node_modules/pi-mono-team-mode/core/fs-utils.ts +44 -0
  141. package/node_modules/pi-mono-team-mode/core/model-config.ts +432 -0
  142. package/node_modules/pi-mono-team-mode/core/parallel-utils.ts +48 -0
  143. package/node_modules/pi-mono-team-mode/core/prompts.ts +158 -0
  144. package/node_modules/pi-mono-team-mode/core/store.ts +156 -0
  145. package/node_modules/pi-mono-team-mode/core/tasks.ts +99 -0
  146. package/node_modules/pi-mono-team-mode/core/teammate-specs.ts +124 -0
  147. package/node_modules/pi-mono-team-mode/core/types.ts +160 -0
  148. package/node_modules/pi-mono-team-mode/index.ts +825 -0
  149. package/node_modules/pi-mono-team-mode/managers/agent-manager.ts +654 -0
  150. package/node_modules/pi-mono-team-mode/managers/delegation-manager.ts +211 -0
  151. package/node_modules/pi-mono-team-mode/managers/task-manager.ts +238 -0
  152. package/node_modules/pi-mono-team-mode/managers/team-manager.ts +59 -0
  153. package/node_modules/pi-mono-team-mode/package.json +33 -0
  154. package/node_modules/pi-mono-team-mode/runtime/pi-stream-parser.ts +194 -0
  155. package/node_modules/pi-mono-team-mode/runtime/subprocess.ts +183 -0
  156. package/node_modules/pi-mono-team-mode/runtime/transient-session.ts +196 -0
  157. package/node_modules/pi-mono-team-mode/runtime/worktree.ts +90 -0
  158. package/node_modules/pi-mono-team-mode/ui/formatters.ts +149 -0
  159. package/node_modules/pi-mono-team-mode/ui/notification-box.ts +55 -0
  160. package/node_modules/pi-mono-team-mode/ui/widget.ts +94 -0
  161. package/package.json +76 -0
@@ -0,0 +1,145 @@
1
+ # Sentinel Extension — Permission Gate Guard
2
+
3
+ Stage: `Implemented`
4
+ Last Updated: 2026-04-25
5
+
6
+ ## High-Level Objective
7
+
8
+ Add a proactive permission-gate guard to the `sentinel` extension that intercepts `bash`, `write`, and `edit` tool calls before they perform system-level or out-of-scope operations (e.g., `sudo`, `curl | bash`, modifying shell configs, writing to `/usr/local/bin`, `brew install`, `rm -rf` on system paths). This closes the gap where the current `execution-tracker` only guards *session-written scripts* and misses dangerous commands issued directly as raw `bash` strings or out-of-project writes.
9
+
10
+ <!-- FEEDBACK: high_level_objective
11
+ Status: OPEN
12
+ -->
13
+
14
+ ## Mid-Level Objectives
15
+
16
+ - [ ] Create a new `permission-gate.ts` guard that subscribes to `tool_call` events for `bash`, `write`, and `edit`.
17
+ - [ ] Implement `bash` command pattern matching for high-risk operations (piped remote execution, sudo, privileged-path rm -rf, brew install, persistence hooks).
18
+ - [ ] Implement path classification logic to detect writes/edits targeting outside the current project root, system directories (`/usr/*`, `/Library/*`, `/System/*`, `/opt/*`), and shell config files (`~/.zshrc`, `~/.bashrc`, etc.).
19
+ - [ ] Provide a consistent escalation UX: `ctx.ui.confirm` when UI is available; fail-safe block with a descriptive `reason` when UI is unavailable.
20
+ - [ ] Register the new guard in `index.ts` alongside `output-scanner` and `execution-tracker`.
21
+ - [ ] Add unit tests for pattern matching and path classification helpers.
22
+ - [ ] Update the `sentinel` README to document the new guard and its behavior matrix.
23
+ - [ ] Bump the sentinel package version and update `CHANGELOG.md`.
24
+
25
+ <!-- FEEDBACK: mid_level_objectives
26
+ Questions or feedback about the requirements and milestones.
27
+ Status: OPEN
28
+ -->
29
+
30
+ ## Context
31
+
32
+ The `sentinel` extension currently provides two guards:
33
+
34
+ 1. **`output-scanner`** — Pre-reads files before `read` tool calls and scans them for secrets/credentials. Blocks or asks based on scan results.
35
+ 2. **`execution-tracker`** — Tracks files written via `write`/`edit` and scans them for dangerous patterns; later correlates those files with `bash` executions. If a script written in the session is executed and contains dangerous patterns, it asks/denies.
36
+
37
+ **The gap:** `execution-tracker` does **not** intercept raw `bash` commands that themselves contain dangerous operations (e.g., `curl -Ls https://mise.run | bash`). It only acts when a *file written earlier in the session* is executed. Similarly, neither guard prevents writes to system paths or shell config files.
38
+
39
+ The incident report from 2026-04-24 documents seven classes of ungated operations that should have required explicit user confirmation:
40
+
41
+ | Operation | Current behavior |
42
+ |-----------|----------------|
43
+ | `curl … \| bash` raw command | **Not blocked** |
44
+ | `wget … \| bash` raw command | **Not blocked** |
45
+ | `sudo …` raw command | **Not blocked** |
46
+ | `brew install …` raw command | **Not blocked** |
47
+ | `rm -rf /Library/…` raw command | **Not blocked** by sentinel (only `rm -rf` in session-written scripts) |
48
+ | Write to `~/.zshrc`, `~/.bashrc` | **Not blocked** |
49
+ | Write to `/usr/local/bin`, `/usr/*`, `/Library/*`, `/opt/*` | **Not blocked** |
50
+
51
+ The pi extension API supports blocking via returning `{ block: true, reason: string }` from `pi.on("tool_call", …)` handlers, and user confirmation via `ctx.ui.confirm(title, message)` when `ctx.hasUI` is true.
52
+
53
+ There are already example extensions (`permission-gate.ts`, `confirm-destructive.ts`, `protected-paths.ts`) demonstrating this pattern.
54
+
55
+ <!-- FEEDBACK: context
56
+ Questions or feedback about the technical context and background.
57
+ Status: OPEN
58
+ -->
59
+
60
+ ## Proposed Solution
61
+
62
+ Introduce a third sentinel guard named **`permission-gate`** (file: `guards/permission-gate.ts`).
63
+
64
+ ### Bash permission gating
65
+
66
+ On every `bash` `tool_call`, scan `event.input.command` against a curated list of dangerous patterns grouped by risk class:
67
+
68
+ | Risk class | Patterns | Escalation |
69
+ |------------|----------|------------|
70
+ | **Remote pipe execution** | `curl \| (bash\|sh\|zsh)`, `wget \| (bash\|sh\|zsh)` | Confirm (or block if no UI) |
71
+ | **Privilege escalation** | `\bsudo\b` | Confirm (showing full command) |
72
+ | **Destructive recursive delete** | `rm\s+-[a-zA-Z]*rf?.*(/(usr\|Library\|System\|opt)\|~/)` | Double-confirm or block (system paths); confirm for project-local paths |
73
+ | **Package manager system install** | `\bbrew\s+(install\|upgrade\|update)\b` | Confirm |
74
+ | **Persistence** | `crontab`, `systemctl enable`, `launchctl load` | Confirm |
75
+ | **Shell config modification (via bash)** | Appending to `~/.zshrc`, `~/.bashrc`, etc. | Confirm |
76
+ | **Binary installation outside project** | `cp\s+.*\s+/usr/local/bin/`, `mv\s+.*\s+/usr/local/bin/` | Confirm |
77
+
78
+ ### Write/Edit permission gating
79
+
80
+ On every `write` and `edit` `tool_call`, resolve the absolute target path and classify it:
81
+
82
+ | Path category | Example | Action |
83
+ |---------------|---------|--------|
84
+ | **Shell config files** | `~/.zshrc`, `~/.bashrc`, `~/.profile` | Confirm |
85
+ | **System directories** | `/usr/*`, `/Library/*`, `/System/*`, `/opt/*`, `/usr/local/bin` | Confirm |
86
+ | **Outside project root** | Any path not under `ctx.cwd` or the resolved project root | Confirm (with path shown) |
87
+
88
+ When a `write`/`edit` targets a shell config file, the confirmation dialog should show the target path and warn that this is a persistent system change.
89
+
90
+ ### Decision matrix
91
+
92
+ ```
93
+ UI available + user allows → return undefined (proceed)
94
+ UI available + user denies → return { block: true, reason }
95
+ No UI + dangerous detected → return { block: true, reason }
96
+ No dangerous patterns → return undefined (proceed)
97
+ ```
98
+
99
+ ### Scope boundaries
100
+
101
+ - This guard does **not** replace `output-scanner` or `execution-tracker`; it complements them.
102
+ - This guard does **not** block reads; only writes, edits, and bash executions.
103
+ - This guard intentionally does **not** block every `rm -rf` in the project directory (that would be overly restrictive); it only escalates `rm -rf` on known system/privileged paths.
104
+
105
+ <!-- FEEDBACK: proposed_solution
106
+ Questions or feedback about the proposed approach and scope.
107
+ Status: OPEN
108
+ -->
109
+
110
+ ## Implementation Notes
111
+
112
+ _No phases defined yet. Use `/dev:pair plan extensions/sentinel/specs/2026/04/sentinel/001-permission-gate.md` to generate the implementation plan._
113
+
114
+ <!-- FEEDBACK: implementation_approach
115
+ Questions or feedback about the overall implementation approach before diving into phases.
116
+ Status: OPEN
117
+ -->
118
+
119
+ ## Success Criteria
120
+
121
+ - [ ] A `bash` command containing `curl … | bash` is intercepted and escalated to the user (or blocked without UI).
122
+ - [ ] A `bash` command containing `sudo …` is intercepted and escalated.
123
+ - [ ] A `bash` command running `brew install` is intercepted and escalated.
124
+ - [ ] A `write` or `edit` targeting `~/.zshrc` is intercepted and escalated.
125
+ - [ ] A `write` or `edit` targeting `/usr/local/bin/` is intercepted and escalated.
126
+ - [ ] A `bash` command running `rm -rf /Library/Developer/CommandLineTools` is blocked or double-confirmed.
127
+ - [ ] When UI is unavailable, all matched dangerous operations fail-safe (block with a clear reason).
128
+ - [ ] Safe operations (e.g., `echo "hello"`, writing to project-local files) are not blocked and incur minimal overhead.
129
+ - [ ] The sentinel README and CHANGELOG are updated.
130
+
131
+ <!-- FEEDBACK: success_criteria
132
+ Questions or feedback about the completion criteria and validation approach.
133
+ Status: OPEN
134
+ -->
135
+
136
+ ## Notes
137
+
138
+ - Consider whether `sudo rm -rf` should trigger a single combined confirmation for both the `sudo` and the `rm -rf` risk classes, or if they should stack. A single confirmation with all matched labels is simpler and less noisy.
139
+ - Path resolution must handle `~` expansion and `ctx.cwd`-relative paths correctly.
140
+ - The guard should share the same notification style as existing guards (`[sentinel] …` prefix).
141
+
142
+ <!-- FEEDBACK: general
143
+ General questions, concerns, or suggestions for the entire implementation plan.
144
+ Status: OPEN
145
+ -->
@@ -0,0 +1,39 @@
1
+ /** Tri-state guard decision. */
2
+ export type Decision =
3
+ | { action: "allow" }
4
+ | { action: "deny"; reason: string }
5
+ | { action: "ask"; title: string; message: string };
6
+
7
+ /** A single secret match found during content scanning. */
8
+ export type ScanMatch = {
9
+ /** Human-readable label, e.g. "AWS Access Key". */
10
+ label: string;
11
+ /** 1-based line number where the match was found. */
12
+ line: number;
13
+ /** Masked excerpt of the matched value. */
14
+ snippet: string;
15
+ };
16
+
17
+ /** Aggregated result of scanning content for secrets. */
18
+ export type ScanResult = {
19
+ hasSecrets: boolean;
20
+ matches: ScanMatch[];
21
+ };
22
+
23
+ /** A dangerous-content pattern detected in written file content (Gap 3). */
24
+ export type DangerousPattern = {
25
+ label: string;
26
+ pattern: RegExp;
27
+ };
28
+
29
+ /** Entry in the session write registry (Gap 3). */
30
+ export type WriteEntry = {
31
+ /** Absolute path of the written file. */
32
+ path: string;
33
+ /** Timestamp (Date.now()) of the write. */
34
+ timestamp: number;
35
+ /** Whether dangerous execution patterns were detected in the content. */
36
+ hasDangerousContent: boolean;
37
+ /** Labels of detected dangerous patterns. */
38
+ dangerousPatterns: string[];
39
+ };
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Whitelist persistence for sentinel permission gate.
3
+ *
4
+ * Stores user-approved paths in ~/.pi/agent/sentinel-whitelist.json
5
+ * so that repeated write/edit operations to the same outside-project
6
+ * path do not trigger confirmation dialogs every session.
7
+ */
8
+
9
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
10
+ import { homedir } from "node:os";
11
+ import { join } from "node:path";
12
+
13
+ const WHITELIST_FILENAME = "sentinel-whitelist.json";
14
+ const AGENT_DIR_ENV = "PI_CODING_AGENT_DIR";
15
+
16
+ function getAgentDir(): string {
17
+ const envDir = process.env[AGENT_DIR_ENV];
18
+ if (envDir) {
19
+ if (envDir === "~") return homedir();
20
+ if (envDir.startsWith("~/")) return join(homedir(), envDir.slice(2));
21
+ return envDir;
22
+ }
23
+ return join(homedir(), ".pi", "agent");
24
+ }
25
+
26
+ function getWhitelistPath(): string {
27
+ return join(getAgentDir(), WHITELIST_FILENAME);
28
+ }
29
+
30
+ export function loadWhitelist(): Set<string> {
31
+ return loadWhitelistKey("paths");
32
+ }
33
+
34
+ export function saveWhitelist(paths: Iterable<string>): void {
35
+ saveWhitelistKey("paths", paths);
36
+ }
37
+
38
+ export function loadReadWhitelist(): Set<string> {
39
+ return loadWhitelistKey("readPaths");
40
+ }
41
+
42
+ export function saveReadWhitelist(paths: Iterable<string>): void {
43
+ saveWhitelistKey("readPaths", paths);
44
+ }
45
+
46
+ function loadWhitelistKey(key: "paths" | "readPaths"): Set<string> {
47
+ const filePath = getWhitelistPath();
48
+ if (!existsSync(filePath)) {
49
+ return new Set();
50
+ }
51
+ try {
52
+ const raw = readFileSync(filePath, "utf-8");
53
+ const parsed = JSON.parse(raw) as {
54
+ paths?: string[];
55
+ readPaths?: string[];
56
+ };
57
+ const values = parsed[key];
58
+ return new Set(Array.isArray(values) ? values : []);
59
+ } catch {
60
+ return new Set();
61
+ }
62
+ }
63
+
64
+ function saveWhitelistKey(
65
+ key: "paths" | "readPaths",
66
+ paths: Iterable<string>,
67
+ ): void {
68
+ const filePath = getWhitelistPath();
69
+ try {
70
+ let data: { paths?: string[]; readPaths?: string[] } = {};
71
+ if (existsSync(filePath)) {
72
+ try {
73
+ data = JSON.parse(readFileSync(filePath, "utf-8")) as {
74
+ paths?: string[];
75
+ readPaths?: string[];
76
+ };
77
+ } catch {
78
+ data = {};
79
+ }
80
+ }
81
+ data[key] = [...paths];
82
+ writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
83
+ } catch {
84
+ // silently fail if we can't write; the user still gets their operation
85
+ }
86
+ }
@@ -0,0 +1,163 @@
1
+ # pi-mono-simplify
2
+
3
+ ## 1.7.2
4
+
5
+ ### Patch Changes
6
+
7
+ ### Fixed: ask-user-question
8
+
9
+ - Remove unused `StringEnum` import from `@mariozechner/pi-ai`.
10
+
11
+
12
+ ## 1.7.1
13
+
14
+ ### Patch Changes
15
+
16
+ ### Fixed: team-mode
17
+
18
+ - Widget no longer mislabels blocked or approval-pending teams as "running smoothly" — blockers and pending approvals are now detected via team summaries.
19
+ - Preserve in-flight work on re-emitted `session_start` events instead of tearing the runtime down and SIGTERM-ing live teammates.
20
+ - Auto-relaunch leaders for `running` teams after a session reset; surface failures as both a team signal and a UI notification.
21
+ - `createTeam` now defaults `repoRoots` to `[process.cwd()]` when the caller passes an empty array.
22
+ - Archive `process.json` into `history/` before a new task reuses the same role slot, so the prior task's final state is no longer silently clobbered.
23
+
24
+ ### Enhanced: team-mode
25
+
26
+ - Durable intent queue for subprocess handoff: `team_spawn_teammate` calls made from a teammate subprocess are written to disk and executed by the main session's `LeaderRuntime` instead of spawning orphaned grand-children.
27
+ - New tool `team_task_create_batch` lets the leader emit the full initial task DAG in one call, removing per-task LLM round-trips during bootstrap.
28
+ - `team_create` / `launchLeader` accept an `awaitBootstrap` option so the user sees the task graph before the tool returns; leader launch retries up to 3 times on transient failures.
29
+ - Persist per-turn debug artifacts (prompt, invocation, stderr, raw event stream) for both leader and teammate subprocesses, exposed via `TeammateSummary.debugArtifacts`.
30
+ - Track `exitCode`, `exitSignal`, `terminationReason`, `stderrTail`, `toolExecutions`, `model` and `modelProvider` on every `TeammateProcess` record.
31
+ - Provider detection now consults pi's `settings.json` and `auth.json` in addition to env vars; default model IDs aligned with the provider/model scheme.
32
+ - `collectPiOutput` supports `AbortSignal` cancellation.
33
+
34
+ ### Tests
35
+
36
+ - New `intent-queue` and `model-config` suites; expanded coverage across `leader-runtime`, `team-manager`, `team-query-tool` and `formatters`.
37
+
38
+
39
+ ## 1.7.0
40
+
41
+ ### Minor Changes
42
+
43
+ ### Enhanced: status-line
44
+
45
+ - Improved progress rendering and colors in expert mode
46
+
47
+ ### Enhanced: team-mode
48
+
49
+ - **LLM-driven leader** — replaced the hardcoded `research → synthesis → implementation → verification` state machine with a pi subprocess coordinator that authors the task graph via tool calls
50
+ - **New tool `team_task_create`** so the leader can author tasks at runtime
51
+ - **New tool `team_handoff`** for explicit teammate → teammate context handoffs (replaces regex-scraping of `Handoffs:` output sections)
52
+ - **File-based teammate specs** — drop `.claude/teammates/<role>.md` frontmatter files (`name`, `description`, `needsWorktree`, `hasMemory`, `modelTier`) to extend or override the seven built-in roles
53
+ - **Event-driven leader wakes** — mailbox messages addressed to the leader (or broadcast) trigger a debounced (~200ms) cycle instead of waiting for the 20s polling tick
54
+ - **Templates accept any string** — `fullstack` / `research` / `refactor` remain as built-ins, but unknown template keys are accepted and no-op gracefully
55
+ - **Provider config per team** — per-team model overrides via `/team models`
56
+ - Reduced leader overhead and parent-session token churn
57
+ - `spawnTeammate` now always appends the full runtime-built context (signals, mailbox, dependencies, team memory) so teammates get the richer snapshot even when the caller's `context` argument is brief
58
+
59
+ ### Breaking changes: team-mode
60
+
61
+ - Removed `LeaderPhase` enum and `currentPhase` field from `TeamRecord` / `TeamSummary`
62
+ - Removed `parseExplicitHandoffs` export and the legacy `Handoffs:` output parser — peer handoffs must go through the `team_handoff` tool
63
+ - Removed the deterministic auto-spawn loop (`ensureBootstrapTasks`) — all task authoring and teammate spawning is now the LLM leader's responsibility
64
+ - Removed `StringEnum` gate on `team_create`'s `template` parameter (now plain string)
65
+
66
+ ### Fixed: review
67
+
68
+ - Annotate diff lines so the model picks correct line numbers
69
+ - Fix slice chunk around lines for comments in the reviewer TUI
70
+
71
+ ### Documentation
72
+
73
+ - Updated root README and sentinel extension README
74
+ - Documented the new file-based teammate spec format and event-driven leader wake in the team-mode README
75
+
76
+ ## 1.6.0
77
+
78
+ ### Minor Changes
79
+
80
+ ### New Extension: sentinel
81
+
82
+ Replaced the `grep` extension with a new security-focused `sentinel` extension for monitoring and guarding sensitive operations.
83
+
84
+ ### Enhanced: team-mode
85
+
86
+ - Added comprehensive test suite with integration tests
87
+ - New mock helpers for subprocess testing
88
+ - Improved signal manager with better error handling
89
+ - Leader runtime refactoring for stability
90
+ - Team query tool with dedicated tests
91
+
92
+ ### Enhanced: status-line
93
+
94
+ - Added basic and expert mode displays
95
+ - Improved index.ts with better state management
96
+
97
+ ### Enhanced: clear
98
+
99
+ - Updated keyboard shortcut to `Ctrl+Shift+L`
100
+ - Better busy-state handling for shortcuts
101
+ - Added warning/cancel handling and error notifications
102
+
103
+ ### Enhanced: context-guard
104
+
105
+ - Improved read deduplication across sessions
106
+ - Added `context-guard:file-modified` event for cache eviction
107
+
108
+ ### Documentation
109
+
110
+ - Added dedicated README for `clear` extension
111
+ - Added dedicated README for `context-guard` extension
112
+ - Updated main README with improved extension descriptions
113
+
114
+ ## 1.5.0
115
+
116
+ ### Minor Changes
117
+
118
+ - ### `multi-edit` — diverge from upstream fork
119
+
120
+ The extension was originally derived from [mitsuhiko/agent-stuff](https://github.com/mitsuhiko/agent-stuff)'s `pi-extensions/multi-edit.ts`. This release rewrites the largest unmodified subsystems so the implementation is structurally distinct from upstream while keeping the public contract intact.
121
+
122
+ - **Modularized layout** — the 953-line `index.ts` is split into purpose-scoped modules: `types.ts`, `workspace.ts`, `classic.ts`, `patch.ts`, `diff.ts`, and a slim `index.ts` (~180 lines of registration + dispatch wiring).
123
+ - **New patch engine** — `patch.ts` is now a recursive-descent parser over a `LineCursor` class with `indexOf`-based hunk anchoring. Hunks are stored as `{ oldBlock, newBlock }` raw strings (previously `{ oldLines[], newLines[] }` arrays), letting the applier splice content directly instead of reconstructing line arrays per apply.
124
+ - **Two-pass diff renderer** — `diff.ts` now walks `diffLines` parts into a typed `Entry[]` stream and makes all gutter / context-collapse decisions in a second pass, replacing the prior single-loop state-flag design.
125
+ - **Polished classic edits** — extracted `groupEditsByPath`, `sortGroupByPosition`, `applyGroupToContent`, and `rollbackSnapshots` helpers; formalized the quote-fallback as an ordered `MATCH_PASSES` array so new normalizers (dashes, NBSP, etc.) can be added by appending one entry.
126
+ - **First contract test suite** — 34 tests under `__tests__/` cover classic edits (positional reordering, redundant-pair skip, quote fallback, atomic rollback, read-only preflight), patch operations (Add/Delete/Update round-trips, move-rejection, multi-op batches), and diff rendering (line-number gutter, context collapse, add/remove-only cases). Runs via `npm test` (`tsx --test`).
127
+ - **Dropped Codex apply_patch edge cases** (documented in `README.md` → "Codex apply_patch compatibility"): `*** End of File` sentinel hunks, 4-pass fuzzy `seekSequence` matching, implicit first hunk without `@@`, whitespace-tolerant anchoring. Common paths (Add/Delete/Update-single-chunk, Update with multiple hunks, Add+Update+Delete batches) are fully tested and preserved.
128
+ - **README attribution** — new "Origins" section crediting `mitsuhiko/agent-stuff` as the original source.
129
+
130
+ ## 1.4.0
131
+
132
+ ### Minor Changes
133
+
134
+ - Add teammate progress heartbeats and widget refresh improvements to team mode.
135
+
136
+ ## 1.3.0
137
+
138
+ ### Minor Changes
139
+
140
+ - ### New Extensions
141
+
142
+ #### `loop`
143
+
144
+ New extension that runs a prompt or slash command on a recurring interval. Useful for periodic tasks, polling, and automated repeated actions within a pi session.
145
+
146
+ #### `simplify`
147
+
148
+ New extension that reviews changed code for reuse, quality, and efficiency, then automatically fixes any issues found. Integrates with `git diff` to scope the review to recent changes.
149
+
150
+ ***
151
+
152
+ ### Bug Fixes
153
+
154
+ #### `multi-edit`
155
+
156
+ - **Broader unicode normalization**: `findActualString` now handles the full range of Unicode single-quote variants (`‘’‚‛`) and double-quote variants (`“”„‟`) when falling back from exact match — fixes more curly-quote mismatch cases
157
+ - **Parallel write-access preflight**: `checkWriteAccess` calls are now issued concurrently via `Promise.all` instead of sequentially — faster batch preflight on large edit sets
158
+ - **Removed redundant `editOrder` array**: `Map` insertion order is now relied upon directly, simplifying the grouping loop
159
+
160
+ #### `team-mode`
161
+
162
+ - **Stall detection hardened**: introduced `STALL_BLOCKER_MARKER` / `STALL_BLOCKER_MESSAGE` constants so the marker used to detect and record abnormal process exits stays in sync — prevents duplicate stall reports
163
+ - **Leader cycle guard comment clarified**: `cycleRunning` guard comment now explicitly calls out the race between the poll interval and teammate-completion handlers
@@ -0,0 +1,56 @@
1
+ # Simplify Extension
2
+
3
+ Registers a `/simplify` command that reviews all git-changed files for code reuse, quality, and efficiency — then fixes any issues found.
4
+
5
+ Ported from the [`simplify` skill](https://github.com/emanuelcasco/claude-code/blob/main/src/skills/bundled/simplify.ts) for Claude Code.
6
+
7
+ ## Usage
8
+
9
+ ```
10
+ /simplify
11
+ /simplify <additional focus>
12
+ ```
13
+
14
+ **Examples:**
15
+
16
+ ```
17
+ /simplify
18
+ /simplify focus on performance and memory usage
19
+ /simplify pay extra attention to React re-renders
20
+ ```
21
+
22
+ ## Structure
23
+
24
+ - `index.ts` — extension entrypoint, registers the `/simplify` command
25
+
26
+ ## How It Works
27
+
28
+ Running `/simplify` injects a structured prompt into the conversation that drives a three-phase review:
29
+
30
+ ### Phase 1 — Identify Changes
31
+
32
+ Runs `git diff` (or `git diff HEAD` for staged changes) to get the full diff. Falls back to recently modified files if no git changes are present.
33
+
34
+ ### Phase 2 — Parallel Review (3 agents)
35
+
36
+ Three sub-agents run concurrently, each receiving the full diff:
37
+
38
+ | Agent | Focus |
39
+ |-------|-------|
40
+ | **Code Reuse** | Flags duplicated logic, hand-rolled utilities that shadow existing helpers, and inline patterns that should use shared abstractions |
41
+ | **Code Quality** | Detects redundant state, parameter sprawl, copy-paste blocks, leaky abstractions, stringly-typed code, unnecessary JSX nesting, and low-value comments |
42
+ | **Efficiency** | Catches unnecessary work, missed concurrency, hot-path bloat, recurring no-op updates, TOCTOU existence checks, memory leaks, and overly broad data fetches |
43
+
44
+ ### Phase 3 — Fix & Summarize
45
+
46
+ Aggregates findings from all three agents, applies fixes directly, skips false positives, and prints a brief summary of what changed (or confirms the code was already clean).
47
+
48
+ ## Optional Focus
49
+
50
+ Pass extra instructions after the command to steer the review:
51
+
52
+ ```
53
+ /simplify pay close attention to SQL query efficiency
54
+ ```
55
+
56
+ This appends an **Additional Focus** section to the prompt, which all agents will take into account.
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Simplify — reviews changed code for reuse, quality, and efficiency,
3
+ * then fixes any issues found.
4
+ *
5
+ * Ported from: https://github.com/emanuelcasco/claude-code/blob/main/src/skills/bundled/simplify.ts
6
+ *
7
+ * Usage:
8
+ * /simplify — review all git-changed files
9
+ * /simplify focus on perf — review with additional focus
10
+ */
11
+
12
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
13
+
14
+ const SIMPLIFY_PROMPT = `# Simplify: Code Review and Cleanup
15
+
16
+ Review all changed files for reuse, quality, and efficiency. Fix any issues found.
17
+
18
+ ## Phase 1: Identify Changes
19
+
20
+ Run \`git diff\` (or \`git diff HEAD\` if there are staged changes) to see what changed. If there are no git changes, review the most recently modified files that the user mentioned or that you edited earlier in this conversation.
21
+
22
+ ## Phase 2: Launch Three Review Agents in Parallel
23
+
24
+ Use the agent tool to launch all three agents concurrently in a single message. Pass each agent the full diff so it has the complete context.
25
+
26
+ ### Agent 1: Code Reuse Review
27
+
28
+ For each change:
29
+
30
+ 1. **Search for existing utilities and helpers** that could replace newly written code. Look for similar patterns elsewhere in the codebase — common locations are utility directories, shared modules, and files adjacent to the changed ones.
31
+ 2. **Flag any new function that duplicates existing functionality.** Suggest the existing function to use instead.
32
+ 3. **Flag any inline logic that could use an existing utility** — hand-rolled string manipulation, manual path handling, custom environment checks, ad-hoc type guards, and similar patterns are common candidates.
33
+
34
+ ### Agent 2: Code Quality Review
35
+
36
+ Review the same changes for hacky patterns:
37
+
38
+ 1. **Redundant state**: state that duplicates existing state, cached values that could be derived, observers/effects that could be direct calls
39
+ 2. **Parameter sprawl**: adding new parameters to a function instead of generalizing or restructuring existing ones
40
+ 3. **Copy-paste with slight variation**: near-duplicate code blocks that should be unified with a shared abstraction
41
+ 4. **Leaky abstractions**: exposing internal details that should be encapsulated, or breaking existing abstraction boundaries
42
+ 5. **Stringly-typed code**: using raw strings where constants, enums (string unions), or branded types already exist in the codebase
43
+ 6. **Unnecessary JSX nesting**: wrapper Boxes/elements that add no layout value — check if inner component props (flexShrink, alignItems, etc.) already provide the needed behavior
44
+ 7. **Unnecessary comments**: comments explaining WHAT the code does (well-named identifiers already do that), narrating the change, or referencing the task/caller — delete; keep only non-obvious WHY (hidden constraints, subtle invariants, workarounds)
45
+
46
+ ### Agent 3: Efficiency Review
47
+
48
+ Review the same changes for efficiency:
49
+
50
+ 1. **Unnecessary work**: redundant computations, repeated file reads, duplicate network/API calls, N+1 patterns
51
+ 2. **Missed concurrency**: independent operations run sequentially when they could run in parallel
52
+ 3. **Hot-path bloat**: new blocking work added to startup or per-request/per-render hot paths
53
+ 4. **Recurring no-op updates**: state/store updates inside polling loops, intervals, or event handlers that fire unconditionally — add a change-detection guard so downstream consumers aren't notified when nothing changed. Also: if a wrapper function takes an updater/reducer callback, verify it honors same-reference returns (or whatever the "no change" signal is) — otherwise callers' early-return no-ops are silently defeated
54
+ 5. **Unnecessary existence checks**: pre-checking file/resource existence before operating (TOCTOU anti-pattern) — operate directly and handle the error
55
+ 6. **Memory**: unbounded data structures, missing cleanup, event listener leaks
56
+ 7. **Overly broad operations**: reading entire files when only a portion is needed, loading all items when filtering for one
57
+
58
+ ## Phase 3: Fix Issues
59
+
60
+ Wait for all three agents to complete. Aggregate their findings and fix each issue directly. If a finding is a false positive or not worth addressing, note it and move on — do not argue with the finding, just skip it.
61
+
62
+ When done, briefly summarize what was fixed (or confirm the code was already clean).
63
+ `;
64
+
65
+ export default function simplifyExtension(pi: ExtensionAPI): void {
66
+ pi.registerCommand("simplify", {
67
+ description: "Review changed code for reuse, quality, and efficiency, then fix any issues found.",
68
+ handler: async (args, ctx) => {
69
+ let prompt = SIMPLIFY_PROMPT;
70
+
71
+ if (args?.trim()) {
72
+ prompt += `\n\n## Additional Focus\n\n${args.trim()}`;
73
+ }
74
+
75
+ pi.sendUserMessage(prompt);
76
+ },
77
+ });
78
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "pi-mono-simplify",
3
+ "version": "1.7.2",
4
+ "description": "Pi extension that reviews changed code for reuse, quality, and efficiency, then fixes any issues found",
5
+ "keywords": [
6
+ "pi-package",
7
+ "pi-extension"
8
+ ],
9
+ "peerDependencies": {
10
+ "@mariozechner/pi-ai": "*",
11
+ "@mariozechner/pi-coding-agent": "*",
12
+ "@mariozechner/pi-tui": "*",
13
+ "@sinclair/typebox": "*"
14
+ },
15
+ "pi": {
16
+ "extensions": [
17
+ "./index.ts"
18
+ ]
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/emanuelcasco/pi-mono-extensions.git",
23
+ "directory": "extensions/simplify"
24
+ },
25
+ "bugs": {
26
+ "url": "https://github.com/emanuelcasco/pi-mono-extensions/issues"
27
+ },
28
+ "homepage": "https://github.com/emanuelcasco/pi-mono-extensions#readme"
29
+ }