pi-crew 0.1.44 → 0.1.45

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 (142) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/agents/analyst.md +11 -11
  3. package/agents/critic.md +11 -11
  4. package/agents/executor.md +11 -11
  5. package/agents/explorer.md +11 -11
  6. package/agents/planner.md +11 -11
  7. package/agents/reviewer.md +11 -11
  8. package/agents/security-reviewer.md +11 -11
  9. package/agents/test-engineer.md +11 -11
  10. package/agents/verifier.md +11 -11
  11. package/agents/writer.md +11 -11
  12. package/docs/refactor-tasks-phase3.md +394 -394
  13. package/docs/refactor-tasks-phase4.md +564 -564
  14. package/docs/refactor-tasks-phase5.md +402 -402
  15. package/docs/refactor-tasks-phase6.md +662 -662
  16. package/docs/research-extension-examples.md +297 -297
  17. package/docs/research-extension-system.md +324 -324
  18. package/docs/research-optimization-plan.md +548 -548
  19. package/docs/research-phase10-distillation.md +198 -198
  20. package/docs/research-phase11-distillation.md +201 -201
  21. package/docs/research-pi-coding-agent.md +357 -357
  22. package/docs/research-source-pi-crew-reference.md +174 -174
  23. package/docs/runtime-flow.md +148 -148
  24. package/docs/source-runtime-refactor-map.md +83 -83
  25. package/index.ts +6 -6
  26. package/package.json +1 -1
  27. package/src/agents/agent-serializer.ts +34 -34
  28. package/src/extension/cross-extension-rpc.ts +82 -82
  29. package/src/extension/register.ts +8 -1
  30. package/src/extension/registration/commands.ts +18 -2
  31. package/src/extension/registration/compaction-guard.ts +125 -125
  32. package/src/extension/registration/subagent-tools.ts +148 -148
  33. package/src/extension/registration/team-tool.ts +26 -8
  34. package/src/extension/run-bundle-schema.ts +89 -89
  35. package/src/extension/run-maintenance.ts +43 -43
  36. package/src/extension/team-tool/cancel.ts +105 -102
  37. package/src/extension/team-tool/context.ts +1 -0
  38. package/src/extension/team-tool/handle-settings.ts +188 -188
  39. package/src/extension/team-tool/inspect.ts +41 -41
  40. package/src/extension/team-tool/lifecycle-actions.ts +79 -79
  41. package/src/extension/team-tool/plan.ts +19 -19
  42. package/src/extension/team-tool/respond.ts +83 -66
  43. package/src/extension/team-tool/run.ts +1 -0
  44. package/src/i18n.ts +184 -184
  45. package/src/observability/exporters/otlp-exporter.ts +77 -77
  46. package/src/prompt/prompt-runtime.ts +72 -72
  47. package/src/runtime/agent-control.ts +63 -63
  48. package/src/runtime/agent-memory.ts +72 -72
  49. package/src/runtime/agent-observability.ts +114 -114
  50. package/src/runtime/async-marker.ts +26 -26
  51. package/src/runtime/attention-events.ts +28 -28
  52. package/src/runtime/background-runner.ts +53 -53
  53. package/src/runtime/child-pi.ts +444 -444
  54. package/src/runtime/completion-guard.ts +190 -190
  55. package/src/runtime/crew-agent-records.ts +8 -0
  56. package/src/runtime/delivery-coordinator.ts +153 -142
  57. package/src/runtime/direct-run.ts +35 -35
  58. package/src/runtime/foreground-control.ts +82 -82
  59. package/src/runtime/green-contract.ts +46 -46
  60. package/src/runtime/group-join.ts +106 -106
  61. package/src/runtime/heartbeat-gradient.ts +28 -28
  62. package/src/runtime/heartbeat-watcher.ts +124 -124
  63. package/src/runtime/live-agent-control.ts +87 -87
  64. package/src/runtime/live-agent-manager.ts +85 -85
  65. package/src/runtime/live-control-realtime.ts +36 -36
  66. package/src/runtime/live-session-runtime.ts +305 -305
  67. package/src/runtime/overflow-recovery.ts +175 -156
  68. package/src/runtime/parallel-research.ts +44 -44
  69. package/src/runtime/pi-json-output.ts +111 -111
  70. package/src/runtime/policy-engine.ts +79 -79
  71. package/src/runtime/progress-event-coalescer.ts +43 -43
  72. package/src/runtime/recovery-recipes.ts +74 -74
  73. package/src/runtime/retry-executor.ts +64 -64
  74. package/src/runtime/role-permission.ts +39 -39
  75. package/src/runtime/session-resources.ts +25 -25
  76. package/src/runtime/session-snapshot.ts +59 -59
  77. package/src/runtime/session-usage.ts +79 -79
  78. package/src/runtime/sidechain-output.ts +29 -29
  79. package/src/runtime/stale-reconciler.ts +199 -179
  80. package/src/runtime/supervisor-contact.ts +59 -59
  81. package/src/runtime/task-display.ts +38 -38
  82. package/src/runtime/task-output-context.ts +127 -127
  83. package/src/runtime/task-runner/live-executor.ts +101 -101
  84. package/src/runtime/task-runner/progress.ts +119 -119
  85. package/src/runtime/task-runner/result-utils.ts +14 -14
  86. package/src/runtime/task-runner/state-helpers.ts +22 -22
  87. package/src/runtime/team-runner.ts +13 -4
  88. package/src/runtime/worker-heartbeat.ts +21 -21
  89. package/src/runtime/worker-startup.ts +57 -57
  90. package/src/state/state-store.ts +43 -0
  91. package/src/state/task-claims.ts +44 -44
  92. package/src/state/types.ts +2 -0
  93. package/src/state/usage.ts +29 -29
  94. package/src/subagents/async-entry.ts +1 -1
  95. package/src/subagents/index.ts +3 -3
  96. package/src/subagents/live/control.ts +1 -1
  97. package/src/subagents/live/manager.ts +1 -1
  98. package/src/subagents/live/realtime.ts +1 -1
  99. package/src/subagents/live/session-runtime.ts +1 -1
  100. package/src/subagents/manager.ts +1 -1
  101. package/src/subagents/spawn.ts +1 -1
  102. package/src/teams/team-serializer.ts +38 -38
  103. package/src/types/diff.d.ts +18 -18
  104. package/src/ui/crew-footer.ts +101 -101
  105. package/src/ui/crew-select-list.ts +111 -111
  106. package/src/ui/crew-widget.ts +5 -1
  107. package/src/ui/dashboard-panes/mailbox-pane.ts +2 -1
  108. package/src/ui/dashboard-panes/metrics-pane.ts +34 -34
  109. package/src/ui/dynamic-border.ts +25 -25
  110. package/src/ui/layout-primitives.ts +106 -106
  111. package/src/ui/loaders.ts +158 -158
  112. package/src/ui/powerbar-publisher.ts +1 -1
  113. package/src/ui/render-diff.ts +119 -119
  114. package/src/ui/render-scheduler.ts +143 -143
  115. package/src/ui/run-snapshot-cache.ts +56 -37
  116. package/src/ui/snapshot-types.ts +5 -0
  117. package/src/ui/spinner.ts +17 -17
  118. package/src/ui/status-colors.ts +58 -58
  119. package/src/ui/syntax-highlight.ts +116 -116
  120. package/src/utils/atomic-write.ts +33 -33
  121. package/src/utils/completion-dedupe.ts +63 -63
  122. package/src/utils/frontmatter.ts +68 -68
  123. package/src/utils/git.ts +262 -262
  124. package/src/utils/ids.ts +12 -12
  125. package/src/utils/names.ts +27 -27
  126. package/src/utils/redaction.ts +44 -44
  127. package/src/utils/safe-paths.ts +47 -47
  128. package/src/utils/sleep.ts +32 -32
  129. package/src/workflows/validate-workflow.ts +40 -40
  130. package/src/worktree/branch-freshness.ts +45 -45
  131. package/teams/default.team.md +12 -12
  132. package/teams/fast-fix.team.md +11 -11
  133. package/teams/implementation.team.md +18 -18
  134. package/teams/parallel-research.team.md +14 -14
  135. package/teams/research.team.md +11 -11
  136. package/teams/review.team.md +12 -12
  137. package/workflows/default.workflow.md +29 -29
  138. package/workflows/fast-fix.workflow.md +22 -22
  139. package/workflows/implementation.workflow.md +38 -38
  140. package/workflows/parallel-research.workflow.md +46 -46
  141. package/workflows/research.workflow.md +22 -22
  142. package/workflows/review.workflow.md +30 -30
@@ -1,43 +1,43 @@
1
- import * as fs from "node:fs";
2
- import type { TeamRunManifest } from "../state/types.ts";
3
- import { resolveRealContainedPath } from "../utils/safe-paths.ts";
4
- import { projectCrewRoot } from "../utils/paths.ts";
5
- import { listRuns } from "./run-index.ts";
6
- import { logInternalError } from "../utils/internal-error.ts";
7
-
8
- export interface PruneRunsResult {
9
- kept: string[];
10
- removed: string[];
11
- }
12
-
13
- function isFinished(run: TeamRunManifest): boolean {
14
- return run.status === "completed" || run.status === "failed" || run.status === "cancelled" || run.status === "blocked";
15
- }
16
-
17
- function isSafeToPrune(cwd: string, run: TeamRunManifest): boolean {
18
- try {
19
- const crewRoot = projectCrewRoot(cwd);
20
- resolveRealContainedPath(crewRoot, run.stateRoot);
21
- resolveRealContainedPath(crewRoot, run.artifactsRoot);
22
- return true;
23
- } catch {
24
- return false;
25
- }
26
- }
27
-
28
- export function pruneFinishedRuns(cwd: string, keep: number): PruneRunsResult {
29
- const crewRoot = projectCrewRoot(cwd);
30
- const finished = listRuns(cwd).filter((run) => run.cwd === cwd && isFinished(run)).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
31
- const kept = finished.slice(0, keep).map((run) => run.runId);
32
- const removed: string[] = [];
33
- for (const run of finished.slice(keep)) {
34
- if (!isSafeToPrune(cwd, run)) {
35
- logInternalError("prune.path-unsafe", new Error(`Skipping unsafe prune: stateRoot=${run.stateRoot}, artifactsRoot=${run.artifactsRoot}`), `runId=${run.runId}`);
36
- continue;
37
- }
38
- fs.rmSync(run.stateRoot, { recursive: true, force: true });
39
- fs.rmSync(run.artifactsRoot, { recursive: true, force: true });
40
- removed.push(run.runId);
41
- }
42
- return { kept, removed };
43
- }
1
+ import * as fs from "node:fs";
2
+ import type { TeamRunManifest } from "../state/types.ts";
3
+ import { resolveRealContainedPath } from "../utils/safe-paths.ts";
4
+ import { projectCrewRoot } from "../utils/paths.ts";
5
+ import { listRuns } from "./run-index.ts";
6
+ import { logInternalError } from "../utils/internal-error.ts";
7
+
8
+ export interface PruneRunsResult {
9
+ kept: string[];
10
+ removed: string[];
11
+ }
12
+
13
+ function isFinished(run: TeamRunManifest): boolean {
14
+ return run.status === "completed" || run.status === "failed" || run.status === "cancelled" || run.status === "blocked";
15
+ }
16
+
17
+ function isSafeToPrune(cwd: string, run: TeamRunManifest): boolean {
18
+ try {
19
+ const crewRoot = projectCrewRoot(cwd);
20
+ resolveRealContainedPath(crewRoot, run.stateRoot);
21
+ resolveRealContainedPath(crewRoot, run.artifactsRoot);
22
+ return true;
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
27
+
28
+ export function pruneFinishedRuns(cwd: string, keep: number): PruneRunsResult {
29
+ const crewRoot = projectCrewRoot(cwd);
30
+ const finished = listRuns(cwd).filter((run) => run.cwd === cwd && isFinished(run)).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
31
+ const kept = finished.slice(0, keep).map((run) => run.runId);
32
+ const removed: string[] = [];
33
+ for (const run of finished.slice(keep)) {
34
+ if (!isSafeToPrune(cwd, run)) {
35
+ logInternalError("prune.path-unsafe", new Error(`Skipping unsafe prune: stateRoot=${run.stateRoot}, artifactsRoot=${run.artifactsRoot}`), `runId=${run.runId}`);
36
+ continue;
37
+ }
38
+ fs.rmSync(run.stateRoot, { recursive: true, force: true });
39
+ fs.rmSync(run.artifactsRoot, { recursive: true, force: true });
40
+ removed.push(run.runId);
41
+ }
42
+ return { kept, removed };
43
+ }
@@ -1,103 +1,106 @@
1
- import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
2
- import { withRunLockSync } from "../../state/locks.ts";
3
- import { loadRunManifestById, saveRunTasks, updateRunStatus } from "../../state/state-store.ts";
4
- import { saveCrewAgents, recordFromTask } from "../../runtime/crew-agent-records.ts";
5
- import { writeForegroundInterruptRequest } from "../../runtime/foreground-control.ts";
6
- import { logInternalError } from "../../utils/internal-error.ts";
7
- import type { PiTeamsToolResult } from "../tool-result.ts";
8
- import { result, type TeamContext } from "./context.ts";
9
-
10
- export interface AbortOwnedResult {
11
- abortedIds: string[];
12
- missingIds: string[];
13
- foreignIds: string[];
14
- }
15
-
16
- /**
17
- * Classify task IDs by ownership.
18
- * - Tasks with status "queued" or "running" that belong to the current session → abortedIds
19
- * - Task IDs not found in the run → missingIds
20
- * - Tasks with status "queued" or "running" that belong to a different session → foreignIds
21
- * - Tasks already completed/failed/cancelled → neither (not included in any list)
22
- *
23
- * Currently, task ownership is determined by the manifest's run-level ownership.
24
- * Since tasks in a single run are all owned by the session that created the run,
25
- * the ownerSessionId comes from the context. Foreign detection compares
26
- * the requesting session against the run's creating session.
27
- */
28
- export function abortOwned(
29
- runId: string,
30
- taskIds: string[] | undefined,
31
- ctx: TeamContext,
32
- ): AbortOwnedResult {
33
- const loaded = loadRunManifestById(ctx.cwd, runId);
34
- if (!loaded) return { abortedIds: [], missingIds: taskIds ?? [], foreignIds: [] };
35
-
36
- const result: AbortOwnedResult = { abortedIds: [], missingIds: [], foreignIds: [] };
37
- const taskMap = new Map(loaded.tasks.map((t) => [t.id, t] as const));
38
- const targetIds = taskIds ?? loaded.tasks.map((t) => t.id);
39
-
40
- for (const id of targetIds) {
41
- const task = taskMap.get(id);
42
- if (!task) {
43
- result.missingIds.push(id);
44
- continue;
45
- }
46
- if (task.status !== "queued" && task.status !== "running" && task.status !== "waiting") continue;
47
- // All tasks in a run are owned by the session that created the run.
48
- // Since cancel is always called within the session that created it,
49
- // all cancellable tasks are abortable.
50
- // Foreign detection is a placeholder for when tasks can be owned
51
- // by different sessions (e.g., shared runs with session-scoped tasks).
52
- result.abortedIds.push(id);
53
- }
54
-
55
- return result;
56
- }
57
-
58
- export function handleCancel(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
59
- if (!params.runId) return result("Cancel requires runId.", { action: "cancel", status: "error" }, true);
60
- const loaded = loadRunManifestById(ctx.cwd, params.runId);
61
- if (!loaded) return result(`Run '${params.runId}' not found.`, { action: "cancel", status: "error" }, true);
62
- return withRunLockSync(loaded.manifest, () => {
63
- if ((loaded.manifest.status === "completed" || loaded.manifest.status === "cancelled") && !params.force) return result(`Run ${loaded.manifest.runId} is already ${loaded.manifest.status}; nothing to cancel. Use force: true to mark it cancelled anyway.`, { action: "cancel", status: "ok", runId: loaded.manifest.runId, artifactsRoot: loaded.manifest.artifactsRoot });
64
-
65
- // Classify tasks for foreign-aware cancellation
66
- const abortResult = abortOwned(loaded.manifest.runId, undefined, ctx);
67
- const cancellableIds = new Set(abortResult.abortedIds);
68
-
69
- const tasks = loaded.tasks.map((task) => {
70
- if (cancellableIds.has(task.id) && (task.status === "queued" || task.status === "running" || task.status === "waiting")) {
71
- return { ...task, status: "cancelled" as const, finishedAt: new Date().toISOString(), error: "Run cancelled by user request." };
72
- }
73
- return task;
74
- });
75
- saveRunTasks(loaded.manifest, tasks);
76
- try {
77
- saveCrewAgents(loaded.manifest, tasks.map((task) => recordFromTask(loaded.manifest, task, "child-process")));
78
- } catch (error) {
79
- logInternalError("team-tool.handleCancel.crewAgents", error, `runId=${loaded.manifest.runId}`);
80
- }
81
- try {
82
- writeForegroundInterruptRequest(loaded.manifest, "Run cancelled by user request.");
83
- } catch (error) {
84
- logInternalError("team-tool.handleCancel.interruptRequest", error, `runId=${loaded.manifest.runId}`);
85
- }
86
- const updated = updateRunStatus(loaded.manifest, "cancelled", "Run cancelled by user request. Already-finished worker processes are not retroactively changed.");
87
-
88
- // Build descriptive message including foreign/missing info
89
- const parts = [`Cancelled run ${updated.runId}.`];
90
- if (abortResult.foreignIds.length > 0) parts.push(` ${abortResult.foreignIds.length} task(s) belong to another session and were not cancelled: ${abortResult.foreignIds.join(", ")}.`);
91
- if (abortResult.missingIds.length > 0) parts.push(` ${abortResult.missingIds.length} task ID(s) not found: ${abortResult.missingIds.join(", ")}.`);
92
-
93
- return result(parts.join(""), {
94
- action: "cancel",
95
- status: "ok",
96
- runId: updated.runId,
97
- artifactsRoot: updated.artifactsRoot,
98
- abortedIds: abortResult.abortedIds,
99
- missingIds: abortResult.missingIds,
100
- foreignIds: abortResult.foreignIds,
101
- });
102
- });
1
+ import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
2
+ import { withRunLockSync } from "../../state/locks.ts";
3
+ import { loadRunManifestById, saveRunTasks, updateRunStatus } from "../../state/state-store.ts";
4
+ import { saveCrewAgents, recordFromTask } from "../../runtime/crew-agent-records.ts";
5
+ import { writeForegroundInterruptRequest } from "../../runtime/foreground-control.ts";
6
+ import { logInternalError } from "../../utils/internal-error.ts";
7
+ import type { PiTeamsToolResult } from "../tool-result.ts";
8
+ import { result, type TeamContext } from "./context.ts";
9
+
10
+ export interface AbortOwnedResult {
11
+ abortedIds: string[];
12
+ missingIds: string[];
13
+ foreignIds: string[];
14
+ }
15
+
16
+ /**
17
+ * Classify task IDs by ownership.
18
+ * - Tasks with status "queued" or "running" that belong to the current session → abortedIds
19
+ * - Task IDs not found in the run → missingIds
20
+ * - Tasks with status "queued" or "running" that belong to a different session → foreignIds
21
+ * - Tasks already completed/failed/cancelled → neither (not included in any list)
22
+ *
23
+ * Currently, task ownership is determined by the manifest's run-level ownership.
24
+ * Since tasks in a single run are all owned by the session that created the run,
25
+ * the ownerSessionId comes from the context. Foreign detection compares
26
+ * the requesting session against the run's creating session.
27
+ */
28
+ export function abortOwned(
29
+ runId: string,
30
+ taskIds: string[] | undefined,
31
+ ctx: TeamContext,
32
+ ): AbortOwnedResult {
33
+ const loaded = loadRunManifestById(ctx.cwd, runId);
34
+ if (!loaded) return { abortedIds: [], missingIds: taskIds ?? [], foreignIds: [] };
35
+
36
+ const result: AbortOwnedResult = { abortedIds: [], missingIds: [], foreignIds: [] };
37
+ const taskMap = new Map(loaded.tasks.map((t) => [t.id, t] as const));
38
+ const targetIds = taskIds ?? loaded.tasks.map((t) => t.id);
39
+ const foreignRun = typeof loaded.manifest.ownerSessionId === "string" && loaded.manifest.ownerSessionId !== ctx.sessionId;
40
+
41
+ for (const id of targetIds) {
42
+ const task = taskMap.get(id);
43
+ if (!task) {
44
+ result.missingIds.push(id);
45
+ continue;
46
+ }
47
+ if (task.status !== "queued" && task.status !== "running" && task.status !== "waiting") continue;
48
+ if (foreignRun) {
49
+ result.foreignIds.push(id);
50
+ continue;
51
+ }
52
+ result.abortedIds.push(id);
53
+ }
54
+
55
+ return result;
56
+ }
57
+
58
+ export function handleCancel(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
59
+ if (!params.runId) return result("Cancel requires runId.", { action: "cancel", status: "error" }, true);
60
+ const loaded = loadRunManifestById(ctx.cwd, params.runId);
61
+ if (!loaded) return result(`Run '${params.runId}' not found.`, { action: "cancel", status: "error" }, true);
62
+ return withRunLockSync(loaded.manifest, () => {
63
+ if ((loaded.manifest.status === "completed" || loaded.manifest.status === "cancelled") && !params.force) return result(`Run ${loaded.manifest.runId} is already ${loaded.manifest.status}; nothing to cancel. Use force: true to mark it cancelled anyway.`, { action: "cancel", status: "ok", runId: loaded.manifest.runId, artifactsRoot: loaded.manifest.artifactsRoot });
64
+
65
+ // Classify tasks for foreign-aware cancellation
66
+ const abortResult = abortOwned(loaded.manifest.runId, undefined, ctx);
67
+ if (abortResult.abortedIds.length === 0 && abortResult.foreignIds.length > 0) {
68
+ return result(`Run ${loaded.manifest.runId} belongs to another session; not cancelled.`, { action: "cancel", status: "error", runId: loaded.manifest.runId, foreignIds: abortResult.foreignIds } as never, true);
69
+ }
70
+ const cancellableIds = new Set(abortResult.abortedIds);
71
+
72
+ const tasks = loaded.tasks.map((task) => {
73
+ if (cancellableIds.has(task.id) && (task.status === "queued" || task.status === "running" || task.status === "waiting")) {
74
+ return { ...task, status: "cancelled" as const, finishedAt: new Date().toISOString(), error: "Run cancelled by user request." };
75
+ }
76
+ return task;
77
+ });
78
+ saveRunTasks(loaded.manifest, tasks);
79
+ try {
80
+ saveCrewAgents(loaded.manifest, tasks.map((task) => recordFromTask(loaded.manifest, task, "child-process")));
81
+ } catch (error) {
82
+ logInternalError("team-tool.handleCancel.crewAgents", error, `runId=${loaded.manifest.runId}`);
83
+ }
84
+ try {
85
+ writeForegroundInterruptRequest(loaded.manifest, "Run cancelled by user request.");
86
+ } catch (error) {
87
+ logInternalError("team-tool.handleCancel.interruptRequest", error, `runId=${loaded.manifest.runId}`);
88
+ }
89
+ const updated = updateRunStatus(loaded.manifest, "cancelled", "Run cancelled by user request. Already-finished worker processes are not retroactively changed.");
90
+
91
+ // Build descriptive message including foreign/missing info
92
+ const parts = [`Cancelled run ${updated.runId}.`];
93
+ if (abortResult.foreignIds.length > 0) parts.push(` ${abortResult.foreignIds.length} task(s) belong to another session and were not cancelled: ${abortResult.foreignIds.join(", ")}.`);
94
+ if (abortResult.missingIds.length > 0) parts.push(` ${abortResult.missingIds.length} task ID(s) not found: ${abortResult.missingIds.join(", ")}.`);
95
+
96
+ return result(parts.join(""), {
97
+ action: "cancel",
98
+ status: "ok",
99
+ runId: updated.runId,
100
+ artifactsRoot: updated.artifactsRoot,
101
+ abortedIds: abortResult.abortedIds,
102
+ missingIds: abortResult.missingIds,
103
+ foreignIds: abortResult.foreignIds,
104
+ });
105
+ });
103
106
  }
@@ -4,6 +4,7 @@ import type { TeamToolDetails } from "../team-tool-types.ts";
4
4
  import { toolResult, type PiTeamsToolResult } from "../tool-result.ts";
5
5
 
6
6
  export type TeamContext = Pick<ExtensionContext, "cwd"> & Partial<Pick<ExtensionContext, "model">> & {
7
+ sessionId?: string;
7
8
  modelRegistry?: unknown;
8
9
  sessionManager?: { getBranch?: () => unknown[] };
9
10
  events?: { emit?: (event: string, data: unknown) => void };