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.
- package/CHANGELOG.md +9 -0
- package/README.md +80 -27
- package/agents/analyst.md +11 -11
- package/agents/critic.md +11 -11
- package/agents/executor.md +11 -11
- package/agents/explorer.md +11 -11
- package/agents/planner.md +11 -11
- package/agents/reviewer.md +11 -11
- package/agents/security-reviewer.md +11 -11
- package/agents/test-engineer.md +11 -11
- package/agents/verifier.md +11 -11
- package/agents/writer.md +11 -11
- package/docs/architecture.md +173 -164
- package/docs/refactor-tasks-phase3.md +394 -394
- package/docs/refactor-tasks-phase4.md +564 -564
- package/docs/refactor-tasks-phase5.md +402 -402
- package/docs/refactor-tasks-phase6.md +662 -662
- package/docs/research-extension-examples.md +297 -0
- package/docs/research-extension-system.md +324 -0
- package/docs/research-optimization-plan.md +548 -0
- package/docs/research-pi-coding-agent.md +357 -0
- package/docs/resource-formats.md +4 -3
- package/docs/runtime-flow.md +148 -148
- package/docs/source-runtime-refactor-map.md +83 -83
- package/docs/usage.md +3 -3
- package/index.ts +6 -6
- package/package.json +1 -1
- package/schema.json +53 -1
- package/skills/git-master/SKILL.md +24 -19
- package/skills/read-only-explorer/SKILL.md +26 -21
- package/skills/safe-bash/SKILL.md +21 -16
- package/skills/task-packet/SKILL.md +28 -23
- package/skills/verify-evidence/SKILL.md +27 -22
- package/src/agents/agent-serializer.ts +34 -34
- package/src/agents/discover-agents.ts +102 -102
- package/src/config/config.ts +14 -1
- package/src/config/defaults.ts +3 -2
- package/src/extension/cross-extension-rpc.ts +82 -82
- package/src/extension/import-index.ts +4 -3
- package/src/extension/management.ts +2 -2
- package/src/extension/project-init.ts +9 -7
- package/src/extension/register.ts +63 -0
- package/src/extension/registration/artifact-cleanup.ts +15 -14
- package/src/extension/registration/commands.ts +208 -208
- package/src/extension/registration/compaction-guard.ts +125 -0
- package/src/extension/registration/subagent-tools.ts +27 -8
- package/src/extension/registration/team-tool.ts +61 -44
- package/src/extension/result-watcher.ts +98 -98
- package/src/extension/run-import.ts +4 -4
- package/src/extension/run-index.ts +14 -14
- package/src/extension/run-maintenance.ts +24 -24
- package/src/extension/team-tool/api.ts +3 -0
- package/src/extension/team-tool/cancel.ts +31 -31
- package/src/extension/team-tool/doctor.ts +179 -178
- package/src/extension/team-tool/inspect.ts +41 -41
- package/src/extension/team-tool/lifecycle-actions.ts +79 -79
- package/src/extension/team-tool/plan.ts +19 -19
- package/src/extension/team-tool/status.ts +73 -73
- package/src/prompt/prompt-runtime.ts +68 -68
- package/src/runtime/agent-control.ts +64 -64
- package/src/runtime/agent-memory.ts +72 -72
- package/src/runtime/agent-observability.ts +113 -113
- package/src/runtime/async-marker.ts +26 -26
- package/src/runtime/background-runner.ts +53 -53
- package/src/runtime/crew-agent-runtime.ts +58 -58
- package/src/runtime/direct-run.ts +35 -35
- package/src/runtime/foreground-control.ts +82 -82
- package/src/runtime/green-contract.ts +46 -46
- package/src/runtime/group-join.ts +88 -88
- package/src/runtime/live-agent-control.ts +78 -78
- package/src/runtime/live-agent-manager.ts +85 -85
- package/src/runtime/live-control-realtime.ts +36 -36
- package/src/runtime/live-session-runtime.ts +299 -299
- package/src/runtime/manifest-cache.ts +212 -214
- package/src/runtime/model-fallback.ts +261 -261
- package/src/runtime/parallel-research.ts +44 -44
- package/src/runtime/parallel-utils.ts +99 -99
- package/src/runtime/pi-json-output.ts +111 -111
- package/src/runtime/pi-spawn.ts +96 -96
- package/src/runtime/policy-engine.ts +78 -78
- package/src/runtime/post-exit-stdio-guard.ts +86 -86
- package/src/runtime/process-status.ts +56 -56
- package/src/runtime/progress-event-coalescer.ts +43 -43
- package/src/runtime/recovery-recipes.ts +74 -74
- package/src/runtime/role-permission.ts +39 -39
- package/src/runtime/session-usage.ts +79 -79
- package/src/runtime/sidechain-output.ts +28 -28
- package/src/runtime/subagent-manager.ts +29 -2
- package/src/runtime/task-display.ts +38 -38
- package/src/runtime/task-output-context.ts +106 -106
- package/src/runtime/task-packet.ts +84 -84
- package/src/runtime/task-runner/live-executor.ts +98 -98
- package/src/runtime/task-runner/progress.ts +111 -111
- package/src/runtime/task-runner/prompt-builder.ts +72 -72
- package/src/runtime/task-runner/result-utils.ts +14 -14
- package/src/runtime/task-runner/state-helpers.ts +22 -22
- package/src/runtime/worker-heartbeat.ts +21 -21
- package/src/runtime/worker-startup.ts +57 -57
- package/src/schema/config-schema.ts +12 -0
- package/src/schema/team-tool-schema.ts +100 -100
- package/src/state/artifact-store.ts +108 -108
- package/src/state/contracts.ts +105 -105
- package/src/state/jsonl-writer.ts +77 -77
- package/src/state/state-store.ts +8 -9
- package/src/state/task-claims.ts +42 -42
- package/src/state/types.ts +180 -180
- package/src/state/usage.ts +29 -29
- package/src/subagents/async-entry.ts +1 -1
- package/src/subagents/index.ts +3 -3
- package/src/subagents/live/control.ts +1 -1
- package/src/subagents/live/manager.ts +1 -1
- package/src/subagents/live/realtime.ts +1 -1
- package/src/subagents/live/session-runtime.ts +1 -1
- package/src/subagents/manager.ts +1 -1
- package/src/subagents/spawn.ts +1 -1
- package/src/teams/discover-teams.ts +2 -2
- package/src/teams/team-serializer.ts +36 -36
- package/src/types/diff.d.ts +18 -0
- package/src/ui/crew-footer.ts +101 -101
- package/src/ui/crew-select-list.ts +111 -111
- package/src/ui/crew-widget.ts +285 -285
- package/src/ui/dynamic-border.ts +25 -25
- package/src/ui/layout-primitives.ts +106 -106
- package/src/ui/loaders.ts +158 -158
- package/src/ui/mascot.ts +441 -441
- package/src/ui/powerbar-publisher.ts +94 -94
- package/src/ui/render-diff.ts +119 -119
- package/src/ui/run-dashboard.ts +372 -372
- package/src/ui/status-colors.ts +54 -54
- package/src/ui/syntax-highlight.ts +116 -116
- package/src/ui/transcript-viewer.ts +302 -302
- package/src/utils/completion-dedupe.ts +63 -63
- package/src/utils/file-coalescer.ts +84 -84
- package/src/utils/frontmatter.ts +36 -36
- package/src/utils/fs-watch.ts +31 -31
- package/src/utils/git.ts +262 -262
- package/src/utils/ids.ts +12 -12
- package/src/utils/names.ts +26 -26
- package/src/utils/paths.ts +34 -7
- package/src/utils/sleep.ts +32 -32
- package/src/utils/timings.ts +31 -31
- package/src/utils/visual.ts +159 -159
- package/src/workflows/discover-workflows.ts +2 -2
- package/src/workflows/validate-workflow.ts +40 -40
- package/src/worktree/branch-freshness.ts +45 -45
- package/src/worktree/cleanup.ts +71 -69
- package/src/worktree/worktree-manager.ts +3 -1
- package/teams/default.team.md +12 -12
- package/teams/fast-fix.team.md +11 -11
- package/teams/implementation.team.md +18 -18
- package/teams/parallel-research.team.md +14 -14
- package/teams/research.team.md +11 -11
- package/teams/review.team.md +12 -12
- package/workflows/default.workflow.md +29 -29
- package/workflows/fast-fix.workflow.md +22 -22
- package/workflows/implementation.workflow.md +38 -38
- package/workflows/parallel-research.workflow.md +46 -46
- package/workflows/research.workflow.md +22 -22
- 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
|
+
}
|
package/src/state/state-store.ts
CHANGED
|
@@ -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,
|
|
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
|
|
53
|
-
|
|
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 =
|
|
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 {
|
package/src/state/task-claims.ts
CHANGED
|
@@ -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
|
+
}
|
package/src/state/types.ts
CHANGED
|
@@ -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
|
+
}
|