@coreplane/switchboard 1.234.0 → 1.235.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/deploy/cloudflare-resident/gc.ts +6 -9
- package/dist/assets/deploy/cloudflare-resident/worker.ts +125 -78
- package/dist/assets/deploy/cloudflare-sandbox/worker.ts +82 -13
- 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/runEvents.ts +7 -0
- package/dist/assets/src/execution/residentCleanliness.ts +24 -0
- package/dist/assets/src/execution/residentDiskBudget.ts +7 -6
- package/dist/assets/src/execution/sandboxErrors.ts +5 -0
- package/dist/assets/src/execution/sandboxIdle.ts +220 -0
- package/dist/assets/web/dist/.vite/manifest.json +26 -25
- package/dist/assets/web/dist/assets/{ResidentDetailPage-C_WNBUao.js → ResidentDetailPage-DSpsye5e.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentsIndexPage-D1sTyaZ_.js → ResidentsIndexPage-CT8fI1M3.js} +1 -1
- package/dist/assets/web/dist/assets/RunFoldRow-Cqh8pTXC.js +9 -0
- package/dist/assets/web/dist/assets/RunRoutePage-oN9GkVEA.js +6 -0
- package/dist/assets/web/dist/assets/{RunsIndexPage-H6GkSv0a.js → RunsIndexPage-sjXr8iCV.js} +1 -1
- package/dist/assets/web/dist/assets/{ScheduledPage-BLcPzm1S.js → ScheduledPage-Tz__zLzi.js} +1 -1
- package/dist/assets/web/dist/assets/{StatusDot-Ct6AtHhS.js → StatusDot-D14iJMy7.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-qol5Boof.js → Tooltip-B0Ob5MQ4.js} +1 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-CbKCL58v.js +1 -0
- package/dist/assets/web/dist/assets/{dist-DwtJj-ou.js → dist-pOdUzj6D.js} +1 -1
- package/dist/assets/web/dist/assets/{main-CRtlGxRm.js → main-D3lG-yQ9.js} +2 -2
- package/dist/cli.js +84 -25
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/RunFoldRow-C_bcTSjA.js +0 -5
- package/dist/assets/web/dist/assets/RunRoutePage-BWTi_6PG.js +0 -10
- package/dist/assets/web/dist/assets/UnitRoutePage-CIhTEwN7.js +0 -1
|
@@ -93,6 +93,30 @@ export function leftBehindOf(measured: WorktreeCleanliness): LeftBehind | undefi
|
|
|
93
93
|
return { uncommittedChanges: measured.changes, unpushedCommits: measured.unpushed };
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
/** What an eviction records about the tree it removed
|
|
97
|
+
* (docs/reference/specs/resident-repos.md item 17: dirt never keeps a tree,
|
|
98
|
+
* and nothing is discarded silently), written on the binding beside the
|
|
99
|
+
* cause: the counts when the probes ran and found something, or the probe's
|
|
100
|
+
* first error line when git could not read the tree — nothing readable was
|
|
101
|
+
* kept, but the record must not read as clean. */
|
|
102
|
+
export type EvictedTree = { leftBehind: LeftBehind } | { unmeasured: string };
|
|
103
|
+
|
|
104
|
+
/** The measurement as the eviction's record: `undefined` for a clean tree or
|
|
105
|
+
* one already gone with the disk (nothing was discarded). */
|
|
106
|
+
export function evictedTreeOf(measured: WorktreeCleanliness): EvictedTree | undefined {
|
|
107
|
+
const leftBehind = leftBehindOf(measured);
|
|
108
|
+
if (leftBehind) return { leftBehind };
|
|
109
|
+
if (!measured.clean) return { unmeasured: measured.reason ?? "clean-check failed" };
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The resident's log line for what an eviction discarded. */
|
|
114
|
+
export function evictedTreeSentence(tree: EvictedTree): string {
|
|
115
|
+
if ("leftBehind" in tree)
|
|
116
|
+
return `left behind ${tree.leftBehind.uncommittedChanges} uncommitted change(s) and ${tree.leftBehind.unpushedCommits} unpushed commit(s), discarded with the tree`;
|
|
117
|
+
return `the tree could not be measured before its removal (${tree.unmeasured})`;
|
|
118
|
+
}
|
|
119
|
+
|
|
96
120
|
/** The bot's word for a discarded tree, in the release log and the run's
|
|
97
121
|
* record: what was left, why it is gone, what to do instead. */
|
|
98
122
|
export function leftBehindSentence(left: LeftBehind): string {
|
|
@@ -311,17 +311,18 @@ export interface DiskEvictionCandidate {
|
|
|
311
311
|
|
|
312
312
|
/** Why a tree was kept under disk pressure. `other` is the caller's fallback
|
|
313
313
|
* for a keep decided outside `orderEvictionCandidates` (a binding that moved
|
|
314
|
-
* during the check); free text never becomes a token.
|
|
315
|
-
|
|
314
|
+
* during the check); free text never becomes a token. No token names dirt:
|
|
315
|
+
* a tree is never kept for what it holds (a run starts from a clean tree),
|
|
316
|
+
* the Worker records what it removes instead. */
|
|
317
|
+
export type DiskKeepWhy = "busy" | "default-ref" | "recent" | "requesting" | "other";
|
|
316
318
|
|
|
317
319
|
/** Order the live trees for eviction under pressure and name every one that is
|
|
318
320
|
* kept: the requesting thread itself, a busy tree, the default branch (the
|
|
319
321
|
* one most likely re-attached — the same rule as `reclaimDecision`), and a
|
|
320
322
|
* tree attached within `DISK_EVICT_MIN_IDLE_MS` are never candidates; the
|
|
321
|
-
* rest are ordered coldest first (oldest `lastAttachAt`, ties on key).
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
* or unreadable one (`dirty`), exactly like the sweep. */
|
|
323
|
+
* rest are ordered coldest first (oldest `lastAttachAt`, ties on key). What
|
|
324
|
+
* each tree holds is not asked — the Worker measures it as the thread user
|
|
325
|
+
* right before the eviction, for the record only. */
|
|
325
326
|
export function orderEvictionCandidates(input: {
|
|
326
327
|
candidates: readonly DiskEvictionCandidate[];
|
|
327
328
|
now: number;
|
|
@@ -48,6 +48,11 @@ const FLEET_BUSY_PATTERNS: readonly RegExp[] = [
|
|
|
48
48
|
/^Failed to create session: 503\b/i,
|
|
49
49
|
/no container instance (?:that can be provided|available)/i,
|
|
50
50
|
/\bCONTAINER_UNAVAILABLE\b/,
|
|
51
|
+
// The platform's wording since the 0.13 line ("… Try again later, or try
|
|
52
|
+
// configuring a higher value for max_instances"): the 0.13 SDK's own warm
|
|
53
|
+
// pool matches on this exact phrase. Seen live passing through as a plain
|
|
54
|
+
// in-body error and ending two reviews in under a minute each.
|
|
55
|
+
/Maximum number of running container instances exceeded/i,
|
|
51
56
|
];
|
|
52
57
|
|
|
53
58
|
export function isFleetBusy(message: string): boolean {
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
// The per-thread sandbox's idle deadline, decided by the Durable Object from
|
|
2
|
+
// the one fact it owns (docs/reference/specs/execution.md item 22): when it
|
|
3
|
+
// last served a request. Deliberately free of node: imports so wrangler can
|
|
4
|
+
// bundle it into the sandbox Worker, like sandboxErrors.ts and
|
|
5
|
+
// sandboxLifecycle.ts.
|
|
6
|
+
//
|
|
7
|
+
// Why this exists: on the 0.13 SDK line the Container's `sleepAfter` is no
|
|
8
|
+
// longer a deadline. At expiry the SDK asks its runtime whether any tracked
|
|
9
|
+
// process or terminal is still active and, if so — or if the probe fails at
|
|
10
|
+
// all — renews the timeout instead of stopping. A detached pi holds its
|
|
11
|
+
// command's stdio open, a bot deploy mid-run orphans that pi until the same
|
|
12
|
+
// thread's next run, and the container is awake for good: twenty-five
|
|
13
|
+
// sandboxes were found running 10–16 h after their last request against a
|
|
14
|
+
// 5-minute sleepAfter with three runs in flight, and the fleet answered every
|
|
15
|
+
// new thread "Maximum number of running container instances exceeded". The
|
|
16
|
+
// guard below makes the deadline ours again: served-time is recorded on every
|
|
17
|
+
// request, a sweep the Durable Object schedules for itself checks it once a
|
|
18
|
+
// minute (and the SDK's own expiry hook is answered by the same verdict), and
|
|
19
|
+
// a container past the window is destroyed — through the SDK's clean teardown
|
|
20
|
+
// when that finishes in time, by the platform's own kill when it does not.
|
|
21
|
+
// Nothing inside the container can extend its life; only a request can.
|
|
22
|
+
|
|
23
|
+
import { BASH_TIMEOUT_MAX_MS } from "./bashTimeout.js";
|
|
24
|
+
|
|
25
|
+
/** The idle window in milliseconds — the twin of `SANDBOX_SLEEP_AFTER` ("5m",
|
|
26
|
+
* sandboxLifecycle.ts), which stays the SDK's own setting so its alarm loop
|
|
27
|
+
* still calls `onActivityExpired` on this cadence. A test holds the two
|
|
28
|
+
* together. */
|
|
29
|
+
export const SANDBOX_SLEEP_AFTER_MS = 5 * 60_000;
|
|
30
|
+
|
|
31
|
+
/** The guard's own cadence: a scheduled callback the Durable Object re-arms
|
|
32
|
+
* after each run while there is a container to guard. Independent of the
|
|
33
|
+
* SDK's activity renewals, so a deadline is met within a minute of passing
|
|
34
|
+
* even when the SDK's busy poll renews its timeout every second. */
|
|
35
|
+
export const IDLE_SWEEP_INTERVAL_MS = 60_000;
|
|
36
|
+
|
|
37
|
+
/** A request in flight this long is stuck, not service: the longest command
|
|
38
|
+
* `/exec` admits (`BASH_TIMEOUT_MAX_MS`, 20 min) plus the SDK backstop and
|
|
39
|
+
* output-wait margins with room to spare. Requests are measured one by one
|
|
40
|
+
* (each carries its own start), so an overlapping chain of short polls beside
|
|
41
|
+
* a long command is never read as one long request. */
|
|
42
|
+
export const INFLIGHT_STUCK_MS = BASH_TIMEOUT_MAX_MS + 10 * 60_000;
|
|
43
|
+
|
|
44
|
+
/** How often the served-time reaches Durable Object storage: the in-memory
|
|
45
|
+
* fact is exact while the object lives, storage is the baseline for the next
|
|
46
|
+
* wake, and the pi harness polls every 750 ms — one write per poll would be
|
|
47
|
+
* the loudest thing the Worker does. */
|
|
48
|
+
export const PERSIST_EVERY_MS = 10_000;
|
|
49
|
+
|
|
50
|
+
/** How long the SDK's clean `destroy()` may take before the platform's own
|
|
51
|
+
* kill ends the container regardless. The SDK bounds its runtime cleanup at
|
|
52
|
+
* 30 s; a teardown that has not finished twice that is not going to. */
|
|
53
|
+
export const DESTROY_GRACE_MS = 60_000;
|
|
54
|
+
|
|
55
|
+
/** The facts the verdict is drawn from. `inflight` holds the start time of
|
|
56
|
+
* every request being served right now — a list, not a count, so the oldest
|
|
57
|
+
* LIVE request decides "stuck" and a finished one stops counting. */
|
|
58
|
+
export interface IdleLedger {
|
|
59
|
+
lastServedAt: number;
|
|
60
|
+
inflight: number[];
|
|
61
|
+
lastPersistedAt: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function newIdleLedger(now: number): IdleLedger {
|
|
65
|
+
return { lastServedAt: now, inflight: [], lastPersistedAt: now };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type IdleVerdict =
|
|
69
|
+
| { action: "destroy"; why: "idle" | "stuck"; idleMs: number }
|
|
70
|
+
| { action: "keep"; why: "warm" | "serving"; recheckInMs: number };
|
|
71
|
+
|
|
72
|
+
/** The decision, pure: destroy when nothing is in flight and the last request
|
|
73
|
+
* finished a full window ago, or when the oldest request in flight has been
|
|
74
|
+
* there longer than any command may run; keep otherwise. A clock that went
|
|
75
|
+
* backwards reads as a fresh request, never as an idle container. */
|
|
76
|
+
export function idleVerdict(ledger: IdleLedger, now: number, sleepAfterMs = SANDBOX_SLEEP_AFTER_MS): IdleVerdict {
|
|
77
|
+
if (ledger.inflight.length > 0) {
|
|
78
|
+
const oldest = Math.min(...ledger.inflight);
|
|
79
|
+
const inflightMs = now - oldest;
|
|
80
|
+
if (inflightMs >= INFLIGHT_STUCK_MS) return { action: "destroy", why: "stuck", idleMs: inflightMs };
|
|
81
|
+
return { action: "keep", why: "serving", recheckInMs: IDLE_SWEEP_INTERVAL_MS };
|
|
82
|
+
}
|
|
83
|
+
const idleMs = now - ledger.lastServedAt;
|
|
84
|
+
if (idleMs >= sleepAfterMs) return { action: "destroy", why: "idle", idleMs };
|
|
85
|
+
return { action: "keep", why: "warm", recheckInMs: sleepAfterMs - idleMs };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** What the guard needs from the Durable Object, as plain functions so the
|
|
89
|
+
* whole decision — arming, counting, destroying, forcing — is exercised
|
|
90
|
+
* against a fake in tests and the Worker's class only forwards. */
|
|
91
|
+
export interface IdleGuardHost {
|
|
92
|
+
now(): number;
|
|
93
|
+
/** `ctx.container?.running`: false when the platform says stopped, true when
|
|
94
|
+
* running, undefined when the object cannot tell — guarded like running. */
|
|
95
|
+
containerRunning(): boolean | undefined;
|
|
96
|
+
/** Whether a sweep callback is already scheduled (the SDK's schedule table). */
|
|
97
|
+
sweepScheduled(): Promise<boolean>;
|
|
98
|
+
scheduleSweep(delayMs: number): Promise<void>;
|
|
99
|
+
/** The SDK's clean teardown (`Sandbox.destroy()`): sessions closed, the
|
|
100
|
+
* container SIGKILLed at the end. May hang or throw; the guard bounds it. */
|
|
101
|
+
destroySandbox(): Promise<void>;
|
|
102
|
+
/** The platform primitive (`ctx.container.destroy()`): the microVM is gone. */
|
|
103
|
+
killContainer(): Promise<void>;
|
|
104
|
+
loadLastServedAt(): Promise<number | undefined>;
|
|
105
|
+
saveLastServedAt(at: number): Promise<void>;
|
|
106
|
+
log(event: Record<string, unknown>): void;
|
|
107
|
+
wait(ms: number): Promise<void>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export type IdleStopSource = "sweep" | "sdk-expiry";
|
|
111
|
+
|
|
112
|
+
export class IdleGuard {
|
|
113
|
+
readonly ledger: IdleLedger;
|
|
114
|
+
private armed = false;
|
|
115
|
+
private destroying: Promise<void> | null = null;
|
|
116
|
+
|
|
117
|
+
constructor(private readonly host: IdleGuardHost) {
|
|
118
|
+
this.ledger = newIdleLedger(host.now());
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** On every Durable Object wake (its constructor): the stored served-time is
|
|
122
|
+
* the baseline when there is one — a container found awake with no record
|
|
123
|
+
* is idle from now, so a fleet leaked before this code arrived is gone one
|
|
124
|
+
* window after the deploy — and one sweep is armed when a container may be
|
|
125
|
+
* running and none is scheduled. */
|
|
126
|
+
async wake(): Promise<void> {
|
|
127
|
+
const stored = await this.host.loadLastServedAt();
|
|
128
|
+
if (stored !== undefined) {
|
|
129
|
+
this.ledger.lastServedAt = stored;
|
|
130
|
+
this.ledger.lastPersistedAt = stored;
|
|
131
|
+
}
|
|
132
|
+
if (this.guarding()) await this.arm();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Every request the object serves runs inside this: counted in flight from
|
|
136
|
+
* its start (so a live command is never idle), recorded at its finish
|
|
137
|
+
* (success or failure alike), persisted on the persist cadence. */
|
|
138
|
+
async served<T>(op: () => Promise<T>): Promise<T> {
|
|
139
|
+
const startedAt = this.host.now();
|
|
140
|
+
this.ledger.inflight.push(startedAt);
|
|
141
|
+
try {
|
|
142
|
+
await this.arm();
|
|
143
|
+
return await op();
|
|
144
|
+
} finally {
|
|
145
|
+
const i = this.ledger.inflight.indexOf(startedAt);
|
|
146
|
+
if (i >= 0) this.ledger.inflight.splice(i, 1);
|
|
147
|
+
const now = this.host.now();
|
|
148
|
+
this.ledger.lastServedAt = now;
|
|
149
|
+
if (now - this.ledger.lastPersistedAt >= PERSIST_EVERY_MS) {
|
|
150
|
+
this.ledger.lastPersistedAt = now;
|
|
151
|
+
try {
|
|
152
|
+
await this.host.saveLastServedAt(now);
|
|
153
|
+
} catch (err) {
|
|
154
|
+
this.host.log({ event: "sandbox.idle-ledger.persist-failed", error: String(err) });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** The scheduled callback. The SDK deletes a schedule row once it has run,
|
|
161
|
+
* so the guard re-arms itself here while there is a container to guard;
|
|
162
|
+
* with none (destroyed, or never started), the next request arms it. */
|
|
163
|
+
async sweep(): Promise<void> {
|
|
164
|
+
this.armed = false;
|
|
165
|
+
await this.enforce("sweep");
|
|
166
|
+
if (this.guarding()) await this.arm();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** The SDK's `onActivityExpired`, answered by the same verdict — its
|
|
170
|
+
* process and terminal probes never decide. */
|
|
171
|
+
async expired(): Promise<void> {
|
|
172
|
+
await this.enforce("sdk-expiry");
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private guarding(): boolean {
|
|
176
|
+
return this.host.containerRunning() !== false || this.ledger.inflight.length > 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private async arm(): Promise<void> {
|
|
180
|
+
if (this.armed) return;
|
|
181
|
+
if (!(await this.host.sweepScheduled())) await this.host.scheduleSweep(IDLE_SWEEP_INTERVAL_MS);
|
|
182
|
+
this.armed = true;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private async enforce(source: IdleStopSource): Promise<void> {
|
|
186
|
+
if (this.destroying) return this.destroying;
|
|
187
|
+
if (!this.guarding()) return;
|
|
188
|
+
const verdict = idleVerdict(this.ledger, this.host.now());
|
|
189
|
+
if (verdict.action === "keep") return;
|
|
190
|
+
this.destroying = this.destroy(verdict, source).finally(() => {
|
|
191
|
+
this.destroying = null;
|
|
192
|
+
});
|
|
193
|
+
return this.destroying;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** The SDK's clean destroy, bounded; then the platform's kill unless the
|
|
197
|
+
* container is known stopped. The guarantee lives in the second step. */
|
|
198
|
+
private async destroy(verdict: Extract<IdleVerdict, { action: "destroy" }>, source: IdleStopSource): Promise<void> {
|
|
199
|
+
const base = { why: verdict.why, idleMs: verdict.idleMs, source, sleepAfterMs: SANDBOX_SLEEP_AFTER_MS };
|
|
200
|
+
this.host.log({ event: "sandbox.idle-stop", ...base });
|
|
201
|
+
let outcome: "done" | "timeout" | "failed";
|
|
202
|
+
let error: string | undefined;
|
|
203
|
+
try {
|
|
204
|
+
outcome = await Promise.race([
|
|
205
|
+
this.host.destroySandbox().then(() => "done" as const),
|
|
206
|
+
this.host.wait(DESTROY_GRACE_MS).then(() => "timeout" as const),
|
|
207
|
+
]);
|
|
208
|
+
} catch (err) {
|
|
209
|
+
outcome = "failed";
|
|
210
|
+
error = String(err);
|
|
211
|
+
}
|
|
212
|
+
if (outcome === "done" && this.host.containerRunning() === false) return;
|
|
213
|
+
this.host.log({ event: "sandbox.idle-stop.forced", ...base, outcome, ...(error ? { error } : {}) });
|
|
214
|
+
try {
|
|
215
|
+
await this.host.killContainer();
|
|
216
|
+
} catch (err) {
|
|
217
|
+
this.host.log({ event: "sandbox.idle-stop.kill-failed", ...base, error: String(err) });
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -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-pOdUzj6D.js",
|
|
32
32
|
"name": "dist",
|
|
33
33
|
"src": "../node_modules/@pierre/diffs/dist/index.js",
|
|
34
34
|
"isDynamicEntry": true,
|
|
@@ -2554,16 +2554,17 @@
|
|
|
2554
2554
|
"_RunsTabs-DEICQ4FY.js"
|
|
2555
2555
|
]
|
|
2556
2556
|
},
|
|
2557
|
-
"_RunFoldRow-
|
|
2558
|
-
"file": "assets/RunFoldRow-
|
|
2557
|
+
"_RunFoldRow-Cqh8pTXC.js": {
|
|
2558
|
+
"file": "assets/RunFoldRow-Cqh8pTXC.js",
|
|
2559
2559
|
"name": "RunFoldRow",
|
|
2560
2560
|
"imports": [
|
|
2561
2561
|
"_AppShell-lYVcj-k7.js",
|
|
2562
2562
|
"_seed-DeKSHrt2.js",
|
|
2563
2563
|
"_wallClock-61NpVkY6.js",
|
|
2564
|
-
"_StatusDot-
|
|
2564
|
+
"_StatusDot-D14iJMy7.js",
|
|
2565
2565
|
"_indexFormat-B-pd4r7Y.js",
|
|
2566
|
-
"_indexRow-Bnj883ii.js"
|
|
2566
|
+
"_indexRow-Bnj883ii.js",
|
|
2567
|
+
"_localIso-L06jV29p.js"
|
|
2567
2568
|
]
|
|
2568
2569
|
},
|
|
2569
2570
|
"_RunsTabs-DEICQ4FY.js": {
|
|
@@ -2574,16 +2575,16 @@
|
|
|
2574
2575
|
"_seed-DeKSHrt2.js"
|
|
2575
2576
|
]
|
|
2576
2577
|
},
|
|
2577
|
-
"_StatusDot-
|
|
2578
|
-
"file": "assets/StatusDot-
|
|
2578
|
+
"_StatusDot-D14iJMy7.js": {
|
|
2579
|
+
"file": "assets/StatusDot-D14iJMy7.js",
|
|
2579
2580
|
"name": "StatusDot",
|
|
2580
2581
|
"imports": [
|
|
2581
2582
|
"_seed-DeKSHrt2.js",
|
|
2582
|
-
"_Tooltip-
|
|
2583
|
+
"_Tooltip-B0Ob5MQ4.js"
|
|
2583
2584
|
]
|
|
2584
2585
|
},
|
|
2585
|
-
"_Tooltip-
|
|
2586
|
-
"file": "assets/Tooltip-
|
|
2586
|
+
"_Tooltip-B0Ob5MQ4.js": {
|
|
2587
|
+
"file": "assets/Tooltip-B0Ob5MQ4.js",
|
|
2587
2588
|
"name": "Tooltip",
|
|
2588
2589
|
"imports": [
|
|
2589
2590
|
"_AppShell-lYVcj-k7.js",
|
|
@@ -2808,7 +2809,7 @@
|
|
|
2808
2809
|
]
|
|
2809
2810
|
},
|
|
2810
2811
|
"src/main.ts": {
|
|
2811
|
-
"file": "assets/main-
|
|
2812
|
+
"file": "assets/main-D3lG-yQ9.js",
|
|
2812
2813
|
"name": "main",
|
|
2813
2814
|
"src": "src/main.ts",
|
|
2814
2815
|
"isEntry": true,
|
|
@@ -2861,19 +2862,19 @@
|
|
|
2861
2862
|
]
|
|
2862
2863
|
},
|
|
2863
2864
|
"src/pages/ResidentDetailPage.vue": {
|
|
2864
|
-
"file": "assets/ResidentDetailPage-
|
|
2865
|
+
"file": "assets/ResidentDetailPage-DSpsye5e.js",
|
|
2865
2866
|
"name": "ResidentDetailPage",
|
|
2866
2867
|
"src": "src/pages/ResidentDetailPage.vue",
|
|
2867
2868
|
"isDynamicEntry": true,
|
|
2868
2869
|
"imports": [
|
|
2869
2870
|
"_AppShell-lYVcj-k7.js",
|
|
2870
2871
|
"_seed-DeKSHrt2.js",
|
|
2871
|
-
"_StatusDot-
|
|
2872
|
+
"_StatusDot-D14iJMy7.js",
|
|
2872
2873
|
"_residentDiskBudget-BMBKlYRH.js"
|
|
2873
2874
|
]
|
|
2874
2875
|
},
|
|
2875
2876
|
"src/pages/ResidentsIndexPage.vue": {
|
|
2876
|
-
"file": "assets/ResidentsIndexPage-
|
|
2877
|
+
"file": "assets/ResidentsIndexPage-CT8fI1M3.js",
|
|
2877
2878
|
"name": "ResidentsIndexPage",
|
|
2878
2879
|
"src": "src/pages/ResidentsIndexPage.vue",
|
|
2879
2880
|
"isDynamicEntry": true,
|
|
@@ -2881,27 +2882,27 @@
|
|
|
2881
2882
|
"_AppShell-lYVcj-k7.js",
|
|
2882
2883
|
"_seed-DeKSHrt2.js",
|
|
2883
2884
|
"_wallClock-61NpVkY6.js",
|
|
2884
|
-
"_StatusDot-
|
|
2885
|
+
"_StatusDot-D14iJMy7.js",
|
|
2885
2886
|
"_residentDiskBudget-BMBKlYRH.js",
|
|
2886
2887
|
"_indexFormat-B-pd4r7Y.js"
|
|
2887
2888
|
]
|
|
2888
2889
|
},
|
|
2889
2890
|
"src/pages/RunRoutePage.vue": {
|
|
2890
|
-
"file": "assets/RunRoutePage-
|
|
2891
|
+
"file": "assets/RunRoutePage-oN9GkVEA.js",
|
|
2891
2892
|
"name": "RunRoutePage",
|
|
2892
2893
|
"src": "src/pages/RunRoutePage.vue",
|
|
2893
2894
|
"isDynamicEntry": true,
|
|
2894
2895
|
"imports": [
|
|
2895
2896
|
"_AppShell-lYVcj-k7.js",
|
|
2896
2897
|
"_seed-DeKSHrt2.js",
|
|
2897
|
-
"_Tooltip-
|
|
2898
|
+
"_Tooltip-B0Ob5MQ4.js",
|
|
2898
2899
|
"src/main.ts",
|
|
2899
2900
|
"_wallClock-61NpVkY6.js",
|
|
2900
2901
|
"_NotFoundPage-BzWS4Ca1.js",
|
|
2901
2902
|
"_indexFormat-B-pd4r7Y.js",
|
|
2902
2903
|
"_indexRow-Bnj883ii.js",
|
|
2903
2904
|
"_localIso-L06jV29p.js",
|
|
2904
|
-
"_RunFoldRow-
|
|
2905
|
+
"_RunFoldRow-Cqh8pTXC.js",
|
|
2905
2906
|
"_favicon-BQsePYv5.js"
|
|
2906
2907
|
],
|
|
2907
2908
|
"dynamicImports": [
|
|
@@ -2912,17 +2913,17 @@
|
|
|
2912
2913
|
]
|
|
2913
2914
|
},
|
|
2914
2915
|
"src/pages/RunsIndexPage.vue": {
|
|
2915
|
-
"file": "assets/RunsIndexPage-
|
|
2916
|
+
"file": "assets/RunsIndexPage-sjXr8iCV.js",
|
|
2916
2917
|
"name": "RunsIndexPage",
|
|
2917
2918
|
"src": "src/pages/RunsIndexPage.vue",
|
|
2918
2919
|
"isDynamicEntry": true,
|
|
2919
2920
|
"imports": [
|
|
2920
2921
|
"_AppShell-lYVcj-k7.js",
|
|
2921
2922
|
"_seed-DeKSHrt2.js",
|
|
2922
|
-
"_Tooltip-
|
|
2923
|
+
"_Tooltip-B0Ob5MQ4.js",
|
|
2923
2924
|
"_wallClock-61NpVkY6.js",
|
|
2924
2925
|
"_RunsTabs-DEICQ4FY.js",
|
|
2925
|
-
"_StatusDot-
|
|
2926
|
+
"_StatusDot-D14iJMy7.js",
|
|
2926
2927
|
"_indexFormat-B-pd4r7Y.js",
|
|
2927
2928
|
"_indexRow-Bnj883ii.js",
|
|
2928
2929
|
"_localIso-L06jV29p.js",
|
|
@@ -2930,14 +2931,14 @@
|
|
|
2930
2931
|
]
|
|
2931
2932
|
},
|
|
2932
2933
|
"src/pages/ScheduledPage.vue": {
|
|
2933
|
-
"file": "assets/ScheduledPage-
|
|
2934
|
+
"file": "assets/ScheduledPage-Tz__zLzi.js",
|
|
2934
2935
|
"name": "ScheduledPage",
|
|
2935
2936
|
"src": "src/pages/ScheduledPage.vue",
|
|
2936
2937
|
"isDynamicEntry": true,
|
|
2937
2938
|
"imports": [
|
|
2938
2939
|
"_AppShell-lYVcj-k7.js",
|
|
2939
2940
|
"_seed-DeKSHrt2.js",
|
|
2940
|
-
"_Tooltip-
|
|
2941
|
+
"_Tooltip-B0Ob5MQ4.js",
|
|
2941
2942
|
"_wallClock-61NpVkY6.js",
|
|
2942
2943
|
"_RunsTabs-DEICQ4FY.js",
|
|
2943
2944
|
"_indexFormat-B-pd4r7Y.js",
|
|
@@ -2945,7 +2946,7 @@
|
|
|
2945
2946
|
]
|
|
2946
2947
|
},
|
|
2947
2948
|
"src/pages/UnitRoutePage.vue": {
|
|
2948
|
-
"file": "assets/UnitRoutePage-
|
|
2949
|
+
"file": "assets/UnitRoutePage-CbKCL58v.js",
|
|
2949
2950
|
"name": "UnitRoutePage",
|
|
2950
2951
|
"src": "src/pages/UnitRoutePage.vue",
|
|
2951
2952
|
"isDynamicEntry": true,
|
|
@@ -2957,7 +2958,7 @@
|
|
|
2957
2958
|
"_indexFormat-B-pd4r7Y.js",
|
|
2958
2959
|
"_indexRow-Bnj883ii.js",
|
|
2959
2960
|
"_localIso-L06jV29p.js",
|
|
2960
|
-
"_RunFoldRow-
|
|
2961
|
+
"_RunFoldRow-Cqh8pTXC.js"
|
|
2961
2962
|
]
|
|
2962
2963
|
}
|
|
2963
2964
|
}
|
|
@@ -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-Ct6AtHhS.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-D14iJMy7.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 +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 s,mr as c,on as l,r as u,sn as d,un as f,ur as p,wi as m,xi as h,yn as g}from"./seed-DeKSHrt2.js";import{n as _}from"./wallClock-61NpVkY6.js";import{t as v}from"./StatusDot-
|
|
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 s,mr as c,on as l,r as u,sn as d,un as f,ur as p,wi as m,xi as h,yn as g}from"./seed-DeKSHrt2.js";import{n as _}from"./wallClock-61NpVkY6.js";import{t as v}from"./StatusDot-D14iJMy7.js";import{c as y,d as b,f as x,l as S,o as C,r as w,u as T}from"./residentDiskBudget-BMBKlYRH.js";import{n as E}from"./indexFormat-B-pd4r7Y.js";var D={class:`mb-2 text-xs text-muted`},O={class:`m-0 list-none p-0`},k={class:`font-mono font-medium text-primary`},A={class:`font-medium`},j=[`title`],M=[`title`],N={key:0,class:`basis-full pl-5 text-xs text-warn`},P={key:1,class:`px-2 py-1.5 text-muted`},F=g({__name:`ResidentsIndexPage`,setup(g){let F=u(`residents`),I=_(),L=l(()=>(F?.residents??[]).map((e,t)=>{let n=e,r=T(n),i=S(n),a=x(i.sha),o=x(i.lastRefreshAt),s=o?Date.parse(o):NaN,c=y(n);return{key:`${r||`?`}-${t}`,display:r||x(n.resource)||`?`,state:i.state,tone:b(i.state),reason:i.reason,ref:x(n.defaultRef)||`?`,sha:a?a.slice(0,8):``,refreshed:o,refreshedLabel:Number.isFinite(s)?E(s,I):o,disk:c?w(c):``,diskAt:c?.at??``,href:C.test(r)?`/residents/${r}`:null}})),R=l(()=>x(F?.cap)||`?`),z=l(()=>x(F?.count)||String(L.value.length));return(l,u)=>(o(),i(e,{title:`Resident repos`,nav:`residents`},{default:t(()=>[L.value.length>0?(o(),f(n,{key:0},[d(`p`,D,m(z.value)+`/`+m(R.value)+` resident slots in use · live registry read, not cached `,1),d(`ul`,O,[(o(!0),f(n,null,p(L.value,e=>(o(),f(`li`,{key:e.key,class:`border-b border-muted first:border-t`},[(o(),i(c(e.href?`a`:`span`),{class:h([`row flex flex-wrap items-center gap-2.5 rounded-md px-2 py-1.5 text-inherit no-underline`,e.href?`hover:bg-elevated`:``]),href:e.href??void 0},{default:t(()=>[r(v,{tone:e.tone,label:e.state,tip:e.state},null,8,[`tone`,`label`,`tip`]),d(`span`,k,m(e.display),1),d(`span`,A,m(e.state),1),d(`span`,{class:`font-mono text-xs text-muted max-sm:basis-full max-sm:pl-5`,title:e.refreshed||void 0},[a(` ref `+m(e.ref),1),e.sha?(o(),f(n,{key:0},[a(` · sha `+m(e.sha),1)],64)):s(``,!0),e.refreshedLabel?(o(),f(n,{key:1},[a(` · refreshed `+m(e.refreshedLabel),1)],64)):s(``,!0),e.disk?(o(),f(n,{key:2},[u[0]||=a(` · `,-1),d(`span`,{title:e.diskAt?`measured ${e.diskAt}`:void 0},`disk `+m(e.disk),9,M)],64)):s(``,!0)],8,j),e.reason?(o(),f(`span`,N,m(e.reason),1)):s(``,!0)]),_:2},1032,[`class`,`href`]))]))),128))])],64)):(o(),f(`p`,P,[a(` No repos onboarded (0/`+m(R.value)+`). Onboard one from chat: `,1),u[1]||=d(`code`,{class:`rounded bg-elevated px-1.5 py-0.5`},`repo onboard <owner/name>`,-1),u[2]||=a(`. `,-1)]))]),_:1}))}});export{F as default};
|