@saadnvd1/agent-os 0.3.723 → 0.3.728
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/README.md +1 -0
- package/app/api/loops/route.ts +17 -0
- package/app/api/tasks/[id]/loop/cycles/[n]/log/route.ts +29 -0
- package/app/api/tasks/[id]/loop/draft-criteria/route.ts +17 -0
- package/app/api/tasks/[id]/loop/next/route.ts +25 -0
- package/app/api/tasks/[id]/loop/route.ts +72 -0
- package/app/api/tasks/[id]/loop/run/route.ts +12 -0
- package/app/api/tasks/[id]/loop/stop/route.ts +12 -0
- package/app/api/tasks/[id]/mode/route.ts +29 -0
- package/app/api/tasks/[id]/report/draft/route.ts +54 -0
- package/app/api/tasks/[id]/report/evidence/[evId]/route.ts +18 -0
- package/app/api/tasks/[id]/report/route.ts +39 -0
- package/app/api/workspaces/[id]/mode/route.ts +23 -0
- package/app/api/workspaces/[id]/reports/route.ts +17 -0
- package/app/page.tsx +8 -0
- package/components/Analyst/PairChip.tsx +131 -0
- package/components/Analyst/PairSwitch.tsx +76 -0
- package/components/Analyst/ReviewCard.tsx +272 -0
- package/components/Analyst/SignalChips.tsx +39 -0
- package/components/Analyst/StartAnalystSheet.tsx +109 -0
- package/components/Analyst/cardState.test.ts +109 -0
- package/components/Analyst/cardState.ts +95 -0
- package/components/Analyst/pair.ts +81 -0
- package/components/Chat/Code.tsx +3 -0
- package/components/Chat/Messages.tsx +6 -1
- package/components/Chat/itemContext.ts +14 -0
- package/components/Draft/DraftChips.tsx +10 -0
- package/components/Draft/DraftPanel.tsx +7 -0
- package/components/Pane/DesktopTabBar.tsx +6 -0
- package/components/Pane/MobileTabBar.tsx +17 -0
- package/components/Pane/MobileViewPicker.tsx +4 -0
- package/components/Pane/PaneMenu.test.ts +21 -0
- package/components/Pane/PaneMenu.tsx +16 -0
- package/components/Pane/PaneViewToggle.tsx +12 -0
- package/components/Pane/index.tsx +19 -0
- package/components/Report/DraftCard.tsx +89 -0
- package/components/Report/EstimateBar.tsx +51 -0
- package/components/Report/EvidenceSheet.tsx +98 -0
- package/components/Report/ModeChooser.tsx +43 -0
- package/components/Report/ReportView.tsx +289 -0
- package/components/SessionList/SessionRowMenu.tsx +6 -0
- package/components/Sessions/RolePill.tsx +7 -0
- package/components/Tasks/Loop/LoopButton.tsx +74 -0
- package/components/Tasks/Loop/LoopSetup.tsx +146 -0
- package/components/Tasks/Loop/LoopView.tsx +350 -0
- package/components/Tasks/Loop/labels.ts +17 -0
- package/components/Tasks/TaskRow.tsx +2 -0
- package/components/Workspaces/WorkspaceModeForm.tsx +22 -0
- package/components/Workspaces/WorkspaceSettings.tsx +2 -0
- package/components/ui/segmented.tsx +55 -0
- package/components/ui/status-pill.tsx +3 -0
- package/contexts/PaneContext.tsx +21 -1
- package/data/loops/index.ts +3 -0
- package/data/loops/keys.ts +4 -0
- package/data/loops/mutations.ts +68 -0
- package/data/loops/queries.ts +40 -0
- package/data/push/topics.ts +6 -0
- package/data/reports/index.ts +115 -0
- package/lib/analyst/forward.ts +1 -1
- package/lib/db/changes.ts +7 -0
- package/lib/db/migrations/20261021T1600_task_loops.ts +81 -0
- package/lib/db/migrations/20261021T1800_health_reports.ts +38 -0
- package/lib/done/index.ts +2 -0
- package/lib/drafts.ts +2 -0
- package/lib/loops/analyse.ts +46 -0
- package/lib/loops/analyst-prompt.ts +203 -0
- package/lib/loops/checkCriteria.ts +114 -0
- package/lib/loops/compactEvidence.ts +140 -0
- package/lib/loops/controls.ts +317 -0
- package/lib/loops/decideStop.ts +113 -0
- package/lib/loops/deps.ts +128 -0
- package/lib/loops/diffMap.ts +39 -0
- package/lib/loops/draftCriteria.ts +71 -0
- package/lib/loops/gatherEvidence.ts +265 -0
- package/lib/loops/hooks.ts +40 -0
- package/lib/loops/index.ts +7 -0
- package/lib/loops/route.ts +83 -0
- package/lib/loops/runCycle.ts +323 -0
- package/lib/loops/screenInstruction.ts +59 -0
- package/lib/loops/sendInstruction.ts +83 -0
- package/lib/loops/snapshot.ts +38 -0
- package/lib/loops/stopLoop.ts +86 -0
- package/lib/loops/store.ts +481 -0
- package/lib/loops/summary.ts +27 -0
- package/lib/loops/tickLoops.ts +141 -0
- package/lib/loops/types.ts +223 -0
- package/lib/loops/world.test-helpers.ts +223 -0
- package/lib/models/plan-step.ts +4 -1
- package/lib/orchestrator/digest.ts +2 -1
- package/lib/orchestrator/loop-guard.ts +5 -2
- package/lib/orchestrator/pr-wake.ts +4 -0
- package/lib/orchestrator/watcher.ts +8 -1
- package/lib/panes.ts +52 -0
- package/lib/plans/acceptance.ts +23 -0
- package/lib/reports/drafts.ts +87 -0
- package/lib/reports/end-hook.ts +17 -0
- package/lib/reports/estimate.ts +107 -0
- package/lib/reports/evidence/build.ts +193 -0
- package/lib/reports/evidence/gather.ts +229 -0
- package/lib/reports/fixtures.ts +17 -0
- package/lib/reports/generate.ts +159 -0
- package/lib/reports/hooks.ts +30 -0
- package/lib/reports/mode.ts +65 -0
- package/lib/reports/model.ts +115 -0
- package/lib/reports/read.ts +26 -0
- package/lib/reports/store.ts +180 -0
- package/lib/reports/template.ts +117 -0
- package/lib/reports/types.ts +135 -0
- package/lib/reports/validate.ts +142 -0
- package/lib/sidebar/row-menu.ts +9 -0
- package/lib/tasks/contract/routes.ts +5 -0
- package/lib/tasks/contract/types.ts +3 -0
- package/lib/tasks/finish.ts +2 -0
- package/lib/tasks/move-carry.ts +1 -0
- package/package.json +2 -2
- package/stores/analystUi.ts +19 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// Plain-English health reports: types shared by the server, the browser and
|
|
2
|
+
// the native app (no Node modules here).
|
|
3
|
+
|
|
4
|
+
import type { TaskState } from "../tasks/state";
|
|
5
|
+
|
|
6
|
+
export const OPERATING_MODES = ["manual", "assisted", "autonomous"] as const;
|
|
7
|
+
export type OperatingMode = (typeof OPERATING_MODES)[number];
|
|
8
|
+
export const isMode = (v: unknown): v is OperatingMode =>
|
|
9
|
+
typeof v === "string" && (OPERATING_MODES as readonly string[]).includes(v);
|
|
10
|
+
|
|
11
|
+
export const MODE_COPY: Record<
|
|
12
|
+
OperatingMode,
|
|
13
|
+
{ label: string; blurb: string }
|
|
14
|
+
> = {
|
|
15
|
+
manual: {
|
|
16
|
+
label: "Manual",
|
|
17
|
+
blurb: "The analyst recommends, you decide.",
|
|
18
|
+
},
|
|
19
|
+
assisted: {
|
|
20
|
+
label: "Assisted",
|
|
21
|
+
blurb: "The analyst drafts the next prompt, you approve it with one click.",
|
|
22
|
+
},
|
|
23
|
+
autonomous: {
|
|
24
|
+
label: "Autonomous",
|
|
25
|
+
blurb: "Agents iterate on their own, within the loop's safeguards.",
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type ReportTrigger = "on-demand" | "cycle" | "end";
|
|
30
|
+
export type LineTone = "done" | "warn" | "blocked" | "next";
|
|
31
|
+
export type EvidenceKind =
|
|
32
|
+
| "ci"
|
|
33
|
+
| "test"
|
|
34
|
+
| "review"
|
|
35
|
+
| "diff"
|
|
36
|
+
| "piece"
|
|
37
|
+
| "accept"
|
|
38
|
+
| "ask"
|
|
39
|
+
| "state"
|
|
40
|
+
| "log";
|
|
41
|
+
export type EvidenceStatus = "pass" | "fail" | "pending" | "info";
|
|
42
|
+
|
|
43
|
+
export interface EvidenceRef {
|
|
44
|
+
id: string;
|
|
45
|
+
kind: EvidenceKind;
|
|
46
|
+
label: string;
|
|
47
|
+
status: EvidenceStatus;
|
|
48
|
+
at: string;
|
|
49
|
+
// The head it belongs to; stale when it differs from the current head.
|
|
50
|
+
sha?: string;
|
|
51
|
+
url?: string;
|
|
52
|
+
href?: string;
|
|
53
|
+
excerpt?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface ReportLine {
|
|
57
|
+
id: string;
|
|
58
|
+
tone: LineTone;
|
|
59
|
+
text: string;
|
|
60
|
+
evidence: string[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface EstimateItem {
|
|
64
|
+
label: string;
|
|
65
|
+
verified: boolean;
|
|
66
|
+
evidence: string[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface Estimate {
|
|
70
|
+
done: number;
|
|
71
|
+
total: number;
|
|
72
|
+
basis: "acceptance" | "stages";
|
|
73
|
+
items: EstimateItem[];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type DraftStatus = "pending" | "sent" | "dismissed" | "superseded";
|
|
77
|
+
|
|
78
|
+
export interface NextPromptDraft {
|
|
79
|
+
// The report row that holds it, or the analyst recommendation.
|
|
80
|
+
source: "report" | "analyst";
|
|
81
|
+
id: string;
|
|
82
|
+
text: string;
|
|
83
|
+
status: DraftStatus;
|
|
84
|
+
// Analyst drafts send through the analyst link.
|
|
85
|
+
linkId?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface HealthReport {
|
|
89
|
+
id: number;
|
|
90
|
+
sessionId: string;
|
|
91
|
+
workspaceId: string | null;
|
|
92
|
+
head: string | null;
|
|
93
|
+
trigger: ReportTrigger;
|
|
94
|
+
createdAt: string;
|
|
95
|
+
headline: string;
|
|
96
|
+
state: TaskState;
|
|
97
|
+
estimate: Estimate;
|
|
98
|
+
lines: ReportLine[];
|
|
99
|
+
recommendation: { text: string; evidence: string[] } | null;
|
|
100
|
+
draft: NextPromptDraft | null;
|
|
101
|
+
evidence: EvidenceRef[];
|
|
102
|
+
// "template": the model failed, or every line it wrote was rejected.
|
|
103
|
+
source: "model" | "template";
|
|
104
|
+
// Model lines the validator rejected.
|
|
105
|
+
dropped: number;
|
|
106
|
+
model: string | null;
|
|
107
|
+
costUsd: number | null;
|
|
108
|
+
// Computed on read: the head moved since.
|
|
109
|
+
stale: boolean;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface ReportSummary {
|
|
113
|
+
sessionId: string;
|
|
114
|
+
name: string;
|
|
115
|
+
headline: string;
|
|
116
|
+
state: TaskState;
|
|
117
|
+
estimate: Pick<Estimate, "done" | "total" | "basis">;
|
|
118
|
+
createdAt: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface ReportResponse {
|
|
122
|
+
report: HealthReport | null;
|
|
123
|
+
generating: boolean;
|
|
124
|
+
mode: { mode: OperatingMode; source: "task" | "workspace" | "default" };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const estimateLabel = (e: Pick<Estimate, "done" | "total" | "basis">) =>
|
|
128
|
+
`Estimate · ${e.done} of ${e.total} ${
|
|
129
|
+
e.basis === "acceptance"
|
|
130
|
+
? "acceptance items verified"
|
|
131
|
+
: "delivery stages reached"
|
|
132
|
+
}`;
|
|
133
|
+
|
|
134
|
+
export const estimatePercent = (e: Pick<Estimate, "done" | "total">) =>
|
|
135
|
+
e.total ? Math.round((100 * e.done) / e.total) : 0;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// What a model may say in a report. Every line must cite evidence that
|
|
2
|
+
// exists, say only numbers that evidence contains, never use a percent sign,
|
|
3
|
+
// and take a tone its evidence supports. What fails is dropped and counted.
|
|
4
|
+
|
|
5
|
+
import type { EvidenceRef, LineTone, ReportLine } from "./types";
|
|
6
|
+
import type { Mapping } from "./estimate";
|
|
7
|
+
|
|
8
|
+
export interface ModelReport {
|
|
9
|
+
headline?: unknown;
|
|
10
|
+
lines?: unknown;
|
|
11
|
+
recommendation?: unknown;
|
|
12
|
+
acceptance?: unknown;
|
|
13
|
+
nextPrompt?: unknown;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface Validated {
|
|
17
|
+
headline: string | null;
|
|
18
|
+
lines: ReportLine[];
|
|
19
|
+
recommendation: { text: string; evidence: string[] } | null;
|
|
20
|
+
mappings: Mapping[];
|
|
21
|
+
nextPrompt: string | null;
|
|
22
|
+
dropped: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const MAX_LINE = 280;
|
|
26
|
+
export const MAX_LINES = 10;
|
|
27
|
+
export const MAX_PROMPT = 4000;
|
|
28
|
+
const TONES: LineTone[] = ["done", "warn", "blocked", "next"];
|
|
29
|
+
|
|
30
|
+
const str = (v: unknown, max: number) =>
|
|
31
|
+
typeof v === "string" ? v.trim().slice(0, max) : "";
|
|
32
|
+
const ids = (v: unknown): string[] =>
|
|
33
|
+
Array.isArray(v)
|
|
34
|
+
? [...new Set(v.filter((x): x is string => typeof x === "string"))]
|
|
35
|
+
: [];
|
|
36
|
+
|
|
37
|
+
// Digits in the text that none of the cited evidence contains.
|
|
38
|
+
function inventedNumber(text: string, cited: EvidenceRef[]): boolean {
|
|
39
|
+
const nums = text.match(/\d+/g);
|
|
40
|
+
if (!nums) return false;
|
|
41
|
+
const haystack = cited
|
|
42
|
+
.map((e) => `${e.id} ${e.label} ${e.excerpt ?? ""} ${e.sha ?? ""}`)
|
|
43
|
+
.join("\n");
|
|
44
|
+
return nums.some((n) => !new RegExp(`(?<!\\d)${n}(?!\\d)`).test(haystack));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function sayable(text: string, cited: EvidenceRef[]): boolean {
|
|
48
|
+
return (
|
|
49
|
+
!!text &&
|
|
50
|
+
text.length <= MAX_LINE &&
|
|
51
|
+
!/%/.test(text) &&
|
|
52
|
+
!inventedNumber(text, cited)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function toneFits(tone: LineTone, cited: EvidenceRef[]): boolean {
|
|
57
|
+
if (tone === "done") return cited.some((e) => e.status === "pass");
|
|
58
|
+
if (tone === "warn" || tone === "blocked")
|
|
59
|
+
return cited.some(
|
|
60
|
+
(e) => e.status === "fail" || e.status === "pending" || e.kind === "ask"
|
|
61
|
+
);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function validateModelReport(
|
|
66
|
+
raw: unknown,
|
|
67
|
+
evidence: EvidenceRef[]
|
|
68
|
+
): Validated {
|
|
69
|
+
const out: Validated = {
|
|
70
|
+
headline: null,
|
|
71
|
+
lines: [],
|
|
72
|
+
recommendation: null,
|
|
73
|
+
mappings: [],
|
|
74
|
+
nextPrompt: null,
|
|
75
|
+
dropped: 0,
|
|
76
|
+
};
|
|
77
|
+
if (!raw || typeof raw !== "object") return out;
|
|
78
|
+
const m = raw as ModelReport;
|
|
79
|
+
const byId = new Map(evidence.map((e) => [e.id, e]));
|
|
80
|
+
const resolve = (cites: string[]) => {
|
|
81
|
+
const found = cites.map((c) => byId.get(c));
|
|
82
|
+
return found.some((e) => !e) ? null : (found as EvidenceRef[]);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const headline = str(m.headline, MAX_LINE);
|
|
86
|
+
if (
|
|
87
|
+
headline &&
|
|
88
|
+
sayable(
|
|
89
|
+
headline,
|
|
90
|
+
evidence.filter((e) => e.kind === "state")
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
out.headline = headline;
|
|
94
|
+
else if (headline) out.dropped++;
|
|
95
|
+
|
|
96
|
+
const rawLines = Array.isArray(m.lines) ? m.lines.slice(0, 24) : [];
|
|
97
|
+
for (const l of rawLines) {
|
|
98
|
+
const o = (l ?? {}) as Record<string, unknown>;
|
|
99
|
+
const tone = o.tone as LineTone;
|
|
100
|
+
const text = str(o.text, MAX_LINE + 1);
|
|
101
|
+
const cites = ids(o.evidence);
|
|
102
|
+
const cited = cites.length ? resolve(cites) : null;
|
|
103
|
+
if (
|
|
104
|
+
!TONES.includes(tone) ||
|
|
105
|
+
!cited ||
|
|
106
|
+
!sayable(text, cited) ||
|
|
107
|
+
!toneFits(tone, cited) ||
|
|
108
|
+
out.lines.length >= MAX_LINES
|
|
109
|
+
) {
|
|
110
|
+
out.dropped++;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
out.lines.push({
|
|
114
|
+
id: `l${out.lines.length + 1}`,
|
|
115
|
+
tone,
|
|
116
|
+
text,
|
|
117
|
+
evidence: cites,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (m.recommendation && typeof m.recommendation === "object") {
|
|
122
|
+
const r = m.recommendation as Record<string, unknown>;
|
|
123
|
+
const text = str(r.text, 600);
|
|
124
|
+
const cites = ids(r.evidence);
|
|
125
|
+
const cited = cites.length ? resolve(cites) : null;
|
|
126
|
+
if (text && cited && !/%/.test(text) && !inventedNumber(text, cited))
|
|
127
|
+
out.recommendation = { text, evidence: cites };
|
|
128
|
+
else out.dropped++;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (Array.isArray(m.acceptance))
|
|
132
|
+
for (const a of m.acceptance.slice(0, 24)) {
|
|
133
|
+
const o = (a ?? {}) as Record<string, unknown>;
|
|
134
|
+
// The model sees items numbered from 1, as in "accept:1".
|
|
135
|
+
if (typeof o.item === "number" && Number.isInteger(o.item) && o.item >= 1)
|
|
136
|
+
out.mappings.push({ item: o.item - 1, evidence: ids(o.evidence) });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const prompt = str(m.nextPrompt, MAX_PROMPT);
|
|
140
|
+
if (prompt) out.nextPrompt = prompt;
|
|
141
|
+
return out;
|
|
142
|
+
}
|
package/lib/sidebar/row-menu.ts
CHANGED
|
@@ -23,6 +23,7 @@ export type RowMenuItem =
|
|
|
23
23
|
| "move-machine"
|
|
24
24
|
| "move-project"
|
|
25
25
|
| "move-group"
|
|
26
|
+
| "add-analyst"
|
|
26
27
|
| "check-ins"
|
|
27
28
|
| "save-recipe"
|
|
28
29
|
| "run-again"
|
|
@@ -55,6 +56,7 @@ export interface RowMenuInput {
|
|
|
55
56
|
| "has_brief"
|
|
56
57
|
| "archived_at"
|
|
57
58
|
| "pause_state"
|
|
59
|
+
| "agent_role"
|
|
58
60
|
>;
|
|
59
61
|
row?: Pick<SidebarRow, "task" | "wakesAt" | "settled">;
|
|
60
62
|
// A linked machine runs it: what can't reach it yet is left out.
|
|
@@ -142,6 +144,13 @@ export function rowMenu(input: RowMenuInput): RowMenuPlan {
|
|
|
142
144
|
agentRow && "move-group",
|
|
143
145
|
]),
|
|
144
146
|
...group("automate", [
|
|
147
|
+
// A local chat can have an analyst review its turns; not an analyst.
|
|
148
|
+
s.view === "chat" &&
|
|
149
|
+
agentRow &&
|
|
150
|
+
live &&
|
|
151
|
+
!s.archived_at &&
|
|
152
|
+
s.agent_role !== "analyst" &&
|
|
153
|
+
"add-analyst",
|
|
145
154
|
input.hasWorkspace &&
|
|
146
155
|
!orchestrator &&
|
|
147
156
|
(!s.task_status || s.task_status === "running") &&
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
export const taskPath = (id: string, leaf: string) =>
|
|
4
4
|
`/api/tasks/${encodeURIComponent(id)}/${leaf}`;
|
|
5
5
|
|
|
6
|
+
// The loop's routes are the task's own: GET/POST/PATCH on `loop`, and the
|
|
7
|
+
// leaves stop, run and next beside it (lib/loops/route.ts).
|
|
8
|
+
export const loopPath = (id: string, leaf = "") =>
|
|
9
|
+
taskPath(id, leaf ? `loop/${leaf}` : "loop");
|
|
10
|
+
|
|
6
11
|
export const LIST = "/api/tasks";
|
|
7
12
|
export const IMPORT = "/api/tasks/import";
|
|
8
13
|
export const HELD_REPLIES = "/api/tasks/held-replies";
|
|
@@ -27,6 +27,9 @@ export const TASK_CAPABILITIES = [
|
|
|
27
27
|
// compat: the shims marked "task-contract-1" in contract/ go once every
|
|
28
28
|
// linked machine reports this.
|
|
29
29
|
"task-contract-1",
|
|
30
|
+
// A task's developer-analyst loop: /api/tasks/:id/loop and its leaves
|
|
31
|
+
// (lib/loops). A task started on a linked machine is looped from there.
|
|
32
|
+
"task-loop-1",
|
|
30
33
|
] as const;
|
|
31
34
|
|
|
32
35
|
export interface HostTasks {
|
package/lib/tasks/finish.ts
CHANGED
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
} from "./session";
|
|
37
37
|
import { releaseSessionLeftovers } from "../sessions/leftovers";
|
|
38
38
|
import { captureMergedTask } from "../session-logs";
|
|
39
|
+
import { taskEnded } from "../reports/end-hook";
|
|
39
40
|
import { sessionEnded } from "../experiments/hooks";
|
|
40
41
|
import { snapshotWorktree } from "../resurrect/snapshot";
|
|
41
42
|
import { keepSessionFiles } from "../session-artifacts/collect";
|
|
@@ -202,6 +203,7 @@ export async function signOffTask(
|
|
|
202
203
|
pushMerged(id);
|
|
203
204
|
// Reads the plan file now: cleanup below removes the worktree.
|
|
204
205
|
void captureMergedTask(id, { head: opts.head ?? pr!.head ?? null });
|
|
206
|
+
taskEnded(id);
|
|
205
207
|
void sessionEnded(id, "merged");
|
|
206
208
|
const head = opts.head ?? pr!.head;
|
|
207
209
|
resolveMergedTaskAsks(
|
package/lib/tasks/move-carry.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saadnvd1/agent-os",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.728",
|
|
4
4
|
"description": "Self-hosted web UI for managing Claude Code sessions",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agent-os": "scripts/agent-os"
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"mdast-util-from-markdown": "^2.1.0",
|
|
134
134
|
"mdast-util-gfm": "^3.1.0",
|
|
135
135
|
"mdast-util-to-markdown": "^2.2.0",
|
|
136
|
-
"mermaid": "^
|
|
136
|
+
"mermaid": "^12.2.0",
|
|
137
137
|
"micromark-extension-gfm": "^3.0.0",
|
|
138
138
|
"monaco-editor": "^0.57.0",
|
|
139
139
|
"next": "^16.3.8",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { proxy } from "valtio";
|
|
2
|
+
|
|
3
|
+
// The Add analyst sheet: the chat it pairs with, and the pane to open the
|
|
4
|
+
// analyst beside.
|
|
5
|
+
export const analystUi = proxy<{
|
|
6
|
+
open: boolean;
|
|
7
|
+
sessionId: string | null;
|
|
8
|
+
name: string;
|
|
9
|
+
paneId: string | null;
|
|
10
|
+
}>({ open: false, sessionId: null, name: "", paneId: null });
|
|
11
|
+
|
|
12
|
+
export const analystUiActions = {
|
|
13
|
+
open(sessionId: string, name: string, paneId: string | null = null) {
|
|
14
|
+
Object.assign(analystUi, { open: true, sessionId, name, paneId });
|
|
15
|
+
},
|
|
16
|
+
close() {
|
|
17
|
+
analystUi.open = false;
|
|
18
|
+
},
|
|
19
|
+
};
|