@coreplane/switchboard 1.230.0 → 1.231.0
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/assets/package-lock.json +3 -3
- package/dist/assets/package.json +1 -1
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/core/coordinator/contract.ts +22 -14
- package/dist/assets/src/core/coordinator/driver.ts +4 -0
- package/dist/assets/src/core/ship/contract.ts +35 -29
- package/dist/assets/src/core/ship/coordinator.ts +89 -4
- package/dist/assets/web/dist/.vite/manifest.json +19 -19
- package/dist/assets/web/dist/assets/CostsPage-D-v8am88.js +2 -0
- package/dist/assets/web/dist/assets/{ResidentDetailPage-DYxDruS0.js → ResidentDetailPage-Df6D2emM.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentsIndexPage-DIBRBmuq.js → ResidentsIndexPage-B0yECe2z.js} +1 -1
- package/dist/assets/web/dist/assets/{RunRoutePage-B4s8hJlW.js → RunRoutePage-D4FG8JbC.js} +3 -3
- package/dist/assets/web/dist/assets/{RunsIndexPage-CaW07KOf.js → RunsIndexPage-qxjCAVwQ.js} +1 -1
- package/dist/assets/web/dist/assets/{ScheduledPage-Cr7269s9.js → ScheduledPage-B0xQSZIS.js} +1 -1
- package/dist/assets/web/dist/assets/{StatusDot-lCLi16zY.js → StatusDot-D-h9p7Iv.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-DKMPwNyy.js → Tooltip-BuDnXjL7.js} +1 -1
- package/dist/assets/web/dist/assets/{dist-DRkTB2rt.js → dist-BjLBNLkl.js} +1 -1
- package/dist/assets/web/dist/assets/{main-CXKOiCOK.js → main-BRrMt0Kr.js} +2 -2
- package/dist/cli.js +369 -219
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/CostsPage-B08bdD-1.js +0 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.231.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "switchboard",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.231.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"workspaces": [
|
|
12
12
|
"web",
|
|
@@ -20032,7 +20032,7 @@
|
|
|
20032
20032
|
},
|
|
20033
20033
|
"packages/switchboard": {
|
|
20034
20034
|
"name": "@coreplane/switchboard",
|
|
20035
|
-
"version": "1.
|
|
20035
|
+
"version": "1.231.0",
|
|
20036
20036
|
"license": "Apache-2.0",
|
|
20037
20037
|
"dependencies": {
|
|
20038
20038
|
"@earendil-works/pi-ai": "0.85.1",
|
package/dist/assets/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.231.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
|
|
6
6
|
"license": "Apache-2.0",
|
package/dist/assets/source.json
CHANGED
|
@@ -117,20 +117,23 @@ export interface CoordinatorInstance {
|
|
|
117
117
|
userName?: string;
|
|
118
118
|
channelId: string;
|
|
119
119
|
channelName?: string;
|
|
120
|
-
/** The requesting thread: where the card lives and where a
|
|
121
|
-
*
|
|
120
|
+
/** The requesting thread: where the card lives and where a generated plan's
|
|
121
|
+
* one unit runs; a seeded plan's units each open a thread of their own. */
|
|
122
122
|
threadKey: string;
|
|
123
123
|
sourceUrl?: string;
|
|
124
|
-
/** `owner/name`, and the head branch the pipeline works on (
|
|
125
|
-
*
|
|
124
|
+
/** `owner/name`, and the head branch the pipeline works on (the first unit's
|
|
125
|
+
* — each unit row names its own). */
|
|
126
126
|
repo: string;
|
|
127
127
|
branch: string;
|
|
128
128
|
/** The pull request's base branch, when the creator knew it. */
|
|
129
129
|
base?: string;
|
|
130
130
|
/** Epoch ms. */
|
|
131
131
|
createdAt: number;
|
|
132
|
-
/** The plan the instance runs
|
|
133
|
-
plan
|
|
132
|
+
/** The plan the instance runs: its id and, for a seeded plan, its path in
|
|
133
|
+
* the repository. A `plan` without a `path` is the generated one-unit plan a
|
|
134
|
+
* task request becomes — the mark that keeps its unit in the requesting
|
|
135
|
+
* thread (agent-ship item 16). */
|
|
136
|
+
plan?: { id: string; path?: string };
|
|
134
137
|
/** Who merges the units' pull requests: `runner` for a seeded plan (the
|
|
135
138
|
* `merge` step under `plan:merge`), `person` for a task. Written by the
|
|
136
139
|
* hand-off, answered by the plan route, checked at the merge door; absent
|
|
@@ -150,20 +153,21 @@ export interface CoordinatorInstance {
|
|
|
150
153
|
attempt?: number;
|
|
151
154
|
}
|
|
152
155
|
|
|
153
|
-
/** One unit of the plan an instance runs (a task string is a plan of
|
|
154
|
-
* `
|
|
155
|
-
* its thread, its pull request, the round boundaries the card
|
|
156
|
-
* ended. One row a person can read for "what happened to this
|
|
156
|
+
/** One unit of the plan an instance runs (a task string is a generated plan of
|
|
157
|
+
* one unit, `U1`): its branch, the units it waits on, and — as the runner
|
|
158
|
+
* reaches it — its thread, its pull request, the round boundaries the card
|
|
159
|
+
* drew and how it ended. One row a person can read for "what happened to this
|
|
160
|
+
* unit". */
|
|
157
161
|
export interface CoordinatorUnit {
|
|
158
162
|
instanceId: string;
|
|
159
|
-
/** `U<n>` as the plan spells it
|
|
163
|
+
/** `U<n>` as the plan spells it. */
|
|
160
164
|
unit: string;
|
|
161
165
|
slug: string;
|
|
162
166
|
title?: string;
|
|
163
|
-
/** `plan/<plan-id>/<unit-slug
|
|
167
|
+
/** `plan/<plan-id>/<unit-slug>` (a resume's is the pull request's own head branch). */
|
|
164
168
|
branch: string;
|
|
165
169
|
dependsOn: string[];
|
|
166
|
-
/** The unit's thread, once opened; a
|
|
170
|
+
/** The unit's thread, once opened; a generated plan's is the requesting thread from the start. */
|
|
167
171
|
threadKey?: string;
|
|
168
172
|
sourceUrl?: string;
|
|
169
173
|
/** The unit's review thread, opened once beside the unit's thread: every
|
|
@@ -214,7 +218,11 @@ export function isCoordinatorInstance(v: unknown): v is CoordinatorInstance {
|
|
|
214
218
|
if (typeof r.repo !== "string" || !REPO_SLUG.test(r.repo)) return false;
|
|
215
219
|
if (!isText(r.branch) || !isOptionalText(r.base)) return false;
|
|
216
220
|
if (!isFinite(r.createdAt)) return false;
|
|
217
|
-
if (
|
|
221
|
+
if (
|
|
222
|
+
r.plan !== undefined &&
|
|
223
|
+
!(isObject(r.plan) && isText(r.plan.id) && (r.plan.path === undefined || isText(r.plan.path, 1024)))
|
|
224
|
+
)
|
|
225
|
+
return false;
|
|
218
226
|
if (r.merge !== undefined && r.merge !== "runner" && r.merge !== "person") return false;
|
|
219
227
|
if (r.caps !== undefined && !(isObject(r.caps) && isFinite(r.caps.maxRounds) && isFinite(r.caps.maxMinutes)))
|
|
220
228
|
return false;
|
|
@@ -158,6 +158,8 @@ interface PlanFacts {
|
|
|
158
158
|
planId?: string;
|
|
159
159
|
/** Who merges, as the instance's field has it: the plan route answers it, `person` when absent. */
|
|
160
160
|
merge: "runner" | "person";
|
|
161
|
+
/** The instance's mark as the plan route answers it: a generated one-unit plan (a `plan` with no `path`). */
|
|
162
|
+
generated: boolean;
|
|
161
163
|
repo: string;
|
|
162
164
|
base: string;
|
|
163
165
|
caps: ShipCaps;
|
|
@@ -186,6 +188,7 @@ function readPlan(a: BotAnswer): PlanFacts {
|
|
|
186
188
|
return {
|
|
187
189
|
...(typeof b.planId === "string" ? { planId: b.planId } : {}),
|
|
188
190
|
merge: b.merge === "runner" ? "runner" : "person",
|
|
191
|
+
generated: b.generated === true,
|
|
189
192
|
repo: b.repo,
|
|
190
193
|
base: b.base,
|
|
191
194
|
caps: { maxRounds: b.caps.maxRounds, maxMinutes: b.caps.maxMinutes },
|
|
@@ -429,6 +432,7 @@ async function runUnit(
|
|
|
429
432
|
// seeded plan and `person` on a task, and the door re-checks it — the
|
|
430
433
|
// branch's name never decides.
|
|
431
434
|
merge: plan.merge,
|
|
435
|
+
generated: plan.generated,
|
|
432
436
|
...(resume !== undefined ? { resume } : {}),
|
|
433
437
|
},
|
|
434
438
|
start.at,
|
|
@@ -326,9 +326,30 @@ export function resolveSpecRow(ref: SpecItemRef, specMarkdown: string | undefine
|
|
|
326
326
|
|
|
327
327
|
// ---- the builders ----------------------------------------------------------------------------------
|
|
328
328
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
329
|
+
const TITLE_MAX = 80;
|
|
330
|
+
|
|
331
|
+
/** A unit's title from free text: its first non-blank line, cut to 80
|
|
332
|
+
* characters with an ellipsis — the one rule the hand-off's unit row and the
|
|
333
|
+
* generated contract share. */
|
|
334
|
+
export function unitTitleOf(text: string): string {
|
|
335
|
+
const firstLine =
|
|
336
|
+
text
|
|
337
|
+
.split("\n")
|
|
338
|
+
.find((l) => l.trim() !== "")
|
|
339
|
+
?.trim() ?? "";
|
|
340
|
+
return firstLine.length > TITLE_MAX ? `${firstLine.slice(0, TITLE_MAX - 1).trimEnd()}…` : firstLine;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/** A generated plan's one unit (agent-ship item 16): the text is the whole
|
|
344
|
+
* section under a `### <id>.` heading titled by its first line. Built, never
|
|
345
|
+
* parsed back out of markdown — a heading line inside the text is the text's
|
|
346
|
+
* own, not the end of the section. */
|
|
347
|
+
export function generatedUnit(id: string, text: string): ContractUnit {
|
|
348
|
+
const title = unitTitleOf(text);
|
|
349
|
+
return { id, title, section: `### ${id}. ${title}\n\n${text}`, bullets: {} };
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
interface ContractInputCommon {
|
|
332
353
|
/** The spec's text by file name (`resident-repos.md`); undefined when it is not there. */
|
|
333
354
|
readSpec: (spec: string) => string | undefined;
|
|
334
355
|
agentRules?: AgentRules;
|
|
@@ -337,8 +358,15 @@ export interface ContractFromPlanInput {
|
|
|
337
358
|
issue?: { repo: string; number: number };
|
|
338
359
|
}
|
|
339
360
|
|
|
361
|
+
/** The unit: parsed out of the plan's markdown by id (a seeded plan), or the
|
|
362
|
+
* unit itself when the caller already holds it (a generated plan's one unit,
|
|
363
|
+
* `generatedUnit`). */
|
|
364
|
+
export type ContractFromPlanInput = ContractInputCommon &
|
|
365
|
+
({ planMarkdown: string; unitId: string } | { unit: ContractUnit });
|
|
366
|
+
|
|
340
367
|
/** The contract for one unit of a plan. Throws when the plan has no such unit. */
|
|
341
368
|
export function contractFromPlan(input: ContractFromPlanInput): ChildContract {
|
|
369
|
+
if ("unit" in input) return contractOf(input.unit, input);
|
|
342
370
|
const unit = parsePlanUnit(input.planMarkdown, input.unitId);
|
|
343
371
|
if (!unit) {
|
|
344
372
|
const ids = planUnitIds(input.planMarkdown);
|
|
@@ -346,35 +374,13 @@ export function contractFromPlan(input: ContractFromPlanInput): ChildContract {
|
|
|
346
374
|
`the plan has no unit ${input.unitId} (its units: ${ids.length > 0 ? ids.join(", ") : "none — no `### U<n>.` heading"})`,
|
|
347
375
|
);
|
|
348
376
|
}
|
|
349
|
-
return
|
|
350
|
-
unit,
|
|
351
|
-
specRows: specItemRefs(unit.section).map((ref) => resolveSpecRow(ref, input.readSpec(ref.spec))),
|
|
352
|
-
agentRules: input.agentRules,
|
|
353
|
-
guards: GUARDS,
|
|
354
|
-
rebase: { branch: input.rebase?.branch, onto: input.rebase?.onto },
|
|
355
|
-
issue: input.issue,
|
|
356
|
-
};
|
|
377
|
+
return contractOf(unit, input);
|
|
357
378
|
}
|
|
358
379
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
/** The compatibility path record 0031 names: a task string is a plan of one
|
|
362
|
-
* unit with no spec rows. The task is the unit's whole section. */
|
|
363
|
-
export function contractFromTask(input: {
|
|
364
|
-
task: string;
|
|
365
|
-
agentRules?: AgentRules;
|
|
366
|
-
rebase?: { branch?: string; onto?: string };
|
|
367
|
-
issue?: { repo: string; number: number };
|
|
368
|
-
}): ChildContract {
|
|
369
|
-
const firstLine =
|
|
370
|
-
input.task
|
|
371
|
-
.split("\n")
|
|
372
|
-
.find((l) => l.trim() !== "")
|
|
373
|
-
?.trim() ?? "";
|
|
374
|
-
const title = firstLine.length > TITLE_MAX ? `${firstLine.slice(0, TITLE_MAX - 1).trimEnd()}…` : firstLine;
|
|
380
|
+
function contractOf(unit: ContractUnit, input: ContractInputCommon): ChildContract {
|
|
375
381
|
return {
|
|
376
|
-
unit
|
|
377
|
-
specRows:
|
|
382
|
+
unit,
|
|
383
|
+
specRows: specItemRefs(unit.section).map((ref) => resolveSpecRow(ref, input.readSpec(ref.spec))),
|
|
378
384
|
agentRules: input.agentRules,
|
|
379
385
|
guards: GUARDS,
|
|
380
386
|
rebase: { branch: input.rebase?.branch, onto: input.rebase?.onto },
|
|
@@ -139,6 +139,85 @@ export function planInstanceId(planId: string, attempt = 1): string {
|
|
|
139
139
|
return `${base.slice(0, INSTANCE_ID_MAX - suffix.length)}${suffix}`;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
// A compact sha-256 (FIPS 180-4) in plain TypeScript: this module is imported
|
|
143
|
+
// by the shim Worker, whose runtime has no `node:crypto`, so the generated
|
|
144
|
+
// plan id's hash cannot come from the Node API the preflight once used.
|
|
145
|
+
function sha256Hex(text: string): string {
|
|
146
|
+
const K = new Uint32Array([
|
|
147
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,
|
|
148
|
+
0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
|
149
|
+
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8,
|
|
150
|
+
0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
151
|
+
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
|
|
152
|
+
0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
|
153
|
+
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
|
|
154
|
+
0xc67178f2,
|
|
155
|
+
]);
|
|
156
|
+
const h = new Uint32Array([
|
|
157
|
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
|
158
|
+
]);
|
|
159
|
+
const bytes = new TextEncoder().encode(text);
|
|
160
|
+
const padded = new Uint8Array((((bytes.length + 8) >> 6) << 6) + 64);
|
|
161
|
+
padded.set(bytes);
|
|
162
|
+
padded[bytes.length] = 0x80;
|
|
163
|
+
new DataView(padded.buffer).setBigUint64(padded.length - 8, BigInt(bytes.length) * 8n);
|
|
164
|
+
const w = new Uint32Array(64);
|
|
165
|
+
const rotr = (x: number, n: number) => (x >>> n) | (x << (32 - n));
|
|
166
|
+
const view = new DataView(padded.buffer);
|
|
167
|
+
for (let i = 0; i < padded.length; i += 64) {
|
|
168
|
+
for (let t = 0; t < 16; t++) w[t] = view.getUint32(i + t * 4);
|
|
169
|
+
for (let t = 16; t < 64; t++) {
|
|
170
|
+
const s0 = rotr(w[t - 15]!, 7) ^ rotr(w[t - 15]!, 18) ^ (w[t - 15]! >>> 3);
|
|
171
|
+
const s1 = rotr(w[t - 2]!, 17) ^ rotr(w[t - 2]!, 19) ^ (w[t - 2]! >>> 10);
|
|
172
|
+
w[t] = (w[t - 16]! + s0 + w[t - 7]! + s1) >>> 0;
|
|
173
|
+
}
|
|
174
|
+
let [a, b, c, d, e, f, g, hh] = [h[0]!, h[1]!, h[2]!, h[3]!, h[4]!, h[5]!, h[6]!, h[7]!];
|
|
175
|
+
for (let t = 0; t < 64; t++) {
|
|
176
|
+
const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
177
|
+
const ch = (e & f) ^ (~e & g);
|
|
178
|
+
const t1 = (hh + S1 + ch + K[t]! + w[t]!) >>> 0;
|
|
179
|
+
const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
180
|
+
const maj = (a & b) ^ (a & c) ^ (b & c);
|
|
181
|
+
const t2 = (S0 + maj) >>> 0;
|
|
182
|
+
hh = g;
|
|
183
|
+
g = f;
|
|
184
|
+
f = e;
|
|
185
|
+
e = (d + t1) >>> 0;
|
|
186
|
+
d = c;
|
|
187
|
+
c = b;
|
|
188
|
+
b = a;
|
|
189
|
+
a = (t1 + t2) >>> 0;
|
|
190
|
+
}
|
|
191
|
+
h[0] = (h[0]! + a) >>> 0;
|
|
192
|
+
h[1] = (h[1]! + b) >>> 0;
|
|
193
|
+
h[2] = (h[2]! + c) >>> 0;
|
|
194
|
+
h[3] = (h[3]! + d) >>> 0;
|
|
195
|
+
h[4] = (h[4]! + e) >>> 0;
|
|
196
|
+
h[5] = (h[5]! + f) >>> 0;
|
|
197
|
+
h[6] = (h[6]! + g) >>> 0;
|
|
198
|
+
h[7] = (h[7]! + hh) >>> 0;
|
|
199
|
+
}
|
|
200
|
+
return [...h].map((x) => x.toString(16).padStart(8, "0")).join("");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** The generated plan's id (agent-ship item 16): `<slug>-<hash>` — the slug
|
|
204
|
+
* from the request text (24 characters in the branch alphabet, the bound the
|
|
205
|
+
* ship branch namer used), the hash the first six hex of the sha256 of the
|
|
206
|
+
* thread key, a newline and the normalised request text. Byte-identical text
|
|
207
|
+
* in the same thread is the same plan; a rephrase, however it starts, is a
|
|
208
|
+
* new one; two threads never share an id. Always fits `PLAN_ID_PATTERN`. */
|
|
209
|
+
export function generatedPlanId(text: string, threadKey: string): string {
|
|
210
|
+
const normalised = text.toLowerCase().replace(/\s+/g, " ").trim();
|
|
211
|
+
const slug =
|
|
212
|
+
normalised
|
|
213
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
214
|
+
.replace(/^-+|-+$/g, "")
|
|
215
|
+
.slice(0, SLUG_MAX)
|
|
216
|
+
.replace(/-+$/, "") || "task";
|
|
217
|
+
const hash = sha256Hex(`${threadKey}\n${normalised}`).slice(0, 6);
|
|
218
|
+
return `${slug}-${hash}`;
|
|
219
|
+
}
|
|
220
|
+
|
|
142
221
|
/** The Dependencies bullet's unit ids — lists, `to` ranges — the unit itself excluded. */
|
|
143
222
|
function dependenciesOf(text: string, self: string): string[] {
|
|
144
223
|
const out: string[] = [];
|
|
@@ -428,6 +507,10 @@ export interface UnitPipelineInput {
|
|
|
428
507
|
* `runner` (a seeded plan, under its grant) or `person` (a task, or a
|
|
429
508
|
* record without the field). */
|
|
430
509
|
merge: "runner" | "person";
|
|
510
|
+
/** The instance's mark (agent-ship item 16): a generated one-unit plan — a
|
|
511
|
+
* `plan` with an id and no `path` — whose unit runs in the requesting
|
|
512
|
+
* thread and is re-issued with the request's own text, never a plan path. */
|
|
513
|
+
generated: boolean;
|
|
431
514
|
/** Resume at review: an open pull request of ship's own the requester named. */
|
|
432
515
|
resume?: { pr: number; headSha?: string; url?: string };
|
|
433
516
|
}
|
|
@@ -1082,10 +1165,12 @@ export function renderUnitReport(s: UnitPipelineState): string {
|
|
|
1082
1165
|
const rounds = `${e.reviewRounds} review round${e.reviewRounds === 1 ? "" : "s"}`;
|
|
1083
1166
|
const prUrl = s.pr?.url;
|
|
1084
1167
|
const prLine = prUrl ? ` PR: ${prUrl}` : "";
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1168
|
+
// The re-issue line keys on the instance's mark, never on who merges: a
|
|
1169
|
+
// generated plan is re-issued with the request's own text, a seeded one by
|
|
1170
|
+
// its plan path — and a seeded plan can be a person's merge too.
|
|
1171
|
+
const reissue = s.input.generated
|
|
1172
|
+
? `To continue, re-issue \`agent:ship\` in this thread with the same text${prUrl ? ` and include the PR URL (${prUrl})` : " — include the PR URL if a PR exists"}.`
|
|
1173
|
+
: `The unit's dependents in this plan stay blocked; the unit runs again when the plan is re-issued.`;
|
|
1089
1174
|
const declined = [...(s.dispositionsByRound[e.reviewRounds - 1] ?? [])].filter((d) => d.disposition === "declined");
|
|
1090
1175
|
const declinedLine = `Declined findings: ${declined.length > 0 ? declined.map((d) => `${d.findingId}${d.note ? ` — ${d.note}` : ""}`).join("; ") : "none"}`;
|
|
1091
1176
|
const verdictLine = `Verdict: LGTM${s.lastVerdictSummary ? ` — ${s.lastVerdictSummary}` : ""}`;
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"src": "../node_modules/@fontsource-variable/jetbrains-mono/files/jetbrains-mono-vietnamese-wght-normal.woff2"
|
|
29
29
|
},
|
|
30
30
|
"../node_modules/@pierre/diffs/dist/index.js": {
|
|
31
|
-
"file": "assets/dist-
|
|
31
|
+
"file": "assets/dist-BjLBNLkl.js",
|
|
32
32
|
"name": "dist",
|
|
33
33
|
"src": "../node_modules/@pierre/diffs/dist/index.js",
|
|
34
34
|
"isDynamicEntry": true,
|
|
@@ -2562,16 +2562,16 @@
|
|
|
2562
2562
|
"_seed-DeKSHrt2.js"
|
|
2563
2563
|
]
|
|
2564
2564
|
},
|
|
2565
|
-
"_StatusDot-
|
|
2566
|
-
"file": "assets/StatusDot-
|
|
2565
|
+
"_StatusDot-D-h9p7Iv.js": {
|
|
2566
|
+
"file": "assets/StatusDot-D-h9p7Iv.js",
|
|
2567
2567
|
"name": "StatusDot",
|
|
2568
2568
|
"imports": [
|
|
2569
2569
|
"_seed-DeKSHrt2.js",
|
|
2570
|
-
"_Tooltip-
|
|
2570
|
+
"_Tooltip-BuDnXjL7.js"
|
|
2571
2571
|
]
|
|
2572
2572
|
},
|
|
2573
|
-
"_Tooltip-
|
|
2574
|
-
"file": "assets/Tooltip-
|
|
2573
|
+
"_Tooltip-BuDnXjL7.js": {
|
|
2574
|
+
"file": "assets/Tooltip-BuDnXjL7.js",
|
|
2575
2575
|
"name": "Tooltip",
|
|
2576
2576
|
"imports": [
|
|
2577
2577
|
"_AppShell-lYVcj-k7.js",
|
|
@@ -2789,7 +2789,7 @@
|
|
|
2789
2789
|
]
|
|
2790
2790
|
},
|
|
2791
2791
|
"src/main.ts": {
|
|
2792
|
-
"file": "assets/main-
|
|
2792
|
+
"file": "assets/main-BRrMt0Kr.js",
|
|
2793
2793
|
"name": "main",
|
|
2794
2794
|
"src": "src/main.ts",
|
|
2795
2795
|
"isEntry": true,
|
|
@@ -2820,7 +2820,7 @@
|
|
|
2820
2820
|
]
|
|
2821
2821
|
},
|
|
2822
2822
|
"src/pages/CostsPage.vue": {
|
|
2823
|
-
"file": "assets/CostsPage-
|
|
2823
|
+
"file": "assets/CostsPage-D-v8am88.js",
|
|
2824
2824
|
"name": "CostsPage",
|
|
2825
2825
|
"src": "src/pages/CostsPage.vue",
|
|
2826
2826
|
"isDynamicEntry": true,
|
|
@@ -2841,19 +2841,19 @@
|
|
|
2841
2841
|
]
|
|
2842
2842
|
},
|
|
2843
2843
|
"src/pages/ResidentDetailPage.vue": {
|
|
2844
|
-
"file": "assets/ResidentDetailPage-
|
|
2844
|
+
"file": "assets/ResidentDetailPage-Df6D2emM.js",
|
|
2845
2845
|
"name": "ResidentDetailPage",
|
|
2846
2846
|
"src": "src/pages/ResidentDetailPage.vue",
|
|
2847
2847
|
"isDynamicEntry": true,
|
|
2848
2848
|
"imports": [
|
|
2849
2849
|
"_AppShell-lYVcj-k7.js",
|
|
2850
2850
|
"_seed-DeKSHrt2.js",
|
|
2851
|
-
"_StatusDot-
|
|
2851
|
+
"_StatusDot-D-h9p7Iv.js",
|
|
2852
2852
|
"_residentDiskBudget-BMBKlYRH.js"
|
|
2853
2853
|
]
|
|
2854
2854
|
},
|
|
2855
2855
|
"src/pages/ResidentsIndexPage.vue": {
|
|
2856
|
-
"file": "assets/ResidentsIndexPage-
|
|
2856
|
+
"file": "assets/ResidentsIndexPage-B0yECe2z.js",
|
|
2857
2857
|
"name": "ResidentsIndexPage",
|
|
2858
2858
|
"src": "src/pages/ResidentsIndexPage.vue",
|
|
2859
2859
|
"isDynamicEntry": true,
|
|
@@ -2861,20 +2861,20 @@
|
|
|
2861
2861
|
"_AppShell-lYVcj-k7.js",
|
|
2862
2862
|
"_seed-DeKSHrt2.js",
|
|
2863
2863
|
"_wallClock-61NpVkY6.js",
|
|
2864
|
-
"_StatusDot-
|
|
2864
|
+
"_StatusDot-D-h9p7Iv.js",
|
|
2865
2865
|
"_residentDiskBudget-BMBKlYRH.js",
|
|
2866
2866
|
"_indexFormat-B-pd4r7Y.js"
|
|
2867
2867
|
]
|
|
2868
2868
|
},
|
|
2869
2869
|
"src/pages/RunRoutePage.vue": {
|
|
2870
|
-
"file": "assets/RunRoutePage-
|
|
2870
|
+
"file": "assets/RunRoutePage-D4FG8JbC.js",
|
|
2871
2871
|
"name": "RunRoutePage",
|
|
2872
2872
|
"src": "src/pages/RunRoutePage.vue",
|
|
2873
2873
|
"isDynamicEntry": true,
|
|
2874
2874
|
"imports": [
|
|
2875
2875
|
"_AppShell-lYVcj-k7.js",
|
|
2876
2876
|
"_seed-DeKSHrt2.js",
|
|
2877
|
-
"_Tooltip-
|
|
2877
|
+
"_Tooltip-BuDnXjL7.js",
|
|
2878
2878
|
"src/main.ts",
|
|
2879
2879
|
"_wallClock-61NpVkY6.js",
|
|
2880
2880
|
"_NotFoundPage-BzWS4Ca1.js",
|
|
@@ -2890,31 +2890,31 @@
|
|
|
2890
2890
|
]
|
|
2891
2891
|
},
|
|
2892
2892
|
"src/pages/RunsIndexPage.vue": {
|
|
2893
|
-
"file": "assets/RunsIndexPage-
|
|
2893
|
+
"file": "assets/RunsIndexPage-qxjCAVwQ.js",
|
|
2894
2894
|
"name": "RunsIndexPage",
|
|
2895
2895
|
"src": "src/pages/RunsIndexPage.vue",
|
|
2896
2896
|
"isDynamicEntry": true,
|
|
2897
2897
|
"imports": [
|
|
2898
2898
|
"_AppShell-lYVcj-k7.js",
|
|
2899
2899
|
"_seed-DeKSHrt2.js",
|
|
2900
|
-
"_Tooltip-
|
|
2900
|
+
"_Tooltip-BuDnXjL7.js",
|
|
2901
2901
|
"_wallClock-61NpVkY6.js",
|
|
2902
2902
|
"_RunsTabs-DEICQ4FY.js",
|
|
2903
|
-
"_StatusDot-
|
|
2903
|
+
"_StatusDot-D-h9p7Iv.js",
|
|
2904
2904
|
"_indexFormat-B-pd4r7Y.js",
|
|
2905
2905
|
"_favicon-CWPcvWvp.js",
|
|
2906
2906
|
"_localIso-L06jV29p.js"
|
|
2907
2907
|
]
|
|
2908
2908
|
},
|
|
2909
2909
|
"src/pages/ScheduledPage.vue": {
|
|
2910
|
-
"file": "assets/ScheduledPage-
|
|
2910
|
+
"file": "assets/ScheduledPage-B0xQSZIS.js",
|
|
2911
2911
|
"name": "ScheduledPage",
|
|
2912
2912
|
"src": "src/pages/ScheduledPage.vue",
|
|
2913
2913
|
"isDynamicEntry": true,
|
|
2914
2914
|
"imports": [
|
|
2915
2915
|
"_AppShell-lYVcj-k7.js",
|
|
2916
2916
|
"_seed-DeKSHrt2.js",
|
|
2917
|
-
"_Tooltip-
|
|
2917
|
+
"_Tooltip-BuDnXjL7.js",
|
|
2918
2918
|
"_wallClock-61NpVkY6.js",
|
|
2919
2919
|
"_RunsTabs-DEICQ4FY.js",
|
|
2920
2920
|
"_indexFormat-B-pd4r7Y.js",
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./AppShell-lYVcj-k7.js";import{Ci as t,Lr as n,Lt as r,Vt as i,Xt as a,_n as o,ci as s,cn as c,gn as l,ir as u,ln as d,on as f,r as p,sn as m,un as h,ur as g,vi as _,wi as v,xi as y,yn as b,zr as x}from"./seed-DeKSHrt2.js";var S=`Durable Objects`,C=`Workers · storage · R2`,w=`LLM (Anthropic)`,T=(e,t=2)=>`$${e.toFixed(t)}`,E=e=>e.workersUsd+e.doRowsUsd+e.doStorageUsd+e.r2Usd+e.workflowsUsd;function D(e){let t=[];for(let n of e.days)for(let e of Object.keys(n.containers))t.includes(e)||t.push(e);return e.days.some(e=>Object.keys(e.durableObjects).length>0)&&t.push(S),e.days.some(e=>E(e)>0)&&t.push(C),e.llmAvailable&&t.push(w),t}function O(e,t){return t===`Durable Objects`?Object.values(e.durableObjects).reduce((e,t)=>e+t,0)+e.doRequestsUsd:t===`Workers · storage · R2`?E(e):t===`LLM (Anthropic)`?e.llmUsd:e.containers[t]?.total??0}var k=30.4;function ee(e){let t=e.range.partialLastDay?e.days.slice(0,-1):e.days,n=e.range.partialLastDay?e.days[e.days.length-1]:void 0,r=t[t.length-1],i=t.slice(-7),a=i.length?i.reduce((e,t)=>e+t.total,0)/i.length:void 0,o=e.account.cloudUsd>0?Math.round(e.totals.cloudUsd/e.account.cloudUsd*100):0;return{...r?{yesterday:{date:r.date,total:r.total}}:{},...n?{today:{date:n.date,total:n.total}}:{},...a===void 0?{}:{avg7:a},projection:M(e,t,n),llm:{range:e.totals.llmUsd,...r?{yesterday:r.llmUsd}:{},...n?{today:{usd:n.llmUsd,estimated:n.llmEstimated}}:{}},accountShare:o}}var A=e=>e.reduce((e,t)=>e+t,0)/e.length;function j(e,t){let n=Date.parse(`${t.date}T00:00:00Z`),r=(e.generatedAt-n)/864e5;return Math.min(1,Math.max(1/24,Number.isFinite(r)?r:1))}function M(e,t,n){let r=n?j(e,n):1,i=t.slice(-7),a=0,o=`full-days`;i.length?a=A(i.map(e=>e.cloudUsd)):n&&(a=n.cloudUsd/r,o=`today`);let s=0,c=`none`,l=0;if(e.llmAvailable){let e=t.findIndex(e=>e.llmUsd>0),i=e===-1?[]:t.slice(e).slice(-7);i.length?(s=A(i.map(e=>e.llmUsd)),c=`closed-days`,l=i.length):n&&n.llmUsd>0&&(s=n.llmUsd/r,c=`today`)}return{monthUsd:(a+s)*k,cloudRate:a,llmRate:s,cloudBasis:o,llmBasis:c,llmClosedDays:l}}function te(e){let t=`https://dash.cloudflare.com/${e.account.id}`;return{account:t,billing:`${t}/billing`,containers:`${t}/workers/containers`,durableObjects:`${t}/workers/durable-objects`,workers:`${t}/workers-and-pages`,r2:`${t}/r2/overview`,workflows:`${t}/workers/workflows`,worker:e=>`${t}/workers/services/view/${encodeURIComponent(e)}/production/metrics`,bucket:e=>`${t}/r2/default/buckets/${encodeURIComponent(e)}`,anthropic:`https://platform.claude.com/cost`}}var ne=e=>e.account.name??`${e.account.id.slice(0,8)}…`;function N(e,t,n){let r=[`${e.date} · total ${T(e.total)}${n?` (partial day)`:``}`];for(let n of t){let t=O(e,n);t<=0||r.push(`${n} ${T(t)}${n===`LLM (Anthropic)`&&e.llmEstimated?` (estimate)`:``}`)}return r.join(`
|
|
2
|
+
`)}function P(e){let t=new Date(`${e}T00:00:00Z`);return Number.isNaN(t.getTime())?e:`${[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`][t.getUTCMonth()]} ${t.getUTCDate()}`}function F(e,t,n){let r=t.map(t=>({series:t,usd:O(e,t),estimated:t===`LLM (Anthropic)`&&e.llmEstimated})).filter(e=>e.usd>0).sort((e,t)=>t.usd-e.usd);return{date:e.date,label:P(e.date),partial:n,total:e.total,rows:r}}function I(e,t){let n={t:12,r:12,b:30,l:48},r=960-n.l-n.r,i=260-n.t-n.b,a=e.days,o=Math.max(1e-9,...a.map(e=>e.total))*1.08,s=r/Math.max(1,a.length),c=Math.min(10,s*.28),l=e=>n.t+i-e/o*i,u=Array.from({length:5},(e,t)=>{let n=o/4*t;return{y:Number(l(n).toFixed(1)),label:T(n)}}),d=[],f=[],p=[];return a.forEach((r,o)=>{let u=0,m=n.l+o*s+c/2,h=s-c;f.push({x:Number((n.l+o*s).toFixed(1)),y:n.t,width:Number(s.toFixed(1)),height:i,title:N(r,t,e.range.partialLastDay&&o===a.length-1),tip:F(r,t,e.range.partialLastDay&&o===a.length-1)}),t.forEach((e,t)=>{let n=O(r,e);if(n<=0)return;let i=l(u+n),a=l(u),o=Math.max(0,a-i-2);d.push({seriesIndex:t,x:Number(m.toFixed(1)),y:Number(i.toFixed(1)),width:Number(h.toFixed(1)),height:Number(o.toFixed(1))}),u+=n}),(a.length<=16||o%Math.ceil(a.length/16)===0)&&p.push({x:Number((m+h/2).toFixed(1)),label:r.date.slice(5)})}),{width:960,height:260,gridLines:u,segments:d,dayHovers:f,dayLabels:p,axisY:Number(l(0).toFixed(1)),marginLeft:n.l,marginRight:n.r}}function re(e){let t=e.totals.byResource,n=[[`Memory (provisioned while awake)`,t.memory],[`vCPU (active use only)`,t.cpu],[`Durable Object duration + requests`,t.durableObjects],[`Disk (provisioned while awake)`,t.disk],[`Workers requests + CPU`,t.workers],[`Durable Object SQLite rows`,t.doRows],[`Durable Object SQLite storage`,t.doStorage],[`R2 storage + operations`,t.r2],[`Workflow steps + state`,t.workflows]],r=n.reduce((e,t)=>e+t[1],0)||1;return n.map(([e,t])=>({label:e,usd:t,percent:t/r*100}))}var L=[`fill-[#4478b8] dark:fill-[#7aa7e0]`,`fill-[#c8823b] dark:fill-[#e0a95a]`,`fill-[#4c8c57] dark:fill-[#6fae7a]`,`fill-[#b8963e] dark:fill-[#d4b45a]`,`fill-[#b0568c] dark:fill-[#d489b8]`,`fill-[#6b7bcc] dark:fill-[#98a5e6]`,`fill-[#d05252] dark:fill-[#e07a74]`,`fill-[#3e8e96] dark:fill-[#6fb9c0]`],R=[`bg-[#4478b8] dark:bg-[#7aa7e0]`,`bg-[#c8823b] dark:bg-[#e0a95a]`,`bg-[#4c8c57] dark:bg-[#6fae7a]`,`bg-[#b8963e] dark:bg-[#d4b45a]`,`bg-[#b0568c] dark:bg-[#d489b8]`,`bg-[#6b7bcc] dark:bg-[#98a5e6]`,`bg-[#d05252] dark:bg-[#e07a74]`,`bg-[#3e8e96] dark:bg-[#6fb9c0]`],z={class:`overflow-x-auto`},B=[`viewBox`],V=[`x1`,`x2`,`y1`,`y2`],H=[`x`,`y`],U=[`x`,`y`,`width`,`height`],W=[`aria-label`,`x`,`y`,`width`,`height`,`onPointerenter`,`onPointermove`],G=[`x`,`y`],K=[`x1`,`x2`,`y1`,`y2`],q={class:`tip-head mb-1.5 flex items-baseline justify-between gap-3 border-b border-muted pb-1.5`},J={class:`font-medium text-highlighted`},Y={key:0,class:`ml-1.5 font-normal text-dimmed`},X={class:`font-medium text-highlighted`},ie={class:`tip-name truncate text-muted`},ae={class:`text-highlighted`},oe={class:`tip-usd`},se={key:0,class:`ml-1 text-dimmed`},Z=256,Q=12,ce=b({__name:`CostChart`,props:{report:{},series:{}},setup(e){let n=e,r=f(()=>I(n.report,n.series)),i=e=>44+e*20,o=s(null),c=s(null);function p(e,t){let n=c.value,r=n?.getBoundingClientRect(),a=t.clientX-(r?.left??0),s=t.clientY-(r?.top??0),l=n?.clientWidth??0,u=n?.clientHeight??0,d=i(e.tip.rows.length),f=l>0&&a+Q+Z>l,p=u>0&&s+Q+d>u;o.value={x:Math.max(0,f?a-Q-Z:a+Q),y:Math.max(0,p?s-Q-d:s+Q),data:e.tip}}return(e,n)=>(u(),h(`div`,{ref_key:`host`,ref:c,class:`chart-host relative`},[m(`div`,z,[(u(),h(`svg`,{class:`block h-auto w-full font-mono`,viewBox:`0 0 ${r.value.width} ${r.value.height}`,role:`img`,"aria-label":`Daily cost, stacked by component`},[(u(!0),h(a,null,g(r.value.gridLines,(e,t)=>(u(),h(a,{key:`g${t}`},[m(`line`,{class:`stroke-(--ui-border-muted)`,x1:r.value.marginLeft,x2:r.value.width-r.value.marginRight,y1:e.y,y2:e.y},null,8,V),m(`text`,{class:`fill-(--ui-text-dimmed) text-[11px] tabular-nums`,x:r.value.marginLeft-8,y:e.y+4,"text-anchor":`end`},v(e.label),9,H)],64))),128)),(u(!0),h(a,null,g(r.value.segments,(e,t)=>(u(),h(`rect`,{key:`s${t}`,class:y([`seg hover:opacity-85`,_(L)[e.seriesIndex%_(L).length]]),x:e.x,y:e.y,width:e.width,height:e.height},null,10,U))),128)),(u(!0),h(a,null,g(r.value.dayHovers,(e,t)=>(u(),h(`rect`,{key:`h${t}`,class:`day fill-transparent`,role:`img`,"aria-label":e.title,x:e.x,y:e.y,width:e.width,height:e.height,onPointerenter:t=>p(e,t),onPointermove:t=>p(e,t),onPointerleave:n[0]||=e=>o.value=null},null,40,W))),128)),(u(!0),h(a,null,g(r.value.dayLabels,(e,t)=>(u(),h(`text`,{key:`d${t}`,class:`fill-(--ui-text-dimmed) text-[11px]`,x:e.x,y:r.value.height-10,"text-anchor":`middle`},v(e.label),9,G))),128)),m(`line`,{class:`stroke-(--ui-border)`,x1:r.value.marginLeft,x2:r.value.width-r.value.marginRight,y1:r.value.axisY,y2:r.value.axisY},null,8,K)],8,B))]),o.value?(u(),h(`div`,{key:0,class:`chart-tip pointer-events-none absolute z-10 w-64 rounded-md border border-default bg-elevated px-3 py-2 font-mono text-xs tabular-nums whitespace-nowrap shadow-lg`,role:`tooltip`,style:t({left:`${o.value.x}px`,top:`${o.value.y}px`})},[m(`div`,q,[m(`span`,J,[l(v(o.value.data.label),1),o.value.data.partial?(u(),h(`span`,Y,`partial day`)):d(``,!0)]),m(`span`,X,v(_(T)(o.value.data.total)),1)]),(u(!0),h(a,null,g(o.value.data.rows,e=>(u(),h(`div`,{key:e.series,class:`tip-row flex items-baseline justify-between gap-3 leading-5`},[m(`span`,ie,v(e.series),1),m(`span`,ae,[m(`span`,oe,v(_(T)(e.usd)),1),e.estimated?(u(),h(`span`,se,`est.`)):d(``,!0)])]))),128))],4)):d(``,!0)],512))}}),le={class:`by-user grid gap-3`},ue={class:`flex flex-wrap items-center gap-x-4 gap-y-2`},de={class:`flex items-center gap-2 text-sm text-muted`},fe=[`title`],pe=[`disabled`,`aria-describedby`],me={key:0,id:`me-hint`,class:`me-hint text-xs text-dimmed`},he={class:`coverage font-mono text-xs tabular-nums text-muted`},ge={class:`overflow-x-auto`},_e={class:`users w-full min-w-[40rem] border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},ve=[`title`],ye={class:`text-highlighted`},be={class:`ml-1.5 text-xs text-dimmed`},xe={key:0,class:`ml-1.5 rounded-xs bg-accented px-1 text-xs text-highlighted`},Se=[`title`],Ce={class:`border-b border-muted px-2.5 py-1.5 text-right`},we={class:`border-b border-muted px-2.5 py-1.5 text-right`},Te={class:`border-b border-muted px-2.5 py-1.5 text-right`},Ee={class:`border-b border-muted px-2.5 py-1.5 text-right font-medium text-highlighted`},De={class:`border-b border-muted px-2.5 py-1.5 text-right`},Oe={key:0},ke={class:`empty px-2.5 py-3 text-sm text-muted`,colspan:`6`},Ae={key:0},je={class:`px-2.5 py-1.5 text-right text-xs text-muted`},Me={class:`px-2.5 py-1.5 text-right text-xs text-muted`},Ne={class:`reconciliation font-mono text-xs tabular-nums text-muted`},Pe=b({__name:`CostsByUser`,props:{report:{}},setup(e){let t=e,n=s(``),o=s(!1),c=f(()=>t.report.viewer.userIds.length>0),p=f(()=>{let e=n.value.trim().toLowerCase(),r=new Set(t.report.viewer.userIds);return t.report.users.filter(t=>o.value&&!r.has(t.userId)?!1:!e||t.userId.toLowerCase().includes(e)||(t.userName??``).toLowerCase().includes(e))}),b=f(()=>t.report.users.reduce((e,t)=>e+t.totalUsd,0)),S=f(()=>p.value.reduce((e,t)=>e+t.totalUsd,0)),C=e=>t.report.viewer.userIds.includes(e.userId),w=e=>e.userName??e.userId.replace(/^[a-z]+:/,``),E=e=>e.userId.split(`:`)[0]??``,D=e=>`${e} day${e===1?``:`s`}`;return(t,s)=>(u(),h(`section`,le,[m(`div`,ue,[m(`label`,de,[s[2]||=m(`span`,null,`Filter`,-1),x(m(`input`,{"onUpdate:modelValue":s[0]||=e=>n.value=e,class:`user-filter rounded-md border border-default bg-elevated px-2.5 py-1 font-mono text-xs text-highlighted`,type:`search`,placeholder:`name or id`,"aria-label":`Filter users`},null,512),[[i,n.value]])]),m(`label`,{class:y([`me-toggle flex items-center gap-2 text-sm`,c.value?`text-muted`:`text-dimmed`]),title:c.value?`Only your own runs`:void 0},[x(m(`input`,{"onUpdate:modelValue":s[1]||=e=>o.value=e,type:`checkbox`,disabled:!c.value,"aria-label":`Only me`,"aria-describedby":c.value?void 0:`me-hint`},null,8,pe),[[r,o.value]]),s[3]||=m(`span`,null,`me`,-1),c.value?d(``,!0):(u(),h(`span`,me,`— your sign-in email matched no Slack user in this range`))],10,fe),m(`p`,he,[e.report.coverage.historyOn?(u(),h(a,{key:1},[l(` runs from `+v(_(P)(e.report.coverage.from))+` to `+v(_(P)(e.report.range.to)),1),e.report.coverage.clamped?(u(),h(a,{key:0},[l(` · earlier days are past the history's `+v(e.report.coverage.retentionDays)+`-day window`,1)],64)):d(``,!0),e.report.pending>0?(u(),h(a,{key:1},[l(` · `+v(e.report.pending)+` run`+v(e.report.pending===1?``:`s`)+` still being priced`,1)],64)):d(``,!0)],64)):(u(),h(a,{key:0},[l(`run history is off — no runs to attribute`)],64))])]),m(`div`,ge,[m(`table`,_e,[s[5]||=m(`thead`,null,[m(`tr`,null,[m(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-left text-xs font-medium text-muted`},` User `),m(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` Runs `),m(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` LLM `),m(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},[l(` Cloud `),m(`span`,{class:`font-normal text-dimmed`},`allocated`)]),m(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` Total `),m(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` Share `)])],-1),m(`tbody`,null,[(u(!0),h(a,null,g(p.value,e=>(u(),h(`tr`,{key:e.userId,class:y([`user-row`,C(e)?`is-me`:``])},[m(`td`,{class:`border-b border-muted px-2.5 py-1.5`,title:e.userId},[m(`span`,ye,v(w(e)),1),m(`span`,be,v(E(e)),1),C(e)?(u(),h(`span`,xe,`me`)):d(``,!0),e.unpricedTokens>0?(u(),h(`span`,{key:1,class:`ml-1.5 text-xs text-warn`,title:`${e.unpricedTokens} tokens ran under a model with no list price`},`unpriced tokens`,8,Se)):d(``,!0)],8,ve),m(`td`,Ce,v(e.runs),1),m(`td`,we,v(_(T)(e.llmUsd)),1),m(`td`,Te,v(_(T)(e.cloudUsd)),1),m(`td`,Ee,v(_(T)(e.totalUsd)),1),m(`td`,De,v(b.value>0?Math.round(e.totalUsd/b.value*100):0)+`% `,1)],2))),128)),p.value.length===0?(u(),h(`tr`,Oe,[m(`td`,ke,v(e.report.users.length===0?`no runs in this range`:`no user matches`),1)])):d(``,!0)]),p.value.length>0&&p.value.length<e.report.users.length?(u(),h(`tfoot`,Ae,[m(`tr`,null,[s[4]||=m(`td`,{class:`px-2.5 py-1.5 text-xs text-muted`,colspan:`4`},`shown`,-1),m(`td`,je,v(_(T)(S.value)),1),m(`td`,Me,v(b.value>0?Math.round(S.value/b.value*100):0)+`% `,1)])])):d(``,!0)])]),m(`p`,Ne,[e.report.reconciliation.comparedDays>0?(u(),h(a,{key:0},[l(` LLM attributed `+v(_(T)(e.report.reconciliation.attributedLlmUsd))+` of `+v(_(T)(e.report.reconciliation.workspaceLlmUsd))+` on the workspace over `+v(D(e.report.reconciliation.comparedDays))+` · `,1),e.report.reconciliation.unattributedLlmUsd>=0?(u(),h(a,{key:0},[l(v(_(T)(e.report.reconciliation.unattributedLlmUsd))+` unattributed (router, review abridges, runs without a record, list vs invoice) `,1)],64)):(u(),h(a,{key:1},[l(v(_(T)(-e.report.reconciliation.unattributedLlmUsd))+` more attributed than the workspace figure (list vs invoice, or spend billed outside this workspace on a compared day) `,1)],64))],64)):(u(),h(a,{key:1},[l(`no day in range has a workspace LLM figure to compare against`)],64)),e.report.reconciliation.uncomparedDays>0?(u(),h(a,{key:2},[l(` · `+v(D(e.report.reconciliation.uncomparedDays))+` with `+v(_(T)(e.report.reconciliation.uncomparedLlmUsd))+` of run tokens but no workspace figure (billed outside this workspace) not compared`,1)],64)):d(``,!0),l(` · cloud allocated `+v(_(T)(e.report.reconciliation.cloudAllocatedUsd)),1),e.report.reconciliation.cloudUnallocatedUsd>0?(u(),h(a,{key:3},[l(` · `+v(_(T)(e.report.reconciliation.cloudUnallocatedUsd))+` on days with no runs`,1)],64)):d(``,!0)]),s[6]||=m(`p`,{class:`text-xs text-dimmed`},` A user's LLM is their runs' tokens at Anthropic list (cache writes at the 5-minute rate); a child run bills to whoever started its parent. Cloud is each day's Cloudflare spend split by share of run wall-clock — an allocation, not a meter. `,-1)]))}}),Fe={class:`mb-4 flex flex-wrap items-center gap-x-4 gap-y-2`},Ie={class:`flex items-center gap-1`,"aria-label":`Range`},Le={key:0,class:`rounded-md bg-accented px-2.5 py-1 font-mono text-xs font-medium tabular-nums text-highlighted`,"aria-current":`page`},Re=[`href`],ze={key:0,class:`flex items-center gap-1`,"aria-label":`Cost groups`},Be={key:0,class:`rounded-md bg-accented px-2.5 py-1 text-xs font-medium text-highlighted`,"aria-current":`page`},Ve=[`href`],He={class:`font-mono text-sm tabular-nums text-muted`},Ue={class:`mb-5 grid grid-cols-[repeat(auto-fit,minmax(190px,1fr))] gap-3`},We={key:0,class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Ge={class:`font-mono text-2xl font-medium tabular-nums`},Ke={class:`text-xs text-muted`},qe={key:1,class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Je={class:`font-mono text-2xl font-medium tabular-nums`},Ye={class:`text-xs text-muted`},Xe={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Ze={class:`font-mono text-2xl font-medium tabular-nums`},Qe={class:`text-xs text-muted`},$e={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},et={class:`font-mono text-2xl font-medium tabular-nums`},tt={class:`text-xs text-muted`},nt={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},rt={class:`font-mono text-2xl font-medium tabular-nums`},it={class:`text-xs text-muted`},at={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},ot={class:`font-mono text-2xl font-medium tabular-nums`},st={class:`text-xs text-muted`},ct=[`href`,`title`],lt=[`href`],ut={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},dt={class:`flex flex-wrap items-baseline justify-between gap-x-4 gap-y-2`},ft={class:`legend flex flex-wrap gap-x-4 gap-y-1.5 text-xs text-muted`},pt=[`href`,`title`],mt={key:0,class:`text-xs text-warn`},ht={key:1,class:`text-xs text-muted`},gt={class:`mb-3 flex items-center gap-1 border-b border-default`,"aria-label":`View`},_t={key:0,class:`-mb-px border-b-2 border-primary px-3 py-1.5 text-sm font-medium text-highlighted`,"aria-current":`page`},vt=[`href`],yt={key:0,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},bt={key:1,class:`text-sm text-warn`},xt={class:`text-xs text-muted`},St={class:`rounded bg-accented px-1 py-0.5`},Ct={key:1,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},wt={class:`w-full border-collapse font-mono text-[0.8125rem] tabular-nums`},Tt={class:`px-2.5 py-1.5`},Et=[`href`],Dt={class:`px-2.5 py-1.5 text-right`},Ot={class:`px-2.5 py-1.5 text-right`},kt={class:`w-2/5 px-2.5 py-1.5`},At={key:2,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},jt={open:``},Mt={class:`mt-2.5 overflow-x-auto`},Nt={class:`data w-full min-w-[38rem] border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},$=[`title`],Pt={key:0,class:`text-xs text-dimmed`},Ft={key:1,class:`text-xs text-dimmed`},It={class:`border-b border-muted px-2.5 py-1.5 text-right font-medium`},Lt={class:`text-xs text-muted`},Rt={class:`rounded bg-accented px-1 py-0.5`},zt={class:`border-t border-default pt-3.5 text-xs text-dimmed`},Bt={class:`mt-2 grid gap-1.5`},Vt=[`href`],Ht={key:2},Ut=[`href`],Wt={key:2},Gt=[`href`],Kt=[`href`],qt=b({__name:`CostsPage`,setup(r){let i=p(`costs`),s=f(()=>i?.report??null),b=f(()=>i?.groups??[]),x=f(()=>i?.view??`daily`),S=f(()=>x.value===`users`?i?.users??null:null);function C(e,t,n){let r=[`days=${t}`];return n===`users`&&r.push(`view=users`),`/costs/${e}?${r.join(`&`)}`}let w=f(()=>s.value?D(s.value):[]),E=f(()=>s.value?ee(s.value):null),k=f(()=>s.value?re(s.value):[]),A=f(()=>s.value?te(s.value):null),j=f(()=>s.value?ne(s.value):``);function M(e){let t=A.value;if(t){if(/^(Memory|vCPU|Disk)/.test(e))return t.containers;if(e.startsWith(`Durable Object`))return t.durableObjects;if(e.startsWith(`Workers`))return t.workers;if(e.startsWith(`R2`))return t.r2;if(e.startsWith(`Workflow`))return t.workflows}}function N(e){let t=A.value;if(t)return e===`LLM (Anthropic)`?t.anthropic:e===`Durable Objects`?t.durableObjects:e===`Workers · storage · R2`?t.workers:t.containers}let P=f(()=>{let e=s.value,t=E.value;if(!e||!t)return``;let n=t.projection,r=`cloud ${T(n.cloudRate)}/day`,i=n.cloudBasis===`today`?`cloud from today so far`:`cloud from the last 7 full days`;if(!e.llmAvailable)return`${r} × 30.4 · ${i} · before plan fees and included allowances`;let a=`LLM ${T(n.llmRate)}/day`,o=n.llmBasis===`closed-days`?`LLM from ${n.llmClosedDays} closed day${n.llmClosedDays===1?``:`s`}`:n.llmBasis===`today`?`LLM from today so far`:`no LLM spend in range`;return`${r} + ${a} · × 30.4 · ${n.cloudBasis===`today`&&n.llmBasis===`today`?`both from today so far`:`${i} · ${o}`}`}),F=f(()=>s.value?[...s.value.days].reverse():[]),I=[1,7,30,90],L=e=>e===1?`today`:`${e}d`,z=f(()=>{let e=s.value,t=E.value;if(!e||!t)return``;if(!e.llmAvailable)return`LLM spend not configured`;let n=[];return t.llm.yesterday!==void 0&&n.push(`yesterday ${T(t.llm.yesterday)}`),t.llm.today&&n.push(`today ${T(t.llm.today.usd)}${t.llm.today.estimated?` (estimate)`:``}`),n.length?n.join(` · `):`in range`});function B(e){let t=new Date(`${e}T00:00:00Z`);return Number.isNaN(t.getTime())?e:`${[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`][t.getUTCMonth()]} ${t.getUTCDate()}`}return(r,i)=>s.value&&E.value?(u(),c(e,{key:0,title:`${s.value.label} spend`,nav:`costs`},{default:n(()=>[m(`div`,Fe,[m(`nav`,Ie,[(u(),h(a,null,g(I,e=>(u(),h(a,{key:e},[e===s.value.range.days?(u(),h(`span`,Le,v(L(e)),1)):(u(),h(`a`,{key:1,class:`rounded-md px-2.5 py-1 font-mono text-xs tabular-nums text-muted no-underline hover:bg-elevated hover:text-highlighted`,href:C(s.value.group,e,x.value)},v(L(e)),9,Re))],64))),64))]),b.value.length>1?(u(),h(`nav`,ze,[(u(!0),h(a,null,g(b.value,e=>(u(),h(a,{key:e},[e===s.value.group?(u(),h(`span`,Be,v(e),1)):(u(),h(`a`,{key:1,class:`rounded-md px-2.5 py-1 text-xs text-muted no-underline hover:bg-elevated hover:text-highlighted`,href:C(e,s.value.range.days,x.value)},v(e),9,Ve))],64))),128))])):d(``,!0),m(`p`,He,[l(v(B(s.value.range.from))+` → `+v(B(s.value.range.to))+` · `+v(s.value.range.days)+`d`,1),s.value.range.partialLastDay?(u(),h(a,{key:0},[l(` · today partial`)],64)):d(``,!0)])]),m(`section`,Ue,[E.value.yesterday?(u(),h(`div`,We,[i[0]||=m(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Yesterday`,-1),m(`span`,Ge,v(_(T)(E.value.yesterday.total)),1),m(`span`,Ke,v(E.value.yesterday.date)+` · last full day`,1)])):(u(),h(`div`,qe,[i[1]||=m(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Today so far`,-1),m(`span`,Je,v(E.value.today?_(T)(E.value.today.total):`—`),1),m(`span`,Ye,v(E.value.today?`${E.value.today.date} · partial day, UTC`:`no day in range`),1)])),m(`div`,Xe,[i[2]||=m(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`7-day average`,-1),m(`span`,Ze,v(E.value.avg7===void 0?`—`:_(T)(E.value.avg7)),1),m(`span`,Qe,v(E.value.avg7===void 0?`no full day yet in this range`:`per day, full days only`),1)]),m(`div`,$e,[i[3]||=m(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Projected month`,-1),m(`span`,et,v(_(T)(E.value.projection.monthUsd,0)),1),m(`span`,tt,v(P.value),1)]),m(`div`,nt,[i[4]||=m(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`LLM spend`,-1),m(`span`,rt,v(s.value.llmAvailable?_(T)(E.value.llm.range):`—`),1),m(`span`,it,v(z.value),1)]),m(`div`,at,[i[6]||=m(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Share of account`,-1),m(`span`,ot,v(E.value.accountShare)+`%`,1),m(`span`,st,[l(v(_(T)(s.value.totals.cloudUsd))+` of `+v(_(T)(s.value.account.cloudUsd))+` on `,1),A.value?(u(),h(`a`,{key:0,class:`text-primary hover:underline`,href:A.value.account,target:`_blank`,rel:`noopener noreferrer`,title:`Cloudflare account ${s.value.account.id}`},v(j.value),9,ct)):d(``,!0),i[5]||=l(` · Cloudflare spend in range · `,-1),A.value?(u(),h(`a`,{key:1,class:`text-primary hover:underline`,href:A.value.billing,target:`_blank`,rel:`noopener noreferrer`},`billing`,8,lt)):d(``,!0)])])]),m(`section`,ut,[m(`div`,dt,[i[7]||=m(`div`,null,[m(`h2`,{class:`text-[0.9375rem] font-medium`},`Daily cost`),m(`p`,{class:`text-sm text-muted`},`Stacked by component · USD list price`)],-1),m(`div`,ft,[(u(!0),h(a,null,g(w.value,(e,t)=>(u(),h(`a`,{key:e,class:`inline-flex items-center gap-1.5 no-underline hover:text-highlighted hover:underline`,href:N(e),target:`_blank`,rel:`noopener noreferrer`,title:`Open where ${e} is billed`},[m(`i`,{class:y([`inline-block size-2.5 rounded-xs`,_(R)[t%_(R).length]])},null,2),l(v(e),1)],8,pt))),128))])]),o(ce,{report:s.value,series:w.value},null,8,[`report`,`series`]),s.value.llmAvailable?s.value.days.some(e=>e.llmEstimated)?(u(),h(`p`,ht,[i[9]||=l(` A day the Anthropic cost report has not closed yet (today, and yesterday until a few hours after midnight UTC) shows its LLM figure as an estimate: the hourly usage report priced at list. The closed days are the cost report itself. `,-1),s.value.days.some(e=>e.llmUnpricedTokens>0)?(u(),h(a,{key:0},[l(` Some tokens ran under a model this page has no price for and are not in the estimate. `)],64)):d(``,!0)])):d(``,!0):(u(),h(`p`,mt,[...i[8]||=[l(` LLM spend not configured — set `,-1),m(`code`,null,`ANTHROPIC_ADMIN_KEY`,-1),l(` and the group's `,-1),m(`code`,null,`anthropicWorkspaceId`,-1),l(` to layer it in. `,-1)]]))]),m(`nav`,gt,[(u(),h(a,null,g([`daily`,`users`],e=>(u(),h(a,{key:e},[e===x.value?(u(),h(`span`,_t,v(e===`daily`?`Daily`:`By user`),1)):(u(),h(`a`,{key:1,class:`-mb-px border-b-2 border-transparent px-3 py-1.5 text-sm text-muted no-underline hover:border-muted hover:text-highlighted`,href:C(s.value.group,s.value.range.days,e)},v(e===`daily`?`Daily`:`By user`),9,vt))],64))),64))]),x.value===`users`?(u(),h(`section`,yt,[i[12]||=m(`div`,null,[m(`h2`,{class:`text-[0.9375rem] font-medium`},`Cost by user`),m(`p`,{class:`text-sm text-muted`},` Who started the runs · LLM at list from their tokens · cloud allocated by wall-clock `)],-1),S.value?(u(),c(Pe,{key:0,report:S.value},null,8,[`report`])):(u(),h(`p`,bt,`The by-user report did not load with this page.`)),m(`p`,xt,[i[10]||=l(` Machine-readable twin: `,-1),m(`code`,St,`GET /costs/`+v(s.value.group)+`/users.json`,1),i[11]||=l(` (same Access gate). `,-1)])])):d(``,!0),x.value===`daily`?(u(),h(`section`,Ct,[i[13]||=m(`div`,null,[m(`h2`,{class:`text-[0.9375rem] font-medium`},`What each cloud dollar buys`)],-1),m(`table`,wt,[m(`tbody`,null,[(u(!0),h(a,null,g(k.value,e=>(u(),h(`tr`,{key:e.label,class:`border-b border-muted`},[m(`td`,Tt,[M(e.label)?(u(),h(`a`,{key:0,class:`no-underline hover:text-highlighted hover:underline`,href:M(e.label),target:`_blank`,rel:`noopener noreferrer`,title:`Open where this is billed on Cloudflare`},v(e.label),9,Et)):(u(),h(a,{key:1},[l(v(e.label),1)],64))]),m(`td`,Dt,v(_(T)(e.usd)),1),m(`td`,Ot,v(Math.round(e.percent))+`%`,1),m(`td`,kt,[m(`i`,{class:`block h-2.5 rounded-xs bg-primary opacity-75`,style:t({width:`${e.percent.toFixed(1)}%`})},null,4)])]))),128))])])])):d(``,!0),x.value===`daily`?(u(),h(`section`,At,[m(`details`,jt,[i[16]||=m(`summary`,{class:`cursor-pointer text-sm text-muted`},`Table view — daily cost by component (USD)`,-1),m(`div`,Mt,[m(`table`,Nt,[m(`thead`,null,[m(`tr`,null,[i[14]||=m(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-left text-xs font-medium text-muted`},` Date `,-1),(u(!0),h(a,null,g(w.value,e=>(u(),h(`th`,{key:e,class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},v(e),1))),128)),i[15]||=m(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` Total `,-1)])]),m(`tbody`,null,[(u(!0),h(a,null,g(F.value,e=>(u(),h(`tr`,{key:e.date},[m(`td`,{class:`border-b border-muted px-2.5 py-1.5`,title:e.date},[l(v(B(e.date))+` `,1),s.value.range.partialLastDay&&e.date===s.value.range.to?(u(),h(`span`,Pt,`(partial day`+v(e.llmEstimated?` · LLM estimated`:``)+`)`,1)):e.llmEstimated?(u(),h(`span`,Ft,`(LLM estimated)`)):d(``,!0)],8,$),(u(!0),h(a,null,g(w.value,t=>(u(),h(`td`,{key:t,class:`border-b border-muted px-2.5 py-1.5 text-right`},v(_(T)(_(O)(e,t),3)),1))),128)),m(`td`,It,v(_(T)(e.total,3)),1)]))),128))])])])]),m(`p`,Lt,[i[17]||=l(` Machine-readable twin: `,-1),m(`code`,Rt,`GET /costs/`+v(s.value.group)+`.json`,1),i[18]||=l(` (same Access gate). `,-1)])])):d(``,!0),m(`footer`,zt,[m(`details`,null,[i[26]||=m(`summary`,{class:`cursor-pointer text-muted`},`How these numbers are computed`,-1),m(`div`,Bt,[i[24]||=m(`div`,null,[m(`b`,null,`Live.`),l(` Both billing sources are read live from this page — nothing cached, nothing stored. Cloudflare bills vCPU on active use only; memory and disk bill on the provisioned size for every second a container is awake. LLM spend is the Anthropic Admin API cost report for this group's workspace (gross, USD); a day the cost report has not closed is the Admin API usage report, hourly, priced at Anthropic list per model (input, output, cache writes, cache reads) and marked as an estimate. `)],-1),i[25]||=m(`div`,null,[m(`b`,null,`Method.`),l(` Cloudflare GraphQL Analytics, every meter a Workers deployment is billed on: `),m(`code`,null,`containersUsageAdaptiveGroups`),l(` (cpuTimeSec, allocatedMemory, allocatedDisk per app per UTC day), `),m(`code`,null,`durableObjectsPeriodicGroups`),l(` (billable `),m(`code`,null,`duration`),l(` GB-s and SQLite rows read and written per namespace), `),m(`code`,null,`durableObjectsInvocationsAdaptiveGroups`),l(` (requests per namespace), `),m(`code`,null,`durableObjectsSqlStorageGroups`),l(` (bytes stored), `),m(`code`,null,`workersInvocationsAdaptive`),l(` (requests, CPU time), `),m(`code`,null,`r2StorageAdaptiveGroups`),l(` and `),m(`code`,null,`r2OperationsAdaptiveGroups`),l(` (bytes stored, class A/B operations). Prices: vCPU $0.000020/s, memory $0.0000025/GiB-s, disk $0.00000007/GB-s, DO duration $12.50 per million GB-s, DO requests $0.15/M, SQLite rows $0.001/M read and $1.00/M written, DO storage $0.20/GB-month, Workers $0.30/M requests and $0.02/M CPU-ms, R2 $0.015/GB-month, $4.50/M class A and $0.36/M class B (deletes free). Storage is the day's peak, prorated over a 30.44-day month. Gross list price — plan fees and included allowances are not subtracted; Workers Logs volume has no analytics dataset and is not priced. `)],-1),m(`div`,null,[i[19]||=m(`b`,null,`Scope.`,-1),i[20]||=l(` Attributed to this group: the Workers `,-1),(u(!0),h(a,null,g(s.value.attribution.workers,(e,t)=>(u(),h(a,{key:e},[t>0?(u(),h(a,{key:0},[l(`, `)],64)):d(``,!0),A.value?(u(),h(`a`,{key:1,class:`font-mono hover:underline`,href:A.value.worker(e),target:`_blank`,rel:`noopener noreferrer`},v(e),9,Vt)):(u(),h(`code`,Ht,v(e),1))],64))),128)),l(`, every Durable Object namespace they host (`+v(Object.keys(s.value.attribution.durableObjectNamespaces).length)+`), the R2 buckets named after them (`,1),(u(!0),h(a,null,g(Object.keys(s.value.attribution.r2Buckets),(e,t)=>(u(),h(a,{key:e},[t>0?(u(),h(a,{key:0},[l(`, `)],64)):d(``,!0),A.value?(u(),h(`a`,{key:1,class:`font-mono hover:underline`,href:A.value.bucket(e),target:`_blank`,rel:`noopener noreferrer`},v(e),9,Ut)):(u(),h(`code`,Wt,v(e),1))],64))),128)),Object.keys(s.value.attribution.r2Buckets).length===0?(u(),h(a,{key:0},[l(`none`)],64)):d(``,!0),i[21]||=l(`), and the container apps mapped in `,-1),m(`code`,null,`costs.groups.`+v(s.value.group),1),l(` (`+v(Object.keys(s.value.attribution.containerApps).length)+`). Everything else in the account is priced the same way into the account total, which is what "share of account" divides by. Every figure above links to where it is billed: the `,1),A.value?(u(),h(`a`,{key:1,class:`hover:underline`,href:A.value.account,target:`_blank`,rel:`noopener noreferrer`},`Cloudflare dashboard`,8,Gt)):d(``,!0),i[22]||=l(` for the account `,-1),m(`code`,null,v(s.value.account.id),1),l(v(s.value.account.name?` (${s.value.account.name})`:``)+`, and `,1),A.value?(u(),h(`a`,{key:2,class:`hover:underline`,href:A.value.anthropic,target:`_blank`,rel:`noopener noreferrer`},`Anthropic's cost page`,8,Kt)):d(``,!0),i[23]||=l(` for the LLM line. `,-1)])])])])]),_:1},8,[`title`])):d(``,!0)}});export{qt as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./AppShell-lYVcj-k7.js";import{Lr as t,Xt as n,_n as r,cn as i,gn as a,ir as o,ln as ee,on as s,r as c,sn as l,un as u,ur as d,vi as f,wi as p,yn as te}from"./seed-DeKSHrt2.js";import{t as m}from"./StatusDot-lCLi16zY.js";import{a as ne,c as re,d as ie,f as h,i as g,l as ae,n as oe,o as se,r as ce,s as _,t as le,u as ue}from"./residentDiskBudget-BMBKlYRH.js";var de={class:`mt-4 first:mt-0`},fe={class:`w-full border-collapse font-mono text-[0.8125rem]`},pe={class:`border-t border-muted`},me={class:`px-2 py-1 align-top`},v={class:`ml-1.5 font-medium`},y={class:`border-t border-muted`},b={class:`break-all px-2 py-1 align-top`},x={key:0},S={key:1,class:`text-dimmed`},C={class:`border-t border-muted`},w={class:`break-all px-2 py-1 align-top`},T={key:0},E={key:1,class:`text-dimmed`},D={class:`border-t border-muted`},O={class:`break-all px-2 py-1 align-top`},k={key:0},A={key:1,class:`text-dimmed`},j={class:`border-t border-muted`},M={class:`break-all px-2 py-1 align-top`},N={key:0},P={key:1,class:`text-dimmed`},F={class:`border-t border-muted`},I={class:`break-all px-2 py-1 align-top`},L={key:1,class:`text-dimmed`},R={class:`mt-4`},z={class:`w-full border-collapse font-mono text-[0.8125rem]`},he={class:`border-t border-muted`},ge={class:`break-all px-2 py-1 align-top`},_e=[`href`],ve={key:1},ye={class:`border-t border-muted`},be={class:`break-all px-2 py-1 align-top`},xe={class:`border-t border-muted`},Se={class:`break-all px-2 py-1 align-top`},Ce=[`href`],we={key:1},Te={key:2,class:`text-dimmed`},Ee={class:`border-t border-muted`},De={class:`break-all px-2 py-1 align-top`},Oe={key:0},ke={key:1,class:`text-dimmed`},Ae={class:`border-t border-muted`},je={class:`break-all px-2 py-1 align-top`},Me={key:0},Ne={key:1,class:`text-dimmed`},Pe={class:`border-t border-muted`},Fe={class:`break-all px-2 py-1 align-top`},Ie={key:0},Le={key:1,class:`text-dimmed`},Re={class:`mt-4`},ze={class:`w-full border-collapse font-mono text-[0.8125rem]`},Be={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Ve={class:`break-all px-2 py-1 align-top`},He={class:`w-full border-collapse font-mono text-[0.8125rem]`},Ue={class:`w-32 break-all px-2 py-1 align-top text-muted sm:w-96 sm:break-words`},We={class:`px-2 py-1 align-top`},Ge={key:1,class:`text-xs text-muted`},Ke={class:`mt-4`},qe={key:0,class:`w-full border-collapse font-mono text-[0.8125rem]`},Je={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Ye={class:`break-all px-2 py-1 align-top`},Xe={key:0},B={key:1,class:`text-dimmed`},Ze={key:1,class:`text-xs text-muted`},Qe={class:`mt-4`},$e={class:`mb-1 text-xs text-muted`},et={class:`overflow-x-auto`},tt={class:`w-full border-collapse font-mono text-[0.8125rem]`},nt={class:`break-all px-2 py-1 align-top`},rt={key:0,class:`text-xs text-muted`},it={class:`break-all px-2 py-1 align-top`},at=[`href`],ot={key:1},st={key:2,class:`text-dimmed`},ct={class:`break-all px-2 py-1 align-top`},lt={key:0},ut={key:1,class:`text-dimmed`},dt={key:2},ft={key:3,class:`text-dimmed`},pt={class:`break-all px-2 py-1 align-top`},mt={key:0},ht={key:1,class:`text-dimmed`},gt={key:2},_t={key:3,class:`text-dimmed`},vt={key:1,class:`text-xs text-muted`},yt={class:`mt-4`},bt={class:`w-full border-collapse font-mono text-[0.8125rem]`},xt={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},St={class:`px-2 py-1 align-top`},Ct={class:`mt-4`},wt={key:0,class:`w-full border-collapse font-mono text-[0.8125rem]`},Tt={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Et={class:`break-all px-2 py-1 align-top`},Dt={class:`text-xs text-muted`},Ot={key:1,class:`text-xs text-muted`},kt={class:`mt-4`},At={class:`w-full border-collapse font-mono text-[0.8125rem]`},jt={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Mt={class:`break-all px-2 py-1 align-top`},Nt={key:0},Pt={key:1,class:`text-dimmed`},Ft={class:`mt-4 text-xs text-muted`},It={class:`rounded bg-elevated px-1 py-0.5`},Lt={class:`rounded bg-elevated px-1 py-0.5`},Rt={class:`rounded bg-elevated px-1 py-0.5`},V=te({__name:`ResidentDetailPage`,setup(te){let V=c(`resident`),H=s(()=>V?.record??{}),U=s(()=>ae(H.value)),W=s(()=>ue(H.value)||(V?.slug??``)),G=s(()=>h(U.value.sha)),K=s(()=>se.test(W.value)?`https://github.com/${W.value}`:void 0),q=s(()=>K.value&&/^[0-9a-f]{7,40}$/.test(G.value)?`${K.value}/commit/${G.value}`:void 0),J=s(()=>{let e=U.value.snapshot;return e&&typeof e==`object`?_(e):void 0}),zt=s(()=>_(U.value.schedules)),Y=s(()=>{let e=_(H.value.commands),t=_(H.value.effects);return Object.keys(e).sort().map(n=>({name:n,command:h(e[n]),effect:h(t[n])||`readonly`}))}),X=s(()=>{let e=U.value.threads;return(Array.isArray(e)?e.map(_):[]).map(e=>{let t=h(e.sha);return{threadKey:h(e.threadKey)||`?`,ref:h(e.ref)||`?`,sha:t?t.slice(0,8):``,commitHref:K.value&&/^[0-9a-f]{7,40}$/.test(t)?`${K.value}/commit/${t}`:void 0,user:h(e.user),deps:h(e.deps),boundAt:h(e.boundAt),lastAttachAt:h(e.lastAttachAt),evicted:e.evicted===!0,evictedAt:h(e.evictedAt),evictedWhy:h(e.evictedWhy)}}).sort((e,t)=>t.lastAttachAt.localeCompare(e.lastAttachAt))}),Z=s(()=>X.value.filter(e=>!e.evicted).length),Q=s(()=>{let e=U.value.lastRestore;return e?JSON.stringify(e):``}),$=s(()=>re(H.value)),Bt=s(()=>typeof H.value.diskBudgetMb==`number`?H.value.diskBudgetMb:void 0),Vt=s(()=>{let e=$.value;if(!e)return[];let t=le(e),{freeKiB:n,capped:r,capacityKiB:i}=oe(e,Bt.value),a=n-t.totalKiB,o=t=>{let n=ne(e.parts,t);return n===null?`? (checkout not measured)`:n===0?`?`:`${Math.max(0,Math.floor(a/n))} more (${g(n)} each)`};return[[`used / total`,ce(e)],[`free`,`${g(n)}${r?` under the ${g(i)} diskBudgetMb cap`:``}`],[`reserve`,`${g(t.totalKiB)} (snapshot staging ${g(t.stagingKiB)} + floor ${g(t.floorKiB)})`],[`headroom`,`${g(Math.max(0,a))} — room for ${o(`hardlink`)} hardlinked trees, ${o(`reconcile`)} lockfile-diverged (reconciling)`],[`measured`,e.at||`—`]]}),Ht=s(()=>{let e=$.value;if(!e)return[];let t=[[`mirror`,g(e.parts.mirror)],[`checkout deps (node_modules)`,g(e.parts.deps)],[`checkout (history + tree + build)`,g(e.parts.checkout)]];for(let[n,r]of Object.entries(e.parts.threads).sort((e,t)=>t[1]-e[1]))t.push([`thread ${n}`,g(r)]);for(let[n,r]of Object.entries(e.parts.homes).sort((e,t)=>t[1]-e[1]))r>=1024&&t.push([`home ${n}`,g(r)]);return t.push([`other (image, /tmp, …)`,g(e.parts.other)]),t});return(s,c)=>(o(),i(e,{title:W.value||`Resident`,nav:`residents`},{leading:t(()=>[...c[0]||=[l(`a`,{class:`back text-sm text-muted no-underline hover:text-primary`,href:`/residents`},`← All residents`,-1)]]),default:t(()=>[l(`section`,de,[c[8]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Lifecycle`,-1),l(`table`,fe,[l(`tbody`,null,[l(`tr`,pe,[c[1]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`state`,-1),l(`td`,me,[r(m,{tone:f(ie)(U.value.state),label:U.value.state},null,8,[`tone`,`label`]),l(`span`,v,p(U.value.state),1)])]),l(`tr`,y,[c[2]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`reason`,-1),l(`td`,b,[U.value.reason?(o(),u(`span`,x,p(U.value.reason),1)):(o(),u(`span`,S,`—`))])]),l(`tr`,C,[c[3]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`last refresh error`,-1),l(`td`,w,[f(h)(U.value.lastRefreshError)?(o(),u(`span`,T,p(f(h)(U.value.lastRefreshError)),1)):(o(),u(`span`,E,`—`))])]),l(`tr`,D,[c[4]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`last restore`,-1),l(`td`,O,[Q.value?(o(),u(`span`,k,p(Q.value),1)):(o(),u(`span`,A,`—`))])]),l(`tr`,j,[c[5]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`state updated`,-1),l(`td`,M,[f(h)(U.value.updatedAt)?(o(),u(`span`,N,p(f(h)(U.value.updatedAt)),1)):(o(),u(`span`,P,`—`))])]),l(`tr`,F,[c[7]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`idle since`,-1),l(`td`,I,[f(h)(U.value.idleSince)?(o(),u(n,{key:0},[a(p(f(h)(U.value.idleSince))+` `,1),c[6]||=l(`span`,{class:`text-xs text-muted`},`(refresh parked; container may sleep)`,-1)],64)):(o(),u(`span`,L,`awake`))])])])])]),l(`section`,R,[c[15]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Pinned facts`,-1),l(`table`,z,[l(`tbody`,null,[l(`tr`,he,[c[9]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`repository`,-1),l(`td`,ge,[K.value?(o(),u(`a`,{key:0,class:`text-primary`,href:K.value},p(K.value),9,_e)):(o(),u(`span`,ve,p(f(h)(H.value.resource)||`—`),1))])]),l(`tr`,ye,[c[10]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`default ref`,-1),l(`td`,be,p(f(h)(U.value.defaultRef)||f(h)(H.value.defaultRef)||`—`),1)]),l(`tr`,xe,[c[11]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`pinned sha`,-1),l(`td`,Se,[q.value?(o(),u(`a`,{key:0,class:`text-primary`,href:q.value},p(G.value),9,Ce)):G.value?(o(),u(`span`,we,p(G.value),1)):(o(),u(`span`,Te,`—`))])]),l(`tr`,Ee,[c[12]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`lockfile hash`,-1),l(`td`,De,[f(h)(U.value.lockfileHash)?(o(),u(`span`,Oe,p(f(h)(U.value.lockfileHash)),1)):(o(),u(`span`,ke,`—`))])]),l(`tr`,Ae,[c[13]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`provisioned`,-1),l(`td`,je,[f(h)(U.value.provisionedAt)?(o(),u(`span`,Me,p(f(h)(U.value.provisionedAt)),1)):(o(),u(`span`,Ne,`—`))])]),l(`tr`,Pe,[c[14]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`last refresh`,-1),l(`td`,Fe,[f(h)(U.value.lastRefreshAt)?(o(),u(`span`,Ie,p(f(h)(U.value.lastRefreshAt)),1)):(o(),u(`span`,Le,`—`))])])])])]),l(`section`,Re,[c[17]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Disk`,-1),$.value?(o(),u(n,{key:0},[l(`table`,ze,[l(`tbody`,null,[(o(!0),u(n,null,d(Vt.value,([e,t])=>(o(),u(`tr`,{key:e,class:`border-t border-muted`},[l(`td`,Be,p(e),1),l(`td`,Ve,p(t),1)]))),128))])]),c[16]||=l(`p`,{class:`mb-1 mt-2 text-xs text-muted`},` components (one du, hardlinks counted once — a thread tree shows only what it does not share with the checkout) `,-1),l(`table`,He,[l(`tbody`,null,[(o(!0),u(n,null,d(Ht.value,([e,t])=>(o(),u(`tr`,{key:e,class:`border-t border-muted`},[l(`td`,Ue,p(e),1),l(`td`,We,p(t),1)]))),128))])])],64)):(o(),u(`p`,Ge,` not measured yet — the first refresh cycle or attach of this container measures it `))]),l(`section`,Ke,[c[18]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Snapshot stamp`,-1),J.value?(o(),u(`table`,qe,[l(`tbody`,null,[(o(),u(n,null,d([`ref`,`sha`,`lockfileHash`,`createdAt`,`mirrorBackupId`,`checkoutBackupId`],e=>l(`tr`,{key:e,class:`border-t border-muted`},[l(`td`,Je,p(e),1),l(`td`,Ye,[f(h)(J.value[e])?(o(),u(`span`,Xe,p(f(h)(J.value[e])),1)):(o(),u(`span`,B,`—`))])])),64))])])):(o(),u(`p`,Ze,`no snapshot recorded`))]),l(`section`,Qe,[c[22]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Thread worktrees`,-1),X.value.length>0?(o(),u(n,{key:0},[l(`p`,$e,p(Z.value)+` live · `+p(X.value.length-Z.value)+` evicted`,1),l(`div`,et,[l(`table`,tt,[l(`tbody`,null,[c[21]||=l(`tr`,{class:`text-xs text-muted`},[l(`td`,{class:`px-2 py-1`},`thread`),l(`td`,{class:`px-2 py-1`},`ref · sha`),l(`td`,{class:`px-2 py-1`},`user · deps`),l(`td`,{class:`px-2 py-1`},`bound · last attach`)],-1),(o(!0),u(n,null,d(X.value,e=>(o(),u(`tr`,{key:e.threadKey,class:`border-t border-muted`},[l(`td`,nt,[e.evicted?(o(),u(`span`,rt,[a(`evicted `+p(e.evictedAt||`—`),1),e.evictedWhy?(o(),u(n,{key:0},[a(` · `+p(e.evictedWhy),1)],64)):ee(``,!0)])):(o(),i(m,{key:1,tone:`green`,label:`live`,tip:`live`})),a(` `+p(e.threadKey),1)]),l(`td`,it,[a(p(e.ref)+` · `,1),e.commitHref?(o(),u(`a`,{key:0,class:`text-primary`,href:e.commitHref},p(e.sha),9,at)):e.sha?(o(),u(`span`,ot,p(e.sha),1)):(o(),u(`span`,st,`—`))]),l(`td`,ct,[e.user?(o(),u(`span`,lt,p(e.user),1)):(o(),u(`span`,ut,`—`)),c[19]||=a(` · `,-1),e.deps?(o(),u(`span`,dt,p(e.deps),1)):(o(),u(`span`,ft,`—`))]),l(`td`,pt,[e.boundAt?(o(),u(`span`,mt,p(e.boundAt),1)):(o(),u(`span`,ht,`—`)),c[20]||=a(` · `,-1),e.lastAttachAt?(o(),u(`span`,gt,p(e.lastAttachAt),1)):(o(),u(`span`,_t,`—`))])]))),128))])])])],64)):(o(),u(`p`,vt,`no thread worktrees`))]),l(`section`,yt,[c[23]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Pending schedules`,-1),l(`table`,bt,[l(`tbody`,null,[(o(),u(n,null,d([[`refresh`,`refresh`],[`provision run`,`provisionRun`],[`provision deadline`,`provisionDeadline`]],([e,t])=>l(`tr`,{key:t,class:`border-t border-muted`},[l(`td`,xt,p(e),1),l(`td`,St,p(f(h)(zt.value[t]??0)||`0`),1)])),64))])])]),l(`section`,Ct,[c[25]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Command table`,-1),Y.value.length>0?(o(),u(`table`,wt,[l(`tbody`,null,[(o(!0),u(n,null,d(Y.value,e=>(o(),u(`tr`,{key:e.name,class:`border-t border-muted`},[l(`td`,Tt,p(e.name),1),l(`td`,Et,[l(`code`,null,p(e.command),1),c[24]||=a(),l(`span`,Dt,p(e.effect),1)])]))),128))])])):(o(),u(`p`,Ot,`no command table`))]),l(`section`,kt,[c[26]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Registry settings`,-1),l(`table`,At,[l(`tbody`,null,[(o(!0),u(n,null,d([[`onboarded`,f(h)(H.value.onboardedAt)],[`record updated`,f(h)(H.value.updatedAt)],[`provisioning timeout (ms)`,f(h)(H.value.provisioningTimeoutMs)],[`disk budget (MB)`,f(h)(H.value.diskBudgetMb)],[`worktree TTL (days)`,f(h)(H.value.worktreeTtlDays??7)]],([e,t])=>(o(),u(`tr`,{key:e,class:`border-t border-muted`},[l(`td`,jt,p(e),1),l(`td`,Mt,[t?(o(),u(`span`,Nt,p(t),1)):(o(),u(`span`,Pt,`—`))])]))),128))])])]),l(`p`,Ft,[c[27]||=a(` Manage from chat: `,-1),l(`code`,It,`repo rebuild `+p(W.value),1),c[28]||=a(` · `,-1),l(`code`,Lt,`repo reconfigure `+p(W.value)+` …`,1),c[29]||=a(` · `,-1),l(`code`,Rt,`repo offboard `+p(W.value)+` --dry-run`,1)])]),_:1},8,[`title`]))}});export{V as default};
|
|
1
|
+
import{t as e}from"./AppShell-lYVcj-k7.js";import{Lr as t,Xt as n,_n as r,cn as i,gn as a,ir as o,ln as ee,on as s,r as c,sn as l,un as u,ur as d,vi as f,wi as p,yn as te}from"./seed-DeKSHrt2.js";import{t as m}from"./StatusDot-D-h9p7Iv.js";import{a as ne,c as re,d as ie,f as h,i as g,l as ae,n as oe,o as se,r as ce,s as _,t as le,u as ue}from"./residentDiskBudget-BMBKlYRH.js";var de={class:`mt-4 first:mt-0`},fe={class:`w-full border-collapse font-mono text-[0.8125rem]`},pe={class:`border-t border-muted`},me={class:`px-2 py-1 align-top`},v={class:`ml-1.5 font-medium`},y={class:`border-t border-muted`},b={class:`break-all px-2 py-1 align-top`},x={key:0},S={key:1,class:`text-dimmed`},C={class:`border-t border-muted`},w={class:`break-all px-2 py-1 align-top`},T={key:0},E={key:1,class:`text-dimmed`},D={class:`border-t border-muted`},O={class:`break-all px-2 py-1 align-top`},k={key:0},A={key:1,class:`text-dimmed`},j={class:`border-t border-muted`},M={class:`break-all px-2 py-1 align-top`},N={key:0},P={key:1,class:`text-dimmed`},F={class:`border-t border-muted`},I={class:`break-all px-2 py-1 align-top`},L={key:1,class:`text-dimmed`},R={class:`mt-4`},z={class:`w-full border-collapse font-mono text-[0.8125rem]`},he={class:`border-t border-muted`},ge={class:`break-all px-2 py-1 align-top`},_e=[`href`],ve={key:1},ye={class:`border-t border-muted`},be={class:`break-all px-2 py-1 align-top`},xe={class:`border-t border-muted`},Se={class:`break-all px-2 py-1 align-top`},Ce=[`href`],we={key:1},Te={key:2,class:`text-dimmed`},Ee={class:`border-t border-muted`},De={class:`break-all px-2 py-1 align-top`},Oe={key:0},ke={key:1,class:`text-dimmed`},Ae={class:`border-t border-muted`},je={class:`break-all px-2 py-1 align-top`},Me={key:0},Ne={key:1,class:`text-dimmed`},Pe={class:`border-t border-muted`},Fe={class:`break-all px-2 py-1 align-top`},Ie={key:0},Le={key:1,class:`text-dimmed`},Re={class:`mt-4`},ze={class:`w-full border-collapse font-mono text-[0.8125rem]`},Be={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Ve={class:`break-all px-2 py-1 align-top`},He={class:`w-full border-collapse font-mono text-[0.8125rem]`},Ue={class:`w-32 break-all px-2 py-1 align-top text-muted sm:w-96 sm:break-words`},We={class:`px-2 py-1 align-top`},Ge={key:1,class:`text-xs text-muted`},Ke={class:`mt-4`},qe={key:0,class:`w-full border-collapse font-mono text-[0.8125rem]`},Je={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Ye={class:`break-all px-2 py-1 align-top`},Xe={key:0},B={key:1,class:`text-dimmed`},Ze={key:1,class:`text-xs text-muted`},Qe={class:`mt-4`},$e={class:`mb-1 text-xs text-muted`},et={class:`overflow-x-auto`},tt={class:`w-full border-collapse font-mono text-[0.8125rem]`},nt={class:`break-all px-2 py-1 align-top`},rt={key:0,class:`text-xs text-muted`},it={class:`break-all px-2 py-1 align-top`},at=[`href`],ot={key:1},st={key:2,class:`text-dimmed`},ct={class:`break-all px-2 py-1 align-top`},lt={key:0},ut={key:1,class:`text-dimmed`},dt={key:2},ft={key:3,class:`text-dimmed`},pt={class:`break-all px-2 py-1 align-top`},mt={key:0},ht={key:1,class:`text-dimmed`},gt={key:2},_t={key:3,class:`text-dimmed`},vt={key:1,class:`text-xs text-muted`},yt={class:`mt-4`},bt={class:`w-full border-collapse font-mono text-[0.8125rem]`},xt={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},St={class:`px-2 py-1 align-top`},Ct={class:`mt-4`},wt={key:0,class:`w-full border-collapse font-mono text-[0.8125rem]`},Tt={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Et={class:`break-all px-2 py-1 align-top`},Dt={class:`text-xs text-muted`},Ot={key:1,class:`text-xs text-muted`},kt={class:`mt-4`},At={class:`w-full border-collapse font-mono text-[0.8125rem]`},jt={class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},Mt={class:`break-all px-2 py-1 align-top`},Nt={key:0},Pt={key:1,class:`text-dimmed`},Ft={class:`mt-4 text-xs text-muted`},It={class:`rounded bg-elevated px-1 py-0.5`},Lt={class:`rounded bg-elevated px-1 py-0.5`},Rt={class:`rounded bg-elevated px-1 py-0.5`},V=te({__name:`ResidentDetailPage`,setup(te){let V=c(`resident`),H=s(()=>V?.record??{}),U=s(()=>ae(H.value)),W=s(()=>ue(H.value)||(V?.slug??``)),G=s(()=>h(U.value.sha)),K=s(()=>se.test(W.value)?`https://github.com/${W.value}`:void 0),q=s(()=>K.value&&/^[0-9a-f]{7,40}$/.test(G.value)?`${K.value}/commit/${G.value}`:void 0),J=s(()=>{let e=U.value.snapshot;return e&&typeof e==`object`?_(e):void 0}),zt=s(()=>_(U.value.schedules)),Y=s(()=>{let e=_(H.value.commands),t=_(H.value.effects);return Object.keys(e).sort().map(n=>({name:n,command:h(e[n]),effect:h(t[n])||`readonly`}))}),X=s(()=>{let e=U.value.threads;return(Array.isArray(e)?e.map(_):[]).map(e=>{let t=h(e.sha);return{threadKey:h(e.threadKey)||`?`,ref:h(e.ref)||`?`,sha:t?t.slice(0,8):``,commitHref:K.value&&/^[0-9a-f]{7,40}$/.test(t)?`${K.value}/commit/${t}`:void 0,user:h(e.user),deps:h(e.deps),boundAt:h(e.boundAt),lastAttachAt:h(e.lastAttachAt),evicted:e.evicted===!0,evictedAt:h(e.evictedAt),evictedWhy:h(e.evictedWhy)}}).sort((e,t)=>t.lastAttachAt.localeCompare(e.lastAttachAt))}),Z=s(()=>X.value.filter(e=>!e.evicted).length),Q=s(()=>{let e=U.value.lastRestore;return e?JSON.stringify(e):``}),$=s(()=>re(H.value)),Bt=s(()=>typeof H.value.diskBudgetMb==`number`?H.value.diskBudgetMb:void 0),Vt=s(()=>{let e=$.value;if(!e)return[];let t=le(e),{freeKiB:n,capped:r,capacityKiB:i}=oe(e,Bt.value),a=n-t.totalKiB,o=t=>{let n=ne(e.parts,t);return n===null?`? (checkout not measured)`:n===0?`?`:`${Math.max(0,Math.floor(a/n))} more (${g(n)} each)`};return[[`used / total`,ce(e)],[`free`,`${g(n)}${r?` under the ${g(i)} diskBudgetMb cap`:``}`],[`reserve`,`${g(t.totalKiB)} (snapshot staging ${g(t.stagingKiB)} + floor ${g(t.floorKiB)})`],[`headroom`,`${g(Math.max(0,a))} — room for ${o(`hardlink`)} hardlinked trees, ${o(`reconcile`)} lockfile-diverged (reconciling)`],[`measured`,e.at||`—`]]}),Ht=s(()=>{let e=$.value;if(!e)return[];let t=[[`mirror`,g(e.parts.mirror)],[`checkout deps (node_modules)`,g(e.parts.deps)],[`checkout (history + tree + build)`,g(e.parts.checkout)]];for(let[n,r]of Object.entries(e.parts.threads).sort((e,t)=>t[1]-e[1]))t.push([`thread ${n}`,g(r)]);for(let[n,r]of Object.entries(e.parts.homes).sort((e,t)=>t[1]-e[1]))r>=1024&&t.push([`home ${n}`,g(r)]);return t.push([`other (image, /tmp, …)`,g(e.parts.other)]),t});return(s,c)=>(o(),i(e,{title:W.value||`Resident`,nav:`residents`},{leading:t(()=>[...c[0]||=[l(`a`,{class:`back text-sm text-muted no-underline hover:text-primary`,href:`/residents`},`← All residents`,-1)]]),default:t(()=>[l(`section`,de,[c[8]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Lifecycle`,-1),l(`table`,fe,[l(`tbody`,null,[l(`tr`,pe,[c[1]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`state`,-1),l(`td`,me,[r(m,{tone:f(ie)(U.value.state),label:U.value.state},null,8,[`tone`,`label`]),l(`span`,v,p(U.value.state),1)])]),l(`tr`,y,[c[2]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`reason`,-1),l(`td`,b,[U.value.reason?(o(),u(`span`,x,p(U.value.reason),1)):(o(),u(`span`,S,`—`))])]),l(`tr`,C,[c[3]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`last refresh error`,-1),l(`td`,w,[f(h)(U.value.lastRefreshError)?(o(),u(`span`,T,p(f(h)(U.value.lastRefreshError)),1)):(o(),u(`span`,E,`—`))])]),l(`tr`,D,[c[4]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`last restore`,-1),l(`td`,O,[Q.value?(o(),u(`span`,k,p(Q.value),1)):(o(),u(`span`,A,`—`))])]),l(`tr`,j,[c[5]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`state updated`,-1),l(`td`,M,[f(h)(U.value.updatedAt)?(o(),u(`span`,N,p(f(h)(U.value.updatedAt)),1)):(o(),u(`span`,P,`—`))])]),l(`tr`,F,[c[7]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`idle since`,-1),l(`td`,I,[f(h)(U.value.idleSince)?(o(),u(n,{key:0},[a(p(f(h)(U.value.idleSince))+` `,1),c[6]||=l(`span`,{class:`text-xs text-muted`},`(refresh parked; container may sleep)`,-1)],64)):(o(),u(`span`,L,`awake`))])])])])]),l(`section`,R,[c[15]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Pinned facts`,-1),l(`table`,z,[l(`tbody`,null,[l(`tr`,he,[c[9]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`repository`,-1),l(`td`,ge,[K.value?(o(),u(`a`,{key:0,class:`text-primary`,href:K.value},p(K.value),9,_e)):(o(),u(`span`,ve,p(f(h)(H.value.resource)||`—`),1))])]),l(`tr`,ye,[c[10]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`default ref`,-1),l(`td`,be,p(f(h)(U.value.defaultRef)||f(h)(H.value.defaultRef)||`—`),1)]),l(`tr`,xe,[c[11]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`pinned sha`,-1),l(`td`,Se,[q.value?(o(),u(`a`,{key:0,class:`text-primary`,href:q.value},p(G.value),9,Ce)):G.value?(o(),u(`span`,we,p(G.value),1)):(o(),u(`span`,Te,`—`))])]),l(`tr`,Ee,[c[12]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`lockfile hash`,-1),l(`td`,De,[f(h)(U.value.lockfileHash)?(o(),u(`span`,Oe,p(f(h)(U.value.lockfileHash)),1)):(o(),u(`span`,ke,`—`))])]),l(`tr`,Ae,[c[13]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`provisioned`,-1),l(`td`,je,[f(h)(U.value.provisionedAt)?(o(),u(`span`,Me,p(f(h)(U.value.provisionedAt)),1)):(o(),u(`span`,Ne,`—`))])]),l(`tr`,Pe,[c[14]||=l(`td`,{class:`w-32 px-2 py-1 align-top text-muted sm:w-48 sm:whitespace-nowrap`},`last refresh`,-1),l(`td`,Fe,[f(h)(U.value.lastRefreshAt)?(o(),u(`span`,Ie,p(f(h)(U.value.lastRefreshAt)),1)):(o(),u(`span`,Le,`—`))])])])])]),l(`section`,Re,[c[17]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Disk`,-1),$.value?(o(),u(n,{key:0},[l(`table`,ze,[l(`tbody`,null,[(o(!0),u(n,null,d(Vt.value,([e,t])=>(o(),u(`tr`,{key:e,class:`border-t border-muted`},[l(`td`,Be,p(e),1),l(`td`,Ve,p(t),1)]))),128))])]),c[16]||=l(`p`,{class:`mb-1 mt-2 text-xs text-muted`},` components (one du, hardlinks counted once — a thread tree shows only what it does not share with the checkout) `,-1),l(`table`,He,[l(`tbody`,null,[(o(!0),u(n,null,d(Ht.value,([e,t])=>(o(),u(`tr`,{key:e,class:`border-t border-muted`},[l(`td`,Ue,p(e),1),l(`td`,We,p(t),1)]))),128))])])],64)):(o(),u(`p`,Ge,` not measured yet — the first refresh cycle or attach of this container measures it `))]),l(`section`,Ke,[c[18]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Snapshot stamp`,-1),J.value?(o(),u(`table`,qe,[l(`tbody`,null,[(o(),u(n,null,d([`ref`,`sha`,`lockfileHash`,`createdAt`,`mirrorBackupId`,`checkoutBackupId`],e=>l(`tr`,{key:e,class:`border-t border-muted`},[l(`td`,Je,p(e),1),l(`td`,Ye,[f(h)(J.value[e])?(o(),u(`span`,Xe,p(f(h)(J.value[e])),1)):(o(),u(`span`,B,`—`))])])),64))])])):(o(),u(`p`,Ze,`no snapshot recorded`))]),l(`section`,Qe,[c[22]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Thread worktrees`,-1),X.value.length>0?(o(),u(n,{key:0},[l(`p`,$e,p(Z.value)+` live · `+p(X.value.length-Z.value)+` evicted`,1),l(`div`,et,[l(`table`,tt,[l(`tbody`,null,[c[21]||=l(`tr`,{class:`text-xs text-muted`},[l(`td`,{class:`px-2 py-1`},`thread`),l(`td`,{class:`px-2 py-1`},`ref · sha`),l(`td`,{class:`px-2 py-1`},`user · deps`),l(`td`,{class:`px-2 py-1`},`bound · last attach`)],-1),(o(!0),u(n,null,d(X.value,e=>(o(),u(`tr`,{key:e.threadKey,class:`border-t border-muted`},[l(`td`,nt,[e.evicted?(o(),u(`span`,rt,[a(`evicted `+p(e.evictedAt||`—`),1),e.evictedWhy?(o(),u(n,{key:0},[a(` · `+p(e.evictedWhy),1)],64)):ee(``,!0)])):(o(),i(m,{key:1,tone:`green`,label:`live`,tip:`live`})),a(` `+p(e.threadKey),1)]),l(`td`,it,[a(p(e.ref)+` · `,1),e.commitHref?(o(),u(`a`,{key:0,class:`text-primary`,href:e.commitHref},p(e.sha),9,at)):e.sha?(o(),u(`span`,ot,p(e.sha),1)):(o(),u(`span`,st,`—`))]),l(`td`,ct,[e.user?(o(),u(`span`,lt,p(e.user),1)):(o(),u(`span`,ut,`—`)),c[19]||=a(` · `,-1),e.deps?(o(),u(`span`,dt,p(e.deps),1)):(o(),u(`span`,ft,`—`))]),l(`td`,pt,[e.boundAt?(o(),u(`span`,mt,p(e.boundAt),1)):(o(),u(`span`,ht,`—`)),c[20]||=a(` · `,-1),e.lastAttachAt?(o(),u(`span`,gt,p(e.lastAttachAt),1)):(o(),u(`span`,_t,`—`))])]))),128))])])])],64)):(o(),u(`p`,vt,`no thread worktrees`))]),l(`section`,yt,[c[23]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Pending schedules`,-1),l(`table`,bt,[l(`tbody`,null,[(o(),u(n,null,d([[`refresh`,`refresh`],[`provision run`,`provisionRun`],[`provision deadline`,`provisionDeadline`]],([e,t])=>l(`tr`,{key:t,class:`border-t border-muted`},[l(`td`,xt,p(e),1),l(`td`,St,p(f(h)(zt.value[t]??0)||`0`),1)])),64))])])]),l(`section`,Ct,[c[25]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Command table`,-1),Y.value.length>0?(o(),u(`table`,wt,[l(`tbody`,null,[(o(!0),u(n,null,d(Y.value,e=>(o(),u(`tr`,{key:e.name,class:`border-t border-muted`},[l(`td`,Tt,p(e.name),1),l(`td`,Et,[l(`code`,null,p(e.command),1),c[24]||=a(),l(`span`,Dt,p(e.effect),1)])]))),128))])])):(o(),u(`p`,Ot,`no command table`))]),l(`section`,kt,[c[26]||=l(`h2`,{class:`mb-1.5 font-mono text-xs font-medium uppercase tracking-wider text-muted`},`Registry settings`,-1),l(`table`,At,[l(`tbody`,null,[(o(!0),u(n,null,d([[`onboarded`,f(h)(H.value.onboardedAt)],[`record updated`,f(h)(H.value.updatedAt)],[`provisioning timeout (ms)`,f(h)(H.value.provisioningTimeoutMs)],[`disk budget (MB)`,f(h)(H.value.diskBudgetMb)],[`worktree TTL (days)`,f(h)(H.value.worktreeTtlDays??7)]],([e,t])=>(o(),u(`tr`,{key:e,class:`border-t border-muted`},[l(`td`,jt,p(e),1),l(`td`,Mt,[t?(o(),u(`span`,Nt,p(t),1)):(o(),u(`span`,Pt,`—`))])]))),128))])])]),l(`p`,Ft,[c[27]||=a(` Manage from chat: `,-1),l(`code`,It,`repo rebuild `+p(W.value),1),c[28]||=a(` · `,-1),l(`code`,Lt,`repo reconfigure `+p(W.value)+` …`,1),c[29]||=a(` · `,-1),l(`code`,Rt,`repo offboard `+p(W.value)+` --dry-run`,1)])]),_:1},8,[`title`]))}});export{V as default};
|