@coreplane/switchboard 1.254.0 → 1.255.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.
Files changed (63) hide show
  1. package/dist/assets/.dockerignore +3 -0
  2. package/dist/assets/Dockerfile +12 -1
  3. package/dist/assets/config/config.example.yaml +6 -1
  4. package/dist/assets/deploy/cloudflare/worker.ts +39 -23
  5. package/dist/assets/deploy/cloudflare-memory/worker.ts +552 -5
  6. package/dist/assets/deploy/cloudflare-memory/wrangler.template.jsonc +5 -0
  7. package/dist/assets/deploy/cloudflare-resident/Dockerfile +13 -1
  8. package/dist/assets/deploy/cloudflare-resident/levels.ts +84 -0
  9. package/dist/assets/deploy/cloudflare-resident/prepare-commit-msg +17 -0
  10. package/dist/assets/deploy/cloudflare-resident/worker.ts +202 -31
  11. package/dist/assets/deploy/cloudflare-sandbox/Dockerfile +11 -1
  12. package/dist/assets/deploy/cloudflare-sandbox/prepare-commit-msg +17 -0
  13. package/dist/assets/deploy/cloudflare-sandbox/worker.ts +21 -4
  14. package/dist/assets/deploy/hooks/prepare-commit-msg +17 -0
  15. package/dist/assets/deploy/secrets.manifest.json +12 -0
  16. package/dist/assets/package-lock.json +3 -3
  17. package/dist/assets/package.json +1 -1
  18. package/dist/assets/source.json +3 -3
  19. package/dist/assets/src/agents/registry.ts +21 -0
  20. package/dist/assets/src/core/budgets.ts +35 -2
  21. package/dist/assets/src/core/coordinator/contract.ts +6 -0
  22. package/dist/assets/src/core/coordinator/driver.ts +49 -6
  23. package/dist/assets/src/core/costs.ts +39 -16
  24. package/dist/assets/src/core/pipelineStanding.ts +5 -0
  25. package/dist/assets/src/core/plane/decide.ts +389 -22
  26. package/dist/assets/src/core/refusal.ts +3 -0
  27. package/dist/assets/src/core/reviewVerdict.ts +15 -2
  28. package/dist/assets/src/core/runEvents.ts +32 -13
  29. package/dist/assets/src/core/runLedger/sessionLog.ts +128 -0
  30. package/dist/assets/src/core/runLedger/types.ts +3 -0
  31. package/dist/assets/src/core/runRecord.ts +24 -7
  32. package/dist/assets/src/core/ship/coordinator.ts +327 -61
  33. package/dist/assets/src/core/trace/workerTrace.ts +3 -0
  34. package/dist/assets/src/execution/sandboxErrors.ts +77 -6
  35. package/dist/assets/web/dist/.vite/manifest.json +59 -58
  36. package/dist/assets/web/dist/assets/CostsPage-BaeWnm-o.js +1 -0
  37. package/dist/assets/web/dist/assets/{DeliveryPage-ngPsO2to.js → DeliveryPage-BBAyLwPq.js} +1 -1
  38. package/dist/assets/web/dist/assets/{HomePage-DvxTHzPx.js → HomePage-Be7jLLnU.js} +1 -1
  39. package/dist/assets/web/dist/assets/PendingTurnRow-DGINv9XT.js +1 -0
  40. package/dist/assets/web/dist/assets/{PlanePage-DpWfiX4C.js → PlanePage-JEj-lqgz.js} +1 -1
  41. package/dist/assets/web/dist/assets/{ResidentDetailPage-DG86v39Y.js → ResidentDetailPage-D_RD6wLo.js} +1 -1
  42. package/dist/assets/web/dist/assets/{ResidentsIndexPage-x6p689VH.js → ResidentsIndexPage-BLkSuCxo.js} +1 -1
  43. package/dist/assets/web/dist/assets/RunFoldRow-CfuZqf_O.js +1 -0
  44. package/dist/assets/web/dist/assets/{RunRoutePage-ysJBY8xQ.js → RunRoutePage-CmWYGR36.js} +4 -4
  45. package/dist/assets/web/dist/assets/{RunsIndexPage-CuzFchcn.js → RunsIndexPage-DW-HHuZa.js} +1 -1
  46. package/dist/assets/web/dist/assets/{ScheduledPage-BuLmfcbG.js → ScheduledPage-3aYsDf-q.js} +1 -1
  47. package/dist/assets/web/dist/assets/{SettingsPage-BujWkdU_.js → SettingsPage-DG-p5Xy1.js} +1 -1
  48. package/dist/assets/web/dist/assets/{StatusDot-C8Bc0pTX.js → StatusDot-CEnGlyAL.js} +1 -1
  49. package/dist/assets/web/dist/assets/{Tooltip-BWwJx27K.js → Tooltip-CiunVowT.js} +1 -1
  50. package/dist/assets/web/dist/assets/UnitRoutePage-iOYnmTcQ.js +1 -0
  51. package/dist/assets/web/dist/assets/budgets-c1eumrqD.js +1 -0
  52. package/dist/assets/web/dist/assets/{dist-CpnyQGOb.js → dist-luhv3YSo.js} +1 -1
  53. package/dist/assets/web/dist/assets/indexRow-DborJPFp.js +1 -0
  54. package/dist/assets/web/dist/assets/{main-Comxmwi4.js → main-mAKx_zo9.js} +2 -2
  55. package/dist/assets/web/dist/assets/{sseReplay-IzTdD4-3.js → sseReplay-DE6wv1Ua.js} +6 -6
  56. package/dist/cli.js +4154 -3061
  57. package/package.json +1 -1
  58. package/dist/assets/web/dist/assets/CostsPage-BuKjw3nv.js +0 -1
  59. package/dist/assets/web/dist/assets/PendingTurnRow-ZYIRCCZ2.js +0 -1
  60. package/dist/assets/web/dist/assets/RunFoldRow-DG29LOTs.js +0 -1
  61. package/dist/assets/web/dist/assets/UnitRoutePage-B9kjA1AT.js +0 -1
  62. package/dist/assets/web/dist/assets/budgets-CbIyPAER.js +0 -1
  63. package/dist/assets/web/dist/assets/indexRow-DABQtONT.js +0 -1
@@ -103,23 +103,94 @@ export function isFleetBusyError(err: unknown): boolean {
103
103
 
104
104
  /** The Worker's answer on /read and /write (sent as HTTP 503): the named
105
105
  * reason plus an `error` that keeps the SDK's own message as the cause, so
106
- * the logs and the model can still see what the platform actually said. */
107
- export function fleetBusyAnswer(cause: string): { error: string; reason: typeof FLEET_BUSY_REASON } {
108
- return { error: `${FLEET_BUSY_REASON}: ${FLEET_BUSY_EXPLANATION} (${cause})`, reason: FLEET_BUSY_REASON };
106
+ * the logs and the model can still see what the platform actually said.
107
+ * `containerId` is the thread's Durable Object id when the Worker knows it —
108
+ * additive, so an older Worker's answer without it changes nothing — carried
109
+ * so the bot's ending log can name which object the fleet refused. */
110
+ export function fleetBusyAnswer(
111
+ cause: string,
112
+ containerId?: string,
113
+ ): { error: string; reason: typeof FLEET_BUSY_REASON; containerId?: string } {
114
+ return {
115
+ error: `${FLEET_BUSY_REASON}: ${FLEET_BUSY_EXPLANATION} (${cause})`,
116
+ reason: FLEET_BUSY_REASON,
117
+ ...(containerId !== undefined ? { containerId } : {}),
118
+ };
109
119
  }
110
120
 
111
121
  /** The Worker's answer on /exec, in-body under the streamed HTTP 200 like every
112
122
  * other exec failure: the dual `error` + exit-127/stderr shape (item 3) so an
113
123
  * executor that predates in-body errors still renders it, plus the reason. */
114
- export function fleetBusyExecAnswer(cause: string): {
124
+ export function fleetBusyExecAnswer(
125
+ cause: string,
126
+ containerId?: string,
127
+ ): {
115
128
  error: string;
116
129
  reason: typeof FLEET_BUSY_REASON;
130
+ containerId?: string;
117
131
  stdout: "";
118
132
  stderr: string;
119
133
  exitCode: 127;
120
134
  } {
121
- const { error, reason } = fleetBusyAnswer(cause);
122
- return { error, reason, stdout: "", stderr: error, exitCode: 127 };
135
+ const { error, reason, containerId: id } = fleetBusyAnswer(cause, containerId);
136
+ return { error, reason, ...(id !== undefined ? { containerId: id } : {}), stdout: "", stderr: error, exitCode: 127 };
137
+ }
138
+
139
+ // ---------------------------------------------------------------------------
140
+ // The fleet-busy ending as ONE queryable log line on each side. A run this
141
+ // condition ends used to exist only on its card and its record — the Worker's
142
+ // logs held the platform's raw refusals with no run attached, the bot's stdout
143
+ // held nothing — so a log sweep after a capacity incident could not count the
144
+ // runs it killed. The stable prefix below selects both lines in one query;
145
+ // the card and the record are unchanged.
146
+
147
+ /** The stable prefix both events share — a log query on it selects the pair. */
148
+ export const FLEET_BUSY_LOG_PREFIX = "sandbox.fleet-busy" as const;
149
+ /** The sandbox Worker's line, where the platform's refusal is named `fleet-busy`. */
150
+ export const FLEET_BUSY_REFUSED_EVENT = `${FLEET_BUSY_LOG_PREFIX}.refused` as const;
151
+ /** The bot's line, at the one site where the spent wait ends the run. */
152
+ export const FLEET_BUSY_RUN_ENDED_EVENT = `${FLEET_BUSY_LOG_PREFIX}.run-ended` as const;
153
+
154
+ /** What the executor learned from the LAST busy answer before its wait was
155
+ * spent — carried on `ExecCapacityError` so the bot's ending site can log
156
+ * these facts beside the run id, which only the bot knows. */
157
+ export interface FleetBusyEndingFacts {
158
+ /** The Worker's error text, which keeps the platform's own refusal as the cause. */
159
+ refusal: string;
160
+ /** The total time the run spent waiting for an instance, in ms. */
161
+ waitedMs: number;
162
+ /** The sandbox Durable Object id the Worker answered with (absent from an older Worker). */
163
+ containerId?: string;
164
+ }
165
+
166
+ /** The Worker's one JSON line where the platform's refusal is turned into the
167
+ * named condition, beside `sandbox.starting` and `sandbox.idle-stop`. */
168
+ export function fleetBusyRefusedLine(fields: {
169
+ thread: string;
170
+ container: string;
171
+ refusal: string;
172
+ route?: string;
173
+ }): string {
174
+ return JSON.stringify({ event: FLEET_BUSY_REFUSED_EVENT, ...fields });
175
+ }
176
+
177
+ /** The bot's one JSON line for a run the full fleet ended — or null for every
178
+ * other ending, so the caller logs nothing then. Matched by the error's name
179
+ * and its carried facts, never `instanceof`: this module is bundled into the
180
+ * Worker and cannot import the executor's class. */
181
+ export function fleetBusyRunEndedLine(run: string | undefined, thread: string, err: unknown): string | null {
182
+ if (typeof err !== "object" || err === null) return null;
183
+ const e = err as { name?: unknown; fleetBusy?: FleetBusyEndingFacts };
184
+ if (e.name !== "ExecCapacityError" || e.fleetBusy === undefined) return null;
185
+ const { refusal, waitedMs, containerId } = e.fleetBusy;
186
+ return JSON.stringify({
187
+ event: FLEET_BUSY_RUN_ENDED_EVENT,
188
+ ...(run !== undefined ? { run } : {}),
189
+ thread,
190
+ ...(containerId !== undefined ? { container: containerId } : {}),
191
+ refusal,
192
+ waitedMs,
193
+ });
123
194
  }
124
195
 
125
196
  /** The message `ExecCapacityError` carries once the wait is spent: names the
@@ -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-CpnyQGOb.js",
31
+ "file": "assets/dist-luhv3YSo.js",
32
32
  "name": "dist",
33
33
  "src": "../node_modules/@pierre/diffs/dist/index.js",
34
34
  "isDynamicEntry": true,
@@ -2570,28 +2570,28 @@
2570
2570
  "_RunsTabs-kHbbxVHx.js"
2571
2571
  ]
2572
2572
  },
2573
- "_PendingTurnRow-ZYIRCCZ2.js": {
2574
- "file": "assets/PendingTurnRow-ZYIRCCZ2.js",
2573
+ "_PendingTurnRow-DGINv9XT.js": {
2574
+ "file": "assets/PendingTurnRow-DGINv9XT.js",
2575
2575
  "name": "PendingTurnRow",
2576
2576
  "imports": [
2577
2577
  "_AppShell-CSXDCV4x.js",
2578
2578
  "_browser-B6T5hjfR.js",
2579
- "_indexRow-DABQtONT.js",
2579
+ "_indexRow-DborJPFp.js",
2580
2580
  "_format-BldUwl_R.js",
2581
- "_sseReplay-IzTdD4-3.js"
2581
+ "_sseReplay-DE6wv1Ua.js"
2582
2582
  ]
2583
2583
  },
2584
- "_RunFoldRow-DG29LOTs.js": {
2585
- "file": "assets/RunFoldRow-DG29LOTs.js",
2584
+ "_RunFoldRow-CfuZqf_O.js": {
2585
+ "file": "assets/RunFoldRow-CfuZqf_O.js",
2586
2586
  "name": "RunFoldRow",
2587
2587
  "imports": [
2588
2588
  "_browser-B6T5hjfR.js",
2589
2589
  "_indexFormat-B-pd4r7Y.js",
2590
- "_indexRow-DABQtONT.js",
2590
+ "_indexRow-DborJPFp.js",
2591
2591
  "_format-BldUwl_R.js",
2592
2592
  "_durationTone-U_rOqo6r.js",
2593
- "_sseReplay-IzTdD4-3.js",
2594
- "_StatusDot-C8Bc0pTX.js"
2593
+ "_sseReplay-DE6wv1Ua.js",
2594
+ "_StatusDot-CEnGlyAL.js"
2595
2595
  ]
2596
2596
  },
2597
2597
  "_RunsTabs-kHbbxVHx.js": {
@@ -2610,16 +2610,16 @@
2610
2610
  "_browser-B6T5hjfR.js"
2611
2611
  ]
2612
2612
  },
2613
- "_StatusDot-C8Bc0pTX.js": {
2614
- "file": "assets/StatusDot-C8Bc0pTX.js",
2613
+ "_StatusDot-CEnGlyAL.js": {
2614
+ "file": "assets/StatusDot-CEnGlyAL.js",
2615
2615
  "name": "StatusDot",
2616
2616
  "imports": [
2617
2617
  "_browser-B6T5hjfR.js",
2618
- "_Tooltip-BWwJx27K.js"
2618
+ "_Tooltip-CiunVowT.js"
2619
2619
  ]
2620
2620
  },
2621
- "_Tooltip-BWwJx27K.js": {
2622
- "file": "assets/Tooltip-BWwJx27K.js",
2621
+ "_Tooltip-CiunVowT.js": {
2622
+ "file": "assets/Tooltip-CiunVowT.js",
2623
2623
  "name": "Tooltip",
2624
2624
  "imports": [
2625
2625
  "_AppShell-CSXDCV4x.js",
@@ -2639,8 +2639,8 @@
2639
2639
  "file": "assets/browser-B6T5hjfR.js",
2640
2640
  "name": "browser"
2641
2641
  },
2642
- "_budgets-CbIyPAER.js": {
2643
- "file": "assets/budgets-CbIyPAER.js",
2642
+ "_budgets-c1eumrqD.js": {
2643
+ "file": "assets/budgets-c1eumrqD.js",
2644
2644
  "name": "budgets"
2645
2645
  },
2646
2646
  "_c-L_QOnFVv.js": {
@@ -2729,11 +2729,11 @@
2729
2729
  "file": "assets/indexFormat-B-pd4r7Y.js",
2730
2730
  "name": "indexFormat"
2731
2731
  },
2732
- "_indexRow-DABQtONT.js": {
2733
- "file": "assets/indexRow-DABQtONT.js",
2732
+ "_indexRow-DborJPFp.js": {
2733
+ "file": "assets/indexRow-DborJPFp.js",
2734
2734
  "name": "indexRow",
2735
2735
  "imports": [
2736
- "_budgets-CbIyPAER.js",
2736
+ "_budgets-c1eumrqD.js",
2737
2737
  "_format-BldUwl_R.js"
2738
2738
  ]
2739
2739
  },
@@ -2813,13 +2813,13 @@
2813
2813
  "_AppShell-CSXDCV4x.js"
2814
2814
  ]
2815
2815
  },
2816
- "_sseReplay-IzTdD4-3.js": {
2817
- "file": "assets/sseReplay-IzTdD4-3.js",
2816
+ "_sseReplay-DE6wv1Ua.js": {
2817
+ "file": "assets/sseReplay-DE6wv1Ua.js",
2818
2818
  "name": "sseReplay",
2819
2819
  "imports": [
2820
2820
  "_browser-B6T5hjfR.js",
2821
2821
  "_wallClock-DmaC1sKA.js",
2822
- "_indexRow-DABQtONT.js",
2822
+ "_indexRow-DborJPFp.js",
2823
2823
  "_format-BldUwl_R.js",
2824
2824
  "_durationTone-U_rOqo6r.js"
2825
2825
  ]
@@ -2869,7 +2869,7 @@
2869
2869
  ]
2870
2870
  },
2871
2871
  "src/main.ts": {
2872
- "file": "assets/main-Comxmwi4.js",
2872
+ "file": "assets/main-mAKx_zo9.js",
2873
2873
  "name": "main",
2874
2874
  "src": "src/main.ts",
2875
2875
  "isEntry": true,
@@ -2905,7 +2905,7 @@
2905
2905
  ]
2906
2906
  },
2907
2907
  "src/pages/CostsPage.vue": {
2908
- "file": "assets/CostsPage-BuKjw3nv.js",
2908
+ "file": "assets/CostsPage-BaeWnm-o.js",
2909
2909
  "name": "CostsPage",
2910
2910
  "src": "src/pages/CostsPage.vue",
2911
2911
  "isDynamicEntry": true,
@@ -2919,7 +2919,7 @@
2919
2919
  ]
2920
2920
  },
2921
2921
  "src/pages/DeliveryPage.vue": {
2922
- "file": "assets/DeliveryPage-ngPsO2to.js",
2922
+ "file": "assets/DeliveryPage-BBAyLwPq.js",
2923
2923
  "name": "DeliveryPage",
2924
2924
  "src": "src/pages/DeliveryPage.vue",
2925
2925
  "isDynamicEntry": true,
@@ -2928,27 +2928,27 @@
2928
2928
  "_browser-B6T5hjfR.js",
2929
2929
  "_delivery-CTdOqpVK.js",
2930
2930
  "_wallClock-DmaC1sKA.js",
2931
- "_budgets-CbIyPAER.js"
2931
+ "_budgets-c1eumrqD.js"
2932
2932
  ]
2933
2933
  },
2934
2934
  "src/pages/HomePage.vue": {
2935
- "file": "assets/HomePage-DvxTHzPx.js",
2935
+ "file": "assets/HomePage-Be7jLLnU.js",
2936
2936
  "name": "HomePage",
2937
2937
  "src": "src/pages/HomePage.vue",
2938
2938
  "isDynamicEntry": true,
2939
2939
  "imports": [
2940
2940
  "_AppShell-CSXDCV4x.js",
2941
2941
  "_browser-B6T5hjfR.js",
2942
- "_Tooltip-BWwJx27K.js",
2943
- "_PendingTurnRow-ZYIRCCZ2.js",
2942
+ "_Tooltip-CiunVowT.js",
2943
+ "_PendingTurnRow-DGINv9XT.js",
2944
2944
  "src/main.ts",
2945
2945
  "_eventSource-Bj_dZf6M.js",
2946
2946
  "_wallClock-DmaC1sKA.js",
2947
2947
  "_indexFormat-B-pd4r7Y.js",
2948
- "_indexRow-DABQtONT.js",
2948
+ "_indexRow-DborJPFp.js",
2949
2949
  "_format-BldUwl_R.js",
2950
2950
  "_durationTone-U_rOqo6r.js",
2951
- "_sseReplay-IzTdD4-3.js"
2951
+ "_sseReplay-DE6wv1Ua.js"
2952
2952
  ]
2953
2953
  },
2954
2954
  "src/pages/MetricsPage.vue": {
@@ -2963,7 +2963,7 @@
2963
2963
  ]
2964
2964
  },
2965
2965
  "src/pages/PlanePage.vue": {
2966
- "file": "assets/PlanePage-DpWfiX4C.js",
2966
+ "file": "assets/PlanePage-JEj-lqgz.js",
2967
2967
  "name": "PlanePage",
2968
2968
  "src": "src/pages/PlanePage.vue",
2969
2969
  "isDynamicEntry": true,
@@ -2971,12 +2971,12 @@
2971
2971
  "_AppShell-CSXDCV4x.js",
2972
2972
  "_browser-B6T5hjfR.js",
2973
2973
  "_wallClock-DmaC1sKA.js",
2974
- "_indexRow-DABQtONT.js",
2974
+ "_indexRow-DborJPFp.js",
2975
2975
  "_format-BldUwl_R.js"
2976
2976
  ]
2977
2977
  },
2978
2978
  "src/pages/ResidentDetailPage.vue": {
2979
- "file": "assets/ResidentDetailPage-DG86v39Y.js",
2979
+ "file": "assets/ResidentDetailPage-D_RD6wLo.js",
2980
2980
  "name": "ResidentDetailPage",
2981
2981
  "src": "src/pages/ResidentDetailPage.vue",
2982
2982
  "isDynamicEntry": true,
@@ -2984,47 +2984,47 @@
2984
2984
  "_AppShell-CSXDCV4x.js",
2985
2985
  "_browser-B6T5hjfR.js",
2986
2986
  "src/main.ts",
2987
- "_StatusDot-C8Bc0pTX.js"
2987
+ "_StatusDot-CEnGlyAL.js"
2988
2988
  ]
2989
2989
  },
2990
2990
  "src/pages/ResidentsIndexPage.vue": {
2991
- "file": "assets/ResidentsIndexPage-x6p689VH.js",
2991
+ "file": "assets/ResidentsIndexPage-BLkSuCxo.js",
2992
2992
  "name": "ResidentsIndexPage",
2993
2993
  "src": "src/pages/ResidentsIndexPage.vue",
2994
2994
  "isDynamicEntry": true,
2995
2995
  "imports": [
2996
2996
  "_AppShell-CSXDCV4x.js",
2997
2997
  "_browser-B6T5hjfR.js",
2998
- "_Tooltip-BWwJx27K.js",
2998
+ "_Tooltip-CiunVowT.js",
2999
2999
  "src/main.ts",
3000
3000
  "_eventSource-Bj_dZf6M.js",
3001
3001
  "_wallClock-DmaC1sKA.js",
3002
3002
  "_indexFormat-B-pd4r7Y.js",
3003
- "_indexRow-DABQtONT.js",
3003
+ "_indexRow-DborJPFp.js",
3004
3004
  "_format-BldUwl_R.js",
3005
- "_StatusDot-C8Bc0pTX.js"
3005
+ "_StatusDot-CEnGlyAL.js"
3006
3006
  ]
3007
3007
  },
3008
3008
  "src/pages/RunRoutePage.vue": {
3009
- "file": "assets/RunRoutePage-ysJBY8xQ.js",
3009
+ "file": "assets/RunRoutePage-CmWYGR36.js",
3010
3010
  "name": "RunRoutePage",
3011
3011
  "src": "src/pages/RunRoutePage.vue",
3012
3012
  "isDynamicEntry": true,
3013
3013
  "imports": [
3014
3014
  "_AppShell-CSXDCV4x.js",
3015
3015
  "_browser-B6T5hjfR.js",
3016
- "_Tooltip-BWwJx27K.js",
3017
- "_PendingTurnRow-ZYIRCCZ2.js",
3016
+ "_Tooltip-CiunVowT.js",
3017
+ "_PendingTurnRow-DGINv9XT.js",
3018
3018
  "src/main.ts",
3019
3019
  "_eventSource-Bj_dZf6M.js",
3020
3020
  "_wallClock-DmaC1sKA.js",
3021
3021
  "_indexFormat-B-pd4r7Y.js",
3022
- "_indexRow-DABQtONT.js",
3022
+ "_indexRow-DborJPFp.js",
3023
3023
  "_format-BldUwl_R.js",
3024
3024
  "_durationTone-U_rOqo6r.js",
3025
- "_sseReplay-IzTdD4-3.js",
3025
+ "_sseReplay-DE6wv1Ua.js",
3026
3026
  "_NotFoundPage-DHuWyjlq.js",
3027
- "_RunFoldRow-DG29LOTs.js"
3027
+ "_RunFoldRow-CfuZqf_O.js"
3028
3028
  ],
3029
3029
  "dynamicImports": [
3030
3030
  "../node_modules/@pierre/diffs/dist/index.js"
@@ -3034,35 +3034,35 @@
3034
3034
  ]
3035
3035
  },
3036
3036
  "src/pages/RunsIndexPage.vue": {
3037
- "file": "assets/RunsIndexPage-CuzFchcn.js",
3037
+ "file": "assets/RunsIndexPage-DW-HHuZa.js",
3038
3038
  "name": "RunsIndexPage",
3039
3039
  "src": "src/pages/RunsIndexPage.vue",
3040
3040
  "isDynamicEntry": true,
3041
3041
  "imports": [
3042
3042
  "_AppShell-CSXDCV4x.js",
3043
3043
  "_browser-B6T5hjfR.js",
3044
- "_Tooltip-BWwJx27K.js",
3044
+ "_Tooltip-CiunVowT.js",
3045
3045
  "_InputMenu-BdZXnibG.js",
3046
3046
  "src/main.ts",
3047
3047
  "_eventSource-Bj_dZf6M.js",
3048
3048
  "_wallClock-DmaC1sKA.js",
3049
3049
  "_indexFormat-B-pd4r7Y.js",
3050
- "_indexRow-DABQtONT.js",
3050
+ "_indexRow-DborJPFp.js",
3051
3051
  "_format-BldUwl_R.js",
3052
3052
  "_durationTone-U_rOqo6r.js",
3053
3053
  "_RunsTabs-kHbbxVHx.js",
3054
- "_StatusDot-C8Bc0pTX.js"
3054
+ "_StatusDot-CEnGlyAL.js"
3055
3055
  ]
3056
3056
  },
3057
3057
  "src/pages/ScheduledPage.vue": {
3058
- "file": "assets/ScheduledPage-BuLmfcbG.js",
3058
+ "file": "assets/ScheduledPage-3aYsDf-q.js",
3059
3059
  "name": "ScheduledPage",
3060
3060
  "src": "src/pages/ScheduledPage.vue",
3061
3061
  "isDynamicEntry": true,
3062
3062
  "imports": [
3063
3063
  "_AppShell-CSXDCV4x.js",
3064
3064
  "_browser-B6T5hjfR.js",
3065
- "_Tooltip-BWwJx27K.js",
3065
+ "_Tooltip-CiunVowT.js",
3066
3066
  "_wallClock-DmaC1sKA.js",
3067
3067
  "_indexFormat-B-pd4r7Y.js",
3068
3068
  "_format-BldUwl_R.js",
@@ -3070,7 +3070,7 @@
3070
3070
  ]
3071
3071
  },
3072
3072
  "src/pages/SettingsPage.vue": {
3073
- "file": "assets/SettingsPage-BujWkdU_.js",
3073
+ "file": "assets/SettingsPage-DG-p5Xy1.js",
3074
3074
  "name": "SettingsPage",
3075
3075
  "src": "src/pages/SettingsPage.vue",
3076
3076
  "isDynamicEntry": true,
@@ -3078,14 +3078,14 @@
3078
3078
  "_AppShell-CSXDCV4x.js",
3079
3079
  "_browser-B6T5hjfR.js",
3080
3080
  "_SettingSelect-BfID5nF4.js",
3081
- "_Tooltip-BWwJx27K.js",
3081
+ "_Tooltip-CiunVowT.js",
3082
3082
  "_InputMenu-BdZXnibG.js",
3083
3083
  "_settingsApi-Dm6eaQcu.js",
3084
- "_indexRow-DABQtONT.js"
3084
+ "_indexRow-DborJPFp.js"
3085
3085
  ]
3086
3086
  },
3087
3087
  "src/pages/UnitRoutePage.vue": {
3088
- "file": "assets/UnitRoutePage-B9kjA1AT.js",
3088
+ "file": "assets/UnitRoutePage-iOYnmTcQ.js",
3089
3089
  "name": "UnitRoutePage",
3090
3090
  "src": "src/pages/UnitRoutePage.vue",
3091
3091
  "isDynamicEntry": true,
@@ -3095,11 +3095,12 @@
3095
3095
  "_SettingSelect-BfID5nF4.js",
3096
3096
  "_wallClock-DmaC1sKA.js",
3097
3097
  "_indexFormat-B-pd4r7Y.js",
3098
+ "_indexRow-DborJPFp.js",
3098
3099
  "_format-BldUwl_R.js",
3099
3100
  "_durationTone-U_rOqo6r.js",
3100
- "_sseReplay-IzTdD4-3.js",
3101
+ "_sseReplay-DE6wv1Ua.js",
3101
3102
  "_NotFoundPage-DHuWyjlq.js",
3102
- "_RunFoldRow-DG29LOTs.js"
3103
+ "_RunFoldRow-CfuZqf_O.js"
3103
3104
  ]
3104
3105
  }
3105
3106
  }
@@ -0,0 +1 @@
1
+ import{t as e}from"./AppShell-CSXDCV4x.js";import{Cn as t,Cr as n,Ii as r,Li as i,Mn as a,Pi as o,Qr as s,Sn as c,Tr as l,Xr as u,Xt as d,_r as f,bn as p,dr as m,en as h,hr as ee,ji as g,kn as _,ln as v,o as y,xi as b,xn as x,yn as S}from"./browser-B6T5hjfR.js";import{a as C,c as te,d as w,f as T,g as E,h as D,l as O,m as k,o as ne,p as re,s as ie,t as A,u as j}from"./CostChart-DsuPS2g7.js";import{t as ae}from"./eventSource-Bj_dZf6M.js";import{r as oe}from"./settingsApi-Dm6eaQcu.js";import{t as se}from"./wallClock-DmaC1sKA.js";var M=[`data-dimension`],ce={class:`flex flex-wrap items-center gap-x-4 gap-y-2`},N={class:`flex items-center gap-2 text-sm text-muted`},P=[`placeholder`,`aria-label`],F=[`title`],I=[`disabled`,`aria-describedby`],L={key:0,id:`me-hint`,class:`me-hint text-xs text-dimmed`},R={class:`coverage font-mono text-xs tabular-nums text-muted`},z={class:`overflow-x-auto`},le={class:`by w-full min-w-[40rem] border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},B={class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-left text-xs font-medium text-muted`},V={class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},H={key:0,class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},ue=[`title`],U={class:`text-highlighted`},de={key:0,class:`ml-1.5 text-xs text-dimmed`},fe={key:1,class:`ml-1.5 rounded-xs bg-accented px-1 text-xs text-highlighted`},W=[`title`],G={class:`border-b border-muted px-2.5 py-1.5 text-right`},K={class:`border-b border-muted px-2.5 py-1.5 text-right`},q={key:0,class:`border-b border-muted px-2.5 py-1.5 text-right`},J={class:`border-b border-muted px-2.5 py-1.5 text-right font-medium text-highlighted`},Y={class:`border-b border-muted px-2.5 py-1.5 text-right`},X={key:0},Z=[`colspan`],pe={key:0},Q=[`colspan`],me={class:`px-2.5 py-1.5 text-right text-xs text-muted`},he={class:`px-2.5 py-1.5 text-right text-xs text-muted`},ge={class:`reconciliation font-mono text-xs tabular-nums text-muted`},_e={class:`text-xs text-dimmed`},ve=a({__name:`CostsByDimension`,props:{report:{}},setup(e){let r=e,a={user:`User`,thread:`Thread`,channel:`Channel`,agent:`Agent`,model:`Model`},l=b(``),u=b(!1),m=S(()=>r.report.dimension),ee=S(()=>r.report.viewer!==void 0),y=S(()=>(r.report.viewer?.userIds.length??0)>0),x=S(()=>r.report.cloudAllocated),C=S(()=>m.value===`model`?`Turns`:`Runs`),te=e=>m.value===`model`?e.turns:e.runs,w=S(()=>{let e=l.value.trim().toLowerCase(),t=new Set(r.report.viewer?.userIds??[]);return r.report.rows.filter(n=>u.value&&!t.has(n.key)?!1:!e||n.key.toLowerCase().includes(e)||(n.label??``).toLowerCase().includes(e))}),T=S(()=>r.report.rows.reduce((e,t)=>e+t.totalUsd,0)),E=S(()=>w.value.reduce((e,t)=>e+t.totalUsd,0)),k=e=>r.report.viewer?.userIds.includes(e.key)??!1,ne=S(()=>m.value===`user`||m.value===`thread`||m.value===`channel`),re=e=>e.label?m.value===`channel`?`#${e.label}`:e.label:ne.value?e.key.replace(/^[a-z]+:/,``):e.key,ie=e=>ne.value&&e.key.includes(`:`)?e.key.split(`:`)[0]:``,A=e=>`${e} day${e===1?``:`s`}`,j=S(()=>x.value?6:5);return(r,b)=>(f(),t(`section`,{class:`by-dimension grid gap-3`,"data-dimension":m.value},[p(`div`,ce,[p(`label`,N,[b[2]||=p(`span`,null,`Filter`,-1),s(p(`input`,{"onUpdate:modelValue":b[0]||=e=>l.value=e,class:`key-filter rounded-md border border-default bg-elevated px-2.5 py-1 font-mono text-xs text-highlighted`,type:`search`,placeholder:m.value===`user`?`name or id`:a[m.value].toLowerCase(),"aria-label":`Filter by ${a[m.value].toLowerCase()}`},null,8,P),[[h,l.value]])]),ee.value?(f(),t(`label`,{key:0,class:o([`me-toggle flex items-center gap-2 text-sm`,y.value?`text-muted`:`text-dimmed`]),title:y.value?`Only your own runs`:void 0},[s(p(`input`,{"onUpdate:modelValue":b[1]||=e=>u.value=e,type:`checkbox`,disabled:!y.value,"aria-label":`Only me`,"aria-describedby":y.value?void 0:`me-hint`},null,8,I),[[d,u.value]]),b[3]||=p(`span`,null,`me`,-1),y.value?c(``,!0):(f(),t(`span`,L,`— your sign-in email matched no Slack user in this range`))],10,F)):c(``,!0),p(`p`,R,[e.report.coverage.historyOn?(f(),t(v,{key:1},[_(` runs from `+i(g(O)(e.report.coverage.from))+` to `+i(g(O)(e.report.range.to)),1),e.report.coverage.clamped?(f(),t(v,{key:0},[_(` · earlier days are past the history's `+i(e.report.coverage.retentionDays)+`-day window`,1)],64)):c(``,!0),e.report.pending>0?(f(),t(v,{key:1},[_(` · `+i(e.report.pending)+` run`+i(e.report.pending===1?``:`s`)+` still being priced`,1)],64)):c(``,!0)],64)):(f(),t(v,{key:0},[_(`run history is off — no runs to attribute`)],64))])]),p(`div`,z,[p(`table`,le,[p(`thead`,null,[p(`tr`,null,[p(`th`,B,i(a[m.value]),1),p(`th`,V,i(C.value),1),b[5]||=p(`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 `,-1),x.value?(f(),t(`th`,H,[...b[4]||=[_(` Cloud `,-1),p(`span`,{class:`font-normal text-dimmed`},`allocated`,-1)]])):c(``,!0),b[6]||=p(`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),b[7]||=p(`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)])]),p(`tbody`,null,[(f(!0),t(v,null,n(w.value,e=>(f(),t(`tr`,{key:e.key,class:o([`by-row`,k(e)?`is-me`:``])},[p(`td`,{class:`border-b border-muted px-2.5 py-1.5`,title:e.key},[p(`span`,U,i(re(e)),1),ie(e)?(f(),t(`span`,de,i(ie(e)),1)):c(``,!0),k(e)?(f(),t(`span`,fe,`me`)):c(``,!0),e.unpricedTokens>0?(f(),t(`span`,{key:2,class:`ml-1.5 text-xs text-warn`,title:`${e.unpricedTokens} tokens ran under a model with no price`},`unpriced tokens`,8,W)):c(``,!0)],8,ue),p(`td`,G,i(te(e)),1),p(`td`,K,i(g(D)(e.llmUsd)),1),x.value?(f(),t(`td`,q,i(g(D)(e.cloudUsd)),1)):c(``,!0),p(`td`,J,i(g(D)(e.totalUsd)),1),p(`td`,Y,i(T.value>0?Math.round(e.totalUsd/T.value*100):0)+`% `,1)],2))),128)),w.value.length===0?(f(),t(`tr`,X,[p(`td`,{class:`empty px-2.5 py-3 text-sm text-muted`,colspan:j.value},i(e.report.rows.length===0?`no runs in this range`:`no ${a[m.value].toLowerCase()} matches`),9,Z)])):c(``,!0)]),w.value.length>0&&w.value.length<e.report.rows.length?(f(),t(`tfoot`,pe,[p(`tr`,null,[p(`td`,{class:`px-2.5 py-1.5 text-xs text-muted`,colspan:j.value-2},`shown`,8,Q),p(`td`,me,i(g(D)(E.value)),1),p(`td`,he,i(T.value>0?Math.round(E.value/T.value*100):0)+`% `,1)])])):c(``,!0)])]),p(`p`,ge,[e.report.reconciliation.comparedDays>0?(f(),t(v,{key:0},[_(` LLM attributed `+i(g(D)(e.report.reconciliation.attributedLlmUsd))+` of `+i(g(D)(e.report.reconciliation.workspaceLlmUsd))+` on the workspace over `+i(A(e.report.reconciliation.comparedDays))+` · `,1),e.report.reconciliation.unattributedLlmUsd>=0?(f(),t(v,{key:0},[_(i(g(D)(e.report.reconciliation.unattributedLlmUsd))+` unattributed (router, review abridges, runs without a record, list vs invoice) `,1)],64)):(f(),t(v,{key:1},[_(i(g(D)(-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)):(f(),t(v,{key:1},[_(`no day in range has a workspace LLM figure to compare against`)],64)),e.report.reconciliation.uncomparedDays>0?(f(),t(v,{key:2},[_(` · `+i(A(e.report.reconciliation.uncomparedDays))+` with `+i(g(D)(e.report.reconciliation.uncomparedLlmUsd))+` of run tokens but no workspace figure (billed outside this workspace) not compared`,1)],64)):c(``,!0),x.value?(f(),t(v,{key:3},[_(` · cloud allocated `+i(g(D)(e.report.reconciliation.cloudAllocatedUsd)),1),e.report.reconciliation.cloudUnallocatedUsd>0?(f(),t(v,{key:0},[_(` · `+i(g(D)(e.report.reconciliation.cloudUnallocatedUsd))+` on days with no runs`,1)],64)):c(``,!0)],64)):c(``,!0)]),p(`p`,_e,[m.value===`model`?(f(),t(v,{key:0},[_(` A model's LLM is the runs' tokens on it, priced through the price table (the configured rates over Anthropic list; cache writes at the 5-minute rate); a run that spent on two models counts under both, and cloud is not split by model — a container runs a run, not a model. `)],64)):(f(),t(v,{key:1},[_(` A `+i(a[m.value].toLowerCase())+`'s LLM is its runs' tokens priced through the price table (the configured rates over Anthropic list; cache writes at the 5-minute rate); a child run bills to whoever started its parent, in the child's own thread and agent. Cloud is each day's Cloudflare spend split by share of run wall-clock — an allocation, not a meter. `,1)],64))])],8,M))}}),ye={class:`mb-4 flex flex-wrap items-center gap-x-4 gap-y-2`},be={class:`flex items-center gap-1`,"aria-label":`Range`},xe={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`},Se={key:0,class:`flex items-center gap-1`,"aria-label":`Cost groups`},Ce={key:0,class:`rounded-md bg-accented px-2.5 py-1 text-xs font-medium text-highlighted`,"aria-current":`page`},we={class:`font-mono text-sm tabular-nums text-muted`},Te={key:1,class:`flex basis-full flex-wrap items-center gap-x-3 gap-y-1`},Ee={class:`font-mono text-xs tabular-nums text-dimmed`,"data-snapshot-status":``},De=[`disabled`],Oe={key:1,class:`text-xs text-error`,role:`status`,"data-snapshot-error":``},ke={class:`mb-5 grid grid-cols-[repeat(auto-fit,minmax(190px,1fr))] gap-3`},Ae={key:0,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`},Me={class:`text-xs text-muted`},Ne={key:1,class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Pe={class:`font-mono text-2xl font-medium tabular-nums`},Fe={class:`text-xs text-muted`},Ie={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Le={class:`font-mono text-2xl font-medium tabular-nums`},Re={class:`text-xs text-muted`},ze={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Be={class:`font-mono text-2xl font-medium tabular-nums`},Ve={class:`text-xs text-muted`},He={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Ue={class:`font-mono text-2xl font-medium tabular-nums`},We={class:`text-xs text-muted`},Ge={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Ke={class:`font-mono text-2xl font-medium tabular-nums`},qe={class:`text-xs text-muted`},Je=[`href`,`title`],Ye=[`href`],Xe={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},Ze={class:`flex flex-wrap items-baseline justify-between gap-x-4 gap-y-2`},Qe={class:`legend flex flex-wrap gap-x-4 gap-y-1.5 text-xs text-muted`},$e=[`href`,`title`],et={key:1,class:`text-xs text-warn`},tt={key:2,class:`text-xs text-muted`},nt={class:`mb-3 flex flex-wrap items-center gap-1 border-b border-default`,"aria-label":`View`},rt={key:0,class:`-mb-px border-b-2 border-primary px-3 py-1.5 text-sm font-medium text-highlighted`,"aria-current":`page`},it={key:0,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},at={class:`text-[0.9375rem] font-medium`},ot={class:`text-sm text-muted`},st={key:1,class:`text-sm text-warn`},ct={class:`text-xs text-muted`},lt={class:`rounded bg-accented px-1 py-0.5`},ut={key:1,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},dt={class:`w-full border-collapse font-mono text-[0.8125rem] tabular-nums`},ft={class:`px-2.5 py-1.5`},pt=[`href`],mt={class:`px-2.5 py-1.5 text-right`},ht={class:`px-2.5 py-1.5 text-right`},gt={class:`w-2/5 px-2.5 py-1.5`},_t={key:2,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},vt={open:``},yt={class:`mt-2.5 overflow-x-auto`},bt={class:`data w-full min-w-[38rem] border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},xt=[`title`],St={key:0,class:`text-xs text-dimmed`},Ct={key:1,class:`text-xs text-dimmed`},wt={class:`border-b border-muted px-2.5 py-1.5 text-right font-medium`},Tt={class:`text-xs text-muted`},Et={class:`rounded bg-accented px-1 py-0.5`},Dt={key:3,class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},Ot=[`data-biller`],kt={class:`text-sm`},At={key:1,class:`text-muted`},jt={key:2,class:`text-muted`},Mt={key:0,class:`overflow-x-auto`},Nt={class:`data w-full border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},Pt={key:0,class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},Ft={key:1,class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},It=[`title`],Lt={key:0,class:`border-b border-muted px-2.5 py-1 text-right`},Rt={class:`border-b border-muted px-2.5 py-1 text-right`},zt={class:`border-b border-muted px-2.5 py-1 text-right`},Bt={class:`border-b border-muted px-2.5 py-1 text-right`},Vt={key:1,class:`border-b border-muted px-2.5 py-1 text-right`},Ht={class:`border-t border-default pt-3.5 text-xs text-dimmed`},Ut={class:`mt-2 grid gap-1.5`},Wt=[`href`],Gt={key:2},Kt=[`href`],qt={key:2},Jt=[`href`],Yt=[`href`],Xt={class:`mb-4 flex flex-wrap items-center gap-x-4 gap-y-2`},Zt={key:0,class:`flex items-center gap-1`,"aria-label":`Cost groups`},Qt={key:0,class:`rounded-md bg-accented px-2.5 py-1 text-xs font-medium text-highlighted`,"aria-current":`page`},$t={class:`mb-5 grid gap-2 rounded-lg border border-default bg-elevated px-5 py-4`},en={class:`flex flex-wrap items-center gap-x-3 gap-y-1`},tn={class:`font-mono text-xs tabular-nums text-muted`,"data-snapshot-status":``},nn=[`disabled`],rn={key:1,class:`text-xs text-error`,role:`status`,"data-snapshot-error":``},an=a({__name:`CostsPage`,setup(a){let s=y(`costs`),d=b(s?.report??null),h=S(()=>s?.groups??[]),O=S(()=>s?.group??d.value?.group??``),M=b(s?.snapshot??null),ce=se(void 0,6e4),N=S(()=>M.value?re(M.value,ce.value):``),P=S(()=>s?.view??`daily`),F=b(s&&s.view!==`daily`?s.by??null:null),I=[{view:`daily`,tab:`Daily`,subtitle:``},{view:`users`,tab:`By user`,subtitle:`Who started the runs · LLM from their tokens through the price table · cloud allocated by wall-clock`},{view:`threads`,tab:`By thread`,subtitle:`The thread each run ran in · LLM from its tokens through the price table · cloud allocated by wall-clock`},{view:`channels`,tab:`By channel`,subtitle:`The channel each run ran in · LLM from its tokens through the price table · cloud allocated by wall-clock`},{view:`agents`,tab:`By agent`,subtitle:`The agent each run ran on · LLM from its tokens through the price table · cloud allocated by wall-clock`},{view:`models`,tab:`By model`,subtitle:`The model each turn ran on · LLM from its tokens through the price table · cloud is not split by model`}],L=S(()=>I.find(e=>e.view===P.value)??I[0]),R=S(()=>s?.canSnapshot===!0),z=S(()=>typeof window>`u`?null:new URLSearchParams(window.location.search).get(`days`)),le=e=>`/costs/${O.value}${e}${z.value?`?days=${z.value}`:``}`,B=s?.snapshot?.snapshot?.takenAt??null,V=B,H=null;async function ue(){try{let[e,t]=await Promise.all([fetch(le(`.json`),{credentials:`same-origin`}),P.value===`daily`?Promise.resolve(null):fetch(le(`/${P.value}.json`),{credentials:`same-origin`})]);return e.ok?(d.value=await e.json(),t?.ok&&(F.value=await t.json()),!0):!1}catch{return!1}}function U(){if(H||V===null||V===B)return;let e=V;H=ue().then(t=>{t&&(B=e)}).finally(()=>{H=null,V!==e&&U()})}function de(e){M.value=e;let t=e.snapshot?.takenAt??null;t&&(V=t,U())}let fe=ae(),W=null;m(()=>{O.value&&(W=fe(`/costs/${O.value}?stream=1`),W.onmessage=e=>{let t=j(e.data);t&&de(t)})}),ee(()=>W?.close());let G=b(!1),K=b(``);async function q(){G.value=!0,K.value=``;let e=await oe(fetch,`costs.snapshot`,{});e.ok||(K.value=e.failure.message),G.value=!1}function J(e,t,n){let r=[`days=${t}`];return n!==`daily`&&r.push(`view=${n}`),`/costs/${e}?${r.join(`&`)}`}let Y=S(()=>d.value?T(d.value):[]),X=S(()=>d.value?ie(d.value,Y.value):null),Z=S(()=>d.value?k(d.value):null),pe=S(()=>d.value?w(d.value):[]),Q=S(()=>d.value?te(d.value):null),me=S(()=>d.value?ne(d.value):``);function he(e){let t=Q.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 ge(e){let t=Q.value;if(t)return e===`LLM (Anthropic)`?t.anthropic:e===`Durable Objects`?t.durableObjects:e===`Workers · storage · R2`?t.workers:t.containers}let _e=S(()=>{let e=d.value,t=Z.value;if(!e||!t)return``;let n=t.projection,r=`cloud ${D(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 ${D(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}`}`}),an=S(()=>d.value?[...d.value.days].reverse():[]),on=S(()=>(d.value?.billers??[]).map(e=>({...e,days:[...e.days].reverse(),unpricedTokens:e.days.reduce((e,t)=>e+(t.unpricedTokens??0),0)}))),sn=[1,7,30],cn=e=>e===1?`today`:`${e}d`,ln=S(()=>{let e=d.value,t=Z.value;if(!e||!t)return``;if(!e.llmAvailable)return`LLM spend not configured`;let n=[];return t.llm.yesterday!==void 0&&n.push(`yesterday ${D(t.llm.yesterday)}`),t.llm.today&&n.push(`today ${D(t.llm.today.usd)}${t.llm.today.estimated?` (estimate)`:``}`),n.length?n.join(` · `):`in range`});function $(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(a,s)=>{let m=l(`RouterLink`);return d.value&&Z.value?(f(),x(e,{key:0,title:`${d.value.label} spend`,nav:`costs`},{default:u(()=>[p(`div`,ye,[p(`nav`,be,[(f(),t(v,null,n(sn,e=>(f(),t(v,{key:e},[e===d.value.range.days?(f(),t(`span`,xe,i(cn(e)),1)):(f(),x(m,{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`,to:J(d.value.group,e,P.value)},{default:u(()=>[_(i(cn(e)),1)]),_:2},1032,[`to`]))],64))),64))]),h.value.length>1?(f(),t(`nav`,Se,[(f(!0),t(v,null,n(h.value,e=>(f(),t(v,{key:e},[e===d.value.group?(f(),t(`span`,Ce,i(e),1)):(f(),x(m,{key:1,class:`rounded-md px-2.5 py-1 text-xs text-muted no-underline hover:bg-elevated hover:text-highlighted`,to:J(e,d.value.range.days,P.value)},{default:u(()=>[_(i(e),1)]),_:2},1032,[`to`]))],64))),128))])):c(``,!0),p(`p`,we,[_(i($(d.value.range.from))+` → `+i($(d.value.range.to))+` · `+i(d.value.range.days)+`d`,1),d.value.range.partialLastDay?(f(),t(v,{key:0},[_(` · today partial`)],64)):c(``,!0)]),N.value?(f(),t(`div`,Te,[p(`p`,Ee,i(N.value),1),R.value?(f(),t(`button`,{key:0,type:`button`,class:`rounded-md border border-default px-2 py-0.5 text-xs text-muted hover:bg-elevated hover:text-highlighted disabled:cursor-not-allowed disabled:opacity-60`,disabled:G.value||M.value?.inFlight!==null,"data-snapshot-now":``,onClick:q},i(M.value?.inFlight?`Taking…`:`Snapshot now`),9,De)):c(``,!0),K.value?(f(),t(`span`,Oe,i(K.value),1)):c(``,!0)])):c(``,!0)]),p(`section`,ke,[Z.value.yesterday?(f(),t(`div`,Ae,[s[0]||=p(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Yesterday`,-1),p(`span`,je,i(g(D)(Z.value.yesterday.total)),1),p(`span`,Me,i(Z.value.yesterday.date)+` · last full day`,1)])):(f(),t(`div`,Ne,[s[1]||=p(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Today so far`,-1),p(`span`,Pe,i(Z.value.today?g(D)(Z.value.today.total):`—`),1),p(`span`,Fe,i(Z.value.today?`${Z.value.today.date} · partial day, UTC`:`no day in range`),1)])),p(`div`,Ie,[s[2]||=p(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`7-day average`,-1),p(`span`,Le,i(Z.value.avg7===void 0?`—`:g(D)(Z.value.avg7)),1),p(`span`,Re,i(Z.value.avg7===void 0?`no full day yet in this range`:`per day, full days only`),1)]),p(`div`,ze,[s[3]||=p(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Projected month`,-1),p(`span`,Be,i(g(D)(Z.value.projection.monthUsd,0)),1),p(`span`,Ve,i(_e.value),1)]),p(`div`,He,[s[4]||=p(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`LLM spend`,-1),p(`span`,Ue,i(d.value.llmAvailable?g(D)(Z.value.llm.range):`—`),1),p(`span`,We,i(ln.value),1)]),p(`div`,Ge,[s[6]||=p(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Share of account`,-1),p(`span`,Ke,i(Z.value.accountShare)+`%`,1),p(`span`,qe,[_(i(g(D)(d.value.totals.cloudUsd))+` of `+i(g(D)(d.value.account.cloudUsd))+` on `,1),Q.value?(f(),t(`a`,{key:0,class:`text-primary hover:underline`,href:Q.value.account,target:`_blank`,rel:`noopener noreferrer`,title:`Cloudflare account ${d.value.account.id}`},i(me.value),9,Je)):c(``,!0),s[5]||=_(` · Cloudflare spend in range · `,-1),Q.value?(f(),t(`a`,{key:1,class:`text-primary hover:underline`,href:Q.value.billing,target:`_blank`,rel:`noopener noreferrer`},`billing`,8,Ye)):c(``,!0)])])]),p(`section`,Xe,[p(`div`,Ze,[s[7]||=p(`div`,null,[p(`h2`,{class:`text-[0.9375rem] font-medium`},`Daily cost`),p(`p`,{class:`text-sm text-muted`},`Stacked by component · USD list price`)],-1),p(`div`,Qe,[(f(!0),t(v,null,n(Y.value,(e,n)=>(f(),t(`a`,{key:e,class:`inline-flex items-center gap-1.5 no-underline hover:text-highlighted hover:underline`,href:ge(e),target:`_blank`,rel:`noopener noreferrer`,title:`Open where ${e} is billed`},[p(`i`,{class:o([`inline-block size-2.5 rounded-xs`,g(C)[n%g(C).length]])},null,2),_(i(e),1)],8,$e))),128))])]),X.value?(f(),x(A,{key:0,model:X.value,label:`Daily cost, stacked by component`},null,8,[`model`])):c(``,!0),d.value.llmAvailable?d.value.days.some(e=>e.llmEstimated)?(f(),t(`p`,tt,[s[9]||=_(` 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),d.value.days.some(e=>e.llmUnpricedTokens>0)?(f(),t(v,{key:0},[_(` Some tokens ran under a model this page has no price for and are not in the estimate. `)],64)):c(``,!0)])):c(``,!0):(f(),t(`p`,et,[...s[8]||=[_(` LLM spend not configured — set `,-1),p(`code`,null,`ANTHROPIC_ADMIN_KEY`,-1),_(` and the group's `,-1),p(`code`,null,`anthropicWorkspaceId`,-1),_(` to layer it in. `,-1)]]))]),p(`nav`,nt,[(f(),t(v,null,n(I,e=>(f(),t(v,{key:e.view},[e.view===P.value?(f(),t(`span`,rt,i(e.tab),1)):(f(),x(m,{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`,to:J(d.value.group,d.value.range.days,e.view)},{default:u(()=>[_(i(e.tab),1)]),_:2},1032,[`to`]))],64))),64))]),P.value===`daily`?c(``,!0):(f(),t(`section`,it,[p(`div`,null,[p(`h2`,at,`Cost `+i(L.value.tab.toLowerCase()),1),p(`p`,ot,i(L.value.subtitle),1)]),F.value?(f(),x(ve,{key:0,report:F.value},null,8,[`report`])):(f(),t(`p`,st,` The `+i(L.value.tab.toLowerCase())+` report did not load with this page. `,1)),p(`p`,ct,[s[10]||=_(` Machine-readable twin: `,-1),p(`code`,lt,`GET /costs/`+i(d.value.group)+`/`+i(P.value)+`.json`,1),s[11]||=_(` (same Access gate). `,-1)])])),P.value===`daily`?(f(),t(`section`,ut,[s[12]||=p(`div`,null,[p(`h2`,{class:`text-[0.9375rem] font-medium`},`What each cloud dollar buys`)],-1),p(`table`,dt,[p(`tbody`,null,[(f(!0),t(v,null,n(pe.value,e=>(f(),t(`tr`,{key:e.label,class:`border-b border-muted`},[p(`td`,ft,[he(e.label)?(f(),t(`a`,{key:0,class:`no-underline hover:text-highlighted hover:underline`,href:he(e.label),target:`_blank`,rel:`noopener noreferrer`,title:`Open where this is billed on Cloudflare`},i(e.label),9,pt)):(f(),t(v,{key:1},[_(i(e.label),1)],64))]),p(`td`,mt,i(g(D)(e.usd)),1),p(`td`,ht,i(Math.round(e.percent))+`%`,1),p(`td`,gt,[p(`i`,{class:`block h-2.5 rounded-xs bg-primary opacity-75`,style:r({width:`${e.percent.toFixed(1)}%`})},null,4)])]))),128))])])])):c(``,!0),P.value===`daily`?(f(),t(`section`,_t,[p(`details`,vt,[s[15]||=p(`summary`,{class:`cursor-pointer text-sm text-muted`},`Table view — daily cost by component (USD)`,-1),p(`div`,yt,[p(`table`,bt,[p(`thead`,null,[p(`tr`,null,[s[13]||=p(`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),(f(!0),t(v,null,n(Y.value,e=>(f(),t(`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`},i(e),1))),128)),s[14]||=p(`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)])]),p(`tbody`,null,[(f(!0),t(v,null,n(an.value,e=>(f(),t(`tr`,{key:e.date},[p(`td`,{class:`border-b border-muted px-2.5 py-1.5`,title:e.date},[_(i($(e.date))+` `,1),d.value.range.partialLastDay&&e.date===d.value.range.to?(f(),t(`span`,St,`(partial day`+i(e.llmEstimated?` · LLM estimated`:``)+`)`,1)):e.llmEstimated?(f(),t(`span`,Ct,`(LLM estimated)`)):c(``,!0)],8,xt),(f(!0),t(v,null,n(Y.value,n=>(f(),t(`td`,{key:n,class:`border-b border-muted px-2.5 py-1.5 text-right`},i(g(D)(g(E)(e,n),3)),1))),128)),p(`td`,wt,i(g(D)(e.total,3)),1)]))),128))])])])]),p(`p`,Tt,[s[16]||=_(` Machine-readable twin: `,-1),p(`code`,Et,`GET /costs/`+i(d.value.group)+`.json`,1),s[17]||=_(` (same Access gate). `,-1)])])):c(``,!0),P.value===`daily`&&on.value.length?(f(),t(`section`,Dt,[s[22]||=p(`div`,null,[p(`h2`,{class:`text-[0.9375rem] font-medium`},`Invoice tie-out by biller`),p(`p`,{class:`text-xs text-muted`},[_(` Each biller's own invoice beside the summed `),p(`code`,null,`model.turn`),_(` dollars its runs attributed — an aggregator's fee against the summed fees, its BYOK upstream against the remainder. Attributed is the meter's charged figure — each turn's own `),p(`code`,null,`usd`),_(` (the provider's, the operator's or the registry's price at the time) — never the price table's repricing the dimension tabs show, so the two need not agree. `)])],-1),(f(!0),t(v,null,n(on.value,e=>(f(),t(`div`,{key:e.biller,class:`grid gap-1.5`,"data-biller":e.biller},[p(`p`,kt,[p(`b`,null,i(e.biller),1),e.invoice?(f(),t(v,{key:0},[_(` · invoice `+i(g(D)(e.totals.invoiceUsd,4))+` · attributed `+i(g(D)(e.totals.attributedUsd,4)),1)],64)):(f(),t(`span`,At,` · no invoice — the block names no invoice source`)),e.unpricedTokens>0?(f(),t(`span`,jt,` · `+i(e.unpricedTokens.toLocaleString(`en-US`))+` tokens unpriced — not in the attributed figure`,1)):c(``,!0)]),e.days.length?(f(),t(`div`,Mt,[p(`table`,Nt,[p(`thead`,null,[p(`tr`,null,[s[18]||=p(`th`,{class:`border-b border-muted px-2.5 py-1 text-left text-xs font-medium text-muted`},`Date`,-1),e.invoice?(f(),t(`th`,Pt,` Invoice `)):c(``,!0),s[19]||=p(`th`,{class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},`Attributed`,-1),s[20]||=p(`th`,{class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},` Fee (invoice / rows) `,-1),s[21]||=p(`th`,{class:`border-b border-muted px-2.5 py-1 text-right text-xs font-medium text-muted`},` Upstream (invoice / remainder) `,-1),e.unpricedTokens>0?(f(),t(`th`,Ft,` Unpriced tokens `)):c(``,!0)])]),p(`tbody`,null,[(f(!0),t(v,null,n(e.days,n=>(f(),t(`tr`,{key:n.date},[p(`td`,{class:`border-b border-muted px-2.5 py-1`,title:n.date},i($(n.date)),9,It),e.invoice?(f(),t(`td`,Lt,i(n.invoiceUsd===void 0?`—`:g(D)(n.invoiceUsd,4)),1)):c(``,!0),p(`td`,Rt,i(g(D)(n.attributedUsd,4)),1),p(`td`,zt,[n.invoiceFeeUsd!==void 0||n.attributedFeeUsd!==void 0?(f(),t(v,{key:0},[_(i(n.invoiceFeeUsd===void 0?`—`:g(D)(n.invoiceFeeUsd,4))+` / `+i(n.attributedFeeUsd===void 0?`—`:g(D)(n.attributedFeeUsd,4)),1)],64)):(f(),t(v,{key:1},[_(`—`)],64))]),p(`td`,Bt,[n.invoiceByokUsd!==void 0||n.attributedUpstreamUsd!==void 0?(f(),t(v,{key:0},[_(i(n.invoiceByokUsd===void 0?`—`:g(D)(n.invoiceByokUsd,4))+` / `+i(n.attributedUpstreamUsd===void 0?`—`:g(D)(n.attributedUpstreamUsd,4)),1)],64)):(f(),t(v,{key:1},[_(`—`)],64))]),e.unpricedTokens>0?(f(),t(`td`,Vt,i((n.unpricedTokens??0).toLocaleString(`en-US`)),1)):c(``,!0)]))),128))])])])):c(``,!0)],8,Ot))),128))])):c(``,!0),p(`footer`,Ht,[p(`details`,null,[s[30]||=p(`summary`,{class:`cursor-pointer text-muted`},`How these numbers are computed`,-1),p(`div`,Ut,[s[28]||=p(`div`,null,[p(`b`,null,`Snapshot.`),_(` Both billing sources and the run history are read once over the widest range this page offers and kept as a snapshot; every figure here, the JSON twins and the dimension tabs are arithmetic over it, with `),p(`em`,null,`today`),_(` the day it was taken. The line under the range says when that was, how old it is and when the next one is due (`),p(`code`,null,`costs.snapshot.everyHours`),_(`, daily by default); `),p(`code`,null,`costs snapshot`),_(` takes one now. 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. The invoice tie-out's attributed side is different money: the meter's charged figure from each turn's own `),p(`code`,null,`usd`),_(`, never the price table's repricing the dimension tabs show, with the tokens no turn priced counted beside it as unpriced. `)],-1),s[29]||=p(`div`,null,[p(`b`,null,`Method.`),_(` Cloudflare GraphQL Analytics, every meter a Workers deployment is billed on: `),p(`code`,null,`containersUsageAdaptiveGroups`),_(` (cpuTimeSec, allocatedMemory, allocatedDisk per app per UTC day), `),p(`code`,null,`durableObjectsPeriodicGroups`),_(` (billable `),p(`code`,null,`duration`),_(` GB-s and SQLite rows read and written per namespace), `),p(`code`,null,`durableObjectsInvocationsAdaptiveGroups`),_(` (requests per namespace), `),p(`code`,null,`durableObjectsSqlStorageGroups`),_(` (bytes stored), `),p(`code`,null,`workersInvocationsAdaptive`),_(` (requests, CPU time), `),p(`code`,null,`r2StorageAdaptiveGroups`),_(` and `),p(`code`,null,`r2OperationsAdaptiveGroups`),_(` (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),p(`div`,null,[s[23]||=p(`b`,null,`Scope.`,-1),s[24]||=_(` Attributed to this group: the Workers `,-1),(f(!0),t(v,null,n(d.value.attribution.workers,(e,n)=>(f(),t(v,{key:e},[n>0?(f(),t(v,{key:0},[_(`, `)],64)):c(``,!0),Q.value?(f(),t(`a`,{key:1,class:`font-mono hover:underline`,href:Q.value.worker(e),target:`_blank`,rel:`noopener noreferrer`},i(e),9,Wt)):(f(),t(`code`,Gt,i(e),1))],64))),128)),_(`, every Durable Object namespace they host (`+i(Object.keys(d.value.attribution.durableObjectNamespaces).length)+`), the R2 buckets named after them (`,1),(f(!0),t(v,null,n(Object.keys(d.value.attribution.r2Buckets),(e,n)=>(f(),t(v,{key:e},[n>0?(f(),t(v,{key:0},[_(`, `)],64)):c(``,!0),Q.value?(f(),t(`a`,{key:1,class:`font-mono hover:underline`,href:Q.value.bucket(e),target:`_blank`,rel:`noopener noreferrer`},i(e),9,Kt)):(f(),t(`code`,qt,i(e),1))],64))),128)),Object.keys(d.value.attribution.r2Buckets).length===0?(f(),t(v,{key:0},[_(`none`)],64)):c(``,!0),s[25]||=_(`), and the container apps mapped in `,-1),p(`code`,null,`costs.groups.`+i(d.value.group),1),_(` (`+i(Object.keys(d.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),Q.value?(f(),t(`a`,{key:1,class:`hover:underline`,href:Q.value.account,target:`_blank`,rel:`noopener noreferrer`},`Cloudflare dashboard`,8,Jt)):c(``,!0),s[26]||=_(` for the account `,-1),p(`code`,null,i(d.value.account.id),1),_(i(d.value.account.name?` (${d.value.account.name})`:``)+`, and `,1),Q.value?(f(),t(`a`,{key:2,class:`hover:underline`,href:Q.value.anthropic,target:`_blank`,rel:`noopener noreferrer`},`Anthropic's cost page`,8,Yt)):c(``,!0),s[27]||=_(` for the LLM line. `,-1)])])])])]),_:1},8,[`title`])):(f(),x(e,{key:1,title:`${O.value} spend`,nav:`costs`},{default:u(()=>[p(`div`,Xt,[h.value.length>1?(f(),t(`nav`,Zt,[(f(!0),t(v,null,n(h.value,e=>(f(),t(v,{key:e},[e===O.value?(f(),t(`span`,Qt,i(e),1)):(f(),x(m,{key:1,class:`rounded-md px-2.5 py-1 text-xs text-muted no-underline hover:bg-elevated hover:text-highlighted`,to:`/costs/${e}`},{default:u(()=>[_(i(e),1)]),_:2},1032,[`to`]))],64))),128))])):c(``,!0)]),p(`section`,$t,[s[31]||=p(`h2`,{class:`text-sm font-medium text-highlighted`},`Nothing to show yet`,-1),p(`div`,en,[p(`p`,tn,i(N.value),1),R.value?(f(),t(`button`,{key:0,type:`button`,class:`rounded-md border border-default px-2 py-0.5 text-xs text-muted hover:bg-elevated hover:text-highlighted disabled:cursor-not-allowed disabled:opacity-60`,disabled:G.value||M.value?.inFlight!==null,"data-snapshot-now":``,onClick:q},i(M.value?.inFlight?`Taking…`:`Snapshot now`),9,nn)):c(``,!0),K.value?(f(),t(`span`,rn,i(K.value),1)):c(``,!0)]),s[32]||=p(`p`,{class:`text-xs text-dimmed`},[_(` The page prices a stored snapshot of both billing sources, never a live read; the figures appear here the moment the first one lands (this page listens for it), or take one now with `),p(`code`,null,`costs snapshot`),_(`. `)],-1)])]),_:1},8,[`title`]))}}});export{an as default};
@@ -1 +1 @@
1
- import{t as e}from"./AppShell-CSXDCV4x.js";import{An as t,Cn as n,Cr as r,Li as i,Mn as ee,Pi as a,Sn as o,Tr as te,Xr as s,_r as c,bn as l,ji as u,kn as d,ln as f,o as p,xn as m,yn as h}from"./browser-B6T5hjfR.js";import{a as g,c as ne,d as re,i as ie,l as _,n as ae,o as v,r as y,s as b,t as x,u as oe}from"./delivery-CTdOqpVK.js";import{t as se}from"./wallClock-DmaC1sKA.js";import"./budgets-CbIyPAER.js";function S(e,t){return e.truncated&&e.completeFrom!==void 0&&Date.parse(`${t}T00:00:00Z`)<Date.parse(e.completeFrom)}Object.freeze({reviewers:[],agentLogins:[],agentCoauthors:[]}),Object.freeze({default:60,min:5,max:1440});var C={class:`text-xs text-muted`},w={key:1,class:`text-highlighted`},T={class:`mb-4 flex flex-wrap items-center gap-x-4 gap-y-2`},E={key:0,class:`flex items-center gap-1`,"aria-label":`Repositories`},D={key:0,class:`rounded-md bg-accented px-2.5 py-1 text-xs font-medium text-highlighted`,"aria-current":`page`},O={class:`font-mono text-sm tabular-nums text-muted`},k={class:`mb-5 grid gap-3`},A={key:0,class:`text-sm text-muted`},j={class:`grid grid-cols-[repeat(auto-fit,minmax(190px,1fr))] gap-3`},M={class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},N={class:`font-mono text-2xl font-medium tabular-nums`},P={class:`text-xs text-muted`},F={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},I={class:`overflow-x-auto`},L={class:`weeks w-full min-w-[52rem] border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},R=[`title`],z={key:0,class:`ml-1 text-xs`},B={key:0,class:`text-xs text-muted`},V={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},ce={key:0,class:`text-sm text-muted`},H={key:1,class:`overflow-x-auto`},U={class:`units w-full min-w-[52rem] border-collapse font-mono text-[0.8125rem] tabular-nums`},W=[`href`],G={key:1,class:`text-dimmed`},le=[`title`],ue=[`href`],de={class:`text-xs text-muted`},fe={class:`rounded bg-accented px-1 py-0.5`},pe={class:`border-t border-default pt-3.5 text-xs text-dimmed`},me={key:0,class:`mb-2 font-mono tabular-nums text-muted`},he={class:`mt-2 grid gap-1.5`},K=`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-xs font-medium text-muted whitespace-nowrap`,q=`border-b border-muted px-2.5 py-1.5`,J=ee({__name:`DeliveryPage`,setup(ee){let J=p(`delivery`),Y=h(()=>J?.report??null),X=h(()=>J?.repos??[]),ge=h(()=>Y.value?oe(Y.value):[]),Z=h(()=>Y.value?ae(Y.value):void 0),Q=e=>Y.value?S(Y.value,e):!1,$=h(()=>Y.value?.weeks.some(e=>Q(e.week))??!1),_e=[1,2,4,8,13],ve=se(void 0,6e4),ye=typeof window>`u`?``:window.location.search;return(ee,p)=>{let h=te(`RouterLink`);return Y.value?(c(),m(e,{key:0,title:`${Y.value.repo} delivery`,nav:`delivery`},{actions:s(()=>[l(`span`,C,[(c(),n(f,null,r(_e,(e,t)=>(c(),n(f,{key:e},[t>0?(c(),n(f,{key:0},[d(` · `)],64)):o(``,!0),e===Y.value.range.weeks?(c(),n(`b`,w,i(e)+`w`,1)):(c(),m(h,{key:2,class:`text-primary hover:underline`,to:`/delivery/${Y.value.repo}?weeks=${e}`},{default:s(()=>[d(i(e)+`w`,1)]),_:2},1032,[`to`]))],64))),64))])]),default:s(()=>[l(`div`,T,[X.value.length>1?(c(),n(`nav`,E,[(c(!0),n(f,null,r(X.value,e=>(c(),n(f,{key:e},[e===Y.value.repo?(c(),n(`span`,D,i(e),1)):(c(),m(h,{key:1,class:`rounded-md px-2.5 py-1 text-xs text-muted no-underline hover:bg-elevated hover:text-highlighted`,to:`/delivery/${e}`},{default:s(()=>[d(i(e),1)]),_:2},1032,[`to`]))],64))),128))])):o(``,!0),l(`p`,O,i(u(v)(Y.value.range.since))+` → `+i(u(v)(Y.value.range.until))+` · `+i(Y.value.range.weeks)+`w · weeks start Monday, UTC `,1)]),l(`section`,k,[Z.value?(c(),n(`p`,A,i(Z.value),1)):o(``,!0),l(`div`,j,[(c(!0),n(f,null,r(ge.value,e=>(c(),n(`div`,{key:e.label,class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},[l(`span`,M,i(e.label),1),l(`span`,N,i(e.value),1),l(`span`,P,i(e.note),1)]))),128))])]),l(`section`,F,[p[0]||=l(`div`,null,[l(`h2`,{class:`text-[0.9375rem] font-medium`},`By week`),l(`p`,{class:`text-sm text-muted`},`One row per Monday-start week · merged pull requests only`)],-1),l(`div`,I,[l(`table`,L,[l(`thead`,null,[l(`tr`,null,[l(`th`,{class:a([K,`text-left`])},`Week`,2),l(`th`,{class:a([K,`text-right`])},`Merged`,2),l(`th`,{class:a([K,`text-right`])},`Agent-authored`,2),l(`th`,{class:a([K,`text-right`])},`Issue → merge`,2),l(`th`,{class:a([K,`text-right`])},`First-pass CI`,2),l(`th`,{class:a([K,`text-right`])},`Rounds / PR`,2),l(`th`,{class:a([K,`text-right`])},`Findings`,2),l(`th`,{class:a([K,`text-right`])},`No human edit`,2),l(`th`,{class:a([K,`text-right`])},`Agent run min`,2)])]),l(`tbody`,null,[(c(!0),n(f,null,r(Y.value.weeks,e=>(c(),n(`tr`,{key:e.week,class:a(Q(e.week)?`text-dimmed`:``)},[l(`td`,{class:a(q),title:`${e.week} → ${e.until}`},[d(i(u(v)(e.week))+` – `+i(u(v)(e.until))+` `,1),Q(e.week)?(c(),n(`span`,z,`(incomplete)`)):o(``,!0)],8,R),l(`td`,{class:a([q,`text-right font-medium`])},i(e.prsMerged),3),l(`td`,{class:a([q,`text-right`])},i(e.agentAuthoredPrs),3),l(`td`,{class:a([q,`text-right`])},i(u(g)(e.leadTimeHours.median)),3),l(`td`,{class:a([q,`text-right`])},i(u(x)(e)),3),l(`td`,{class:a([q,`text-right`])},i(u(ne)(e.reviewRounds.perPr)),3),l(`td`,{class:a([q,`text-right`])},i(u(y)(e)),3),l(`td`,{class:a([q,`text-right`])},i(u(b)(e.findings.noHumanEditShare)),3),l(`td`,{class:a([q,`text-right`])},i(e.agentRuns.minutes.toFixed(0)),3)],2))),128))])])]),$.value&&Y.value.completeFrom?(c(),n(`p`,B,` Incomplete weeks hold the newest pull requests the read reached — it is complete from `+i(u(_)(Y.value.completeFrom))+` — so their numbers are a floor on the merges, not the week's. `,1)):o(``,!0)]),l(`section`,V,[p[3]||=l(`div`,null,[l(`h2`,{class:`text-[0.9375rem] font-medium`},`By unit`),l(`p`,{class:`text-sm text-muted`},` One row per board issue the pull requests link · the issue's opening starts the clock `)],-1),Y.value.units.length===0?(c(),n(`p`,ce,`Nothing merged in range.`)):(c(),n(`div`,H,[l(`table`,U,[l(`thead`,null,[l(`tr`,null,[l(`th`,{class:a([K,`text-left`])},`Issue`,2),l(`th`,{class:a([K,`text-left`])},`Unit`,2),l(`th`,{class:a([K,`text-left`])},`PRs`,2),l(`th`,{class:a([K,`text-right`])},`Issue → merge`,2),l(`th`,{class:a([K,`text-right`])},`First-pass CI`,2),l(`th`,{class:a([K,`text-right`])},`Rounds`,2),l(`th`,{class:a([K,`text-right`])},`Findings`,2),l(`th`,{class:a([K,`text-right`])},`No human edit`,2)])]),l(`tbody`,null,[(c(!0),n(f,null,r(Y.value.units,e=>(c(),n(`tr`,{key:e.issue??`none`},[l(`td`,{class:a([q,`whitespace-nowrap`])},[e.issue===null?(c(),n(`span`,G,`—`)):(c(),n(`a`,{key:0,class:`text-primary hover:underline`,href:`https://github.com/${Y.value.repo}/issues/${e.issue}`},`#`+i(e.issue),9,W))],2),l(`td`,{class:a([q,`max-w-[28rem] truncate font-sans`]),title:e.title},i(e.title),11,le),l(`td`,{class:a([q,`whitespace-nowrap`])},[(c(!0),n(f,null,r(e.prs,(e,t)=>(c(),n(f,{key:e},[t>0?(c(),n(f,{key:0},[d(`, `)],64)):o(``,!0),l(`a`,{class:`text-primary hover:underline`,href:`https://github.com/${Y.value.repo}/pull/${e}`},i(e),9,ue)],64))),128))],2),l(`td`,{class:a([q,`text-right`])},i(u(g)(e.leadTimeHours.median)),3),l(`td`,{class:a([q,`text-right`])},i(u(x)(e)),3),l(`td`,{class:a([q,`text-right`])},i(e.reviewRounds.verdicts),3),l(`td`,{class:a([q,`text-right`])},i(u(y)(e)),3),l(`td`,{class:a([q,`text-right`])},i(u(b)(e.findings.noHumanEditShare)),3)]))),128))])])])),l(`p`,de,[p[1]||=d(` Machine-readable twin: `,-1),l(`code`,fe,`GET /delivery/`+i(Y.value.repo)+`.json`,1),p[2]||=d(` (same gate). `,-1)])]),l(`footer`,pe,[Y.value.snapshotAt?(c(),n(`p`,me,[d(` As of `+i(u(_)(Y.value.snapshotAt))+`, `+i(u(re)(Y.value.snapshotAt,u(ve)))+` · `,1),t(h,{class:`text-primary hover:underline`,to:`/delivery/${Y.value.repo}${u(ie)(u(ye))}`},{default:s(()=>[...p[4]||=[d(`read GitHub now`,-1)]]),_:1},8,[`to`])])):o(``,!0),l(`details`,null,[p[14]||=l(`summary`,{class:`cursor-pointer text-muted`},`How these numbers are computed`,-1),l(`div`,he,[p[12]||=l(`div`,null,[l(`b`,null,`Snapshot.`),d(` GitHub's record of the merged pull requests (each one's timeline and its branch's workflow runs, the board issue its body links) is read on an interval and kept as a snapshot the page, its JSON twin and `),l(`code`,null,`delivery report`),d(` serve; `),l(`code`,null,`?fresh=1`),d(` reads GitHub now. The run history you may see joins on every load. `)],-1),p[13]||=l(`div`,null,[l(`b`,null,`Issue → merge`),d(` runs from the linked board issue's opening (a closing keyword or a `),l(`code`,null,`board item`),d(` reference in the body) to the merge; a pull request that links no issue counts from its own opening. `),l(`b`,null,`First-pass CI`),d(` is green when every pull-request-triggered workflow run (`),l(`code`,null,`pull_request`),d(`, `),l(`code`,null,`pull_request_target`),d(`) on the first head succeeded at its first attempt — a rerun or a red run fails it; a head with no such run is not counted. `),l(`b`,null,`Review rounds`),d(` are the review agent's verdicts; a `),l(`i`,null,`fix round`),d(` is a verdict that followed a push. `),l(`b`,null,`No human edit`),d(` is the share of the agent's findings on pull requests where every push after the first verdict was an agent's: a bot login, or a commit co-authored by an agent. `),l(`b`,null,`Agent run minutes`),d(` are the finished runs of this repository that named a pull request. `)],-1),l(`div`,null,[p[6]||=l(`b`,null,`Identities.`,-1),p[7]||=d(` Verdicts by `,-1),l(`code`,null,i(Y.value.identities.reviewers.join(`, `)||`(none configured)`),1),p[8]||=d(`; agent logins end in `,-1),p[9]||=l(`code`,null,`[bot]`,-1),Y.value.identities.agentLogins.length?(c(),n(f,{key:0},[p[5]||=d(`, plus `,-1),l(`code`,null,i(Y.value.identities.agentLogins.join(`, `)),1)],64)):o(``,!0),p[10]||=d(`; agent co-authors named `,-1),l(`code`,null,i(Y.value.identities.agentCoauthors.join(`, `)||`(none)`),1),p[11]||=d(`. `,-1)])])])])]),_:1},8,[`title`])):o(``,!0)}}});export{J as default};
1
+ import{t as e}from"./AppShell-CSXDCV4x.js";import{An as t,Cn as n,Cr as r,Li as i,Mn as ee,Pi as a,Sn as o,Tr as te,Xr as s,_r as c,bn as l,ji as u,kn as d,ln as f,o as p,xn as m,yn as h}from"./browser-B6T5hjfR.js";import{a as g,c as ne,d as re,i as ie,l as _,n as ae,o as v,r as y,s as b,t as x,u as oe}from"./delivery-CTdOqpVK.js";import{t as se}from"./wallClock-DmaC1sKA.js";import"./budgets-c1eumrqD.js";function S(e,t){return e.truncated&&e.completeFrom!==void 0&&Date.parse(`${t}T00:00:00Z`)<Date.parse(e.completeFrom)}Object.freeze({reviewers:[],agentLogins:[],agentCoauthors:[]}),Object.freeze({default:60,min:5,max:1440});var C={class:`text-xs text-muted`},w={key:1,class:`text-highlighted`},T={class:`mb-4 flex flex-wrap items-center gap-x-4 gap-y-2`},E={key:0,class:`flex items-center gap-1`,"aria-label":`Repositories`},D={key:0,class:`rounded-md bg-accented px-2.5 py-1 text-xs font-medium text-highlighted`,"aria-current":`page`},O={class:`font-mono text-sm tabular-nums text-muted`},k={class:`mb-5 grid gap-3`},A={key:0,class:`text-sm text-muted`},j={class:`grid grid-cols-[repeat(auto-fit,minmax(190px,1fr))] gap-3`},M={class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},N={class:`font-mono text-2xl font-medium tabular-nums`},P={class:`text-xs text-muted`},F={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},I={class:`overflow-x-auto`},L={class:`weeks w-full min-w-[52rem] border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},R=[`title`],z={key:0,class:`ml-1 text-xs`},B={key:0,class:`text-xs text-muted`},V={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},ce={key:0,class:`text-sm text-muted`},H={key:1,class:`overflow-x-auto`},U={class:`units w-full min-w-[52rem] border-collapse font-mono text-[0.8125rem] tabular-nums`},W=[`href`],G={key:1,class:`text-dimmed`},le=[`title`],ue=[`href`],de={class:`text-xs text-muted`},fe={class:`rounded bg-accented px-1 py-0.5`},pe={class:`border-t border-default pt-3.5 text-xs text-dimmed`},me={key:0,class:`mb-2 font-mono tabular-nums text-muted`},he={class:`mt-2 grid gap-1.5`},K=`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-xs font-medium text-muted whitespace-nowrap`,q=`border-b border-muted px-2.5 py-1.5`,J=ee({__name:`DeliveryPage`,setup(ee){let J=p(`delivery`),Y=h(()=>J?.report??null),X=h(()=>J?.repos??[]),ge=h(()=>Y.value?oe(Y.value):[]),Z=h(()=>Y.value?ae(Y.value):void 0),Q=e=>Y.value?S(Y.value,e):!1,$=h(()=>Y.value?.weeks.some(e=>Q(e.week))??!1),_e=[1,2,4,8,13],ve=se(void 0,6e4),ye=typeof window>`u`?``:window.location.search;return(ee,p)=>{let h=te(`RouterLink`);return Y.value?(c(),m(e,{key:0,title:`${Y.value.repo} delivery`,nav:`delivery`},{actions:s(()=>[l(`span`,C,[(c(),n(f,null,r(_e,(e,t)=>(c(),n(f,{key:e},[t>0?(c(),n(f,{key:0},[d(` · `)],64)):o(``,!0),e===Y.value.range.weeks?(c(),n(`b`,w,i(e)+`w`,1)):(c(),m(h,{key:2,class:`text-primary hover:underline`,to:`/delivery/${Y.value.repo}?weeks=${e}`},{default:s(()=>[d(i(e)+`w`,1)]),_:2},1032,[`to`]))],64))),64))])]),default:s(()=>[l(`div`,T,[X.value.length>1?(c(),n(`nav`,E,[(c(!0),n(f,null,r(X.value,e=>(c(),n(f,{key:e},[e===Y.value.repo?(c(),n(`span`,D,i(e),1)):(c(),m(h,{key:1,class:`rounded-md px-2.5 py-1 text-xs text-muted no-underline hover:bg-elevated hover:text-highlighted`,to:`/delivery/${e}`},{default:s(()=>[d(i(e),1)]),_:2},1032,[`to`]))],64))),128))])):o(``,!0),l(`p`,O,i(u(v)(Y.value.range.since))+` → `+i(u(v)(Y.value.range.until))+` · `+i(Y.value.range.weeks)+`w · weeks start Monday, UTC `,1)]),l(`section`,k,[Z.value?(c(),n(`p`,A,i(Z.value),1)):o(``,!0),l(`div`,j,[(c(!0),n(f,null,r(ge.value,e=>(c(),n(`div`,{key:e.label,class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},[l(`span`,M,i(e.label),1),l(`span`,N,i(e.value),1),l(`span`,P,i(e.note),1)]))),128))])]),l(`section`,F,[p[0]||=l(`div`,null,[l(`h2`,{class:`text-[0.9375rem] font-medium`},`By week`),l(`p`,{class:`text-sm text-muted`},`One row per Monday-start week · merged pull requests only`)],-1),l(`div`,I,[l(`table`,L,[l(`thead`,null,[l(`tr`,null,[l(`th`,{class:a([K,`text-left`])},`Week`,2),l(`th`,{class:a([K,`text-right`])},`Merged`,2),l(`th`,{class:a([K,`text-right`])},`Agent-authored`,2),l(`th`,{class:a([K,`text-right`])},`Issue → merge`,2),l(`th`,{class:a([K,`text-right`])},`First-pass CI`,2),l(`th`,{class:a([K,`text-right`])},`Rounds / PR`,2),l(`th`,{class:a([K,`text-right`])},`Findings`,2),l(`th`,{class:a([K,`text-right`])},`No human edit`,2),l(`th`,{class:a([K,`text-right`])},`Agent run min`,2)])]),l(`tbody`,null,[(c(!0),n(f,null,r(Y.value.weeks,e=>(c(),n(`tr`,{key:e.week,class:a(Q(e.week)?`text-dimmed`:``)},[l(`td`,{class:a(q),title:`${e.week} → ${e.until}`},[d(i(u(v)(e.week))+` – `+i(u(v)(e.until))+` `,1),Q(e.week)?(c(),n(`span`,z,`(incomplete)`)):o(``,!0)],8,R),l(`td`,{class:a([q,`text-right font-medium`])},i(e.prsMerged),3),l(`td`,{class:a([q,`text-right`])},i(e.agentAuthoredPrs),3),l(`td`,{class:a([q,`text-right`])},i(u(g)(e.leadTimeHours.median)),3),l(`td`,{class:a([q,`text-right`])},i(u(x)(e)),3),l(`td`,{class:a([q,`text-right`])},i(u(ne)(e.reviewRounds.perPr)),3),l(`td`,{class:a([q,`text-right`])},i(u(y)(e)),3),l(`td`,{class:a([q,`text-right`])},i(u(b)(e.findings.noHumanEditShare)),3),l(`td`,{class:a([q,`text-right`])},i(e.agentRuns.minutes.toFixed(0)),3)],2))),128))])])]),$.value&&Y.value.completeFrom?(c(),n(`p`,B,` Incomplete weeks hold the newest pull requests the read reached — it is complete from `+i(u(_)(Y.value.completeFrom))+` — so their numbers are a floor on the merges, not the week's. `,1)):o(``,!0)]),l(`section`,V,[p[3]||=l(`div`,null,[l(`h2`,{class:`text-[0.9375rem] font-medium`},`By unit`),l(`p`,{class:`text-sm text-muted`},` One row per board issue the pull requests link · the issue's opening starts the clock `)],-1),Y.value.units.length===0?(c(),n(`p`,ce,`Nothing merged in range.`)):(c(),n(`div`,H,[l(`table`,U,[l(`thead`,null,[l(`tr`,null,[l(`th`,{class:a([K,`text-left`])},`Issue`,2),l(`th`,{class:a([K,`text-left`])},`Unit`,2),l(`th`,{class:a([K,`text-left`])},`PRs`,2),l(`th`,{class:a([K,`text-right`])},`Issue → merge`,2),l(`th`,{class:a([K,`text-right`])},`First-pass CI`,2),l(`th`,{class:a([K,`text-right`])},`Rounds`,2),l(`th`,{class:a([K,`text-right`])},`Findings`,2),l(`th`,{class:a([K,`text-right`])},`No human edit`,2)])]),l(`tbody`,null,[(c(!0),n(f,null,r(Y.value.units,e=>(c(),n(`tr`,{key:e.issue??`none`},[l(`td`,{class:a([q,`whitespace-nowrap`])},[e.issue===null?(c(),n(`span`,G,`—`)):(c(),n(`a`,{key:0,class:`text-primary hover:underline`,href:`https://github.com/${Y.value.repo}/issues/${e.issue}`},`#`+i(e.issue),9,W))],2),l(`td`,{class:a([q,`max-w-[28rem] truncate font-sans`]),title:e.title},i(e.title),11,le),l(`td`,{class:a([q,`whitespace-nowrap`])},[(c(!0),n(f,null,r(e.prs,(e,t)=>(c(),n(f,{key:e},[t>0?(c(),n(f,{key:0},[d(`, `)],64)):o(``,!0),l(`a`,{class:`text-primary hover:underline`,href:`https://github.com/${Y.value.repo}/pull/${e}`},i(e),9,ue)],64))),128))],2),l(`td`,{class:a([q,`text-right`])},i(u(g)(e.leadTimeHours.median)),3),l(`td`,{class:a([q,`text-right`])},i(u(x)(e)),3),l(`td`,{class:a([q,`text-right`])},i(e.reviewRounds.verdicts),3),l(`td`,{class:a([q,`text-right`])},i(u(y)(e)),3),l(`td`,{class:a([q,`text-right`])},i(u(b)(e.findings.noHumanEditShare)),3)]))),128))])])])),l(`p`,de,[p[1]||=d(` Machine-readable twin: `,-1),l(`code`,fe,`GET /delivery/`+i(Y.value.repo)+`.json`,1),p[2]||=d(` (same gate). `,-1)])]),l(`footer`,pe,[Y.value.snapshotAt?(c(),n(`p`,me,[d(` As of `+i(u(_)(Y.value.snapshotAt))+`, `+i(u(re)(Y.value.snapshotAt,u(ve)))+` · `,1),t(h,{class:`text-primary hover:underline`,to:`/delivery/${Y.value.repo}${u(ie)(u(ye))}`},{default:s(()=>[...p[4]||=[d(`read GitHub now`,-1)]]),_:1},8,[`to`])])):o(``,!0),l(`details`,null,[p[14]||=l(`summary`,{class:`cursor-pointer text-muted`},`How these numbers are computed`,-1),l(`div`,he,[p[12]||=l(`div`,null,[l(`b`,null,`Snapshot.`),d(` GitHub's record of the merged pull requests (each one's timeline and its branch's workflow runs, the board issue its body links) is read on an interval and kept as a snapshot the page, its JSON twin and `),l(`code`,null,`delivery report`),d(` serve; `),l(`code`,null,`?fresh=1`),d(` reads GitHub now. The run history you may see joins on every load. `)],-1),p[13]||=l(`div`,null,[l(`b`,null,`Issue → merge`),d(` runs from the linked board issue's opening (a closing keyword or a `),l(`code`,null,`board item`),d(` reference in the body) to the merge; a pull request that links no issue counts from its own opening. `),l(`b`,null,`First-pass CI`),d(` is green when every pull-request-triggered workflow run (`),l(`code`,null,`pull_request`),d(`, `),l(`code`,null,`pull_request_target`),d(`) on the first head succeeded at its first attempt — a rerun or a red run fails it; a head with no such run is not counted. `),l(`b`,null,`Review rounds`),d(` are the review agent's verdicts; a `),l(`i`,null,`fix round`),d(` is a verdict that followed a push. `),l(`b`,null,`No human edit`),d(` is the share of the agent's findings on pull requests where every push after the first verdict was an agent's: a bot login, or a commit co-authored by an agent. `),l(`b`,null,`Agent run minutes`),d(` are the finished runs of this repository that named a pull request. `)],-1),l(`div`,null,[p[6]||=l(`b`,null,`Identities.`,-1),p[7]||=d(` Verdicts by `,-1),l(`code`,null,i(Y.value.identities.reviewers.join(`, `)||`(none configured)`),1),p[8]||=d(`; agent logins end in `,-1),p[9]||=l(`code`,null,`[bot]`,-1),Y.value.identities.agentLogins.length?(c(),n(f,{key:0},[p[5]||=d(`, plus `,-1),l(`code`,null,i(Y.value.identities.agentLogins.join(`, `)),1)],64)):o(``,!0),p[10]||=d(`; agent co-authors named `,-1),l(`code`,null,i(Y.value.identities.agentCoauthors.join(`, `)||`(none)`),1),p[11]||=d(`. `,-1)])])])])]),_:1},8,[`title`])):o(``,!0)}}});export{J as default};