@selvakumaresra/specship 0.3.0 → 0.5.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 (97) hide show
  1. package/README.md +11 -1
  2. package/commands/ss-brainstorm.md +68 -0
  3. package/commands/ss-design-implement.md +5 -0
  4. package/commands/ss-design-loop.md +125 -0
  5. package/dist/analytics/specship-impact.d.ts +72 -0
  6. package/dist/analytics/specship-impact.d.ts.map +1 -0
  7. package/dist/analytics/specship-impact.js +216 -0
  8. package/dist/analytics/specship-impact.js.map +1 -0
  9. package/dist/bin/specship.js +70 -4
  10. package/dist/bin/specship.js.map +1 -1
  11. package/dist/db/migrations.d.ts +1 -1
  12. package/dist/db/migrations.d.ts.map +1 -1
  13. package/dist/db/migrations.js +15 -1
  14. package/dist/db/migrations.js.map +1 -1
  15. package/dist/db/schema.sql +8 -0
  16. package/dist/designer/artifact-store.js +54 -0
  17. package/dist/designer/browser.js +141 -0
  18. package/dist/designer/cdp-ensure.js +60 -0
  19. package/dist/designer/cdp-env.js +18 -0
  20. package/dist/designer/cdp-trace.js +599 -0
  21. package/dist/designer/cross-platform.js +74 -0
  22. package/dist/designer/designer-controller.js +1413 -0
  23. package/dist/designer/file-panel.js +39 -0
  24. package/dist/designer/interstitials.js +97 -0
  25. package/dist/designer/oopif-reader.js +176 -0
  26. package/dist/designer/package-meta.js +18 -0
  27. package/dist/designer/preview-host.js +50 -0
  28. package/dist/designer/repo-root.js +31 -0
  29. package/dist/designer/run-state.js +353 -0
  30. package/dist/designer/session-store.js +59 -0
  31. package/dist/designer/ui-anchors.js +651 -0
  32. package/dist/index.d.ts +27 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +48 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/installer/index.d.ts +7 -2
  37. package/dist/installer/index.d.ts.map +1 -1
  38. package/dist/installer/index.js +3 -2
  39. package/dist/installer/index.js.map +1 -1
  40. package/dist/installer/instructions-template.d.ts +17 -0
  41. package/dist/installer/instructions-template.d.ts.map +1 -1
  42. package/dist/installer/instructions-template.js +31 -1
  43. package/dist/installer/instructions-template.js.map +1 -1
  44. package/dist/installer/targets/claude.d.ts +19 -0
  45. package/dist/installer/targets/claude.d.ts.map +1 -1
  46. package/dist/installer/targets/claude.js +100 -1
  47. package/dist/installer/targets/claude.js.map +1 -1
  48. package/dist/installer/targets/shared.d.ts +14 -0
  49. package/dist/installer/targets/shared.d.ts.map +1 -1
  50. package/dist/installer/targets/shared.js +49 -0
  51. package/dist/installer/targets/shared.js.map +1 -1
  52. package/dist/installer/targets/types.d.ts +8 -0
  53. package/dist/installer/targets/types.d.ts.map +1 -1
  54. package/dist/mcp/designer-tools.d.ts +33 -0
  55. package/dist/mcp/designer-tools.d.ts.map +1 -0
  56. package/dist/mcp/designer-tools.js +313 -0
  57. package/dist/mcp/designer-tools.js.map +1 -0
  58. package/dist/mcp/tools.d.ts.map +1 -1
  59. package/dist/mcp/tools.js +22 -1
  60. package/dist/mcp/tools.js.map +1 -1
  61. package/dist/server/ingest/impact-backfill.js +69 -0
  62. package/dist/server/ingest/impact-query.js +343 -0
  63. package/dist/server/ingest/index.js +2 -1
  64. package/dist/server/ingest/ingestor.js +41 -6
  65. package/dist/server/ingest/specship-classify.js +153 -0
  66. package/dist/server/routes/claude.js +32 -0
  67. package/dist/server/routes/spec.js +94 -0
  68. package/dist/server/server.js +26 -2
  69. package/dist/web/{chunk-JN6W7HCN.js → chunk-45QHGCB4.js} +1 -1
  70. package/dist/web/{chunk-RAAMPHPJ.js → chunk-A5R3MJMO.js} +1 -1
  71. package/dist/web/{chunk-2DHIGIOI.js → chunk-ASZ77FMZ.js} +1 -1
  72. package/dist/web/chunk-D5OCNEJA.js +2 -0
  73. package/dist/web/{chunk-3SEJX2BK.js → chunk-FHZHD2ZG.js} +1 -1
  74. package/dist/web/chunk-GR72OOCN.js +1 -0
  75. package/dist/web/{chunk-YAWCRPHV.js → chunk-NZEZCT65.js} +1 -1
  76. package/dist/web/chunk-O7434ZMN.js +1 -0
  77. package/dist/web/chunk-ODX6CT3I.js +6 -0
  78. package/dist/web/chunk-RASJHUXS.js +1 -0
  79. package/dist/web/chunk-TQ3P2QZO.js +1 -0
  80. package/dist/web/{chunk-BCZM5AXU.js → chunk-UBOZGQNK.js} +1 -1
  81. package/dist/web/chunk-WCHGDXWC.js +1 -0
  82. package/dist/web/{chunk-BPECIDVO.js → chunk-WCKHQIYN.js} +1 -1
  83. package/dist/web/{chunk-JFYVCXK3.js → chunk-WLIMNDS3.js} +1 -1
  84. package/dist/web/{chunk-LV4G6QFG.js → chunk-YAMRN47K.js} +1 -1
  85. package/dist/web/index.html +1 -1
  86. package/dist/web/main-X2KCYXZ4.js +1 -0
  87. package/dist/web/sw.js +69 -0
  88. package/dist/workflows/defaults/claude-design-implement.yaml +138 -49
  89. package/hooks/hooks.json +11 -0
  90. package/package.json +7 -3
  91. package/selectors.json +41 -0
  92. package/dist/web/chunk-2OKMB4KX.js +0 -2
  93. package/dist/web/chunk-4N5DWG46.js +0 -1
  94. package/dist/web/chunk-DA6SNNAF.js +0 -1
  95. package/dist/web/chunk-JT7P3DEK.js +0 -6
  96. package/dist/web/chunk-TWXZK6XM.js +0 -1
  97. package/dist/web/main-WVI3YTDU.js +0 -1
@@ -1,5 +1,5 @@
1
1
  name: claude-design-implement
2
- description: Import a Claude Design file (snapshot + tokens + source record), draft the spec, gate at review, write the spec — ready to hand off to /ss-implement.
2
+ description: Import a Claude Design (live URL or a designer handoff bundle) — snapshot + tokens + source record draft the spec, gate at review, write the spec — ready to hand off to /ss-implement.
3
3
  tags: [spec, ui, claude-design, default]
4
4
  requires: [specship, git]
5
5
 
@@ -10,10 +10,29 @@ requires: [specship, git]
10
10
  worktree:
11
11
  enabled: true
12
12
 
13
+ # Two entry shapes (provide exactly one source):
14
+ # - CONNECTOR_URL — a live claude.ai/design URL (the `/ss-design-implement`
15
+ # command). The snapshot node fetches it, preferring the `designer` MCP.
16
+ # - HANDOFF_DIR — a designer handoff bundle already on disk (the
17
+ # `/ss-design-loop` command, after the human-tasted loop + designer_handoff).
18
+ # The snapshot node reads files straight from the bundle — no fetch, no CDP.
19
+ # Optional inputs default to "" (see the CLI's declared-default handling), so a
20
+ # `$INPUT.X` reference to an omitted optional input resolves to "" rather than
21
+ # throwing — that is what lets a single snapshot node branch on whichever
22
+ # source was supplied.
13
23
  inputs:
14
24
  - name: CONNECTOR_URL
15
- description: The full Claude Design URL (https://claude.ai/design/p/<id>/?file=<name>.html)
16
- required: true
25
+ description: A live Claude Design URL (https://claude.ai/design/p/<id>/?file=<name>.html). Provide this OR HANDOFF_DIR.
26
+ required: false
27
+ default: ""
28
+ - name: HANDOFF_DIR
29
+ description: Path to a designer handoff bundle (artifacts/<key>/handoff-<ts>/) containing project/ + decision-record.md. Provide this OR CONNECTOR_URL.
30
+ required: false
31
+ default: ""
32
+ - name: CHOSEN_FILE
33
+ description: When importing from HANDOFF_DIR, the variant filename inside project/ to spec (e.g. "dashboard.html"). Omit if the bundle has a single obvious file.
34
+ required: false
35
+ default: ""
17
36
  - name: FILE_LABEL
18
37
  description: Human label for the imported file (e.g. "Data Flow")
19
38
  required: true
@@ -23,9 +42,11 @@ inputs:
23
42
  - name: OWNER
24
43
  description: Spec owner — used in frontmatter when set
25
44
  required: false
45
+ default: ""
26
46
  - name: PRIORITY
27
47
  description: high / medium / low — used in frontmatter when set
28
48
  required: false
49
+ default: ""
29
50
 
30
51
  systemPromptAppend: |
31
52
  You are implementing a Claude Design import for SpecShip.
@@ -35,9 +56,14 @@ systemPromptAppend: |
35
56
  zero-loss reference layer; the spec captures contract only (behaviour,
36
57
  accessibility, responsive, interaction states, data shape).
37
58
 
38
- Use whichever Claude Design tooling is available (an MCP connector,
39
- the figma-implement-design skill, or a direct fetch) to pull the
40
- source file. Save it byte-for-byte to specs/$INPUT.SLUG/snapshot.html.
59
+ There are two import shapes exactly one source input is non-empty:
60
+ - HANDOFF_DIR set → read the design files straight off disk from the
61
+ designer handoff bundle. No network, no CDP, no MCP fetch.
62
+ - CONNECTOR_URL set → pull the live design. Prefer the `designer`
63
+ MCP (it reads the real rendered HTML over CDP); a plain fetch of a
64
+ claude.ai/design URL returns only a ~1 KB loader shell.
65
+
66
+ Either way: save the source byte-for-byte to specs/$INPUT.SLUG/snapshot.html.
41
67
  Never edit the snapshot during this workflow.
42
68
 
43
69
  nodes:
@@ -50,49 +76,89 @@ nodes:
50
76
  - Bash
51
77
  - mcp__specship__specship_explore
52
78
  - mcp__specship__specship_search
79
+ - mcp__specship__designer_snapshot
80
+ - mcp__specship__designer_handoff
53
81
  prompt: |
54
- Source URL: $INPUT.CONNECTOR_URL
55
- File label: $INPUT.FILE_LABEL
56
- Slug: $INPUT.SLUG
82
+ File label: $INPUT.FILE_LABEL
83
+ Slug: $INPUT.SLUG
84
+ Handoff dir: $INPUT.HANDOFF_DIR
85
+ Chosen file: $INPUT.CHOSEN_FILE
86
+ Source URL: $INPUT.CONNECTOR_URL
57
87
 
58
88
  Goal: snapshot the Claude Design source into specs/$INPUT.SLUG/
59
89
  so the rest of the workflow has a zero-loss reference layer.
60
90
 
61
- 1. Create the directory `specs/$INPUT.SLUG/` if it doesn't exist.
62
-
63
- 2. Fetch the design content from $INPUT.CONNECTOR_URL. Try in
64
- this order:
65
- a. Any Claude Design MCP connector tool available in this
66
- session (look for `mcp__*design*` or similar).
67
- b. The `figma-implement-design` or `figma-use` skill if
68
- loaded — Claude Design and Figma share a similar handoff
69
- shape.
70
- c. A direct `curl` of the URL, as a last resort.
71
-
72
- Save the FULL rendered HTML byte-for-byte to
73
- `specs/$INPUT.SLUG/snapshot.html`. Do NOT filter, summarise, or
74
- re-format. If the design has linked CSS / asset files, save
75
- them alongside.
91
+ Exactly one of "Handoff dir" or "Source URL" above is non-empty.
92
+ If BOTH are empty, stop and report the error — there is nothing to
93
+ import. Pick the branch by which one is set.
76
94
 
77
- 3. Write `specs/$INPUT.SLUG/source.md` with the import audit
78
- record:
79
-
80
- ```markdown
81
- # $INPUT.FILE_LABEL — Claude Design import
82
-
83
- **Imported:** <today's date in YYYY-MM-DD>
84
- **Connector URL:** $INPUT.CONNECTOR_URL
85
- **Project ID:** <extracted from the URL — the segment after /p/>
86
- **File:** $INPUT.FILE_LABEL
87
-
88
- **Snapshot:** snapshot.html (byte-for-byte capture)
89
- **Tokens:** tokens.css (extracted CSS custom properties)
95
+ 1. Create the directory `specs/$INPUT.SLUG/` if it doesn't exist.
90
96
 
91
- **Original prompt:**
92
- > Import this Claude Design project using the Claude Design connector:
93
- > $INPUT.CONNECTOR_URL
94
- > Implement: $INPUT.FILE_LABEL
95
- ```
97
+ ── BRANCH A — Handoff dir is set (preferred; reads disk, no fetch) ──
98
+
99
+ A1. Locate the chosen design file inside the bundle:
100
+ - If "Chosen file" is set, use `$INPUT.HANDOFF_DIR/project/$INPUT.CHOSEN_FILE`.
101
+ - Else list `$INPUT.HANDOFF_DIR/project/`: if there is exactly one
102
+ top-level `.html`, use it; if several, STOP and report the
103
+ candidate filenames, asking the caller to re-run with CHOSEN_FILE.
104
+ A2. Copy that file BYTE-FOR-BYTE to `specs/$INPUT.SLUG/snapshot.html`
105
+ (use `cp`, do not re-render). Copy any CSS / JS / asset files it
106
+ references from `project/` alongside it.
107
+ A3. Write `specs/$INPUT.SLUG/source.md` as the import audit record,
108
+ then APPEND the bundle's decision record verbatim — it is the
109
+ richest provenance you have (every prompt + reply + the human's
110
+ final reaction):
111
+
112
+ ```markdown
113
+ # $INPUT.FILE_LABEL — Claude Design import (handoff bundle)
114
+
115
+ **Imported:** <today's date in YYYY-MM-DD>
116
+ **Handoff bundle:** $INPUT.HANDOFF_DIR
117
+ **Chosen file:** <the file you copied>
118
+
119
+ **Snapshot:** snapshot.html (byte-for-byte capture)
120
+ **Tokens:** tokens.css (extracted CSS custom properties)
121
+
122
+ ## Design decision record (verbatim)
123
+
124
+ <full contents of $INPUT.HANDOFF_DIR/decision-record.md, copied in
125
+ unchanged — if that file is missing, say so here>
126
+ ```
127
+
128
+ ── BRANCH B — Source URL is set (live fetch) ──
129
+
130
+ B1. Fetch the design content from $INPUT.CONNECTOR_URL. Try in order:
131
+ a. The `designer` MCP — `mcp__specship__designer_snapshot`
132
+ (reads the real rendered HTML over CDP from inside the
133
+ cross-origin preview iframe). This is the only path that
134
+ reliably returns the real design for a claude.ai/design URL.
135
+ b. Any other Claude Design MCP connector tool in this session
136
+ (look for `mcp__*design*`), or the `figma-implement-design`
137
+ / `figma-use` skill if loaded.
138
+ c. A direct `curl` of the URL, as a last resort (warning: for
139
+ claude.ai/design this usually returns only a loader shell).
140
+ Save the FULL rendered HTML byte-for-byte to
141
+ `specs/$INPUT.SLUG/snapshot.html`. Do NOT filter, summarise, or
142
+ re-format. Save any linked CSS / asset files alongside.
143
+ B2. Write `specs/$INPUT.SLUG/source.md` with the import audit record:
144
+
145
+ ```markdown
146
+ # $INPUT.FILE_LABEL — Claude Design import
147
+
148
+ **Imported:** <today's date in YYYY-MM-DD>
149
+ **Connector URL:** $INPUT.CONNECTOR_URL
150
+ **Project ID:** <extracted from the URL — the segment after /p/>
151
+ **File:** $INPUT.FILE_LABEL
152
+
153
+ **Snapshot:** snapshot.html (byte-for-byte capture)
154
+ **Tokens:** tokens.css (extracted CSS custom properties)
155
+
156
+ **Original prompt:**
157
+ > Import this Claude Design project: $INPUT.CONNECTOR_URL
158
+ > Implement: $INPUT.FILE_LABEL
159
+ ```
160
+
161
+ ── BOTH BRANCHES ──
96
162
 
97
163
  4. Extract CSS custom properties + literal token-like values
98
164
  (colors, spacing, font sizes, radii, transitions) from the
@@ -102,12 +168,15 @@ nodes:
102
168
  project token, map it by name instead of duplicating.
103
169
 
104
170
  Output: a ≤250-word summary covering:
171
+ - Which branch ran and the file captured.
105
172
  - Snapshot structure (top-level layout, key components).
106
173
  - Token mapping (which match existing project tokens, which are
107
174
  new and added to tokens.css).
108
175
  - Any visible interaction or state cues in the CSS (`:hover`,
109
176
  `:focus`, `:disabled`, `[aria-*]` selectors) the spec
110
177
  author should be aware of.
178
+ - For Branch A: note that source.md carries the verbatim decision
179
+ record — the draft step should mine it for stated behaviour.
111
180
 
112
181
  - id: draft_spec
113
182
  kind: prompt
@@ -130,6 +199,14 @@ nodes:
130
199
 
131
200
  Spec scope: $INPUT.FILE_LABEL component(s).
132
201
  Optional inputs: owner=$INPUT.OWNER priority=$INPUT.PRIORITY
202
+ (an empty value means "not provided" — use "[needs review]").
203
+
204
+ If `source.md` contains a "Design decision record (verbatim)"
205
+ section (a handoff-bundle import), READ IT FIRST and mine it for
206
+ contract: interaction states, failure modes, data shapes, and the
207
+ human's stated intent are often spelled out in that transcript.
208
+ Prefer what the record states over guessing; reserve [needs review]
209
+ for items genuinely absent from both the snapshot and the record.
133
210
 
134
211
  Cover, as separate REQs:
135
212
  - Behavioural contract (what the component renders, given what data).
@@ -203,17 +280,29 @@ nodes:
203
280
  - Read
204
281
  - Bash
205
282
  prompt: |
206
- Write the approved spec to `specs/$INPUT.SLUG.md` using the
207
- Write tool.
283
+ Write the approved spec to `specs/$INPUT.SLUG.md` using the Write
284
+ tool. The spec content is the DRAFT below; the reviewer's gate
285
+ response carries the gap-fill answers / edits to fold in.
208
286
 
209
- If `specs/$INPUT.SLUG.md` already exists (re-importing an
210
- iteration), APPEND the new requirements to it instead of
211
- overwriting; preserve all existing REQ IDs. Tell the user
212
- explicitly what you did.
287
+ APPROVED DRAFT (this is the spec to write):
288
+ $draft_spec.output
213
289
 
214
- Approved draft:
290
+ REVIEWER GATE RESPONSE (gap-fill answers / edits — apply these,
291
+ resolving any `[needs review]` markers the reviewer answered; if it
292
+ is just "approved" with no substantive content, write the draft as
293
+ is):
215
294
  $gap_review.output
216
295
 
296
+ Rules:
297
+ - Write the full spec Markdown (frontmatter + REQ bodies +
298
+ acceptance bullets), NOT the reviewer's comment verbatim.
299
+ - Resolve `[needs review]` markers the reviewer answered; leave
300
+ any they didn't as `[needs review]`.
301
+ - Keep ALL existing REQ IDs stable.
302
+ - If `specs/$INPUT.SLUG.md` already exists (re-importing an
303
+ iteration), APPEND new requirements instead of overwriting and
304
+ preserve existing REQ IDs. Tell the user explicitly what you did.
305
+
217
306
  Then run:
218
307
  specship sync
219
308
 
package/hooks/hooks.json CHANGED
@@ -22,6 +22,17 @@
22
22
  }
23
23
  ]
24
24
  }
25
+ ],
26
+ "UserPromptSubmit": [
27
+ {
28
+ "matcher": "",
29
+ "hooks": [
30
+ {
31
+ "type": "command",
32
+ "command": "specship spec-nudge"
33
+ }
34
+ ]
35
+ }
25
36
  ]
26
37
  }
27
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@selvakumaresra/specship",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Supercharge Claude Code with semantic code intelligence. 94% fewer tool calls • 77% faster exploration • 100% local.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -14,10 +14,11 @@
14
14
  ".claude-plugin",
15
15
  "commands",
16
16
  "agents",
17
- "hooks"
17
+ "hooks",
18
+ "selectors.json"
18
19
  ],
19
20
  "scripts": {
20
- "build": "tsc && npm run copy-assets && npm run build:server && npm run build:web && node -e \"require('fs').chmodSync('dist/bin/specship.js', 0o755)\"",
21
+ "build": "tsc && tsc -p src/designer/tsconfig.json && npm run copy-assets && npm run build:server && npm run build:web && node -e \"require('fs').chmodSync('dist/bin/specship.js', 0o755)\"",
21
22
  "build:server": "node scripts/build-server-bundle.mjs",
22
23
  "build:web": "node scripts/build-web-bundle.mjs",
23
24
  "preuninstall": "node dist/bin/uninstall.js",
@@ -44,9 +45,11 @@
44
45
  "@clack/prompts": "^1.3.0",
45
46
  "@fastify/cors": "^9.0.1",
46
47
  "commander": "^14.0.2",
48
+ "cross-spawn": "^7.0.6",
47
49
  "fast-string-width": "^3.0.2",
48
50
  "fast-wrap-ansi": "^0.2.0",
49
51
  "fastify": "^4.28.1",
52
+ "fflate": "^0.8.3",
50
53
  "ignore": "^7.0.5",
51
54
  "jsonc-parser": "^3.3.1",
52
55
  "picomatch": "^4.0.3",
@@ -57,6 +60,7 @@
57
60
  },
58
61
  "devDependencies": {
59
62
  "@types/better-sqlite3": "^7.6.0",
63
+ "@types/cross-spawn": "^6.0.6",
60
64
  "@types/node": "^20.19.30",
61
65
  "@types/picomatch": "^4.0.2",
62
66
  "typescript": "^5.0.0",
package/selectors.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "_notes": "Captured 2026-04-17 from Chrome 147 via CDP. Override at ~/.designer/selectors.override.json. Prefer data-testid over class names — Claude's styled-components classes (sc-xxx) are regenerated on every build.",
3
+ "_drift": "2026-06 (issue #61): the home was rebuilt around a composer. Captured live 2026-06-16 from Chrome 149 (signed-in profile); creation-type card labels re-captured 2026-06-19. There is no project-name input or wireframe/high-fi toggle anymore — you seed an intent in the chat composer ([data-testid=chat-composer-input], the SAME element as the in-session composer) and click 'Start project' ([data-testid=chat-send-button], the same as the in-session send button). Creation-type cards (Start with a file / Slides / Product prototype / Product wireframe / Document / Animation / Blank canvas) are text-only buttons with no data-testid; the default flow doesn't require clicking one, so wireframeButtonText/highFiButtonText are health-anchor drift sentinels only (NOT on the create path). The high-fi card was renamed 'Prototype' → 'Product prototype' (auto-heal PR #75/#76). Projects render as <a href=/design/p/<uuid>> with the name as text (no project-card/projects-list testid). `designer adopt` remains available to bind an already-open tab to a key.",
4
+ "_urls": {
5
+ "home": "https://claude.ai/design",
6
+ "session": "https://claude.ai/design/p/{uuid}"
7
+ },
8
+ "login": {
9
+ "signedInIndicator": "[data-testid=\"chat-composer-input\"]"
10
+ },
11
+ "home": {
12
+ "creator": "[data-testid=\"chat-composer-input\"]",
13
+ "nameInput": "[data-testid=\"chat-composer-input\"]",
14
+ "wireframeButtonText": "Product wireframe",
15
+ "highFiButtonText": "Product prototype",
16
+ "createButton": "[data-testid=\"chat-send-button\"]",
17
+ "projectsList": "a[href*=\"/design/p/\"]",
18
+ "projectCard": "a[href*=\"/design/p/\"]"
19
+ },
20
+ "composer": {
21
+ "promptTextarea": "[data-testid=\"chat-composer-input\"]",
22
+ "sendButton": "[data-testid=\"chat-send-button\"], button[title^=\"Send (\"]",
23
+ "stopButton": null,
24
+ "attachButton": "button[aria-label=\"Attach file\"]",
25
+ "modelButton": "[data-testid=\"model-selector-button\"]"
26
+ },
27
+ "preview": {
28
+ "iframeOrContainer": "[data-testid=\"html-viewer-iframe\"]",
29
+ "exportButtonText": "Export",
30
+ "shareButtonText": "Share",
31
+ "emptyStateHeading": "Creations will appear here"
32
+ },
33
+ "messages": {
34
+ "chatMessagesContainer": "[data-testid=\"chat-messages\"]",
35
+ "generatingIndicator": null
36
+ },
37
+ "interstitials": {
38
+ "_note": "Content-only overlays on claude.ai/design (no data-testid). Detection regexes live in interstitials.ts (the unit-tested source of truth); this block only overrides the actionable button text. Captured live 2026-06-19 (Chrome 149). The token banner ('Start a new chat to save Nk tokens of context') is dismissed by clicking 'Continue here' — NOT 'New chat', which discards the session's context. Verbs run this pre-flight via ensureReady; recover manually with `designer clear`.",
39
+ "continueHere": "Continue here"
40
+ }
41
+ }
@@ -1,2 +0,0 @@
1
- import{a as L,b as Q,c as q}from"./chunk-T66XVKGB.js";import{a as Y}from"./chunk-DTRN7FZR.js";import{a as U}from"./chunk-MC4DFIHG.js";import{a as H}from"./chunk-UYC52MBC.js";import{a as W}from"./chunk-2GBEK2GM.js";import{a as K}from"./chunk-SUZYBYDW.js";import{b}from"./chunk-4N5DWG46.js";import{c as G,d as B}from"./chunk-SHPTC4RL.js";import{a as V}from"./chunk-7RNS77UP.js";import{a as j}from"./chunk-E44X4RH2.js";import{Aa as l,Ga as P,I as E,Ia as _,Ka as c,M as f,N as C,Ta as T,Ua as y,Va as s,W as R,Wa as k,Xa as v,Ya as D,bb as N,ea as r,gb as O,ib as z,ka as F,lb as m,ra as u,sa as g,ua as I,va as w,vb as $,wa as M,xa as p,ya as a,za as o,zb as A}from"./chunk-PDN6QYGJ.js";import"./chunk-Q7L6LLAK.js";var Z=()=>[0,1,2,3],ee=()=>[0,1,2,3,4],X=(i,e)=>e.id;function te(i,e){if(i&1&&s(0),i&2){let n=c();v(" ",n.fmt$(n.lastSessionCostStat().value)," ")}}function ne(i,e){i&1&&s(0," \xA0 ")}function ie(i,e){if(i&1&&l(0,"app-sparkline",11),i&2){let n=c();p("data",n.lastSessionCostStat().series)("width",64)("height",22)("fill",!0)}}function ae(i,e){if(i&1&&l(0,"app-delta",12),i&2){let n=c();p("value",n.lastSessionCostStat().delta)("invert",!0)}}function oe(i,e){if(i&1&&s(0),i&2){let n=c();v(" ",n.toolCallsStat().value.toLocaleString()," ")}}function re(i,e){i&1&&s(0," \xA0 ")}function se(i,e){if(i&1&&l(0,"app-sparkline",14),i&2){let n=c();p("data",n.toolCallsStat().series)("width",64)("height",22)("fill",!0)}}function le(i,e){if(i&1&&l(0,"app-delta",12),i&2){let n=c();p("value",n.toolCallsStat().delta)("invert",!0)}}function de(i,e){if(i&1&&s(0),i&2){let n=c();v(" ",n.subagentPctStat().value,"% ")}}function pe(i,e){i&1&&s(0," \xA0 ")}function ce(i,e){if(i&1&&l(0,"app-sparkline",16),i&2){let n=c();p("data",n.subagentPctStat().series)("width",64)("height",22)("fill",!0)}}function me(i,e){if(i&1&&l(0,"app-delta",12),i&2){let n=c();p("value",n.subagentPctStat().delta)("invert",!0)}}function ue(i,e){if(i&1&&s(0),i&2){let n=c();v(" ",n.driftStat().value," ")}}function ge(i,e){i&1&&s(0," \xA0 ")}function he(i,e){i&1&&(a(0,"span",24),s(1,"seed"),o())}function _e(i,e){if(i&1&&(a(0,"span",31),s(1),o()),i&2){let n=c();r(),v(" ",n.urgentTipCount()," urgent ")}}function ve(i,e){i&1&&l(0,"div",58)}function be(i,e){i&1&&w(0,ve,1,0,"div",58,I),i&2&&M(N(0,Z))}function xe(i,e){i&1&&(a(0,"div",34),s(1,"No tips yet. Run more sessions to populate."),o())}function fe(i,e){if(i&1&&(a(0,"code",66),s(1),o()),i&2){let n=c().$implicit;r(),k(n.fix)}}function Ce(i,e){if(i&1&&(a(0,"span",73),s(1),o()),i&2){let n=c().$implicit,t=c(2);T("color",t.tipSevColor(n.severity)),r(),k(n.saving)}}function ye(i,e){if(i&1){let n=P();a(0,"div",60)(1,"div",61),l(2,"app-icon",62),o(),a(3,"div",63)(4,"div",64),s(5),o(),a(6,"div",65),u(7,fe,2,1,"code",66),l(8,"span",67),u(9,Ce,2,3,"span",68),o()(),a(10,"div",69)(11,"button",70),_("click",function(){f(n);let d=c(2);return C(d.go("tips"))}),s(12,"Apply"),o(),a(13,"button",71),_("click",function(){let d=f(n).$implicit,h=c(2);return C(h.dismissTip(d.id))}),l(14,"app-icon",72),o()()()}if(i&2){let n=e.$implicit,t=c(2);T("border-left-color",t.tipSevColor(n.severity)),r(),T("color",t.tipSevColor(n.severity)),r(),p("name",t.tipIcon(n))("size",14),r(3),k(n.title),r(2),g(n.fix?7:-1),r(2),g(n.saving?9:-1),r(5),p("size",12)}}function ke(i,e){if(i&1&&w(0,ye,15,10,"div",59,X),i&2){let n=c();M(n.visibleTips())}}function Se(i,e){i&1&&l(0,"div",42)}function we(i,e){i&1&&(a(0,"div",43),s(1," No tool calls in the selected window. "),o())}function Me(i,e){if(i&1){let n=P();a(0,"app-treemap",74),_("pick",function(){f(n);let d=c();return C(d.go("heatmap"))}),o()}if(i&2){let n=c();p("items",n.treemapItems())("height",116)("selKey",null)}}function Te(i,e){i&1&&l(0,"div",75)}function Ee(i,e){i&1&&w(0,Te,1,0,"div",75,I),i&2&&M(N(0,ee))}function Pe(i,e){i&1&&(a(0,"div",34),s(1,"No prompts ingested for this range."),o())}function De(i,e){i&1&&l(0,"app-icon",80),i&2&&p("size",11)}function Oe(i,e){if(i&1){let n=P();a(0,"div",77),_("click",function(){f(n);let d=c(2);return C(d.go("sessions"))})("keydown.enter",function(){f(n);let d=c(2);return C(d.go("sessions"))})("keydown.space",function(){f(n);let d=c(2);return C(d.go("sessions"))}),a(1,"div",78)(2,"div",79),u(3,De,1,1,"app-icon",80),s(4),o(),a(5,"div",81),l(6,"app-bar",82),o()(),a(7,"div",83)(8,"div",84),s(9),o(),a(10,"div",85),s(11),O(12,"number"),o()()()}if(i&2){let n=e.$implicit,t=c(2);r(3),g(n.is_sidechain?3:-1),r(),v(" ",n.text||"(no text)"," "),r(2),p("frac",t.promptFrac(n.cost_usd))("color",t.promptBarColor(n.cost_usd))("height",4),r(2),T("color",n.cost_usd/t.maxPromptCost()>.7?"var(--error)":"var(--text-primary)"),y("expensive",n.cost_usd/t.maxPromptCost()>.7),r(),v(" ",t.fmt$(n.cost_usd)," "),r(2),D(" ",t.fmtK(t.promptTotalTokens(n))," \xB7 ",z(12,12,t.promptCacheRate(n)*100,"1.0-0"),"% ")}}function ze(i,e){if(i&1&&w(0,Oe,13,15,"div",76,X),i&2){let n=c();M(n.topPrompts())}}function Re(i,e){i&1&&l(0,"div",56)}function Ie(i,e){if(i&1&&(a(0,"div",86)(1,"div",87),s(2),O(3,"number"),o(),a(4,"div",88)(5,"div",40),s(6,"cache read rate"),o(),l(7,"app-delta",12),o()(),l(8,"div",89),a(9,"div",90)(10,"div",91)(11,"div",92),s(12,"Creation tokens"),o(),a(13,"div",93),s(14),o(),a(15,"div",94),s(16,"ephemeral"),o()(),a(17,"div",91)(18,"div",92),s(19,"Read tokens"),o(),a(20,"div",93),s(21),o(),a(22,"div",94),s(23,"charged at ~10%"),o()(),a(24,"div",91)(25,"div",92),s(26,"Saved this week"),o(),a(27,"div",95),s(28),o(),a(29,"div",94),s(30,"vs no cache"),o()(),a(31,"div",91)(32,"div",92),s(33,"WoW"),o(),a(34,"div",95),s(35),O(36,"number"),o(),a(37,"div",94),s(38,"more reuse"),o()()()),i&2){let n=c(),t=n.cache.state().data;r(2),v("",z(3,8,t.readRate*100,"1.0-0"),"%"),r(5),p("value",t.wowDelta)("invert",!1),r(7),k(n.fmtK(t.creationTokens)),r(7),k(n.fmtK(t.readTokens)),r(7),k(n.fmt$(t.dollarsSaved)),r(7),D(" ",t.wowDelta>=0?"+":"","",z(36,11,t.wowDelta*100,"1.0-0"),"% ")}}var J=class i{api=E(j);router=E(G);projects=E(V);range=R("week");rangeOptions=[{value:"today",label:"Today"},{value:"week",label:"This week"},{value:"month",label:"This month"},{value:"all",label:"All time"}];status=b(this.api,()=>`/api/status${this.projects.projectQuery()}`);miniGraphSearch=b(this.api,()=>`/api/graph/search?q=on&limit=18${this.projects.projectQuery("&")}`);tips=b(this.api,()=>"/api/claude/tips");heatmap=b(this.api,()=>`/api/claude/heatmap?range=${this.range()}`);costs=b(this.api,()=>`/api/claude/costs?range=${this.range()}`);cache=b(this.api,()=>`/api/claude/cache?range=${this.range()}`);sessions=b(this.api,()=>`/api/claude/sessions?range=${this.range()}&limit=10`);stats=b(this.api,()=>`/api/claude/stats?range=${this.range()}`);EMPTY_METRIC={value:0,delta:0,series:[]};lastSessionCostStat=m(()=>this.stats.state().data?.lastSessionCost??this.EMPTY_METRIC);toolCallsStat=m(()=>this.stats.state().data?.toolCalls??this.EMPTY_METRIC);subagentPctStat=m(()=>this.stats.state().data?.subagentPct??this.EMPTY_METRIC);driftStat=m(()=>this.stats.state().data?.drift??this.EMPTY_METRIC);lastSession=m(()=>(this.sessions.state().data?.sessions??[])[0]??null);lastSessionCost=m(()=>this.lastSession()?.total_cost_usd??0);toolCallCount=m(()=>(this.heatmap.state().data?.tools??[]).reduce((n,t)=>n+(t.calls??0),0));subagentShare=m(()=>{let e=this.heatmap.state().data?.subagents??[],n=e.find(x=>x.type==="subagent"),t=e.find(x=>x.type==="main"),d=n?.cost??0,h=t?.cost??0,S=d+h;return S>0?Math.round(d/S*100):0});driftCount=m(()=>this.status.state().data?.drift??0);nodeCountLabel=m(()=>this.status.state().data?.nodeCount??0);urgentTipCount=m(()=>(this.tips.state().data?.tips??[]).filter(n=>n.severity==="error").length);dismissedTips=R(new Set);dismissTip(e){this.dismissedTips.update(n=>{let t=new Set(n);return t.add(e),t})}isTipDismissed(e){return this.dismissedTips().has(e)}visibleTips=m(()=>{let e=this.dismissedTips();return(this.tips.state().data?.tips??[]).filter(n=>!e.has(n.id)).slice(0,4)});treemapItems=m(()=>{let e=(this.heatmap.state().data?.files??[]).slice(0,30);if(!e.length)return[];let n=Math.max(1,...e.map(t=>t.resultBytes&&t.calls?t.resultBytes/t.calls:0));return e.map(t=>{let d=t.calls>0?t.resultBytes/t.calls:0,h=Math.min(1,d/n);return{key:t.path,label:L(t.path),value:t.calls,intensity:h,sub:t.calls+" calls",title:`${t.path}
2
- ${t.calls} calls \xB7 ${this.fmtK(Math.round(d))}/call`}})});topPrompts=m(()=>(this.costs.state().data?.topPrompts??[]).slice(0,8));maxPromptCost=m(()=>Math.max(.01,...this.topPrompts().map(e=>e.cost_usd??0)));rangeTotal=m(()=>(this.costs.state().data?.series??[]).reduce((n,t)=>n+(t.cost??0),0));liveSource=m(()=>this.status.state().source==="api"&&this.status.state().data?"live":"mock");miniGraphSource=m(()=>(this.miniGraphSearch.state().data?.results?.length??0)>0?"api":"seed");miniGraphNodes=m(()=>{let e=this.miniGraphSearch.state().data?.results??[];return e.length>0?$e(e.slice(0,18).map(n=>({id:n.node.id,label:n.node.name,sub:n.node.filePath?.split("/").slice(-2).join("/"),kind:n.node.kind}))):Ne});miniGraphEdges=m(()=>{if(this.miniGraphSource()==="api"){let e=this.miniGraphNodes(),n=[];for(let t=1;t<e.length;t++){let d=e[Math.floor(Math.random()*t)],h=e[t];d&&h&&n.push({from:d.id,to:h.id,kind:"calls"})}return n}return Fe});onMiniGraphPick(e){this.router.navigate(["/graph"],{queryParams:{focus:e}})}setRange(e){this.range.set(e)}go(e){this.router.navigate(["/"+e])}fmt$(e){return"$"+e.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}fmtK(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(e>=1e4?0:1)+"k":String(e)}promptCacheRate(e){let n=(e.input_tokens??0)+(e.cache_creation_tokens??0)+(e.cache_read_tokens??0);return n>0?(e.cache_read_tokens??0)/n:0}promptTotalTokens(e){return(e.input_tokens??0)+(e.output_tokens??0)+(e.cache_creation_tokens??0)+(e.cache_read_tokens??0)}promptBarColor(e){return e/this.maxPromptCost()>.7?"var(--error)":"var(--accent)"}promptFrac(e){return Math.max(0,Math.min(1,e/this.maxPromptCost()))}tipSevColor(e){return e==="error"?"var(--error)":e==="warn"?"var(--warn)":"var(--info)"}tipIcon(e){return e.icon?e.icon:e.severity==="error"?"cancel":e.severity==="warn"?"warn":"info"}static \u0275fac=function(n){return new(n||i)};static \u0275cmp=F({type:i,selectors:[["app-dashboard"]],decls:122,vars:48,consts:[[1,"scroll-y","dashboard"],["icon","dashboard","title","Dashboard",3,"sub"],["actions",""],["size","sm",3,"change","options","value"],[1,"stat-grid"],["type","button",1,"stat-tile",3,"click"],[1,"row","gap-8","stat-eyebrow"],["name","coins",2,"color","var(--accent)",3,"size"],[1,"eyebrow",2,"letter-spacing","0.04em"],[1,"row","stat-value-row"],[1,"stat-value","tabular"],["color","var(--accent)",3,"data","width","height","fill"],[3,"value","invert"],["name","wrench",2,"color","var(--node-spec)",3,"size"],["color","var(--node-spec)",3,"data","width","height","fill"],["name","bot",2,"color","var(--node-code)",3,"size"],["color","var(--node-code)",3,"data","width","height","fill"],["name","drift",2,"color","var(--warn)",3,"size"],[1,"center-grid"],[1,"card","graph-card"],[1,"card-head"],[1,"card-title","row","gap-8"],["name","graph",2,"color","var(--accent)",3,"size"],[1,"muted",2,"font-size","11px","font-weight","400"],["title","No graph data yet \u2014 illustrative",1,"pill","seed-pill"],["routerLink","/graph",1,"btn","btn-ghost","btn-xs"],["name","arrowRight",3,"size"],[1,"mini-graph"],[3,"nodeClick","nodes","edges"],[1,"card","tips-card"],["name","tips",2,"color","var(--warn)",3,"size"],[1,"pill",2,"font-size","10px","background","var(--error-soft)","color","var(--error)"],["routerLink","/tips",1,"btn","btn-ghost","btn-xs"],[1,"scroll-y","tips-body"],[1,"tip-empty"],[1,"card","card-pad","heatmap-card"],[1,"row","heatmap-head"],[1,"row","gap-8"],["name","flame",2,"color","var(--warn)",3,"size"],[2,"font-weight","600","font-size","12.5px"],[1,"muted",2,"font-size","11px"],["routerLink","/heatmap",1,"btn","btn-ghost","btn-xs"],[1,"skel",2,"height","116px","border-radius","7px"],[1,"tip-empty",2,"height","116px","display","grid","place-items","center"],[3,"items","height","selKey"],[1,"row","gap-10","heatmap-legend"],[1,"muted",2,"font-size","10px"],[1,"heatmap-gradient"],[1,"muted",2,"font-size","9.5px"],[1,"bottom-grid"],[1,"card","card-pad","prompts-card"],[1,"row","prompts-head"],["routerLink","/costs",1,"btn","btn-ghost","btn-xs"],[1,"col"],[1,"card","card-pad","cache-card"],["name","database",2,"color","var(--node-route)",3,"size"],[1,"skel",2,"height","70px","border-radius","5px"],[1,"dash-footer","mono","muted"],[1,"skel",2,"height","64px","border-radius","8px"],[1,"tip-row",3,"border-left-color"],[1,"tip-row"],[1,"tip-sev-icon"],[3,"name","size"],[1,"grow","tip-body-col",2,"min-width","0"],[1,"tip-title"],[1,"row","gap-8","tip-meta-row"],[1,"mono","tip-fix"],[1,"grow"],[1,"pill",2,"font-size","10px","color","inherit","background","transparent",3,"color"],[1,"row","gap-4",2,"flex-shrink","0"],["type","button",1,"btn","btn-secondary","btn-xs",3,"click"],["type","button","title","Dismiss",1,"btn","btn-ghost","btn-xs",3,"click"],["name","x",3,"size"],[1,"pill",2,"font-size","10px","color","inherit","background","transparent"],[3,"pick","items","height","selKey"],[1,"skel",2,"height","26px","margin","4px 0","border-radius","4px"],["role","button","tabindex","0",1,"prompt-row"],["role","button","tabindex","0",1,"prompt-row",3,"click","keydown.enter","keydown.space"],[1,"grow","prompt-left",2,"min-width","0"],[1,"prompt-text"],["name","bot",2,"color","var(--node-code)","margin-right","5px","vertical-align","-1px",3,"size"],[2,"margin-top","4px","width","70%"],[3,"frac","color","height"],[1,"prompt-right"],[1,"mono","tabular","prompt-cost"],[1,"mono","muted",2,"font-size","10px"],[1,"row","cache-headline"],[1,"tabular","cache-rate"],[2,"padding-bottom","3px"],[1,"cache-divider"],[1,"cache-kv-grid"],[1,"kv"],[1,"kv-label"],[1,"kv-value","mono","tabular"],[1,"kv-sub","mono","muted"],[1,"kv-value","mono","tabular",2,"color","var(--success)"]],template:function(n,t){n&1&&(a(0,"div",0)(1,"app-page-head",1)(2,"div",2)(3,"app-segmented",3),_("change",function(h){return t.setRange(h)}),o()()(),a(4,"div",4)(5,"button",5),_("click",function(){return t.go("sessions")}),a(6,"div",6),l(7,"app-icon",7),a(8,"span",8),s(9,"Last session cost"),o()(),a(10,"div",9)(11,"div",10),u(12,te,1,1)(13,ne,1,0),o(),u(14,ie,1,4,"app-sparkline",11),o(),u(15,ae,1,2,"app-delta",12),o(),a(16,"button",5),_("click",function(){return t.go("heatmap")}),a(17,"div",6),l(18,"app-icon",13),a(19,"span",8),s(20),o()(),a(21,"div",9)(22,"div",10),u(23,oe,1,1)(24,re,1,0),o(),u(25,se,1,4,"app-sparkline",14),o(),u(26,le,1,2,"app-delta",12),o(),a(27,"button",5),_("click",function(){return t.go("heatmap")}),a(28,"div",6),l(29,"app-icon",15),a(30,"span",8),s(31,"Subagent spend"),o()(),a(32,"div",9)(33,"div",10),u(34,de,1,1)(35,pe,1,0),o(),u(36,ce,1,4,"app-sparkline",16),o(),u(37,me,1,2,"app-delta",12),o(),a(38,"button",5),_("click",function(){return t.go("drift")}),a(39,"div",6),l(40,"app-icon",17),a(41,"span",8),s(42,"Drift queue"),o()(),a(43,"div",9)(44,"div",10),u(45,ue,1,1)(46,ge,1,0),o()()()(),a(47,"div",18)(48,"div",19)(49,"div",20)(50,"div",21),l(51,"app-icon",22),a(52,"span"),s(53,"Recent neighborhood"),o(),a(54,"span",23),s(55,"\xB7 last edited files"),o(),u(56,he,2,0,"span",24),o(),a(57,"a",25),s(58," Open graph "),l(59,"app-icon",26),o()(),a(60,"div",27)(61,"app-graph-canvas",28),_("nodeClick",function(h){return t.onMiniGraphPick(h)}),o()()(),a(62,"div",29)(63,"div",20)(64,"div",21),l(65,"app-icon",30),a(66,"span"),s(67,"Tips"),o(),u(68,_e,2,1,"span",31),o(),a(69,"a",32),s(70,"All"),o()(),a(71,"div",33),u(72,be,2,1)(73,xe,2,0,"div",34)(74,ke,2,0),o()()(),a(75,"div",35)(76,"div",36)(77,"div",37),l(78,"app-icon",38),a(79,"span",39),s(80,"Tool-call heatmap"),o(),a(81,"span",40),s(82,"\xB7 area = calls, color = tokens / call"),o()(),a(83,"a",41),s(84," Open heatmap "),l(85,"app-icon",26),o()(),u(86,Se,1,0,"div",42)(87,we,2,0,"div",43)(88,Me,1,3,"app-treemap",44),a(89,"div",45)(90,"span",46),s(91,"tokens / call"),o(),l(92,"div",47),a(93,"span",48),s(94,"efficient \u2192 wasteful"),o()()(),a(95,"div",49)(96,"div",50)(97,"div",51)(98,"div",37),l(99,"app-icon",7),a(100,"span",39),s(101,"Recent prompts"),o(),a(102,"span",40),s(103,"\xB7 by cost"),o()(),a(104,"a",52),s(105,"Cost ranking"),o()(),a(106,"div",53),u(107,Ee,2,1)(108,Pe,2,0,"div",34)(109,ze,2,0),o()(),a(110,"div",54)(111,"div",37),l(112,"app-icon",55),a(113,"span",39),s(114,"Cache analytics"),o()(),u(115,Re,1,0,"div",56)(116,Ie,39,14),o()(),a(117,"footer",57),s(118),a(119,"span"),s(120,"\u25CF"),o(),s(121),o()()),n&2&&(r(),p("sub","specship \xB7 "+t.nodeCountLabel().toLocaleString()+" nodes \xB7 last session "+t.fmt$(t.lastSessionCost())),r(2),p("options",t.rangeOptions)("value",t.range()),r(4),p("size",13),r(4),y("skel",t.stats.state().loading),r(),g(t.stats.state().loading?13:12),r(2),g(t.lastSessionCostStat().series.length>0?14:-1),r(),g(t.lastSessionCostStat().delta!==0?15:-1),r(3),p("size",13),r(2),v("Tool calls \xB7 ",t.range()),r(2),y("skel",t.stats.state().loading),r(),g(t.stats.state().loading?24:23),r(2),g(t.toolCallsStat().series.length>0?25:-1),r(),g(t.toolCallsStat().delta!==0?26:-1),r(3),p("size",13),r(4),y("skel",t.stats.state().loading),r(),g(t.stats.state().loading?35:34),r(2),g(t.subagentPctStat().series.length>0?36:-1),r(),g(t.subagentPctStat().delta!==0?37:-1),r(3),p("size",13),r(4),y("skel",t.stats.state().loading),r(),g(t.stats.state().loading?46:45),r(6),p("size",14),r(5),g(t.miniGraphSource()==="seed"?56:-1),r(3),p("size",11),r(2),p("nodes",t.miniGraphNodes())("edges",t.miniGraphEdges()),r(4),p("size",14),r(3),g(t.urgentTipCount()>0?68:-1),r(4),g(t.tips.state().loading?72:t.visibleTips().length===0?73:74),r(6),p("size",14),r(7),p("size",11),r(),g(t.heatmap.state().loading?86:t.treemapItems().length===0?87:88),r(13),p("size",14),r(8),g(t.costs.state().loading?107:t.topPrompts().length===0?108:109),r(5),p("size",14),r(3),g(t.cache.state().loading?115:t.cache.state().data?116:-1),r(3),D(" ",t.range()," window total: ",t.fmt$(t.rangeTotal())," \xB7 "),r(),y("dot-live",t.liveSource()==="live")("dot-mock",t.liveSource()==="mock"),r(2),v(" ",t.liveSource()," "))},dependencies:[B,A,H,K,U,Y,Q,q,W,$],styles:['@charset "UTF-8";[_nghost-%COMP%]{display:contents}.dashboard[_ngcontent-%COMP%]{flex:1;padding:18px;color:var(--text-primary);background:var(--bg-canvas)}.stat-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:14px}.stat-tile[_ngcontent-%COMP%]{text-align:left;padding:11px 13px;cursor:pointer;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--r-lg);display:flex;flex-direction:column;gap:6px;color:var(--text-primary);font-family:inherit;transition:background .1s,border-color .1s}.stat-tile[_ngcontent-%COMP%]:hover{background:var(--bg-panel-2);border-color:var(--border-strong)}.stat-eyebrow[_ngcontent-%COMP%]{color:var(--text-muted)}.stat-value-row[_ngcontent-%COMP%]{justify-content:space-between;align-items:flex-end;gap:8px}.stat-value[_ngcontent-%COMP%]{font-size:23px;font-weight:650;letter-spacing:-.02em;line-height:1;min-height:23px}.center-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:2fr 1fr;gap:12px;margin-bottom:14px}.graph-card[_ngcontent-%COMP%], .tips-card[_ngcontent-%COMP%]{height:340px;display:flex;flex-direction:column;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--r-lg);overflow:hidden}.card-head[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;padding:11px 13px;border-bottom:1px solid var(--border-subtle);flex-shrink:0}.card-title[_ngcontent-%COMP%]{font-weight:600;font-size:12.5px;display:inline-flex;align-items:center;gap:8px}.mini-graph[_ngcontent-%COMP%]{flex:1;min-height:0;overflow:hidden;border-bottom-left-radius:var(--r-lg);border-bottom-right-radius:var(--r-lg)}.mini-graph[_ngcontent-%COMP%] app-graph-canvas[_ngcontent-%COMP%]{display:block;width:100%;height:100%}.seed-pill[_ngcontent-%COMP%]{color:var(--warn);background:var(--warn-soft);font-size:9.5px;font-weight:600;padding:1px 6px}.tips-body[_ngcontent-%COMP%]{flex:1;padding:10px;display:flex;flex-direction:column;gap:8px;min-height:0}.tip-empty[_ngcontent-%COMP%]{color:var(--text-muted);font-size:12px;text-align:center;padding:12px}.tip-row[_ngcontent-%COMP%]{display:flex;gap:10px;padding:10px 12px;border-radius:8px;background:var(--bg-panel-2);border:1px solid var(--border-subtle);border-left-width:2.5px;animation:_ngcontent-%COMP%_slideInRight .2s ease;flex-shrink:0}.tip-sev-icon[_ngcontent-%COMP%]{flex-shrink:0;margin-top:1px}.tip-body-col[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:0}.tip-title[_ngcontent-%COMP%]{font-size:12.5px;font-weight:550;line-height:1.35;text-wrap:pretty}.tip-meta-row[_ngcontent-%COMP%]{margin-top:7px}.tip-fix[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-secondary);background:var(--bg-canvas);padding:2px 6px;border-radius:4px;border:1px solid var(--border-subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px}.heatmap-card[_ngcontent-%COMP%]{margin-bottom:14px}.heatmap-head[_ngcontent-%COMP%]{justify-content:space-between;margin-bottom:10px}.heatmap-legend[_ngcontent-%COMP%]{margin-top:9px;align-items:center}.heatmap-gradient[_ngcontent-%COMP%]{width:96px;height:6px;border-radius:999px;background:linear-gradient(90deg,var(--node-route),var(--warn),var(--error))}.bottom-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:1.4fr 1fr;gap:12px}.prompts-card[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:0}.prompts-head[_ngcontent-%COMP%]{justify-content:space-between;margin-bottom:6px}.prompt-row[_ngcontent-%COMP%]{display:flex;gap:10px;padding:7px 4px;border-radius:6px;cursor:pointer;align-items:center}.prompt-row[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.prompt-text[_ngcontent-%COMP%]{font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prompt-right[_ngcontent-%COMP%]{text-align:right;flex-shrink:0}.prompt-cost[_ngcontent-%COMP%]{font-size:12px;font-weight:600}.prompt-cost.expensive[_ngcontent-%COMP%]{color:var(--error)}.cache-card[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:12px}.cache-headline[_ngcontent-%COMP%]{align-items:flex-end;gap:10px}.cache-rate[_ngcontent-%COMP%]{font-size:38px;font-weight:700;letter-spacing:-.03em;line-height:.9;color:var(--node-route)}.cache-divider[_ngcontent-%COMP%]{height:1px;background:var(--border-subtle)}.cache-kv-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr 1fr;gap:10px 14px}.kv[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:1px}.kv-label[_ngcontent-%COMP%]{color:var(--text-muted);font-size:10.5px}.kv-value[_ngcontent-%COMP%]{font-size:15px;font-weight:600}.kv-sub[_ngcontent-%COMP%]{font-size:9.5px}.dash-footer[_ngcontent-%COMP%]{margin-top:16px;text-align:right;font-size:10px}.dot-live[_ngcontent-%COMP%]{color:var(--success)}.dot-mock[_ngcontent-%COMP%]{color:var(--warn)}@keyframes _ngcontent-%COMP%_slideInRight{0%{opacity:0;transform:translate(14px)}to{opacity:1;transform:translate(0)}}'],changeDetection:0})},Ne=[{id:"s-1",label:"validateSession",sub:"src/auth.ts",kind:"function",x:0,y:0},{id:"s-2",label:"checkExpiry",sub:"src/auth.ts",kind:"method",x:-180,y:-70},{id:"s-3",label:"signToken",sub:"src/auth.ts",kind:"function",x:-180,y:50},{id:"s-4",label:"AuthRoute",sub:"src/routes/auth.ts",kind:"route",x:200,y:-90},{id:"s-5",label:"login",sub:"src/routes/auth.ts",kind:"function",x:200,y:30},{id:"s-6",label:"logout",sub:"src/routes/auth.ts",kind:"function",x:230,y:110},{id:"s-7",label:"auth.test.ts",sub:"test/auth.test.ts",kind:"test",x:-240,y:140},{id:"s-8",label:"session.test.ts",sub:"test/session.test.ts",kind:"test",x:-100,y:180},{id:"s-9",label:"REQ-AUTH-005",sub:"reject expired tokens",kind:"spec",state:"drifted",x:30,y:-180},{id:"s-10",label:"REQ-AUTH-001",sub:"sign session tokens",kind:"spec",state:"verified",x:-150,y:-190},{id:"s-11",label:"User",sub:"src/types/user.ts",kind:"class",x:-340,y:-10},{id:"s-12",label:"Session",sub:"src/types/session.ts",kind:"class",x:60,y:130},{id:"s-13",label:"jwtSign",sub:"src/lib/jwt.ts",kind:"function",x:-340,y:80},{id:"s-14",label:"jwtVerify",sub:"src/lib/jwt.ts",kind:"function",x:350,y:-10},{id:"s-15",label:"tokenStore",sub:"src/db/tokens.ts",kind:"function",x:350,y:90}],Fe=[{from:"s-1",to:"s-2",kind:"calls"},{from:"s-1",to:"s-3",kind:"calls"},{from:"s-4",to:"s-5",kind:"calls"},{from:"s-4",to:"s-6",kind:"calls"},{from:"s-5",to:"s-1",kind:"calls"},{from:"s-6",to:"s-1",kind:"calls"},{from:"s-3",to:"s-13",kind:"calls"},{from:"s-2",to:"s-14",kind:"calls"},{from:"s-1",to:"s-12",kind:"references"},{from:"s-5",to:"s-11",kind:"references"},{from:"s-9",to:"s-1",kind:"implements"},{from:"s-10",to:"s-3",kind:"implements"},{from:"s-7",to:"s-1",kind:"references"},{from:"s-8",to:"s-12",kind:"references"},{from:"s-14",to:"s-15",kind:"calls"}];function $e(i){if(i.length===0)return[];let e=i[0],n=i.slice(1),t=[{id:e.id,label:e.label,sub:e.sub,kind:e.kind,x:0,y:0}],d=220;for(let h=0;h<n.length;h++){let S=h/n.length*Math.PI*2-Math.PI/2,x=n[h];t.push({id:x.id,label:x.label,sub:x.sub,kind:x.kind,x:Math.cos(S)*d,y:Math.sin(S)*d})}return t}export{J as Dashboard};
@@ -1 +0,0 @@
1
- import{a as v}from"./chunk-7RNS77UP.js";import{a as m,b}from"./chunk-E44X4RH2.js";import{E as p,I as n,R as h,W as o,X as S,lb as y}from"./chunk-PDN6QYGJ.js";import{a as d,b as f}from"./chunk-Q7L6LLAK.js";var s=class i{api=n(m);projects=n(v);tickSig=o(0);loadingSig=o(!1);errorSig=o(null);lastRefreshSig=o(null);tick=this.tickSig.asReadonly();loading=this.loadingSig.asReadonly();error=this.errorSig.asReadonly();lastRefreshAt=this.lastRefreshSig.asReadonly();lastRefreshLabel=y(()=>{let r=this.lastRefreshSig();if(r===null)return null;let e=Date.now()-r;return e<5e3?"just now":e<6e4?`${Math.round(e/1e3)}s ago`:e<36e5?`${Math.round(e/6e4)}m ago`:`${Math.round(e/36e5)}h ago`});async triggerGlobalRefresh(){if(!this.loadingSig()){this.loadingSig.set(!0),this.errorSig.set(null);try{let r=this.projects.projectQuery(),e=await this.api.post(`/api/refresh${r}`,{});(e.syncError||e.ingestError)&&this.errorSig.set([e.syncError,e.ingestError].filter(Boolean).join(" \xB7 ")),this.lastRefreshSig.set(Date.now()),this.tickSig.update(c=>c+1)}catch(r){this.errorSig.set(r instanceof Error?r.message:String(r))}finally{this.loadingSig.set(!1)}}}notifyLocalChange(){this.lastRefreshSig.set(Date.now()),this.tickSig.update(r=>r+1)}static \u0275fac=function(e){return new(e||i)};static \u0275prov=p({token:i,factory:i.\u0275fac,providedIn:"root"})};function $(i,r){let e=o({data:null,loading:!0,error:null,source:"init",noProject:!1}),c=n(h),R=n(s),g=o(0),j=()=>{let l=r();if(!l){e.set({data:null,loading:!1,error:null,source:"init",noProject:!1});return}a&&a.abort(),a=new AbortController,e.update(t=>f(d({},t),{loading:!0,error:null,noProject:!1})),i.get(l,a.signal).then(t=>e.set({data:t,loading:!1,error:null,source:"api",noProject:!1})).catch(t=>{if(t instanceof Error&&t.name==="AbortError")return;let u=t instanceof b&&t.status===409&&(t.code==="no_project"||t.code==="no_primary");e.set({data:null,loading:!1,error:u?null:t instanceof Error?t:new Error(String(t)),source:"api",noProject:u})})},a=null;return S(()=>{r(),g(),R.tick(),j()}),c.onDestroy(()=>{a?.abort()}),{state:e,refetch:()=>g.update(l=>l+1)}}export{s as a,$ as b};
@@ -1 +0,0 @@
1
- import{a as le}from"./chunk-SEXBRGYK.js";import{a as re}from"./chunk-G7VZT5KB.js";import{a as ae}from"./chunk-X2HTISHL.js";import{a as oe}from"./chunk-DTRN7FZR.js";import{a as ne,b as H}from"./chunk-4N5DWG46.js";import{a as Z,d as ee}from"./chunk-SHPTC4RL.js";import"./chunk-7RNS77UP.js";import{a as te}from"./chunk-E44X4RH2.js";import{Aa as x,C as j,Ga as $,I as M,Ia as E,Ka as d,M as D,N as I,R as F,Ta as C,Ua as z,Va as l,W as S,Wa as u,X as B,Xa as g,Ya as V,Za as J,aa as L,bb as Y,ea as o,gb as k,hb as K,ib as w,ka as W,lb as h,qa as A,ra as p,sa as m,ua as G,va as P,vb as Q,wa as O,xa as _,ya as a,yb as X,za as r,zb as ie}from"./chunk-PDN6QYGJ.js";import"./chunk-Q7L6LLAK.js";function se(i,t){let n=!t?.manualCleanup?t?.injector?.get(F)??M(F):null,s=_e(t?.equal),c;t?.requireSync?c=S({kind:0},{equal:s}):c=S({kind:1,value:t?.initialValue},{equal:s});let v,y=i.subscribe({next:f=>c.set({kind:1,value:f}),error:f=>{c.set({kind:2,error:f}),v?.()},complete:()=>{v?.()}});if(t?.requireSync&&c().kind===0)throw new j(601,!1);return v=n?.onDestroy(y.unsubscribe.bind(y)),h(()=>{let f=c();switch(f.kind){case 1:return f.value;case 2:throw f.error;case 0:throw new j(601,!1)}},{equal:t?.equal})}function _e(i=Object.is){return(t,e)=>t.kind===1&&e.kind===1&&i(t.value,e.value)}var xe=()=>["/sessions"],pe=(i,t)=>t.prompt.id,ge=(i,t)=>t.id,de=(i,t)=>t.name;function fe(i,t){if(i&1&&(a(0,"app-pill",7),l(1),r()),i&2){let e=d();_("color","var(--node-spec)")("bg","var(--node-spec-soft)"),o(),u(e.session().last_model)}}function ve(i,t){if(i&1&&l(0),i&2){let e=d(),n=d();J(" \xB7 ",n.fmtClock(e.started_at)," \u2013 ",n.fmtClock(e.ended_at)," (",n.fmtDurationSec(e.started_at,e.ended_at),") ")}}function be(i,t){if(i&1&&(a(0,"div",10),l(1),p(2,ve,1,3),r()),i&2){let e=t;o(),g("",e.project_path," "),o(),m(e.started_at&&e.ended_at?2:-1)}}function he(i,t){i&1&&(a(0,"div",14),l(1,"Loading session\u2026"),r())}function Ce(i,t){if(i&1){let e=$();a(0,"div",15)(1,"div",18),l(2,"Couldn't load session"),r(),a(3,"div",19),l(4),r(),a(5,"button",20),E("click",function(){D(e);let s=d();return I(s.forceRefresh())}),l(6,"Retry"),r()()}if(i&2){let e,n=d();o(4),u((e=n.resource.state().error)==null?null:e.message)}}function ye(i,t){i&1&&(a(0,"app-pill",59),x(1,"app-icon",72),l(2,"subagent "),r()),i&2&&(_("color","var(--node-route)")("bg","var(--node-route-soft)"),o(),_("size",10))}function ke(i,t){if(i&1&&x(0,"app-icon",60),i&2){let e=d().$implicit;_("size",12)("title",e.slashCommand)}}function Me(i,t){if(i&1&&l(0),i&2){let e=d().$implicit;g(" ",e.prompt.text.length>140?e.prompt.text.slice(0,140)+"\u2026":e.prompt.text," ")}}function Se(i,t){i&1&&(a(0,"span",62),l(1,"(assistant-only turn)"),r())}function we(i,t){if(i&1&&(a(0,"span",66),l(1),r()),i&2){let e=d().$implicit,n=d(2);o(),u(n.fmtDurationMs(e.prompt.durationMs))}}function Pe(i,t){if(i&1&&(a(0,"section",73)(1,"div",74),l(2,"User prompt"),r(),a(3,"pre",80),l(4),r()()),i&2){let e=d(2).$implicit;o(4),u(e.prompt.text)}}function Oe(i,t){if(i&1&&(a(0,"section",73)(1,"div",74),l(2,"Assistant response"),r(),x(3,"div",81),r()),i&2){let e=d(2).$implicit,n=d(2);o(3),_("innerHTML",n.renderAssistant(e.prompt.assistant_text),L)}}function Ee(i,t){if(i&1&&(a(0,"section",73)(1,"details",82)(2,"summary",83),l(3," Extended thinking "),a(4,"span",84),l(5,"(click to expand)"),r()(),x(6,"div",85),r()()),i&2){let e=d(2).$implicit,n=d(2);o(6),_("innerHTML",n.renderAssistant(e.prompt.thinking_text),L)}}function Te(i,t){if(i&1&&(a(0,"div",76)(1,"div",77),l(2,"Duration"),r(),a(3,"div",78),l(4),r()()),i&2){let e=d(2).$implicit,n=d(2);o(4),u(n.fmtDurationMs(e.prompt.durationMs))}}function De(i,t){if(i&1&&(a(0,"div",76)(1,"div",77),l(2,"Model"),r(),a(3,"div",78),l(4),r()()),i&2){let e=d(2).$implicit;o(4),u(e.prompt.model)}}function Ie(i,t){if(i&1&&(a(0,"div",87)(1,"span",88),l(2),r()()),i&2){let e=t.$implicit;_("title",e),o(2),u(e)}}function ze(i,t){if(i&1&&(a(0,"section",73)(1,"div",74),l(2),r(),a(3,"div",86),P(4,Ie,3,2,"div",87,G),r()()),i&2){let e=d(2).$implicit;o(2),g("Files touched \xB7 ",e.filesTouched.length),o(2),O(e.filesTouched)}}function Re(i,t){i&1&&l(0," \u203A ")}function Fe(i,t){if(i&1&&(a(0,"span",94),l(1),r()),i&2){let e=d().$implicit;o(),u(e.input_summary)}}function $e(i,t){if(i&1&&(a(0,"span",95),l(1),r()),i&2){let e=d().$implicit,n=d(5);o(),u(n.fmtBytes(e.result_length))}}function Be(i,t){if(i&1&&(a(0,"pre",96),l(1),r()),i&2){let e=d().$implicit,n=d(5);o(),u(n.formatToolInput(e.input_json))}}function Ne(i,t){if(i&1){let e=$();a(0,"div",90)(1,"button",91),E("click",function(){let s=D(e).$implicit,c=d(5);return I(c.toggleToolInput(s.id))}),a(2,"span",92),p(3,Re,1,0),r(),a(4,"span",93),l(5),r(),p(6,Fe,2,1,"span",94),x(7,"span",31),p(8,$e,2,1,"span",95),r(),p(9,Be,2,1,"pre",96),r()}if(i&2){let e=t.$implicit,n=d(5);o(),z("has-input",!!e.input_json)("expanded",n.isToolInputExpanded(e.id)),_("disabled",!e.input_json),A("aria-expanded",n.isToolInputExpanded(e.id)),o(),z("open",n.isToolInputExpanded(e.id)),o(),m(e.input_json?3:-1),o(),C("color",n.toolColor(e.tool_name)),o(),u(e.tool_name),o(),m(e.input_summary?6:-1),o(2),m(e.result_length?8:-1),o(),m(e.input_json&&n.isToolInputExpanded(e.id)?9:-1)}}function je(i,t){if(i&1&&(a(0,"section",73)(1,"div",74),l(2),r(),a(3,"div",89),P(4,Ne,10,15,"div",90,ge),r()()),i&2){let e=d(2).$implicit,n=d(2);o(2),V("Tool calls \xB7 ",e.tools.length," \xB7 returned ",n.fmtBytes(e.toolBytes)),o(2),O(e.tools)}}function Le(i,t){if(i&1&&(a(0,"div",71),p(1,Pe,5,1,"section",73),p(2,Oe,4,1,"section",73),p(3,Ee,7,1,"section",73),a(4,"section",73)(5,"div",74),l(6,"Token breakdown"),r(),a(7,"div",75)(8,"div",76)(9,"div",77),l(10,"Input"),r(),a(11,"div",78),l(12),r()(),a(13,"div",76)(14,"div",77),l(15,"Output"),r(),a(16,"div",78),l(17),r()(),a(18,"div",76)(19,"div",77),l(20,"Cache write"),r(),a(21,"div",78),l(22),r()(),a(23,"div",76)(24,"div",77),l(25,"Cache read"),r(),a(26,"div",78),l(27),r()(),a(28,"div",76)(29,"div",77),l(30,"Cost"),r(),a(31,"div",79),l(32),r()(),p(33,Te,5,1,"div",76),p(34,De,5,1,"div",76),r()(),p(35,ze,6,1,"section",73),p(36,je,6,2,"section",73),r()),i&2){let e=d().$implicit,n=d(2);o(),m(e.prompt.text?1:-1),o(),m(e.prompt.assistant_text?2:-1),o(),m(e.prompt.thinking_text?3:-1),o(9),u(n.fmtTokens(e.prompt.input_tokens)),o(5),u(n.fmtTokens(e.prompt.output_tokens)),o(5),u(n.fmtTokens(e.prompt.cache_creation_tokens)),o(5),u(n.fmtTokens(e.prompt.cache_read_tokens)),o(5),g("$",e.prompt.cost_usd.toFixed(4)),o(),m(e.prompt.durationMs?33:-1),o(),m(e.prompt.model?34:-1),o(),m(e.filesTouched.length>0?35:-1),o(),m(e.tools.length>0?36:-1)}}function Ae(i,t){if(i&1){let e=$();a(0,"div",34)(1,"button",56),E("click",function(){let s=D(e).$implicit,c=d(2);return I(c.toggleExpand(s.prompt.id))}),a(2,"span",57),l(3),r(),x(4,"span",58),k(5,"number"),p(6,ye,3,3,"app-pill",59),p(7,ke,1,2,"app-icon",60),a(8,"span",61),p(9,Me,1,1)(10,Se,2,0,"span",62),r(),a(11,"span",63),x(12,"app-icon",64),a(13,"span",65),l(14),r()(),p(15,we,2,1,"span",66),a(16,"span",67),l(17),r(),a(18,"span",68),l(19),k(20,"number"),r(),a(21,"span",69),l(22),r(),x(23,"app-icon",70),r(),p(24,Le,37,12,"div",71),r()}if(i&2){let e=t.$implicit,n=d(2);o(),z("expanded",n.isExpanded(e.prompt.id)),A("aria-expanded",n.isExpanded(e.prompt.id)),o(2),u(n.fmtClock(e.prompt.ts)),o(),C("background",n.cacheColor(e.prompt.cache_read_tokens>0?e.prompt.cache_read_tokens/(e.prompt.input_tokens+e.prompt.cache_creation_tokens+e.prompt.cache_read_tokens||1):0)),_("title","Cache: "+K(5,22,e.prompt.cache_read_tokens)),o(2),m(e.prompt.is_sidechain===1?6:-1),o(),m(e.slashCommand?7:-1),o(2),m(e.prompt.text?9:10),o(3),_("size",11),o(2),u(e.tools.length),o(),m(e.prompt.durationMs?15:-1),o(2),u(n.fmtTokens(e.totalTokens)),o(),C("color",n.cacheColor(e.totalTokens>0?(e.prompt.cache_read_tokens||0)/e.totalTokens:0)),o(),g(" ",e.totalTokens>0?w(20,24,(e.prompt.cache_read_tokens||0)/e.totalTokens*100,"1.0-0"):0,"% "),o(2),C("color",e.prompt.cost_usd>2.5?"var(--error)":"var(--text-primary)"),o(),g("$",e.prompt.cost_usd.toFixed(2)),o(),_("size",14),o(),m(n.isExpanded(e.prompt.id)?24:-1)}}function Ve(i,t){i&1&&(a(0,"div",17),l(1,"No prompts logged for this session yet."),r())}function He(i,t){if(i&1&&(a(0,"span",102),l(1),r()),i&2){let e=d().$implicit;o(),g("\xD7",e.count)}}function qe(i,t){if(i&1&&(a(0,"span",99),x(1,"app-icon",101),l(2),p(3,He,2,1,"span",102),r()),i&2){let e=t.$implicit;o(),_("size",10),o(),g("",e.name," "),o(),m(e.count>1?3:-1)}}function Ue(i,t){if(i&1&&(a(0,"span",102),l(1),r()),i&2){let e=d().$implicit;o(),g("\xD7",e.count)}}function We(i,t){if(i&1&&(a(0,"span",100),x(1,"app-icon",103),l(2),p(3,Ue,2,1,"span",102),r()),i&2){let e=t.$implicit;o(),_("size",10),o(),g("",e.name," "),o(),m(e.count>1?3:-1)}}function Ge(i,t){if(i&1&&(a(0,"div",97)(1,"div",36),l(2,"Commands & skills"),r(),a(3,"div",98),P(4,qe,4,3,"span",99,de),P(6,We,4,3,"span",100,de),r()()),i&2){let e=d();o(4),O(e.slashCommands),o(2),O(e.skills)}}function Je(i,t){if(i&1&&(a(0,"div",36),l(1),r(),x(2,"app-h-bars",104),a(3,"div",105),l(4,"bar = call count"),r()),i&2){let e=d(),n=d(2);o(),g("Tools used \xB7 ",e.byTool.length),o(),_("items",e.byTool)("fmt",n.fmtTokensFn)("color",n.toolBarColor)}}function Ye(i,t){if(i&1&&(p(0,Ge,8,0,"div",97),p(1,Je,5,4)),i&2){let e=t;m(e.slashCommands.length||e.skills.length?0:-1),o(),m(e.byTool.length?1:-1)}}function Ke(i,t){if(i&1&&(a(0,"div",43)(1,"span",108),l(2),r(),a(3,"div",31),x(4,"app-bar",109),r(),a(5,"span",110),l(6),r()()),i&2){let e=t.$implicit,n=d(3);o(2),u(n.fmtClock(e.prompt.ts)),o(2),_("frac",e.prompt.cost_usd/n.maxPromptCost())("color",e.prompt.cost_usd>2.5?"var(--error)":"var(--accent)"),o(2),g("$",e.prompt.cost_usd.toFixed(2))}}function Qe(i,t){if(i&1&&(a(0,"div",106),l(1,"Cost per prompt"),r(),a(2,"div",107),P(3,Ke,7,4,"div",43,pe),r()),i&2){let e=d(2);o(3),O(e.groups())}}function Xe(i,t){if(i&1){let e=$();a(0,"div",16)(1,"div",21)(2,"div",22)(3,"div",23)(4,"div",24),l(5,"Cost"),r(),a(6,"div",25),l(7),r()(),a(8,"div",23)(9,"div",24),l(10,"Prompts"),r(),a(11,"div",26),l(12),r()(),a(13,"div",23)(14,"div",24),l(15,"Window"),r(),a(16,"div",27),l(17),r()(),a(18,"div",23)(19,"div",24),l(20,"Cache hit"),r(),a(21,"div",26),l(22),k(23,"number"),r()(),a(24,"div",23)(25,"div",24),l(26,"Tool calls"),r(),a(27,"div",26),l(28),r()()(),a(29,"div",28)(30,"span",29),l(31),r(),a(32,"span",30),l(33,"click a prompt for full detail"),r(),x(34,"div",31),a(35,"button",32),E("click",function(){D(e);let s=d();return I(s.expandAll())}),l(36,"Expand all"),r(),a(37,"button",32),E("click",function(){D(e);let s=d();return I(s.collapseAll())}),l(38,"Collapse all"),r()(),a(39,"div",33),P(40,Ae,25,27,"div",34,pe,!1,Ve,2,0,"div",17),r()(),a(43,"div",35)(44,"div",36),l(45,"Token mix"),r(),a(46,"div",37),x(47,"div",38)(48,"div",39)(49,"div",40)(50,"div",41),r(),a(51,"div",42)(52,"div",43),x(53,"span",44),a(54,"span",45),l(55,"Input"),r(),a(56,"span",46),l(57),r(),a(58,"span",47),l(59),k(60,"number"),r()(),a(61,"div",43),x(62,"span",48),a(63,"span",45),l(64,"Output"),r(),a(65,"span",46),l(66),r(),a(67,"span",47),l(68),k(69,"number"),r()(),a(70,"div",43),x(71,"span",49),a(72,"span",45),l(73,"Cache write"),r(),a(74,"span",46),l(75),r(),a(76,"span",47),l(77),k(78,"number"),r()(),a(79,"div",43),x(80,"span",50),a(81,"span",45),l(82,"Cache read"),r(),a(83,"span",46),l(84),r(),a(85,"span",47),l(86),k(87,"number"),r()()(),a(88,"div",51)(89,"div",43),x(90,"app-icon",52),a(91,"span",53),l(92,"Cache effectiveness"),r()(),a(93,"div",54)(94,"span",55),l(95),k(96,"number"),r(),a(97,"span",53),l(98,"of input served from cache"),r()()(),p(99,Ye,2,2),p(100,Qe,5,0),r()()}if(i&2){let e,n=t,s=d();o(7),g("$",n.total_cost_usd.toFixed(2)),o(5),u(n.prompt_count),o(5),V(" ",s.fmtClock(n.started_at)," \u2013 ",s.fmtClock(n.ended_at).split(" ").pop()," "),o(4),C("color",s.cacheColor(s.cacheReadRate())),o(),g(" ",w(23,34,s.cacheReadRate()*100,"1.0-0"),"% "),o(6),u(s.totalToolCalls()),o(3),g("Prompt timeline \xB7 ",s.groups().length),o(9),O(s.groups()),o(7),C("width",s.tokPct("input"),"%"),_("title","Input: "+s.fmtTokens(n.total_input_tokens)),o(),C("width",s.tokPct("output"),"%"),_("title","Output: "+s.fmtTokens(n.total_output_tokens)),o(),C("width",s.tokPct("cacheWrite"),"%"),_("title","Cache write: "+s.fmtTokens(n.total_cache_creation_tokens)),o(),C("width",s.tokPct("cacheRead"),"%"),_("title","Cache read: "+s.fmtTokens(n.total_cache_read_tokens)),o(7),u(s.fmtTokens(n.total_input_tokens)),o(2),g("",w(60,37,s.tokPct("input"),"1.0-0"),"%"),o(7),u(s.fmtTokens(n.total_output_tokens)),o(2),g("",w(69,40,s.tokPct("output"),"1.0-0"),"%"),o(7),u(s.fmtTokens(n.total_cache_creation_tokens)),o(2),g("",w(78,43,s.tokPct("cacheWrite"),"1.0-0"),"%"),o(7),u(s.fmtTokens(n.total_cache_read_tokens)),o(2),g("",w(87,46,s.tokPct("cacheRead"),"1.0-0"),"%"),o(4),_("size",13),o(5),g("",w(96,49,s.cacheReadRate()*100,"1.0-0"),"%"),o(4),m((e=s.summaryData())?99:-1,e),o(),m(s.groups().length>0?100:-1)}}function Ze(i,t){i&1&&(a(0,"div",17),l(1,"Session not found."),r())}var et=5e3,tt=/<command-name>([^<]+)<\/command-name>/,nt=new Set(["Read","Edit","Write","NotebookEdit","MultiEdit"]),ce=class i{api=M(te);route=M(Z);sanitizer=M(X);destroyRef=M(F);refresh=M(ne);liveMode=S("idle");idSig=se(this.route.paramMap,{initialValue:this.route.snapshot.paramMap});id=h(()=>this.idSig().get("id")??"");localRefreshing=S(!1);expandedIds=S(new Set);expandedToolInputs=S(new Set);resource=H(this.api,()=>{let t=this.id();return t?`/api/claude/session/${encodeURIComponent(t)}`:null});summary=H(this.api,()=>{let t=this.id();return t?`/api/claude/session/${encodeURIComponent(t)}/summary`:null});session=h(()=>this.resource.state().data?.session??null);prompts=h(()=>this.resource.state().data?.prompts??[]);toolCalls=h(()=>this.resource.state().data?.toolCalls??[]);summaryData=h(()=>this.summary.state().data??null);groups=h(()=>{let t=this.prompts(),e=this.toolCalls(),n=new Map;for(let s of e){let c=n.get(s.prompt_id)??[];c.push(s),n.set(s.prompt_id,c)}return t.map(s=>{let c=n.get(s.id)??[],v=(s.input_tokens||0)+(s.output_tokens||0)+(s.cache_creation_tokens||0)+(s.cache_read_tokens||0),y=c.reduce((b,R)=>b+(R.result_length||0),0),f=s.text?tt.exec(s.text):null,T=f?f[1].trim():null,q=c.length>0?Math.max(...c.map(b=>b.ts||0)):0,me=q>s.ts?q-s.ts:0,N=new Map;for(let b of c)N.set(b.tool_name,(N.get(b.tool_name)??0)+1);let ue=Array.from(N.entries()).map(([b,R])=>({name:b,count:R,color:this.toolColor(b)})).sort((b,R)=>R.count-b.count),U=new Set;for(let b of c)nt.has(b.tool_name)&&b.input_summary&&U.add(b.input_summary);return{prompt:s,tools:c,totalTokens:v,toolBytes:y,slashCommand:T,durationMs:me,toolBreakdown:ue,filesTouched:Array.from(U)}})});totalToolCalls=h(()=>this.toolCalls().length);totalTokens=h(()=>{let t=this.session();return t&&(t.total_input_tokens||0)+(t.total_output_tokens||0)+(t.total_cache_creation_tokens||0)+(t.total_cache_read_tokens||0)||1});maxPromptCost=h(()=>{let t=this.groups();return Math.max(1e-4,...t.map(e=>e.prompt.cost_usd||0))});toolBarColor=t=>{let e=t.name;return e==="Read"?"var(--node-spec)":e==="Edit"||e==="Write"||e==="MultiEdit"?"var(--accent)":e==="Bash"?"var(--warn)":e==="Grep"||e==="Glob"?"var(--node-test)":e==="Task"?"var(--node-route)":e.startsWith("mcp__")?"var(--success)":"var(--node-code)"};cacheReadRate=h(()=>{let t=this.session();if(!t)return 0;let e=(t.total_input_tokens||0)+(t.total_cache_creation_tokens||0)+(t.total_cache_read_tokens||0);return e>0?(t.total_cache_read_tokens||0)/e:0});constructor(){B(()=>{!this.resource.state().loading&&this.localRefreshing()&&this.localRefreshing.set(!1)});let t=null,e=null,n=()=>{e!==null&&(clearInterval(e),e=null)},s=()=>{e===null&&(e=setInterval(()=>{typeof document<"u"&&document.visibilityState==="visible"&&this.resource.refetch()},et))},c=()=>{t&&(t(),t=null)},v=f=>{f&&(c(),t=this.api.openEventStream(`/api/claude/session/${encodeURIComponent(f)}/events`,T=>{T==="prompt_added"||T==="tool_call_added"?this.resource.refetch():T==="snapshot"?(this.liveMode.set("live"),n()):T==="stream_error"&&(this.liveMode.set("polling"),s())},()=>{this.liveMode.set("polling"),s()},["prompt_added","tool_call_added","snapshot","stream_error"]))},y=()=>{if(!(typeof document>"u"))if(document.visibilityState==="visible"){this.resource.refetch();let f=this.id();f&&this.liveMode()==="polling"&&v(f)}else n()};B(()=>{let f=this.id();if(c(),n(),!f){this.liveMode.set("idle");return}v(f)}),typeof document<"u"&&document.addEventListener("visibilitychange",y),this.destroyRef.onDestroy(()=>{c(),n(),this.liveMode.set("idle"),typeof document<"u"&&document.removeEventListener("visibilitychange",y)})}async forceRefresh(){this.localRefreshing.set(!0),await this.refresh.triggerGlobalRefresh()}isExpanded(t){return this.expandedIds().has(t)}toggleExpand(t){this.expandedIds.update(e=>{let n=new Set(e);return n.has(t)?n.delete(t):n.add(t),n})}expandAll(){this.expandedIds.set(new Set(this.prompts().map(t=>t.id)))}collapseAll(){this.expandedIds.set(new Set)}isToolInputExpanded(t){return this.expandedToolInputs().has(t)}toggleToolInput(t){this.expandedToolInputs.update(e=>{let n=new Set(e);return n.has(t)?n.delete(t):n.add(t),n})}renderAssistant(t){return this.sanitizer.bypassSecurityTrustHtml(re(t??""))}formatToolInput(t){if(!t)return"";try{return JSON.stringify(JSON.parse(t),null,2)}catch{return t}}fmtBytes(t){return t?t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} kB`:`${(t/(1024*1024)).toFixed(1)} MB`:"0"}fmtTokens(t){return t<1e3?`${t}`:t<1e6?`${(t/1e3).toFixed(1)}k`:`${(t/1e6).toFixed(2)}M`}fmtTokensFn=t=>this.fmtTokens(t);fmtClock(t){if(!t)return"";try{let e=new Date(t),n=new Date;n.setHours(0,0,0,0);let s=864e5,c=n.getTime()-new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime(),v=e.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"});return c===0?v:c===s?"Yest "+v:e.toLocaleDateString([],{month:"short",day:"numeric"})+" "+v}catch{return String(t)}}fmtDurationSec(t,e){if(!t||!e)return"";let n=Math.round((e-t)/1e3);if(n<60)return`${n}s`;let s=Math.floor(n/60),c=n%60;if(s<60)return`${s}m ${c}s`;let v=Math.floor(s/60),y=s%60;return`${v}h ${y}m`}fmtDurationMs(t){if(!t||t<=0)return"";if(t<1e3)return`${t}ms`;let e=t/1e3;if(e<60)return`${e.toFixed(e<10?1:0)}s`;let n=Math.floor(e/60),s=Math.round(e%60);if(n<60)return`${n}m ${s}s`;let c=Math.floor(n/60),v=n%60;return`${c}h ${v}m`}basename(t){if(!t)return"";if(t.length<=40)return t;let e=t.split("/");return e.length<=2?t:"\u2026/"+e.slice(-2).join("/")}toolColor(t){return t==="Read"?"var(--node-spec)":t==="Edit"||t==="Write"||t==="MultiEdit"||t==="NotebookEdit"?"var(--accent)":t==="Bash"?"var(--warn)":t==="Grep"||t==="Glob"?"var(--node-test)":t==="Task"?"var(--node-route)":t.startsWith("mcp__")?"var(--success)":"var(--text-secondary)"}cacheColor(t){return t>=.7?"var(--success)":t>=.5?"var(--warn)":"var(--error)"}tokPct(t){let e=this.session();if(!e)return 0;let n=this.totalTokens();return(t==="input"?e.total_input_tokens||0:t==="output"?e.total_output_tokens||0:t==="cacheWrite"?e.total_cache_creation_tokens||0:e.total_cache_read_tokens||0)/n*100}static \u0275fac=function(e){return new(e||i)};static \u0275cmp=W({type:i,selectors:[["app-session-detail"]],decls:22,vars:20,consts:[[1,"sd-root"],[1,"page-head"],[1,"back-link","btn","btn-ghost","btn-sm",3,"routerLink"],["name","chevronLeft",3,"size"],[1,"title-block"],[1,"title"],[1,"mono","session-id"],[3,"color","bg"],[1,"live-pill",3,"title"],[1,"dot"],[1,"sub"],[1,"page-actions"],["type","button","aria-label","Refresh session detail",1,"btn","btn-secondary","btn-sm","refresh-btn",3,"click","disabled"],["name","refresh",3,"size"],[1,"loading"],[1,"error"],[1,"sd-body"],[1,"empty"],[1,"error-title"],[1,"error-detail"],[1,"btn","btn-secondary","btn-sm",3,"click"],[1,"scroll-y","sd-main"],[1,"stat-strip"],[1,"stat"],[1,"stat-lbl"],[1,"stat-val","cost"],[1,"stat-val","mono"],[1,"stat-val","mono",2,"font-size","12px"],[1,"row","gap-8",2,"justify-content","space-between","margin-bottom","8px"],[1,"eyebrow"],[1,"muted",2,"font-size","11px"],[1,"grow"],["type","button",1,"btn","btn-ghost","btn-sm",3,"click"],[1,"col","gap-6",2,"padding-bottom","16px"],[1,"prompt","card"],[1,"scroll-y","sd-rail"],[1,"eyebrow",2,"margin-bottom","10px"],[1,"tok-bar",2,"margin-bottom","10px"],[1,"tok-seg",2,"background","var(--node-spec)",3,"title"],[1,"tok-seg",2,"background","var(--node-code)",3,"title"],[1,"tok-seg",2,"background","var(--warn)",3,"title"],[1,"tok-seg",2,"background","var(--node-route)",3,"title"],[1,"col","gap-6",2,"margin-bottom","20px"],[1,"row","gap-8"],[2,"width","9px","height","9px","border-radius","2px","background","var(--node-spec)","flex-shrink","0"],[1,"muted","grow",2,"font-size","11.5px"],[1,"mono","tabular",2,"font-size","11.5px"],[1,"mono","tabular","muted",2,"font-size","10px","width","32px","text-align","right"],[2,"width","9px","height","9px","border-radius","2px","background","var(--node-code)","flex-shrink","0"],[2,"width","9px","height","9px","border-radius","2px","background","var(--warn)","flex-shrink","0"],[2,"width","9px","height","9px","border-radius","2px","background","var(--node-route)","flex-shrink","0"],[1,"cache-card",2,"margin-bottom","20px"],["name","database",2,"color","var(--success)",3,"size"],[1,"muted",2,"font-size","10.5px"],[1,"row",2,"align-items","baseline","gap","8px","margin-top","4px"],[1,"tabular",2,"font-size","24px","font-weight","700","color","var(--success)"],["type","button",1,"prompt-head","row","gap-10",3,"click"],[1,"mono","muted",2,"font-size","10.5px","width","52px","flex-shrink","0"],[2,"width","8px","height","8px","border-radius","50%","flex-shrink","0",3,"title"],[2,"flex-shrink","0",3,"color","bg"],["name","command",2,"color","var(--node-code)","flex-shrink","0",3,"size","title"],[1,"grow",2,"font-size","12.5px","overflow","hidden","text-overflow","ellipsis","white-space","nowrap","min-width","0"],[1,"muted"],[1,"row","gap-4",2,"flex-shrink","0"],["name","wrench",2,"color","var(--text-muted)",3,"size"],[1,"mono","tabular","muted",2,"font-size","11px"],["title","Wall-clock duration for this prompt",1,"mono","tabular","muted",2,"font-size","11px","width","44px","text-align","right","flex-shrink","0"],[1,"mono","tabular","muted",2,"font-size","11px","width","50px","text-align","right","flex-shrink","0"],[1,"mono","tabular",2,"font-size","11px","width","38px","text-align","right","flex-shrink","0"],[1,"mono","tabular",2,"font-size","13px","font-weight","600","width","54px","text-align","right","flex-shrink","0"],["name","chevronRight",2,"color","var(--text-muted)","flex-shrink","0",3,"size"],[1,"prompt-body"],["name","bot",3,"size"],[1,"prompt-section"],[1,"section-lbl"],[1,"kv-row"],[1,"kv"],[1,"kv-lbl"],[1,"kv-val","mono"],[1,"kv-val","mono","cost"],[1,"prompt-pre"],[1,"assistant-body","md-content",3,"innerHTML"],[1,"thinking-details"],[1,"section-lbl","thinking-summary"],[1,"muted","xs"],[1,"thinking-body","md-content",3,"innerHTML"],[1,"files-touched"],[1,"file-row",3,"title"],[1,"file-path","mono"],[1,"tools"],[1,"tool-block"],["type","button",1,"tool-row",3,"click","disabled"],["aria-hidden","true",1,"tool-chevron","mono"],[1,"tool-name","mono"],[1,"tool-input","mono"],[1,"tool-bytes","mono","muted"],[1,"tool-input-json","mono"],[2,"margin-bottom","20px"],[1,"row","gap-6",2,"flex-wrap","wrap"],[1,"pill",2,"color","var(--node-code)","background","var(--node-code-soft)","font-family","var(--font-mono)","font-weight","500"],[1,"pill",2,"color","var(--node-test)","background","var(--node-test-soft)","font-family","var(--font-mono)","font-weight","500"],["name","command",3,"size"],[2,"opacity","0.7"],["name","sparkles",3,"size"],["valueKey","calls",3,"items","fmt","color"],[1,"muted",2,"font-size","10px","margin-top","8px"],[1,"eyebrow",2,"margin","20px 0 10px"],[1,"col","gap-5"],[1,"mono","muted",2,"font-size","10px","width","44px","flex-shrink","0"],[3,"frac","color"],[1,"mono","tabular",2,"font-size","10.5px","width","40px","text-align","right"]],template:function(e,n){if(e&1&&(a(0,"div",0)(1,"header",1)(2,"a",2),x(3,"app-icon",3),l(4," Sessions "),r(),a(5,"div",4)(6,"div",5)(7,"span",6),l(8),r(),p(9,fe,2,3,"app-pill",7),a(10,"span",8),x(11,"span",9),l(12),r()(),p(13,be,3,2,"div",10),r(),a(14,"div",11)(15,"button",12),E("click",function(){return n.forceRefresh()}),x(16,"app-icon",13),l(17),r()()(),p(18,he,2,0,"div",14)(19,Ce,7,1,"div",15)(20,Xe,101,52,"div",16)(21,Ze,2,0,"div",17),r()),e&2){let s,c,v;o(2),_("routerLink",Y(19,xe)),o(),_("size",14),o(5),u(n.id().slice(0,12)),o(),m((s=n.session())!=null&&s.last_model?9:-1),o(),z("live",n.liveMode()==="live")("polling",n.liveMode()==="polling")("idle",n.liveMode()==="idle"),_("title",n.liveMode()==="live"?"Live \u2014 new prompts push as Claude Code writes them":n.liveMode()==="polling"?"Polling \u2014 SSE unavailable, refetching every 5s":"Idle \u2014 live updates paused"),o(2),g(" ",n.liveMode()==="live"?"Live":n.liveMode()==="polling"?"Polling":"Idle"," "),o(),m((c=n.session())?13:-1,c),o(2),z("spinning",n.localRefreshing()||n.refresh.loading()),_("disabled",n.refresh.loading()),o(),_("size",13),o(),g(" ",n.localRefreshing()||n.refresh.loading()?"Refreshing\u2026":"Refresh"," "),o(),m(n.resource.state().loading&&!n.session()?18:n.resource.state().error?19:(v=n.session())?20:21,v)}},dependencies:[ee,ie,ae,oe,le,Q],styles:['@charset "UTF-8";[_nghost-%COMP%]{display:contents}.sd-root[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;min-height:0;padding:16px 18px 0}.page-head[_ngcontent-%COMP%]{display:flex;align-items:flex-start;gap:12px;margin-bottom:14px;flex-wrap:wrap}.back-link[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:4px;color:var(--text-muted);text-decoration:none}.title-block[_ngcontent-%COMP%]{flex:1;min-width:250px}.title[_ngcontent-%COMP%]{font-size:var(--fs-title);font-weight:600;letter-spacing:-.01em;display:flex;align-items:center;gap:10px;flex-wrap:wrap}.session-id[_ngcontent-%COMP%]{color:var(--accent);font-size:14px}.live-pill[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:6px;font-size:10.5px;font-weight:600;padding:2px 8px;border-radius:999px;white-space:nowrap;cursor:help}.live-pill[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%]{width:7px;height:7px;border-radius:50%;flex-shrink:0}.live-pill.live[_ngcontent-%COMP%]{color:var(--success);background:var(--success-soft)}.live-pill.live[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%]{background:var(--success);animation:_ngcontent-%COMP%_live-pulse 1.6s ease-in-out infinite}.live-pill.polling[_ngcontent-%COMP%]{color:var(--warn);background:var(--warn-soft)}.live-pill.polling[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%]{background:var(--warn)}.live-pill.idle[_ngcontent-%COMP%]{color:var(--text-muted);background:var(--bg-canvas)}.live-pill.idle[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%]{background:var(--text-muted)}@keyframes _ngcontent-%COMP%_live-pulse{0%,to{opacity:.4;transform:scale(.85)}50%{opacity:1;transform:scale(1.05)}}.sub[_ngcontent-%COMP%]{color:var(--text-secondary);font-size:12px;margin-top:2px}.page-actions[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px}.refresh-btn[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:6px}.refresh-btn.spinning[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{animation:_ngcontent-%COMP%_spin .9s linear infinite;color:var(--accent)}.refresh-btn[_ngcontent-%COMP%]:disabled{cursor:progress;opacity:.8}@keyframes _ngcontent-%COMP%_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.sd-body[_ngcontent-%COMP%]{flex:1;display:flex;min-height:0;gap:0}.sd-main[_ngcontent-%COMP%]{flex:1;min-width:0;padding:0 0 18px}.sd-rail[_ngcontent-%COMP%]{width:290px;flex-shrink:0;border-left:1px solid var(--border-subtle);background:var(--bg-panel);padding:16px}.stat-strip[_ngcontent-%COMP%]{display:flex;gap:24px;padding:12px 0;border-top:1px solid var(--border-subtle);border-bottom:1px solid var(--border-subtle);margin-bottom:16px}.stat[_ngcontent-%COMP%] .stat-lbl[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted)}.stat[_ngcontent-%COMP%] .stat-val[_ngcontent-%COMP%]{font-size:16px;font-weight:600;margin-top:2px;color:var(--text-primary);font-variant-numeric:tabular-nums}.stat-val.cost[_ngcontent-%COMP%]{color:var(--accent)}.tok-bar[_ngcontent-%COMP%]{display:flex;height:10px;border-radius:999px;overflow:hidden}.tok-seg[_ngcontent-%COMP%]{height:100%}.cache-card[_ngcontent-%COMP%]{background:var(--success-soft);border:1px solid rgba(70,194,107,.25);border-radius:8px;padding:10px 12px}.prompt.card[_ngcontent-%COMP%]{background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:9px;overflow:hidden;transition:border-color .12s}.prompt.card[_ngcontent-%COMP%]:hover{border-color:var(--border-strong)}.prompt-head[_ngcontent-%COMP%]{width:100%;padding:11px 12px;background:transparent;border:0;text-align:left;cursor:pointer;color:inherit;font-family:inherit}.prompt-head[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.prompt-head[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.prompt-body[_ngcontent-%COMP%]{border-top:1px solid var(--border-subtle);padding:14px 16px;background:var(--bg-canvas)}.prompt-section[_ngcontent-%COMP%]{margin-bottom:14px}.prompt-section[_ngcontent-%COMP%]:last-child{margin-bottom:0}.section-lbl[_ngcontent-%COMP%]{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);margin-bottom:6px}.prompt-pre[_ngcontent-%COMP%]{margin:0;padding:10px 12px;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:7px;font-family:var(--font-mono);font-size:11.5px;line-height:1.55;color:var(--text-primary);white-space:pre-wrap;word-break:break-word;max-height:280px;overflow-y:auto}.kv-row[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:10px 18px}.kv[_ngcontent-%COMP%] .kv-lbl[_ngcontent-%COMP%]{font-size:10px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.04em;font-weight:600}.kv[_ngcontent-%COMP%] .kv-val[_ngcontent-%COMP%]{font-size:12.5px;font-weight:600;margin-top:2px;color:var(--text-primary);font-variant-numeric:tabular-nums}.kv-val.cost[_ngcontent-%COMP%]{color:var(--accent)}.tools[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:3px}.tool-block[_ngcontent-%COMP%]{display:flex;flex-direction:column}.tool-row[_ngcontent-%COMP%]{appearance:none;background:var(--bg-panel);border:1px solid var(--border-subtle);color:inherit;font-family:inherit;text-align:left;display:flex;align-items:center;gap:8px;width:100%;padding:5px 10px;border-radius:6px;font-size:11.5px;cursor:pointer}.tool-row[_ngcontent-%COMP%]:hover:not(:disabled){background:var(--bg-hover)}.tool-row[_ngcontent-%COMP%]:disabled{cursor:default}.tool-row[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.tool-row.expanded[_ngcontent-%COMP%]{border-bottom-left-radius:0;border-bottom-right-radius:0}.tool-chevron[_ngcontent-%COMP%]{width:10px;color:var(--text-muted);transition:transform .12s;font-size:12px;flex-shrink:0;display:inline-block}.tool-chevron.open[_ngcontent-%COMP%]{transform:rotate(90deg);color:var(--accent)}.tool-name[_ngcontent-%COMP%]{font-weight:600;flex-shrink:0}.tool-input[_ngcontent-%COMP%]{color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:11px}.tool-bytes[_ngcontent-%COMP%]{font-size:10.5px;flex-shrink:0}.tool-input-json[_ngcontent-%COMP%]{margin:0;padding:10px 14px;background:var(--bg-canvas);border:1px solid var(--border-subtle);border-top:0;border-radius:0 0 6px 6px;font-family:var(--font-mono);font-size:11px;line-height:1.5;color:var(--text-primary);white-space:pre-wrap;word-break:break-word;max-height:320px;overflow-y:auto}.assistant-body[_ngcontent-%COMP%]{padding:10px 14px;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:7px;font-size:12.5px;line-height:1.55;color:var(--text-primary);max-height:480px;overflow-y:auto;overflow-wrap:anywhere}.thinking-details[_ngcontent-%COMP%]{background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:7px;padding:8px 12px}.thinking-summary[_ngcontent-%COMP%]{cursor:pointer;list-style:none;display:flex;align-items:center;gap:6px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted)}.thinking-summary[_ngcontent-%COMP%]::-webkit-details-marker{display:none}.thinking-summary[_ngcontent-%COMP%]:before{content:"\\203a";display:inline-block;transition:transform .12s;font-size:14px;color:var(--text-muted)}.thinking-details[open][_ngcontent-%COMP%] .thinking-summary[_ngcontent-%COMP%]:before{transform:rotate(90deg);color:var(--accent)}.thinking-body[_ngcontent-%COMP%]{margin-top:10px;padding:8px 0 0;border-top:1px dashed var(--border-subtle);font-size:12px;line-height:1.55;color:var(--text-secondary);max-height:320px;overflow-y:auto;overflow-wrap:anywhere}.files-touched[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:3px;font-size:11.5px;max-height:180px;overflow-y:auto;padding:6px 10px;background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:6px}.files-touched[_ngcontent-%COMP%] .file-row[_ngcontent-%COMP%]{display:flex;align-items:center;min-width:0}.files-touched[_ngcontent-%COMP%] .file-path[_ngcontent-%COMP%]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-secondary)}.loading[_ngcontent-%COMP%]{padding:40px 18px;text-align:center;color:var(--text-muted);font-size:13px}.error[_ngcontent-%COMP%]{padding:16px;margin:12px 0;border-radius:8px;border:1px solid rgba(255,90,90,.35);background:var(--error-soft);color:var(--error);display:flex;flex-direction:column;gap:8px;align-items:flex-start}.error-title[_ngcontent-%COMP%]{font-weight:600;font-size:13px}.error-detail[_ngcontent-%COMP%]{font-size:12px;color:var(--text-secondary)}.empty[_ngcontent-%COMP%]{padding:30px 18px;color:var(--text-muted);font-size:12.5px;text-align:center}.md-content[_ngcontent-%COMP%] .md-h1[_ngcontent-%COMP%]{font-size:14px;font-weight:650;color:var(--text-primary);letter-spacing:-.01em;margin:0 0 8px}.md-content[_ngcontent-%COMP%] .md-h2[_ngcontent-%COMP%]{font-size:12.5px;font-weight:650;color:var(--text-primary);margin:14px 0 4px;padding-bottom:3px;border-bottom:1px solid var(--border-subtle)}.md-content[_ngcontent-%COMP%] .md-h3[_ngcontent-%COMP%]{font-size:12px;font-weight:650;color:var(--text-primary);margin:12px 0 4px}.md-content[_ngcontent-%COMP%] .md-p[_ngcontent-%COMP%]{font-size:12.5px;line-height:1.6;color:var(--text-primary);margin:0 0 4px;overflow-wrap:anywhere}.md-content[_ngcontent-%COMP%] .md-p[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{color:var(--text-primary);font-weight:650}.md-content[_ngcontent-%COMP%] .md-list[_ngcontent-%COMP%], .md-content[_ngcontent-%COMP%] .md-ol[_ngcontent-%COMP%]{padding:0;margin:4px 0 6px}.md-content[_ngcontent-%COMP%] .md-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%], .md-content[_ngcontent-%COMP%] .md-ol[_ngcontent-%COMP%] li[_ngcontent-%COMP%]{position:relative;padding:2px 0 2px 20px;font-size:12.5px;line-height:1.55;color:var(--text-primary);overflow-wrap:anywhere}.md-content[_ngcontent-%COMP%] .md-list[_ngcontent-%COMP%]{list-style:none}.md-content[_ngcontent-%COMP%] .md-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%]:before{content:"\\2022";position:absolute;left:4px;top:1px;color:var(--text-faint)}.md-content[_ngcontent-%COMP%] .md-spacer[_ngcontent-%COMP%]{height:5px}.md-content[_ngcontent-%COMP%] .md-inline-code[_ngcontent-%COMP%]{font-size:11px;background:var(--bg-canvas);padding:1px 5px;border-radius:3px;border:1px solid var(--border-subtle);color:var(--node-spec)}.md-content[_ngcontent-%COMP%] .md-blockquote[_ngcontent-%COMP%]{margin:5px 0;padding:6px 10px;border-left:3px solid var(--accent);background:var(--accent-soft);color:var(--text-secondary);font-size:12px;line-height:1.5;border-radius:0 5px 5px 0}.md-content[_ngcontent-%COMP%] .md-pre[_ngcontent-%COMP%]{position:relative;margin:6px 0 8px;padding:10px 12px;background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:6px;overflow-x:auto}.md-content[_ngcontent-%COMP%] .md-pre[_ngcontent-%COMP%] code[_ngcontent-%COMP%]{display:block;font-size:11px;line-height:1.5;color:var(--text-primary);white-space:pre}.md-content[_ngcontent-%COMP%] > [_ngcontent-%COMP%]:first-child{margin-top:0}'],changeDetection:0})};export{ce as SessionDetail};