pi-crew 0.1.30 → 0.1.32

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 (159) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +80 -27
  3. package/agents/analyst.md +11 -11
  4. package/agents/critic.md +11 -11
  5. package/agents/executor.md +11 -11
  6. package/agents/explorer.md +11 -11
  7. package/agents/planner.md +11 -11
  8. package/agents/reviewer.md +11 -11
  9. package/agents/security-reviewer.md +11 -11
  10. package/agents/test-engineer.md +11 -11
  11. package/agents/verifier.md +11 -11
  12. package/agents/writer.md +11 -11
  13. package/docs/architecture.md +173 -164
  14. package/docs/refactor-tasks-phase3.md +394 -394
  15. package/docs/refactor-tasks-phase4.md +564 -564
  16. package/docs/refactor-tasks-phase5.md +402 -402
  17. package/docs/refactor-tasks-phase6.md +662 -662
  18. package/docs/research-extension-examples.md +297 -0
  19. package/docs/research-extension-system.md +324 -0
  20. package/docs/research-optimization-plan.md +548 -0
  21. package/docs/research-pi-coding-agent.md +357 -0
  22. package/docs/resource-formats.md +4 -3
  23. package/docs/runtime-flow.md +148 -148
  24. package/docs/source-runtime-refactor-map.md +83 -83
  25. package/docs/usage.md +3 -3
  26. package/index.ts +6 -6
  27. package/package.json +1 -1
  28. package/schema.json +53 -1
  29. package/skills/git-master/SKILL.md +24 -19
  30. package/skills/read-only-explorer/SKILL.md +26 -21
  31. package/skills/safe-bash/SKILL.md +21 -16
  32. package/skills/task-packet/SKILL.md +28 -23
  33. package/skills/verify-evidence/SKILL.md +27 -22
  34. package/src/agents/agent-serializer.ts +34 -34
  35. package/src/agents/discover-agents.ts +102 -102
  36. package/src/config/config.ts +14 -1
  37. package/src/config/defaults.ts +3 -2
  38. package/src/extension/cross-extension-rpc.ts +82 -82
  39. package/src/extension/import-index.ts +4 -3
  40. package/src/extension/management.ts +2 -2
  41. package/src/extension/project-init.ts +9 -7
  42. package/src/extension/register.ts +63 -0
  43. package/src/extension/registration/artifact-cleanup.ts +15 -14
  44. package/src/extension/registration/commands.ts +208 -208
  45. package/src/extension/registration/compaction-guard.ts +125 -0
  46. package/src/extension/registration/subagent-tools.ts +27 -8
  47. package/src/extension/registration/team-tool.ts +61 -44
  48. package/src/extension/result-watcher.ts +98 -98
  49. package/src/extension/run-import.ts +4 -4
  50. package/src/extension/run-index.ts +14 -14
  51. package/src/extension/run-maintenance.ts +24 -24
  52. package/src/extension/team-tool/api.ts +3 -0
  53. package/src/extension/team-tool/cancel.ts +31 -31
  54. package/src/extension/team-tool/doctor.ts +179 -178
  55. package/src/extension/team-tool/inspect.ts +41 -41
  56. package/src/extension/team-tool/lifecycle-actions.ts +79 -79
  57. package/src/extension/team-tool/plan.ts +19 -19
  58. package/src/extension/team-tool/status.ts +73 -73
  59. package/src/prompt/prompt-runtime.ts +68 -68
  60. package/src/runtime/agent-control.ts +64 -64
  61. package/src/runtime/agent-memory.ts +72 -72
  62. package/src/runtime/agent-observability.ts +113 -113
  63. package/src/runtime/async-marker.ts +26 -26
  64. package/src/runtime/background-runner.ts +53 -53
  65. package/src/runtime/crew-agent-runtime.ts +58 -58
  66. package/src/runtime/direct-run.ts +35 -35
  67. package/src/runtime/foreground-control.ts +82 -82
  68. package/src/runtime/green-contract.ts +46 -46
  69. package/src/runtime/group-join.ts +88 -88
  70. package/src/runtime/live-agent-control.ts +78 -78
  71. package/src/runtime/live-agent-manager.ts +85 -85
  72. package/src/runtime/live-control-realtime.ts +36 -36
  73. package/src/runtime/live-session-runtime.ts +299 -299
  74. package/src/runtime/manifest-cache.ts +212 -214
  75. package/src/runtime/model-fallback.ts +261 -261
  76. package/src/runtime/parallel-research.ts +44 -44
  77. package/src/runtime/parallel-utils.ts +99 -99
  78. package/src/runtime/pi-json-output.ts +111 -111
  79. package/src/runtime/pi-spawn.ts +96 -96
  80. package/src/runtime/policy-engine.ts +78 -78
  81. package/src/runtime/post-exit-stdio-guard.ts +86 -86
  82. package/src/runtime/process-status.ts +56 -56
  83. package/src/runtime/progress-event-coalescer.ts +43 -43
  84. package/src/runtime/recovery-recipes.ts +74 -74
  85. package/src/runtime/role-permission.ts +39 -39
  86. package/src/runtime/session-usage.ts +79 -79
  87. package/src/runtime/sidechain-output.ts +28 -28
  88. package/src/runtime/subagent-manager.ts +29 -2
  89. package/src/runtime/task-display.ts +38 -38
  90. package/src/runtime/task-output-context.ts +106 -106
  91. package/src/runtime/task-packet.ts +84 -84
  92. package/src/runtime/task-runner/live-executor.ts +98 -98
  93. package/src/runtime/task-runner/progress.ts +111 -111
  94. package/src/runtime/task-runner/prompt-builder.ts +72 -72
  95. package/src/runtime/task-runner/result-utils.ts +14 -14
  96. package/src/runtime/task-runner/state-helpers.ts +22 -22
  97. package/src/runtime/worker-heartbeat.ts +21 -21
  98. package/src/runtime/worker-startup.ts +57 -57
  99. package/src/schema/config-schema.ts +12 -0
  100. package/src/schema/team-tool-schema.ts +100 -100
  101. package/src/state/artifact-store.ts +108 -108
  102. package/src/state/contracts.ts +105 -105
  103. package/src/state/jsonl-writer.ts +77 -77
  104. package/src/state/state-store.ts +8 -9
  105. package/src/state/task-claims.ts +42 -42
  106. package/src/state/types.ts +180 -180
  107. package/src/state/usage.ts +29 -29
  108. package/src/subagents/async-entry.ts +1 -1
  109. package/src/subagents/index.ts +3 -3
  110. package/src/subagents/live/control.ts +1 -1
  111. package/src/subagents/live/manager.ts +1 -1
  112. package/src/subagents/live/realtime.ts +1 -1
  113. package/src/subagents/live/session-runtime.ts +1 -1
  114. package/src/subagents/manager.ts +1 -1
  115. package/src/subagents/spawn.ts +1 -1
  116. package/src/teams/discover-teams.ts +2 -2
  117. package/src/teams/team-serializer.ts +36 -36
  118. package/src/types/diff.d.ts +18 -0
  119. package/src/ui/crew-footer.ts +101 -101
  120. package/src/ui/crew-select-list.ts +111 -111
  121. package/src/ui/crew-widget.ts +285 -285
  122. package/src/ui/dynamic-border.ts +25 -25
  123. package/src/ui/layout-primitives.ts +106 -106
  124. package/src/ui/loaders.ts +158 -158
  125. package/src/ui/mascot.ts +441 -441
  126. package/src/ui/powerbar-publisher.ts +94 -94
  127. package/src/ui/render-diff.ts +119 -119
  128. package/src/ui/run-dashboard.ts +372 -372
  129. package/src/ui/status-colors.ts +54 -54
  130. package/src/ui/syntax-highlight.ts +116 -116
  131. package/src/ui/transcript-viewer.ts +302 -302
  132. package/src/utils/completion-dedupe.ts +63 -63
  133. package/src/utils/file-coalescer.ts +84 -84
  134. package/src/utils/frontmatter.ts +36 -36
  135. package/src/utils/fs-watch.ts +31 -31
  136. package/src/utils/git.ts +262 -262
  137. package/src/utils/ids.ts +12 -12
  138. package/src/utils/names.ts +26 -26
  139. package/src/utils/paths.ts +34 -7
  140. package/src/utils/sleep.ts +32 -32
  141. package/src/utils/timings.ts +31 -31
  142. package/src/utils/visual.ts +159 -159
  143. package/src/workflows/discover-workflows.ts +2 -2
  144. package/src/workflows/validate-workflow.ts +40 -40
  145. package/src/worktree/branch-freshness.ts +45 -45
  146. package/src/worktree/cleanup.ts +71 -69
  147. package/src/worktree/worktree-manager.ts +3 -1
  148. package/teams/default.team.md +12 -12
  149. package/teams/fast-fix.team.md +11 -11
  150. package/teams/implementation.team.md +18 -18
  151. package/teams/parallel-research.team.md +14 -14
  152. package/teams/research.team.md +11 -11
  153. package/teams/review.team.md +12 -12
  154. package/workflows/default.workflow.md +29 -29
  155. package/workflows/fast-fix.workflow.md +22 -22
  156. package/workflows/implementation.workflow.md +38 -38
  157. package/workflows/parallel-research.workflow.md +46 -46
  158. package/workflows/research.workflow.md +22 -22
  159. package/workflows/review.workflow.md +30 -30
@@ -1,77 +1,77 @@
1
- import * as fs from "node:fs";
2
-
3
- export interface DrainableSource {
4
- pause(): void;
5
- resume(): void;
6
- }
7
-
8
- export interface JsonlWriteStream {
9
- write(chunk: string): boolean;
10
- once(event: "drain", listener: () => void): JsonlWriteStream;
11
- end(callback?: () => void): void;
12
- }
13
-
14
- const DEFAULT_MAX_JSONL_BYTES = 50 * 1024 * 1024;
15
-
16
- export interface JsonlWriterDeps {
17
- createWriteStream?: (filePath: string) => JsonlWriteStream;
18
- maxBytes?: number;
19
- }
20
-
21
- export interface JsonlWriter {
22
- writeLine(line: string): void;
23
- close(): Promise<void>;
24
- }
25
-
26
- export function createJsonlWriter(filePath: string | undefined, source: DrainableSource, deps: JsonlWriterDeps = {}): JsonlWriter {
27
- if (!filePath) {
28
- return {
29
- writeLine() {},
30
- async close() {},
31
- };
32
- }
33
-
34
- const createWriteStream = deps.createWriteStream ?? ((targetPath: string) => fs.createWriteStream(targetPath, { flags: "a" }));
35
- let stream: JsonlWriteStream | undefined;
36
- try {
37
- stream = createWriteStream(filePath);
38
- } catch {
39
- return {
40
- writeLine() {},
41
- async close() {},
42
- };
43
- }
44
-
45
- let backpressured = false;
46
- let closed = false;
47
- let bytesWritten = 0;
48
- const maxBytes = deps.maxBytes ?? DEFAULT_MAX_JSONL_BYTES;
49
-
50
- return {
51
- writeLine(line: string) {
52
- if (!stream || closed || !line.trim()) return;
53
- const chunk = `${line}\n`;
54
- const chunkBytes = Buffer.byteLength(chunk, "utf-8");
55
- if (bytesWritten + chunkBytes > maxBytes) return;
56
- try {
57
- const ok = stream.write(chunk);
58
- bytesWritten += chunkBytes;
59
- if (!ok && !backpressured) {
60
- backpressured = true;
61
- source.pause();
62
- stream.once("drain", () => {
63
- backpressured = false;
64
- if (!closed) source.resume();
65
- });
66
- }
67
- } catch {}
68
- },
69
- async close() {
70
- if (!stream || closed) return;
71
- closed = true;
72
- const current = stream;
73
- stream = undefined;
74
- await new Promise<void>((resolve) => current.end(() => resolve()));
75
- },
76
- };
77
- }
1
+ import * as fs from "node:fs";
2
+
3
+ export interface DrainableSource {
4
+ pause(): void;
5
+ resume(): void;
6
+ }
7
+
8
+ export interface JsonlWriteStream {
9
+ write(chunk: string): boolean;
10
+ once(event: "drain", listener: () => void): JsonlWriteStream;
11
+ end(callback?: () => void): void;
12
+ }
13
+
14
+ const DEFAULT_MAX_JSONL_BYTES = 50 * 1024 * 1024;
15
+
16
+ export interface JsonlWriterDeps {
17
+ createWriteStream?: (filePath: string) => JsonlWriteStream;
18
+ maxBytes?: number;
19
+ }
20
+
21
+ export interface JsonlWriter {
22
+ writeLine(line: string): void;
23
+ close(): Promise<void>;
24
+ }
25
+
26
+ export function createJsonlWriter(filePath: string | undefined, source: DrainableSource, deps: JsonlWriterDeps = {}): JsonlWriter {
27
+ if (!filePath) {
28
+ return {
29
+ writeLine() {},
30
+ async close() {},
31
+ };
32
+ }
33
+
34
+ const createWriteStream = deps.createWriteStream ?? ((targetPath: string) => fs.createWriteStream(targetPath, { flags: "a" }));
35
+ let stream: JsonlWriteStream | undefined;
36
+ try {
37
+ stream = createWriteStream(filePath);
38
+ } catch {
39
+ return {
40
+ writeLine() {},
41
+ async close() {},
42
+ };
43
+ }
44
+
45
+ let backpressured = false;
46
+ let closed = false;
47
+ let bytesWritten = 0;
48
+ const maxBytes = deps.maxBytes ?? DEFAULT_MAX_JSONL_BYTES;
49
+
50
+ return {
51
+ writeLine(line: string) {
52
+ if (!stream || closed || !line.trim()) return;
53
+ const chunk = `${line}\n`;
54
+ const chunkBytes = Buffer.byteLength(chunk, "utf-8");
55
+ if (bytesWritten + chunkBytes > maxBytes) return;
56
+ try {
57
+ const ok = stream.write(chunk);
58
+ bytesWritten += chunkBytes;
59
+ if (!ok && !backpressured) {
60
+ backpressured = true;
61
+ source.pause();
62
+ stream.once("drain", () => {
63
+ backpressured = false;
64
+ if (!closed) source.resume();
65
+ });
66
+ }
67
+ } catch {}
68
+ },
69
+ async close() {
70
+ if (!stream || closed) return;
71
+ closed = true;
72
+ const current = stream;
73
+ stream = undefined;
74
+ await new Promise<void>((resolve) => current.end(() => resolve()));
75
+ },
76
+ };
77
+ }
@@ -6,7 +6,7 @@ import { atomicWriteJson, atomicWriteJsonAsync, readJsonFile } from "./atomic-wr
6
6
  import { appendEvent } from "./event-log.ts";
7
7
  import { DEFAULT_CACHE, DEFAULT_PATHS } from "../config/defaults.ts";
8
8
  import { createRunId, createTaskId } from "../utils/ids.ts";
9
- import { findRepoRoot, projectPiRoot, userPiRoot } from "../utils/paths.ts";
9
+ import { findRepoRoot, projectCrewRoot, userCrewRoot } from "../utils/paths.ts";
10
10
  import type { TeamConfig } from "../teams/team-config.ts";
11
11
  import type { WorkflowConfig } from "../workflows/workflow-config.ts";
12
12
 
@@ -48,18 +48,17 @@ function invalidateRunCache(stateRoot: string): void {
48
48
  manifestCache.delete(stateRoot);
49
49
  }
50
50
 
51
+ function scopeBaseRoot(cwd: string): string {
52
+ return useProjectState(cwd) ? projectCrewRoot(cwd) : userCrewRoot();
53
+ }
54
+
51
55
  function resolveRunStateRoot(cwd: string, runId: string): string | undefined {
52
- const projectPath = path.join(projectPiRoot(cwd), DEFAULT_PATHS.state.projectBase, DEFAULT_PATHS.state.runsSubdir, runId);
53
- const userPath = path.join(userPiRoot(), "extensions", "pi-crew", DEFAULT_PATHS.state.userBase, DEFAULT_PATHS.state.runsSubdir, runId);
54
- if (fs.existsSync(projectPath)) return projectPath;
55
- if (fs.existsSync(userPath)) return userPath;
56
- return undefined;
56
+ const scopedPath = path.join(scopeBaseRoot(cwd), DEFAULT_PATHS.state.runsSubdir, runId);
57
+ return fs.existsSync(scopedPath) ? scopedPath : undefined;
57
58
  }
58
59
 
59
60
  export function createRunPaths(cwd: string, runId = createRunId()): RunPaths {
60
- const baseRoot = useProjectState(cwd)
61
- ? path.join(projectPiRoot(cwd), DEFAULT_PATHS.state.projectBase)
62
- : path.join(userPiRoot(), "extensions", "pi-crew", DEFAULT_PATHS.state.userBase);
61
+ const baseRoot = scopeBaseRoot(cwd);
63
62
  const stateRoot = path.join(baseRoot, DEFAULT_PATHS.state.runsSubdir, runId);
64
63
  const artifactsRoot = path.join(baseRoot, DEFAULT_PATHS.state.artifactsSubdir, runId);
65
64
  return {
@@ -1,42 +1,42 @@
1
- import { randomUUID } from "node:crypto";
2
- import type { TeamTaskState } from "./types.ts";
3
-
4
- export interface TaskClaimState {
5
- owner: string;
6
- token: string;
7
- leasedUntil: string;
8
- }
9
-
10
- export function createTaskClaim(owner: string, leaseMs = 5 * 60_000, now = new Date()): TaskClaimState {
11
- return { owner, token: randomUUID(), leasedUntil: new Date(now.getTime() + leaseMs).toISOString() };
12
- }
13
-
14
- export function isTaskClaimExpired(claim: TaskClaimState | undefined, now = new Date()): boolean {
15
- if (!claim) return false;
16
- return Date.parse(claim.leasedUntil) <= now.getTime();
17
- }
18
-
19
- export function canUseTaskClaim(task: Pick<TeamTaskState, "claim">, owner: string, token: string, now = new Date()): boolean {
20
- return task.claim?.owner === owner && task.claim.token === token && !isTaskClaimExpired(task.claim, now);
21
- }
22
-
23
- export function claimTask<T extends TeamTaskState>(task: T, owner: string, leaseMs?: number, now = new Date()): T {
24
- if (task.claim && !isTaskClaimExpired(task.claim, now)) {
25
- throw new Error(`Task '${task.id}' is already claimed by '${task.claim.owner}'.`);
26
- }
27
- return { ...task, claim: createTaskClaim(owner, leaseMs, now) };
28
- }
29
-
30
- export function releaseTaskClaim<T extends TeamTaskState>(task: T, owner: string, token: string, now = new Date()): T {
31
- if (!canUseTaskClaim(task, owner, token, now)) {
32
- throw new Error(`Task '${task.id}' claim is not held by '${owner}' or has expired.`);
33
- }
34
- return { ...task, claim: undefined };
35
- }
36
-
37
- export function transitionClaimedTaskStatus<T extends TeamTaskState>(task: T, owner: string, token: string, status: T["status"], now = new Date()): T {
38
- if (!canUseTaskClaim(task, owner, token, now)) {
39
- throw new Error(`Task '${task.id}' claim is not held by '${owner}' or has expired.`);
40
- }
41
- return { ...task, status };
42
- }
1
+ import { randomUUID } from "node:crypto";
2
+ import type { TeamTaskState } from "./types.ts";
3
+
4
+ export interface TaskClaimState {
5
+ owner: string;
6
+ token: string;
7
+ leasedUntil: string;
8
+ }
9
+
10
+ export function createTaskClaim(owner: string, leaseMs = 5 * 60_000, now = new Date()): TaskClaimState {
11
+ return { owner, token: randomUUID(), leasedUntil: new Date(now.getTime() + leaseMs).toISOString() };
12
+ }
13
+
14
+ export function isTaskClaimExpired(claim: TaskClaimState | undefined, now = new Date()): boolean {
15
+ if (!claim) return false;
16
+ return Date.parse(claim.leasedUntil) <= now.getTime();
17
+ }
18
+
19
+ export function canUseTaskClaim(task: Pick<TeamTaskState, "claim">, owner: string, token: string, now = new Date()): boolean {
20
+ return task.claim?.owner === owner && task.claim.token === token && !isTaskClaimExpired(task.claim, now);
21
+ }
22
+
23
+ export function claimTask<T extends TeamTaskState>(task: T, owner: string, leaseMs?: number, now = new Date()): T {
24
+ if (task.claim && !isTaskClaimExpired(task.claim, now)) {
25
+ throw new Error(`Task '${task.id}' is already claimed by '${task.claim.owner}'.`);
26
+ }
27
+ return { ...task, claim: createTaskClaim(owner, leaseMs, now) };
28
+ }
29
+
30
+ export function releaseTaskClaim<T extends TeamTaskState>(task: T, owner: string, token: string, now = new Date()): T {
31
+ if (!canUseTaskClaim(task, owner, token, now)) {
32
+ throw new Error(`Task '${task.id}' claim is not held by '${owner}' or has expired.`);
33
+ }
34
+ return { ...task, claim: undefined };
35
+ }
36
+
37
+ export function transitionClaimedTaskStatus<T extends TeamTaskState>(task: T, owner: string, token: string, status: T["status"], now = new Date()): T {
38
+ if (!canUseTaskClaim(task, owner, token, now)) {
39
+ throw new Error(`Task '${task.id}' claim is not held by '${owner}' or has expired.`);
40
+ }
41
+ return { ...task, status };
42
+ }
@@ -1,180 +1,180 @@
1
- import type { TeamRunStatus, TeamTaskStatus } from "./contracts.ts";
2
- import type { TaskClaimState } from "./task-claims.ts";
3
- import type { WorkerHeartbeatState } from "../runtime/worker-heartbeat.ts";
4
- import type { CrewAgentProgress } from "../runtime/crew-agent-runtime.ts";
5
- export type { TeamRunStatus, TeamTaskStatus } from "./contracts.ts";
6
-
7
- export interface ArtifactDescriptor {
8
- kind: "plan" | "prompt" | "result" | "summary" | "log" | "diff" | "patch" | "progress" | "notepad" | "metadata";
9
- path: string;
10
- createdAt: string;
11
- producer: string;
12
- sizeBytes?: number;
13
- contentHash?: string;
14
- retention: "run" | "project" | "temporary";
15
- expiresAt?: string;
16
- }
17
-
18
- export type TaskScope = "workspace" | "module" | "single_file" | "custom";
19
- export type GreenLevel = "none" | "targeted" | "package" | "workspace" | "merge_ready";
20
-
21
- export interface VerificationCommandResult {
22
- cmd: string;
23
- status: "passed" | "failed" | "not_run";
24
- exitCode?: number | null;
25
- outputArtifact?: ArtifactDescriptor;
26
- }
27
-
28
- export interface VerificationContract {
29
- requiredGreenLevel: GreenLevel;
30
- commands: string[];
31
- allowManualEvidence: boolean;
32
- }
33
-
34
- export interface VerificationEvidence {
35
- requiredGreenLevel: GreenLevel;
36
- observedGreenLevel: GreenLevel;
37
- satisfied: boolean;
38
- commands: VerificationCommandResult[];
39
- notes?: string;
40
- }
41
-
42
- export interface TaskPacket {
43
- objective: string;
44
- scope: TaskScope;
45
- scopePath?: string;
46
- repo: string;
47
- worktree?: string;
48
- branchPolicy: string;
49
- acceptanceTests: string[];
50
- commitPolicy: string;
51
- reportingContract: string;
52
- escalationPolicy: string;
53
- constraints: string[];
54
- expectedArtifacts: string[];
55
- verification: VerificationContract;
56
- }
57
-
58
- export type PolicyDecisionAction = "retry" | "reassign" | "escalate" | "block" | "notify" | "cleanup" | "closeout";
59
- export type PolicyDecisionReason = "task_failed" | "worker_stale" | "green_unsatisfied" | "limit_exceeded" | "run_complete" | "mailbox_timeout" | "review_rejected" | "branch_stale" | "scope_mismatch";
60
-
61
- export interface PolicyDecision {
62
- action: PolicyDecisionAction;
63
- reason: PolicyDecisionReason;
64
- message: string;
65
- taskId?: string;
66
- createdAt: string;
67
- }
68
-
69
- export interface TaskGraphNode {
70
- taskId: string;
71
- parentId?: string;
72
- children: string[];
73
- dependencies: string[];
74
- queue: "ready" | "blocked" | "running" | "done";
75
- sessionForkFrom?: string;
76
- }
77
-
78
- export interface AsyncRunState {
79
- pid?: number;
80
- logPath: string;
81
- spawnedAt: string;
82
- }
83
-
84
- export interface TeamRunManifest {
85
- schemaVersion: 1;
86
- runId: string;
87
- team: string;
88
- workflow?: string;
89
- goal: string;
90
- status: TeamRunStatus;
91
- workspaceMode: "single" | "worktree";
92
- createdAt: string;
93
- updatedAt: string;
94
- cwd: string;
95
- stateRoot: string;
96
- artifactsRoot: string;
97
- tasksPath: string;
98
- eventsPath: string;
99
- artifacts: ArtifactDescriptor[];
100
- async?: AsyncRunState;
101
- summary?: string;
102
- policyDecisions?: PolicyDecision[];
103
- }
104
-
105
- export interface UsageState {
106
- input?: number;
107
- output?: number;
108
- cacheRead?: number;
109
- cacheWrite?: number;
110
- cost?: number;
111
- turns?: number;
112
- }
113
-
114
- export interface ModelAttemptState {
115
- model: string;
116
- success: boolean;
117
- exitCode?: number | null;
118
- error?: string;
119
- }
120
-
121
- export interface ModelRoutingState {
122
- requested?: string;
123
- resolved: string;
124
- fallbackChain: string[];
125
- reason?: string;
126
- usedAttempt: number;
127
- }
128
-
129
- export interface TaskWorktreeState {
130
- path: string;
131
- branch: string;
132
- reused: boolean;
133
- }
134
-
135
- export interface TaskCheckpointState {
136
- phase: "started" | "child-spawned" | "child-stdout-final" | "artifact-written";
137
- updatedAt: string;
138
- childPid?: number;
139
- }
140
-
141
- export interface TeamTaskState {
142
- id: string;
143
- runId: string;
144
- stepId?: string;
145
- role: string;
146
- agent: string;
147
- title: string;
148
- status: TeamTaskStatus;
149
- dependsOn: string[];
150
- cwd: string;
151
- worktree?: TaskWorktreeState;
152
- promptArtifact?: ArtifactDescriptor;
153
- resultArtifact?: ArtifactDescriptor;
154
- logArtifact?: ArtifactDescriptor;
155
- transcriptArtifact?: ArtifactDescriptor;
156
- startedAt?: string;
157
- finishedAt?: string;
158
- exitCode?: number | null;
159
- model?: string;
160
- modelAttempts?: ModelAttemptState[];
161
- modelRouting?: ModelRoutingState;
162
- usage?: UsageState;
163
- jsonEvents?: number;
164
- agentProgress?: CrewAgentProgress;
165
- error?: string;
166
- claim?: TaskClaimState;
167
- heartbeat?: WorkerHeartbeatState;
168
- checkpoint?: TaskCheckpointState;
169
- taskPacket?: TaskPacket;
170
- verification?: VerificationEvidence;
171
- graph?: TaskGraphNode;
172
- adaptive?: {
173
- phase: string;
174
- task: string;
175
- };
176
- policy?: {
177
- retryCount?: number;
178
- lastDecision?: PolicyDecision;
179
- };
180
- }
1
+ import type { TeamRunStatus, TeamTaskStatus } from "./contracts.ts";
2
+ import type { TaskClaimState } from "./task-claims.ts";
3
+ import type { WorkerHeartbeatState } from "../runtime/worker-heartbeat.ts";
4
+ import type { CrewAgentProgress } from "../runtime/crew-agent-runtime.ts";
5
+ export type { TeamRunStatus, TeamTaskStatus } from "./contracts.ts";
6
+
7
+ export interface ArtifactDescriptor {
8
+ kind: "plan" | "prompt" | "result" | "summary" | "log" | "diff" | "patch" | "progress" | "notepad" | "metadata";
9
+ path: string;
10
+ createdAt: string;
11
+ producer: string;
12
+ sizeBytes?: number;
13
+ contentHash?: string;
14
+ retention: "run" | "project" | "temporary";
15
+ expiresAt?: string;
16
+ }
17
+
18
+ export type TaskScope = "workspace" | "module" | "single_file" | "custom";
19
+ export type GreenLevel = "none" | "targeted" | "package" | "workspace" | "merge_ready";
20
+
21
+ export interface VerificationCommandResult {
22
+ cmd: string;
23
+ status: "passed" | "failed" | "not_run";
24
+ exitCode?: number | null;
25
+ outputArtifact?: ArtifactDescriptor;
26
+ }
27
+
28
+ export interface VerificationContract {
29
+ requiredGreenLevel: GreenLevel;
30
+ commands: string[];
31
+ allowManualEvidence: boolean;
32
+ }
33
+
34
+ export interface VerificationEvidence {
35
+ requiredGreenLevel: GreenLevel;
36
+ observedGreenLevel: GreenLevel;
37
+ satisfied: boolean;
38
+ commands: VerificationCommandResult[];
39
+ notes?: string;
40
+ }
41
+
42
+ export interface TaskPacket {
43
+ objective: string;
44
+ scope: TaskScope;
45
+ scopePath?: string;
46
+ repo: string;
47
+ worktree?: string;
48
+ branchPolicy: string;
49
+ acceptanceTests: string[];
50
+ commitPolicy: string;
51
+ reportingContract: string;
52
+ escalationPolicy: string;
53
+ constraints: string[];
54
+ expectedArtifacts: string[];
55
+ verification: VerificationContract;
56
+ }
57
+
58
+ export type PolicyDecisionAction = "retry" | "reassign" | "escalate" | "block" | "notify" | "cleanup" | "closeout";
59
+ export type PolicyDecisionReason = "task_failed" | "worker_stale" | "green_unsatisfied" | "limit_exceeded" | "run_complete" | "mailbox_timeout" | "review_rejected" | "branch_stale" | "scope_mismatch";
60
+
61
+ export interface PolicyDecision {
62
+ action: PolicyDecisionAction;
63
+ reason: PolicyDecisionReason;
64
+ message: string;
65
+ taskId?: string;
66
+ createdAt: string;
67
+ }
68
+
69
+ export interface TaskGraphNode {
70
+ taskId: string;
71
+ parentId?: string;
72
+ children: string[];
73
+ dependencies: string[];
74
+ queue: "ready" | "blocked" | "running" | "done";
75
+ sessionForkFrom?: string;
76
+ }
77
+
78
+ export interface AsyncRunState {
79
+ pid?: number;
80
+ logPath: string;
81
+ spawnedAt: string;
82
+ }
83
+
84
+ export interface TeamRunManifest {
85
+ schemaVersion: 1;
86
+ runId: string;
87
+ team: string;
88
+ workflow?: string;
89
+ goal: string;
90
+ status: TeamRunStatus;
91
+ workspaceMode: "single" | "worktree";
92
+ createdAt: string;
93
+ updatedAt: string;
94
+ cwd: string;
95
+ stateRoot: string;
96
+ artifactsRoot: string;
97
+ tasksPath: string;
98
+ eventsPath: string;
99
+ artifacts: ArtifactDescriptor[];
100
+ async?: AsyncRunState;
101
+ summary?: string;
102
+ policyDecisions?: PolicyDecision[];
103
+ }
104
+
105
+ export interface UsageState {
106
+ input?: number;
107
+ output?: number;
108
+ cacheRead?: number;
109
+ cacheWrite?: number;
110
+ cost?: number;
111
+ turns?: number;
112
+ }
113
+
114
+ export interface ModelAttemptState {
115
+ model: string;
116
+ success: boolean;
117
+ exitCode?: number | null;
118
+ error?: string;
119
+ }
120
+
121
+ export interface ModelRoutingState {
122
+ requested?: string;
123
+ resolved: string;
124
+ fallbackChain: string[];
125
+ reason?: string;
126
+ usedAttempt: number;
127
+ }
128
+
129
+ export interface TaskWorktreeState {
130
+ path: string;
131
+ branch: string;
132
+ reused: boolean;
133
+ }
134
+
135
+ export interface TaskCheckpointState {
136
+ phase: "started" | "child-spawned" | "child-stdout-final" | "artifact-written";
137
+ updatedAt: string;
138
+ childPid?: number;
139
+ }
140
+
141
+ export interface TeamTaskState {
142
+ id: string;
143
+ runId: string;
144
+ stepId?: string;
145
+ role: string;
146
+ agent: string;
147
+ title: string;
148
+ status: TeamTaskStatus;
149
+ dependsOn: string[];
150
+ cwd: string;
151
+ worktree?: TaskWorktreeState;
152
+ promptArtifact?: ArtifactDescriptor;
153
+ resultArtifact?: ArtifactDescriptor;
154
+ logArtifact?: ArtifactDescriptor;
155
+ transcriptArtifact?: ArtifactDescriptor;
156
+ startedAt?: string;
157
+ finishedAt?: string;
158
+ exitCode?: number | null;
159
+ model?: string;
160
+ modelAttempts?: ModelAttemptState[];
161
+ modelRouting?: ModelRoutingState;
162
+ usage?: UsageState;
163
+ jsonEvents?: number;
164
+ agentProgress?: CrewAgentProgress;
165
+ error?: string;
166
+ claim?: TaskClaimState;
167
+ heartbeat?: WorkerHeartbeatState;
168
+ checkpoint?: TaskCheckpointState;
169
+ taskPacket?: TaskPacket;
170
+ verification?: VerificationEvidence;
171
+ graph?: TaskGraphNode;
172
+ adaptive?: {
173
+ phase: string;
174
+ task: string;
175
+ };
176
+ policy?: {
177
+ retryCount?: number;
178
+ lastDecision?: PolicyDecision;
179
+ };
180
+ }