@repo-os/repoos 0.5.69 → 0.5.70
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/dist/.build-info.json +2 -2
- package/dist/.build-stamp.json +1 -1
- package/dist/cli/help.js +3 -3
- package/dist/commands/control-api.js +19 -5
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +9 -1
- package/dist/server/agents.d.ts +9 -0
- package/dist/server/agents.js +26 -0
- package/dist/server/routes/tasks.js +40 -0
- package/dist/server/server.js +2 -1
- package/dist/ui/assets/{AgentModelModal-C8GhSyIa.js → AgentModelModal-qiRXdw6a.js} +1 -1
- package/dist/ui/assets/AgentsView-YS1AZ1v2.js +1 -0
- package/dist/ui/assets/AgentsView-kKt4CrDo.css +1 -0
- package/dist/ui/assets/{ChecksView-CU7ikl8l.js → ChecksView-Ch8Ncat5.js} +0 -0
- package/dist/ui/assets/{ContextView-Dx2siGFv.js → ContextView-DGMk39_r.js} +2 -2
- package/dist/ui/assets/{DashboardView-DP81OKcA.js → DashboardView-B_9hD8tR.js} +1 -1
- package/dist/ui/assets/{DevView-omNNz-ZQ.js → DevView-DZb2LbMn.js} +1 -1
- package/dist/ui/assets/{DiffView-CKMjBvIa.js → DiffView-DeZzB47D.js} +1 -1
- package/dist/ui/assets/{FailedTestsList-3_oexlME.js → FailedTestsList-CdlcNhbe.js} +1 -1
- package/dist/ui/assets/{InputsView-B79I4jwu.js → InputsView-0b4Sjg0Q.js} +1 -1
- package/dist/ui/assets/{ReleasesView-D3qIgMaL.js → ReleasesView-B7yJdjLp.js} +1 -1
- package/dist/ui/assets/{SearchOverlay-0rM6zfNm.js → SearchOverlay-D44KxIbl.js} +1 -1
- package/dist/ui/assets/{SettingsView-gqVC3E7s.js → SettingsView-BN-H2QBT.js} +2 -2
- package/dist/ui/assets/{StoriesView-BazXnyDz.js → StoriesView-CnAlxgkT.js} +1 -1
- package/dist/ui/assets/VoiceDictate-CS-9Kmsa.css +1 -0
- package/dist/ui/assets/{VoiceDictate-JU6yFzDl.js → VoiceDictate-CbJnmeNg.js} +2 -2
- package/dist/ui/assets/{WorkView-qq7xNw0b.js → WorkView-B4J9uqPn.js} +1 -1
- package/dist/ui/assets/{abnfDiagram-VCTEODGH-KzOgBc6g.js → abnfDiagram-VCTEODGH-DrTaHBvQ.js} +1 -1
- package/dist/ui/assets/{architectureDiagram-5GKGNRK7-CP4J_21k.js → architectureDiagram-5GKGNRK7-4pbmksoa.js} +1 -1
- package/dist/ui/assets/{blockDiagram-I7D4REHJ-B5q-JPzd.js → blockDiagram-I7D4REHJ-DotXLktk.js} +1 -1
- package/dist/ui/assets/{c4Diagram-7LVT6UL2-C8gg_KAI.js → c4Diagram-7LVT6UL2-CX4XAag_.js} +1 -1
- package/dist/ui/assets/channel-BrKb638S.js +1 -0
- package/dist/ui/assets/{chunk-2E4U76K2-Bgho8hyQ.js → chunk-2E4U76K2-DBwbHQrf.js} +1 -1
- package/dist/ui/assets/{chunk-4HAMMTFA-DQYpRm2O.js → chunk-4HAMMTFA-CC2YIavJ.js} +1 -1
- package/dist/ui/assets/{chunk-75Z2AOVW-DlvTKtcP.js → chunk-75Z2AOVW-GQ3dA3RS.js} +1 -1
- package/dist/ui/assets/{chunk-CLGD4ZFX-xhgIfmhG.js → chunk-CLGD4ZFX-DJeOtdRW.js} +1 -1
- package/dist/ui/assets/{chunk-DU6HZSFF-Dkcc-d_4.js → chunk-DU6HZSFF-Dth3AgVP.js} +1 -1
- package/dist/ui/assets/{chunk-F27PBJKO-gD-r9Rww.js → chunk-F27PBJKO-CUKJ_1GV.js} +1 -1
- package/dist/ui/assets/{chunk-GMAD6QVW-rvBxuygZ.js → chunk-GMAD6QVW-DUokwNqt.js} +1 -1
- package/dist/ui/assets/{chunk-GVQU2GXP-Cq3-rF-u.js → chunk-GVQU2GXP--wyu3z_M.js} +1 -1
- package/dist/ui/assets/{chunk-IMKFNOWR-BHREb6T1.js → chunk-IMKFNOWR-DKnHgEdS.js} +1 -1
- package/dist/ui/assets/{chunk-L3NEJ4N5-D-R9OvAs.js → chunk-L3NEJ4N5-vio-PK5r.js} +1 -1
- package/dist/ui/assets/{chunk-OSK3NFVY-D0WDbtxw.js → chunk-OSK3NFVY-BF4uJ1Wv.js} +1 -1
- package/dist/ui/assets/{chunk-P2QGCYS3-DLFLbH4p.js → chunk-P2QGCYS3-B9OHNM4g.js} +1 -1
- package/dist/ui/assets/{chunk-POPQ4Y6H-Cw6X8QGG.js → chunk-POPQ4Y6H-DfPkV4K8.js} +1 -1
- package/dist/ui/assets/{chunk-PWAF6VOD-Ds6RWXzu.js → chunk-PWAF6VOD-C6pQpja9.js} +1 -1
- package/dist/ui/assets/{chunk-SHT3W25Y-DvJuv0Ft.js → chunk-SHT3W25Y-D1FyTkkv.js} +1 -1
- package/dist/ui/assets/{chunk-SVP7TREG-DMasMVeC.js → chunk-SVP7TREG-DtQlvhPk.js} +1 -1
- package/dist/ui/assets/{chunk-TICWLB2K-yWH6tp94.js → chunk-TICWLB2K-BpnCR3pz.js} +1 -1
- package/dist/ui/assets/{chunk-TLUHSLCS-CzTkKr54.js → chunk-TLUHSLCS-BeK-nkSE.js} +2 -2
- package/dist/ui/assets/classDiagram-ZZMXUADV-BO_a0cvs.js +1 -0
- package/dist/ui/assets/classDiagram-v2-VYDZK3BY-BO_a0cvs.js +1 -0
- package/dist/ui/assets/{cynefinDiagram-5FMLGOSQ-DAETHLCh.js → cynefinDiagram-5FMLGOSQ-D3SEdRnG.js} +1 -1
- package/dist/ui/assets/{dagre-GXQ25YYZ-BoTD9ES5.js → dagre-GXQ25YYZ-C8gQG-lD.js} +1 -1
- package/dist/ui/assets/{diagram-S7CK7UJ4-etZnEmAz.js → diagram-S7CK7UJ4-Czu_0uu0.js} +1 -1
- package/dist/ui/assets/{diagram-UQ7AKVKN-CywmEzAf.js → diagram-UQ7AKVKN-ViXph8nh.js} +1 -1
- package/dist/ui/assets/{diagram-VSXAHHWV-Dp_aDmgC.js → diagram-VSXAHHWV-C6BtTSHW.js} +1 -1
- package/dist/ui/assets/{diagram-VX7I27RA-Bxt7i5Mf.js → diagram-VX7I27RA-TbbO1fXg.js} +1 -1
- package/dist/ui/assets/{diagram-Z3DM3KII-BReedDkK.js → diagram-Z3DM3KII-BO9R4sQs.js} +1 -1
- package/dist/ui/assets/{ebnfDiagram-PWID7BFC-Dz7S0T6B.js → ebnfDiagram-PWID7BFC-aKXt7bQt.js} +1 -1
- package/dist/ui/assets/{erDiagram-RLTQ6QDP-C2OhjIoP.js → erDiagram-RLTQ6QDP-47HSz_yo.js} +1 -1
- package/dist/ui/assets/flowDiagram-HODETNUW-DPrFUvzg.js +1 -0
- package/dist/ui/assets/{ganttDiagram-EL5Y4UJY-X63oIy-b.js → ganttDiagram-EL5Y4UJY-CLH5Zx6B.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-WWUBYQGX-CjRtFyZs.js → gitGraphDiagram-WWUBYQGX-BOxdVoS7.js} +1 -1
- package/dist/ui/assets/index-ChEmz2Dy.css +1 -0
- package/dist/ui/assets/index-DcF5KN6q.js +57 -0
- package/dist/ui/assets/{infoDiagram-27XIBGKW-D_WjlHCS.js → infoDiagram-27XIBGKW-CuAZPnDi.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-5VMMS53U-CcSnDibc.js → ishikawaDiagram-5VMMS53U-B7Eq3ePc.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-3NMN7TZE-C_cOiv3U.js → journeyDiagram-3NMN7TZE-BhW2Sqpt.js} +1 -1
- package/dist/ui/assets/{kanban-definition-UXKFOSKX-BE6bTzJ_.js → kanban-definition-UXKFOSKX-Cw_klMxM.js} +1 -1
- package/dist/ui/assets/{line-B0YzR-ai.js → line-CX-sssw_.js} +1 -1
- package/dist/ui/assets/{mermaid-parser.core-D-C4q-gD.js → mermaid-parser.core-DU36LHRU.js} +1 -1
- package/dist/ui/assets/{mermaid.core-BinXQHOy.js → mermaid.core-DKxErDRT.js} +3 -3
- package/dist/ui/assets/{mindmap-definition-YA3MSWOX-H_1t8eO8.js → mindmap-definition-YA3MSWOX-NMTZuXGJ.js} +1 -1
- package/dist/ui/assets/{pegDiagram-XKGWAZYB-DEzpGr4J.js → pegDiagram-XKGWAZYB-B9DqL68I.js} +1 -1
- package/dist/ui/assets/{pieDiagram-E7YTZNPT-DzBWBOML.js → pieDiagram-E7YTZNPT-EPN4fJwb.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-AXDQQJYC-BJNb82FM.js → quadrantDiagram-AXDQQJYC-B1vP5hUF.js} +1 -1
- package/dist/ui/assets/{railroadDiagram-O6MQD6OU-dHphbrs7.js → railroadDiagram-O6MQD6OU-q57-HBoV.js} +1 -1
- package/dist/ui/assets/{repo-Rgx38OJH.js → repo-3D9Lh1aB.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-BXWQKSXE-BpZeR6MN.js → requirementDiagram-BXWQKSXE-B1nzxnDE.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-P5KCCOFB-pfWwS_Ol.js → sankeyDiagram-P5KCCOFB-CvGzdKI2.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-WJ2MYXX4-jX0ZWILZ.js → sequenceDiagram-WJ2MYXX4-G73REJUS.js} +1 -1
- package/dist/ui/assets/{stateDiagram-D77RDMKH-cx9TocBZ.js → stateDiagram-D77RDMKH-CRW4gM0e.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-C8VGcrPt.js +1 -0
- package/dist/ui/assets/{swimlanes-42K2YHIH-D0HO4IaA.js → swimlanes-42K2YHIH-CE91Y-lT.js} +1 -1
- package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-CJy_fpiy.js +8 -0
- package/dist/ui/assets/{timeline-definition-24CTP7MA-CU20d-G7.js → timeline-definition-24CTP7MA-DVw_tCzX.js} +1 -1
- package/dist/ui/assets/useChatScroll-BiQjE1tB.js +1 -0
- package/dist/ui/assets/{vennDiagram-4TSXK5OY-Du2dqf4k.js → vennDiagram-4TSXK5OY-gBaTlcOW.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-VM6X3IG4-CsiwW_49.js → wardleyDiagram-VM6X3IG4-B9w0GtT1.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-S5SC5T6Z-8lEaXvDi.js → xychartDiagram-S5SC5T6Z-D2o0fTLK.js} +1 -1
- package/dist/ui/index.html +8 -8
- package/dist/ui/sw.js +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/AgentsView-0r3QjL0C.css +0 -1
- package/dist/ui/assets/AgentsView-ChOMboOE.js +0 -1
- package/dist/ui/assets/VoiceDictate-Bc00yWSj.css +0 -1
- package/dist/ui/assets/channel-CKK9ZV4r.js +0 -1
- package/dist/ui/assets/classDiagram-ZZMXUADV-AoAfBymA.js +0 -1
- package/dist/ui/assets/classDiagram-v2-VYDZK3BY-AoAfBymA.js +0 -1
- package/dist/ui/assets/flowDiagram-HODETNUW-DWZFA4j8.js +0 -1
- package/dist/ui/assets/index-BBJ0SQAG.css +0 -1
- package/dist/ui/assets/index-DpAh1097.js +0 -57
- package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-C8aOH2zy.js +0 -1
- package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-TUNEXRA4.js +0 -8
- package/dist/ui/assets/useChatScroll-BD10j3cq.js +0 -1
package/dist/.build-info.json
CHANGED
package/dist/.build-stamp.json
CHANGED
package/dist/cli/help.js
CHANGED
|
@@ -88,9 +88,9 @@ const GROUPS = [
|
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
name: "message",
|
|
91
|
-
usage: 'message <id> "<text>" [--json] [--port N]',
|
|
92
|
-
desc: "Send a follow-up to the task agent (POST /api/tasks/:id/message)",
|
|
93
|
-
flags: "--json · --port",
|
|
91
|
+
usage: 'message <id> "<text>" [--now] [--json] [--port N]',
|
|
92
|
+
desc: "Send a follow-up to the task agent; queues while busy, --now interrupts the turn and delivers immediately (POST /api/tasks/:id/message)",
|
|
93
|
+
flags: "--now · --json · --port",
|
|
94
94
|
},
|
|
95
95
|
{
|
|
96
96
|
name: "review",
|
|
@@ -6,7 +6,7 @@ import { pollUntil, RepoOsApi, RepoOsApiError, resolveControlPlaneBase, } from "
|
|
|
6
6
|
import { effectiveEngineerFromApi } from "../cli/effective-from-api.js";
|
|
7
7
|
import { HANDOFF_DEADLINE_MS } from "../server/handoff.js";
|
|
8
8
|
function parseCommonFlags(args) {
|
|
9
|
-
const opts = { json: false, wait: false };
|
|
9
|
+
const opts = { json: false, wait: false, now: false };
|
|
10
10
|
const rest = [];
|
|
11
11
|
for (let i = 0; i < args.length; i++) {
|
|
12
12
|
const a = args[i];
|
|
@@ -14,6 +14,8 @@ function parseCommonFlags(args) {
|
|
|
14
14
|
opts.json = true;
|
|
15
15
|
else if (a === "--wait")
|
|
16
16
|
opts.wait = true;
|
|
17
|
+
else if (a === "--now")
|
|
18
|
+
opts.now = true;
|
|
17
19
|
else if (a === "--port") {
|
|
18
20
|
const p = args[++i];
|
|
19
21
|
const n = Number(p);
|
|
@@ -133,18 +135,30 @@ export async function cmdMessage(args) {
|
|
|
133
135
|
const id = rest[0];
|
|
134
136
|
const text = rest.slice(1).join(" ").trim();
|
|
135
137
|
if (!id || !text) {
|
|
136
|
-
printErr('Usage: repoos message <id> "<text>" [--json] [--port N]');
|
|
138
|
+
printErr('Usage: repoos message <id> "<text>" [--now] [--json] [--port N]');
|
|
137
139
|
return 1;
|
|
138
140
|
}
|
|
139
141
|
const api = new RepoOsApi({ port: opts.port });
|
|
140
142
|
try {
|
|
141
143
|
await ensureServer(api);
|
|
142
|
-
const data = await api.requestOk("POST", `/api/tasks/${id}/message`, {
|
|
144
|
+
const data = await api.requestOk("POST", `/api/tasks/${id}/message`, {
|
|
145
|
+
text,
|
|
146
|
+
...(opts.now ? { now: true } : {}),
|
|
147
|
+
});
|
|
143
148
|
if (opts.json)
|
|
144
149
|
printJson(data);
|
|
150
|
+
else if (data?.queued) {
|
|
151
|
+
const why = data.now
|
|
152
|
+
? (data.reason ?? "agent still busy after the interrupt")
|
|
153
|
+
: "agent busy — delivers when the turn ends";
|
|
154
|
+
console.log(c.green(" ✓ ") + c.dim(`message queued to #${id} (${why})`));
|
|
155
|
+
}
|
|
156
|
+
else if (data?.deliveredNow) {
|
|
157
|
+
const how = data.interrupted ? " (interrupted the running turn)" : " (agent was idle)";
|
|
158
|
+
console.log(c.green(" ✓ ") + c.dim(`message delivered now to #${id}${how}`));
|
|
159
|
+
}
|
|
145
160
|
else {
|
|
146
|
-
|
|
147
|
-
console.log(c.green(" ✓ ") + c.dim(`message ${status} to #${id}`));
|
|
161
|
+
console.log(c.green(" ✓ ") + c.dim(`message sent to #${id}`));
|
|
148
162
|
}
|
|
149
163
|
return 0;
|
|
150
164
|
}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type Assignee = "ai" | "human" | "unassigned";
|
|
|
18
18
|
export type Theme = "dark" | "light" | "system";
|
|
19
19
|
/** Visual design language of the web UI. */
|
|
20
20
|
/** Every UI theme. `repoos doctor` validates `uiTheme` against this list. */
|
|
21
|
-
export declare const UI_THEMES: readonly ["classic", "clear", "gen z", "jelly", "gruvbox", "catppuccin"];
|
|
21
|
+
export declare const UI_THEMES: readonly ["classic", "clear", "gen z", "jelly", "gruvbox", "catppuccin", "solarized"];
|
|
22
22
|
export type UiTheme = (typeof UI_THEMES)[number];
|
|
23
23
|
/** Which flow the New task drawer opens with. */
|
|
24
24
|
export type TaskMode = "freeform" | "manual";
|
|
@@ -454,7 +454,7 @@ export interface RepoOSConfig {
|
|
|
454
454
|
ntfyBaseUrl?: string;
|
|
455
455
|
/** UI theme preference: dark, light, or system (follow OS). Cosmetic only. */
|
|
456
456
|
theme?: Theme;
|
|
457
|
-
/** UI design language: classic, clear, gen z, jelly, gruvbox, or
|
|
457
|
+
/** UI design language: classic, clear, gen z, jelly, gruvbox, catppuccin, or solarized. Cosmetic only. */
|
|
458
458
|
uiTheme?: UiTheme;
|
|
459
459
|
/** New-task drawer mode: freeform (PM agent) or manual form. Default "freeform". */
|
|
460
460
|
defaultTaskMode?: TaskMode;
|
package/dist/core/types.js
CHANGED
|
@@ -11,7 +11,15 @@ export const PRIORITIES = ["p0", "p1", "p2", "p3"];
|
|
|
11
11
|
export const TASK_TYPES = ["feature", "bug", "chore", "spec", "refactor"];
|
|
12
12
|
/** Visual design language of the web UI. */
|
|
13
13
|
/** Every UI theme. `repoos doctor` validates `uiTheme` against this list. */
|
|
14
|
-
export const UI_THEMES = [
|
|
14
|
+
export const UI_THEMES = [
|
|
15
|
+
"classic",
|
|
16
|
+
"clear",
|
|
17
|
+
"gen z",
|
|
18
|
+
"jelly",
|
|
19
|
+
"gruvbox",
|
|
20
|
+
"catppuccin",
|
|
21
|
+
"solarized",
|
|
22
|
+
];
|
|
15
23
|
/**
|
|
16
24
|
* Machine-readable reasons `needsInput` gets set, one per escalation call
|
|
17
25
|
* site. Stored alongside the flag so a later automated success (e.g. a
|
package/dist/server/agents.d.ts
CHANGED
|
@@ -1585,6 +1585,15 @@ export declare class AgentRunner {
|
|
|
1585
1585
|
* (#0507). Only a process that exits badly on its OWN escalates.
|
|
1586
1586
|
*/
|
|
1587
1587
|
stop(taskId: string): StopResult;
|
|
1588
|
+
/**
|
|
1589
|
+
* Wait for a task's stopped agent process to actually leave the running
|
|
1590
|
+
* registry (#0760). {@link stop} only *signals* — the process may take up to
|
|
1591
|
+
* the 3s SIGKILL grace before `cleanup()` deletes its entry, and until then
|
|
1592
|
+
* `isRunning` is still true. A caller that must not start a new turn on top of
|
|
1593
|
+
* a live process (the `--now` message path) polls here until the entry is
|
|
1594
|
+
* gone or the timeout expires. Returns true when the process has exited.
|
|
1595
|
+
*/
|
|
1596
|
+
waitForStop(taskId: string, timeoutMs?: number): Promise<boolean>;
|
|
1588
1597
|
/**
|
|
1589
1598
|
* Interrupt a running AI chat response (PM, guide, debugger, …). Stops the
|
|
1590
1599
|
* in-flight agent process via {@link stop} and appends a persistent marker to
|
package/dist/server/agents.js
CHANGED
|
@@ -6399,6 +6399,32 @@ export class AgentRunner {
|
|
|
6399
6399
|
}
|
|
6400
6400
|
return { stopped: true };
|
|
6401
6401
|
}
|
|
6402
|
+
/**
|
|
6403
|
+
* Wait for a task's stopped agent process to actually leave the running
|
|
6404
|
+
* registry (#0760). {@link stop} only *signals* — the process may take up to
|
|
6405
|
+
* the 3s SIGKILL grace before `cleanup()` deletes its entry, and until then
|
|
6406
|
+
* `isRunning` is still true. A caller that must not start a new turn on top of
|
|
6407
|
+
* a live process (the `--now` message path) polls here until the entry is
|
|
6408
|
+
* gone or the timeout expires. Returns true when the process has exited.
|
|
6409
|
+
*/
|
|
6410
|
+
waitForStop(taskId, timeoutMs = 5000) {
|
|
6411
|
+
if (!this.entries.has(taskId))
|
|
6412
|
+
return Promise.resolve(true);
|
|
6413
|
+
return new Promise((resolve) => {
|
|
6414
|
+
const started = Date.now();
|
|
6415
|
+
const poll = setInterval(() => {
|
|
6416
|
+
if (!this.entries.has(taskId)) {
|
|
6417
|
+
clearInterval(poll);
|
|
6418
|
+
resolve(true);
|
|
6419
|
+
return;
|
|
6420
|
+
}
|
|
6421
|
+
if (Date.now() - started >= timeoutMs) {
|
|
6422
|
+
clearInterval(poll);
|
|
6423
|
+
resolve(false);
|
|
6424
|
+
}
|
|
6425
|
+
}, 25);
|
|
6426
|
+
});
|
|
6427
|
+
}
|
|
6402
6428
|
/**
|
|
6403
6429
|
* Interrupt a running AI chat response (PM, guide, debugger, …). Stops the
|
|
6404
6430
|
* in-flight agent process via {@link stop} and appends a persistent marker to
|
|
@@ -1267,6 +1267,13 @@ function rejectIgnoredOverrides(res, id, body) {
|
|
|
1267
1267
|
return true;
|
|
1268
1268
|
}
|
|
1269
1269
|
// Task actions: start, pause, message, done, sync
|
|
1270
|
+
/**
|
|
1271
|
+
* How long a `--now` message waits for a paused turn to actually exit (#0760).
|
|
1272
|
+
* Must stay below the pause path's 3s SIGKILL grace (`AgentRunner.stop`): a
|
|
1273
|
+
* process still alive at this point is reported as "pause did not stop the
|
|
1274
|
+
* run" rather than resumed over.
|
|
1275
|
+
*/
|
|
1276
|
+
const INTERRUPT_WAIT_MS = 2500;
|
|
1270
1277
|
export const taskAction = async (ctx, req, res, params) => {
|
|
1271
1278
|
const { config, index, runner, previews, reviews, syncTaskBranch, onServerStatusChange, logger } = ctx;
|
|
1272
1279
|
const { jobCoordinator } = ctx;
|
|
@@ -1778,6 +1785,9 @@ export const taskAction = async (ctx, req, res, params) => {
|
|
|
1778
1785
|
if (!text) {
|
|
1779
1786
|
return json(res, 400, { error: "message text is required" });
|
|
1780
1787
|
}
|
|
1788
|
+
// #0760: `now: true` interrupts a busy agent and delivers immediately.
|
|
1789
|
+
// Without it, a busy agent queues the message (#0756) — unchanged.
|
|
1790
|
+
const now = body?.now === true;
|
|
1781
1791
|
if (existing.needsInput) {
|
|
1782
1792
|
const cleared = patchTaskFile(config, existing.absPath, {
|
|
1783
1793
|
needsInput: false,
|
|
@@ -1818,6 +1828,32 @@ export const taskAction = async (ctx, req, res, params) => {
|
|
|
1818
1828
|
preamble = resumePreamble(config, existing, existing.branch, wtPath) || undefined;
|
|
1819
1829
|
}
|
|
1820
1830
|
}
|
|
1831
|
+
// #0760: --now steers a busy agent. Interrupt the running turn through the
|
|
1832
|
+
// same stop path `pause` uses, wait for the process to actually exit, and
|
|
1833
|
+
// only then deliver — so a message never lands on top of a live turn. The
|
|
1834
|
+
// wait window is deliberately shorter than the pause path's 3s SIGKILL
|
|
1835
|
+
// grace: a process that only dies to SIGKILL was not stopped *cleanly*
|
|
1836
|
+
// (a half-written edit is exactly what we must not resume over), so treat
|
|
1837
|
+
// that as "pause did not stop the run" and fail without delivering.
|
|
1838
|
+
let interrupted = false;
|
|
1839
|
+
if (now && runner.isRunning(id)) {
|
|
1840
|
+
const stopRes = runner.stop(id);
|
|
1841
|
+
const stopped = stopRes.stopped && (await runner.waitForStop(id, INTERRUPT_WAIT_MS));
|
|
1842
|
+
if (!stopped) {
|
|
1843
|
+
// The stop was still requested (SIGKILL follows on the pause path's
|
|
1844
|
+
// grace timer), so record it as a human pause exactly like `pause`
|
|
1845
|
+
// does — the watchdog must not flag a task left with no process.
|
|
1846
|
+
runner.markPaused(id);
|
|
1847
|
+
return json(res, 409, {
|
|
1848
|
+
ok: false,
|
|
1849
|
+
now: true,
|
|
1850
|
+
interrupted: true,
|
|
1851
|
+
error: `Could not interrupt the running agent for #${id} — it did not stop within ${INTERRUPT_WAIT_MS / 1000}s; the message was not delivered. The task is paused: resend the message once the agent has stopped.`,
|
|
1852
|
+
reason: "pause did not stop the run",
|
|
1853
|
+
});
|
|
1854
|
+
}
|
|
1855
|
+
interrupted = true;
|
|
1856
|
+
}
|
|
1821
1857
|
const sendRes = runner.send(id, text, agent, { resumePreamble: preamble });
|
|
1822
1858
|
if (!sendRes.ok) {
|
|
1823
1859
|
return json(res, 400, {
|
|
@@ -1828,11 +1864,15 @@ export const taskAction = async (ctx, req, res, params) => {
|
|
|
1828
1864
|
return json(res, 200, {
|
|
1829
1865
|
ok: true,
|
|
1830
1866
|
queued: true,
|
|
1867
|
+
// #0760: with `now`, the run stopped but the runner is still busy
|
|
1868
|
+
// (e.g. the interrupted turn had requested a handoff, now in flight).
|
|
1869
|
+
...(now ? { now: true, interrupted, reason: "agent still busy after the interrupt" } : {}),
|
|
1831
1870
|
});
|
|
1832
1871
|
}
|
|
1833
1872
|
return json(res, 200, {
|
|
1834
1873
|
ok: true,
|
|
1835
1874
|
spawn: { ok: true, pid: sendRes.pid },
|
|
1875
|
+
...(now ? { now: true, interrupted, deliveredNow: true } : {}),
|
|
1836
1876
|
});
|
|
1837
1877
|
}
|
|
1838
1878
|
if (action === "pause") {
|
package/dist/server/server.js
CHANGED
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
* POST /api/tasks/:id/start -> launch the engineer agent on the task (ready -> active);
|
|
39
39
|
* also relaunches a paused active task (stays active)
|
|
40
40
|
* POST /api/tasks/:id/pause -> stop the running agent; task stays active
|
|
41
|
-
* POST /api/tasks/:id/message -> send a follow-up to the task's agent session (active, review)
|
|
41
|
+
* POST /api/tasks/:id/message -> send a follow-up to the task's agent session (active, review);
|
|
42
|
+
* `{ now: true }` interrupts a busy turn first (#0760)
|
|
42
43
|
* POST /api/tasks/:id/pm/message -> send a message to the PM agent about this task
|
|
43
44
|
* GET /api/tasks/:id/output -> { lines, stats } the retained transcript + live run stats (0080)
|
|
44
45
|
* GET /api/tasks/:id/review -> { ok, running, enabled, review, lines } the agent's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,D as t,Dt as n,K as r,L as i,O as a,S as o,St as s,T as c,W as l,at as ee,et as u,it as d,k as f,mt as p,p as te,v as m,w as h,wt as g,x as _,y as ne}from"./vendor-vue-0d2wfih_.js";import{M as re}from"./repo-
|
|
1
|
+
import{C as e,D as t,Dt as n,K as r,L as i,O as a,S as o,St as s,T as c,W as l,at as ee,et as u,it as d,k as f,mt as p,p as te,v as m,w as h,wt as g,x as _,y as ne}from"./vendor-vue-0d2wfih_.js";import{M as re}from"./repo-3D9Lh1aB.js";import{L as ie,j as v,w as ae}from"./vendor-ui-D3ucVR3C.js";import{a as oe,i as se,n as ce,o as le,r as ue,t as de}from"./title-CKCTFTPg.js";var y=`agent-model-favorites`;function b(){try{let e=localStorage.getItem(y);return e?JSON.parse(e):[]}catch{return[]}}function x(e){try{localStorage.setItem(y,JSON.stringify(e))}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[useFavorites] Failed to persist favorites: ${t}`)}}function fe(){let e=p(b());function t(t,n){return e.value.some(e=>e.cli===t&&e.model===n)}function n(n,r){t(n,r)?e.value=e.value.filter(e=>e.cli!==n||e.model!==r):e.value.push({cli:n,model:r,addedAt:Date.now()}),x(e.value)}function r(t,n){let r=e.value.find(e=>e.cli===t&&e.model===n);r&&(r.recentlyUsedAt=Date.now(),x(e.value))}function i(t){return e.value.filter(e=>e.cli===t).sort((e,t)=>(t.recentlyUsedAt??t.addedAt)-(e.recentlyUsedAt??e.addedAt)||t.addedAt-e.addedAt)}return{favorites:e,isFavorite:t,toggleFavorite:n,markRecentlyUsed:r,getFavoritesForCli:i,hasFavorites:_(()=>e.value.length>0)}}var S=`agent-model-last-by-context`;function C(){try{let e=localStorage.getItem(S);if(!e)return{};let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))return{};let n={};for(let[e,r]of Object.entries(t))!r||typeof r!=`object`||Array.isArray(r)||(n[e]=r);return n}catch{return{}}}function w(){function e(e,t,n){if(!(!e||!t||!n))try{let r=C();r[e]={...r[e]??{},[t]:n},localStorage.setItem(S,JSON.stringify(r))}catch{}}function t(e,t){if(!(!e||!t))return C()[e]?.[t]||void 0}return{remember:e,recall:t}}var T=`agent-cli-favorites`;function E(){try{let e=localStorage.getItem(T);return e?JSON.parse(e):[]}catch{return[]}}function D(e){try{localStorage.setItem(T,JSON.stringify(e))}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[useAgentFavorites] Failed to persist agent favorites: ${t}`)}}function O(){let e=p(E());function t(t){return e.value.includes(t)}function n(n){t(n)?e.value=e.value.filter(e=>e!==n):e.value=[...e.value,n],D(e.value)}return{favoritedIds:e,isAgentFavorite:t,toggleAgentFavorite:n,hasAgentFavorites:_(()=>e.value.length>0)}}var pe={class:`am-modal-head`},me={class:`am-modal-head-text`},k={class:`am-modal-current`},A={class:`am-cli-picker`},j=[`onClick`],M={key:0,class:`am-reset-notice`,role:`status`,"data-testid":`am-reset-notice`},N={class:`am-reset-notice-detail`},P={class:`am-list-notice-text`},F={class:`am-model-search`},I={class:`am-model-search-wrap`},L={key:0,class:`am-favorites-section`},R={class:`am-favorites-count`},z={key:0,class:`am-favorites-list`},he=[`aria-disabled`,`aria-selected`,`onClick`],ge={class:`am-model-label`},_e={key:0,class:`am-model-disabled-hint`},ve={class:`am-model-actions`},ye={key:0,class:`am-model-check`},be=[`onClick`],B={key:1,class:`am-all-models-section`},xe={key:0,class:`am-all-models-header`},Se=[`aria-disabled`,`aria-selected`,`onClick`],Ce={class:`am-model-label`},we={key:0,class:`am-model-disabled-hint`},Te={class:`am-model-actions`},Ee={key:0,class:`am-model-check`},De=[`onClick`],Oe={key:2,class:`am-model-empty`},ke={key:3,class:`am-no-favorites-hint`},V=f({__name:`AgentModelModal`,props:{open:{type:Boolean},cliOptions:{},modelOptions:{},cli:{},model:{},memoryKey:{},disabled:{type:Boolean}},emits:[`update:open`,`update:cli`,`update:model`],setup(f,{emit:y}){let b=f,x=y,S=p(``),C=p(null),T=p(null),E=p(!0),{isFavorite:D,toggleFavorite:V,markRecentlyUsed:Ae,getFavoritesForCli:H,hasFavorites:je}=fe(),{remember:U,recall:Me}=w(),W=re(),G=_(()=>W.modelNoticeFor(b.cli));function Ne(){W.refreshModelsForCli(b.cli)}let{isAgentFavorite:Pe,hasAgentFavorites:Fe}=O(),Ie=_(()=>Fe.value?b.cliOptions.filter(e=>Pe(e)):b.cliOptions),K=_(()=>b.memoryKey),q=p(null);function J(e){return b.modelOptions.find(t=>t.value===e)?.label??e}let Le=_(()=>J(b.model)),Y=_(()=>{let e=S.value.trim().toLowerCase();return e?b.modelOptions.filter(t=>t.value==="default"||t.label.toLowerCase().includes(e)):b.modelOptions}),X=_(()=>H(b.cli).length>0),Z=_(()=>H(b.cli).map(e=>b.modelOptions.find(t=>t.value===e.model)).filter(e=>e!==void 0));function Re(e){let t=Me(K.value,e);return t&&W.isKnownModelForCli(e,t)?t:`default`}function ze(e){let t=b.cli;if(e===t)return;let n=b.model;U(K.value,t,n),x(`update:cli`,e);let r=Re(e);x(`update:model`,r),q.value=r==="default"&&n&&n!=="default"?J(n):null}function Q(e){Ae(b.cli,e),U(K.value,b.cli,e),q.value=null,x(`update:model`,e),x(`update:open`,!1)}function $(e,t,n){n.stopPropagation(),V(e,t)}return u(()=>b.open,e=>{e&&(q.value=null,S.value=``,i(()=>{let e=T.value;e&&(e.scrollTop=0),C.value?.focus()}))}),(i,u)=>(l(),e(ne,{to:`body`},[a(le,{open:f.open,"onUpdate:open":u[2]||=e=>x(`update:open`,e)},{default:d(()=>[a(ce),a(se,{class:`am-modal am-modal-wide`},{default:d(()=>[o(`div`,pe,[o(`div`,me,[a(de,null,{default:d(()=>[...u[3]||=[t(`Coding Agent + Model`,-1)]]),_:1}),o(`div`,k,n(f.cli)+` · `+n(Le.value),1)]),a(ue,{class:`sr-only`},{default:d(()=>[...u[4]||=[t(` Choose a coding agent and model `,-1)]]),_:1}),a(oe,{class:`close-x`},{default:d(()=>[a(s(ae),{class:`size-[15px]`})]),_:1})]),o(`div`,A,[(l(!0),c(m,null,r(Ie.value,e=>(l(),c(`button`,{key:e,type:`button`,class:g([`am-cli-btn`,{active:e===f.cli}]),onClick:t=>ze(e)},n(e),11,j))),128))]),q.value?(l(),c(`div`,M,[u[5]||=o(`span`,{class:`am-reset-notice-title`},`Model reset to default`,-1),o(`span`,N,`— was `+n(q.value),1)])):h(``,!0),G.value?(l(),c(`div`,{key:1,class:g([`am-list-notice`,G.value.kind===`failed`?`am-list-notice-failed`:`am-list-notice-loading`]),role:`status`,"data-testid":`am-model-list-notice`},[o(`span`,P,n(G.value.text),1),G.value.kind===`failed`?(l(),c(`button`,{key:0,type:`button`,class:`am-list-notice-retry`,"data-testid":`am-model-list-retry`,onClick:Ne},` Retry `)):h(``,!0)],2)):h(``,!0),o(`div`,F,[o(`div`,I,[a(s(ie),{class:`pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-[var(--txt-faint)]`}),ee(o(`input`,{ref_key:`modelSearchEl`,ref:C,"onUpdate:modelValue":u[0]||=e=>S.value=e,type:`text`,role:`combobox`,"aria-label":`Search models`,placeholder:`Search models…`,class:`am-model-search-input`},null,512),[[te,S.value]])])]),o(`div`,{ref_key:`modelListEl`,ref:T,class:`am-model-list`,role:`listbox`,"aria-label":`Models`},[X.value&&!S.value?(l(),c(`div`,L,[o(`button`,{type:`button`,class:`am-favorites-header`,onClick:u[1]||=e=>E.value=!E.value},[u[6]||=o(`span`,{class:`am-favorites-title`},`Favorites`,-1),o(`span`,R,n(Z.value.length),1),o(`span`,{class:g([`am-favorites-toggle`,{expanded:E.value}])},` ▼ `,2)]),E.value?(l(),c(`div`,z,[(l(!0),c(m,null,r(Z.value,e=>(l(),c(`div`,{key:e.value,class:g([`am-model-item am-favorite-item`,{active:e.value===f.model,disabled:e.disabled}]),"aria-disabled":e.disabled,role:`option`,"aria-selected":e.value===f.model,onClick:t=>!e.disabled&&Q(e.value)},[o(`span`,ge,n(e.label),1),e.disabled?(l(),c(`span`,_e,`— unavailable`)):h(``,!0),o(`div`,ve,[e.value===f.model?(l(),c(`span`,ye,`✓`)):h(``,!0),o(`button`,{type:`button`,class:`am-star-btn`,onClick:t=>$(f.cli,e.value,t),title:`Remove from favorites`},[a(s(v),{class:`size-3.5`,fill:`currentColor`})],8,be)])],10,he))),128))])):h(``,!0)])):h(``,!0),Y.value.length>0?(l(),c(`div`,B,[X.value&&!S.value?(l(),c(`div`,xe,` All Models `)):h(``,!0),(l(!0),c(m,null,r(Y.value,e=>(l(),c(`div`,{key:e.value,class:g([`am-model-item`,{active:e.value===f.model,disabled:e.disabled}]),"aria-disabled":e.disabled,role:`option`,"aria-selected":e.value===f.model,onClick:t=>!e.disabled&&Q(e.value)},[o(`span`,Ce,n(e.label),1),e.disabled?(l(),c(`span`,we,`— unavailable`)):h(``,!0),o(`div`,Te,[e.value===f.model?(l(),c(`span`,Ee,`✓`)):h(``,!0),o(`button`,{type:`button`,class:g([`am-star-btn`,{active:s(D)(f.cli,e.value)}]),onClick:t=>$(f.cli,e.value,t),title:`Add to favorites`},[a(s(v),{class:`size-3.5`,fill:s(D)(f.cli,e.value)?`currentColor`:`none`},null,8,[`fill`])],10,De)])],10,Se))),128))])):h(``,!0),Y.value.length?h(``,!0):(l(),c(`div`,Oe,` No models match "`+n(S.value)+`" `,1)),!s(je)&&!S.value?(l(),c(`div`,ke,` No favorites yet — click the star icon to save your favorite agent + model combinations `)):h(``,!0)],512)]),_:1})]),_:1},8,[`open`])]))}});export{O as n,w as r,V as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{C as e,D as t,Dt as n,Et as r,H as i,J as a,K as o,O as s,S as c,St as l,T as u,V as d,W as f,at as p,et as m,f as h,ft as g,g as ee,h as te,i as _,it as v,k as y,m as b,mt as x,p as S,r as C,v as w,w as T,wt as E,x as D,y as O}from"./vendor-vue-0d2wfih_.js";import{a as k,r as ne}from"./api-BXg3t-A6.js";import{M as re,d as A}from"./repo-3D9Lh1aB.js";import{t as j}from"./docs-CypCpmgt.js";import{B as M,Ct as N,Nt as P,St as F,bt as I,j as L}from"./vendor-ui-D3ucVR3C.js";import{t as R}from"./_plugin-vue_export-helper-BDNMzG2s.js";import{t as z}from"./button-Cg7Fwvfz.js";import{a as ie,i as ae,n as oe,o as se,r as B,t as V}from"./title-CKCTFTPg.js";import{o as H,t as U}from"./VoiceDictate-CbJnmeNg.js";import{t as ce}from"./input-Cg7deJC2.js";import{n as W,r as le,t as ue}from"./useChatScroll-BiQjE1tB.js";import{t as de}from"./clipboard-CkhTprDX.js";import{a as fe,i as pe,n as me,r as he,t as ge}from"./viewport-BVLcUJ9I.js";import{t as _e}from"./value-BsoQhhdg.js";import{n as ve}from"./AgentModelModal-qiRXdw6a.js";import{t as G}from"./switch-BYQwbwcZ.js";import{E as ye,m as be,u as xe}from"./index-DcF5KN6q.js";var Se={class:`agent-head`},Ce={class:`agent-title`},we={key:1,class:`agent-name`},Te={key:2,class:`agent-badge`},Ee={key:0,style:{display:`flex`,"align-items":`center`,gap:`10px`}},De={class:`agent-body`},Oe={class:`agent-field`},ke={key:0,class:`agent-legacy-notice`,role:`status`},Ae={class:`agent-field agent-test-result`},je={class:`agent-test-actions`},Me={key:0,class:`model-test-spinner`},Ne=[`title`],Pe={class:`agent-field agent-instr-field`},K={class:`instr-header agent-instr-header`},Fe={class:`agent-instr-header-actions`},Ie=[`aria-expanded`,`title`],Le=[`value`],Re={key:0,class:`agent-field agent-skills-field`},ze={class:`agent-skills-row`},Be={class:`agent-skills-inline-summary`},Ve=`Skills are selected dynamically for each task/run from repository skills; these are this agent's preferred candidates.`,He=y({__name:`AgentCard`,props:{agent:{},variant:{},cliOptions:{},memoryKey:{},skillsAvailable:{type:Boolean},testing:{type:Boolean},testResult:{},registerInstrRef:{type:Function}},emits:[`test`,`open-skills`,`remove`,`instr-input`,`instr-blur`,`open-recommendations`,`transcribed`],setup(r,{emit:i}){let a=r,o=i,d=re(),p=x(!1);function m(e){return e.toLowerCase()===`gemini`}function h(){return a.variant==="default"?`default`:a.variant===`team`?`team`:null}return(i,g)=>(f(),u(`div`,{class:E([`agent-card`,{off:!r.agent.enabled}])},[c(`div`,Se,[c(`div`,Ce,[g[13]||=c(`span`,{class:`agent-dot`},null,-1),r.variant===`custom`?(f(),e(ce,{key:0,"model-value":r.agent.name,class:`w-[180px] h-[30px]`,"onUpdate:modelValue":g[0]||=e=>r.agent.name=String(e??``)},null,8,[`model-value`])):(f(),u(`span`,we,n(r.agent.name),1)),h()?(f(),u(`span`,Te,n(h()),1)):T(``,!0)]),r.variant===`custom`?(f(),u(`div`,Ee,[s(z,{variant:`ghost`,size:`sm`,class:`agent-remove`,onClick:g[1]||=e=>o(`remove`)},{default:v(()=>[...g[14]||=[t(` Remove `,-1)]]),_:1}),s(G,{checked:r.agent.enabled,"onUpdate:checked":g[2]||=e=>r.agent.enabled=e},null,8,[`checked`])])):(f(),e(G,{key:1,checked:r.agent.enabled,"onUpdate:checked":g[3]||=e=>r.agent.enabled=e},null,8,[`checked`]))]),c(`div`,De,[c(`div`,Oe,[g[17]||=c(`label`,null,`Coding agent + Model`,-1),s(xe,{"cli-options":r.cliOptions,"model-options":l(d).modelsFor(r.agent.cli,r.agent.model),"memory-key":r.memoryKey,cli:r.agent.cli,"onUpdate:cli":g[4]||=e=>r.agent.cli=e,model:r.agent.model,"onUpdate:model":g[5]||=e=>r.agent.model=e},null,8,[`cli-options`,`model-options`,`memory-key`,`cli`,`model`]),m(r.agent.cli)?(f(),u(`div`,ke,[g[15]||=c(`strong`,null,`Deprecated Gemini CLI`,-1),g[16]||=t(` — this saved value is preserved for history, but new assignments use Antigravity CLI (agy). `,-1),c(`button`,{type:`button`,class:`model-pricing-link`,onClick:g[6]||=e=>o(`open-recommendations`)},` Migrate in the agent guide → `)])):T(``,!0)]),c(`div`,Ae,[g[18]||=c(`label`,null,`Compatibility`,-1),c(`div`,je,[s(z,{variant:`outline`,size:`sm`,disabled:r.testing,onClick:g[7]||=e=>o(`test`)},{default:v(()=>[r.testing?(f(),u(`span`,Me)):T(``,!0),t(` `+n(r.testing?`Testing…`:r.testResult?`Test again`:`Test`),1)]),_:1},8,[`disabled`]),r.testResult?(f(),u(`span`,{key:0,class:E(`model-test model-test-`+r.testResult.status),title:r.testResult.error},n(r.testResult.status.replace(`_`,` `)),11,Ne)):T(``,!0)])]),c(`div`,Pe,[c(`div`,K,[g[19]||=c(`label`,null,`Instructions`,-1),c(`div`,Fe,[p.value?(f(),e(U,{key:0,onTranscribed:g[8]||=e=>o(`transcribed`,e)})):T(``,!0),c(`button`,{type:`button`,class:`agent-instr-toggle`,"aria-expanded":p.value,title:p.value?`Collapse instructions`:`Expand instructions`,onClick:g[9]||=e=>p.value=!p.value},[p.value?(f(),e(l(F),{key:0,class:`size-4`,"aria-hidden":`true`})):(f(),e(l(I),{key:1,class:`size-4`,"aria-hidden":`true`}))],8,Ie)])]),p.value?(f(),u(`textarea`,{key:0,ref:e=>a.registerInstrRef(e),value:r.agent.instructions??``,class:`agent-instr`,rows:`2`,placeholder:`Optional — how this agent should behave`,onInput:g[10]||=e=>o(`instr-input`,e),onBlur:g[11]||=e=>o(`instr-blur`)},null,40,Le)):T(``,!0)]),r.skillsAvailable?(f(),u(`div`,Re,[g[20]||=c(`label`,{class:`agent-skills-label`},`Enabled skills`,-1),c(`div`,ze,[s(z,{variant:`ghost`,size:`sm`,class:`agent-skills-add`,title:`Add skills to agent`,onClick:g[12]||=e=>o(`open-skills`)},{default:v(()=>[s(l(M),{class:`size-3.5`,"aria-hidden":`true`})]),_:1}),c(`span`,{class:`agent-skills-info`,title:Ve,"aria-label":`About enabled skills`},`ⓘ`),c(`span`,Be,n((r.agent.skills??[]).join(`, `)||`No default candidates`),1)])])):T(``,!0)])],2))}}),Ue={class:`agent-head`},We={class:`agent-title`},Ge={class:`agent-name`},Ke={class:`agent-body`},qe={class:`agent-field`},Je={key:0,class:`agent-field`},Ye={key:1,class:`agent-field`},Xe={class:`agent-field`},q={class:`agent-test-actions`},J={key:0,class:`built-in-last-run`},Y={key:2,class:`agent-field built-in-status-field`},Ze={key:0,class:`built-in-status success`},X={key:0,class:`built-in-autofixed`},Z={key:1,class:`built-in-task-link`},Qe={key:2,class:`built-in-run-doc`},$e=[`href`],et={key:1,class:`built-in-status error`},tt={"data-testid":`built-in-started-modal`},nt={class:`built-in-started-head`},rt={class:`built-in-started-body`},it={class:`built-in-started-actions`},at=R(y({__name:`BuiltInAgentCard`,props:{agent:{},interactive:{type:Boolean}},setup(r){let i=r,d=re(),p=D(()=>d.agentsMeta.clis[0]??`opencode`),h=D(()=>d.agentsMeta.models[0]??`default`),g=x({enabled:!1,schedule:`manual`,cli:``,model:``});m(()=>d.data?.builtInAgents,e=>{let t=e?.[i.agent];t&&(g.value={enabled:t.enabled??!1,schedule:t.schedule??`manual`,lastRunAt:t.lastRunAt,cli:t.cli||p.value,model:t.model||h.value})},{immediate:!0,deep:!0});let ee=D(()=>d.agentsMeta.clis??[]),te=d.modelsFor,_=x(!1),y=x(!1),b=x(``),S=x(``),C=x(null),A=x([]),j=x(null),M=D(()=>{switch(i.agent){case`performance`:return`Scans for performance issues like slow functions, blocking operations, deeply nested loops, unbounded memory growth, and duplicate computations. Findings are bundled into one inbox task.`;case`tech-debt`:return`Scans for technical debt patterns including outdated dependencies, code duplication, high-complexity files, unused code, and deprecated APIs. Findings are bundled into one inbox task.`;case`design`:return`Reviews your web UI for layout issues, styling inconsistencies, accessibility gaps, and UX friction. Findings and proposed fixes are bundled into one inbox task.`;case`architect`:return`Analyses your codebase for tight coupling, missing abstractions, scalability risks, and over-engineering. Findings are bundled into one inbox task.`;case`docs-debt`:return`Verifies that AGENTS.md and your project docs still match the code — checks file paths, symbols, and stated constraints. Stale references it can fix automatically are committed; anything that needs a human decision is bundled into one inbox task.`;default:return P.value?.description??``}});function N(){y.value=!1}let P=D(()=>i.agent===`debugger`?{name:`Debugger Agent`,description:`Paste a bug, stack trace, or error and get a clear diagnosis — the root cause plus a suggested fix. Chat with him from his floating head next to Ross and the CTO.`,icon:`🐞`}:i.agent===`tech-debt`?{name:`Tech Debt Agent`,description:`Scans your repository for technical debt patterns including outdated dependencies, code duplication, high-complexity files, unused code, and deprecated APIs. Every finding is bundled into one inbox task, and the run is recorded in your configured docs directory.`,icon:`🔧`}:i.agent===`performance`?{name:`Performance Agent`,description:`Keeps your app fast by scanning for performance issues like slow functions, blocking operations, deeply nested loops, unbounded memory growth, and duplicate computations. Every finding is bundled into one inbox task, and the run is recorded in your configured docs directory.`,icon:`⚡`}:i.agent===`architect`?{name:`Architect Agent`,description:`Analyzes your codebase architecture — detects tight coupling, missing abstractions, scalability risks, and over-engineering. Findings are bundled into one inbox task and the run is recorded in your configured docs directory.`,icon:`🏛`}:i.agent===`design`?{name:`Design Agent`,description:`Reviews your web UI's quality — layout, styling consistency, accessibility, and interaction flows. Flags UI bugs and UX friction and proposes concrete fixes and design improvements, bundled into one inbox task and recorded in your configured docs directory.`,icon:`🎨`}:i.agent===`docs-debt`?{name:`Docs Debt Agent`,description:`Checks that AGENTS.md and your configured project docs still tell the truth about the code — a skill-guided agent verifies file paths, symbols, scripts, and stated constraints against the real repo, whatever its layout. A fix auto-commits only after an independent verification passes; everything else is bundled into one task, and the run is recorded in your configured docs directory.`,icon:`📖`}:null),F=D(()=>g.value.lastRunAt?new Date(g.value.lastRunAt).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`}):`Never`),I=D(()=>g.value.cli||p.value),L=D(()=>g.value.model||h.value);async function R(){try{let e=d.data?.builtInAgents||{},t={enabled:g.value.enabled,schedule:g.value.schedule};g.value.lastRunAt&&(t.lastRunAt=g.value.lastRunAt),g.value.cli&&(t.cli=g.value.cli),g.value.model&&(t.model=g.value.model),await k(`/api/config`,ne(`PATCH`,{builtInAgents:{...e,[i.agent]:t}}));let n=await k(`/api/config`);d.data=n.config}catch(e){b.value=e instanceof Error?e.message:`Failed to save configuration`}}function H(e){g.value.enabled=e,R()}function U(e){g.value.cli=e,R()}function ce(e){g.value.model=e,R()}async function W(e){e&&(e===`daily`||e===`weekly`||e===`manual`)&&(g.value.schedule=e,await R())}async function le(){if(!_.value){_.value=!0,y.value=!0,b.value=``,S.value=``,C.value=null,A.value=[],j.value=null;try{let e=await k(`/api/agents/built-in/${i.agent}/run`,ne(`POST`,{}));if(e.ok){if(g.value.lastRunAt=new Date().toISOString(),j.value=e.runDoc??null,C.value=e.taskId??null,e.failed&&e.failed>0)b.value=`${e.taskCount} task(s) created, ${e.failed} failed — ${(e.errors??[]).join(`; `)||`unknown write error`}`;else if(i.agent===`design`)S.value=`Review complete — ${e.findingsFound??0} design finding(s) found (${e.scannedFiles??0} files scanned).`;else if(i.agent===`architect`)S.value=`Review complete — ${e.issuesFound??0} architecture issue(s) found (${e.scannedFiles??0} files scanned).`;else if(i.agent===`docs-debt`)if(e.error)b.value=e.error;else{let t=e.trivialFixesApplied??0;A.value=e.autoFixed??[];let n=t>0?`corrected ${t} stale reference(s); `:``;S.value=(e.findingsFound??0)>0?`Check complete — ${n}${e.findingsFound??0} claim(s) need a human decision, bundled into one task (${e.scannedFiles??0} docs scanned).`:`Check complete — ${n}docs match the code (${e.scannedFiles??0} docs scanned).`}else if(e.taskCount>0){let t=i.agent===`performance`?`performance`:`tech debt`;S.value=`Scan complete — ${e.taskCount} ${t} task(s) created from ${e.issuesFound??0} issue(s).`}else{let t=i.agent===`performance`?`performance`:`tech debt`;S.value=`Scan complete — no ${t} issues found (${e.scannedFiles??0} files scanned).`}await R()}else b.value=`Failed to run agent`}catch(e){b.value=e instanceof Error?e.message:`Failed to run agent`}finally{_.value=!1,y.value=!1}}}return(i,d)=>{let p=a(`router-link`);return P.value?(f(),u(`div`,{key:0,class:E([`agent-card`,{off:!g.value.enabled}])},[c(`div`,Ue,[c(`div`,We,[d[1]||=c(`span`,{class:`agent-dot`},null,-1),c(`span`,Ge,n(P.value.icon)+` `+n(P.value.name),1),d[2]||=c(`span`,{class:`agent-badge`},`built-in`,-1)]),s(G,{checked:g.value.enabled,"onUpdate:checked":H},null,8,[`checked`])]),c(`div`,Ke,[c(`div`,qe,[d[3]||=c(`label`,null,`Coding agent + Model`,-1),s(xe,{"cli-options":ee.value,"model-options":l(te)(I.value,L.value),cli:I.value,model:L.value,"memory-key":`builtin:`+r.agent,"onUpdate:cli":U,"onUpdate:model":ce},null,8,[`cli-options`,`model-options`,`cli`,`model`,`memory-key`])]),r.interactive?(f(),u(`div`,Ye,[...d[8]||=[c(`label`,null,`Interaction`,-1),c(`div`,{class:`built-in-interactive-hint`},[c(`span`,{class:`built-in-interactive-dot`}),t(` Chat from floating head `)],-1)]])):(f(),u(`div`,Je,[d[7]||=c(`label`,null,`Run schedule`,-1),s(fe,{"model-value":g.value.schedule,"onUpdate:modelValue":W},{default:v(()=>[s(me,{class:`h-[34px] w-full rounded-[9px] px-[11px]`},{default:v(()=>[s(_e)]),_:1}),s(pe,{position:`popper`},{default:v(()=>[s(ge,{class:`min-w-[var(--radix-select-trigger-width)]`},{default:v(()=>[s(he,{value:`daily`},{default:v(()=>[...d[4]||=[t(`Daily`,-1)]]),_:1}),s(he,{value:`weekly`},{default:v(()=>[...d[5]||=[t(`Weekly`,-1)]]),_:1}),s(he,{value:`manual`},{default:v(()=>[...d[6]||=[t(`Manual only`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`model-value`])])),c(`div`,Xe,[d[9]||=c(`label`,null,`Actions`,-1),c(`div`,q,[s(z,{variant:`outline`,size:`sm`,disabled:_.value||!g.value.enabled,onClick:le},{default:v(()=>[t(n(_.value?`Running…`:`Run now`),1)]),_:1},8,[`disabled`]),g.value.lastRunAt?(f(),u(`span`,J,` Last: `+n(F.value),1)):T(``,!0)])]),S.value||b.value?(f(),u(`div`,Y,[S.value?(f(),u(`div`,Ze,[c(`span`,null,n(S.value),1),A.value.length?(f(),u(`ul`,X,[(f(!0),u(w,null,o(A.value,e=>(f(),u(`li`,{key:`${e.doc}:${e.from}`},[c(`code`,null,n(e.doc),1),d[10]||=t(`: `,-1),c(`code`,null,n(e.from),1),d[11]||=t(` → `,-1),c(`code`,null,n(e.to),1)]))),128))])):T(``,!0),C.value?(f(),u(`div`,Z,[s(p,{to:`/work?task=${C.value}`},{default:v(()=>[t(` #`+n(C.value)+` — review the findings task `,1)]),_:1},8,[`to`])])):T(``,!0),j.value?(f(),u(`div`,Qe,[c(`a`,{href:`/${j.value}`,target:`_blank`,rel:`noopener`},` Run doc: `+n(j.value),9,$e)])):T(``,!0)])):T(``,!0),b.value?(f(),u(`div`,et,n(b.value),1)):T(``,!0)])):T(``,!0)]),(f(),e(O,{to:`body`},[s(se,{open:y.value,"onUpdate:open":d[0]||=e=>y.value=e},{default:v(()=>[s(oe),s(ae,{class:`built-in-started-modal`},{default:v(()=>[c(`div`,tt,[c(`div`,nt,[s(V,{class:`built-in-started-title`},{default:v(()=>[t(n(P.value.icon)+` `+n(P.value.name)+` started `,1)]),_:1}),s(ie,{class:`close-x`,"aria-label":`Close`,onClick:N},{default:v(()=>[...d[12]||=[t(` × `,-1)]]),_:1})]),c(`div`,rt,[s(B,{class:`built-in-started-summary`},{default:v(()=>[t(n(M.value),1)]),_:1}),d[13]||=c(`div`,{class:`built-in-started-details`},[c(`p`,{class:`built-in-started-timing`},[c(`span`,{class:`built-in-started-dot`}),t(` Usually takes 1–3 minutes `)]),c(`p`,{class:`built-in-started-location`},` Findings will appear as a new task in your inbox when the run is complete. `)],-1)]),c(`div`,it,[s(z,{variant:`outline`,size:`sm`,onClick:N},{default:v(()=>[...d[14]||=[t(`Got it`,-1)]]),_:1})])])]),_:1})]),_:1},8,[`open`])]))],2)):T(``,!0)}}}),[[`__scopeId`,`data-v-2ba6742c`]]),ot=[`pm`,`engineer`,`reviewer`];function st(e){let t=new Map(ot.map((e,t)=>[e,t]));return[...e].sort((e,n)=>{let r=t.get(e.name.toLowerCase())??999,i=t.get(n.name.toLowerCase())??999;return r===i?e.name.localeCompare(n.name):r-i})}var ct={class:`playground`},lt=[`aria-busy`],ut={class:`playground-sidebar-head`},dt={class:`playground-filters`},ft={class:`playground-filter-row`},Q=[`value`],pt=[`value`],$={key:0,class:`playground-error`},mt={class:`playground-list`},ht={key:0,class:`playground-skeletons`,"aria-hidden":`true`},gt={key:1,class:`playground-loading playground-no-match`},_t={key:2,class:`playground-loading`},vt={key:0,class:`playground-provider-group`},yt={class:`playground-provider-label`},bt={key:0,class:`playground-provider-error`},xt=[`disabled`,`onClick`],St={class:`playground-model-name`},Ct={class:`playground-model-reason`},wt={class:`playground-model-meta`},Tt={key:0},Et={class:`playground-chat`},Dt={class:`playground-chat-head`},Ot={class:`playground-active-info`},kt=[`disabled`],At={class:`playground-log-wrap`},jt=[`aria-label`],Mt={key:0,class:`playground-welcome`},Nt={class:`playground-starters`},Pt=[`onClick`],Ft=[`innerHTML`],It={key:1},Lt={key:1,class:`playground-send-error`},Rt=[`disabled`,`placeholder`,`aria-label`],zt={key:1,class:`playground-empty`},Bt={key:0},Vt=R(y({__name:`ModelPlaygroundPanel`,props:{active:{type:Boolean,default:!0}},setup(e){let r=e,i=[`What's this repo about?`,`Explain this codebase`,`What would you improve here first?`],a=x([]),m=x(!1),g=x(``),te=x(!1),_=x(null),y=x([]),b=x(``),C=x(!1),O=x(``),re=x(null),A=x(null),{showJumpToLatest:j,onScroll:M,scrollToLatest:N}=ue(re,{chatId:()=>`playground:${_.value?.runId??`none`}`,contentSize:()=>y.value.length,active:()=>r.active}),F=D(()=>a.value.flatMap(e=>e.models.map(t=>({...t,providerLabel:e.label})))),I=x(``),L=x(``),R=x(``),ie=[.5,1,2,5,10];function ae(e){let t=I.value.trim().toLowerCase();if(t&&!e.name.toLowerCase().includes(t))return!1;let n=R.value===``?null:Number(R.value);if(n!=null){let t=e.inputPricePerM??e.outputPricePerM;if(t!=null&&t>n)return!1}return!0}let oe=D(()=>a.value.filter(e=>!L.value||e.id===L.value).map(e=>({...e,models:e.models.filter(ae)})).filter(e=>e.models.length>0||e.error)),se=D(()=>oe.value.reduce((e,t)=>e+t.models.length,0)),B=D(()=>I.value.trim()!==``||L.value!==``||R.value!==``);function V(){I.value=``,L.value=``,R.value=``}function U(e){return e==null?`—`:e<1?`$${e.toFixed(3)}`:`$${e.toFixed(2)}`}async function ce(e=!1){m.value=!0,g.value=``;try{let t=await k(`/api/playground/models${e?`?refresh=1`:``}`);a.value=t.providers;let n=F.value;if(_.value){let e=n.find(e=>e.runId===_.value?.runId);_.value=e??_.value}else n.length&&(_.value=n[0])}catch(e){g.value=e instanceof Error?e.message:`Could not load the model catalog.`}finally{m.value=!1,te.value=!0}}function de(e){C.value||_.value?.runId===e.runId||(_.value=e,y.value=[],O.value=``,b.value=``)}function fe(){C.value||(y.value=[],O.value=``,b.value=``)}async function pe(e){let t=(e??b.value).trim();if(!t||C.value||!_.value)return;let n=_.value;y.value=[...y.value,{role:`user`,text:t}],b.value=``,O.value=``,C.value=!0,N(`auto`);try{let e=await k(`/api/playground/chat`,ne(`POST`,{runId:n.runId,messages:y.value}));y.value=[...y.value,{role:`assistant`,text:e.text}]}catch(e){O.value=e instanceof Error?e.message:`The model did not respond.`}finally{C.value=!1,N(`auto`)}}function me(e){e.key!==`Enter`||e.shiftKey||e.isComposing||(e.preventDefault(),pe())}return d(()=>{ce()}),(e,r)=>(f(),u(`div`,ct,[c(`aside`,{class:`playground-sidebar`,"aria-label":`Models worth trying`,"aria-busy":m.value},[c(`div`,ut,[r[9]||=c(`span`,{class:`sec-label`},[c(`span`,{class:`live-dot`}),t(`Models worth trying`)],-1),s(z,{variant:`outline`,size:`sm`,disabled:m.value,onClick:r[0]||=e=>ce(!0)},{default:v(()=>[t(n(m.value?`Refreshing…`:`Refresh`),1)]),_:1},8,[`disabled`])]),c(`div`,dt,[p(c(`input`,{"onUpdate:modelValue":r[1]||=e=>I.value=e,type:`search`,class:`playground-search`,placeholder:`Search models…`,"aria-label":`Search models by name`},null,512),[[S,I.value]]),c(`div`,ft,[p(c(`select`,{"onUpdate:modelValue":r[2]||=e=>L.value=e,class:`playground-provider-select`,"aria-label":`Filter by provider`},[r[10]||=c(`option`,{value:``},`All providers`,-1),(f(!0),u(w,null,o(a.value,e=>(f(),u(`option`,{key:e.id,value:e.id},n(e.label),9,Q))),128))],512),[[h,L.value]]),p(c(`select`,{"onUpdate:modelValue":r[3]||=e=>R.value=e,class:`playground-cost-select`,"aria-label":`Filter by maximum token cost`},[r[11]||=c(`option`,{value:``},`Any cost`,-1),(f(),u(w,null,o(ie,e=>c(`option`,{key:e,value:String(e)},` ≤ `+n(U(e))+` / 1M `,9,pt)),64))],512),[[h,R.value]])])]),g.value?(f(),u(`div`,$,n(g.value),1)):T(``,!0),c(`div`,mt,[m.value&&!F.value.length?(f(),u(`div`,ht,[(f(),u(w,null,o(3,e=>c(`div`,{key:e,class:`playground-skeleton`},[...r[12]||=[c(`div`,{class:`playground-skeleton-line w-70`},null,-1),c(`div`,{class:`playground-skeleton-line w-90`},null,-1),c(`div`,{class:`playground-skeleton-line w-45`},null,-1)]])),64))])):te.value&&!g.value&&F.value.length&&!se.value?(f(),u(`div`,gt,[r[13]||=t(` No models match your filters. `,-1),B.value?(f(),u(`button`,{key:0,type:`button`,class:`playground-filter-clear`,onClick:V},` Clear filters `)):T(``,!0)])):te.value&&!F.value.length&&!g.value?(f(),u(`div`,_t,` No models available right now. `)):T(``,!0),(f(!0),u(w,null,o(oe.value,e=>(f(),u(w,{key:e.id},[e.models.length||e.error?(f(),u(`div`,vt,[c(`div`,yt,n(e.label),1),e.error?(f(),u(`div`,bt,n(e.error),1)):T(``,!0),(f(!0),u(w,null,o(e.models,t=>(f(),u(`button`,{key:t.runId,type:`button`,class:E([`playground-model-card`,{active:_.value?.runId===t.runId}]),disabled:C.value&&_.value?.runId!==t.runId,onClick:n=>de({...t,providerLabel:e.label})},[c(`div`,St,n(t.name),1),c(`div`,Ct,n(t.reason),1),c(`div`,wt,[c(`span`,null,n(U(t.inputPricePerM))+` / `+n(U(t.outputPricePerM))+` per 1M`,1),t.contextWindow?(f(),u(`span`,Tt,n(l(ye)(t.contextWindow))+` ctx`,1)):T(``,!0)])],10,xt))),128))])):T(``,!0)],64))),128))])],8,lt),c(`section`,Et,[_.value?(f(),u(w,{key:0},[c(`header`,Dt,[r[14]||=c(`span`,{class:`playground-active-dot`,"aria-hidden":`true`},null,-1),c(`div`,Ot,[c(`strong`,null,n(_.value.name),1),c(`span`,null,n(_.value.providerLabel)+` · active model`,1)]),y.value.length?(f(),u(`button`,{key:0,type:`button`,class:`playground-clear`,disabled:C.value,"aria-label":`Clear conversation`,onClick:r[4]||=e=>fe()},` Clear `,8,kt)):T(``,!0)]),c(`div`,At,[c(`div`,{ref_key:`log`,ref:re,class:`playground-log ai-chat-log`,role:`log`,"aria-live":`polite`,"aria-label":`Conversation with ${_.value.name}`,onScroll:r[5]||=(...e)=>l(M)&&l(M)(...e)},[y.value.length?T(``,!0):(f(),u(`div`,Mt,[c(`strong`,null,`Try `+n(_.value.name),1),c(`p`,null,n(_.value.reason),1),c(`div`,Nt,[(f(),u(w,null,o(i,e=>c(`button`,{key:e,type:`button`,onClick:t=>pe(e)},n(e),9,Pt)),64))])])),(f(!0),u(w,null,o(y.value,(e,t)=>(f(),u(`div`,{key:t,class:E([`playground-row`,`playground-row-${e.role}`])},[c(`div`,{class:E([`playground-bubble`,`playground-bubble-${e.role}`])},[e.role===`assistant`?(f(),u(`div`,{key:0,class:`playground-markdown`,innerHTML:l(H)(e.text)},null,8,Ft)):(f(),u(`span`,It,n(e.text),1))],2)],2))),128)),s(le,{active:C.value,label:`Model is responding`},null,8,[`active`]),O.value?(f(),u(`div`,Lt,n(O.value),1)):T(``,!0)],40,jt),l(j)?(f(),u(`button`,{key:0,type:`button`,class:`agent-jump`,onClick:r[6]||=e=>l(N)()},[s(l(P),{class:`size-3.5`}),r[15]||=t(` Latest `,-1)])):T(``,!0)]),c(`form`,{class:`ai-chat-compose playground-compose`,onSubmit:r[8]||=ee(e=>pe(),[`prevent`])},[p(c(`textarea`,{ref_key:`draftTextarea`,ref:A,"onUpdate:modelValue":r[7]||=e=>b.value=e,rows:`1`,disabled:C.value,placeholder:`Message ${_.value.name}…`,"aria-label":`Message ${_.value.name}`,onKeydown:me},null,40,Rt),[[S,b.value]]),s(W,{disabled:!b.value.trim()||C.value},null,8,[`disabled`])],32)],64)):(f(),u(`div`,zt,[m.value?T(``,!0):(f(),u(`p`,Bt,`Pick a model from the sidebar to start chatting.`))]))])]))}}),[[`__scopeId`,`data-v-a40765cd`]]),Ht={class:`mp-panel agent-tab-panel`},Ut={key:0,class:`mp-error`},Wt={key:1,class:`agent-empty`},Gt={class:`mp-row-head`},Kt={class:`mp-row-title`},qt={class:`agent-name`},Jt=[`href`],Yt={class:`mp-note`},Xt={key:0,class:`mp-key-form`},Zt=[`onUpdate:modelValue`,`placeholder`,`aria-label`,`onKeyup`],Qt={key:1,class:`mp-error`},$t={key:0,class:`mp-loading`},en={key:1,class:`mp-error`},tn=[`onClick`],nn={key:2,class:`mp-data`},rn={key:0,class:`mp-stat mp-stat-hero`},an={class:`mp-stat-value`},on={key:0,class:`mp-stat-sub`},sn={key:1,class:`mp-part-error`},cn={key:2,class:`mp-stat-row`},ln={class:`mp-stat`},un={class:`mp-stat-value sm`},dn={class:`mp-stat`},fn={class:`mp-stat-value sm`},pn={class:`mp-stat`},mn={class:`mp-stat-value sm`},hn={key:0,class:`mp-stat`},gn={class:`mp-stat-value sm`},_n={key:3,class:`mp-part-error`},vn={key:3,class:`mp-data`},yn={class:`mp-window-head`},bn={class:`mp-stat-label`},xn={class:`mp-window-pct`},Sn=[`aria-valuenow`,`aria-label`],Cn={key:1,class:`mp-window-reset`},wn={key:1,class:`mp-part-error`},Tn=[`href`],En={key:2,class:`mp-part-error`},Dn={key:4,class:`mp-data`},On={key:0,class:`mp-part-error`},kn={class:`mp-stat mp-stat-hero`},An={class:`mp-stat-value`},jn={key:0,class:`mp-stat-sub`},Mn={class:`mp-stat-row`},Nn={class:`mp-stat`},Pn={class:`mp-stat-value sm`},Fn={key:0,class:`mp-stat`},In={class:`mp-stat-value sm`},Ln={key:1,class:`mp-stat-row`},Rn={class:`mp-stat-label`},zn={class:`mp-stat-value sm`},Bn={key:0,class:`mp-stat-sub`},Vn={key:1,class:`mp-part-error`},Hn={key:2,class:`mp-stat-row`},Un={class:`mp-stat-label`},Wn={class:`mp-stat-value sm`},Gn={key:3,class:`mp-part-error`},Kn={key:4,class:`mp-part-error`},qn={key:5,class:`mp-actions`,"data-test-id":`model-providers-balance-meta`},Jn=[`title`],Yn={key:1,class:`mp-refresh-ok`,role:`status`},Xn=R(y({__name:`ModelProvidersPanel`,setup(i){let a=x([]),m=x(!1),h=x(``),ee=A(),_=g({}),y=g({}),b=g({}),C=g({}),D=g({});function O(e){return _[e]||(_[e]={usage:null,loading:!1,error:``,fetchedAt:null,refreshOk:!1}),_[e]}async function re(){m.value=!0,h.value=``;try{let e=await k(`/api/model-providers`);a.value=e.providers;for(let t of e.providers)t.kind===`live`&&t.hasKey&&!_[t.id]?.usage&&j(t.id)}catch(e){h.value=e instanceof Error?e.message:`Could not load the provider list.`}finally{m.value=!1}}async function j(e,t){let n=O(e);if(n.loading)return;let r=t?.manual===!0;n.loading=!0,n.error=``;try{let t=await k(`/api/model-providers/${e}/usage`);n.usage=t,n.fetchedAt=t&&typeof t==`object`&&`at`in t&&typeof t.at==`string`?t.at:new Date().toISOString(),n.refreshOk=!0,r&&ee.pushToast(`${M(e)} balance updated`,`success`)}catch(e){let t=e instanceof Error?e.message:`Could not load usage.`;n.error=t,n.refreshOk=!1,r&&ee.pushToast(t,`error`)}finally{n.loading=!1}}function M(e){return a.value.find(t=>t.id===e)?.label??e}function P(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`})}async function F(e){await j(e,{manual:!0})}async function I(e){if(!b[e.id]){b[e.id]=!0,D[e.id]=``;try{let t={key:y[e.id]??``},n=await k(`/api/model-providers/${e.id}/key`,ne(`POST`,t));e.hasKey=n.hasKey,y[e.id]=``,C[e.id]=!1,n.hasKey?j(e.id):O(e.id).usage=null}catch(t){D[e.id]=t instanceof Error?t.message:`Could not save the key.`}finally{b[e.id]=!1}}}function L(e){y[e.id]=``,I(e)}function R(e){return e==null?`—`:`$${e.toLocaleString(`en-US`,{minimumFractionDigits:2,maximumFractionDigits:2})}`}let ie=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];function ae(e){let t=/^(\d{4})\.(\d{2})$/.exec(e);if(!t)return e;let n=Number(t[2])-1;return n>=0&&n<12?`${ie[n]} ${t[1]}`:e}function oe(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`})}function se(e){return e.kind===`live`}let B=e=>e?.kind===`openrouter`?e:null,V=e=>e?.kind===`opencode-go`?e:null,H=e=>e?.kind===`deepinfra`?e:null;return d(()=>{re()}),(i,d)=>(f(),u(`div`,Ht,[d[14]||=c(`div`,{class:`sec-label`,style:{"padding-top":`16px`,"margin-bottom":`4px`}},[c(`span`,{class:`live-dot`}),t(`Model providers `)],-1),d[15]||=c(`div`,{class:`agent-desc`}," Spend and usage per model provider, without leaving RepoOS. Three providers report live numbers behind an API key — read from RepoOS's `.env`, or from a coding agent's own login (pi, opencode) when one is already connected; the other rows link to dashboards until live data is connected here. ",-1),h.value?(f(),u(`div`,Ut,n(h.value),1)):m.value&&!a.value.length?(f(),u(`div`,Wt,`Loading providers…`)):T(``,!0),(f(!0),u(w,null,o(a.value,i=>(f(),u(`div`,{key:i.id,class:`mp-row`},[c(`div`,Gt,[c(`div`,Kt,[c(`span`,qt,n(i.label),1),c(`span`,{class:E([`mp-pill`,i.kind===`live`?`pill-live`:`pill-link`])},n(i.kind===`live`?`live`:`no live data`),3)]),c(`a`,{class:`mp-dash-link`,href:i.dashboardUrl,target:`_blank`,rel:`noopener noreferrer`},` Open dashboard ↗ `,8,Jt)]),c(`div`,Yt,n(i.note),1),se(i)?(f(),u(w,{key:0},[!i.hasKey||C[i.id]?(f(),u(`div`,Xt,[p(c(`input`,{"onUpdate:modelValue":e=>y[i.id]=e,type:`password`,autocomplete:`off`,placeholder:`Paste your ${i.label} API key`,"aria-label":`${i.label} API key`,onKeyup:te(e=>I(i),[`enter`])},null,40,Zt),[[S,y[i.id]]]),s(z,{variant:`outline`,size:`sm`,disabled:b[i.id],onClick:e=>I(i)},{default:v(()=>[t(n(b[i.id]?`Saving…`:`Save key`),1)]),_:2},1032,[`disabled`,`onClick`]),i.hasKey?(f(),e(z,{key:0,variant:`ghost`,size:`sm`,disabled:b[i.id],onClick:e=>C[i.id]=!1},{default:v(()=>[...d[0]||=[t(` Cancel `,-1)]]),_:1},8,[`disabled`,`onClick`])):T(``,!0),d[1]||=c(`div`,{class:`mp-key-hint`},[t(` Stored in `),c(`code`,null,`.env`),t(` on this machine (gitignored) — never committed, never logged. `)],-1),D[i.id]?(f(),u(`div`,Qt,n(D[i.id]),1)):T(``,!0)])):(f(),u(w,{key:1},[O(i.id).loading?(f(),u(`div`,$t,`Checking…`)):O(i.id).error?(f(),u(`div`,en,[t(n(O(i.id).error)+` `,1),c(`button`,{class:`mp-retry`,onClick:e=>j(i.id)},`Retry`,8,tn)])):B(O(i.id).usage)?(f(),u(`div`,nn,[B(O(i.id).usage).credits?(f(),u(`div`,rn,[d[2]||=c(`span`,{class:`mp-stat-label`},`Remaining credits`,-1),c(`span`,an,n(R(B(O(i.id).usage).credits.remaining)),1),B(O(i.id).usage).credits.totalCredits==null?T(``,!0):(f(),u(`span`,on,` of `+n(R(B(O(i.id).usage).credits.totalCredits))+` purchased `,1))])):T(``,!0),B(O(i.id).usage).creditsError?(f(),u(`div`,sn,` Balance unavailable: `+n(B(O(i.id).usage).creditsError),1)):T(``,!0),B(O(i.id).usage).key?(f(),u(`div`,cn,[c(`div`,ln,[d[3]||=c(`span`,{class:`mp-stat-label`},`Today`,-1),c(`span`,un,n(R(B(O(i.id).usage).key.usageDaily)),1)]),c(`div`,dn,[d[4]||=c(`span`,{class:`mp-stat-label`},`This week`,-1),c(`span`,fn,n(R(B(O(i.id).usage).key.usageWeekly)),1)]),c(`div`,pn,[d[5]||=c(`span`,{class:`mp-stat-label`},`This month`,-1),c(`span`,mn,n(R(B(O(i.id).usage).key.usageMonthly)),1)]),B(O(i.id).usage).key.rateLimit?.requests==null?T(``,!0):(f(),u(`div`,hn,[d[6]||=c(`span`,{class:`mp-stat-label`},`Rate limit`,-1),c(`span`,gn,n(B(O(i.id).usage).key.rateLimit.requests)+` req / `+n(B(O(i.id).usage).key.rateLimit.interval),1)]))])):T(``,!0),B(O(i.id).usage).keyError?(f(),u(`div`,_n,` Key usage unavailable: `+n(B(O(i.id).usage).keyError),1)):T(``,!0)])):V(O(i.id).usage)?(f(),u(`div`,vn,[V(O(i.id).usage).windows.length?(f(!0),u(w,{key:0},o(V(O(i.id).usage).windows,e=>(f(),u(`div`,{key:e.id,class:`mp-window`},[c(`div`,yn,[c(`span`,bn,n(e.label),1),c(`span`,xn,[t(n(e.usedPct==null?`—`:`${Math.round(e.usedPct)}% used`)+` `,1),e.usedUsd!=null&&e.limitUsd!=null?(f(),u(w,{key:0},[t(` · `+n(R(e.usedUsd))+` of `+n(R(e.limitUsd)),1)],64)):T(``,!0)])]),e.usedPct==null?T(``,!0):(f(),u(`div`,{key:0,class:`mp-bar`,role:`progressbar`,"aria-valuenow":Math.round(e.usedPct),"aria-valuemin":`0`,"aria-valuemax":`100`,"aria-label":`${e.label} usage`},[c(`div`,{class:`mp-bar-fill`,style:r({width:`${Math.min(100,Math.max(0,e.usedPct))}%`})},null,4)],8,Sn)),oe(e.resetsAt)?(f(),u(`div`,Cn,` resets `+n(oe(e.resetsAt)),1)):T(``,!0)]))),128)):V(O(i.id).usage).unrecognized?(f(),u(`div`,wn,[d[7]||=t(` Live usage responded, but in a format this build doesn't recognize — check the `,-1),c(`a`,{href:i.dashboardUrl,target:`_blank`,rel:`noopener noreferrer`},`console`,8,Tn),d[8]||=t(`. `,-1)])):(f(),u(`div`,En,`No usage reported yet.`))])):H(O(i.id).usage)?(f(),u(`div`,Dn,[H(O(i.id).usage).checklist?(f(),u(w,{key:0},[H(O(i.id).usage).checklist.suspended?(f(),u(`div`,On,n(H(O(i.id).usage).checklist.suspendReason?`Account suspended (${H(O(i.id).usage).checklist.suspendReason}).`:`Account suspended.`),1)):T(``,!0),c(`div`,kn,[d[9]||=c(`span`,{class:`mp-stat-label`},`Available credit`,-1),c(`span`,An,n(R(H(O(i.id).usage).checklist.availableUsd)),1),H(O(i.id).usage).checklist.owedUsd==null?T(``,!0):(f(),u(`span`,jn,` plus `+n(R(H(O(i.id).usage).checklist.owedUsd))+` owed `,1))]),c(`div`,Mn,[c(`div`,Nn,[d[10]||=c(`span`,{class:`mp-stat-label`},`Since last invoice`,-1),c(`span`,Pn,n(R(H(O(i.id).usage).checklist.recentUsd)),1)]),H(O(i.id).usage).checklist.limitUsd==null?T(``,!0):(f(),u(`div`,Fn,[d[11]||=c(`span`,{class:`mp-stat-label`},`Spending limit`,-1),c(`span`,In,n(R(H(O(i.id).usage).checklist.limitUsd)),1)]))]),H(O(i.id).usage).checklist.scopedCredits.length?(f(),u(`div`,Ln,[(f(!0),u(w,null,o(H(O(i.id).usage).checklist.scopedCredits,e=>(f(),u(`div`,{key:e.name,class:`mp-stat`},[c(`span`,Rn,n(e.name),1),c(`span`,zn,n(R(e.remainingUsd))+` left`,1),e.expired?(f(),u(`span`,Bn,`expired`)):T(``,!0)]))),128))])):T(``,!0)],64)):T(``,!0),H(O(i.id).usage).checklistError?(f(),u(`div`,Vn,` Balance unavailable: `+n(H(O(i.id).usage).checklistError),1)):T(``,!0),H(O(i.id).usage).usage?.length?(f(),u(`div`,Hn,[(f(!0),u(w,null,o(H(O(i.id).usage).usage,e=>(f(),u(`div`,{key:e.period,class:`mp-stat`},[c(`span`,Un,n(ae(e.period)),1),c(`span`,Wn,n(R(e.totalUsd)),1)]))),128))])):H(O(i.id).usage).usageError?T(``,!0):(f(),u(`div`,Gn,` No usage reported for this period. `)),H(O(i.id).usage).usageError?(f(),u(`div`,Kn,` Usage unavailable: `+n(H(O(i.id).usage).usageError),1)):T(``,!0)])):T(``,!0),i.hasKey&&!C[i.id]?(f(),u(`div`,qn,[O(i.id).fetchedAt?(f(),u(`span`,{key:0,class:`mp-as-of`,title:O(i.id).fetchedAt??void 0},` As of `+n(P(O(i.id).fetchedAt)),9,Jn)):T(``,!0),O(i.id).refreshOk&&O(i.id).fetchedAt?(f(),u(`span`,Yn,[s(l(N),{class:`size-3.5`,"aria-hidden":`true`})])):T(``,!0),s(z,{variant:`outline`,size:`sm`,disabled:O(i.id).loading,"aria-busy":O(i.id).loading,onClick:e=>F(i.id)},{default:v(()=>[t(n(O(i.id).loading?`Refreshing…`:`Refresh`),1)]),_:2},1032,[`disabled`,`aria-busy`,`onClick`]),s(z,{variant:`ghost`,size:`sm`,onClick:e=>C[i.id]=!0},{default:v(()=>[...d[12]||=[t(`Replace key`,-1)]]),_:1},8,[`onClick`]),s(z,{variant:`ghost`,size:`sm`,disabled:b[i.id],onClick:e=>L(i)},{default:v(()=>[...d[13]||=[t(` Clear `,-1)]]),_:1},8,[`disabled`,`onClick`])])):T(``,!0)],64))],64)):T(``,!0)]))),128))]))}}),[[`__scopeId`,`data-v-4d3be55f`]]),Zn={class:`agents-page`},Qn={class:`page-header`},$n={class:`page-desc`},er={key:0},tr={key:1,class:`save-msg err`},nr={key:2,class:`save-msg ok`},rr={key:0,class:`spin`},ir={class:`agent-tabs`},ar=[`onClick`],or={class:`agents-tab-content`},sr={class:`agent-tab-panel`,style:{padding:`0 18px 6px`,"margin-bottom":`16px`}},cr={class:`sec-label`,style:{"padding-top":`16px`,"margin-bottom":`4px`}},lr={class:`am-list-notice-text`},ur=[`onClick`],dr={class:`agent-tab-panel`,style:{padding:`0 18px 6px`,"margin-bottom":`16px`}},fr={class:`agent-add`},pr={key:0,class:`agent-empty`},mr={class:`agent-tab-panel`,style:{padding:`0 18px 6px`,"margin-bottom":`16px`}},hr={key:0,class:`agent-tab-panel`,style:{padding:`0 18px 6px`,"margin-bottom":`16px`}},gr={class:`sec-label`,style:{"padding-top":`16px`,"margin-bottom":`4px`}},_r={key:0,class:`detect-update-error`},vr={key:1,class:`detect-cache-label`},yr={key:2,class:`detect-cache-label`},br={key:3,class:`detect-loading`},xr={key:4,class:`agent-empty`},Sr={class:`agent-name detect-agent-name`},Cr={class:`detect-compat-slot`},wr=[`aria-label`,`onClick`],Tr={class:`detect-details`},Er={key:0,class:`detect-ver detect-ver-inline`},Dr={class:`detect-binary-item-name`},Or={class:`detect-binary-item-ver`},kr={class:`detect-binary-item-path`},Ar={key:2,class:`detect-row-spinner`,title:`Probing…`},jr={key:3,class:`detect-update-detail`},Mr={class:`detect-update-meta`},Nr={key:0},Pr={key:1},Fr={key:2,class:`detect-update-reason`},Ir=[`onClick`],Lr={key:4,class:`detect-hint-inline`},Rr=[`title`],zr=[`onClick`],Br={key:5,class:`detect-hint-inline`},Vr=[`title`],Hr=[`onClick`],Ur={key:6,class:`detect-hint-inline`},Wr=[`title`],Gr=[`onClick`],Kr=[`aria-pressed`,`aria-label`,`title`,`onClick`],qr={key:0,class:`detect-compat-card`},Jr={class:`detect-compat-card-explanation`},Yr={key:0,class:`detect-compat-probe-row`},Xr={class:`detect-hint-code`},Zr=[`onClick`],Qr={key:1,class:`detect-compat-card-hint`},$r={key:2,class:`detect-compat-card-hint`},ei={class:`am-modal-head`},ti={key:0,class:`agent-skill-modal-list`},ni=[`checked`,`onChange`],ri={key:0},ii=`docs/agent-model-recommendations.md`,ai=`docs/opencode-models.md`,oi=y({__name:`AgentsView`,setup(a){let h=re(),g=_(),y=C(),S=j(),O={default:`Default Agents`,custom:`Custom Agents`,team:`Build Your Team`,detected:`Detected Coding Agents`,playground:`Model Playground`,providers:`Model providers`},A=[`default`,`custom`,`team`,`detected`,`playground`,`providers`],M=x(`default`),N=x(!1),P=x(!1);m(M,e=>{e===`playground`&&(N.value=!0),e===`providers`&&(P.value=!0)});let F=()=>{let e=y.query.tab;return typeof e==`string`&&A.includes(e)?e:`default`};m(()=>y.query.tab,()=>{let e=F();e!==M.value&&(M.value=e)},{immediate:!0}),m(M,e=>{F()!==e&&g.replace({query:{...y.query,tab:e}})});function I(){S.loadDoc(ii),g.push({name:`repo`})}function R(){S.loadDoc(ai),g.push({name:`repo`})}let H=x([]),U=x(``),W=x(null),le=!1,ue,G=!1,ye=!1;function xe(){le=!0,H.value=h.agents.map(e=>({...e})),le=!1}m(()=>h.loaded,e=>{e&&xe()},{immediate:!0});let Se=D(()=>h.agentsMeta.defaults.map(e=>e.name.toLowerCase())),Ce=e=>Se.value.includes(e.toLowerCase()),we=[`ross`,`cto`],Te=e=>we.includes(e.toLowerCase()),Ee=D(()=>st(H.value.filter(e=>Ce(e.name)&&!Te(e.name)))),De=D(()=>H.value.filter(e=>Ce(e.name)&&Te(e.name))),Oe=D(()=>H.value.filter(e=>!Ce(e.name))),ke={"claude code":`Claude Code`,"github copilot":`GitHub Copilot CLI`,"qwen code":`qwen code`,codex:`codex`,antigravity:`Antigravity CLI (agy)`,crush:`Crush`},Ae=new Map,je=new Map;function Me(e,t){let n=Ae.get(e);n&&be(n,t)}function Ne(e,t){let n=je.get(e);n&&be(n,t)}D(()=>h.agentsMeta.clis.map(e=>({value:e,label:ke[e]??e})));let Pe=x({}),K=x({});h.modelsFor;let Fe=D(()=>h.modelsLoading),Ie=D(()=>h.agentsMeta.clis.map(e=>({cli:e,notice:h.modelNoticeFor(e)})).filter(e=>e.notice?.kind===`failed`));function Le(e){return`${e.name}\u0000${e.cli}\u0000${e.model}`}function Re(e){return Pe.value[Le(e)]}async function ze(e){let t=Le(e);if(K.value[t])return;K.value={...K.value,[t]:!0};let n=e.cli,r=e.model;try{let e=await k(`/api/models/test`,ne(`POST`,{cli:n,model:r}));Pe.value={...Pe.value,[t]:e.result}}catch(e){Pe.value={...Pe.value,[t]:{cli:n,model:r,status:`failed`,durationMs:0,error:e instanceof Error?e.message:`Model compatibility test failed.`}}}finally{let e={...K.value};delete e[t],K.value=e}}let Be=(e=!1)=>h.loadModels(e);function Ve(){let e=U.value.trim();if(e){if(H.value.some(t=>t.name.toLowerCase()===e.toLowerCase())){h.error=`An agent named "${e}" already exists.`;return}H.value.push({name:e,cli:h.agentsMeta.clis[0]??`opencode`,model:h.agentsMeta.models[1]??`big pickle`,enabled:!0,instructions:``}),U.value=``,h.error=``}}function Ue(e){H.value=H.value.filter(t=>t!==e)}function We(e,t){e.instructions=t.target.value}function Ge(e){let t=document.activeElement;t instanceof HTMLTextAreaElement&&t.value!==e.instructions&&(e.instructions=t.value)}function Ke(e,t,n){let r=new Set(e.skills??[]);n?r.add(t):r.delete(t),e.skills=[...r]}function qe(e){W.value=e}function Je(){let e=new Set;for(let t of H.value){let n=t.name.trim().toLowerCase();if(!n){h.error=`Every agent needs a name.`;return}if(e.has(n)){h.error=`Duplicate agent name "${t.name}".`;return}e.add(n)}return H.value.map(e=>({...e,name:e.name.trim()}))}async function Ye(){if(G){ye=!0;return}let e=Je();if(e){G=!0,ye=!1;try{await h.saveAgents(e)}catch{}finally{G=!1,ye&&Xe(0)}}}function Xe(e=450){clearTimeout(ue),ue=setTimeout(()=>void Ye(),e)}m(H,()=>{le||!h.loaded||(h.msg=``,h.error=``,G&&(ye=!0),Xe())},{deep:!0,flush:`sync`});let q=x([]),J=x(new Set),Y=x(!1),Ze=x(!1),X=x(null),Z=x(``),Qe=x(null),$e=x({});function et(e){Qe.value=Qe.value===e?null:e}function tt(e,t){$e.value={...$e.value,[e]:t}}function nt(e){let t=$e.value[e.id]??0,n=e.allBinaries?.[t];return n?{path:n.path,version:n.version}:{path:e.path,version:e.version}}function rt(e){if(!e)return``;let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/6e4),r=Math.floor(t/36e5),i=Math.floor(t/864e5);return i>=1?`cached ${i}d ago`:r>=1?`cached ${r}h ago`:n>=1?`cached ${n}m ago`:`cached just now`}let it=x(!1),ot=x(!1),ct=x({}),lt=D(()=>new Set(q.value.filter(e=>e.installed&&e.drivable&&e.cli).map(e=>e.cli)));function ut(e,t={}){return(h.agentsMeta.clis??[]).filter(n=>n!==`antigravity`||n===e||!t.team&<.value.has(n))}let{isAgentFavorite:dt,toggleAgentFavorite:ft}=ve();function Q(e){return e.cli??e.id}let pt=D(()=>q.value.map(e=>e.installed?e.headless===!1?{agent:e,status:`desktop`,statusLabel:`desktop only`,color:`var(--amber)`}:e.auth===!1?{agent:e,status:`auth`,statusLabel:`sign-in required`,color:`var(--amber)`}:{agent:e,status:`ok`,statusLabel:`ready`,color:`var(--green)`}:{agent:e,status:`missing`,statusLabel:`not installed`,color:`var(--red)`}).sort((e,t)=>e.agent.name.localeCompare(t.agent.name,void 0,{sensitivity:`base`}))),$=null;async function mt(){Ze.value=!1,Z.value=``;try{let e=await k(`/api/agents/detect`);e.agents.length&&(q.value=e.agents,X.value=e.cachedAt)}catch{}$?.close();let e=new Set(q.value.map(e=>e.id));J.value=new Set(e.size?e:[`__loading__`]),Y.value=!0;let t=new EventSource(`/api/agents/detect/stream`);$=t,t.addEventListener(`agent`,e=>{try{let t=JSON.parse(e.data),n=q.value.findIndex(e=>e.id===t.id);n>=0?q.value=q.value.map((e,r)=>r===n?t:e):q.value=[...q.value,t];let r=new Set(J.value);r.delete(t.id),J.value=r}catch{}}),t.addEventListener(`done`,e=>{try{let{cachedAt:t}=JSON.parse(e.data);X.value=t}catch{}J.value=new Set,Y.value=!1,t.close(),$=null}),t.onerror=()=>{J.value=new Set,Y.value=!1,q.value.length||(Ze.value=!0),t.close(),$=null}}async function ht(){let e=Object.keys(ct.value).length>0;e&&await mt(),await gt(e)}async function gt(e=!1){it.value=!0,ot.value=!1;try{let t=await k(`/api/agents/updates`,ne(`POST`,{refresh:e}));ct.value=t.updates,q.value=q.value.map(e=>({...e,update:t.updates[e.id]}))}catch{ot.value=!0}finally{it.value=!1}}function _t(e){return e?e.status===`up_to_date`?`Up to date`:e.status===`update_available`?`Update available: ${e.installedVersion} → ${e.latestVersion}`:e.status===`unavailable`?`Could not check`:`Check manually`:`Not checked`}function vt(e){return e?.status===`update_available`?`var(--amber)`:e?.status===`up_to_date`?`var(--green)`:e?.status===`unavailable`?`var(--red)`:`var(--txt-dim)`}function yt(e){let t=e.compatibility?.status;return t===`verified`?`var(--green)`:t===`unsupported`?`var(--red)`:t===`upgrade_recommended`||t===`newer_than_verified`?`var(--amber)`:`var(--txt-dim)`}function bt(e){return`repoos doctor --probe ${e.cli||e.binary} --yes`}function xt(e){let t=e.compatibility;return t?.contract?t.status===`not_probed`||t.status===`newer_than_verified`:!1}function St(e){let t=e.compatibility;if(!t)return``;let n=t.newestCertifiedVersion?`Newest certified: ${t.newestCertifiedVersion}.`:`No release is certified yet.`;return`${t.explanation} ${n}`}function Ct(e){let t=e.compatibility?.status;return t===`verified`?`✓`:t===`unsupported`?`!`:`?`}function wt(e){return e?.checkedAt?`checked ${new Date(e.checkedAt).toLocaleString()}`:``}function Tt(e){de(e),Z.value=e,setTimeout(()=>{Z.value===e&&(Z.value=``)},1500)}return d(()=>{mt(),Be()}),i(()=>{clearTimeout(ue),$?.close(),$=null}),(i,a)=>(f(),u(`div`,Zn,[c(`header`,Qn,[c(`div`,null,[a[4]||=c(`div`,{class:`page-title agents-page-title`},`Agents`,-1),c(`div`,$n,[a[3]||=t(` The AI agents that work this repo `,-1),l(h).saving?(f(),u(`span`,er,` · Saving…`)):l(h).error?(f(),u(`span`,tr,` · `+n(l(h).error),1)):l(h).msg?(f(),u(`span`,nr,` · Saved`)):T(``,!0)])]),c(`div`,{class:`page-header-actions`},[a[5]||=c(`a`,{class:`page-help-link`,href:`https://docs.repoos.org/agents`,target:`_blank`,rel:`noreferrer`},`Set up agents ↗`,-1),c(`button`,{class:`page-help-link`,onClick:I},` Model & agent guide → `),a[6]||=c(`a`,{class:`page-help-link`,href:`/settings?tab=toml`},`Advanced config`,-1)])]),l(h).loaded?(f(),u(w,{key:1},[c(`div`,ir,[(f(),u(w,null,o(A,e=>c(`button`,{key:e,type:`button`,class:E([`tab-btn`,{active:M.value===e}]),onClick:t=>M.value=e},n(O[e]),11,ar)),64))]),c(`div`,or,[p(c(`div`,sr,[c(`div`,cr,[a[7]||=c(`span`,{class:`live-dot`},null,-1),a[8]||=t(`Default agents `,-1),c(`button`,{class:`model-pricing-link`,onClick:R},` Model pricing & use cases → `),s(z,{variant:`outline`,size:`sm`,style:{"margin-left":`auto`},disabled:Fe.value,title:`Re-probe every CLI's live model list (bypasses the cache)`,onClick:a[0]||=e=>Be(!0)},{default:v(()=>[t(n(Fe.value?`Refreshing…`:`Refresh models`),1)]),_:1},8,[`disabled`])]),(f(!0),u(w,null,o(Ie.value,e=>(f(),u(`div`,{key:e.cli,class:`am-list-notice am-list-notice-failed agents-model-failure`,role:`status`,"data-testid":`agents-model-failure`},[c(`span`,lr,n(e.cli)+`: `+n(e.notice.text),1),c(`button`,{type:`button`,class:`am-list-notice-retry`,onClick:t=>l(h).refreshModelsForCli(e.cli)},` Retry `,8,ur)]))),128)),a[9]||=c(`div`,{class:`agent-desc`},` Headless task-engine roles that run the roadmap. Toggle them on or off and pick their coding agent and model. `,-1),(f(!0),u(w,null,o(Ee.value,t=>(f(),e(He,{key:t.name,agent:t,variant:`default`,"cli-options":ut(t.cli),"memory-key":`headless:`+t.name,"skills-available":l(h).agentsMeta.skills.length>0,testing:!!K.value[Le(t)],"test-result":Re(t),"register-instr-ref":e=>l(Ae).set(t.name,e),onTest:e=>ze(t),onOpenSkills:e=>qe(t),onInstrInput:e=>We(t,e),onInstrBlur:e=>Ge(t),onOpenRecommendations:I,onTranscribed:e=>Me(t.name,e)},null,8,[`agent`,`cli-options`,`memory-key`,`skills-available`,`testing`,`test-result`,`register-instr-ref`,`onTest`,`onOpenSkills`,`onInstrInput`,`onInstrBlur`,`onTranscribed`]))),128))],512),[[b,M.value==="default"]]),p(c(`div`,dr,[a[11]||=c(`div`,{class:`sec-label`,style:{"padding-top":`16px`,"margin-bottom":`4px`}},[c(`span`,{class:`live-dot`,style:{background:`var(--violet, var(--cyan))`}}),t(`Custom agents `)],-1),a[12]||=c(`div`,{class:`agent-desc`},` Your own roles — data analyst, refactor agent, anything you need. `,-1),c(`div`,fr,[s(ce,{modelValue:U.value,"onUpdate:modelValue":a[1]||=e=>U.value=e,placeholder:`e.g. data analyst`,class:`w-[220px]`,onKeyup:te(Ve,[`enter`])},null,8,[`modelValue`]),s(z,{variant:`outline`,size:`sm`,disabled:!U.value.trim(),onClick:Ve},{default:v(()=>[...a[10]||=[t(` Add agent `,-1)]]),_:1},8,[`disabled`])]),Oe.value.length?T(``,!0):(f(),u(`div`,pr,` No custom agents yet — add one above. `)),(f(!0),u(w,null,o(Oe.value,t=>(f(),e(He,{key:t.name,agent:t,variant:`custom`,"cli-options":ut(t.cli),"memory-key":`custom:`+t.name,"skills-available":l(h).agentsMeta.skills.length>0,testing:!!K.value[Le(t)],"test-result":Re(t),"register-instr-ref":e=>l(je).set(t.name,e),onTest:e=>ze(t),onOpenSkills:e=>qe(t),onRemove:e=>Ue(t),onInstrInput:e=>We(t,e),onInstrBlur:e=>Ge(t),onOpenRecommendations:I,onTranscribed:e=>Ne(t.name,e)},null,8,[`agent`,`cli-options`,`memory-key`,`skills-available`,`testing`,`test-result`,`register-instr-ref`,`onTest`,`onOpenSkills`,`onRemove`,`onInstrInput`,`onInstrBlur`,`onTranscribed`]))),128))],512),[[b,M.value===`custom`]]),p(c(`div`,mr,[a[13]||=c(`div`,{class:`sec-label`,style:{"padding-top":`16px`,"margin-bottom":`4px`}},[c(`span`,{class:`live-dot`,style:{background:`var(--green)`}}),t(`Build your team `)],-1),a[14]||=c(`div`,{class:`agent-desc`},` The agents that talk back or extend RepoOS. Enable them to add new capabilities. `,-1),(f(!0),u(w,null,o(De.value,t=>(f(),e(He,{key:`team-`+t.name,agent:t,variant:`team`,"cli-options":ut(t.cli,{team:!0}),"memory-key":`team:`+t.name,"skills-available":l(h).agentsMeta.skills.length>0,testing:!!K.value[Le(t)],"test-result":Re(t),"register-instr-ref":e=>l(Ae).set(t.name,e),onTest:e=>ze(t),onOpenSkills:e=>qe(t),onInstrInput:e=>We(t,e),onInstrBlur:e=>Ge(t),onOpenRecommendations:I,onTranscribed:e=>Me(t.name,e)},null,8,[`agent`,`cli-options`,`memory-key`,`skills-available`,`testing`,`test-result`,`register-instr-ref`,`onTest`,`onOpenSkills`,`onInstrInput`,`onInstrBlur`,`onTranscribed`]))),128)),s(at,{agent:`debugger`,interactive:``}),s(at,{agent:`tech-debt`}),s(at,{agent:`performance`}),s(at,{agent:`architect`}),s(at,{agent:`design`}),s(at,{agent:`docs-debt`})],512),[[b,M.value===`team`]]),Ze.value?T(``,!0):p((f(),u(`div`,hr,[c(`div`,gr,[a[15]||=c(`span`,{class:`live-dot`,style:{background:`var(--violet, var(--cyan))`}},null,-1),a[16]||=t(` Detected coding agents `,-1),s(z,{variant:`outline`,size:`sm`,class:`detect-updates-btn`,disabled:it.value||Y.value,onClick:ht},{default:v(()=>[t(n(it.value||Y.value?`Checking…`:Object.keys(ct.value).length>0?`Refresh update checks`:`Check for updates`),1)]),_:1},8,[`disabled`])]),a[17]||=c(`div`,{class:`agent-desc`},` What's on this machine's PATH — installed & headless-ready, desktop-only, or missing. Update checks contact only the supported public source after you request them; results are cached for 6 hours. `,-1),ot.value?(f(),u(`div`,_r,` Update checks are temporarily unavailable. `)):T(``,!0),X.value&&Y.value?(f(),u(`div`,vr,n(rt(X.value))+` · scanning now… `,1)):X.value&&!Y.value?(f(),u(`div`,yr,n(rt(X.value)),1)):T(``,!0),Y.value&&!q.value.length?(f(),u(`div`,br,`Probing PATH…`)):q.value.length?(f(!0),u(w,{key:5},o(pt.value,t=>(f(),u(`div`,{key:t.agent.id,class:`detect-row-wrap`},[c(`div`,{class:E([`detect-row`,{"detect-row-pending":J.value.has(t.agent.id)}])},[c(`span`,{class:`detect-badge`,style:r({background:t.color,boxShadow:`0 0 8px `+t.color})},null,4),c(`span`,Sr,n(t.agent.name),1),c(`span`,{class:`detect-pill`,style:r({color:t.color})},n(t.statusLabel),5),c(`span`,{class:E([`agent-badge`,t.agent.drivable?`detect-driver-yes`:`detect-driver-no`])},n(t.agent.drivable?`RepoOS driver`:`detected only`),3),c(`span`,Cr,[t.agent.compatibility?(f(),u(`button`,{key:0,type:`button`,class:E([`detect-compat-icon`,{active:Qe.value===t.agent.id}]),style:r({color:yt(t.agent)}),"aria-label":`Compatibility details for ${t.agent.name}`,onClick:ee(e=>et(t.agent.id),[`stop`])},n(Ct(t.agent)),15,wr)):T(``,!0)]),c(`div`,Tr,[nt(t.agent).version?(f(),u(`span`,Er,n(nt(t.agent).version),1)):T(``,!0),t.agent.allBinaries&&t.agent.allBinaries.length>1?(f(),e(fe,{key:1,"model-value":String($e.value[t.agent.id]??0),"onUpdate:modelValue":e=>tt(t.agent.id,Number(e))},{default:v(()=>[s(me,{class:`detect-binary-select`,title:`${t.agent.allBinaries.length} copies found on PATH`},{default:v(()=>[s(_e)]),_:1},8,[`title`]),s(pe,{position:`popper`},{default:v(()=>[s(ge,{class:`detect-binary-viewport`},{default:v(()=>[(f(!0),u(w,null,o(t.agent.allBinaries,(t,r)=>(f(),e(he,{key:t.path,value:String(r),"text-value":`${t.name} ${t.version??`?`}`,class:`detect-binary-item`},{default:v(()=>[c(`span`,Dr,n(t.name),1),c(`span`,Or,n(t.version??`?`),1),c(`span`,kr,n(t.path),1)]),_:2},1032,[`value`,`text-value`]))),128))]),_:2},1024)]),_:2},1024)]),_:2},1032,[`model-value`,`onUpdate:modelValue`])):T(``,!0),J.value.has(t.agent.id)?(f(),u(`span`,Ar)):T(``,!0),t.agent.installed&&t.agent.update?(f(),u(`details`,jr,[c(`summary`,{style:r({color:vt(t.agent.update)})},n(_t(t.agent.update)),5),c(`span`,Mr,[t.agent.update.source?(f(),u(`span`,Nr,n(t.agent.update.source),1)):T(``,!0),wt(t.agent.update)?(f(),u(`span`,Pr,n(wt(t.agent.update)),1)):T(``,!0),t.agent.update.error?(f(),u(`span`,Fr,n(t.agent.update.error),1)):T(``,!0),t.agent.update.updateCommand?(f(),u(`button`,{key:3,class:`detect-copy`,onClick:e=>Tt(t.agent.update.updateCommand)},n(Z.value===t.agent.update.updateCommand?`copied`:`copy update command`),9,Ir)):T(``,!0)])])):T(``,!0),t.status===`auth`?(f(),u(`span`,Lr,[c(`code`,{class:`detect-hint-code`,title:t.agent.authHint||`sign in with the CLI`},n(t.agent.authHint||`sign in with the CLI`),9,Rr),t.agent.authHint?(f(),u(`button`,{key:0,class:`detect-copy`,onClick:e=>Tt(t.agent.authHint)},n(Z.value===t.agent.authHint?`copied`:`copy`),9,zr)):T(``,!0)])):t.status===`desktop`?(f(),u(`span`,Br,[c(`code`,{class:`detect-hint-code`,title:t.agent.installHint},n(t.agent.installHint),9,Vr),c(`button`,{class:`detect-copy`,onClick:e=>Tt(t.agent.installHint)},n(Z.value===t.agent.installHint?`copied`:`copy`),9,Hr)])):t.status===`missing`?(f(),u(`span`,Ur,[c(`code`,{class:`detect-hint-code`,title:t.agent.installHint},n(t.agent.installHint),9,Wr),c(`button`,{class:`detect-copy`,onClick:e=>Tt(t.agent.installHint)},n(Z.value===t.agent.installHint?`copied`:`copy`),9,Gr)])):T(``,!0),c(`button`,{type:`button`,class:E([`detect-star-btn`,{on:l(dt)(Q(t.agent))}]),"aria-pressed":l(dt)(Q(t.agent)),"aria-label":l(dt)(Q(t.agent))?`Remove ${t.agent.name} from favorites`:`Add ${t.agent.name} to favorites`,title:l(dt)(Q(t.agent))?`Remove from favorites`:`Add to favorites`,onClick:e=>l(ft)(Q(t.agent))},[s(l(L),{class:`size-3.5`,fill:l(dt)(Q(t.agent))?`currentColor`:`none`},null,8,[`fill`])],10,Kr)])],2),t.agent.compatibility&&Qe.value===t.agent.id?(f(),u(`div`,qr,[c(`div`,{class:`detect-compat-card-label`,style:r({color:yt(t.agent)})},n(t.agent.compatibility.label),5),c(`div`,Jr,n(St(t.agent)),1),xt(t.agent)?(f(),u(`div`,Yr,[c(`code`,Xr,n(bt(t.agent)),1),c(`button`,{class:`detect-copy`,onClick:e=>Tt(bt(t.agent))},n(Z.value===bt(t.agent)?`copied`:`copy`),9,Zr)])):t.agent.compatibility.status===`upgrade_recommended`?(f(),u(`div`,Qr,` upgrade recommended `)):t.agent.compatibility.status===`unsupported`?(f(),u(`div`,$r,` use a supported release `)):T(``,!0)])):T(``,!0)]))),128)):(f(),u(`div`,xr,` No known coding agents detected on PATH. `))],512)),[[b,M.value===`detected`]]),N.value?p((f(),e(Vt,{key:1,active:M.value===`playground`},null,8,[`active`])),[[b,M.value===`playground`]]):T(``,!0),P.value?p((f(),e(Xn,{key:2},null,512)),[[b,M.value===`providers`]]):T(``,!0)])],64)):(f(),u(`div`,rr)),s(se,{open:!!W.value,"onUpdate:open":a[2]||=e=>{e||(W.value=null)}},{default:v(()=>[s(oe),s(ae,{class:`am-modal`},{default:v(()=>[c(`div`,ei,[s(V,null,{default:v(()=>[t(`Skills for `+n(W.value?.name),1)]),_:1}),s(ie,{class:`close-x`},{default:v(()=>[...a[18]||=[t(`×`,-1)]]),_:1})]),s(B,{class:`am-modal-desc`},{default:v(()=>[...a[19]||=[t(`Choose preferred candidates for this agent. RepoOS still selects only task-relevant skills on each run.`,-1)]]),_:1}),W.value?(f(),u(`div`,ti,[(f(!0),u(w,null,o(l(h).agentsMeta.skills,e=>(f(),u(`label`,{key:e.path,class:`agent-skill-option`},[c(`input`,{type:`checkbox`,checked:(W.value.skills??[]).includes(e.name),onChange:t=>Ke(W.value,e.name,t.target.checked)},null,40,ni),c(`span`,null,[c(`strong`,null,n(e.name),1),e.description?(f(),u(`small`,ri,n(e.description),1)):T(``,!0)])]))),128))])):T(``,!0)]),_:1})]),_:1},8,[`open`])]))}});export{oi as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.built-in-interactive-hint[data-v-2ba6742c]{border:1px dashed var(--border-bright);color:var(--txt-secondary);border-radius:8px;align-items:center;gap:8px;padding:9px 12px;font-size:12.5px;line-height:1.4;display:flex}.built-in-interactive-dot[data-v-2ba6742c]{background:var(--green);width:8px;height:8px;box-shadow:0 0 8px var(--green);border-radius:50%;flex:none}.built-in-last-run[data-v-2ba6742c]{color:var(--txt-faint);font-family:JetBrains Mono,monospace;font-size:11px}.built-in-status-field[data-v-2ba6742c]{grid-column:1/-1}.built-in-status[data-v-2ba6742c]{border-radius:4px;margin-top:4px;padding:8px 12px;font-size:12px;line-height:1.3}.built-in-status.success[data-v-2ba6742c]{color:var(--green);background:#22c55e1a}.built-in-status.error[data-v-2ba6742c]{color:var(--red);background:#ef44441a}.built-in-autofixed[data-v-2ba6742c]{margin:6px 0 0;padding-left:16px;font-size:11.5px;line-height:1.5;list-style:outside}.built-in-autofixed code[data-v-2ba6742c]{color:var(--txt-secondary);font-family:JetBrains Mono,monospace}.built-in-task-link[data-v-2ba6742c]{margin-top:6px}.built-in-task-link a[data-v-2ba6742c]{color:var(--accent-foreground);font-size:12px;text-decoration:none}.built-in-task-link a[data-v-2ba6742c]:hover{text-decoration:underline}.built-in-run-doc[data-v-2ba6742c]{margin-top:6px}.built-in-run-doc a[data-v-2ba6742c]{color:var(--txt-secondary);font-family:JetBrains Mono,monospace;font-size:11.5px;text-decoration:none}.built-in-run-doc a[data-v-2ba6742c]:hover{text-decoration:underline}.playground[data-v-a40765cd]{gap:16px;height:100%;min-height:0;padding:16px 18px 20px;display:flex}.playground-sidebar[data-v-a40765cd]{flex-direction:column;flex:1 1 0;gap:10px;min-width:0;min-height:0;display:flex}.playground-sidebar-head[data-v-a40765cd]{justify-content:space-between;align-items:center;gap:8px;padding-bottom:2px;display:flex}.playground-filters[data-v-a40765cd]{flex-direction:column;flex:none;gap:8px;display:flex}.playground-filters input[data-v-a40765cd],.playground-filters select[data-v-a40765cd]{border:1px solid var(--border);background:var(--panel-solid);width:100%;color:var(--txt);font:12px var(--font-sans);border-radius:9px;outline:0;padding:7px 10px;transition:all .15s}.playground-filters input[data-v-a40765cd]:focus,.playground-filters select[data-v-a40765cd]:focus{border-color:var(--border-bright)}.playground-filters input[data-v-a40765cd]::placeholder{color:var(--txt-faint)}.playground-filter-row[data-v-a40765cd]{gap:8px;display:flex}.playground-filter-row select[data-v-a40765cd]{flex:1;min-width:0}.playground-list[data-v-a40765cd]{flex-direction:column;flex:1;gap:10px;min-height:0;padding-right:4px;display:flex;overflow-y:auto}.playground-no-match[data-v-a40765cd]{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.playground-filter-clear[data-v-a40765cd]{border:1px solid var(--border);background:var(--panel);color:var(--txt-dim);font:500 10.5px var(--font-sans);cursor:pointer;border-radius:8px;padding:4px 10px;transition:all .15s}.playground-filter-clear[data-v-a40765cd]:hover{border-color:var(--border-bright);color:var(--txt)}.playground-error[data-v-a40765cd],.playground-loading[data-v-a40765cd]{color:var(--txt-dim);padding:4px 2px;font-size:11.5px}.playground-provider-group[data-v-a40765cd]{flex-direction:column;gap:8px;display:flex}.playground-provider-label[data-v-a40765cd]{letter-spacing:.08em;text-transform:uppercase;color:var(--txt-faint);margin:4px 2px 0;font:600 10px JetBrains Mono,monospace}.playground-provider-error[data-v-a40765cd]{color:var(--amber);padding:0 2px;font-size:11px}.playground-skeletons[data-v-a40765cd]{flex-direction:column;gap:8px;display:flex}.playground-skeleton[data-v-a40765cd]{border:1px solid var(--border);background:var(--panel);border-radius:11px;flex-direction:column;gap:6px;padding:11px;display:flex}.playground-skeleton-line[data-v-a40765cd]{background:linear-gradient(90deg, var(--panel) 0%, var(--border) 50%, var(--panel) 100%);background-size:200% 100%;border-radius:5px;height:9px;animation:1.4s ease-in-out infinite playground-shimmer-a40765cd}.playground-skeleton-line.w-70[data-v-a40765cd]{width:70%}.playground-skeleton-line.w-90[data-v-a40765cd]{width:90%}.playground-skeleton-line.w-45[data-v-a40765cd]{width:45%}.playground-model-card[data-v-a40765cd]{text-align:left;border:1px solid var(--border);background:var(--panel);color:var(--txt);cursor:pointer;border-radius:11px;flex-direction:column;gap:4px;padding:10px 11px;transition:all .15s;display:flex}.playground-model-card[data-v-a40765cd]:hover{border-color:var(--border-bright)}.playground-model-card[data-v-a40765cd]:disabled{opacity:.5;cursor:default}.playground-model-card.active[data-v-a40765cd]{border-color:var(--cyan);box-shadow:var(--card-glow)}.playground-model-name[data-v-a40765cd]{font-size:12.5px;font-weight:600}.playground-model-reason[data-v-a40765cd]{color:var(--txt-dim);font-size:11px;line-height:1.4}.playground-model-meta[data-v-a40765cd]{color:var(--txt-faint);gap:10px;font:500 10px JetBrains Mono,monospace;display:flex}.playground-chat[data-v-a40765cd]{border:1px solid var(--border);background:var(--panel-solid);border-radius:14px;flex-direction:column;flex:1 1 0;min-width:0;min-height:0;display:flex;overflow:hidden}.playground-chat-head[data-v-a40765cd]{border-bottom:1px solid var(--border);background:var(--topbar-bg);align-items:center;gap:9px;padding:12px 14px;display:flex}.playground-active-dot[data-v-a40765cd]{background:var(--green);width:8px;height:8px;box-shadow:0 0 8px var(--green);border-radius:50%;flex:none}.playground-active-info[data-v-a40765cd]{flex-direction:column;gap:2px;min-width:0;display:flex}.playground-active-info strong[data-v-a40765cd]{letter-spacing:-.01em;text-overflow:ellipsis;white-space:nowrap;font-size:13px;overflow:hidden}.playground-active-info span[data-v-a40765cd]{color:var(--txt-dim);font:500 10px JetBrains Mono,monospace}.playground-clear[data-v-a40765cd]{border:1px solid var(--border);background:var(--panel);color:var(--txt-dim);font:500 10.5px var(--font-sans);cursor:pointer;border-radius:8px;flex:none;margin-left:auto;padding:5px 11px;transition:all .15s}.playground-clear[data-v-a40765cd]:hover{border-color:var(--border-bright);color:var(--txt)}.playground-clear[data-v-a40765cd]:disabled{opacity:.5;cursor:default}.playground-log-wrap[data-v-a40765cd]{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.playground-log[data-v-a40765cd]{flex:1;min-height:0;padding:16px;overflow-y:auto}.playground-empty[data-v-a40765cd]{color:var(--txt-dim);flex:1;place-items:center;padding:40px 16px;font-size:12.5px;display:grid}.playground-welcome[data-v-a40765cd]{text-align:center;color:var(--txt-dim);margin:auto 0;padding:22px 12px}.playground-welcome strong[data-v-a40765cd]{color:var(--txt);margin-bottom:6px;font-size:14px;display:block}.playground-welcome p[data-v-a40765cd]{max-width:320px;margin:0 auto;font-size:11.5px;line-height:1.55}.playground-starters[data-v-a40765cd]{flex-wrap:wrap;justify-content:center;gap:7px;margin-top:14px;display:flex}.playground-starters button[data-v-a40765cd]{border:1px solid var(--border);background:var(--panel);color:var(--txt-dim);font:500 10.5px var(--font-sans);cursor:pointer;border-radius:999px;padding:6px 10px}.playground-starters button[data-v-a40765cd]:hover{border-color:var(--border-bright);color:var(--txt)}.playground-row[data-v-a40765cd]{display:flex}.playground-row-user[data-v-a40765cd]{justify-content:flex-end}.playground-bubble[data-v-a40765cd]{overflow-wrap:anywhere;border-radius:13px;max-width:84%;padding:9px 11px;font-size:12.5px;line-height:1.55}.playground-bubble-user[data-v-a40765cd]{color:var(--btn-primary-color);background:var(--btn-primary-bg);border:1px solid var(--border-bright);border-bottom-right-radius:4px}.playground-bubble-assistant[data-v-a40765cd]{color:var(--txt);background:var(--panel);border:1px solid var(--border);border-bottom-left-radius:4px}.playground-markdown[data-v-a40765cd] p{margin:0 0 7px}.playground-markdown[data-v-a40765cd] p:last-child{margin-bottom:0}.playground-markdown[data-v-a40765cd] code{background:var(--md-body-bg);border-radius:4px;padding:1px 4px;font:10.5px JetBrains Mono,monospace}.playground-markdown[data-v-a40765cd] pre{background:var(--md-body-bg);border-radius:7px;margin:7px 0;padding:8px;overflow:auto}.playground-markdown[data-v-a40765cd] pre code{background:0 0;padding:0}.playground-send-error[data-v-a40765cd]{color:var(--red);align-self:center;font-size:11px}.playground-compose[data-v-a40765cd]{margin:12px}@keyframes playground-shimmer-a40765cd{0%{background-position:200% 0}to{background-position:-200% 0}}@media (width<=860px){.playground[data-v-a40765cd]{flex-direction:column;height:auto}.playground-sidebar[data-v-a40765cd]{max-height:320px}.playground-chat[data-v-a40765cd]{width:100%;min-height:420px}}@media (prefers-reduced-motion:reduce){.playground-skeleton-line[data-v-a40765cd]{animation:none}}.mp-panel[data-v-4d3be55f]{margin-bottom:16px;padding:0 18px 14px}.mp-row[data-v-4d3be55f]{border:1px solid var(--border);background:var(--panel-solid);border-radius:10px;padding:14px 16px}.mp-row+.mp-row[data-v-4d3be55f]{margin-top:12px}.mp-row-head[data-v-4d3be55f]{align-items:center;gap:10px;display:flex}.mp-row-title[data-v-4d3be55f]{align-items:center;gap:8px;min-width:0;display:flex}.mp-pill[data-v-4d3be55f]{letter-spacing:.07em;text-transform:uppercase;border:1px solid var(--border);color:var(--txt-dim);border-radius:999px;flex:none;padding:2px 7px;font:600 9px JetBrains Mono,monospace}.mp-pill.pill-live[data-v-4d3be55f]{color:var(--green);border-color:color-mix(in srgb, var(--green) 35%, transparent)}.mp-dash-link[data-v-4d3be55f]{color:var(--cyan);flex:none;margin-left:auto;font:500 10.5px JetBrains Mono,monospace;text-decoration:none}.mp-dash-link[data-v-4d3be55f]:hover{text-decoration:underline}.mp-note[data-v-4d3be55f]{color:var(--txt-dim);margin-top:2px;font-size:11px;line-height:1.5}.mp-key-form[data-v-4d3be55f]{flex-wrap:wrap;align-items:center;gap:8px;margin-top:10px;display:flex}.mp-key-form input[data-v-4d3be55f]{border:1px solid var(--border);background:var(--panel);min-width:0;color:var(--txt);font:12px var(--font-sans);border-radius:9px;outline:0;flex:220px;padding:7px 10px;transition:all .15s}.mp-key-form input[data-v-4d3be55f]:focus{border-color:var(--border-bright)}.mp-key-hint[data-v-4d3be55f]{color:var(--txt-faint);flex-basis:100%;font-size:10.5px}.mp-key-hint code[data-v-4d3be55f],.mp-error code[data-v-4d3be55f]{font:10px JetBrains Mono,monospace}.mp-data[data-v-4d3be55f]{flex-direction:column;gap:10px;margin-top:12px;display:flex}.mp-stat-hero[data-v-4d3be55f]{border:1px solid var(--border);background:var(--panel);border-radius:11px;align-items:baseline;gap:10px;padding:10px 12px;display:flex}.mp-stat-hero .mp-stat-value[data-v-4d3be55f]{font-size:20px}.mp-stat-sub[data-v-4d3be55f]{color:var(--txt-faint);font-size:10.5px}.mp-stat-row[data-v-4d3be55f]{flex-wrap:wrap;gap:8px;display:flex}.mp-stat[data-v-4d3be55f]{border:1px solid var(--border);background:var(--panel);border-radius:11px;flex-direction:column;gap:2px;min-width:90px;padding:8px 11px;display:flex}.mp-stat-value[data-v-4d3be55f]{color:var(--txt);font:600 13px JetBrains Mono,monospace}.mp-stat-value.sm[data-v-4d3be55f]{font-size:12.5px}.mp-stat-label[data-v-4d3be55f]{letter-spacing:.06em;text-transform:uppercase;color:var(--txt-faint);font:500 9.5px JetBrains Mono,monospace}.mp-window[data-v-4d3be55f]{border:1px solid var(--border);background:var(--panel);border-radius:11px;flex-direction:column;gap:6px;padding:10px 12px;display:flex}.mp-window-head[data-v-4d3be55f]{flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:8px;display:flex}.mp-window-pct[data-v-4d3be55f]{color:var(--txt-dim);font:500 10.5px JetBrains Mono,monospace}.mp-bar[data-v-4d3be55f]{background:var(--border);border-radius:999px;height:5px;overflow:hidden}.mp-bar-fill[data-v-4d3be55f]{background:var(--cyan);border-radius:999px;height:100%;transition:width .3s}.mp-window-reset[data-v-4d3be55f]{color:var(--txt-faint);font-size:10px}.mp-actions[data-v-4d3be55f]{flex-wrap:wrap;align-items:center;gap:6px;margin-top:10px;display:flex}.mp-as-of[data-v-4d3be55f]{color:var(--txt-dim);margin-right:2px;font-size:11.5px}.mp-refresh-ok[data-v-4d3be55f]{color:var(--green);display:inline-flex}.mp-loading[data-v-4d3be55f]{color:var(--txt-dim);margin-top:10px;font-size:11.5px}.mp-error[data-v-4d3be55f]{color:var(--red);margin-top:8px;font-size:11.5px}.mp-error .mp-retry[data-v-4d3be55f]{border:1px solid var(--border);background:var(--panel);color:var(--txt-dim);font:500 10.5px var(--font-sans);cursor:pointer;border-radius:7px;margin-left:6px;padding:2px 8px}.mp-error .mp-retry[data-v-4d3be55f]:hover{color:var(--txt);border-color:var(--border-bright)}.mp-part-error[data-v-4d3be55f]{color:var(--amber);font-size:11px}.mp-part-error a[data-v-4d3be55f]{color:inherit}@media (prefers-reduced-motion:reduce){.mp-bar-fill[data-v-4d3be55f]{transition:none}}
|
|
Binary file
|