pi-crew 0.1.28 → 0.1.30
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 +42 -0
- package/NOTICE.md +1 -0
- package/docs/architecture.md +164 -92
- package/docs/refactor-tasks-phase6.md +662 -0
- package/docs/runtime-flow.md +148 -0
- package/package.json +1 -1
- package/schema.json +1 -0
- package/skills/git-master/SKILL.md +19 -0
- package/skills/read-only-explorer/SKILL.md +21 -0
- package/skills/safe-bash/SKILL.md +16 -0
- package/skills/task-packet/SKILL.md +23 -0
- package/skills/verify-evidence/SKILL.md +22 -0
- package/src/config/config.ts +2 -0
- package/src/config/defaults.ts +1 -0
- package/src/extension/async-notifier.ts +33 -4
- package/src/extension/register.ts +15 -522
- package/src/extension/registration/artifact-cleanup.ts +14 -0
- package/src/extension/registration/commands.ts +208 -0
- package/src/extension/registration/subagent-helpers.ts +1 -1
- package/src/extension/registration/subagent-tools.ts +110 -0
- package/src/extension/registration/team-tool.ts +44 -0
- package/src/extension/team-tool/api.ts +4 -4
- package/src/extension/team-tool/cancel.ts +31 -0
- package/src/extension/team-tool/inspect.ts +41 -0
- package/src/extension/team-tool/lifecycle-actions.ts +79 -0
- package/src/extension/team-tool/plan.ts +19 -0
- package/src/extension/team-tool/run.ts +41 -3
- package/src/extension/team-tool/status.ts +73 -0
- package/src/extension/team-tool.ts +57 -224
- package/src/runtime/async-marker.ts +26 -0
- package/src/runtime/async-runner.ts +44 -9
- package/src/runtime/background-runner.ts +2 -0
- package/src/runtime/child-pi.ts +5 -1
- package/src/runtime/concurrency.ts +9 -3
- package/src/runtime/crew-agent-records.ts +1 -0
- package/src/runtime/crew-agent-runtime.ts +2 -1
- package/src/runtime/model-fallback.ts +21 -4
- package/src/runtime/pi-args.ts +2 -0
- package/src/runtime/process-status.ts +1 -0
- package/src/runtime/role-permission.ts +11 -0
- package/src/runtime/task-runner/live-executor.ts +98 -0
- package/src/runtime/task-runner/progress.ts +111 -0
- package/src/runtime/task-runner/prompt-builder.ts +72 -0
- package/src/runtime/task-runner/result-utils.ts +14 -0
- package/src/runtime/task-runner/state-helpers.ts +22 -0
- package/src/runtime/task-runner.ts +38 -283
- package/src/runtime/team-runner.ts +116 -7
- package/src/schema/config-schema.ts +1 -0
- package/src/state/mailbox.ts +28 -0
- package/src/state/types.ts +16 -0
- package/src/subagents/async-entry.ts +1 -0
- package/src/subagents/index.ts +3 -0
- package/src/subagents/live/control.ts +1 -0
- package/src/subagents/live/manager.ts +1 -0
- package/src/subagents/live/realtime.ts +1 -0
- package/src/subagents/live/session-runtime.ts +1 -0
- package/src/subagents/manager.ts +1 -0
- package/src/subagents/spawn.ts +1 -0
- package/src/ui/live-run-sidebar.ts +1 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# pi-crew Runtime Flow
|
|
2
|
+
|
|
3
|
+
This document is a compact map of the runtime paths used by `pi-crew`.
|
|
4
|
+
|
|
5
|
+
## Main sequence
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
User / model
|
|
9
|
+
│ calls team({ action: "run", ... }) or /team-run
|
|
10
|
+
▼
|
|
11
|
+
handleTeamTool()
|
|
12
|
+
│ validates schema and routes action
|
|
13
|
+
▼
|
|
14
|
+
handleRun()
|
|
15
|
+
├─ discoverTeams/discoverWorkflows/discoverAgents
|
|
16
|
+
├─ validateWorkflowForTeam
|
|
17
|
+
├─ expandParallelResearchWorkflow when applicable
|
|
18
|
+
├─ createRunManifest + tasks.json + goal artifact
|
|
19
|
+
├─ if async=true ─────────────────────────────────────────────┐
|
|
20
|
+
│ spawnBackgroundTeamRun() │
|
|
21
|
+
│ ├─ resolve jiti-register.mjs │
|
|
22
|
+
│ ├─ fail-fast if jiti missing │
|
|
23
|
+
│ ├─ node --import jiti-register.mjs background-runner.ts │
|
|
24
|
+
│ └─ parent schedules early-exit guard │
|
|
25
|
+
│ ▼
|
|
26
|
+
│ background-runner.ts
|
|
27
|
+
│ ├─ append async.started
|
|
28
|
+
│ ├─ write async.pid startup marker
|
|
29
|
+
│ ├─ rediscover team/workflow/agents
|
|
30
|
+
│ └─ executeTeamRun()
|
|
31
|
+
│
|
|
32
|
+
└─ if foreground/default
|
|
33
|
+
├─ startForegroundRun schedules session-bound run, or
|
|
34
|
+
└─ executeTeamRun inline for scaffold/non-scheduled paths
|
|
35
|
+
|
|
36
|
+
executeTeamRun()
|
|
37
|
+
├─ write run.running
|
|
38
|
+
├─ materialize queued/running agent records lazily
|
|
39
|
+
├─ build task graph index
|
|
40
|
+
├─ while queued tasks exist
|
|
41
|
+
│ ├─ taskGraphSnapshot
|
|
42
|
+
│ ├─ resolveBatchConcurrency
|
|
43
|
+
│ ├─ getReadyTasks
|
|
44
|
+
│ ├─ append task.progress batch event
|
|
45
|
+
│ ├─ mapConcurrent ready batch
|
|
46
|
+
│ │ └─ runTeamTask()
|
|
47
|
+
│ │ ├─ prepare workspace/worktree
|
|
48
|
+
│ │ ├─ build task packet
|
|
49
|
+
│ │ ├─ render prompt + dependency context
|
|
50
|
+
│ │ ├─ choose model candidates from Pi config
|
|
51
|
+
│ │ ├─ spawn child Pi process
|
|
52
|
+
│ │ ├─ ChildPiLineObserver parses stdout/stderr
|
|
53
|
+
│ │ ├─ append per-agent events/output
|
|
54
|
+
│ │ ├─ update agent progress/task state
|
|
55
|
+
│ │ ├─ parse final JSONL/session usage
|
|
56
|
+
│ │ └─ write result/log/transcript/metadata artifacts
|
|
57
|
+
│ ├─ merge task updates monotonically
|
|
58
|
+
│ ├─ optional adaptive plan injection
|
|
59
|
+
│ ├─ save tasks/agents/progress
|
|
60
|
+
│ └─ write batch artifact
|
|
61
|
+
├─ policy closeout
|
|
62
|
+
└─ run.completed / run.failed / run.blocked / run.cancelled
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Action router
|
|
66
|
+
|
|
67
|
+
| Action | Handler | Purpose |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `run` | `team-tool/run.ts` | Create and execute a run, foreground or async. |
|
|
70
|
+
| `status` | `team-tool.ts` | Show manifest/tasks/agents/events and mark stale async runs failed. |
|
|
71
|
+
| `summary` | `session-summary.ts`/summary handler | Write/read run summary artifact. |
|
|
72
|
+
| `events` | `team-tool.ts` | Tail durable run events. |
|
|
73
|
+
| `artifacts` | `team-tool.ts` | List run artifacts. |
|
|
74
|
+
| `resume` | `team-tool.ts` | Requeue failed/cancelled/skipped/running tasks. |
|
|
75
|
+
| `cancel` | `team-tool.ts` | Mark queued/running tasks cancelled and request foreground interrupt. |
|
|
76
|
+
| `forget` | `run-maintenance.ts` | Delete run state/artifacts with confirmation. |
|
|
77
|
+
| `prune` | `run-maintenance.ts` | Remove old finished runs with confirmation. |
|
|
78
|
+
| `export` | `run-export.ts` | Create portable run bundle. |
|
|
79
|
+
| `import` / `imports` | `run-import.ts` / `import-index.ts` | Store/list imported bundles. |
|
|
80
|
+
| `config` | `config.ts` + config action | Show/update user/project config. |
|
|
81
|
+
| `doctor` | `team-tool/doctor.ts` | Platform/resource/runtime diagnostics. |
|
|
82
|
+
| `validate` | `validate-resources.ts` | Validate agents/teams/workflows. |
|
|
83
|
+
| `recommend` | `team-recommendation.ts` | Suggest team/workflow/action for a goal. |
|
|
84
|
+
| management | `management.ts` | Create/update/delete/rename teams, agents, workflows. |
|
|
85
|
+
| API | `team-tool/api.ts` | File-backed observability/control/mailbox API. |
|
|
86
|
+
|
|
87
|
+
## Worker modes
|
|
88
|
+
|
|
89
|
+
| Mode | Behavior |
|
|
90
|
+
|---|---|
|
|
91
|
+
| `child-process` | Default. Launches real child `pi` processes per task. |
|
|
92
|
+
| `scaffold` | Explicit dry-run. No child Pi worker execution. |
|
|
93
|
+
| `live-session` | Experimental/gated in-process/live agent path. |
|
|
94
|
+
| `auto` | Resolves to child-process unless config/env requests otherwise. |
|
|
95
|
+
|
|
96
|
+
## Important files
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
src/extension/register.ts Pi extension entry/wiring
|
|
100
|
+
src/extension/team-tool/run.ts run creation and foreground/async split
|
|
101
|
+
src/runtime/background-runner.ts detached async entrypoint
|
|
102
|
+
src/runtime/async-runner.ts background spawn command/options
|
|
103
|
+
src/runtime/team-runner.ts workflow/task graph scheduler
|
|
104
|
+
src/runtime/task-runner.ts single task execution
|
|
105
|
+
src/runtime/child-pi.ts child Pi process and output observer
|
|
106
|
+
src/runtime/model-fallback.ts configured model candidates/routing
|
|
107
|
+
src/runtime/concurrency.ts batch concurrency decisions
|
|
108
|
+
src/runtime/process-status.ts pid/liveness/stale detection
|
|
109
|
+
src/state/state-store.ts manifest/tasks persistence
|
|
110
|
+
src/state/event-log.ts JSONL run events
|
|
111
|
+
src/runtime/crew-agent-records.ts aggregate + per-agent status files
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Environment variables
|
|
115
|
+
|
|
116
|
+
| Env | Effect |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `PI_CREW_EXECUTE_WORKERS=0` | Disable real workers, use scaffold behavior. |
|
|
119
|
+
| `PI_TEAMS_EXECUTE_WORKERS=0` | Legacy alias for worker disable. |
|
|
120
|
+
| `PI_CREW_ENABLE_EXPERIMENTAL_LIVE_SESSION=1` | Allow experimental live-session runtime. |
|
|
121
|
+
| `PI_CREW_MOCK_LIVE_SESSION=success` | Test hook for live-session mock. |
|
|
122
|
+
| `PI_TEAMS_MOCK_CHILD_PI` | Test hook for mocked child Pi execution. |
|
|
123
|
+
| `PI_CREW_DEPTH`, `PI_CREW_MAX_DEPTH` | Canonical subagent recursion guard. |
|
|
124
|
+
| `PI_TEAMS_DEPTH`, `PI_TEAMS_MAX_DEPTH` | Legacy recursion guard aliases. |
|
|
125
|
+
| `PI_TEAMS_HOME` | Override user config/state home in tests. |
|
|
126
|
+
| `PI_TEAMS_PI_BIN` | Override child `pi` executable. |
|
|
127
|
+
| `PI_CODING_AGENT_DIR` | Override Pi settings/models directory for model discovery. |
|
|
128
|
+
| `PI_CREW_ASYNC_EARLY_EXIT_GUARD=0` | Disable 3s background early-exit guard. |
|
|
129
|
+
|
|
130
|
+
## State transition summary
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
queued/planning/running ── completed
|
|
134
|
+
├─ failed
|
|
135
|
+
├─ blocked
|
|
136
|
+
└─ cancelled
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Task states follow the same durable contract plus `skipped`. Terminal states are monotonic during parallel merge.
|
|
140
|
+
|
|
141
|
+
## Observability tips
|
|
142
|
+
|
|
143
|
+
- Use `/team-dashboard` for a UI overview.
|
|
144
|
+
- Use `team status runId=...` for canonical state and stale async detection.
|
|
145
|
+
- Read `background.log` for early import/spawn errors.
|
|
146
|
+
- Read `events.jsonl` for event chronology.
|
|
147
|
+
- Read `agents/{taskId}/status.json` for per-agent model/progress/tool status.
|
|
148
|
+
- Read `artifacts/{runId}/transcripts/{taskId}.jsonl` for raw child Pi transcript.
|
package/package.json
CHANGED
package/schema.json
CHANGED
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"description": "Runtime safety limits for crew workers and policy decisions.",
|
|
48
48
|
"properties": {
|
|
49
49
|
"maxConcurrentWorkers": { "type": "integer", "minimum": 1 },
|
|
50
|
+
"allowUnboundedConcurrency": { "type": "boolean" },
|
|
50
51
|
"maxTaskDepth": { "type": "integer", "minimum": 1 },
|
|
51
52
|
"maxChildrenPerTask": { "type": "integer", "minimum": 1 },
|
|
52
53
|
"maxRunMinutes": { "type": "integer", "minimum": 1 },
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# git-master
|
|
2
|
+
|
|
3
|
+
Use this skill for commit/release hygiene.
|
|
4
|
+
|
|
5
|
+
## Commit rules
|
|
6
|
+
|
|
7
|
+
- Check `git status --short` before staging.
|
|
8
|
+
- Stage only files related to the current task.
|
|
9
|
+
- Keep commits independently revertible.
|
|
10
|
+
- Use concise imperative commit messages.
|
|
11
|
+
- Do not push or publish unless explicitly requested.
|
|
12
|
+
- Do not include secrets, OTPs, local temp files, or generated tarballs.
|
|
13
|
+
|
|
14
|
+
## Release rules
|
|
15
|
+
|
|
16
|
+
- Run the required verification gate before version bumps.
|
|
17
|
+
- Bump version only after tests pass and user confirms publish intent.
|
|
18
|
+
- Verify registry after publish with `npm view`.
|
|
19
|
+
- Install through `pi install npm:pi-crew` when validating Pi package loading.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# read-only-explorer
|
|
2
|
+
|
|
3
|
+
Use this skill for explorer, analyst, reviewer, and source-audit roles.
|
|
4
|
+
|
|
5
|
+
## Contract
|
|
6
|
+
|
|
7
|
+
- Do not edit files.
|
|
8
|
+
- Do not write generated artifacts outside the run artifact directory.
|
|
9
|
+
- Prefer `read`, `rg`, `find`, `git status`, and package metadata inspection.
|
|
10
|
+
- Record exact files inspected.
|
|
11
|
+
- Distinguish direct evidence from inference.
|
|
12
|
+
- If implementation is needed, recommend it instead of modifying code.
|
|
13
|
+
|
|
14
|
+
## Output shape
|
|
15
|
+
|
|
16
|
+
Return:
|
|
17
|
+
|
|
18
|
+
1. files inspected;
|
|
19
|
+
2. findings with path references;
|
|
20
|
+
3. risks/unknowns;
|
|
21
|
+
4. recommended next tests or implementation tasks.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# safe-bash
|
|
2
|
+
|
|
3
|
+
Use this skill whenever a task may execute shell commands.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
- Prefer read-only commands first: `pwd`, `ls`, `find`, `rg`, `git status`, package-manager dry runs.
|
|
8
|
+
- Before mutating commands, explain the target path and expected effect.
|
|
9
|
+
- Never run destructive cleanup (`rm -rf`, `git clean`, force delete, prune, reset hard) without explicit confirmation.
|
|
10
|
+
- Avoid shell-specific assumptions when a cross-platform Node/Pi API exists.
|
|
11
|
+
- On Windows, prefer argv-based process execution and avoid `cmd /c start` or `/bin/bash` unless explicitly required.
|
|
12
|
+
- Capture verification output and summarize exit status.
|
|
13
|
+
|
|
14
|
+
## Reporting
|
|
15
|
+
|
|
16
|
+
Mention commands run and whether they were read-only or mutating.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# task-packet
|
|
2
|
+
|
|
3
|
+
Use this skill when creating or executing a worker task.
|
|
4
|
+
|
|
5
|
+
## Required sections
|
|
6
|
+
|
|
7
|
+
Each task should clarify:
|
|
8
|
+
|
|
9
|
+
- objective;
|
|
10
|
+
- scope and paths;
|
|
11
|
+
- constraints and permissions;
|
|
12
|
+
- dependencies and expected inputs;
|
|
13
|
+
- expected outputs/artifacts;
|
|
14
|
+
- acceptance criteria;
|
|
15
|
+
- verification commands;
|
|
16
|
+
- escalation conditions.
|
|
17
|
+
|
|
18
|
+
## Worker behavior
|
|
19
|
+
|
|
20
|
+
- Read dependency outputs before starting dependent work.
|
|
21
|
+
- Keep outputs concise and artifact-oriented.
|
|
22
|
+
- Do not claim completion until required artifacts and status are durable.
|
|
23
|
+
- If blocked, report the blocker and the smallest recoverable next action.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# verify-evidence
|
|
2
|
+
|
|
3
|
+
Use this skill before finalizing implementation, review, or audit work.
|
|
4
|
+
|
|
5
|
+
## Required final evidence
|
|
6
|
+
|
|
7
|
+
Include:
|
|
8
|
+
|
|
9
|
+
- changed files, or `none` for read-only work;
|
|
10
|
+
- tests/checks run with pass/fail result;
|
|
11
|
+
- relevant artifacts, run IDs, or log paths;
|
|
12
|
+
- unresolved risks and rollback notes when code changed.
|
|
13
|
+
|
|
14
|
+
## Verification ladder
|
|
15
|
+
|
|
16
|
+
Prefer the smallest reliable check first, then escalate:
|
|
17
|
+
|
|
18
|
+
1. Targeted unit tests for touched behavior.
|
|
19
|
+
2. Typecheck for TypeScript changes.
|
|
20
|
+
3. Integration tests for runtime/spawn/state changes.
|
|
21
|
+
4. `npm pack --dry-run` for package/release/doc changes.
|
|
22
|
+
5. Real Pi smoke only when needed and safe.
|
package/src/config/config.ts
CHANGED
|
@@ -18,6 +18,7 @@ export interface PiTeamsAutonomousConfig {
|
|
|
18
18
|
|
|
19
19
|
export interface CrewLimitsConfig {
|
|
20
20
|
maxConcurrentWorkers?: number;
|
|
21
|
+
allowUnboundedConcurrency?: boolean;
|
|
21
22
|
maxTaskDepth?: number;
|
|
22
23
|
maxChildrenPerTask?: number;
|
|
23
24
|
maxRunMinutes?: number;
|
|
@@ -292,6 +293,7 @@ function parseLimitsConfig(value: unknown): CrewLimitsConfig | undefined {
|
|
|
292
293
|
if (!obj) return undefined;
|
|
293
294
|
const limits: CrewLimitsConfig = {
|
|
294
295
|
maxConcurrentWorkers: parsePositiveInteger(obj.maxConcurrentWorkers, LIMIT_CEILINGS.maxConcurrentWorkers),
|
|
296
|
+
allowUnboundedConcurrency: parseWithSchema(Type.Boolean(), obj.allowUnboundedConcurrency),
|
|
295
297
|
maxTaskDepth: parsePositiveInteger(obj.maxTaskDepth, LIMIT_CEILINGS.maxTaskDepth),
|
|
296
298
|
maxChildrenPerTask: parsePositiveInteger(obj.maxChildrenPerTask, LIMIT_CEILINGS.maxChildrenPerTask),
|
|
297
299
|
maxRunMinutes: parsePositiveInteger(obj.maxRunMinutes, LIMIT_CEILINGS.maxRunMinutes),
|
package/src/config/defaults.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { appendEvent, readEvents, type TeamEvent } from "../state/event-log.ts";
|
|
3
|
+
import { checkProcessLiveness, isActiveRunStatus } from "../runtime/process-status.ts";
|
|
4
|
+
import { updateRunStatus } from "../state/state-store.ts";
|
|
5
|
+
import type { TeamRunManifest } from "../state/types.ts";
|
|
2
6
|
import { listRuns } from "./run-index.ts";
|
|
3
7
|
|
|
4
8
|
export interface AsyncNotifierState {
|
|
@@ -10,6 +14,30 @@ function isFinished(status: string): boolean {
|
|
|
10
14
|
return status === "completed" || status === "failed" || status === "cancelled" || status === "blocked";
|
|
11
15
|
}
|
|
12
16
|
|
|
17
|
+
function isAsyncTerminalEvent(event: TeamEvent): boolean {
|
|
18
|
+
return event.type === "async.completed" || event.type === "async.failed" || event.type === "async.died";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function latestEventAgeMs(events: TeamEvent[], now = Date.now()): number {
|
|
22
|
+
const latest = events.at(-1);
|
|
23
|
+
if (!latest) return Number.POSITIVE_INFINITY;
|
|
24
|
+
const time = new Date(latest.time).getTime();
|
|
25
|
+
return Number.isFinite(time) ? now - time : Number.POSITIVE_INFINITY;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function markDeadAsyncRunIfNeeded(run: TeamRunManifest, now = Date.now(), quietMs = 30_000): TeamRunManifest | undefined {
|
|
29
|
+
if (!run.async || !isActiveRunStatus(run.status)) return undefined;
|
|
30
|
+
const liveness = checkProcessLiveness(run.async.pid);
|
|
31
|
+
if (liveness.alive) return undefined;
|
|
32
|
+
const events = readEvents(run.eventsPath);
|
|
33
|
+
if (events.some(isAsyncTerminalEvent)) return undefined;
|
|
34
|
+
if (latestEventAgeMs(events, now) < quietMs) return undefined;
|
|
35
|
+
const message = `Background runner died unexpectedly; check background.log (${liveness.detail}).`;
|
|
36
|
+
const failed = updateRunStatus(run, "failed", message);
|
|
37
|
+
appendEvent(failed.eventsPath, { type: "async.died", runId: failed.runId, message, data: { pid: run.async.pid, detail: liveness.detail } });
|
|
38
|
+
return failed;
|
|
39
|
+
}
|
|
40
|
+
|
|
13
41
|
export function startAsyncRunNotifier(ctx: ExtensionContext, state: AsyncNotifierState, intervalMs = 5000): void {
|
|
14
42
|
if (state.interval) clearInterval(state.interval);
|
|
15
43
|
for (const run of listRuns(ctx.cwd)) {
|
|
@@ -20,10 +48,11 @@ export function startAsyncRunNotifier(ctx: ExtensionContext, state: AsyncNotifie
|
|
|
20
48
|
state.interval = setInterval(() => {
|
|
21
49
|
try {
|
|
22
50
|
for (const run of listRuns(ctx.cwd).slice(0, 20)) {
|
|
23
|
-
|
|
24
|
-
state.seenFinishedRunIds.
|
|
25
|
-
|
|
26
|
-
|
|
51
|
+
const current = markDeadAsyncRunIfNeeded(run) ?? run;
|
|
52
|
+
if (!isFinished(current.status) || state.seenFinishedRunIds.has(current.runId)) continue;
|
|
53
|
+
state.seenFinishedRunIds.add(current.runId);
|
|
54
|
+
const level = current.status === "completed" ? "info" : current.status === "cancelled" ? "warning" : "error";
|
|
55
|
+
ctx.ui.notify(`pi-crew run ${current.status}: ${current.runId} (${current.team}/${current.workflow ?? "none"})`, level);
|
|
27
56
|
}
|
|
28
57
|
} catch (error) {
|
|
29
58
|
const message = error instanceof Error ? error.message : String(error);
|