@haposoft/cafekit 0.16.7 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -22
- package/bin/__tests__/codex-hooks-ownership.test.js +2 -2
- package/bin/__tests__/codex-hooks.test.js +169 -272
- package/bin/__tests__/codex-native.test.js +100 -202
- package/bin/__tests__/develop-contract.test.js +122 -1413
- package/bin/__tests__/docs-sync-on-demand.test.js +93 -0
- package/bin/__tests__/grok-envelope.test.js +0 -56
- package/bin/__tests__/hook-payload.test.js +4 -6
- package/bin/__tests__/legacy-authority-decoupled.test.js +154 -0
- package/bin/__tests__/legacy-hooks-retired.test.js +221 -0
- package/bin/__tests__/omp-bridge.test.js +20 -17
- package/bin/__tests__/omp-hooks.test.js +0 -19
- package/bin/__tests__/optional-skill-inventory.test.js +112 -4
- package/bin/__tests__/orca-session.test.js +0 -2
- package/bin/__tests__/package-inventory.test.js +90 -925
- package/bin/__tests__/runtime-dir.test.js +0 -3
- package/bin/__tests__/runtime-schema.test.js +3 -2
- package/bin/__tests__/skill-routing-source.test.js +27 -15
- package/bin/__tests__/spec-narrowing.test.js +30 -161
- package/bin/__tests__/specs-v2-execution-closeout.test.js +0 -437
- package/bin/__tests__/test-runtime-dependency-closure.cjs +1 -2
- package/bin/__tests__/ui-ux-skill.test.js +101 -0
- package/bin/__tests__/usage-hook-retired.test.js +114 -0
- package/bin/__tests__/validator-grounding.test.js +18 -2949
- package/bin/lib/managed-writer.js +2 -3
- package/bin/phases/codex-runtime.js +27 -0
- package/bin/phases/copy-payload.js +13 -28
- package/bin/phases/omp-runtime.js +25 -0
- package/package.json +2 -3
- package/src/claude/CLAUDE.md +3 -10
- package/src/claude/agents/brainstormer.md +7 -3
- package/src/claude/agents/code-auditor.md +44 -56
- package/src/claude/agents/debugger.md +8 -88
- package/src/claude/agents/deployer.md +3 -5
- package/src/claude/agents/docs-keeper.md +6 -14
- package/src/claude/agents/git-ops.md +2 -4
- package/src/claude/agents/implementer.md +12 -16
- package/src/claude/agents/inspector.md +4 -3
- package/src/claude/agents/project-manager.md +9 -17
- package/src/claude/agents/researcher.md +9 -3
- package/src/claude/agents/spec-maker.md +15 -15
- package/src/claude/agents/test-runner.md +8 -11
- package/src/claude/agents/ui-ux-designer.md +0 -1
- package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -1
- package/src/claude/hooks/__tests__/spec-gate.test.js +244 -333
- package/src/claude/hooks/__tests__/spec-state-touched.test.js +160 -0
- package/src/claude/hooks/__tests__/state.test.js +68 -0
- package/src/claude/hooks/__tests__/statusline.test.js +140 -11
- package/src/claude/hooks/agent.cjs +2 -1
- package/src/claude/hooks/lib/hook-payload.cjs +2 -2
- package/src/claude/hooks/rules.cjs +2 -1
- package/src/claude/hooks/session.cjs +0 -1
- package/src/claude/hooks/spec-gate.cjs +17 -83
- package/src/claude/hooks/spec-state.cjs +142 -39
- package/src/claude/hooks/state.cjs +21 -2
- package/src/claude/migration-manifest.json +42 -22
- package/src/claude/output-styles/coding-level-0-eli5.md +9 -9
- package/src/claude/output-styles/coding-level-1-junior.md +3 -3
- package/src/claude/output-styles/coding-level-2-mid.md +3 -3
- package/src/claude/output-styles/coding-level-3-senior.md +2 -2
- package/src/claude/output-styles/coding-level-4-lead.md +5 -5
- package/src/claude/output-styles/coding-level-5-god.md +6 -6
- package/src/claude/rules/ai-dev-rules.md +2 -3
- package/src/claude/rules/hook-protocols.md +8 -15
- package/src/claude/rules/manage-docs.md +9 -23
- package/src/claude/rules/orchestrator.md +3 -4
- package/src/claude/rules/review-audit-self-decision.md +3 -3
- package/src/claude/rules/skill-domain-routing.md +1 -3
- package/src/claude/rules/skill-workflow-routing.md +4 -5
- package/src/claude/rules/state-sync.md +3 -12
- package/src/claude/rules/workflow.md +11 -19
- package/src/claude/runtime.schema.json +5 -3
- package/src/claude/scripts/generate-skill-catalog.cjs +7 -6
- package/src/claude/scripts/provenance.cjs +23 -5
- package/src/claude/scripts/spec-receipt.cjs +24 -121
- package/src/claude/scripts/spec-resolver.cjs +41 -458
- package/src/claude/scripts/workflow-policy.cjs +3 -1801
- package/src/claude/settings/settings.json +1 -32
- package/src/claude/skills/agent-browser/SKILL.md +1 -1
- package/src/claude/skills/{question → ask}/SKILL.md +9 -75
- package/src/claude/skills/brainstorm/SKILL.md +43 -131
- package/src/claude/skills/chrome-devtools/SKILL.md +14 -31
- package/src/claude/skills/code-review/SKILL.md +29 -81
- package/src/claude/skills/code-review/references/spec-compliance-review.md +4 -8
- package/src/claude/skills/debug/SKILL.md +29 -149
- package/src/claude/skills/develop/SKILL.md +26 -83
- package/src/claude/skills/develop/references/parallel-waves.md +0 -8
- package/src/claude/skills/develop/references/quality-gate.md +15 -13
- package/src/claude/skills/develop/references/subagent-patterns.md +0 -6
- package/src/claude/skills/docs/SKILL.md +2 -2
- package/src/claude/skills/docs/references/update-workflow.md +1 -1
- package/src/claude/skills/fix/SKILL.md +153 -0
- package/src/claude/skills/{hotfix → fix}/references/diagnosis-protocol.md +2 -2
- package/src/claude/skills/{hotfix → fix}/references/parallel-patterns.md +2 -2
- package/src/claude/skills/{hotfix → fix}/references/prevention-gate.md +3 -3
- package/src/claude/skills/{hotfix → fix}/references/review-cycle.md +1 -1
- package/src/claude/skills/git/SKILL.md +48 -9
- package/src/claude/skills/git/references/commit-protocols.md +35 -16
- package/src/claude/skills/git/references/worktree-blueprint.md +42 -6
- package/src/claude/skills/orca/SKILL.md +9 -8
- package/src/claude/skills/research/SKILL.md +17 -46
- package/src/claude/skills/scout/SKILL.md +61 -0
- package/src/claude/skills/{inspect → scout}/references/internal-inspection.md +26 -10
- package/src/claude/skills/specs/SKILL.md +22 -29
- package/src/claude/skills/specs/references/review.md +8 -6
- package/src/claude/skills/specs/references/templates.md +34 -41
- package/src/claude/skills/sync/SKILL.md +16 -45
- package/src/claude/skills/sync/references/rebind-and-audit.md +59 -0
- package/src/claude/skills/sync/references/sync-protocols.md +4 -13
- package/src/claude/skills/test/SKILL.md +39 -104
- package/src/claude/skills/test/references/execution-strategy.md +93 -21
- package/src/claude/skills/test/references/failure-triage.md +1 -1
- package/src/claude/skills/ui-ux/LICENSE +21 -0
- package/src/claude/skills/ui-ux/SKILL.md +497 -0
- package/src/claude/skills/ui-ux/references/brand-tokens.md +90 -0
- package/src/claude/skills/ui-ux/references/budgets.md +113 -0
- package/src/claude/skills/ui-ux/references/checklist.md +271 -0
- package/src/claude/skills/ui-ux/references/components/accordion.md +246 -0
- package/src/claude/skills/ui-ux/references/components/avatar.md +153 -0
- package/src/claude/skills/ui-ux/references/components/banner.md +43 -0
- package/src/claude/skills/ui-ux/references/components/breadcrumb.md +201 -0
- package/src/claude/skills/ui-ux/references/components/button.md +142 -0
- package/src/claude/skills/ui-ux/references/components/card.md +113 -0
- package/src/claude/skills/ui-ux/references/components/charts.md +376 -0
- package/src/claude/skills/ui-ux/references/components/chat.md +132 -0
- package/src/claude/skills/ui-ux/references/components/choice-controls.md +369 -0
- package/src/claude/skills/ui-ux/references/components/comment-thread.md +17 -0
- package/src/claude/skills/ui-ux/references/components/description-list.md +116 -0
- package/src/claude/skills/ui-ux/references/components/empty-state.md +98 -0
- package/src/claude/skills/ui-ux/references/components/file-upload.md +107 -0
- package/src/claude/skills/ui-ux/references/components/inline-edit.md +128 -0
- package/src/claude/skills/ui-ux/references/components/input.md +161 -0
- package/src/claude/skills/ui-ux/references/components/list-row.md +56 -0
- package/src/claude/skills/ui-ux/references/components/loading.md +198 -0
- package/src/claude/skills/ui-ux/references/components/logo.md +147 -0
- package/src/claude/skills/ui-ux/references/components/otp-input.md +43 -0
- package/src/claude/skills/ui-ux/references/components/quantity-input.md +100 -0
- package/src/claude/skills/ui-ux/references/components/range-slider.md +16 -0
- package/src/claude/skills/ui-ux/references/components/small-controls.md +340 -0
- package/src/claude/skills/ui-ux/references/components/sortable-header.md +86 -0
- package/src/claude/skills/ui-ux/references/components/tag-input.md +14 -0
- package/src/claude/skills/ui-ux/references/components/timeline.md +38 -0
- package/src/claude/skills/ui-ux/references/components/tree.md +30 -0
- package/src/claude/skills/ui-ux/references/design-process.md +650 -0
- package/src/claude/skills/ui-ux/references/layouts/app-kanban.html +303 -0
- package/src/claude/skills/ui-ux/references/layouts/app.md +1369 -0
- package/src/claude/skills/ui-ux/references/layouts/form.md +430 -0
- package/src/claude/skills/ui-ux/references/layouts/overlay.md +552 -0
- package/src/claude/skills/ui-ux/references/layouts/pricing.md +204 -0
- package/src/claude/skills/ui-ux/references/locked-rules.md +35 -0
- package/src/claude/skills/ui-ux/references/principles.md +408 -0
- package/src/claude/skills/ui-ux/references/refactor.md +245 -0
- package/src/claude/skills/ui-ux/references/responsive.md +195 -0
- package/src/claude/skills/ui-ux/references/review.md +528 -0
- package/src/claude/skills/ui-ux/references/rules-color.md +623 -0
- package/src/claude/skills/ui-ux/references/rules-form.md +235 -0
- package/src/claude/skills/ui-ux/references/rules-state.md +680 -0
- package/src/claude/skills/ui-ux/references/rules-type.md +369 -0
- package/src/claude/skills/ui-ux/references/styles.md +311 -0
- package/src/claude/skills/ui-ux/references/system.md +219 -0
- package/src/claude/skills/ui-ux/references/tailwind-v4-traps.md +237 -0
- package/src/claude/skills/ui-ux/references/tokens.css +362 -0
- package/src/claude/skills/ui-ux/scripts/lint-skill.mjs +216 -0
- package/src/claude/skills/ui-ux/scripts/package.json +9 -0
- package/src/claude/skills/ui-ux/scripts/probe.mjs +4447 -0
- package/src/claude/skills/ui-ux-pro-max/SKILL.md +25 -80
- package/src/claude/skills/web-testing/SKILL.md +2 -20
- package/src/claude/status.cjs +149 -144
- package/src/codex/AGENTS.md +8 -13
- package/src/codex/hooks/agent.cjs +2 -1
- package/src/codex/hooks/lib/spec-receipt.cjs +4 -32
- package/src/codex/hooks/lib/spec-utils.cjs +6 -52
- package/src/codex/hooks/rules.cjs +2 -1
- package/src/codex/hooks/session.cjs +0 -2
- package/src/codex/hooks/spec-gate.cjs +13 -81
- package/src/codex/hooks/spec-state.cjs +37 -41
- package/src/codex/hooks.json +0 -20
- package/src/codex/rules/state-sync.md +3 -12
- package/src/common/AGENTS.md +6 -12
- package/src/omp/extensions/cafekit-bridge.mjs +6 -6
- package/bin/__tests__/change-firewall.semantic-firewall.test.js +0 -2133
- package/bin/__tests__/finalizer-pass-gate.semantic-firewall.test.js +0 -342
- package/bin/__tests__/release-preflight.semantic-firewall.test.js +0 -586
- package/bin/__tests__/review-receipt-c2.semantic-firewall.test.js +0 -378
- package/bin/__tests__/specs-v2-policy-and-scaffold.test.js +0 -665
- package/bin/__tests__/specs-v2-validator-grounder-contract.test.js +0 -1132
- package/src/claude/hooks/__tests__/completion-authority.test.js +0 -990
- package/src/claude/hooks/__tests__/semantic-review-authority.test.js +0 -259
- package/src/claude/hooks/completion-authority-check.cjs +0 -56
- package/src/claude/hooks/completion-authority-state.cjs +0 -527
- package/src/claude/hooks/completion-authority.cjs +0 -163
- package/src/claude/hooks/lib/context.cjs +0 -616
- package/src/claude/hooks/lib/detect.cjs +0 -474
- package/src/claude/hooks/semantic-review-authority.cjs +0 -154
- package/src/claude/hooks/task-scaffold-guard.cjs +0 -114
- package/src/claude/hooks/usage.cjs +0 -197
- package/src/claude/scripts/change-firewall.cjs +0 -1748
- package/src/claude/scripts/spec-authoring-digest.cjs +0 -151
- package/src/claude/scripts/spec-authoring-validation.cjs +0 -126
- package/src/claude/scripts/spec-final-state.cjs +0 -290
- package/src/claude/scripts/spec-ground.cjs +0 -650
- package/src/claude/scripts/spec-readiness.cjs +0 -425
- package/src/claude/scripts/spec-scaffold.cjs +0 -2317
- package/src/claude/scripts/spec-semantic-model.cjs +0 -396
- package/src/claude/scripts/validate-spec-output.cjs +0 -3941
- package/src/claude/skills/code-review/references/verification-gate.md +0 -46
- package/src/claude/skills/delegate/SKILL.md +0 -124
- package/src/claude/skills/delegate/references/codex-delegation.md +0 -71
- package/src/claude/skills/delegate/references/grok-delegation.md +0 -84
- package/src/claude/skills/hotfix/SKILL.md +0 -289
- package/src/claude/skills/inspect/SKILL.md +0 -142
- package/src/claude/skills/loop/SKILL.md +0 -114
- package/src/claude/skills/loop/references/bounded-loop-protocol.md +0 -104
- package/src/claude/skills/loop/references/metric-and-guard-contract.md +0 -76
- package/src/claude/skills/route/SKILL.md +0 -94
- package/src/claude/skills/route/references/agent-timing.md +0 -46
- package/src/claude/skills/route/references/chaining-patterns.md +0 -53
- package/src/claude/skills/route/references/task-taxonomy.md +0 -48
- package/src/claude/skills/specs/templates/design.md +0 -82
- package/src/claude/skills/specs/templates/requirements-init.md +0 -8
- package/src/claude/skills/specs/templates/requirements.md +0 -42
- package/src/claude/skills/specs/templates/spec-state.json +0 -56
- package/src/claude/skills/specs/templates/task.md +0 -47
- package/src/codex/hooks/completion-authority-check.cjs +0 -67
- package/src/codex/hooks/completion-authority-state.cjs +0 -527
- package/src/codex/hooks/completion-authority.cjs +0 -109
- package/src/codex/hooks/semantic-review-authority.cjs +0 -130
- package/src/codex/hooks/task-scaffold-guard.cjs +0 -63
- /package/src/claude/skills/{question → ask}/templates/question.md +0 -0
- /package/src/claude/skills/{hotfix → fix}/references/escalation-tactics.md +0 -0
- /package/src/claude/skills/{hotfix → fix}/references/workflow-specialized.md +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cf:ui-ux-pro-max
|
|
3
|
-
description: "UI/UX
|
|
3
|
+
description: "Searchable UI/UX lookup database for web and mobile products: 50+ visual styles, 161 color palettes, 57 font pairings, 161 product types with reasoning rules, 99 UX guidelines, 25 chart types, Google Fonts, and React Native stack guidance. Use to pick or justify a palette, font pairing, visual style, chart type, or UX guideline for a product type. It does not build, review, or redesign screens; that is cf:ui-ux, which can consult this skill for lookups."
|
|
4
4
|
user-invocable: true
|
|
5
|
-
when_to_use: "Invoke to
|
|
5
|
+
when_to_use: "Invoke to look up color palettes, font pairings, product-type styles, or UX guidelines; to build or review a screen use cf:ui-ux."
|
|
6
6
|
category: frontend
|
|
7
7
|
keywords: [ui, ux, design-system, layout]
|
|
8
8
|
metadata:
|
|
@@ -11,45 +11,13 @@ metadata:
|
|
|
11
11
|
---
|
|
12
12
|
# UI/UX Pro Max - Design Intelligence
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Searchable design database for web and mobile products: 50+ styles, 161 color palettes, 57 font pairings, 161 product types with reasoning rules, 99 UX guidelines, 25 chart types, and stack guidance for React Native only.
|
|
15
15
|
|
|
16
16
|
## When to Apply
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Use this skill to look something up: a palette, font pairing, or visual style for a product type, a chart type, or the UX guideline that applies to a pattern.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
This Skill must be invoked in the following situations:
|
|
23
|
-
|
|
24
|
-
- Designing new pages (Landing Page, Dashboard, Admin, SaaS, Mobile App)
|
|
25
|
-
- Creating or refactoring UI components (buttons, modals, forms, tables, charts, etc.)
|
|
26
|
-
- Choosing color schemes, typography systems, spacing standards, or layout systems
|
|
27
|
-
- Reviewing UI code for user experience, accessibility, or visual consistency
|
|
28
|
-
- Implementing navigation structures, animations, or responsive behavior
|
|
29
|
-
- Making product-level design decisions (style, information hierarchy, brand expression)
|
|
30
|
-
- Improving perceived quality, clarity, or usability of interfaces
|
|
31
|
-
|
|
32
|
-
### Recommended
|
|
33
|
-
|
|
34
|
-
This Skill is recommended in the following situations:
|
|
35
|
-
|
|
36
|
-
- UI looks "not professional enough" but the reason is unclear
|
|
37
|
-
- Receiving feedback on usability or experience
|
|
38
|
-
- Pre-launch UI quality optimization
|
|
39
|
-
- Aligning cross-platform design (Web / iOS / Android)
|
|
40
|
-
- Building design systems or reusable component libraries
|
|
41
|
-
|
|
42
|
-
### Skip
|
|
43
|
-
|
|
44
|
-
This Skill is not needed in the following situations:
|
|
45
|
-
|
|
46
|
-
- Pure backend logic development
|
|
47
|
-
- Only involving API or database design
|
|
48
|
-
- Performance optimization unrelated to the interface
|
|
49
|
-
- Infrastructure or DevOps work
|
|
50
|
-
- Non-visual scripts or automation tasks
|
|
51
|
-
|
|
52
|
-
**Decision criteria**: If the task will change how a feature **looks, feels, moves, or is interacted with**, this Skill should be used.
|
|
20
|
+
Building, reviewing, or redesigning a screen belongs to `cf:ui-ux`, which follows the project's own components and measures the page; it can call this skill when it needs a lookup. Backend, API, infrastructure, and non-visual work need neither skill.
|
|
53
21
|
|
|
54
22
|
## Rule Categories by Priority
|
|
55
23
|
|
|
@@ -313,28 +281,7 @@ Search specific domains using the CLI tool below.
|
|
|
313
281
|
|
|
314
282
|
## Prerequisites
|
|
315
283
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
```bash
|
|
319
|
-
python3 --version || python --version
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
If Python is not installed, install it based on user's OS:
|
|
323
|
-
|
|
324
|
-
**macOS:**
|
|
325
|
-
```bash
|
|
326
|
-
brew install python3
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
**Ubuntu/Debian:**
|
|
330
|
-
```bash
|
|
331
|
-
sudo apt update && sudo apt install python3
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
**Windows:**
|
|
335
|
-
```powershell
|
|
336
|
-
winget install Python.Python.3.12
|
|
337
|
-
```
|
|
284
|
+
Run `search.py` from the project root with `python3 .claude/skills/ui-ux-pro-max/scripts/search.py` (Windows: `python .claude\skills\ui-ux-pro-max\scripts\search.py`). It uses only the Python standard library, so no venv or extra install is needed.
|
|
338
285
|
|
|
339
286
|
---
|
|
340
287
|
|
|
@@ -362,14 +309,14 @@ Extract key information from user request:
|
|
|
362
309
|
- **Product type**: Entertainment (social, video, music, gaming), Tool (scanner, editor, converter), Productivity (task manager, notes, calendar), or hybrid
|
|
363
310
|
- **Target audience**: C-end consumer users; consider age group, usage context (commute, leisure, work)
|
|
364
311
|
- **Style keywords**: playful, vibrant, minimal, dark mode, content-first, immersive, etc.
|
|
365
|
-
- **Stack**:
|
|
312
|
+
- **Stack**: the target project's stack; `--stack` guidance exists only for `react-native`
|
|
366
313
|
|
|
367
|
-
### Step 2: Generate Design System
|
|
314
|
+
### Step 2: Generate Design System
|
|
368
315
|
|
|
369
|
-
|
|
316
|
+
Start with `--design-system` when choosing a whole direction (style, palette, type) for a new product or page; for a single lookup go straight to Step 3:
|
|
370
317
|
|
|
371
318
|
```bash
|
|
372
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "<product_type> <industry> <keywords>" --design-system [-p "Project Name"]
|
|
319
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<product_type> <industry> <keywords>" --design-system [-p "Project Name"]
|
|
373
320
|
```
|
|
374
321
|
|
|
375
322
|
This command:
|
|
@@ -380,7 +327,7 @@ This command:
|
|
|
380
327
|
|
|
381
328
|
**Example:**
|
|
382
329
|
```bash
|
|
383
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "beauty spa wellness service" --design-system -p "Serenity Spa"
|
|
330
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "beauty spa wellness service" --design-system -p "Serenity Spa"
|
|
384
331
|
```
|
|
385
332
|
|
|
386
333
|
### Step 2b: Persist Design System (Master + Overrides Pattern)
|
|
@@ -388,7 +335,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "beauty spa wellness service" --d
|
|
|
388
335
|
To save the design system for **hierarchical retrieval across sessions**, add `--persist`:
|
|
389
336
|
|
|
390
337
|
```bash
|
|
391
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "<query>" --design-system --persist -p "Project Name"
|
|
338
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<query>" --design-system --persist -p "Project Name"
|
|
392
339
|
```
|
|
393
340
|
|
|
394
341
|
This creates:
|
|
@@ -397,7 +344,7 @@ This creates:
|
|
|
397
344
|
|
|
398
345
|
**With page-specific override:**
|
|
399
346
|
```bash
|
|
400
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "<query>" --design-system --persist -p "Project Name" --page "dashboard"
|
|
347
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<query>" --design-system --persist -p "Project Name" --page "dashboard"
|
|
401
348
|
```
|
|
402
349
|
|
|
403
350
|
This also creates:
|
|
@@ -422,7 +369,7 @@ Now, generate the code...
|
|
|
422
369
|
After getting the design system, use domain searches to get additional details:
|
|
423
370
|
|
|
424
371
|
```bash
|
|
425
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "<keyword>" --domain <domain> [-n <max_results>]
|
|
372
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<keyword>" --domain <domain> [-n <max_results>]
|
|
426
373
|
```
|
|
427
374
|
|
|
428
375
|
**When to use detailed searches:**
|
|
@@ -440,14 +387,13 @@ python3 skills/ui-ux-pro-max/scripts/search.py "<keyword>" --domain <domain> [-n
|
|
|
440
387
|
| Landing structure | `landing` | `--domain landing "hero social-proof"` |
|
|
441
388
|
| React Native perf | `react` | `--domain react "rerender memo list"` |
|
|
442
389
|
| App interface a11y | `web` | `--domain web "accessibilityLabel touch safe-areas"` |
|
|
443
|
-
| AI prompt / CSS keywords | `prompt` | `--domain prompt "minimalism"` |
|
|
444
390
|
|
|
445
|
-
### Step 4: Stack Guidelines (React Native)
|
|
391
|
+
### Step 4: Stack Guidelines (React Native projects only)
|
|
446
392
|
|
|
447
|
-
|
|
393
|
+
For a React Native project, get implementation-specific best practices:
|
|
448
394
|
|
|
449
395
|
```bash
|
|
450
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "<keyword>" --stack react-native
|
|
396
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<keyword>" --stack react-native
|
|
451
397
|
```
|
|
452
398
|
|
|
453
399
|
---
|
|
@@ -468,7 +414,6 @@ python3 skills/ui-ux-pro-max/scripts/search.py "<keyword>" --stack react-native
|
|
|
468
414
|
| `google-fonts` | Individual Google Fonts lookup | sans serif, monospace, japanese, variable font, popular |
|
|
469
415
|
| `react` | React/Next.js performance | waterfall, bundle, suspense, memo, rerender, cache |
|
|
470
416
|
| `web` | App interface guidelines (iOS/Android/React Native) | accessibilityLabel, touch targets, safe areas, Dynamic Type |
|
|
471
|
-
| `prompt` | AI prompts, CSS keywords | (style name) |
|
|
472
417
|
|
|
473
418
|
### Available Stacks
|
|
474
419
|
|
|
@@ -488,10 +433,10 @@ python3 skills/ui-ux-pro-max/scripts/search.py "<keyword>" --stack react-native
|
|
|
488
433
|
- Style keywords: modern, minimal, content-first, dark mode
|
|
489
434
|
- Stack: React Native
|
|
490
435
|
|
|
491
|
-
### Step 2: Generate Design System
|
|
436
|
+
### Step 2: Generate Design System
|
|
492
437
|
|
|
493
438
|
```bash
|
|
494
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "AI search tool modern minimal" --design-system -p "AI Search"
|
|
439
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "AI search tool modern minimal" --design-system -p "AI Search"
|
|
495
440
|
```
|
|
496
441
|
|
|
497
442
|
**Output:** Complete design system with pattern, style, colors, typography, effects, and anti-patterns.
|
|
@@ -500,16 +445,16 @@ python3 skills/ui-ux-pro-max/scripts/search.py "AI search tool modern minimal" -
|
|
|
500
445
|
|
|
501
446
|
```bash
|
|
502
447
|
# Get style options for a modern tool product
|
|
503
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "minimalism dark mode" --domain style
|
|
448
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "minimalism dark mode" --domain style
|
|
504
449
|
|
|
505
450
|
# Get UX best practices for search interaction and loading
|
|
506
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "search loading animation" --domain ux
|
|
451
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "search loading animation" --domain ux
|
|
507
452
|
```
|
|
508
453
|
|
|
509
454
|
### Step 4: Stack Guidelines
|
|
510
455
|
|
|
511
456
|
```bash
|
|
512
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "list performance navigation" --stack react-native
|
|
457
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "list performance navigation" --stack react-native
|
|
513
458
|
```
|
|
514
459
|
|
|
515
460
|
**Then:** Synthesize design system + detailed searches and implement the design.
|
|
@@ -522,10 +467,10 @@ The `--design-system` flag supports two output formats:
|
|
|
522
467
|
|
|
523
468
|
```bash
|
|
524
469
|
# ASCII box (default) - best for terminal display
|
|
525
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system
|
|
470
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system
|
|
526
471
|
|
|
527
472
|
# Markdown - best for documentation
|
|
528
|
-
python3 skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system -f markdown
|
|
473
|
+
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system -f markdown
|
|
529
474
|
```
|
|
530
475
|
|
|
531
476
|
---
|
|
@@ -537,7 +482,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system
|
|
|
537
482
|
- Use **multi-dimensional keywords** — combine product + industry + tone + density: `"entertainment social vibrant content-dense"` not just `"app"`
|
|
538
483
|
- Try different keywords for the same need: `"playful neon"` → `"vibrant dark"` → `"content-first minimal"`
|
|
539
484
|
- Use `--design-system` first for full recommendations, then `--domain` to deep-dive any dimension you're unsure about
|
|
540
|
-
-
|
|
485
|
+
- Add `--stack react-native` only when the target project is React Native
|
|
541
486
|
|
|
542
487
|
### Common Sticking Points
|
|
543
488
|
|
|
@@ -26,15 +26,9 @@ npx @axe-core/cli https://example.com # Accessibility
|
|
|
26
26
|
npx lighthouse https://example.com # Performance
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
## Testing Strategy
|
|
29
|
+
## Testing Strategy
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|-------|-----------|----------|
|
|
33
|
-
| Pyramid | Unit 70% > Integration 20% > E2E 10% | Monoliths |
|
|
34
|
-
| Trophy | Integration-heavy | Modern SPAs |
|
|
35
|
-
| Honeycomb | Contract-centric | Microservices |
|
|
36
|
-
|
|
37
|
-
→ `./references/testing-pyramid-strategy.md`
|
|
31
|
+
Choosing between pyramid, trophy, and honeycomb: `./references/testing-pyramid-strategy.md`
|
|
38
32
|
|
|
39
33
|
## Reference Documentation
|
|
40
34
|
|
|
@@ -88,15 +82,3 @@ node ./scripts/analyze-test-results.js \
|
|
|
88
82
|
--output markdown
|
|
89
83
|
```
|
|
90
84
|
Parses Playwright/Vitest/JUnit results into unified summary.
|
|
91
|
-
|
|
92
|
-
## CI/CD Integration
|
|
93
|
-
|
|
94
|
-
```yaml
|
|
95
|
-
jobs:
|
|
96
|
-
test:
|
|
97
|
-
steps:
|
|
98
|
-
- run: npm run test:unit # Gate 1: Fast fail
|
|
99
|
-
- run: npm run test:e2e # Gate 2: After unit pass
|
|
100
|
-
- run: npm run test:a11y # Accessibility
|
|
101
|
-
- run: npx lhci autorun # Performance
|
|
102
|
-
```
|
package/src/claude/status.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Custom Claude Code statusline for Node.js -
|
|
5
|
+
* Custom Claude Code statusline for Node.js - one-line default
|
|
6
6
|
* Cross-platform support: Windows, macOS, Linux
|
|
7
7
|
* Features: ANSI colors, tool/agent/todo tracking, context window, session timer
|
|
8
8
|
* No external dependencies - uses only Node.js built-in modules
|
|
@@ -26,10 +26,6 @@ const { getGitInfo } = require('./hooks/lib/git.cjs');
|
|
|
26
26
|
// ratio so 1M-context models are not treated as if they were 200k.
|
|
27
27
|
const AUTOCOMPACT_BUFFER_RATIO = 0.225;
|
|
28
28
|
|
|
29
|
-
// Usage cache freshness gate: a cache older than this hides the quota area
|
|
30
|
-
// instead of rendering stale numbers.
|
|
31
|
-
const USAGE_CACHE_TTL_MS = 300000;
|
|
32
|
-
|
|
33
29
|
/**
|
|
34
30
|
* Expand home directory to ~
|
|
35
31
|
*/
|
|
@@ -104,7 +100,7 @@ async function readStdin() {
|
|
|
104
100
|
* @returns {string|null} Formatted usage string or null if unavailable
|
|
105
101
|
*/
|
|
106
102
|
function buildUsageString(ctx) {
|
|
107
|
-
if (!ctx.sessionText
|
|
103
|
+
if (!ctx.sessionText) return null;
|
|
108
104
|
let str = ctx.sessionText.replace(' until reset', ' left');
|
|
109
105
|
if (ctx.usagePercent != null) str += ` (${Math.round(ctx.usagePercent)}%)`;
|
|
110
106
|
return str;
|
|
@@ -130,77 +126,115 @@ function buildBranchPart(ctx) {
|
|
|
130
126
|
return branchPart;
|
|
131
127
|
}
|
|
132
128
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
129
|
+
// Default session line: one row of single-width symbols, each value labelled by
|
|
130
|
+
// its glyph so the line stays short and every number says what it measures.
|
|
131
|
+
// ◆ model (effort) ϟfast ✱thinking ◔ context% ⧗ 5h-quota% reset ◷ weekly% ⎇ branch ●changed ↑ahead ↓behind ± +added/-removed ⏱ session ↻ cache-hit%
|
|
132
|
+
|
|
133
|
+
/** Quarter-circle glyph that fills with the percentage. */
|
|
134
|
+
function fillGlyph(percent) {
|
|
135
|
+
if (percent >= 88) return '●';
|
|
136
|
+
if (percent >= 63) return '◕';
|
|
137
|
+
if (percent >= 38) return '◑';
|
|
138
|
+
if (percent >= 13) return '◔';
|
|
139
|
+
return '○';
|
|
140
|
+
}
|
|
137
141
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
/** Same thresholds as the context bar; plain text when colours are off. */
|
|
143
|
+
function tintPercent(percent, text) {
|
|
144
|
+
if (percent >= 85) return red(text);
|
|
145
|
+
if (percent >= 70) return yellow(text);
|
|
146
|
+
return green(text);
|
|
147
|
+
}
|
|
141
148
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const
|
|
149
|
+
/** "2h 48m until reset" → "2h48m"; anything else → null. */
|
|
150
|
+
function shortReset(sessionText) {
|
|
151
|
+
const match = /^(\d+)h (\d+)m/.exec(sessionText || '');
|
|
152
|
+
return match ? `${match[1]}h${match[2]}m` : null;
|
|
153
|
+
}
|
|
145
154
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
155
|
+
/** 28147114 → "7h49m"; under an hour → "12m". */
|
|
156
|
+
function formatDuration(ms) {
|
|
157
|
+
const minutes = Math.floor(ms / 60000);
|
|
158
|
+
const hours = Math.floor(minutes / 60);
|
|
159
|
+
return hours > 0 ? `${hours}h${String(minutes % 60).padStart(2, '0')}m` : `${minutes}m`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** "#80✓" approved, "#80✗" changes requested, "#80" pending, dim "#80" draft; "!80" for a GitLab MR. */
|
|
163
|
+
function formatPr(pr) {
|
|
164
|
+
const label = `${pr.kind === 'mr' ? '!' : '#'}${pr.number}`;
|
|
165
|
+
if (pr.review_state === 'approved') return `${label}${green('✓')}`;
|
|
166
|
+
if (pr.review_state === 'changes_requested') return `${label}${red('✗')}`;
|
|
167
|
+
if (pr.review_state === 'draft') return dim(label);
|
|
168
|
+
return label;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Parts of the default line in display order. `drop` ranks what goes first
|
|
173
|
+
* when the terminal is too narrow (higher drops earlier); 0 never drops.
|
|
174
|
+
*/
|
|
175
|
+
function buildLineParts(ctx, { minimal = false } = {}) {
|
|
176
|
+
let model = `◆ ${ctx.modelName}`;
|
|
177
|
+
if (ctx.effortLevel) model += ` ${dim(`(${ctx.effortLevel})`)}`;
|
|
178
|
+
const flags = `${ctx.fastMode ? 'ϟ' : ''}${ctx.thinking ? '✱' : ''}`;
|
|
179
|
+
if (flags) model += ` ${flags}`;
|
|
180
|
+
const parts = [{ text: model, drop: 0 }];
|
|
149
181
|
|
|
150
|
-
// Build session part: 🤖 model contextBar% ⌛ time left (usage%)
|
|
151
|
-
let sessionPart = `🤖 ${ctx.modelName}`;
|
|
152
182
|
if (ctx.contextPercent > 0) {
|
|
153
|
-
|
|
183
|
+
parts.push({ text: tintPercent(ctx.contextPercent, `${fillGlyph(ctx.contextPercent)} ${ctx.contextPercent}%`), drop: 0 });
|
|
154
184
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
185
|
+
|
|
186
|
+
if (!minimal && ctx.usagePercent != null) {
|
|
187
|
+
const pct = Math.round(ctx.usagePercent);
|
|
188
|
+
const reset = shortReset(ctx.sessionText);
|
|
189
|
+
parts.push({ text: `⧗ ${tintPercent(pct, `${pct}%`)}${reset ? ` ${dim(reset)}` : ''}`, drop: 2 });
|
|
160
190
|
}
|
|
161
191
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// if (ctx.costText) statsItems.push(`💵 ${ctx.costText.replace(/(\.\d{2})\d+/, '$1')}`);
|
|
165
|
-
if (ctx.linesAdded > 0 || ctx.linesRemoved > 0) {
|
|
166
|
-
statsItems.push(`📝 ${green(`+${ctx.linesAdded}`)} ${red(`-${ctx.linesRemoved}`)}`);
|
|
192
|
+
if (!minimal && ctx.weeklyPercent != null) {
|
|
193
|
+
parts.push({ text: `◷ ${tintPercent(ctx.weeklyPercent, `${ctx.weeklyPercent}%`)}`, drop: 3 });
|
|
167
194
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const sessionStats = `${sessionPart} ${statsPart}`;
|
|
181
|
-
|
|
182
|
-
if (visibleLength(allOneLine) <= threshold && statsLen > 0) {
|
|
183
|
-
// Ultra-wide: everything on one line (session first)
|
|
184
|
-
lines.push(allOneLine);
|
|
185
|
-
} else if (visibleLength(sessionLocation) <= threshold) {
|
|
186
|
-
// Wide: session+location on line 1 | stats on line 2
|
|
187
|
-
lines.push(sessionLocation);
|
|
188
|
-
if (statsLen > 0) lines.push(statsPart);
|
|
189
|
-
} else if (sessionLen <= threshold) {
|
|
190
|
-
// Medium: session on line 1 | location on line 2 | stats on line 3
|
|
191
|
-
lines.push(sessionPart);
|
|
192
|
-
lines.push(locationPart);
|
|
193
|
-
if (statsLen > 0) lines.push(statsPart);
|
|
194
|
-
} else {
|
|
195
|
-
// Narrow: session | dir | branch | stats (each on own line)
|
|
196
|
-
lines.push(sessionPart);
|
|
197
|
-
lines.push(dirPart);
|
|
198
|
-
if (branchPart) lines.push(branchPart);
|
|
199
|
-
if (planPart) lines.push(planPart);
|
|
200
|
-
if (statsLen > 0) lines.push(statsPart);
|
|
195
|
+
|
|
196
|
+
if (ctx.gitBranch) {
|
|
197
|
+
let git = `⎇ ${ctx.gitBranch}`;
|
|
198
|
+
if (!minimal) {
|
|
199
|
+
const changed = ctx.gitUnstaged + ctx.gitStaged;
|
|
200
|
+
if (changed > 0) git += ` ${yellow(`●${changed}`)}`;
|
|
201
|
+
if (ctx.gitAhead > 0) git += ` ↑${ctx.gitAhead}`;
|
|
202
|
+
if (ctx.gitBehind > 0) git += ` ↓${ctx.gitBehind}`;
|
|
203
|
+
if (ctx.pr) git += ` ${formatPr(ctx.pr)}`;
|
|
204
|
+
if (ctx.inWorktree) git += ' ⊟';
|
|
205
|
+
}
|
|
206
|
+
parts.push({ text: git, drop: 1 });
|
|
201
207
|
}
|
|
202
208
|
|
|
203
|
-
|
|
209
|
+
if (!minimal && (ctx.linesAdded > 0 || ctx.linesRemoved > 0)) {
|
|
210
|
+
parts.push({ text: `± ${green(`+${ctx.linesAdded}`)}/${red(`-${ctx.linesRemoved}`)}`, drop: 4 });
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (!minimal && ctx.durationMs >= 60000) {
|
|
214
|
+
parts.push({ text: `⏱ ${formatDuration(ctx.durationMs)}`, drop: 5 });
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (!minimal && ctx.cacheHitRatio != null) {
|
|
218
|
+
const pct = Math.round(ctx.cacheHitRatio * 100);
|
|
219
|
+
const tinted = pct < 50 ? red(`${pct}%`) : pct < 80 ? yellow(`${pct}%`) : green(`${pct}%`);
|
|
220
|
+
parts.push({ text: `↻ ${tinted}`, drop: 6 });
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return parts;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** Join parts, dropping the highest-ranked ones until the line fits the terminal. */
|
|
227
|
+
function fitLine(parts) {
|
|
228
|
+
const width = getTerminalWidth() - 2;
|
|
229
|
+
const kept = [...parts];
|
|
230
|
+
const join = () => kept.map((part) => part.text).join(' ');
|
|
231
|
+
while (visibleLength(join()) > width) {
|
|
232
|
+
const candidates = kept.filter((part) => part.drop > 0);
|
|
233
|
+
if (candidates.length === 0) break;
|
|
234
|
+
const victim = candidates.reduce((a, b) => (b.drop > a.drop ? b : a));
|
|
235
|
+
kept.splice(kept.indexOf(victim), 1);
|
|
236
|
+
}
|
|
237
|
+
return join();
|
|
204
238
|
}
|
|
205
239
|
|
|
206
240
|
/**
|
|
@@ -309,52 +343,21 @@ function renderTodosLine(transcript) {
|
|
|
309
343
|
return `${yellow('▸')} ${display} ${dim(`(${completedCount} done, ${pendingCount} pending)`)}`;
|
|
310
344
|
}
|
|
311
345
|
|
|
312
|
-
/**
|
|
313
|
-
* Render minimal mode - single line with emojis, no progress bar
|
|
314
|
-
* Format: "🤖 opus 4.5 🔋 50% ⏰ 2h 16m (38%) 🌿 branch 📁 ~/path"
|
|
315
|
-
*/
|
|
346
|
+
/** minimal mode: model, context and branch only. */
|
|
316
347
|
function renderMinimal(ctx) {
|
|
317
|
-
|
|
318
|
-
if (ctx.contextPercent > 0) {
|
|
319
|
-
const batteryIcon = ctx.contextPercent > 70 ? red('🔋') : '🔋';
|
|
320
|
-
parts.push(`${batteryIcon} ${ctx.contextPercent}%`);
|
|
321
|
-
}
|
|
322
|
-
const usageStr = buildUsageString(ctx);
|
|
323
|
-
if (usageStr) parts.push(`⏰ ${usageStr}${ctx.weeklyText ? ` ${ctx.weeklyText}` : ''}`);
|
|
324
|
-
if (ctx.gitBranch) parts.push(`🌿 ${ctx.gitBranch}`);
|
|
325
|
-
parts.push(`📁 ${ctx.currentDir}`);
|
|
326
|
-
console.log(parts.join(' '));
|
|
348
|
+
writeStyledLines([fitLine(buildLineParts(ctx, { minimal: true }))]);
|
|
327
349
|
}
|
|
328
350
|
|
|
329
|
-
/**
|
|
330
|
-
* Render compact mode - 2 lines: session info + location (branch + dir)
|
|
331
|
-
*/
|
|
351
|
+
/** compact mode: the default line without the agent and todo lines. */
|
|
332
352
|
function renderCompact(ctx) {
|
|
333
|
-
|
|
334
|
-
let line1 = `🤖 ${ctx.modelName}`;
|
|
335
|
-
if (ctx.contextPercent > 0) {
|
|
336
|
-
line1 += ` ${coloredBar(ctx.contextPercent, 12)} ${ctx.contextPercent}%`;
|
|
337
|
-
}
|
|
338
|
-
const usageStr = buildUsageString(ctx);
|
|
339
|
-
if (usageStr) line1 += ` ⌛ ${usageStr}${ctx.weeklyText ? ` ${ctx.weeklyText}` : ''}`;
|
|
340
|
-
console.log(line1.replace(/ /g, '\u00A0'));
|
|
341
|
-
|
|
342
|
-
// Line 2: Location (branch + directory)
|
|
343
|
-
let line2 = `📁 ${ctx.currentDir}`;
|
|
344
|
-
if (ctx.gitBranch) line2 += ` 🌿 ${ctx.gitBranch}`;
|
|
345
|
-
console.log(line2.replace(/ /g, '\u00A0'));
|
|
353
|
+
render(ctx, true);
|
|
346
354
|
}
|
|
347
355
|
|
|
348
356
|
/**
|
|
349
|
-
*
|
|
350
|
-
* Falls back to single line if multi-line fails
|
|
357
|
+
* full mode: the default line, then agent and todo lines only while they exist.
|
|
351
358
|
*/
|
|
352
359
|
function render(ctx, singleLineMode = false) {
|
|
353
|
-
const lines = [];
|
|
354
|
-
|
|
355
|
-
// Session lines (cleaner multi-line layout)
|
|
356
|
-
const sessionLines = renderSessionLines(ctx);
|
|
357
|
-
lines.push(...sessionLines);
|
|
360
|
+
const lines = [fitLine(buildLineParts(ctx))];
|
|
358
361
|
|
|
359
362
|
if (!singleLineMode) {
|
|
360
363
|
// Agents lines (one per agent for clarity)
|
|
@@ -463,6 +466,8 @@ async function main() {
|
|
|
463
466
|
currentDir = expandHome(currentDir);
|
|
464
467
|
|
|
465
468
|
const modelName = data.model?.display_name || 'Claude';
|
|
469
|
+
// Live /effort value; absent when the model has no effort parameter.
|
|
470
|
+
const effortLevel = typeof data.effort?.level === 'string' ? data.effort.level : '';
|
|
466
471
|
|
|
467
472
|
// Git detection using batched cache
|
|
468
473
|
const rawDir = data.workspace?.current_dir || data.cwd || process.cwd();
|
|
@@ -522,55 +527,39 @@ async function main() {
|
|
|
522
527
|
} catch {}
|
|
523
528
|
}
|
|
524
529
|
|
|
525
|
-
//
|
|
530
|
+
// Quota text, filled from the payload's rate_limits below
|
|
526
531
|
let sessionText = '';
|
|
527
532
|
let weeklyText = '';
|
|
533
|
+
let weeklyPercent = null;
|
|
528
534
|
const transcriptPath = data.transcript_path;
|
|
529
535
|
|
|
530
536
|
// Parse transcript for tools/agents/todos
|
|
531
537
|
const transcript = transcriptPath ? await parseTranscript(transcriptPath) : { tools: [], agents: [], todos: [], sessionStart: null };
|
|
532
538
|
|
|
533
|
-
//
|
|
539
|
+
// Quota windows come only from Claude Code's own rate_limits, sent for Pro/Max after
|
|
540
|
+
// the session's first API response; without it the quota segments stay hidden.
|
|
534
541
|
let usagePercent = null;
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
const fresh = typeof cache.timestamp === 'number'
|
|
542
|
-
&& Date.now() - cache.timestamp < USAGE_CACHE_TTL_MS;
|
|
543
|
-
if (cache.status === 'unavailable') {
|
|
544
|
-
sessionText = 'N/A';
|
|
545
|
-
} else if (cache.status === 'available' && fresh) {
|
|
546
|
-
const fiveHour = cache.data?.five_hour;
|
|
547
|
-
usagePercent = fiveHour?.utilization ?? null;
|
|
548
|
-
const resetAt = fiveHour?.resets_at;
|
|
549
|
-
if (resetAt) {
|
|
550
|
-
const resetTime = new Date(resetAt);
|
|
551
|
-
const remaining = Math.floor(resetTime.getTime() / 1000) - Math.floor(Date.now() / 1000);
|
|
552
|
-
if (remaining > 0 && remaining < 18000) {
|
|
553
|
-
const rh = Math.floor(remaining / 3600);
|
|
554
|
-
const rm = Math.floor((remaining % 3600) / 60);
|
|
555
|
-
sessionText = `${rh}h ${rm}m until reset`;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
const sevenDay = cache.data?.seven_day;
|
|
559
|
-
if (sevenDay?.utilization != null) {
|
|
560
|
-
weeklyText = `wk ${Math.round(sevenDay.utilization)}%`;
|
|
561
|
-
const wkResetAt = sevenDay.resets_at;
|
|
562
|
-
if (wkResetAt) {
|
|
563
|
-
const wkRemaining = Math.floor(new Date(wkResetAt).getTime() / 1000) - Math.floor(Date.now() / 1000);
|
|
564
|
-
if (wkRemaining > 0) {
|
|
565
|
-
const wd = Math.floor(wkRemaining / 86400);
|
|
566
|
-
const wh = Math.floor((wkRemaining % 86400) / 3600);
|
|
567
|
-
weeklyText += ` (${wd}d ${wh}h)`;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}
|
|
542
|
+
const applyWindows = (fiveHour, sevenDay) => {
|
|
543
|
+
if (fiveHour?.percent != null) {
|
|
544
|
+
usagePercent = fiveHour.percent;
|
|
545
|
+
const remaining = Math.floor(fiveHour.resetsAtMs / 1000) - Math.floor(Date.now() / 1000);
|
|
546
|
+
if (remaining > 0 && remaining < 18000) {
|
|
547
|
+
sessionText = `${Math.floor(remaining / 3600)}h ${Math.floor((remaining % 3600) / 60)}m until reset`;
|
|
571
548
|
}
|
|
572
549
|
}
|
|
573
|
-
|
|
550
|
+
if (sevenDay?.percent != null) {
|
|
551
|
+
weeklyPercent = Math.round(sevenDay.percent);
|
|
552
|
+
weeklyText = `wk ${weeklyPercent}%`;
|
|
553
|
+
const wkRemaining = Math.floor(sevenDay.resetsAtMs / 1000) - Math.floor(Date.now() / 1000);
|
|
554
|
+
if (wkRemaining > 0) {
|
|
555
|
+
weeklyText += ` (${Math.floor(wkRemaining / 86400)}d ${Math.floor((wkRemaining % 86400) / 3600)}h)`;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
const fromPayload = (window) => (window && typeof window.used_percentage === 'number'
|
|
560
|
+
? { percent: window.used_percentage, resetsAtMs: Number(window.resets_at) * 1000 }
|
|
561
|
+
: null);
|
|
562
|
+
applyWindows(fromPayload(data.rate_limits?.five_hour), fromPayload(data.rate_limits?.seven_day));
|
|
574
563
|
|
|
575
564
|
// Cost and lines changed
|
|
576
565
|
const billingMode = env.CLAUDE_BILLING_MODE || 'api';
|
|
@@ -580,6 +569,14 @@ async function main() {
|
|
|
580
569
|
: null;
|
|
581
570
|
const linesAdded = data.cost?.total_lines_added || 0;
|
|
582
571
|
const linesRemoved = data.cost?.total_lines_removed || 0;
|
|
572
|
+
const durationMs = Number(data.cost?.total_duration_ms) || 0;
|
|
573
|
+
const cacheHitRatio = data.prompt_cache?.requests > 0 && typeof data.prompt_cache.hit_ratio === 'number'
|
|
574
|
+
? data.prompt_cache.hit_ratio
|
|
575
|
+
: null;
|
|
576
|
+
const fastMode = data.fast_mode === true;
|
|
577
|
+
const thinking = data.thinking?.enabled === true;
|
|
578
|
+
const pr = typeof data.pr?.number === 'number' ? data.pr : null;
|
|
579
|
+
const inWorktree = Boolean(data.worktree?.name || data.workspace?.git_worktree);
|
|
583
580
|
|
|
584
581
|
// Config counts
|
|
585
582
|
const configs = countConfigs(rawDir);
|
|
@@ -587,6 +584,7 @@ async function main() {
|
|
|
587
584
|
// Build render context
|
|
588
585
|
const ctx = {
|
|
589
586
|
modelName,
|
|
587
|
+
effortLevel,
|
|
590
588
|
currentDir,
|
|
591
589
|
gitBranch,
|
|
592
590
|
gitUnstaged,
|
|
@@ -597,10 +595,17 @@ async function main() {
|
|
|
597
595
|
contextPercent,
|
|
598
596
|
sessionText,
|
|
599
597
|
weeklyText,
|
|
598
|
+
weeklyPercent,
|
|
600
599
|
usagePercent,
|
|
601
600
|
costText,
|
|
602
601
|
linesAdded,
|
|
603
602
|
linesRemoved,
|
|
603
|
+
durationMs,
|
|
604
|
+
cacheHitRatio,
|
|
605
|
+
fastMode,
|
|
606
|
+
thinking,
|
|
607
|
+
pr,
|
|
608
|
+
inWorktree,
|
|
604
609
|
configs,
|
|
605
610
|
transcript
|
|
606
611
|
};
|
|
@@ -636,11 +641,11 @@ async function main() {
|
|
|
636
641
|
|
|
637
642
|
} catch (err) {
|
|
638
643
|
// Fallback: output minimal single line on any error
|
|
639
|
-
console.log(
|
|
644
|
+
console.log(`◆ ${expandHome(process.cwd() || 'unknown')}`);
|
|
640
645
|
}
|
|
641
646
|
}
|
|
642
647
|
|
|
643
648
|
main().catch(() => {
|
|
644
|
-
console.log('
|
|
649
|
+
console.log('◆ statusline error');
|
|
645
650
|
process.exit(1);
|
|
646
651
|
});
|