pi-crew 0.10.2 → 0.10.3
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 +249 -0
- package/dist/index.mjs +98 -307
- package/package.json +2 -1
- package/schema.json +11 -0
- package/skills/real-test-pi-crew/REPORT-TEMPLATE.md +6 -2
- package/skills/real-test-pi-crew/SKILL.md +278 -79
- package/src/config/config-merge.ts +11 -1
- package/src/config/config-validation.ts +40 -1
- package/src/config/config.ts +28 -6
- package/src/config/defaults.ts +35 -10
- package/src/config/env-vars.ts +27 -2
- package/src/config/types.ts +36 -0
- package/src/extension/registration/lifecycle-handlers.ts +40 -9
- package/src/extension/registration/team-tool.ts +53 -5
- package/src/extension/team-tool/doctor.ts +364 -7
- package/src/extension/team-tool/handle-settings.ts +19 -0
- package/src/extension/team-tool/inspect.ts +10 -2
- package/src/extension/team-tool/status.ts +7 -0
- package/src/extension/team-tool.ts +35 -2
- package/src/hooks/registry.ts +59 -56
- package/src/prompt/inbox-poll.ts +90 -0
- package/src/prompt/message-tool.ts +166 -0
- package/src/prompt/prompt-runtime.ts +201 -18
- package/src/prompt/surface-worker.ts +720 -0
- package/src/prompt/worker-events-channel.ts +49 -3
- package/src/runtime/async-runner.ts +29 -1
- package/src/runtime/background-runner.ts +13 -7
- package/src/runtime/broker/broker-issuer.ts +27 -2
- package/src/runtime/broker/crew-broker-tokens.ts +56 -4
- package/src/runtime/broker/crew-broker.ts +261 -41
- package/src/runtime/child-pi/child-pi-spawn.ts +23 -9
- package/src/runtime/child-pi/child-pi-streams.ts +9 -1
- package/src/runtime/child-pi/child-pi.ts +353 -5
- package/src/runtime/crew-agent-records.ts +13 -1
- package/src/runtime/dispatch-batch.ts +12 -1
- package/src/runtime/event-log-tail-source.ts +374 -0
- package/src/runtime/finalize-run.ts +4 -0
- package/src/runtime/live-session/live-agent-manager.ts +34 -1
- package/src/runtime/live-session/live-control-realtime.ts +10 -0
- package/src/runtime/live-session/live-session-runtime.ts +47 -27
- package/src/runtime/manifest-cache.ts +128 -17
- package/src/runtime/model/pi-args.ts +54 -65
- package/src/runtime/output/sidechain-output.ts +61 -6
- package/src/runtime/process/proc-stat.ts +46 -0
- package/src/runtime/process/zombie-scanner.ts +32 -19
- package/src/runtime/spawn-policy.ts +27 -41
- package/src/runtime/surface/degrade.ts +776 -0
- package/src/runtime/surface/herdr-provider.ts +546 -0
- package/src/runtime/surface/launch-script.ts +172 -0
- package/src/runtime/surface/resolve-surface.ts +274 -0
- package/src/runtime/surface/surface-provider.ts +129 -0
- package/src/runtime/surface/surface-spawn.ts +475 -0
- package/src/runtime/surface/tmux-provider.ts +400 -0
- package/src/runtime/task-runner/child-executor.ts +47 -0
- package/src/runtime/task-runner/post-execution.ts +57 -2
- package/src/runtime/task-runner/prompt-builder.ts +1 -0
- package/src/runtime/task-runner/retrieval-orchestrator.ts +191 -56
- package/src/runtime/task-runner/state-helpers.ts +54 -30
- package/src/runtime/task-runner.ts +4 -2
- package/src/runtime/team-runner.ts +101 -0
- package/src/schema/config-schema.ts +24 -0
- package/src/state/atomic-write.ts +219 -40
- package/src/state/coordination/locks.ts +7 -5
- package/src/state/coordination/mailbox.ts +56 -10
- package/src/state/event-log/cursor.ts +413 -23
- package/src/state/event-log/event-log.ts +120 -113
- package/src/state/event-log/sequence-cache.ts +21 -3
- package/src/state/stores/state-store.ts +98 -6
- package/src/state/types.ts +51 -0
- package/src/ui/inline-panel/agent-pane.ts +3 -0
- package/src/ui/render-diff.ts +16 -8
- package/src/ui/run-dashboard.ts +87 -42
- package/src/ui/run-event-bus.ts +10 -1
- package/src/ui/run-snapshot-cache.ts +83 -35
- package/src/ui/transcript-cache.ts +101 -13
- package/src/ui/transcript-viewer.ts +92 -24
- package/src/ui/widget/index.ts +32 -8
- package/src/utils/visual.ts +43 -0
- package/src/worktree/worktree-manager.ts +65 -4
package/dist/index.mjs
CHANGED
|
@@ -13475,7 +13475,6 @@ function parseWorkflowFile(filePath, source) {
|
|
|
13475
13475
|
topology: parseTopology(frontmatter.topology),
|
|
13476
13476
|
coalesceMicroTasks: parseOptionalBoolean(frontmatter.coalesceMicroTasks),
|
|
13477
13477
|
specStrict: parseOptionalBoolean(frontmatter.specStrict),
|
|
13478
|
-
adaptive: parseOptionalBoolean(frontmatter.adaptive),
|
|
13479
13478
|
steps
|
|
13480
13479
|
};
|
|
13481
13480
|
} catch {
|
|
@@ -21004,52 +21003,20 @@ function createRunPaths(cwd, runId = createRunId()) {
|
|
|
21004
21003
|
eventsPath: path25.join(stateRoot, DEFAULT_PATHS.state.eventsFile)
|
|
21005
21004
|
};
|
|
21006
21005
|
}
|
|
21007
|
-
function
|
|
21008
|
-
let name = prefix.replace(/[\s:—-]+$/, "").trim();
|
|
21009
|
-
let changed = true;
|
|
21010
|
-
while (changed) {
|
|
21011
|
-
changed = false;
|
|
21012
|
-
const lowered = name.toLowerCase();
|
|
21013
|
-
for (const tail of GOAL_TAILS) {
|
|
21014
|
-
if (lowered.endsWith(tail) && lowered.length > tail.length) {
|
|
21015
|
-
name = name.slice(0, name.length - tail.length).replace(/[\s:—-]+$/, "").trim();
|
|
21016
|
-
changed = true;
|
|
21017
|
-
break;
|
|
21018
|
-
}
|
|
21019
|
-
}
|
|
21020
|
-
}
|
|
21021
|
-
return name;
|
|
21022
|
-
}
|
|
21023
|
-
function createTasksFromWorkflow(runId, workflow, team, cwd, goal) {
|
|
21006
|
+
function createTasksFromWorkflow(runId, workflow, team, cwd) {
|
|
21024
21007
|
const stepToTaskId = new Map(workflow.steps.map((step, index) => [step.id, createTaskId(step.id, index)]));
|
|
21025
21008
|
return workflow.steps.map((step, index) => {
|
|
21026
21009
|
const role = team.roles.find((candidate) => candidate.name === step.role);
|
|
21027
21010
|
const id = stepToTaskId.get(step.id) ?? createTaskId(step.id, index);
|
|
21028
21011
|
const dependencies = step.dependsOn ?? [];
|
|
21029
21012
|
const children = workflow.steps.filter((candidate) => candidate.dependsOn?.includes(step.id)).map((candidate) => stepToTaskId.get(candidate.id)).filter((childId) => childId !== void 0);
|
|
21030
|
-
const bodyLines = typeof step.task === "string" && step.task.trim() ? step.task.split("\n").map((line4) => line4.trim()).filter(Boolean) : [];
|
|
21031
|
-
const heading = bodyLines.find((line4) => line4.startsWith("#"));
|
|
21032
|
-
const titleLine = heading ?? bodyLines[0];
|
|
21033
|
-
const substitute = (text) => goal ? text.replaceAll("{goal}", goal) : text;
|
|
21034
|
-
let title;
|
|
21035
|
-
let restLines;
|
|
21036
|
-
const placeholderAt = titleLine?.indexOf("{goal}") ?? -1;
|
|
21037
|
-
if (titleLine && placeholderAt >= 0) {
|
|
21038
|
-
title = stripGoalTail(titleLine.slice(0, placeholderAt)) || goal || step.id;
|
|
21039
|
-
restLines = bodyLines.filter((line4) => line4 !== titleLine);
|
|
21040
|
-
} else {
|
|
21041
|
-
title = (titleLine ?? step.id).replace(/^#+\s*/, "");
|
|
21042
|
-
restLines = heading ? bodyLines.filter((line4) => line4 !== titleLine) : bodyLines.slice(1);
|
|
21043
|
-
}
|
|
21044
|
-
const description = restLines.map(substitute).join("\n");
|
|
21045
21013
|
return {
|
|
21046
21014
|
id,
|
|
21047
21015
|
runId,
|
|
21048
21016
|
stepId: step.id,
|
|
21049
21017
|
role: step.role,
|
|
21050
21018
|
agent: role?.agent ?? step.role,
|
|
21051
|
-
title:
|
|
21052
|
-
description: description && description !== title ? description : void 0,
|
|
21019
|
+
title: step.id,
|
|
21053
21020
|
status: "queued",
|
|
21054
21021
|
dependsOn: dependencies,
|
|
21055
21022
|
cwd,
|
|
@@ -21067,7 +21034,7 @@ function createTasksFromWorkflow(runId, workflow, team, cwd, goal) {
|
|
|
21067
21034
|
function createRunManifest(params) {
|
|
21068
21035
|
const paths = createRunPaths(params.cwd);
|
|
21069
21036
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
21070
|
-
const tasks = params.workflow ? createTasksFromWorkflow(paths.runId, params.workflow, params.team, params.cwd
|
|
21037
|
+
const tasks = params.workflow ? createTasksFromWorkflow(paths.runId, params.workflow, params.team, params.cwd) : [];
|
|
21071
21038
|
const manifest = {
|
|
21072
21039
|
schemaVersion: CURRENT_SCHEMA_VERSION,
|
|
21073
21040
|
runId: paths.runId,
|
|
@@ -21518,7 +21485,7 @@ async function loadRunManifestByIdAsync(cwd, runId) {
|
|
|
21518
21485
|
});
|
|
21519
21486
|
return { manifest, tasks: tasks ?? [] };
|
|
21520
21487
|
}
|
|
21521
|
-
var manifestCacheGeneration, MANIFEST_CACHE_GENERATION_MAX, MANIFEST_CACHE_TTL_MS, LOAD_MANIFEST_RETRY_LIMIT, manifestCache, MANIFEST_CACHE_TTL_MS_VALUE, runStateRootCache, RUN_STATE_ROOT_TTL_MS, RUN_STATE_ROOT_CACHE_MAX
|
|
21488
|
+
var manifestCacheGeneration, MANIFEST_CACHE_GENERATION_MAX, MANIFEST_CACHE_TTL_MS, LOAD_MANIFEST_RETRY_LIMIT, manifestCache, MANIFEST_CACHE_TTL_MS_VALUE, runStateRootCache, RUN_STATE_ROOT_TTL_MS, RUN_STATE_ROOT_CACHE_MAX;
|
|
21522
21489
|
var init_state_store = __esm({
|
|
21523
21490
|
"src/state/stores/state-store.ts"() {
|
|
21524
21491
|
"use strict";
|
|
@@ -21546,7 +21513,6 @@ var init_state_store = __esm({
|
|
|
21546
21513
|
runStateRootCache = /* @__PURE__ */ new Map();
|
|
21547
21514
|
RUN_STATE_ROOT_TTL_MS = 1e4;
|
|
21548
21515
|
RUN_STATE_ROOT_CACHE_MAX = 256;
|
|
21549
|
-
GOAL_TAILS = ["for the goal", "for goal", "the goal", "goal", "cho m\u1EE5c ti\xEAu", "c\u1EE7a m\u1EE5c ti\xEAu", "m\u1EE5c ti\xEAu", "for", "of", "cho", "c\u1EE7a"];
|
|
21550
21516
|
}
|
|
21551
21517
|
});
|
|
21552
21518
|
|
|
@@ -21819,14 +21785,9 @@ function isDisplayActiveRun(run, agents = [], now = Date.now()) {
|
|
|
21819
21785
|
}
|
|
21820
21786
|
if (!isActiveRunStatus(run.status)) return false;
|
|
21821
21787
|
if (agents.length === 0) return false;
|
|
21822
|
-
|
|
21823
|
-
if (agents.some((agent) => agent.status === "queued" || agent.status === "waiting")) {
|
|
21824
|
-
const updatedAt = new Date(run.updatedAt).getTime();
|
|
21825
|
-
if (Number.isFinite(updatedAt) && now - updatedAt < SPAWN_GAP_VISIBILITY_MS) return true;
|
|
21826
|
-
}
|
|
21827
|
-
return false;
|
|
21788
|
+
return agents.some(hasDurableActiveAgentEvidence);
|
|
21828
21789
|
}
|
|
21829
|
-
var ORPHANED_ACTIVE_RUN_MS, COMPLETED_VISIBILITY_GRACE_MS, ERROR_VISIBILITY_GRACE_MS, STALE_ACTIVE_RUN_MS,
|
|
21790
|
+
var ORPHANED_ACTIVE_RUN_MS, COMPLETED_VISIBILITY_GRACE_MS, ERROR_VISIBILITY_GRACE_MS, STALE_ACTIVE_RUN_MS, ORPHANED_NO_PROGRESS_MS;
|
|
21830
21791
|
var init_process_status = __esm({
|
|
21831
21792
|
"src/runtime/process-status.ts"() {
|
|
21832
21793
|
"use strict";
|
|
@@ -21835,7 +21796,6 @@ var init_process_status = __esm({
|
|
|
21835
21796
|
COMPLETED_VISIBILITY_GRACE_MS = 8e3;
|
|
21836
21797
|
ERROR_VISIBILITY_GRACE_MS = 10 * 60 * 1e3;
|
|
21837
21798
|
STALE_ACTIVE_RUN_MS = 30 * 60 * 1e3;
|
|
21838
|
-
SPAWN_GAP_VISIBILITY_MS = 60 * 1e3;
|
|
21839
21799
|
ORPHANED_NO_PROGRESS_MS = 5 * 60 * 1e3;
|
|
21840
21800
|
}
|
|
21841
21801
|
});
|
|
@@ -57904,12 +57864,10 @@ function isActiveStatus(status) {
|
|
|
57904
57864
|
return status === "running" || status === "queued" || status === "waiting";
|
|
57905
57865
|
}
|
|
57906
57866
|
function orderWidgetAgents(entry, now = Date.now()) {
|
|
57907
|
-
const runDone = isFinishedRunStatus(entry.run.status);
|
|
57908
57867
|
const active = entry.agents.filter((agent) => isActiveStatus(agent.status));
|
|
57909
57868
|
const finished = entry.agents.filter((agent) => {
|
|
57910
57869
|
if (isActiveStatus(agent.status)) return false;
|
|
57911
57870
|
if (!agent.completedAt) return false;
|
|
57912
|
-
if (!runDone) return true;
|
|
57913
57871
|
const maxAgeMs = (ERROR_STATUSES.has(agent.status) ? ERROR_LINGER_MAX_AGE : FINISHED_LINGER_MAX_AGE) * 6e4;
|
|
57914
57872
|
const age = now - new Date(agent.completedAt).getTime();
|
|
57915
57873
|
return Number.isFinite(age) && age < maxAgeMs;
|
|
@@ -57919,79 +57877,40 @@ function orderWidgetAgents(entry, now = Date.now()) {
|
|
|
57919
57877
|
finished
|
|
57920
57878
|
};
|
|
57921
57879
|
}
|
|
57922
|
-
function shortModelLabel(agent, run) {
|
|
57923
|
-
const model = agent.model ?? run.modelContext?.parentModel ?? run.modelContext?.override;
|
|
57924
|
-
if (typeof model !== "string" || !model) return void 0;
|
|
57925
|
-
return model.split("/").at(-1) ?? model;
|
|
57926
|
-
}
|
|
57927
|
-
function compactAgentRow(run, agent, finished, runs, options, width, liveHandle) {
|
|
57928
|
-
const marker = options.selectedTaskId === agent.taskId ? "\u276F" : " ";
|
|
57929
|
-
const dockGlyph = options.viewedTaskId === agent.taskId ? "\u23FA" : dockStatusIcon(agent.status);
|
|
57930
|
-
const name = liveHandle?.agent ?? agent.agent;
|
|
57931
|
-
const label = liveHandle?.description ?? agent.role ?? "";
|
|
57932
|
-
const runTag = runs.length > 1 ? `${shortRunLabel(run)} \xB7 ` : "";
|
|
57933
|
-
const taskTag = agent.taskId ? ` \xB7 ${agent.taskId}` : "";
|
|
57934
|
-
const roleTag = label && label !== agent.taskId && label !== name ? ` \xB7 ${label}` : "";
|
|
57935
|
-
const nameText = runTag + name + taskTag + roleTag;
|
|
57936
|
-
const liveLine = liveHandle?.activity?.responseText?.split("\n").find((line4) => line4.trim())?.trim();
|
|
57937
|
-
const activity = !finished && liveHandle?.status === "running" && liveLine ? liveLine.length > 60 ? `${liveLine.slice(0, 60)}\u2026` : liveLine : finished ? dockStatusLabel(agent.status) : agentActivity(agent, liveHandle);
|
|
57938
|
-
const usage = dockUsageText(agent, liveHandle, { viewed: options.viewedTaskId === agent.taskId });
|
|
57939
|
-
const ageText = dockElapsed(agent.completedAt ?? agent.startedAt);
|
|
57940
|
-
const model = shortModelLabel(agent, run);
|
|
57941
|
-
const suffix = `${model ? ` \xB7 ${model}` : ""}${usage ? ` \xB7 ${usage}` : ""}${ageText ? ` \xB7 ${ageText}` : ""}`;
|
|
57942
|
-
return budgetedRow({ lead: `${marker} ${dockGlyph} `, name: nameText, activity, suffix }, width);
|
|
57943
|
-
}
|
|
57944
|
-
function compactDockLines(runs, options, width, maxLines, notificationCount, runningGlyph) {
|
|
57945
|
-
const now = Date.now();
|
|
57946
|
-
const flat = [];
|
|
57947
|
-
for (const entry of runs) {
|
|
57948
|
-
const { active, finished } = orderWidgetAgents(entry, now);
|
|
57949
|
-
const liveForRun = listLiveAgents().filter((a) => a.runId === entry.run.runId);
|
|
57950
|
-
for (const agent of active) {
|
|
57951
|
-
flat.push({ run: entry.run, agent, finished: false, liveHandle: liveForRun.find((h) => h.taskId === agent.taskId) });
|
|
57952
|
-
}
|
|
57953
|
-
for (const agent of finished) {
|
|
57954
|
-
flat.push({ run: entry.run, agent, finished: true, liveHandle: liveForRun.find((h) => h.taskId === agent.taskId) });
|
|
57955
|
-
}
|
|
57956
|
-
}
|
|
57957
|
-
if (flat.length === 0) return [widgetHeader(runs, runningGlyph, maxLines, notificationCount)];
|
|
57958
|
-
const lines = [];
|
|
57959
|
-
let hint;
|
|
57960
|
-
if (options.viewedTaskId) {
|
|
57961
|
-
const viewedName = flat.find((row) => row.agent.taskId === options.viewedTaskId)?.agent.agent ?? "agent";
|
|
57962
|
-
hint = `viewing @${viewedName} \u2014 typing goes to the agent \xB7 \u2193 switch \xB7 esc back`;
|
|
57963
|
-
} else if (options.focused) {
|
|
57964
|
-
hint = "enter to view \xB7 x to stop/cancel \xB7 esc back";
|
|
57965
|
-
} else {
|
|
57966
|
-
hint = `agents (${flat.length}) \u2014 \u2193 to select`;
|
|
57967
|
-
}
|
|
57968
|
-
lines.push(truncate(hint, width));
|
|
57969
|
-
const mainMarker = options.focused && !options.selectedTaskId ? "\u276F" : " ";
|
|
57970
|
-
const mainIcon = options.viewedTaskId ? "\u25EF" : "\u25CF";
|
|
57971
|
-
lines.push(truncate(`${mainMarker} ${mainIcon} main`, width));
|
|
57972
|
-
const selectedIndex = options.selectedTaskId ? flat.findIndex((row) => row.agent.taskId === options.selectedTaskId) : -1;
|
|
57973
|
-
const windowStart = selectedIndex >= 0 ? Math.max(0, selectedIndex - MAX_AGENTS_DISPLAY + 1) : 0;
|
|
57974
|
-
const windowEnd = Math.min(flat.length, windowStart + MAX_AGENTS_DISPLAY);
|
|
57975
|
-
if (windowStart > 0) lines.push(truncate(` \u2026 \u2191${windowStart} earlier (\u2191 to scroll)`, width));
|
|
57976
|
-
for (const row of flat.slice(windowStart, windowEnd)) {
|
|
57977
|
-
lines.push(compactAgentRow(row.run, row.agent, row.finished, runs, options, width, row.liveHandle));
|
|
57978
|
-
}
|
|
57979
|
-
if (windowEnd < flat.length) lines.push(truncate(` \u2026 +${flat.length - windowEnd} more (\u2193 to scroll)`, width));
|
|
57980
|
-
return lines;
|
|
57981
|
-
}
|
|
57982
57880
|
function buildWidgetLines(cwd, frame = 0, maxLines = 8, providedRuns, notificationCount = 0, width = DEFAULT_WIDGET_WIDTH, options = {}) {
|
|
57983
57881
|
const rowStyle = options.rowStyle ?? "detailed";
|
|
57984
57882
|
const focused = options.focused === true;
|
|
57985
57883
|
const runs = providedRuns ?? activeWidgetRuns(cwd);
|
|
57986
57884
|
if (!runs.length) return [];
|
|
57987
57885
|
const runningGlyph = spinnerFrame("widget-header");
|
|
57886
|
+
const lines = [];
|
|
57988
57887
|
if (rowStyle === "compact") {
|
|
57989
|
-
const
|
|
57990
|
-
|
|
57888
|
+
const agentCount = runs.reduce((n, entry) => {
|
|
57889
|
+
const { active, finished } = orderWidgetAgents(entry);
|
|
57890
|
+
return n + active.length + finished.length;
|
|
57891
|
+
}, 0);
|
|
57892
|
+
if (agentCount > 0) {
|
|
57893
|
+
let hint;
|
|
57894
|
+
if (options.viewedTaskId) {
|
|
57895
|
+
const viewedName = runs.flatMap((entry) => entry.agents).find((a) => a.taskId === options.viewedTaskId)?.agent ?? "agent";
|
|
57896
|
+
hint = `viewing @${viewedName} \u2014 typing goes to the agent \xB7 \u2193 switch \xB7 esc back`;
|
|
57897
|
+
} else if (options.focused) {
|
|
57898
|
+
hint = "enter to view \xB7 x to stop/cancel \xB7 esc back";
|
|
57899
|
+
} else {
|
|
57900
|
+
hint = `agents (${agentCount}) \u2014 \u2193 to select`;
|
|
57901
|
+
}
|
|
57902
|
+
lines.push(truncate(hint, width));
|
|
57903
|
+
const mainMarker = options.focused && !options.selectedTaskId ? "\u276F" : " ";
|
|
57904
|
+
const mainIcon = options.viewedTaskId ? "\u25EF" : "\u25CF";
|
|
57905
|
+
lines.push(truncate(`${mainMarker} ${mainIcon} main`, width));
|
|
57906
|
+
} else {
|
|
57907
|
+
lines.push(widgetHeader(runs, runningGlyph, maxLines, notificationCount));
|
|
57908
|
+
}
|
|
57909
|
+
} else {
|
|
57910
|
+
lines.push(widgetHeader(runs, runningGlyph, maxLines, notificationCount));
|
|
57991
57911
|
}
|
|
57992
|
-
const lines = [widgetHeader(runs, runningGlyph, maxLines, notificationCount)];
|
|
57993
57912
|
for (const entry of runs) {
|
|
57994
|
-
const { run, agents } = entry;
|
|
57913
|
+
const { run, agents, snapshot } = entry;
|
|
57995
57914
|
const now = Date.now();
|
|
57996
57915
|
const { active: activeAgents, finished: finishedAgents } = orderWidgetAgents(entry, now);
|
|
57997
57916
|
const completed = agents.filter((a) => a.status === "completed").length;
|
|
@@ -58004,7 +57923,9 @@ function buildWidgetLines(cwd, frame = 0, maxLines = 8, providedRuns, notificati
|
|
|
58004
57923
|
const runElapsedText = `${Math.floor(runElapsedMs / 1e3)}s`;
|
|
58005
57924
|
const statusLabel = isTerminal ? ` \xB7 ${run.status}` : "";
|
|
58006
57925
|
const progressPart = `${agentCountText} \xB7 ${runElapsedText}${statusLabel}`;
|
|
58007
|
-
|
|
57926
|
+
if (rowStyle !== "compact") {
|
|
57927
|
+
lines.push(truncate(`\u251C\u2500 ${runGlyph} ${shortRunLabel(run)} \xB7 ${progressPart} \xB7 ${run.runId.slice(-8)}`, width));
|
|
57928
|
+
}
|
|
58008
57929
|
const liveForRun = listLiveAgents().filter((a) => a.runId === run.runId);
|
|
58009
57930
|
const activeCap = focused ? activeAgents.length : MAX_AGENTS_DISPLAY;
|
|
58010
57931
|
const finishedSlots = focused ? finishedAgents.length : Math.max(0, Math.min(2, MAX_AGENTS_DISPLAY - activeAgents.length));
|
|
@@ -58014,10 +57935,33 @@ function buildWidgetLines(cwd, frame = 0, maxLines = 8, providedRuns, notificati
|
|
|
58014
57935
|
const last = index === visibleAgents.length - 1 && activeAgents.length <= activeCap && finishedSlots === 0;
|
|
58015
57936
|
const branch = last ? "\u2514\u2500" : "\u251C\u2500";
|
|
58016
57937
|
const liveHandle = liveForRun.find((h) => h.taskId === agent.taskId);
|
|
57938
|
+
const dockGlyph = options.viewedTaskId === agent.taskId ? "\u23FA" : dockStatusIcon(agent.status);
|
|
58017
57939
|
const legacyGlyph = options.viewedTaskId === agent.taskId ? "\u25C9" : iconForStatus(agent.status, { runningGlyph });
|
|
58018
57940
|
const stats = agentStats(agent, liveHandle);
|
|
58019
57941
|
const name = liveHandle?.agent ?? agent.agent;
|
|
58020
57942
|
const activity = agentActivity(agent, liveHandle);
|
|
57943
|
+
if (rowStyle === "compact") {
|
|
57944
|
+
const label = liveHandle?.description ?? agent.role ?? "";
|
|
57945
|
+
const runTag = runs.length > 1 ? `${shortRunLabel(run)} \xB7 ` : "";
|
|
57946
|
+
const nameText = runTag + (label ? `${name} \xB7 ${label}` : name);
|
|
57947
|
+
const liveLine = liveHandle?.activity?.responseText?.split("\n").find((l) => l.trim())?.trim();
|
|
57948
|
+
const dockActivity = liveHandle?.status === "running" && liveLine ? liveLine.length > 60 ? `${liveLine.slice(0, 60)}\u2026` : liveLine : activity;
|
|
57949
|
+
const usage = dockUsageText(agent, liveHandle, { viewed: options.viewedTaskId === agent.taskId });
|
|
57950
|
+
const ageText = dockElapsed(agent.completedAt ?? agent.startedAt);
|
|
57951
|
+
const suffix = `${usage ? ` \xB7 ${usage}` : ""}${ageText ? ` \xB7 ${ageText}` : ""}`;
|
|
57952
|
+
lines.push(
|
|
57953
|
+
budgetedRow(
|
|
57954
|
+
{
|
|
57955
|
+
lead: `${markerFor2(agent.taskId)} ${dockGlyph} `,
|
|
57956
|
+
name: nameText,
|
|
57957
|
+
activity: dockActivity,
|
|
57958
|
+
suffix
|
|
57959
|
+
},
|
|
57960
|
+
width
|
|
57961
|
+
)
|
|
57962
|
+
);
|
|
57963
|
+
continue;
|
|
57964
|
+
}
|
|
58021
57965
|
const desc = truncate(liveHandle?.description ?? agent.role ?? "", TASK_DESC_MAX);
|
|
58022
57966
|
const _activeMain = truncate(`\u2502 ${branch} ${legacyGlyph} ${name}${desc ? ` \xB7 ${desc}` : ` \xB7 ${agent.role}`}`, width);
|
|
58023
57967
|
lines.push(_activeMain);
|
|
@@ -58025,13 +57969,39 @@ function buildWidgetLines(cwd, frame = 0, maxLines = 8, providedRuns, notificati
|
|
|
58025
57969
|
lines.push(_activity);
|
|
58026
57970
|
}
|
|
58027
57971
|
if (activeAgents.length > activeCap) {
|
|
58028
|
-
lines.push(
|
|
57972
|
+
lines.push(
|
|
57973
|
+
truncate(
|
|
57974
|
+
rowStyle === "compact" ? `\u2026 +${activeAgents.length - activeCap} more agents` : `\u2502 \u2514\u2500 \u2026 +${activeAgents.length - activeCap} more agents`,
|
|
57975
|
+
width
|
|
57976
|
+
)
|
|
57977
|
+
);
|
|
58029
57978
|
}
|
|
58030
57979
|
for (const [index, agent] of finishedAgents.slice(0, finishedSlots).entries()) {
|
|
58031
57980
|
const liveHandle = liveForRun.find((h) => h.taskId === agent.taskId);
|
|
58032
57981
|
const name = liveHandle?.agent ?? agent.agent;
|
|
57982
|
+
const dockIcon = dockStatusIcon(agent.status);
|
|
58033
57983
|
const legacyIcon = agent.status === "completed" ? "\u2713" : agent.status === "failed" ? "\u2717" : agent.status === "needs_attention" ? "\u26A0" : "\u25AA";
|
|
58034
57984
|
const stats = agentStats(agent, liveHandle);
|
|
57985
|
+
if (rowStyle === "compact") {
|
|
57986
|
+
const label = liveHandle?.description ?? agent.role ?? "";
|
|
57987
|
+
const runTag = runs.length > 1 ? `${shortRunLabel(run)} \xB7 ` : "";
|
|
57988
|
+
const nameText = runTag + (label ? `${name} \xB7 ${label}` : name);
|
|
57989
|
+
const usage = dockUsageText(agent, liveHandle, { viewed: options.viewedTaskId === agent.taskId });
|
|
57990
|
+
const ageText = dockElapsed(agent.completedAt ?? agent.startedAt);
|
|
57991
|
+
const suffix = `${usage ? ` \xB7 ${usage}` : ""}${ageText ? ` \xB7 ${ageText}` : ""}`;
|
|
57992
|
+
lines.push(
|
|
57993
|
+
budgetedRow(
|
|
57994
|
+
{
|
|
57995
|
+
lead: `${markerFor2(agent.taskId)} ${dockIcon} `,
|
|
57996
|
+
name: nameText,
|
|
57997
|
+
activity: dockStatusLabel(agent.status),
|
|
57998
|
+
suffix
|
|
57999
|
+
},
|
|
58000
|
+
width
|
|
58001
|
+
)
|
|
58002
|
+
);
|
|
58003
|
+
continue;
|
|
58004
|
+
}
|
|
58035
58005
|
const desc = truncate(liveHandle?.description ?? agent.role ?? "", TASK_DESC_MAX);
|
|
58036
58006
|
const isLastFinished = index === Math.min(finishedAgents.length, finishedSlots) - 1;
|
|
58037
58007
|
const branch = isLastFinished ? "\u2514\u2500" : "\u251C\u2500";
|
|
@@ -58508,138 +58478,6 @@ var init_shared_overlay_scheduler = __esm({
|
|
|
58508
58478
|
}
|
|
58509
58479
|
});
|
|
58510
58480
|
|
|
58511
|
-
// src/ui/widget/task-list.ts
|
|
58512
|
-
function isDoneStatus(status) {
|
|
58513
|
-
return status === "completed" || status === "failed" || status === "cancelled" || status === "skipped";
|
|
58514
|
-
}
|
|
58515
|
-
function taskTitle(task) {
|
|
58516
|
-
return (task.displayName ?? task.title ?? "").replace(/\s+/g, " ").trim();
|
|
58517
|
-
}
|
|
58518
|
-
function taskStatusIcon(task) {
|
|
58519
|
-
switch (task.status) {
|
|
58520
|
-
case "running":
|
|
58521
|
-
return spinnerFrame("crew-task-list");
|
|
58522
|
-
case "queued":
|
|
58523
|
-
return "\u25FB";
|
|
58524
|
-
case "waiting":
|
|
58525
|
-
case "needs_attention":
|
|
58526
|
-
return "\u25FC";
|
|
58527
|
-
case "completed":
|
|
58528
|
-
return "\u2714";
|
|
58529
|
-
case "failed":
|
|
58530
|
-
case "cancelled":
|
|
58531
|
-
case "skipped":
|
|
58532
|
-
return "\u2717";
|
|
58533
|
-
default:
|
|
58534
|
-
return "?";
|
|
58535
|
-
}
|
|
58536
|
-
}
|
|
58537
|
-
function formatDuration2(ms) {
|
|
58538
|
-
if (!Number.isFinite(ms) || ms < 0) return "";
|
|
58539
|
-
const totalSeconds = Math.floor(ms / 1e3);
|
|
58540
|
-
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
58541
|
-
const minutes = Math.floor(totalSeconds / 60);
|
|
58542
|
-
if (minutes < 60) return `${minutes}m ${String(totalSeconds % 60).padStart(2, "0")}s`;
|
|
58543
|
-
const hours = Math.floor(minutes / 60);
|
|
58544
|
-
return `${hours}h ${String(minutes % 60).padStart(2, "0")}m`;
|
|
58545
|
-
}
|
|
58546
|
-
function compactTokens2(count2) {
|
|
58547
|
-
if (typeof count2 !== "number" || !Number.isFinite(count2) || count2 <= 0) return "";
|
|
58548
|
-
if (count2 >= 1e6) return `${(count2 / 1e6).toFixed(1)}M`;
|
|
58549
|
-
if (count2 >= 1e3) return `${(count2 / 1e3).toFixed(1)}k`;
|
|
58550
|
-
return `${count2}`;
|
|
58551
|
-
}
|
|
58552
|
-
function runningSuffix(task) {
|
|
58553
|
-
const parts = [];
|
|
58554
|
-
const start = Date.parse(task.startedAt ?? "");
|
|
58555
|
-
if (Number.isFinite(start) && start > 0) {
|
|
58556
|
-
const end = task.finishedAt ? Date.parse(task.finishedAt) : Date.now();
|
|
58557
|
-
const elapsed2 = formatDuration2(end - start);
|
|
58558
|
-
if (elapsed2) parts.push(elapsed2);
|
|
58559
|
-
}
|
|
58560
|
-
const input = task.usage?.input ?? 0;
|
|
58561
|
-
const output = task.usage?.output ?? 0;
|
|
58562
|
-
if (input > 0 || output > 0) {
|
|
58563
|
-
parts.push(`\u2191 ${compactTokens2(input) || "0"} \u2193 ${compactTokens2(output) || "0"}`);
|
|
58564
|
-
} else {
|
|
58565
|
-
const live = compactTokens2(task.agentProgress?.tokens ?? 0);
|
|
58566
|
-
if (live) parts.push(live);
|
|
58567
|
-
}
|
|
58568
|
-
return parts.length ? ` (${parts.join(" \xB7 ")})` : "";
|
|
58569
|
-
}
|
|
58570
|
-
function blockedSuffix(task, tasks, numberById) {
|
|
58571
|
-
if (task.status !== "queued") return "";
|
|
58572
|
-
const openDeps = (task.dependsOn ?? []).map((depId) => tasks.find((entry) => entry.id === depId)).filter((dep) => dep !== void 0 && dep.status !== "completed");
|
|
58573
|
-
if (openDeps.length === 0) return "";
|
|
58574
|
-
const labels = openDeps.map((dep) => `#${numberById.get(dep.id) ?? "?"}`);
|
|
58575
|
-
return ` \u203A blocked by ${labels.join(", ")}`;
|
|
58576
|
-
}
|
|
58577
|
-
function taskRow(task, taskNumber, tasks, numberById, width) {
|
|
58578
|
-
const title = taskTitle(task);
|
|
58579
|
-
const suffix = task.status === "running" ? runningSuffix(task) : blockedSuffix(task, tasks, numberById);
|
|
58580
|
-
if (task.status === "completed") {
|
|
58581
|
-
const struck = `${STRIKE_ON}${DIM_ON}#${taskNumber} ${title}${DIM_OFF}${STRIKE_OFF}`;
|
|
58582
|
-
return truncate(` \u2714 ${struck}`.trimEnd(), width);
|
|
58583
|
-
}
|
|
58584
|
-
return truncate(` ${taskStatusIcon(task)} #${taskNumber} ${title}${suffix}`.trimEnd(), width);
|
|
58585
|
-
}
|
|
58586
|
-
function primaryRun(runs) {
|
|
58587
|
-
return runs.find((entry) => (entry.snapshot?.tasks ?? []).some((task) => ACTIVE_TASK_STATUSES.has(task.status))) ?? runs[0];
|
|
58588
|
-
}
|
|
58589
|
-
function visibleTasks(tasks) {
|
|
58590
|
-
if (tasks.length <= MAX_TASK_ROWS) return [...tasks];
|
|
58591
|
-
const active = tasks.filter((task) => ACTIVE_TASK_STATUSES.has(task.status));
|
|
58592
|
-
if (active.length >= MAX_TASK_ROWS) return active.slice(0, MAX_TASK_ROWS);
|
|
58593
|
-
const keep = new Set(active.map((task) => task.id));
|
|
58594
|
-
for (const task of tasks) {
|
|
58595
|
-
if (keep.size >= MAX_TASK_ROWS) break;
|
|
58596
|
-
keep.add(task.id);
|
|
58597
|
-
}
|
|
58598
|
-
return tasks.filter((task) => keep.has(task.id));
|
|
58599
|
-
}
|
|
58600
|
-
function buildTaskListLines(runs, width) {
|
|
58601
|
-
const entry = primaryRun(runs);
|
|
58602
|
-
if (!entry) return [];
|
|
58603
|
-
const tasks = entry.snapshot?.tasks ?? [];
|
|
58604
|
-
if (tasks.length === 0) return [];
|
|
58605
|
-
const numberById = new Map(tasks.map((task, index) => [task.id, index + 1]));
|
|
58606
|
-
const done = tasks.filter((task) => task.status === "completed").length;
|
|
58607
|
-
const dead = tasks.filter((task) => isDoneStatus(task.status) && task.status !== "completed").length;
|
|
58608
|
-
const inProgress = tasks.filter(
|
|
58609
|
-
(task) => task.status === "running" || task.status === "waiting" || task.status === "needs_attention"
|
|
58610
|
-
).length;
|
|
58611
|
-
const open = tasks.filter((task) => task.status === "queued").length;
|
|
58612
|
-
const counts = [`${done} done`];
|
|
58613
|
-
if (dead) counts.push(`${dead} failed`);
|
|
58614
|
-
counts.push(`${inProgress} in progress`, `${open} open`);
|
|
58615
|
-
const headerParts = [`\u25CF ${tasks.length} tasks (${counts.join(", ")})`];
|
|
58616
|
-
if (runs.length > 1) headerParts.push(shortRunLabel(entry.run));
|
|
58617
|
-
const lines = [truncate(headerParts.join(" \xB7 "), width)];
|
|
58618
|
-
const visible = visibleTasks(tasks);
|
|
58619
|
-
for (const task of visible) {
|
|
58620
|
-
lines.push(taskRow(task, numberById.get(task.id) ?? 0, tasks, numberById, width));
|
|
58621
|
-
}
|
|
58622
|
-
if (tasks.length > visible.length) {
|
|
58623
|
-
lines.push(truncate(` \u2026 and ${tasks.length - visible.length} more`, width));
|
|
58624
|
-
}
|
|
58625
|
-
return lines;
|
|
58626
|
-
}
|
|
58627
|
-
var MAX_TASK_ROWS, ACTIVE_TASK_STATUSES, DIM_ON, DIM_OFF, STRIKE_ON, STRIKE_OFF;
|
|
58628
|
-
var init_task_list = __esm({
|
|
58629
|
-
"src/ui/widget/task-list.ts"() {
|
|
58630
|
-
"use strict";
|
|
58631
|
-
init_visual();
|
|
58632
|
-
init_spinner();
|
|
58633
|
-
init_widget_model();
|
|
58634
|
-
MAX_TASK_ROWS = 10;
|
|
58635
|
-
ACTIVE_TASK_STATUSES = /* @__PURE__ */ new Set(["running", "queued", "waiting", "needs_attention"]);
|
|
58636
|
-
DIM_ON = "\x1B[2m";
|
|
58637
|
-
DIM_OFF = "\x1B[22m";
|
|
58638
|
-
STRIKE_ON = "\x1B[9m";
|
|
58639
|
-
STRIKE_OFF = "\x1B[29m";
|
|
58640
|
-
}
|
|
58641
|
-
});
|
|
58642
|
-
|
|
58643
58481
|
// src/ui/widget/index.ts
|
|
58644
58482
|
var widget_exports = {};
|
|
58645
58483
|
__export(widget_exports, {
|
|
@@ -58678,7 +58516,7 @@ function uninstallResizeListener() {
|
|
|
58678
58516
|
clearTimeout(resizeTimer);
|
|
58679
58517
|
resizeTimer = void 0;
|
|
58680
58518
|
}
|
|
58681
|
-
|
|
58519
|
+
activeResizeTarget = void 0;
|
|
58682
58520
|
process.off("SIGWINCH", onResize);
|
|
58683
58521
|
if (typeof process.stdout?.off === "function") {
|
|
58684
58522
|
process.stdout.off("resize", onResize);
|
|
@@ -58716,8 +58554,6 @@ function updateCrewWidget(ctx, state2, config, manifestCache2, snapshotCache, pr
|
|
|
58716
58554
|
if (!lines.length) {
|
|
58717
58555
|
if (state2.lastVisibility !== "hidden" || state2.lastPlacement !== placement) {
|
|
58718
58556
|
setExtensionWidget(ctx, WIDGET_KEY, void 0, { placement: piPlacement });
|
|
58719
|
-
setExtensionWidget(ctx, TASKS_WIDGET_KEY, void 0, { placement: "aboveEditor" });
|
|
58720
|
-
state2.lastTasksVisibility = "hidden";
|
|
58721
58557
|
state2.footerDock?.dispose();
|
|
58722
58558
|
state2.footerDock = void 0;
|
|
58723
58559
|
setFooterDockProvider(void 0);
|
|
@@ -58786,20 +58622,6 @@ function updateCrewWidget(ctx, state2, config, manifestCache2, snapshotCache, pr
|
|
|
58786
58622
|
state2.lastMaxLines = maxLines;
|
|
58787
58623
|
state2.lastCwd = ctx.cwd;
|
|
58788
58624
|
}
|
|
58789
|
-
const tasksVisible = runs.length > 0 && Boolean(state2.model);
|
|
58790
|
-
if (tasksVisible && state2.lastTasksVisibility !== "visible") {
|
|
58791
|
-
const model = state2.model;
|
|
58792
|
-
setExtensionWidget(
|
|
58793
|
-
ctx,
|
|
58794
|
-
TASKS_WIDGET_KEY,
|
|
58795
|
-
((_tui, theme) => new CrewWidgetComponent(model, theme, _tui, "tasks")),
|
|
58796
|
-
{ placement: "aboveEditor" }
|
|
58797
|
-
);
|
|
58798
|
-
state2.lastTasksVisibility = "visible";
|
|
58799
|
-
} else if (!tasksVisible && state2.lastTasksVisibility === "visible") {
|
|
58800
|
-
setExtensionWidget(ctx, TASKS_WIDGET_KEY, void 0, { placement: "aboveEditor" });
|
|
58801
|
-
state2.lastTasksVisibility = "hidden";
|
|
58802
|
-
}
|
|
58803
58625
|
requestRender(ctx);
|
|
58804
58626
|
}
|
|
58805
58627
|
function stopCrewWidget(ctx, state2, config) {
|
|
@@ -58810,8 +58632,6 @@ function stopCrewWidget(ctx, state2, config) {
|
|
|
58810
58632
|
ctx.ui.setStatus(STATUS_KEY, void 0);
|
|
58811
58633
|
setExtensionWidget(ctx, LEGACY_WIDGET_KEY, void 0, { placement: piPlacement });
|
|
58812
58634
|
setExtensionWidget(ctx, WIDGET_KEY, void 0, { placement: piPlacement });
|
|
58813
|
-
setExtensionWidget(ctx, TASKS_WIDGET_KEY, void 0, { placement: "aboveEditor" });
|
|
58814
|
-
state2.lastTasksVisibility = "hidden";
|
|
58815
58635
|
state2.footerDock?.dispose();
|
|
58816
58636
|
state2.footerDock = void 0;
|
|
58817
58637
|
setFooterDockProvider(void 0);
|
|
@@ -58823,7 +58643,7 @@ function stopCrewWidget(ctx, state2, config) {
|
|
|
58823
58643
|
requestRender(ctx);
|
|
58824
58644
|
}
|
|
58825
58645
|
}
|
|
58826
|
-
var MAX_LINES_DEFAULT, LEGACY_WIDGET_KEY, WIDGET_KEY,
|
|
58646
|
+
var MAX_LINES_DEFAULT, LEGACY_WIDGET_KEY, WIDGET_KEY, STATUS_KEY, SIGNATURE_CACHE_TTL_MS, resizeListenerInstalled, activeResizeTarget, resizeTimer, onResize, CrewWidgetComponent, FooterDockHost;
|
|
58827
58647
|
var init_widget = __esm({
|
|
58828
58648
|
"src/ui/widget/index.ts"() {
|
|
58829
58649
|
"use strict";
|
|
@@ -58836,7 +58656,6 @@ var init_widget = __esm({
|
|
|
58836
58656
|
init_shared_overlay_scheduler();
|
|
58837
58657
|
init_spinner();
|
|
58838
58658
|
init_theme_adapter();
|
|
58839
|
-
init_task_list();
|
|
58840
58659
|
init_widget_model();
|
|
58841
58660
|
init_widget_renderer();
|
|
58842
58661
|
init_widget_model();
|
|
@@ -58846,26 +58665,20 @@ var init_widget = __esm({
|
|
|
58846
58665
|
MAX_LINES_DEFAULT = DEFAULT_UI.widgetMaxLines;
|
|
58847
58666
|
LEGACY_WIDGET_KEY = "pi-crew";
|
|
58848
58667
|
WIDGET_KEY = "pi-crew-active";
|
|
58849
|
-
TASKS_WIDGET_KEY = "pi-crew-tasks";
|
|
58850
58668
|
STATUS_KEY = "pi-crew";
|
|
58851
58669
|
SIGNATURE_CACHE_TTL_MS = 100;
|
|
58852
58670
|
resizeListenerInstalled = false;
|
|
58853
|
-
activeResizeTargets = /* @__PURE__ */ new Set();
|
|
58854
58671
|
onResize = () => {
|
|
58855
58672
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
58856
58673
|
resizeTimer = setTimeout(() => {
|
|
58857
58674
|
resizeTimer = void 0;
|
|
58858
|
-
|
|
58859
|
-
|
|
58860
|
-
target.requestRepaint();
|
|
58861
|
-
}
|
|
58675
|
+
activeResizeTarget?.invalidate();
|
|
58676
|
+
activeResizeTarget?.requestRepaint();
|
|
58862
58677
|
}, 120);
|
|
58863
58678
|
};
|
|
58864
58679
|
CrewWidgetComponent = class {
|
|
58865
58680
|
model;
|
|
58866
58681
|
theme;
|
|
58867
|
-
/** Which surface this instance paints: the agent dock, or the task list. */
|
|
58868
|
-
variant;
|
|
58869
58682
|
cacheSignature = "";
|
|
58870
58683
|
/** C4 — invalidate-on-write cache for the buildSignature() result. */
|
|
58871
58684
|
cachedBuildSignature = "";
|
|
@@ -58878,13 +58691,12 @@ var init_widget = __esm({
|
|
|
58878
58691
|
unsubscribeTheme;
|
|
58879
58692
|
unsubscribePanel;
|
|
58880
58693
|
schedulerHandle;
|
|
58881
|
-
constructor(model, themeLike, tui
|
|
58694
|
+
constructor(model, themeLike, tui) {
|
|
58882
58695
|
this.model = model;
|
|
58883
|
-
this.variant = variant;
|
|
58884
58696
|
this.theme = asCrewTheme(themeLike);
|
|
58885
58697
|
this.cachedTheme = this.theme;
|
|
58886
58698
|
this.tui = tui;
|
|
58887
|
-
|
|
58699
|
+
activeResizeTarget = this;
|
|
58888
58700
|
installResizeListener();
|
|
58889
58701
|
this.unsubscribeTheme = subscribeThemeChange(themeLike, () => this.invalidate());
|
|
58890
58702
|
this.unsubscribePanel = subscribePanelChange(() => {
|
|
@@ -58942,7 +58754,7 @@ var init_widget = __esm({
|
|
|
58942
58754
|
this.unsubscribeTheme();
|
|
58943
58755
|
this.unsubscribePanel();
|
|
58944
58756
|
this.schedulerHandle.dispose();
|
|
58945
|
-
|
|
58757
|
+
if (activeResizeTarget === this) activeResizeTarget = void 0;
|
|
58946
58758
|
}
|
|
58947
58759
|
render(width) {
|
|
58948
58760
|
const runs = activeWidgetRuns(
|
|
@@ -58963,20 +58775,6 @@ var init_widget = __esm({
|
|
|
58963
58775
|
}
|
|
58964
58776
|
const signature = `${sigBase}:${this.model.notificationCount ?? 0}`;
|
|
58965
58777
|
const runningGlyph = spinnerFrame("widget-header");
|
|
58966
|
-
if (this.variant === "tasks") {
|
|
58967
|
-
if (this.cacheSignature !== signature || width !== this.cachedWidth || this.cachedTheme !== this.theme) {
|
|
58968
|
-
this.cachedBaseLines = buildTaskListLines(runs, width);
|
|
58969
|
-
this.cachedLines = this.colorize(this.cachedBaseLines, width);
|
|
58970
|
-
this.cachedWidth = width;
|
|
58971
|
-
this.cachedTheme = this.theme;
|
|
58972
|
-
this.cacheSignature = signature;
|
|
58973
|
-
}
|
|
58974
|
-
if (runs.length === 0) {
|
|
58975
|
-
this.invalidate();
|
|
58976
|
-
return [];
|
|
58977
|
-
}
|
|
58978
|
-
return this.cachedLines.map((line4) => truncate(line4, width));
|
|
58979
|
-
}
|
|
58980
58778
|
const panel = panelDisplayState();
|
|
58981
58779
|
const signatureWithPanel = `${signature}|panel:${panel.selectedTaskId ?? ""}/${panel.viewedTaskId ?? ""}/${panel.focused ? 1 : 0}`;
|
|
58982
58780
|
const compactDock = this.model.rowStyle === "compact";
|
|
@@ -60266,7 +60064,7 @@ function loadRunSummaries(cwd, options = {}) {
|
|
|
60266
60064
|
}
|
|
60267
60065
|
return summaries;
|
|
60268
60066
|
}
|
|
60269
|
-
function
|
|
60067
|
+
function formatDuration2(createdAt, completedAt) {
|
|
60270
60068
|
const start = new Date(createdAt).getTime();
|
|
60271
60069
|
const end = completedAt ? new Date(completedAt).getTime() : Date.now();
|
|
60272
60070
|
if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return "?";
|
|
@@ -60310,7 +60108,7 @@ function buildTeamOnboarding(team, cwd, options = {}) {
|
|
|
60310
60108
|
lines.push("| Run | Goal | Duration | Status |");
|
|
60311
60109
|
lines.push("|-----|------|----------|--------|");
|
|
60312
60110
|
for (const run of runs) {
|
|
60313
|
-
const duration =
|
|
60111
|
+
const duration = formatDuration2(run.createdAt, run.completedAt);
|
|
60314
60112
|
const goalPreview = run.goal ? run.goal.slice(0, 40) : "N/A";
|
|
60315
60113
|
const goalSuffix = run.goal && run.goal.length > 40 ? "..." : "";
|
|
60316
60114
|
const status = run.status ?? "unknown";
|
|
@@ -63456,11 +63254,8 @@ function reconstructAdaptiveWorkflow(workflow, tasks) {
|
|
|
63456
63254
|
}
|
|
63457
63255
|
return steps.length ? { ...workflow, steps: [...workflow.steps, ...steps] } : workflow;
|
|
63458
63256
|
}
|
|
63459
|
-
function isAdaptiveWorkflow(workflow) {
|
|
63460
|
-
return workflow.adaptive === true || workflow.name === "implementation";
|
|
63461
|
-
}
|
|
63462
63257
|
async function injectAdaptivePlanIfReady(input) {
|
|
63463
|
-
if (
|
|
63258
|
+
if (input.workflow.name !== "implementation")
|
|
63464
63259
|
return {
|
|
63465
63260
|
tasks: input.tasks,
|
|
63466
63261
|
workflow: input.workflow,
|
|
@@ -63580,13 +63375,11 @@ async function injectAdaptivePlanIfReady(input) {
|
|
|
63580
63375
|
const itemId = `adaptive-p${phaseIndex + 1}-t${taskIndex + 1}`;
|
|
63581
63376
|
const stepId = `adaptive-${phaseIndex + 1}-${taskIndex + 1}-${slug(planned.role)}`;
|
|
63582
63377
|
const taskId = `adaptive-${String(counter).padStart(2, "0")}-${slug(planned.role)}`;
|
|
63583
|
-
const firstLine = planned.task.split("\n").map((line4) => line4.trim()).filter(Boolean).find((line4) => !line4.startsWith("#")) ?? "";
|
|
63584
|
-
const title = (planned.title ?? firstLine ?? stepId).slice(0, 120);
|
|
63585
63378
|
phaseItemIds.push(itemId);
|
|
63586
63379
|
planItems.push({
|
|
63587
63380
|
id: itemId,
|
|
63588
63381
|
ref: stepId,
|
|
63589
|
-
title,
|
|
63382
|
+
title: planned.title ?? planned.task.slice(0, 80),
|
|
63590
63383
|
taskIds: [],
|
|
63591
63384
|
specIds: [],
|
|
63592
63385
|
acceptance: [],
|
|
@@ -63605,8 +63398,7 @@ async function injectAdaptivePlanIfReady(input) {
|
|
|
63605
63398
|
stepId,
|
|
63606
63399
|
role: planned.role,
|
|
63607
63400
|
agent: input.team.roles.find((role) => role.name === planned.role)?.agent ?? planned.role,
|
|
63608
|
-
title,
|
|
63609
|
-
description: planned.task !== title ? planned.task : void 0,
|
|
63401
|
+
title: planned.title ?? stepId,
|
|
63610
63402
|
status: "queued",
|
|
63611
63403
|
dependsOn: previousStepIds,
|
|
63612
63404
|
cwd: input.manifest.cwd,
|
|
@@ -64328,7 +64120,7 @@ async function executeTeamRunCore(input, manifest, workflow) {
|
|
|
64328
64120
|
}
|
|
64329
64121
|
let tasks = refreshTaskGraphQueues(input.tasks);
|
|
64330
64122
|
let queueIndex = buildTaskGraphIndex(tasks);
|
|
64331
|
-
const canInjectAdaptivePlan =
|
|
64123
|
+
const canInjectAdaptivePlan = workflow.name === "implementation";
|
|
64332
64124
|
let adaptivePlanInjected = false;
|
|
64333
64125
|
let adaptivePlanMissing = false;
|
|
64334
64126
|
const attemptAdaptivePlan = async () => {
|
|
@@ -64337,8 +64129,7 @@ async function executeTeamRunCore(input, manifest, workflow) {
|
|
|
64337
64129
|
manifest,
|
|
64338
64130
|
tasks,
|
|
64339
64131
|
workflow,
|
|
64340
|
-
team: input.team
|
|
64341
|
-
executeWorkers: input.executeWorkers
|
|
64132
|
+
team: input.team
|
|
64342
64133
|
});
|
|
64343
64134
|
adaptivePlanInjected = adaptivePlanInjected || adaptivePlan.injected;
|
|
64344
64135
|
adaptivePlanMissing = adaptivePlan.missingPlan;
|