@tmustier/pi-agent-teams 0.5.4 → 0.5.5
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 +5 -0
- package/extensions/teams/activity-tracker.ts +1 -1
- package/extensions/teams/index.ts +1 -1
- package/extensions/teams/leader-attach-commands.ts +1 -1
- package/extensions/teams/leader-inbox.ts +1 -1
- package/extensions/teams/leader-info-commands.ts +1 -1
- package/extensions/teams/leader-lifecycle-commands.ts +1 -1
- package/extensions/teams/leader-messaging-commands.ts +1 -1
- package/extensions/teams/leader-plan-commands.ts +1 -1
- package/extensions/teams/leader-spawn-command.ts +2 -2
- package/extensions/teams/leader-task-commands.ts +1 -1
- package/extensions/teams/leader-team-command.ts +1 -1
- package/extensions/teams/leader-teams-tool.ts +16 -10
- package/extensions/teams/leader.ts +2 -74
- package/extensions/teams/paths.ts +1 -1
- package/extensions/teams/session-branching.ts +1 -1
- package/extensions/teams/session-parent.ts +1 -1
- package/extensions/teams/spawn-types.ts +2 -2
- package/extensions/teams/teammate-rpc.ts +1 -1
- package/extensions/teams/teams-panel.ts +2 -2
- package/extensions/teams/teams-ui-shared.ts +2 -2
- package/extensions/teams/teams-widget.ts +3 -3
- package/extensions/teams/worker.ts +2 -2
- package/package.json +9 -9
- package/scripts/integration-branch-context-test.mts +2 -2
- package/scripts/smoke-test.mts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExtensionCommandContext } from "@
|
|
1
|
+
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { sanitizeName } from "./names.js";
|
|
3
3
|
import { getTeamDir, getTeamsRootDir } from "./paths.js";
|
|
4
4
|
import type { TeammateRpc } from "./teammate-rpc.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import type { ExtensionCommandContext, ExtensionContext } from "@
|
|
4
|
+
import type { ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
5
5
|
import { cleanupTeamDir, gcStaleTeamDirs } from "./cleanup.js";
|
|
6
6
|
import { writeToMailbox } from "./mailbox.js";
|
|
7
7
|
import { sanitizeName } from "./names.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExtensionCommandContext } from "@
|
|
1
|
+
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { writeToMailbox } from "./mailbox.js";
|
|
3
3
|
import { sanitizeName } from "./names.js";
|
|
4
4
|
import { getTeamDir } from "./paths.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExtensionCommandContext } from "@
|
|
1
|
+
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { writeToMailbox } from "./mailbox.js";
|
|
3
3
|
import { sanitizeName } from "./names.js";
|
|
4
4
|
import { getTeamDir } from "./paths.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ThinkingLevel } from "@
|
|
2
|
-
import type { ExtensionCommandContext } from "@
|
|
1
|
+
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import { pickAgentNames, pickNamesFromPool } from "./names.js";
|
|
4
4
|
import type { TeammateRpc } from "./teammate-rpc.js";
|
|
5
5
|
import type { TeamsStyle } from "./teams-style.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
-
import type { ExtensionCommandContext } from "@
|
|
2
|
+
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import { writeToMailbox } from "./mailbox.js";
|
|
4
4
|
import { sanitizeName } from "./names.js";
|
|
5
5
|
import { getTeamDir } from "./paths.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExtensionCommandContext, ExtensionContext } from "@
|
|
1
|
+
import type { ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { getTeamDir } from "./paths.js";
|
|
3
3
|
import {
|
|
4
4
|
handleTeamEnvCommand,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import type { AgentToolResult } from "@
|
|
3
|
-
import { StringEnum } from "@mariozechner/pi-ai";
|
|
2
|
+
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
4
3
|
import { Type, type Static } from "@sinclair/typebox";
|
|
5
|
-
import type { ExtensionAPI } from "@
|
|
4
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
5
|
import { writeToMailbox } from "./mailbox.js";
|
|
7
6
|
import { pickAgentNames, pickNamesFromPool, sanitizeName } from "./names.js";
|
|
8
7
|
import { getTeamDir } from "./paths.js";
|
|
@@ -52,7 +51,14 @@ function describeModelSource(source: TeammateModelSource): string {
|
|
|
52
51
|
return "teammate-default";
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
const
|
|
54
|
+
function stringEnum<const Values extends readonly [string, ...string[]]>(
|
|
55
|
+
values: Values,
|
|
56
|
+
options: Record<string, unknown> = {},
|
|
57
|
+
) {
|
|
58
|
+
return Type.Unsafe<Values[number]>({ type: "string", enum: [...values], ...options });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const TeamsActionSchema = stringEnum(
|
|
56
62
|
[
|
|
57
63
|
"delegate",
|
|
58
64
|
"task_assign",
|
|
@@ -83,30 +89,30 @@ const TeamsActionSchema = StringEnum(
|
|
|
83
89
|
},
|
|
84
90
|
);
|
|
85
91
|
|
|
86
|
-
const TeamsTaskStatusSchema =
|
|
92
|
+
const TeamsTaskStatusSchema = stringEnum(["pending", "in_progress", "completed"] as const, {
|
|
87
93
|
description: "Task status for action=task_set_status.",
|
|
88
94
|
});
|
|
89
95
|
|
|
90
|
-
const TeamsContextModeSchema =
|
|
96
|
+
const TeamsContextModeSchema = stringEnum(["fresh", "branch"] as const, {
|
|
91
97
|
description: "How to initialize comrade session context. 'branch' clones the leader session branch.",
|
|
92
98
|
default: "fresh",
|
|
93
99
|
});
|
|
94
100
|
|
|
95
|
-
const TeamsWorkspaceModeSchema =
|
|
101
|
+
const TeamsWorkspaceModeSchema = stringEnum(["shared", "worktree"] as const, {
|
|
96
102
|
description: "Workspace isolation mode. 'shared' matches Claude Teams; 'worktree' creates a git worktree per comrade.",
|
|
97
103
|
default: "shared",
|
|
98
104
|
});
|
|
99
105
|
|
|
100
|
-
const TeamsThinkingLevelSchema =
|
|
106
|
+
const TeamsThinkingLevelSchema = stringEnum(["off", "minimal", "low", "medium", "high", "xhigh"] as const, {
|
|
101
107
|
description:
|
|
102
108
|
"Thinking level to use for spawned comrades (defaults to the leader's current thinking level when omitted).",
|
|
103
109
|
});
|
|
104
110
|
|
|
105
|
-
const TeamsHookFailureActionSchema =
|
|
111
|
+
const TeamsHookFailureActionSchema = stringEnum(["warn", "followup", "reopen", "reopen_followup"] as const, {
|
|
106
112
|
description: "Hook failure policy for hooks_policy_set.",
|
|
107
113
|
});
|
|
108
114
|
|
|
109
|
-
const TeamsHookFollowupOwnerSchema =
|
|
115
|
+
const TeamsHookFollowupOwnerSchema = stringEnum(["member", "lead", "none"] as const, {
|
|
110
116
|
description: "Follow-up owner policy for hooks_policy_set.",
|
|
111
117
|
});
|
|
112
118
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@
|
|
5
|
-
import { SessionManager } from "@
|
|
4
|
+
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
import { writeToMailbox } from "./mailbox.js";
|
|
7
7
|
import { sanitizeName } from "./names.js";
|
|
8
8
|
import { TEAM_MAILBOX_NS, taskAssignmentPayload } from "./protocol.js";
|
|
@@ -786,78 +786,6 @@ export function runLeader(pi: ExtensionAPI): void {
|
|
|
786
786
|
inboxTimer.unref?.();
|
|
787
787
|
});
|
|
788
788
|
|
|
789
|
-
pi.on("session_switch", async (_event, ctx) => {
|
|
790
|
-
const prevTeamId = currentTeamId;
|
|
791
|
-
const prevCwd = currentCtx?.cwd;
|
|
792
|
-
|
|
793
|
-
if (currentCtx) {
|
|
794
|
-
await releaseActiveAttachClaim(currentCtx);
|
|
795
|
-
const strings = getTeamsStrings(style);
|
|
796
|
-
await stopAllTeammates(currentCtx, `The ${strings.teamNoun} is dissolved — leader moved on`);
|
|
797
|
-
}
|
|
798
|
-
stopLoops();
|
|
799
|
-
delegationTracker.clear();
|
|
800
|
-
|
|
801
|
-
// Clean up worktrees from the old session before switching.
|
|
802
|
-
// Only clean up teams this session owns — never attached teams.
|
|
803
|
-
const prevSessionId = currentCtx?.sessionManager.getSessionId();
|
|
804
|
-
if (prevTeamId && prevTeamId === prevSessionId) {
|
|
805
|
-
const teamDir = getTeamDir(prevTeamId);
|
|
806
|
-
try {
|
|
807
|
-
await cleanupWorktrees({ teamDir, teamId: prevTeamId, repoCwd: prevCwd });
|
|
808
|
-
} catch {
|
|
809
|
-
// Best-effort — don't block session switch.
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
currentCtx = ctx;
|
|
814
|
-
currentTeamId = currentCtx.sessionManager.getSessionId();
|
|
815
|
-
inheritedParentTeamId = getParentSessionId(currentCtx.sessionManager);
|
|
816
|
-
// Keep the task list aligned with the active session. If you want a shared namespace,
|
|
817
|
-
// use `/team task use <taskListId>` after switching.
|
|
818
|
-
taskListId = currentTeamId;
|
|
819
|
-
lastAttachClaimHeartbeatMs = 0;
|
|
820
|
-
// Clear any /team done suppression — new session context.
|
|
821
|
-
widgetSuppressed = false;
|
|
822
|
-
autoDoneNotified = false;
|
|
823
|
-
|
|
824
|
-
await ensureTeamConfig(getTeamDir(currentTeamId), {
|
|
825
|
-
teamId: currentTeamId,
|
|
826
|
-
taskListId: taskListId,
|
|
827
|
-
leadName: "team-lead",
|
|
828
|
-
style,
|
|
829
|
-
});
|
|
830
|
-
|
|
831
|
-
await refreshTasks();
|
|
832
|
-
renderWidget();
|
|
833
|
-
|
|
834
|
-
// Restart background refresh/poll loops for the new session.
|
|
835
|
-
refreshTimer = setInterval(async () => {
|
|
836
|
-
if (isStopping) return;
|
|
837
|
-
if (refreshInFlight) return;
|
|
838
|
-
refreshInFlight = true;
|
|
839
|
-
try {
|
|
840
|
-
await heartbeatActiveAttachClaim(ctx);
|
|
841
|
-
await refreshTasks();
|
|
842
|
-
renderWidget();
|
|
843
|
-
} finally {
|
|
844
|
-
refreshInFlight = false;
|
|
845
|
-
}
|
|
846
|
-
}, 1000);
|
|
847
|
-
refreshTimer.unref?.();
|
|
848
|
-
|
|
849
|
-
inboxTimer = setInterval(async () => {
|
|
850
|
-
if (isStopping) return;
|
|
851
|
-
if (inboxInFlight) return;
|
|
852
|
-
inboxInFlight = true;
|
|
853
|
-
try {
|
|
854
|
-
await pollLeaderInbox();
|
|
855
|
-
} finally {
|
|
856
|
-
inboxInFlight = false;
|
|
857
|
-
}
|
|
858
|
-
}, 700);
|
|
859
|
-
inboxTimer.unref?.();
|
|
860
|
-
});
|
|
861
789
|
|
|
862
790
|
pi.on("session_shutdown", async () => {
|
|
863
791
|
if (!currentCtx) return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import type { SessionEntry, SessionManager } from "@
|
|
3
|
+
import type { SessionEntry, SessionManager } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
|
|
5
5
|
export type BranchLeafSelection = {
|
|
6
6
|
leafId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ThinkingLevel } from "@
|
|
2
|
-
import type { ExtensionContext } from "@
|
|
1
|
+
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
|
|
4
4
|
export type ContextMode = "fresh" | "branch";
|
|
5
5
|
export type WorkspaceMode = "shared" | "worktree";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { matchesKey, truncateToWidth, visibleWidth } from "@
|
|
2
|
-
import type { Theme, ThemeColor, ExtensionCommandContext } from "@
|
|
1
|
+
import { matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
2
|
+
import type { Theme, ThemeColor, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import type { TeammateRpc } from "./teammate-rpc.js";
|
|
4
4
|
import type { ActivityTracker, TranscriptLog, TranscriptEntry } from "./activity-tracker.js";
|
|
5
5
|
import type { TeamTask } from "./task-store.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Theme, ThemeColor } from "@
|
|
2
|
-
import { truncateToWidth, visibleWidth } from "@
|
|
1
|
+
import type { Theme, ThemeColor } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
3
3
|
import type { TeamConfig, TeamMember } from "./team-config.js";
|
|
4
4
|
import type { TeamTask } from "./task-store.js";
|
|
5
5
|
import type { TeammateRpc, TeammateStatus } from "./teammate-rpc.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { truncateToWidth, visibleWidth } from "@
|
|
2
|
-
import type { Component, TUI } from "@
|
|
3
|
-
import type { Theme, ThemeColor } from "@
|
|
1
|
+
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
2
|
+
import type { Component, TUI } from "@earendil-works/pi-tui";
|
|
3
|
+
import type { Theme, ThemeColor } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
import type { TeammateRpc } from "./teammate-rpc.js";
|
|
5
5
|
import type { ActivityTracker } from "./activity-tracker.js";
|
|
6
6
|
import type { TeamTask } from "./task-store.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AgentMessage, AgentToolResult } from "@
|
|
2
|
-
import type { ExtensionAPI, ExtensionContext } from "@
|
|
1
|
+
import type { AgentMessage, AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import { Type, type Static } from "@sinclair/typebox";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { popUnreadMessages, writeToMailbox } from "./mailbox.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tmustier/pi-agent-teams",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"description": "Claude Code agent teams style workflow for Pi.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Thomas Mustier",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@eslint/js": "^9.39.2",
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
43
|
+
"@earendil-works/pi-agent-core": "^0.74.0",
|
|
44
|
+
"@earendil-works/pi-ai": "^0.74.0",
|
|
45
|
+
"@earendil-works/pi-coding-agent": "^0.74.0",
|
|
46
|
+
"@earendil-works/pi-tui": "^0.74.0",
|
|
47
47
|
"@sinclair/typebox": "^0.34.48",
|
|
48
48
|
"eslint": "^9.39.2",
|
|
49
49
|
"tsx": "^4.20.5",
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
"typescript-eslint": "^8.54.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@
|
|
55
|
-
"@
|
|
56
|
-
"@
|
|
57
|
-
"@
|
|
54
|
+
"@earendil-works/pi-agent-core": "*",
|
|
55
|
+
"@earendil-works/pi-ai": "*",
|
|
56
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
57
|
+
"@earendil-works/pi-tui": "*",
|
|
58
58
|
"@sinclair/typebox": "*"
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -22,8 +22,8 @@ import * as path from "node:path";
|
|
|
22
22
|
import { spawn, spawnSync, type ChildProcess } from "node:child_process";
|
|
23
23
|
import { fileURLToPath } from "node:url";
|
|
24
24
|
|
|
25
|
-
import { SessionManager } from "@
|
|
26
|
-
import type { AssistantMessage } from "@
|
|
25
|
+
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
26
|
+
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
27
27
|
import { writeToMailbox } from "../extensions/teams/mailbox.js";
|
|
28
28
|
import { taskAssignmentPayload } from "../extensions/teams/protocol.js";
|
|
29
29
|
import { branchSelectionNote, resolveBranchLeafSelection } from "../extensions/teams/session-branching.js";
|
package/scripts/smoke-test.mts
CHANGED
|
@@ -72,8 +72,8 @@ import {
|
|
|
72
72
|
import { DelegationTracker, pollLeaderInbox } from "../extensions/teams/leader-inbox.js";
|
|
73
73
|
import { getParentSessionId, shouldSilenceInheritedParentAttachClaimWarning } from "../extensions/teams/session-parent.js";
|
|
74
74
|
import { branchSelectionNote, ensureSessionFileMaterialized, resolveBranchLeafSelection } from "../extensions/teams/session-branching.js";
|
|
75
|
-
import { SessionManager, type ExtensionContext } from "@
|
|
76
|
-
import type { AssistantMessage } from "@
|
|
75
|
+
import { SessionManager, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
76
|
+
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
77
77
|
|
|
78
78
|
// ── helpers ──────────────────────────────────────────────────────────
|
|
79
79
|
let passed = 0;
|