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,149 @@
1
+ /**
2
+ * Pi Team-Mode — Compact Text Formatters
3
+ *
4
+ * Pure helpers for rendering status summaries to markdown / ansi lines.
5
+ * No theme or tui imports here so they're trivial to unit test.
6
+ */
7
+
8
+ import type { LiveTeammateSnapshot, TeamRecord, TeammateRecord } from "../core/types.js";
9
+ import type { TaskRecord } from "../core/tasks.js";
10
+
11
+ export const STATUS_ICONS: Record<string, string> = {
12
+ pending: "·",
13
+ running: "▸",
14
+ completed: "✓",
15
+ failed: "✗",
16
+ stopped: "■",
17
+ };
18
+
19
+ export function formatTeammateLine(t: TeammateRecord): string {
20
+ const icon = STATUS_ICONS[t.status] ?? "?";
21
+ const bits = [
22
+ `${icon} ${t.name}`,
23
+ t.subagentType ? `[${t.subagentType}]` : "",
24
+ t.teamId ? `team=${t.teamId}` : "",
25
+ t.isolation === "worktree" ? "wt" : "",
26
+ ].filter(Boolean);
27
+ return bits.join(" ");
28
+ }
29
+
30
+ export function formatTeammateList(teammates: TeammateRecord[]): string {
31
+ if (teammates.length === 0) return "No teammates.";
32
+ return teammates.map(formatTeammateLine).join("\n");
33
+ }
34
+
35
+ export function formatTeamLine(team: TeamRecord, memberCount: number): string {
36
+ return `• ${team.name} (${team.id}) — ${memberCount} teammate${memberCount === 1 ? "" : "s"}, default=${team.defaultIsolation}`;
37
+ }
38
+
39
+ export function formatTeamDashboard(teams: TeamRecord[], teammates: TeammateRecord[]): string {
40
+ if (teams.length === 0 && teammates.length === 0) {
41
+ return "No teams and no teammates.";
42
+ }
43
+ const out: string[] = [];
44
+ if (teams.length > 0) {
45
+ out.push("Teams:");
46
+ for (const team of teams) {
47
+ const members = teammates.filter((t) => t.teamId === team.id);
48
+ out.push(` ${formatTeamLine(team, members.length)}`);
49
+ for (const m of members) out.push(` ${formatTeammateLine(m)}`);
50
+ }
51
+ }
52
+ const loners = teammates.filter((t) => !t.teamId);
53
+ if (loners.length > 0) {
54
+ out.push("Unassigned teammates:");
55
+ for (const m of loners) out.push(` ${formatTeammateLine(m)}`);
56
+ }
57
+ return out.join("\n");
58
+ }
59
+
60
+ export function formatTaskLine(t: TaskRecord): string {
61
+ const icon = STATUS_ICONS[t.status] ?? "?";
62
+ const owner = t.owner ? `@${t.owner}` : "unassigned";
63
+ const blocks = t.blockedBy.length > 0 ? ` ⤴${t.blockedBy.length}` : "";
64
+ return `${icon} [${t.id}] ${t.subject} (${owner}${blocks})`;
65
+ }
66
+
67
+ export function formatTaskList(tasks: TaskRecord[]): string {
68
+ if (tasks.length === 0) return "No tasks.";
69
+ const byStatus: Record<string, TaskRecord[]> = {};
70
+ for (const t of tasks) (byStatus[t.status] ??= []).push(t);
71
+ const order: TaskRecord["status"][] = ["in_progress", "pending", "completed", "failed", "deleted"];
72
+ const out: string[] = [];
73
+ for (const status of order) {
74
+ const group = byStatus[status];
75
+ if (!group || group.length === 0) continue;
76
+ out.push(`${status} (${group.length}):`);
77
+ for (const t of group) out.push(` ${formatTaskLine(t)}`);
78
+ }
79
+ return out.join("\n");
80
+ }
81
+
82
+ export function formatTaskDetails(t: TaskRecord): string {
83
+ const out = [
84
+ `Task: ${t.subject} (${t.id})`,
85
+ `Status: ${t.status}`,
86
+ t.activeForm ? `In-progress form: ${t.activeForm}` : "",
87
+ t.owner ? `Owner: ${t.owner}` : "Owner: unassigned",
88
+ t.teamId ? `Team: ${t.teamId}` : "",
89
+ t.blockedBy.length > 0 ? `Blocked by: ${t.blockedBy.join(", ")}` : "",
90
+ t.blocks.length > 0 ? `Blocks: ${t.blocks.join(", ")}` : "",
91
+ `Version: ${t.version}`,
92
+ `Created: ${t.createdAt}`,
93
+ `Updated: ${t.updatedAt}`,
94
+ t.description ? `\n${t.description}` : "",
95
+ t.result ? `\nResult:\n${t.result}` : "",
96
+ t.hookOutput ? `\nHook output:\n${t.hookOutput}` : "",
97
+ ].filter(Boolean);
98
+ return out.join("\n");
99
+ }
100
+
101
+ export function formatTeammateStatus(t: TeammateRecord): string {
102
+ const modelStr =
103
+ t.provider && t.model ? `${t.provider}/${t.model}` : t.model ?? "(pi default)";
104
+ const out = [
105
+ `Teammate: ${t.name} (${t.id})`,
106
+ `Status: ${t.status}`,
107
+ `Model: ${modelStr}${t.thinkingLevel ? ` (thinking=${t.thinkingLevel})` : ""}`,
108
+ t.subagentType ? `Role: ${t.subagentType}` : "",
109
+ t.teamId ? `Team: ${t.teamId}` : "",
110
+ `Isolation: ${t.isolation}${t.worktreeBranch ? ` (branch=${t.worktreeBranch})` : ""}`,
111
+ `CWD: ${t.cwd}`,
112
+ `Created: ${t.createdAt}`,
113
+ `Updated: ${t.updatedAt}`,
114
+ t.lastExitCode !== undefined ? `Last exit: ${t.lastExitCode}` : "",
115
+ t.lastResult ? `Last result:\n${t.lastResult}` : "",
116
+ ].filter(Boolean);
117
+ return out.join("\n");
118
+ }
119
+
120
+ export function formatDuration(ms: number): string {
121
+ if (!Number.isFinite(ms) || ms < 0) return "0.0s";
122
+ if (ms < 1000) return `${ms.toFixed(0)}ms`;
123
+ return `${(ms / 1000).toFixed(1)}s`;
124
+ }
125
+
126
+ export function formatTokenCount(tokens: number): string {
127
+ if (!Number.isFinite(tokens) || tokens <= 0) return "0";
128
+ if (tokens < 1000) return `${Math.round(tokens)}`;
129
+ return `${(tokens / 1000).toFixed(1)}k`;
130
+ }
131
+
132
+ export function summarizeResult(text: string, max = 120): string {
133
+ const flat = text.replace(/\s+/g, " ").trim();
134
+ if (flat.length <= max) return flat;
135
+ return `${flat.slice(0, max)}…`;
136
+ }
137
+
138
+ export function formatMetricChip(snapshot: LiveTeammateSnapshot): string {
139
+ const elapsed = (snapshot.metrics.finishedAt ?? Date.now()) - snapshot.metrics.startedAt;
140
+ const turns = snapshot.metrics.maxTurns
141
+ ? `⟳ ${snapshot.metrics.turns}≤${snapshot.metrics.maxTurns}`
142
+ : `⟳ ${snapshot.metrics.turns}`;
143
+ return [
144
+ turns,
145
+ `${snapshot.metrics.toolUses} tool uses`,
146
+ `${formatTokenCount(snapshot.metrics.tokens)} tok`,
147
+ formatDuration(elapsed),
148
+ ].join(" · ");
149
+ }
@@ -0,0 +1,55 @@
1
+ import type { Theme } from "@mariozechner/pi-coding-agent";
2
+ import { Box, Text } from "@mariozechner/pi-tui";
3
+
4
+ import type { LiveTeammateMetrics } from "../core/types.js";
5
+ import { formatDuration, formatTokenCount, summarizeResult } from "./formatters.js";
6
+
7
+ export type TaskNotificationDetails = {
8
+ taskId: string;
9
+ status: "completed" | "failed" | "killed";
10
+ durationMs?: number;
11
+ metrics?: LiveTeammateMetrics;
12
+ transcriptPath?: string;
13
+ summary?: string;
14
+ };
15
+
16
+ export function renderTaskNotification(
17
+ message: { content: string | unknown; details?: TaskNotificationDetails },
18
+ options: { expanded: boolean },
19
+ theme: Theme,
20
+ ) {
21
+ const details = message.details;
22
+ if (!details) return undefined;
23
+
24
+ const icon = details.status === "completed" ? "✓" : details.status === "killed" ? "■" : "✗";
25
+ const color = details.status === "completed" ? "success" : details.status === "killed" ? "warning" : "error";
26
+ const chips: string[] = [];
27
+ if (details.metrics) {
28
+ chips.push(`⟳ ${details.metrics.turns}`);
29
+ chips.push(`${details.metrics.toolUses} tool uses`);
30
+ chips.push(`${formatTokenCount(details.metrics.tokens)} tok`);
31
+ }
32
+ if (typeof details.durationMs === "number") chips.push(formatDuration(details.durationMs));
33
+
34
+ const lines = [
35
+ theme.fg(color, `${icon} ${details.summary ?? `Task ${details.taskId} ${details.status}`}`),
36
+ chips.length > 0 ? ` ${chips.join(" · ")}` : "",
37
+ details.transcriptPath ? ` transcript: ${details.transcriptPath}` : "",
38
+ details.status !== "completed" && options.expanded ? "" : "",
39
+ ].filter(Boolean);
40
+
41
+ if (message.content && typeof message.content === "string") {
42
+ const summary = summarizeResult(message.content);
43
+ if (summary && summary !== details.summary) {
44
+ lines.push(` └ ${summary}`);
45
+ }
46
+ }
47
+
48
+ if (options.expanded && typeof message.content === "string" && message.content.trim()) {
49
+ lines.push("", message.content.trim());
50
+ }
51
+
52
+ const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
53
+ box.addChild(new Text(lines.join("\n"), 0, 0));
54
+ return box;
55
+ }
@@ -0,0 +1,94 @@
1
+ // Pi Team-Mode — Live Agents Widget
2
+
3
+ import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
4
+
5
+ import type { TeammateRecord } from "../core/types.js";
6
+ import type { AgentManager } from "../managers/agent-manager.js";
7
+ import { formatMetricChip, STATUS_ICONS } from "./formatters.js";
8
+
9
+ export const WIDGET_ID = "team-mode-status";
10
+
11
+ const SPINNER = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
12
+ const FINISH_LINGER_MS = 3_000;
13
+
14
+ export function renderTeamMateWidget(
15
+ running: ReturnType<AgentManager["getLiveSnapshots"]>,
16
+ recent: TeammateRecord[],
17
+ queuedCount: number,
18
+ now: number,
19
+ spinnerFrame: number,
20
+ ): string[] {
21
+ if (running.length === 0 && recent.length === 0 && queuedCount === 0) return [];
22
+
23
+ const lines: string[] = ["● Agents"];
24
+ const rows: string[] = [];
25
+
26
+ for (const snapshot of running) {
27
+ const head = `${SPINNER[spinnerFrame % SPINNER.length]} ${snapshot.record.name} · ${formatMetricChip(snapshot)}`;
28
+ rows.push(head);
29
+ if (snapshot.metrics.activityHint) rows.push(` └ ${snapshot.metrics.activityHint}`);
30
+ }
31
+
32
+ for (const record of recent) {
33
+ const icon = STATUS_ICONS[record.status] ?? "?";
34
+ rows.push(`${icon} ${record.name} · ${record.status}`);
35
+ }
36
+
37
+ if (queuedCount > 0) {
38
+ rows.push(`${queuedCount} queued`);
39
+ }
40
+
41
+ for (const row of rows) lines.push(` ${row}`);
42
+ return lines;
43
+ }
44
+
45
+ export function startTeamMateWidget(ctx: ExtensionContext, agents: AgentManager): () => void {
46
+ let disposed = false;
47
+ let spinnerFrame = 0;
48
+ let renderInFlight = false;
49
+ let lastActiveAt = 0;
50
+
51
+ const render = async () => {
52
+ if (disposed || renderInFlight) return;
53
+ renderInFlight = true;
54
+ try {
55
+ const running = agents.getLiveSnapshots();
56
+ const all = await agents.list();
57
+ const now = Date.now();
58
+ const recent = all
59
+ .filter((t) => t.status !== "running" && now - Date.parse(t.updatedAt) <= FINISH_LINGER_MS)
60
+ .sort((a, b) => Date.parse(a.updatedAt) - Date.parse(b.updatedAt));
61
+ const queuedCount = agents.getQueuedCount();
62
+ const lines = renderTeamMateWidget(running, recent, queuedCount, now, spinnerFrame);
63
+ if (lines.length === 0) {
64
+ ctx.ui.setWidget(WIDGET_ID, undefined);
65
+ } else {
66
+ ctx.ui.setWidget(WIDGET_ID, lines);
67
+ lastActiveAt = now;
68
+ }
69
+ } finally {
70
+ renderInFlight = false;
71
+ }
72
+ };
73
+
74
+ const unsubscribe = agents.subscribeAll(() => {
75
+ void render();
76
+ });
77
+
78
+ const timer = setInterval(() => {
79
+ spinnerFrame = (spinnerFrame + 1) % SPINNER.length;
80
+ const active = agents.getLiveSnapshots().length > 0 || agents.getQueuedCount() > 0;
81
+ if (active || Date.now() - lastActiveAt <= FINISH_LINGER_MS) {
82
+ void render();
83
+ }
84
+ }, 80);
85
+
86
+ void render();
87
+
88
+ return () => {
89
+ disposed = true;
90
+ clearInterval(timer);
91
+ unsubscribe();
92
+ ctx.ui.setWidget(WIDGET_ID, undefined);
93
+ };
94
+ }
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "pi-mono-all",
3
+ "version": "1.0.0",
4
+ "description": "All pi-mono extensions and bundled skills",
5
+ "type": "module",
6
+ "keywords": [
7
+ "pi-package",
8
+ "pi-extension",
9
+ "pi-skill"
10
+ ],
11
+ "dependencies": {
12
+ "pi-mono-ask-user-question": "1.7.3",
13
+ "pi-mono-btw": "1.7.2",
14
+ "pi-mono-auto-fix": "0.3.0",
15
+ "pi-mono-clear": "1.7.2",
16
+ "pi-mono-context-guard": "1.7.2",
17
+ "pi-mono-figma": "0.2.1",
18
+ "pi-common": "0.1.1",
19
+ "pi-mono-context": "0.1.0",
20
+ "pi-mono-loop": "1.7.2",
21
+ "pi-mono-multi-edit": "1.7.2",
22
+ "pi-mono-simplify": "1.7.2",
23
+ "pi-mono-review": "1.8.1",
24
+ "pi-mono-sentinel": "1.10.1",
25
+ "pi-mono-status-line": "1.7.2",
26
+ "pi-mono-team-mode": "2.3.1",
27
+ "pi-mono-linear": "0.2.1"
28
+ },
29
+ "bundledDependencies": [
30
+ "pi-mono-ask-user-question",
31
+ "pi-mono-auto-fix",
32
+ "pi-mono-btw",
33
+ "pi-mono-clear",
34
+ "pi-mono-context",
35
+ "pi-mono-context-guard",
36
+ "pi-mono-figma",
37
+ "pi-mono-linear",
38
+ "pi-common",
39
+ "pi-mono-loop",
40
+ "pi-mono-multi-edit",
41
+ "pi-mono-review",
42
+ "pi-mono-sentinel",
43
+ "pi-mono-simplify",
44
+ "pi-mono-status-line",
45
+ "pi-mono-team-mode"
46
+ ],
47
+ "peerDependencies": {
48
+ "@mariozechner/pi-ai": "*",
49
+ "@mariozechner/pi-coding-agent": "*",
50
+ "@mariozechner/pi-tui": "*",
51
+ "@sinclair/typebox": "*"
52
+ },
53
+ "pi": {
54
+ "extensions": [
55
+ "./node_modules/pi-mono-ask-user-question/index.ts",
56
+ "./node_modules/pi-mono-auto-fix/index.ts",
57
+ "./node_modules/pi-mono-btw/index.ts",
58
+ "./node_modules/pi-mono-clear/index.ts",
59
+ "./node_modules/pi-mono-context/index.ts",
60
+ "./node_modules/pi-mono-context-guard/index.ts",
61
+ "./node_modules/pi-mono-figma/index.ts",
62
+ "./node_modules/pi-mono-linear/index.ts",
63
+ "./node_modules/pi-mono-loop/index.ts",
64
+ "./node_modules/pi-mono-multi-edit/index.ts",
65
+ "./node_modules/pi-mono-review/index.ts",
66
+ "./node_modules/pi-mono-sentinel/index.ts",
67
+ "./node_modules/pi-mono-simplify/index.ts",
68
+ "./node_modules/pi-mono-status-line/index.ts",
69
+ "./node_modules/pi-mono-team-mode/index.ts"
70
+ ],
71
+ "skills": [
72
+ "./node_modules/pi-mono-figma/skills",
73
+ "./node_modules/pi-mono-linear/skills"
74
+ ]
75
+ }
76
+ }