pi-crew 0.1.51 → 0.2.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/CHANGELOG.md +56 -1
- package/README.md +176 -781
- package/agents/analyst.md +11 -11
- package/agents/critic.md +11 -11
- package/agents/executor.md +11 -11
- package/agents/explorer.md +11 -11
- package/agents/planner.md +11 -11
- package/agents/reviewer.md +11 -11
- package/agents/security-reviewer.md +11 -11
- package/agents/test-engineer.md +11 -11
- package/agents/verifier.md +70 -11
- package/agents/writer.md +11 -11
- package/docs/actions-reference.md +595 -0
- package/docs/commands-reference.md +347 -0
- package/docs/runtime-flow.md +148 -148
- package/index.ts +6 -6
- package/package.json +99 -99
- package/skills/async-worker-recovery/SKILL.md +42 -42
- package/skills/context-artifact-hygiene/SKILL.md +52 -52
- package/skills/delegation-patterns/SKILL.md +54 -54
- package/skills/mailbox-interactive/SKILL.md +40 -40
- package/skills/model-routing-context/SKILL.md +39 -39
- package/skills/multi-perspective-review/SKILL.md +58 -58
- package/skills/observability-reliability/SKILL.md +41 -41
- package/skills/orchestration/SKILL.md +157 -157
- package/skills/ownership-session-security/SKILL.md +41 -41
- package/skills/pi-extension-lifecycle/SKILL.md +39 -39
- package/skills/requirements-to-task-packet/SKILL.md +63 -63
- package/skills/resource-discovery-config/SKILL.md +41 -41
- package/skills/runtime-state-reader/SKILL.md +44 -44
- package/skills/secure-agent-orchestration-review/SKILL.md +45 -45
- package/skills/state-mutation-locking/SKILL.md +42 -42
- package/skills/systematic-debugging/SKILL.md +67 -67
- package/skills/ui-render-performance/SKILL.md +39 -39
- package/skills/verification-before-done/SKILL.md +57 -57
- package/skills/worktree-isolation/SKILL.md +39 -39
- package/src/adapters/claude-adapter.ts +25 -0
- package/src/adapters/codex-adapter.ts +21 -0
- package/src/adapters/cursor-adapter.ts +17 -0
- package/src/adapters/export-util.ts +137 -0
- package/src/adapters/index.ts +15 -0
- package/src/adapters/registry.ts +18 -0
- package/src/adapters/types.ts +23 -0
- package/src/agents/agent-config.ts +2 -0
- package/src/agents/agent-search.ts +98 -98
- package/src/agents/discover-agents.ts +2 -1
- package/src/config/config.ts +13 -1
- package/src/config/drift-detector.ts +211 -0
- package/src/config/markers.ts +327 -0
- package/src/config/resilient-parser.ts +108 -0
- package/src/config/suggestions.ts +74 -0
- package/src/extension/cross-extension-rpc.ts +103 -94
- package/src/extension/project-init.ts +21 -1
- package/src/extension/register.ts +45 -14
- package/src/extension/registration/commands.ts +77 -8
- package/src/extension/registration/subagent-tools.ts +10 -1
- package/src/extension/registration/team-tool.ts +10 -1
- package/src/extension/registration/viewers.ts +48 -34
- package/src/extension/run-bundle-schema.ts +89 -89
- package/src/extension/run-import.ts +25 -1
- package/src/extension/run-index.ts +5 -1
- package/src/extension/run-maintenance.ts +142 -68
- package/src/extension/team-manager-command.ts +10 -1
- package/src/extension/team-tool/doctor.ts +28 -3
- package/src/extension/team-tool/handle-settings.ts +195 -188
- package/src/extension/team-tool/inspect.ts +41 -41
- package/src/extension/team-tool/intent-policy.ts +42 -42
- package/src/extension/team-tool/lifecycle-actions.ts +27 -8
- package/src/extension/team-tool/plan.ts +19 -19
- package/src/extension/team-tool/run.ts +12 -1
- package/src/extension/team-tool.ts +11 -1
- package/src/i18n.ts +184 -184
- package/src/observability/exporters/otlp-exporter.ts +92 -77
- package/src/prompt/prompt-runtime.ts +72 -72
- package/src/runtime/agent-memory.ts +72 -72
- package/src/runtime/agent-observability.ts +114 -114
- package/src/runtime/async-marker.ts +26 -26
- package/src/runtime/attention-events.ts +28 -28
- package/src/runtime/auto-resume.ts +100 -0
- package/src/runtime/background-runner.ts +11 -1
- package/src/runtime/cancellation-token.ts +89 -89
- package/src/runtime/cancellation.ts +61 -61
- package/src/runtime/capability-inventory.ts +116 -116
- package/src/runtime/child-pi.ts +7 -2
- package/src/runtime/compaction-summary.ts +271 -0
- package/src/runtime/completion-guard.ts +190 -190
- package/src/runtime/crash-recovery.ts +33 -0
- package/src/runtime/delta-conflict.ts +360 -0
- package/src/runtime/direct-run.ts +35 -35
- package/src/runtime/foreground-control.ts +82 -82
- package/src/runtime/green-contract.ts +46 -46
- package/src/runtime/group-join.ts +106 -106
- package/src/runtime/heartbeat-gradient.ts +28 -28
- package/src/runtime/heartbeat-watcher.ts +124 -124
- package/src/runtime/iteration-hooks.ts +262 -0
- package/src/runtime/live-agent-control.ts +88 -88
- package/src/runtime/live-control-realtime.ts +36 -36
- package/src/runtime/live-extension-bridge.ts +150 -150
- package/src/runtime/live-irc.ts +92 -92
- package/src/runtime/live-session-health.ts +100 -100
- package/src/runtime/loop-gates.ts +129 -0
- package/src/runtime/metric-parser.ts +40 -0
- package/src/runtime/notebook-helpers.ts +90 -90
- package/src/runtime/orphan-sentinel.ts +7 -7
- package/src/runtime/parallel-research.ts +44 -44
- package/src/runtime/phase-progress.ts +217 -0
- package/src/runtime/pi-args.ts +38 -11
- package/src/runtime/pi-json-output.ts +111 -111
- package/src/runtime/pi-spawn.ts +57 -7
- package/src/runtime/policy-engine.ts +79 -79
- package/src/runtime/post-checks.ts +122 -0
- package/src/runtime/progress-event-coalescer.ts +43 -43
- package/src/runtime/prose-compressor.ts +164 -164
- package/src/runtime/recovery-recipes.ts +74 -74
- package/src/runtime/result-extractor.ts +121 -121
- package/src/runtime/role-permission.ts +39 -39
- package/src/runtime/sensitive-paths.ts +2 -2
- package/src/runtime/session-resources.ts +25 -25
- package/src/runtime/session-snapshot.ts +59 -59
- package/src/runtime/session-usage.ts +79 -79
- package/src/runtime/sidechain-output.ts +29 -29
- package/src/runtime/stream-preview.ts +177 -177
- package/src/runtime/supervisor-contact.ts +59 -59
- package/src/runtime/task-display.ts +38 -38
- package/src/runtime/task-graph.ts +207 -0
- package/src/runtime/task-quality.ts +207 -0
- package/src/runtime/task-runner/capabilities.ts +78 -78
- package/src/runtime/task-runner/live-executor.ts +7 -1
- package/src/runtime/task-runner/progress.ts +119 -119
- package/src/runtime/task-runner/prompt-pipeline.ts +64 -64
- package/src/runtime/task-runner/result-utils.ts +14 -14
- package/src/runtime/task-runner/run-projection.ts +103 -103
- package/src/runtime/task-runner/state-helpers.ts +22 -22
- package/src/runtime/team-runner.ts +117 -7
- package/src/runtime/worker-heartbeat.ts +21 -21
- package/src/runtime/worker-startup.ts +57 -57
- package/src/runtime/workflow-state.ts +187 -0
- package/src/runtime/workspace-tree.ts +298 -298
- package/src/schema/config-schema.ts +11 -0
- package/src/schema/validation-types.ts +148 -0
- package/src/skills/skill-templates.ts +374 -0
- package/src/state/active-run-registry.ts +35 -11
- package/src/state/atomic-write.ts +33 -26
- package/src/state/contracts.ts +1 -0
- package/src/state/event-reconstructor.ts +217 -0
- package/src/state/locks.ts +2 -13
- package/src/state/mailbox.ts +4 -3
- package/src/state/state-store.ts +32 -14
- package/src/state/task-claims.ts +44 -44
- package/src/state/types.ts +9 -0
- package/src/state/usage.ts +29 -29
- package/src/subagents/async-entry.ts +1 -1
- package/src/subagents/index.ts +3 -3
- package/src/subagents/live/control.ts +1 -1
- package/src/subagents/live/manager.ts +1 -1
- package/src/subagents/live/realtime.ts +1 -1
- package/src/subagents/live/session-runtime.ts +1 -1
- package/src/subagents/manager.ts +1 -1
- package/src/subagents/spawn.ts +1 -1
- package/src/teams/team-serializer.ts +38 -38
- package/src/types/diff.d.ts +18 -18
- package/src/ui/crew-footer.ts +101 -101
- package/src/ui/crew-select-list.ts +111 -111
- package/src/ui/crew-widget.ts +5 -2
- package/src/ui/dashboard-panes/cancellation-pane.ts +42 -42
- package/src/ui/dashboard-panes/capability-pane.ts +59 -59
- package/src/ui/dashboard-panes/mailbox-pane.ts +35 -35
- package/src/ui/dashboard-panes/metrics-pane.ts +34 -34
- package/src/ui/dashboard-panes/progress-pane.ts +11 -0
- package/src/ui/dynamic-border.ts +25 -25
- package/src/ui/layout-primitives.ts +106 -106
- package/src/ui/loaders.ts +158 -158
- package/src/ui/render-coalescer.ts +51 -51
- package/src/ui/render-diff.ts +119 -119
- package/src/ui/render-scheduler.ts +143 -143
- package/src/ui/run-action-dispatcher.ts +10 -1
- package/src/ui/spinner.ts +17 -17
- package/src/ui/status-colors.ts +58 -58
- package/src/ui/syntax-highlight.ts +116 -116
- package/src/ui/transcript-entries.ts +258 -258
- package/src/utils/completion-dedupe.ts +63 -63
- package/src/utils/frontmatter.ts +68 -68
- package/src/utils/git.ts +262 -262
- package/src/utils/ids.ts +17 -17
- package/src/utils/incremental-reader.ts +104 -104
- package/src/utils/names.ts +27 -27
- package/src/utils/redaction.ts +44 -44
- package/src/utils/safe-paths.ts +47 -47
- package/src/utils/scan-cache.ts +136 -136
- package/src/utils/sleep.ts +40 -26
- package/src/utils/task-name-generator.ts +337 -337
- package/src/workflows/validate-workflow.ts +40 -40
- package/src/worktree/branch-freshness.ts +45 -45
- package/teams/default.team.md +12 -12
- package/teams/fast-fix.team.md +11 -11
- package/teams/implementation.team.md +18 -18
- package/teams/parallel-research.team.md +14 -14
- package/teams/research.team.md +11 -11
- package/teams/review.team.md +12 -12
- package/workflows/default.workflow.md +30 -29
- package/workflows/fast-fix.workflow.md +23 -22
- package/workflows/implementation.workflow.md +43 -43
- package/workflows/parallel-research.workflow.md +46 -46
- package/workflows/research.workflow.md +22 -22
- package/workflows/review.workflow.md +30 -30
- package/docs/refactor-tasks-phase3.md +0 -394
- package/docs/refactor-tasks-phase4.md +0 -564
- package/docs/refactor-tasks-phase5.md +0 -402
- package/docs/refactor-tasks-phase6.md +0 -662
- package/docs/refactor-tasks.md +0 -1484
- package/docs/research/AGENT-EXECUTION-ARCHITECTURE.md +0 -261
- package/docs/research/AGENT-LIFECYCLE-COMPARISON.md +0 -111
- package/docs/research/AUDIT_OH_MY_PI.md +0 -261
- package/docs/research/AUDIT_PI_CREW.md +0 -457
- package/docs/research/CAVEMAN-DEEP-RESEARCH.md +0 -281
- package/docs/research/COMPARISON_OH_MY_PI_VS_PI_CREW.md +0 -264
- package/docs/research/DEEP-RESEARCH-PI-POWERBAR.md +0 -343
- package/docs/research/DEEP_RESEARCH_SUBAGENT_ARCHITECTURE.md +0 -480
- package/docs/research/GAP_CLOSURE_IMPLEMENTATION_PLAN.md +0 -354
- package/docs/research/IMPLEMENTATION_PLAN.md +0 -385
- package/docs/research/LIVE-SESSION-PRODUCTION-READY-PLAN.md +0 -502
- package/docs/research/OH-MY-PI-DEEP-RESEARCH-v14.7.6.md +0 -266
- package/docs/research/REMAINING-GAPS-PLAN.md +0 -363
- package/docs/research/SESSION-SUMMARY-2026-05-08.md +0 -146
- package/docs/research/UI-RESPONSIVENESS-AUDIT.md +0 -173
- package/docs/research-awesome-agent-skills-distillation.md +0 -100
- package/docs/research-extension-examples.md +0 -297
- package/docs/research-extension-system.md +0 -324
- package/docs/research-oh-my-pi-distillation.md +0 -369
- package/docs/research-optimization-plan.md +0 -548
- package/docs/research-phase10-distillation.md +0 -199
- package/docs/research-phase11-distillation.md +0 -201
- package/docs/research-phase8-operator-experience-plan.md +0 -819
- package/docs/research-phase9-observability-reliability-plan.md +0 -1190
- package/docs/research-pi-coding-agent.md +0 -357
- package/docs/research-source-pi-crew-reference.md +0 -174
- package/docs/research-ui-optimization-plan.md +0 -480
- package/docs/source-runtime-refactor-map.md +0 -107
- package/src/utils/atomic-write.ts +0 -33
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
# Research: Extension Examples & Patterns
|
|
2
|
-
|
|
3
|
-
> Ngày: 2026-04-29 | Read-only research | Source: `source/pi-mono/packages/coding-agent/examples/extensions/`
|
|
4
|
-
|
|
5
|
-
## 1. Example Catalog (86 files, 60+ extensions)
|
|
6
|
-
|
|
7
|
-
### 1.1 Sorted by relevance to pi-crew
|
|
8
|
-
|
|
9
|
-
| Priority | Example | Relevance |
|
|
10
|
-
|---|---|---|
|
|
11
|
-
| ⭐⭐⭐ | `subagent/` | Most similar to pi-crew: child Pi spawning, parallel, chain |
|
|
12
|
-
| ⭐⭐⭐ | `custom-compaction.ts` | Hook compaction — useful for preserving run state |
|
|
13
|
-
| ⭐⭐⭐ | `event-bus.ts` | Cross-extension communication pattern |
|
|
14
|
-
| ⭐⭐⭐ | `plan-mode/` | State persistence, dynamic tools, widget management |
|
|
15
|
-
| ⭐⭐⭐ | `structured-output.ts` | `terminate: true` — save LLM turns |
|
|
16
|
-
| ⭐⭐ | `handoff.ts` | Context transfer to new session |
|
|
17
|
-
| ⭐⭐ | `dynamic-tools.ts` | Register tools at runtime |
|
|
18
|
-
| ⭐⭐ | `permission-gate.ts` | Gate dangerous operations |
|
|
19
|
-
| ⭐⭐ | `trigger-compact.ts` | Proactive compaction monitoring |
|
|
20
|
-
| ⭐⭐ | `send-user-message.ts` | sendUserMessage pattern |
|
|
21
|
-
| ⭐ | `dirty-repo-guard.ts` | Guard against uncommitted changes |
|
|
22
|
-
| ⭐ | `model-status.ts` | Model status in footer |
|
|
23
|
-
| ⭐ | `confirm-destructive.ts` | Confirm destructive operations |
|
|
24
|
-
|
|
25
|
-
## 2. Deep Analysis of Key Examples
|
|
26
|
-
|
|
27
|
-
### 2.1 subagent/ — The Reference Implementation
|
|
28
|
-
|
|
29
|
-
**Files:**
|
|
30
|
-
- `index.ts` (~530 dòng): Main tool with execute + render
|
|
31
|
-
- `agents.ts` (~130 dòng): Agent discovery (user/project scope)
|
|
32
|
-
|
|
33
|
-
**Architecture:**
|
|
34
|
-
```
|
|
35
|
-
subagent tool
|
|
36
|
-
├── Single: runSingleAgent() → spawn pi --mode json -p
|
|
37
|
-
├── Parallel: mapWithConcurrencyLimit(tasks, 4, runSingleAgent)
|
|
38
|
-
└── Chain: sequential loop with {previous} placeholder
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
**Key patterns:**
|
|
42
|
-
- Agent discovery: `discoverAgents(cwd, scope)` — scans `.md` files with YAML frontmatter
|
|
43
|
-
- Child process: `getPiInvocation()` detects current runtime (node/bun/pi binary)
|
|
44
|
-
- Streaming: `onUpdate` callback for partial results during execution
|
|
45
|
-
- Render: `renderCall()` + `renderResult()` with collapsed/expanded views
|
|
46
|
-
- Abort: AbortSignal propagated to child process
|
|
47
|
-
|
|
48
|
-
**What pi-crew does better:**
|
|
49
|
-
- Durable state (manifest, tasks, events) instead of in-memory only
|
|
50
|
-
- Team/workflow abstraction instead of flat agent list
|
|
51
|
-
- Task graph with DAG dependencies instead of linear chain
|
|
52
|
-
- Async background runner with PID tracking
|
|
53
|
-
- Policy engine for limits/retry/escalation
|
|
54
|
-
- Mailbox for inter-task communication
|
|
55
|
-
- Worktree isolation per task
|
|
56
|
-
|
|
57
|
-
**What pi-crew could adopt from this:**
|
|
58
|
-
- `terminate: true` on final results (not used in example either, but available)
|
|
59
|
-
- `renderCall/Result` custom rendering patterns
|
|
60
|
-
- `mapWithConcurrencyLimit` pattern (pi-crew already has similar)
|
|
61
|
-
|
|
62
|
-
### 2.2 custom-compaction.ts — Custom Compaction
|
|
63
|
-
|
|
64
|
-
**Pattern:**
|
|
65
|
-
```typescript
|
|
66
|
-
pi.on("session_before_compact", async (event, ctx) => {
|
|
67
|
-
// 1. Get preparation data
|
|
68
|
-
const { messagesToSummarize, turnPrefixMessages, tokensBefore, firstKeptEntryId } = event.preparation;
|
|
69
|
-
|
|
70
|
-
// 2. Use different model for summarization (cheaper)
|
|
71
|
-
const model = ctx.modelRegistry.find("google", "gemini-2.5-flash");
|
|
72
|
-
|
|
73
|
-
// 3. Custom prompt
|
|
74
|
-
const summary = await complete(model, { messages: [...] }, { apiKey, signal });
|
|
75
|
-
|
|
76
|
-
// 4. Return custom compaction result
|
|
77
|
-
return {
|
|
78
|
-
compaction: { summary, firstKeptEntryId, tokensBefore }
|
|
79
|
-
};
|
|
80
|
-
});
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
**Relevance to pi-crew:**
|
|
84
|
-
- Can use cheap model to summarize completed tasks
|
|
85
|
-
- Can protect foreground runs from being compacted mid-execution
|
|
86
|
-
- Can store structured artifact index in compaction `details`
|
|
87
|
-
|
|
88
|
-
### 2.3 event-bus.ts — Cross-Extension Communication
|
|
89
|
-
|
|
90
|
-
**Pattern:**
|
|
91
|
-
```typescript
|
|
92
|
-
// Extension A: emit events
|
|
93
|
-
pi.events.emit("my:notification", { message: "hello", from: "ext-a" });
|
|
94
|
-
|
|
95
|
-
// Extension B: listen
|
|
96
|
-
pi.events.on("my:notification", (data) => {
|
|
97
|
-
currentCtx?.ui.notify(`Event from ${data.from}: ${data.message}`);
|
|
98
|
-
});
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
**Relevance to pi-crew:**
|
|
102
|
-
- Already used for internal events (`subagent.stuck-blocked`)
|
|
103
|
-
- Could publish structured events for other extensions to consume:
|
|
104
|
-
- `pi-crew:run:completed`
|
|
105
|
-
- `pi-crew:subagent:completed`
|
|
106
|
-
- `pi-crew:run:failed`
|
|
107
|
-
|
|
108
|
-
### 2.4 plan-mode/ — State Persistence + Dynamic Tools
|
|
109
|
-
|
|
110
|
-
**Key patterns:**
|
|
111
|
-
|
|
112
|
-
State persistence:
|
|
113
|
-
```typescript
|
|
114
|
-
// Save
|
|
115
|
-
pi.appendEntry("plan-mode", { enabled, todos, executing });
|
|
116
|
-
|
|
117
|
-
// Restore on session_start
|
|
118
|
-
const entries = ctx.sessionManager.getEntries();
|
|
119
|
-
const state = entries
|
|
120
|
-
.filter(e => e.type === "custom" && e.customType === "plan-mode")
|
|
121
|
-
.pop()?.data;
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Dynamic tools:
|
|
125
|
-
```typescript
|
|
126
|
-
// Switch between tool sets
|
|
127
|
-
if (planModeEnabled) {
|
|
128
|
-
pi.setActiveTools(["read", "bash", "grep", "find", "ls"]);
|
|
129
|
-
} else {
|
|
130
|
-
pi.setActiveTools(["read", "bash", "edit", "write"]);
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
Tool call gate:
|
|
135
|
-
```typescript
|
|
136
|
-
pi.on("tool_call", async (event) => {
|
|
137
|
-
if (planModeEnabled && event.toolName === "bash") {
|
|
138
|
-
if (!isSafeCommand(event.input.command)) {
|
|
139
|
-
return { block: true, reason: "..." };
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
**Relevance to pi-crew:**
|
|
146
|
-
- `pi.appendEntry` pattern for cross-session run awareness
|
|
147
|
-
- `pi.setActiveTools` could be used to restrict tools during team runs
|
|
148
|
-
- `tool_call` gate for destructive team actions
|
|
149
|
-
|
|
150
|
-
### 2.5 structured-output.ts — terminate: true
|
|
151
|
-
|
|
152
|
-
**Pattern:**
|
|
153
|
-
```typescript
|
|
154
|
-
async execute(_toolCallId, params) {
|
|
155
|
-
return {
|
|
156
|
-
content: [{ type: "text", text: "Done" }],
|
|
157
|
-
details: { headline, summary, actionItems },
|
|
158
|
-
terminate: true, // ← No follow-up LLM turn needed
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
**Relevance to pi-crew:**
|
|
164
|
-
- `Agent` tool results could use `terminate: true` when background run queued
|
|
165
|
-
- `get_subagent_result` could terminate when result is final
|
|
166
|
-
- `team` tool status/list/recommend actions could terminate
|
|
167
|
-
|
|
168
|
-
### 2.6 handoff.ts — Context Transfer to New Session
|
|
169
|
-
|
|
170
|
-
**Pattern:**
|
|
171
|
-
```typescript
|
|
172
|
-
// 1. Extract conversation context
|
|
173
|
-
const messages = ctx.sessionManager.getBranch()
|
|
174
|
-
.filter(e => e.type === "message")
|
|
175
|
-
.map(e => e.message);
|
|
176
|
-
|
|
177
|
-
// 2. Generate focused prompt
|
|
178
|
-
const prompt = await complete(model, { systemPrompt, messages }, { apiKey });
|
|
179
|
-
|
|
180
|
-
// 3. Create new session with pre-filled editor
|
|
181
|
-
await ctx.newSession({
|
|
182
|
-
parentSession: currentSessionFile,
|
|
183
|
-
withSession: async (replacementCtx) => {
|
|
184
|
-
replacementCtx.ui.setEditorText(prompt);
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**Relevance to pi-crew:**
|
|
190
|
-
- When a task in a team run needs isolated context, could handoff to new session
|
|
191
|
-
- Parent session tracking via `parentSession`
|
|
192
|
-
|
|
193
|
-
### 2.7 permission-gate.ts — Dangerous Operation Gate
|
|
194
|
-
|
|
195
|
-
**Pattern:**
|
|
196
|
-
```typescript
|
|
197
|
-
pi.on("tool_call", async (event, ctx) => {
|
|
198
|
-
if (event.toolName !== "bash") return;
|
|
199
|
-
if (isDangerousPattern(event.input.command)) {
|
|
200
|
-
const choice = await ctx.ui.select("Allow?", ["Yes", "No"]);
|
|
201
|
-
if (choice !== "Yes") {
|
|
202
|
-
return { block: true, reason: "Blocked by user" };
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
**Relevance to pi-crew:**
|
|
209
|
-
- Gate destructive team actions (delete, forget, prune)
|
|
210
|
-
- Only allow with explicit `confirm: true` parameter
|
|
211
|
-
|
|
212
|
-
### 2.8 trigger-compact.ts — Proactive Compaction
|
|
213
|
-
|
|
214
|
-
**Pattern:**
|
|
215
|
-
```typescript
|
|
216
|
-
pi.on("turn_end", (_event, ctx) => {
|
|
217
|
-
const usage = ctx.getContextUsage();
|
|
218
|
-
if (usage?.tokens && usage.tokens > THRESHOLD) {
|
|
219
|
-
ctx.compact({ customInstructions: "..." });
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
**Relevance to pi-crew:**
|
|
225
|
-
- Monitor context during long team runs
|
|
226
|
-
- Auto-compact before hitting overflow errors
|
|
227
|
-
- Use compact's callback to track state
|
|
228
|
-
|
|
229
|
-
## 3. Pattern Summary
|
|
230
|
-
|
|
231
|
-
### 3.1 Patterns pi-crew already implements well
|
|
232
|
-
|
|
233
|
-
| Pattern | pi-crew implementation |
|
|
234
|
-
|---|---|
|
|
235
|
-
| Child Pi spawning | `SubagentManager` + `spawn.ts` with full process management |
|
|
236
|
-
| Parallel execution | `mapConcurrent` in team runner |
|
|
237
|
-
| State persistence | Durable file-based (manifest, tasks, events, artifacts) |
|
|
238
|
-
| Widget rendering | `CrewWidget`, `LiveRunSidebar`, `Powerbar` |
|
|
239
|
-
| Lifecycle hooks | `session_start`, `session_before_switch`, `session_shutdown` |
|
|
240
|
-
| Config merge | `loadConfig` with user/project priority |
|
|
241
|
-
| Abort propagation | `AbortController` trees in foreground runs |
|
|
242
|
-
|
|
243
|
-
### 3.2 Patterns pi-crew could adopt
|
|
244
|
-
|
|
245
|
-
| Pattern | Current status | Recommendation |
|
|
246
|
-
|---|---|---|
|
|
247
|
-
| `terminate: true` | ❌ Not used | Add to Agent/get_subagent_result |
|
|
248
|
-
| `session_before_compact` hook | ❌ Not hooked | Cancel compact during foreground runs |
|
|
249
|
-
| Custom compaction model | ❌ Not used | Use Haiku/Gemini Flash for task summaries |
|
|
250
|
-
| `pi.events` publish | ⚠️ Internal only | Add public structured events |
|
|
251
|
-
| `pi.appendEntry` | ❌ Not used | Cross-session run references |
|
|
252
|
-
| `tool_call` permission gate | ❌ Not gated | Gate destructive team actions |
|
|
253
|
-
| Config-driven tool registration | ❌ Always all | Register tools per config |
|
|
254
|
-
| Working indicator | ❌ Widget only | Use `ctx.ui.setWorkingIndicator` |
|
|
255
|
-
| Session name auto-set | ❌ Manual only | Auto-name from team run context |
|
|
256
|
-
| `ctx.compact()` proactive | ❌ No monitoring | Monitor + auto-compact at threshold |
|
|
257
|
-
|
|
258
|
-
## 4. Example: Complete Tool with terminate + render
|
|
259
|
-
|
|
260
|
-
This shows a hypothetical optimized pi-crew Agent tool:
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
// OPTIMIZED Agent tool pattern
|
|
264
|
-
const AgentTool = defineTool({
|
|
265
|
-
name: "Agent",
|
|
266
|
-
label: "Agent",
|
|
267
|
-
description: "Launch a real pi-crew subagent...",
|
|
268
|
-
parameters: Type.Object({
|
|
269
|
-
prompt: Type.String(),
|
|
270
|
-
description: Type.String(),
|
|
271
|
-
subagent_type: Type.String(),
|
|
272
|
-
run_in_background: Type.Optional(Type.Boolean()),
|
|
273
|
-
}),
|
|
274
|
-
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
275
|
-
// ... spawn subagent ...
|
|
276
|
-
if (params.run_in_background) {
|
|
277
|
-
return {
|
|
278
|
-
content: [{ type: "text", text: `Agent queued. ID: ${record.id}` }],
|
|
279
|
-
details: { agentId: record.id, status: "queued" },
|
|
280
|
-
terminate: true, // ← No need for LLM follow-up
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
await record.promise;
|
|
284
|
-
const output = readResult(record);
|
|
285
|
-
return {
|
|
286
|
-
content: [{ type: "text", text: output }],
|
|
287
|
-
details: { agentId: record.id, status: record.status },
|
|
288
|
-
terminate: true, // ← Final result, save LLM turn
|
|
289
|
-
};
|
|
290
|
-
},
|
|
291
|
-
renderResult(result, { expanded }, theme) {
|
|
292
|
-
// Custom rendering with colored status icons
|
|
293
|
-
// Collapsed/expanded views
|
|
294
|
-
// Usage stats display
|
|
295
|
-
},
|
|
296
|
-
});
|
|
297
|
-
```
|
|
@@ -1,324 +0,0 @@
|
|
|
1
|
-
# Research: Pi Extension System Deep Dive
|
|
2
|
-
|
|
3
|
-
> Ngày: 2026-04-29 | Read-only research | Source: `source/pi-mono/packages/coding-agent/src/core/extensions/`
|
|
4
|
-
|
|
5
|
-
## 1. Extension System Architecture
|
|
6
|
-
|
|
7
|
-
Pi extension system là plugin framework cho coding agent. Extensions được viết bằng TypeScript,
|
|
8
|
-
load qua jiti (JIT compiler), và có thể hook vào mọi phase của agent lifecycle.
|
|
9
|
-
|
|
10
|
-
```
|
|
11
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
12
|
-
│ ExtensionAPI ("pi.*") │
|
|
13
|
-
│ Event sub: pi.on(event, handler) │
|
|
14
|
-
│ Tools: pi.registerTool(def) │
|
|
15
|
-
│ Commands: pi.registerCommand(name, opts) │
|
|
16
|
-
│ Shortcuts: pi.registerShortcut(key, opts) │
|
|
17
|
-
│ Flags: pi.registerFlag(name, opts) │
|
|
18
|
-
│ Messages: pi.sendMessage() / pi.sendUserMessage() │
|
|
19
|
-
│ State: pi.appendEntry(customType, data) │
|
|
20
|
-
│ Provider: pi.registerProvider(name, config) │
|
|
21
|
-
│ Event bus: pi.events.emit/on() │
|
|
22
|
-
│ Model: pi.setModel() / getThinkingLevel() │
|
|
23
|
-
│ Tools mgmt: pi.getActiveTools() / setActiveTools() │
|
|
24
|
-
├─────────────────────────────────────────────────────────────┤
|
|
25
|
-
│ ExtensionFactory │
|
|
26
|
-
│ (pi: ExtensionAPI) => void | Promise<void> │
|
|
27
|
-
├─────────────────────────────────────────────────────────────┤
|
|
28
|
-
│ loader.ts ──► jiti → TypeScript module loading │
|
|
29
|
-
│ runner.ts ──► ExtensionRunner → lifecycle + event emit │
|
|
30
|
-
│ types.ts ───► 1545 dòng type definitions │
|
|
31
|
-
└─────────────────────────────────────────────────────────────┘
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## 2. Extension Loading Flow
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
discoverAndLoadExtensions(cwd, agentDir, extensionPaths)
|
|
38
|
-
├── Scan directories:
|
|
39
|
-
│ ├── ~/.pi/agent/extensions/**/index.ts (user-global)
|
|
40
|
-
│ ├── .pi/extensions/**/index.ts (project-local)
|
|
41
|
-
│ └── CLI --extension paths (explicit)
|
|
42
|
-
├── Create ExtensionRuntime (shared state + action stubs)
|
|
43
|
-
├── For each extension file:
|
|
44
|
-
│ ├── jiti.import(path) # Load TS module
|
|
45
|
-
│ ├── Call default export: factory(pi) # Register handlers/tools/commands
|
|
46
|
-
│ └── Collect into Extension object
|
|
47
|
-
└── Return LoadExtensionsResult
|
|
48
|
-
|
|
49
|
-
ExtensionRunner.initialize(session, context, actions)
|
|
50
|
-
├── Bind real action implementations to runtime
|
|
51
|
-
├── Process queued provider registrations
|
|
52
|
-
└── Emit session_start event
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### 2.1 Discovery priority
|
|
56
|
-
|
|
57
|
-
Project-local > user-global. Extensions cùng tên: project override user.
|
|
58
|
-
|
|
59
|
-
### 2.2 Runtime replacement (reload)
|
|
60
|
-
|
|
61
|
-
Khi `/reload` hoặc session switch:
|
|
62
|
-
1. `emitSessionShutdownEvent("reload")`
|
|
63
|
-
2. Invalidate old ExtensionRuntime (throws if stale extension tries to act)
|
|
64
|
-
3. Re-discover + re-load tất cả extensions
|
|
65
|
-
4. Re-initialize ExtensionRunner
|
|
66
|
-
|
|
67
|
-
## 3. Full Event Lifecycle
|
|
68
|
-
|
|
69
|
-
### 3.1 Event model (23 event types)
|
|
70
|
-
|
|
71
|
-
**Session events** — session-level lifecycle:
|
|
72
|
-
```
|
|
73
|
-
session_start ← Khi session được tạo/load/reload
|
|
74
|
-
resources_discover ← Extension có thể inject thêm paths
|
|
75
|
-
session_before_switch ← Trước khi switch session (có thể cancel)
|
|
76
|
-
session_before_fork ← Trước khi fork session (có thể cancel)
|
|
77
|
-
session_before_compact ← Trước khi compaction (có thể cancel hoặc custom)
|
|
78
|
-
session_compact ← Sau khi compaction hoàn tất
|
|
79
|
-
session_before_tree ← Trước khi navigate tree (có thể cancel)
|
|
80
|
-
session_tree ← Sau khi navigate tree
|
|
81
|
-
session_shutdown ← Khi session bị hủy (quit/reload/new/resume/fork)
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**Agent events** — per-prompt:
|
|
85
|
-
```
|
|
86
|
-
input ← Khi user input received (có thể transform/block)
|
|
87
|
-
before_agent_start ← Trước khi agent loop chạy (inject custom message / swap system prompt)
|
|
88
|
-
context ← Transform messages trước khi gửi LLM
|
|
89
|
-
before_provider_request ← Thay đổi payload trước khi gửi provider
|
|
90
|
-
after_provider_response ← Quan sát response status/headers
|
|
91
|
-
agent_start ← Agent loop bắt đầu
|
|
92
|
-
agent_end ← Agent loop kết thúc
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Turn events** — per-turn:
|
|
96
|
-
```
|
|
97
|
-
turn_start ← Bắt đầu turn mới
|
|
98
|
-
turn_end ← Kết thúc turn (có message + tool results)
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
**Message events** — per-message:
|
|
102
|
-
```
|
|
103
|
-
message_start ← Message bắt đầu (user/assistant/toolResult)
|
|
104
|
-
message_update ← Streaming token-by-token update
|
|
105
|
-
message_end ← Message hoàn tất
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
**Tool events** — per-tool:
|
|
109
|
-
```
|
|
110
|
-
tool_call ← Trước khi tool execute (có thể block/mutate args)
|
|
111
|
-
tool_execution_start ← Tool bắt đầu chạy
|
|
112
|
-
tool_execution_update ← Partial/streaming result
|
|
113
|
-
tool_execution_end ← Tool hoàn tất
|
|
114
|
-
tool_result ← Sau khi tool execute (có thể modify result)
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
**Other:**
|
|
118
|
-
```
|
|
119
|
-
model_select ← Khi model được chọn/thay đổi
|
|
120
|
-
user_bash ← Khi user dùng ! prefix cho bash
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### 3.2 Event result contracts
|
|
124
|
-
|
|
125
|
-
Mỗi event có thể return result để ảnh hưởng đến behavior:
|
|
126
|
-
|
|
127
|
-
| Event | Result type | Effect |
|
|
128
|
-
|---|---|---|
|
|
129
|
-
| `input` | `{ action: "continue" \| "transform" \| "handled" }` | Transform/block input |
|
|
130
|
-
| `before_agent_start` | `{ message?, systemPrompt? }` | Inject custom message, swap system prompt |
|
|
131
|
-
| `context` | `{ messages? }` | Replace context messages |
|
|
132
|
-
| `before_provider_request` | `any` | Replace payload |
|
|
133
|
-
| `tool_call` | `{ block?, reason? }` | Block tool execution |
|
|
134
|
-
| `tool_result` | `{ content?, details?, isError? }` | Modify result |
|
|
135
|
-
| `user_bash` | `{ operations?, result? }` | Custom bash execution |
|
|
136
|
-
| `session_before_*` | `{ cancel? }` | Cancel session operation |
|
|
137
|
-
| `session_before_compact` | `{ cancel?, compaction? }` | Cancel or custom compact |
|
|
138
|
-
| `session_before_tree` | `{ cancel?, summary?, customInstructions? }` | Cancel or custom summary |
|
|
139
|
-
| `resources_discover` | `{ skillPaths?, promptPaths?, themePaths? }` | Inject resource paths |
|
|
140
|
-
|
|
141
|
-
## 4. Context Objects Available to Extensions
|
|
142
|
-
|
|
143
|
-
### 4.1 ExtensionContext (`ctx.*`) — có sẵn trong mọi event handler
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
interface ExtensionContext {
|
|
147
|
-
ui: ExtensionUIContext; // UI methods (select, confirm, notify, widgets...)
|
|
148
|
-
hasUI: boolean; // false in print/RPC mode
|
|
149
|
-
cwd: string; // Current working directory
|
|
150
|
-
sessionManager: ReadonlySessionManager; // Session access (read-only)
|
|
151
|
-
modelRegistry: ModelRegistry; // Auth + model discovery
|
|
152
|
-
model: Model<any> | undefined; // Current model
|
|
153
|
-
isIdle(): boolean; // Check if agent is streaming
|
|
154
|
-
signal: AbortSignal | undefined;// Current abort signal
|
|
155
|
-
abort(): void; // Abort current operation
|
|
156
|
-
hasPendingMessages(): boolean; // Check message queue
|
|
157
|
-
shutdown(): void; // Graceful shutdown
|
|
158
|
-
getContextUsage(): ContextUsage | undefined; // Token usage
|
|
159
|
-
compact(options?): void; // Trigger compaction
|
|
160
|
-
getSystemPrompt(): string; // Current system prompt
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### 4.2 ExtensionCommandContext — extends Context, chỉ trong command handler
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
interface ExtensionCommandContext extends ExtensionContext {
|
|
168
|
-
waitForIdle(): Promise<void>; // Wait for agent to finish
|
|
169
|
-
newSession(options?): Promise<{cancelled}>;
|
|
170
|
-
fork(entryId, options?): Promise<{cancelled}>;
|
|
171
|
-
navigateTree(targetId, options?): Promise<{cancelled}>;
|
|
172
|
-
switchSession(sessionPath, options?): Promise<{cancelled}>;
|
|
173
|
-
reload(): Promise<void>;
|
|
174
|
-
}
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### 4.3 ReplacedSessionContext — sau khi switch/new session
|
|
178
|
-
|
|
179
|
-
```typescript
|
|
180
|
-
interface ReplacedSessionContext extends ExtensionCommandContext {
|
|
181
|
-
sendMessage(message, options?): Promise<void>;
|
|
182
|
-
sendUserMessage(content, options?): Promise<void>;
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### 4.4 ExtensionUIContext (`ctx.ui.*`) — chỉ khi `hasUI=true`
|
|
187
|
-
|
|
188
|
-
```typescript
|
|
189
|
-
interface ExtensionUIContext {
|
|
190
|
-
select(title, options, opts?): Promise<string | undefined>;
|
|
191
|
-
confirm(title, message, opts?): Promise<boolean>;
|
|
192
|
-
input(title, placeholder?, opts?): Promise<string | undefined>;
|
|
193
|
-
notify(message, type?): void;
|
|
194
|
-
custom<T>(factory, options?): Promise<T>; // Custom overlay component
|
|
195
|
-
setWidget(key, content, options?): void; // Widget above/below editor
|
|
196
|
-
setFooter(factory): void; // Custom footer
|
|
197
|
-
setHeader(factory): void; // Custom header
|
|
198
|
-
setEditorComponent(factory): void; // Custom editor
|
|
199
|
-
setStatus(key, text): void; // Status bar
|
|
200
|
-
setTitle(title): void; // Terminal title
|
|
201
|
-
setWorkingMessage(message?): void; // Working loader text
|
|
202
|
-
setWorkingVisible(visible): void; // Show/hide loader
|
|
203
|
-
setWorkingIndicator(options?): void; // Custom loader animation
|
|
204
|
-
setHiddenThinkingLabel(label?): void; // Thinking block label
|
|
205
|
-
onTerminalInput(handler): () => void; // Raw terminal input
|
|
206
|
-
getToolsExpanded(): boolean;
|
|
207
|
-
setToolsExpanded(expanded): void;
|
|
208
|
-
theme: Theme;
|
|
209
|
-
getAllThemes(): {name, path}[];
|
|
210
|
-
getTheme(name): Theme | undefined;
|
|
211
|
-
setTheme(theme): {success, error?};
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
## 5. ToolDefinition Contract
|
|
216
|
-
|
|
217
|
-
```typescript
|
|
218
|
-
interface ToolDefinition<TParams extends TSchema, TDetails = unknown, TState = any> {
|
|
219
|
-
name: string; // Unique tool name
|
|
220
|
-
label: string; // Human-readable for UI
|
|
221
|
-
description: string; // For LLM
|
|
222
|
-
parameters: TParams; // TypeBox schema
|
|
223
|
-
promptSnippet?: string; // 1-line for system prompt "Available tools"
|
|
224
|
-
promptGuidelines?: string[]; // Bullets for system prompt "Guidelines"
|
|
225
|
-
renderShell?: "default" | "self"; // Who renders the outer frame
|
|
226
|
-
executionMode?: "sequential" | "parallel"; // Concurrency control
|
|
227
|
-
prepareArguments?: (args: unknown) => Static<TParams>;
|
|
228
|
-
|
|
229
|
-
// Core execution
|
|
230
|
-
execute(
|
|
231
|
-
toolCallId: string,
|
|
232
|
-
params: Static<TParams>,
|
|
233
|
-
signal: AbortSignal | undefined,
|
|
234
|
-
onUpdate: AgentToolUpdateCallback<TDetails> | undefined,
|
|
235
|
-
ctx: ExtensionContext,
|
|
236
|
-
): Promise<AgentToolResult<TDetails>>;
|
|
237
|
-
|
|
238
|
-
// Rendering (optional)
|
|
239
|
-
renderCall?(args, theme, context): Component; // Custom call display
|
|
240
|
-
renderResult?(result, options, theme, context): Component; // Custom result display
|
|
241
|
-
}
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### 5.1 `terminate: true` pattern
|
|
245
|
-
|
|
246
|
-
Tool có thể set `terminate: true` trong result để kết thúc turn ngay sau tool call,
|
|
247
|
-
tiết kiệm 1 follow-up LLM turn:
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
return {
|
|
251
|
-
content: [{ type: "text", text: "Done" }],
|
|
252
|
-
details: { ... },
|
|
253
|
-
terminate: true, // ← Kết thúc turn, không cần LLM follow-up
|
|
254
|
-
};
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
## 6. Provider Registration
|
|
258
|
-
|
|
259
|
-
Extension có thể đăng ký provider tùy chỉnh:
|
|
260
|
-
|
|
261
|
-
```typescript
|
|
262
|
-
pi.registerProvider("my-provider", {
|
|
263
|
-
baseUrl: "https://api.example.com",
|
|
264
|
-
apiKey: "PROVIDER_API_KEY",
|
|
265
|
-
api: "anthropic-messages",
|
|
266
|
-
models: [{
|
|
267
|
-
id: "my-model",
|
|
268
|
-
name: "My Model",
|
|
269
|
-
reasoning: false,
|
|
270
|
-
input: ["text", "image"],
|
|
271
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
272
|
-
contextWindow: 200000,
|
|
273
|
-
maxTokens: 16384,
|
|
274
|
-
}],
|
|
275
|
-
// Optional OAuth:
|
|
276
|
-
oauth: {
|
|
277
|
-
name: "My Provider (SSO)",
|
|
278
|
-
async login(callbacks) { ... },
|
|
279
|
-
async refreshToken(credentials) { ... },
|
|
280
|
-
getApiKey(credentials) { return credentials.access; },
|
|
281
|
-
},
|
|
282
|
-
});
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
Hiệu lực ngay lập tức sau `session_start` (không cần `/reload`).
|
|
286
|
-
|
|
287
|
-
## 7. API Comparison: ExtensionAPI vs ExtensionContext
|
|
288
|
-
|
|
289
|
-
| Capability | `pi.*` (ExtensionAPI) | `ctx.*` (ExtensionContext) |
|
|
290
|
-
|---|---|---|
|
|
291
|
-
| Subscribe events | ✅ `pi.on(...)` | ❌ |
|
|
292
|
-
| Register tools | ✅ `pi.registerTool()` | ❌ |
|
|
293
|
-
| Register commands | ✅ `pi.registerCommand()` | ❌ |
|
|
294
|
-
| Register shortcuts | ✅ `pi.registerShortcut()` | ❌ |
|
|
295
|
-
| Register flags | ✅ `pi.registerFlag()` | ❌ |
|
|
296
|
-
| Register providers | ✅ `pi.registerProvider()` | ❌ |
|
|
297
|
-
| Send messages | ✅ `pi.sendMessage()` | ❌ |
|
|
298
|
-
| Send user messages | ✅ `pi.sendUserMessage()` | ❌ |
|
|
299
|
-
| Append entries | ✅ `pi.appendEntry()` | ❌ |
|
|
300
|
-
| Session name | ✅ `pi.setSessionName()` / `getSessionName()` | ❌ |
|
|
301
|
-
| Event bus | ✅ `pi.events` | ❌ |
|
|
302
|
-
| Get/set active tools | ✅ `pi.getActiveTools()` / `setActiveTools()` | ❌ |
|
|
303
|
-
| Get model | ❌ (register-time only) | ✅ `ctx.model` |
|
|
304
|
-
| Check idle | ❌ | ✅ `ctx.isIdle()` |
|
|
305
|
-
| Abort | ❌ | ✅ `ctx.abort()` |
|
|
306
|
-
| Trigger compaction | ❌ | ✅ `ctx.compact()` |
|
|
307
|
-
| Context usage | ❌ | ✅ `ctx.getContextUsage()` |
|
|
308
|
-
| System prompt | ❌ | ✅ `ctx.getSystemPrompt()` |
|
|
309
|
-
| Session manager | ❌ | ✅ `ctx.sessionManager` |
|
|
310
|
-
| UI interaction | ❌ | ✅ `ctx.ui` |
|
|
311
|
-
| Session control | ❌ | ✅ `ctx.newSession()` / `fork()` (command ctx) |
|
|
312
|
-
|
|
313
|
-
**Rule of thumb:**
|
|
314
|
-
- `pi.*`: Registration-time API (trong factory function, `session_start`)
|
|
315
|
-
- `ctx.*`: Runtime API (trong event handlers, command handlers)
|
|
316
|
-
|
|
317
|
-
## 8. Key Design Decisions
|
|
318
|
-
|
|
319
|
-
1. **No sandbox** — Extensions run in same Node.js process, full system access
|
|
320
|
-
2. **jiti loader** — TypeScript extensions compiled JIT, no build step
|
|
321
|
-
3. **Virtual modules** — For Bun compiled binary, built-in dependencies bundled
|
|
322
|
-
4. **Throwing stubs** — Runtime actions start as stubs, real implementations bound by runner
|
|
323
|
-
5. **Stale detection** — After reload, old extension instances throw on any API call
|
|
324
|
-
6. **Event bus** — Separate from extension events, for cross-extension communication
|