@prestyj/cli 5.29.1 → 5.30.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 +11 -12
- package/assets/skills/bulletproof/SKILL.md +1 -1
- package/assets/skills/clarify/SKILL.md +1 -1
- package/assets/skills/code-review/SKILL.md +1 -1
- package/assets/skills/compliance-guard/SKILL.md +1 -1
- package/assets/skills/compliance-guard/references/us.md +1 -1
- package/assets/skills/durable/SKILL.md +1 -1
- package/assets/skills/evidence-led-ui/SKILL.md +1 -1
- package/assets/skills/lean/SKILL.md +1 -1
- package/assets/skills/refactoring/SKILL.md +3 -1
- package/assets/skills/root-cause/SKILL.md +1 -1
- package/assets/skills/shared-language/SKILL.md +1 -1
- package/assets/skills/tdd/SKILL.md +1 -1
- package/dist/app-error.d.ts +21 -0
- package/dist/app-error.js +39 -0
- package/dist/app-error.js.map +1 -0
- package/dist/app-sidecar/app-settings.d.ts +63 -0
- package/dist/app-sidecar/app-settings.js +147 -0
- package/dist/app-sidecar/app-settings.js.map +1 -0
- package/dist/app-sidecar/attachments.d.ts +11 -0
- package/dist/app-sidecar/attachments.js +47 -0
- package/dist/app-sidecar/attachments.js.map +1 -0
- package/dist/app-sidecar/auth-routes.d.ts +3 -0
- package/dist/app-sidecar/auth-routes.js +290 -0
- package/dist/app-sidecar/auth-routes.js.map +1 -0
- package/dist/app-sidecar/autopilot-runner.d.ts +62 -0
- package/dist/app-sidecar/autopilot-runner.js +376 -0
- package/dist/app-sidecar/autopilot-runner.js.map +1 -0
- package/dist/app-sidecar/file-search.d.ts +15 -0
- package/dist/app-sidecar/file-search.js +103 -0
- package/dist/app-sidecar/file-search.js.map +1 -0
- package/dist/app-sidecar/hf-pull-manager.d.ts +20 -0
- package/dist/app-sidecar/hf-pull-manager.js +224 -0
- package/dist/app-sidecar/hf-pull-manager.js.map +1 -0
- package/dist/app-sidecar/history-routes.d.ts +3 -0
- package/dist/app-sidecar/history-routes.js +375 -0
- package/dist/app-sidecar/history-routes.js.map +1 -0
- package/dist/app-sidecar/history.d.ts +67 -0
- package/dist/app-sidecar/history.js +23 -0
- package/dist/app-sidecar/history.js.map +1 -0
- package/dist/app-sidecar/http.d.ts +5 -0
- package/dist/app-sidecar/http.js +27 -0
- package/dist/app-sidecar/http.js.map +1 -0
- package/dist/app-sidecar/integration-routes.d.ts +3 -0
- package/dist/app-sidecar/integration-routes.js +286 -0
- package/dist/app-sidecar/integration-routes.js.map +1 -0
- package/dist/app-sidecar/json-mode.d.ts +10 -0
- package/dist/app-sidecar/json-mode.js +73 -0
- package/dist/app-sidecar/json-mode.js.map +1 -0
- package/dist/app-sidecar/keep-awake.d.ts +4 -0
- package/dist/app-sidecar/keep-awake.js +5 -0
- package/dist/app-sidecar/keep-awake.js.map +1 -0
- package/dist/app-sidecar/mcp-routes.d.ts +3 -0
- package/dist/app-sidecar/mcp-routes.js +185 -0
- package/dist/app-sidecar/mcp-routes.js.map +1 -0
- package/dist/app-sidecar/mcp-rows.d.ts +31 -0
- package/dist/app-sidecar/mcp-rows.js +77 -0
- package/dist/app-sidecar/mcp-rows.js.map +1 -0
- package/dist/app-sidecar/nolan-context.d.ts +20 -0
- package/dist/app-sidecar/nolan-context.js +55 -0
- package/dist/app-sidecar/nolan-context.js.map +1 -0
- package/dist/app-sidecar/progress-manager.d.ts +10 -0
- package/dist/app-sidecar/progress-manager.js +116 -0
- package/dist/app-sidecar/progress-manager.js.map +1 -0
- package/dist/app-sidecar/prompt-routes.d.ts +3 -0
- package/dist/app-sidecar/prompt-routes.js +355 -0
- package/dist/app-sidecar/prompt-routes.js.map +1 -0
- package/dist/app-sidecar/repo-polls.d.ts +15 -0
- package/dist/app-sidecar/repo-polls.js +25 -0
- package/dist/app-sidecar/repo-polls.js.map +1 -0
- package/dist/app-sidecar/route-context.d.ts +145 -0
- package/dist/app-sidecar/route-context.js +2 -0
- package/dist/app-sidecar/route-context.js.map +1 -0
- package/dist/app-sidecar/run-control-routes.d.ts +3 -0
- package/dist/app-sidecar/run-control-routes.js +437 -0
- package/dist/app-sidecar/run-control-routes.js.map +1 -0
- package/dist/app-sidecar/session-routes.d.ts +3 -0
- package/dist/app-sidecar/session-routes.js +115 -0
- package/dist/app-sidecar/session-routes.js.map +1 -0
- package/dist/app-sidecar/session-types.d.ts +39 -0
- package/dist/app-sidecar/session-types.js +5 -0
- package/dist/app-sidecar/session-types.js.map +1 -0
- package/dist/app-sidecar/task-routes.d.ts +3 -0
- package/dist/app-sidecar/task-routes.js +232 -0
- package/dist/app-sidecar/task-routes.js.map +1 -0
- package/dist/app-sidecar/usage.d.ts +19 -0
- package/dist/app-sidecar/usage.js +153 -0
- package/dist/app-sidecar/usage.js.map +1 -0
- package/dist/app-sidecar/workspace-routes.d.ts +3 -0
- package/dist/app-sidecar/workspace-routes.js +374 -0
- package/dist/app-sidecar/workspace-routes.js.map +1 -0
- package/dist/app-sidecar.js +518 -3978
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli.js +6 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/core/acceptance-checks.js +3 -9
- package/dist/core/acceptance-checks.js.map +1 -1
- package/dist/core/agent-session/helpers.d.ts +26 -0
- package/dist/core/agent-session/helpers.js +47 -0
- package/dist/core/agent-session/helpers.js.map +1 -0
- package/dist/core/agent-session/mcp-tools.d.ts +68 -0
- package/dist/core/agent-session/mcp-tools.js +195 -0
- package/dist/core/agent-session/mcp-tools.js.map +1 -0
- package/dist/core/agent-session/run-loop-monitor.d.ts +63 -0
- package/dist/core/agent-session/run-loop-monitor.js +164 -0
- package/dist/core/agent-session/run-loop-monitor.js.map +1 -0
- package/dist/core/agent-session/transcript-markers.d.ts +57 -0
- package/dist/core/agent-session/transcript-markers.js +166 -0
- package/dist/core/agent-session/transcript-markers.js.map +1 -0
- package/dist/core/agent-session/verification-tracker.d.ts +46 -0
- package/dist/core/agent-session/verification-tracker.js +250 -0
- package/dist/core/agent-session/verification-tracker.js.map +1 -0
- package/dist/core/agent-session.d.ts +29 -89
- package/dist/core/agent-session.js +167 -705
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-providers.js +3 -3
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/autopilot-cycle.d.ts +6 -2
- package/dist/core/autopilot-cycle.js +1 -1
- package/dist/core/autopilot-cycle.js.map +1 -1
- package/dist/core/bundled-agents.js +6 -6
- package/dist/core/bundled-agents.js.map +1 -1
- package/dist/core/checklist-detection.d.ts +11 -0
- package/dist/core/checklist-detection.js +238 -0
- package/dist/core/checklist-detection.js.map +1 -0
- package/dist/core/checklist-git.d.ts +19 -0
- package/dist/core/checklist-git.js +54 -0
- package/dist/core/checklist-git.js.map +1 -0
- package/dist/core/checklist-items.d.ts +189 -0
- package/dist/core/checklist-items.js +226 -0
- package/dist/core/checklist-items.js.map +1 -0
- package/dist/core/checklist-prompt.d.ts +7 -0
- package/dist/core/checklist-prompt.js +45 -0
- package/dist/core/checklist-prompt.js.map +1 -0
- package/dist/core/checklist-snapshot.d.ts +17 -0
- package/dist/core/checklist-snapshot.js +46 -0
- package/dist/core/checklist-snapshot.js.map +1 -0
- package/dist/core/checklist-store.d.ts +59 -0
- package/dist/core/checklist-store.js +242 -0
- package/dist/core/checklist-store.js.map +1 -0
- package/dist/core/context-limits.js +1 -1
- package/dist/core/context-limits.js.map +1 -1
- package/dist/core/lsp/client.d.ts +4 -0
- package/dist/core/lsp/client.js +71 -3
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/manager.d.ts +1 -0
- package/dist/core/lsp/manager.js +9 -3
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/project-root.d.ts +9 -0
- package/dist/core/lsp/project-root.js +75 -0
- package/dist/core/lsp/project-root.js.map +1 -0
- package/dist/core/lsp/reference-project.d.ts +6 -0
- package/dist/core/lsp/reference-project.js +110 -0
- package/dist/core/lsp/reference-project.js.map +1 -0
- package/dist/core/lsp/servers.js +1 -0
- package/dist/core/lsp/servers.js.map +1 -1
- package/dist/core/plan-handoff.d.ts +30 -0
- package/dist/core/plan-handoff.js +10 -0
- package/dist/core/plan-handoff.js.map +1 -0
- package/dist/core/plan-submission-gate.d.ts +28 -0
- package/dist/core/plan-submission-gate.js +27 -0
- package/dist/core/plan-submission-gate.js.map +1 -0
- package/dist/core/prompt-commands.js +95 -0
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/skills.js +6 -9
- package/dist/core/skills.js.map +1 -1
- package/dist/core/style-packs/index.js +2 -11
- package/dist/core/style-packs/index.js.map +1 -1
- package/dist/core/style-packs/packs.d.ts +3 -12
- package/dist/core/style-packs/packs.js +132 -173
- package/dist/core/style-packs/packs.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +2 -1
- package/dist/core/subagent-manager.js +8 -5
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/verification-evidence.d.ts +8 -0
- package/dist/core/verification-evidence.js +27 -5
- package/dist/core/verification-evidence.js.map +1 -1
- package/dist/modes/acp-mode.d.ts +2 -1
- package/dist/modes/acp-mode.js +4 -1
- package/dist/modes/acp-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +2 -0
- package/dist/modes/subagent-worker-mode.js +1 -3
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/system-prompt.js +52 -78
- package/dist/system-prompt.js.map +1 -1
- package/dist/tools/ask-user.js +13 -74
- package/dist/tools/ask-user.js.map +1 -1
- package/dist/tools/bash.d.ts +4 -1
- package/dist/tools/bash.js +46 -81
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/checklist.d.ts +48 -0
- package/dist/tools/checklist.js +146 -0
- package/dist/tools/checklist.js.map +1 -0
- package/dist/tools/code-nav.d.ts +1 -1
- package/dist/tools/code-nav.js +9 -30
- package/dist/tools/code-nav.js.map +1 -1
- package/dist/tools/edit.d.ts +3 -9
- package/dist/tools/edit.js +92 -65
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/enter-plan.js +2 -7
- package/dist/tools/enter-plan.js.map +1 -1
- package/dist/tools/exit-plan.d.ts +2 -2
- package/dist/tools/exit-plan.js +9 -4
- package/dist/tools/exit-plan.js.map +1 -1
- package/dist/tools/find.js +3 -4
- package/dist/tools/find.js.map +1 -1
- package/dist/tools/grep.js +6 -18
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/index.d.ts +5 -3
- package/dist/tools/index.js +5 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/ls.js +3 -3
- package/dist/tools/ls.js.map +1 -1
- package/dist/tools/prompt-hints.js +35 -46
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/read.js +8 -20
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/search-code.js +4 -12
- package/dist/tools/search-code.js.map +1 -1
- package/dist/tools/skill.js +13 -7
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/subagent-control.js +7 -22
- package/dist/tools/subagent-control.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +6 -8
- package/dist/tools/subagent-shared.js +17 -11
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent.d.ts +2 -1
- package/dist/tools/subagent.js +7 -7
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/task-output.js +4 -15
- package/dist/tools/task-output.js.map +1 -1
- package/dist/tools/task-send.js +5 -17
- package/dist/tools/task-send.js.map +1 -1
- package/dist/tools/task-stop.js +2 -2
- package/dist/tools/task-stop.js.map +1 -1
- package/dist/tools/tasks.d.ts +1 -1
- package/dist/tools/tool-search.js +2 -7
- package/dist/tools/tool-search.js.map +1 -1
- package/dist/tools/tool-tiers.d.ts +21 -4
- package/dist/tools/tool-tiers.js +45 -17
- package/dist/tools/tool-tiers.js.map +1 -1
- package/dist/tools/verification-review.d.ts +2 -0
- package/dist/tools/verification-review.js +41 -0
- package/dist/tools/verification-review.js.map +1 -0
- package/dist/tools/web-fetch.js +7 -33
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/write.js +3 -4
- package/dist/tools/write.js.map +1 -1
- package/dist/ui/App.js +1 -0
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/Footer.js +1 -2
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/hooks/useModeState.js +15 -0
- package/dist/ui/hooks/useModeState.js.map +1 -1
- package/dist/ui/tool-line-summary.js +11 -1
- package/dist/ui/tool-line-summary.js.map +1 -1
- package/dist/ui/transcript/tool-presentation.js +1 -1
- package/dist/ui/transcript/tool-presentation.js.map +1 -1
- package/dist/utils/shared-poll.d.ts +37 -0
- package/dist/utils/shared-poll.js +104 -0
- package/dist/utils/shared-poll.js.map +1 -0
- package/package.json +8 -5
- package/dist/core/api-benchmark.d.ts +0 -63
- package/dist/core/api-benchmark.js +0 -381
- package/dist/core/api-benchmark.js.map +0 -1
- package/dist/core/bash-spawn-benchmark.d.ts +0 -1
- package/dist/core/bash-spawn-benchmark.js +0 -139
- package/dist/core/bash-spawn-benchmark.js.map +0 -1
- package/dist/core/cache-warm-benchmark.d.ts +0 -21
- package/dist/core/cache-warm-benchmark.js +0 -170
- package/dist/core/cache-warm-benchmark.js.map +0 -1
- package/dist/core/fast-apply-benchmark.d.ts +0 -25
- package/dist/core/fast-apply-benchmark.js +0 -284
- package/dist/core/fast-apply-benchmark.js.map +0 -1
- package/dist/core/hashline-edit-benchmark.d.ts +0 -88
- package/dist/core/hashline-edit-benchmark.js +0 -518
- package/dist/core/hashline-edit-benchmark.js.map +0 -1
- package/dist/core/semantic-search-benchmark.d.ts +0 -36
- package/dist/core/semantic-search-benchmark.js +0 -211
- package/dist/core/semantic-search-benchmark.js.map +0 -1
- package/dist/core/speed-benchmark.d.ts +0 -132
- package/dist/core/speed-benchmark.js +0 -410
- package/dist/core/speed-benchmark.js.map +0 -1
package/README.md
CHANGED
|
@@ -67,18 +67,17 @@ You can still add your own MCPs if you need them. But start with less. You'll ge
|
|
|
67
67
|
|
|
68
68
|
Switch mid-conversation with `/model`. Not locked to anyone.
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
| **
|
|
74
|
-
| **
|
|
75
|
-
| **
|
|
76
|
-
| **
|
|
77
|
-
| **
|
|
78
|
-
| **
|
|
79
|
-
| **
|
|
80
|
-
| **
|
|
81
|
-
| **OpenRouter** | Qwen3.8 Max (image + video) + multi-provider gateway | API key |
|
|
70
|
+
| Provider | Models | Auth |
|
|
71
|
+
| ----------------- | ------------------------------------------------------------------ | ---------------- |
|
|
72
|
+
| **Anthropic** | Claude Fable 5.1, Opus 5.5, Sonnet 5.5, Haiku 5.5 | OAuth |
|
|
73
|
+
| **OpenAI** | GPT-6 Astra, GPT-6.1 Sol, GPT-6 Luna | OAuth |
|
|
74
|
+
| **Moonshot** | Kimi K3, K2.8 Preview (Kimi sign-in), K2.7 Code | OAuth or API key |
|
|
75
|
+
| **Z.AI (GLM)** | GLM-5.3, GLM-5.3-Flash (image) | API key |
|
|
76
|
+
| **MiniMax** | MiniMax M3 (image + video) | API key |
|
|
77
|
+
| **Xiaomi (MiMo)** | MiMo-V2.6-Pro, MiMo-V2.6-Flash, MiMo-V2.6-Pro-UltraSpeed | API key |
|
|
78
|
+
| **DeepSeek** | DeepSeek V4 Pro, V4.1 Flash (image) | API key |
|
|
79
|
+
| **Sakana (Fugu)** | Fugu, Fugu Max, Fugu Ultra (image) | API key |
|
|
80
|
+
| **OpenRouter** | Qwen3.8 Max (image + video) + multi-provider gateway | API key |
|
|
82
81
|
|
|
83
82
|
The same conversation, the same tools, the same project context — only the model changes. Use a strong reasoning model when you need it, swap to a fast cheap one for grunt work, never restart your session.
|
|
84
83
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bulletproof
|
|
3
|
-
description: Use
|
|
3
|
+
description: "Use for attacker-reachable code: auth, tokens, crypto, untrusted input, secrets, tenant data, CI, agent tools. Do NOT use for local scripts without auth or network."
|
|
4
4
|
license: Apache-2.0. Content is defensive engineering guidance, not a security certification or a penetration test. See references/provenance.md.
|
|
5
5
|
compatibility: Works offline from the bundled references, which are a snapshot dated 3 October 2026. Version numbers, CVEs, and incident details decay fast; re-verify date-sensitive claims with web access before stating them as current. Never certifies that software is secure.
|
|
6
6
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clarify
|
|
3
|
-
description: Use when requirements
|
|
3
|
+
description: Use when requirements are genuinely unsettled. Do NOT use for routine work.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Clarify
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: code-review
|
|
3
|
-
description: Use when
|
|
3
|
+
description: Use when asked to review a diff, PR or finished work. Do NOT use mid-build.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Code Review
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: compliance-guard
|
|
3
|
-
description: Use when shipping
|
|
3
|
+
description: Use when shipping to real users risks legal exposure (personal data, payments, minors). Do NOT use for local work.
|
|
4
4
|
license: Apache-2.0. Content is engineering guidance, not legal advice. See references/provenance.md.
|
|
5
5
|
compatibility: Static review works offline from the bundled references. Legal status changes constantly; date-sensitive claims must be re-verified with web access before being stated as current. Never certifies compliance.
|
|
6
6
|
---
|
|
@@ -27,7 +27,7 @@ Also note **Texas and Nebraska have no revenue or volume threshold** — they ap
|
|
|
27
27
|
|
|
28
28
|
Thresholds range from 25,000 consumers (Montana) to 175,000 (Tennessee); 10,000 consumers where a share of revenue comes from selling data (RI, DE, NH, MD); Maryland pairs a 35,000-consumer threshold with the strictest data-minimisation and sensitive-data rules, and bans the sale of sensitive data outright **[V]**.
|
|
29
29
|
|
|
30
|
-
**Universal opt-out / Global Privacy Control — the cheapest high-value engineering task.** As of 1 Jan 2026, twelve states require honouring it (CA, CO, CT, DE, MD, MN, MT, NE, NH, NJ, OR, TX); Virginia-template states, including the 2026 newcomers Indiana,
|
|
30
|
+
**Universal opt-out / Global Privacy Control — the cheapest high-value engineering task.** As of 1 Jan 2026, twelve states require honouring it (CA, CO, CT, DE, MD, MN, MT, NE, NH, NJ, OR, TX); Virginia-template states, including the 2026 newcomers Indiana, Nolantucky and Rhode Island, do not **[V]**. California's regulations effective 1 Jan 2026 also require the business to display whether the signal was honoured (11 CCR §7025(c)(6)) **[S]**. California, Colorado and Connecticut have run a coordinated GPC enforcement sweep **[S]**.
|
|
31
31
|
|
|
32
32
|
```
|
|
33
33
|
Read the Sec-GPC: 1 request header and navigator.globalPrivacyControl.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: durable
|
|
3
|
-
description: Use when
|
|
3
|
+
description: "Use when data could be lost: migrations, destructive ops, real databases. Do NOT use for query speed."
|
|
4
4
|
license: Data-durability engineering guidance, not a DBA certification. Sources and snapshot date are recorded at the foot of each reference file.
|
|
5
5
|
compatibility: Snapshot dated 3 October 2026. Version behaviours, provider retention defaults and tool flags decay — re-verify with web access before asserting them as current.
|
|
6
6
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: evidence-led-ui
|
|
3
|
-
description: Use when building or
|
|
3
|
+
description: Use when building or reviewing UI visuals. Do NOT use for behaviour-only changes.
|
|
4
4
|
license: See LICENSES.md
|
|
5
5
|
compatibility: Full review requires filesystem inspection and rendered screenshots (deferred `screenshot` tool); web research and device tooling are optional and unavailable checks must be reported as unverified.
|
|
6
6
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lean
|
|
3
|
-
description: Use when speed or resource use matters
|
|
3
|
+
description: Use when speed or resource use matters. Do NOT use for correctness bugs.
|
|
4
4
|
license: Performance engineering guidance, not a benchmark certification. Sources and snapshot date are recorded at the foot of each reference file.
|
|
5
5
|
compatibility: Snapshot dated 3 October 2026. Thresholds, tool names, and defaults decay — re-verify with web access before asserting them as current. Claims sourced to that date carry a SNAPSHOT marker.
|
|
6
6
|
---
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: refactoring
|
|
3
|
-
description: Use
|
|
3
|
+
description: Use for behaviour-preserving restructuring behind an unchanged contract. Do NOT use for renames, bug fixes or behaviour changes.
|
|
4
4
|
license: Behavior-preservation methodology synthesized from public sources (Fowler's Refactoring catalog, Tidy First?, and community agent skills by bienhoang, wondelai, mattpocock, jeffallan, vasilyu1983), audited 2026-09-12.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Refactoring
|
|
8
8
|
|
|
9
|
+
**Scope gate:** Decide from the requested behavior, not the word "refactor". A requested change to return values, error handling, or an API contract is implementation work, not a behavior-preserving cleanup. Use the normal implementation workflow: inspect the affected callers, make the requested contract and caller changes together, add regression coverage, and run the checks. Do not manufacture a separate pure-rename stage merely to enter this skill. Existing authorization and safety controls still apply. For a genuine behavior-preserving refactor, use the gated loop below unchanged.
|
|
10
|
+
|
|
9
11
|
**Route first:**
|
|
10
12
|
|
|
11
13
|
| Situation | Mode | Next |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: root-cause
|
|
3
|
-
description: Use when a bug resists the obvious fix
|
|
3
|
+
description: Use when a bug resists the obvious fix or is flaky. Do NOT use when the cause is obvious.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Root-Cause
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: shared-language
|
|
3
|
-
description: Use when
|
|
3
|
+
description: Use when domain terms drift or a decision needs an ADR. Do NOT use for renames.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Shared Language
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tdd
|
|
3
|
-
description: Use when
|
|
3
|
+
description: Use when asked for test-first development. Do NOT use for post-build tests.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# TDD
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type FormattedChatError } from "@prestyj/ai";
|
|
3
|
+
declare const appErrorSchema: z.ZodObject<{
|
|
4
|
+
scope: z.ZodDefault<z.ZodString>;
|
|
5
|
+
headline: z.ZodString;
|
|
6
|
+
message: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
7
|
+
guidance: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
8
|
+
reason: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
9
|
+
source: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
10
|
+
provider: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
11
|
+
statusCode: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
|
|
12
|
+
requestId: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
13
|
+
occurredAt: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
|
|
14
|
+
resetsAt: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
export type AppErrorPayload = z.infer<typeof appErrorSchema>;
|
|
17
|
+
/** The same sanitized snapshot goes to SSE and the append-only history marker. */
|
|
18
|
+
export declare function createAppErrorPayload(error: FormattedChatError, scope: string, occurredAt: number, secrets: Iterable<string>): AppErrorPayload;
|
|
19
|
+
/** Backward-compatible read: no migration or reclassification of old saved text. */
|
|
20
|
+
export declare function restoreAppErrorPayload(value: unknown): AppErrorPayload | undefined;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { redactValue } from "@prestyj/ai";
|
|
3
|
+
const timestamp = z.number().int().nonnegative().max(8_640_000_000_000).optional().catch(undefined);
|
|
4
|
+
const optionalText = z.string().max(8_000).optional().catch(undefined);
|
|
5
|
+
const appErrorSchema = z.object({
|
|
6
|
+
scope: z.string().max(80).default("error"),
|
|
7
|
+
headline: z.string().min(1).max(1_000),
|
|
8
|
+
message: optionalText,
|
|
9
|
+
guidance: optionalText,
|
|
10
|
+
reason: z.string().max(40).optional().catch(undefined),
|
|
11
|
+
source: z.string().max(40).optional().catch(undefined),
|
|
12
|
+
provider: z.string().max(80).optional().catch(undefined),
|
|
13
|
+
statusCode: z.number().int().min(100).max(599).optional().catch(undefined),
|
|
14
|
+
requestId: z.string().max(300).optional().catch(undefined),
|
|
15
|
+
occurredAt: timestamp,
|
|
16
|
+
resetsAt: timestamp,
|
|
17
|
+
});
|
|
18
|
+
/** The same sanitized snapshot goes to SSE and the append-only history marker. */
|
|
19
|
+
export function createAppErrorPayload(error, scope, occurredAt, secrets) {
|
|
20
|
+
return redactValue({
|
|
21
|
+
scope,
|
|
22
|
+
headline: error.headline,
|
|
23
|
+
message: error.message,
|
|
24
|
+
guidance: error.guidance,
|
|
25
|
+
reason: error.reason,
|
|
26
|
+
source: error.source,
|
|
27
|
+
provider: error.provider,
|
|
28
|
+
statusCode: error.statusCode,
|
|
29
|
+
requestId: error.requestId,
|
|
30
|
+
occurredAt,
|
|
31
|
+
resetsAt: error.resetsAt,
|
|
32
|
+
}, { secrets, maxStringLength: 8_000 });
|
|
33
|
+
}
|
|
34
|
+
/** Backward-compatible read: no migration or reclassification of old saved text. */
|
|
35
|
+
export function restoreAppErrorPayload(value) {
|
|
36
|
+
const parsed = appErrorSchema.safeParse(value);
|
|
37
|
+
return parsed.success ? parsed.data : undefined;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=app-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-error.js","sourceRoot":"","sources":["../src/app-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAA2B,MAAM,aAAa,CAAC;AAEnE,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACpG,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACvE,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAC1C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;IACtC,OAAO,EAAE,YAAY;IACrB,QAAQ,EAAE,YAAY;IACtB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;IACtD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;IACtD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;IACxD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;IAC1E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;IAC1D,UAAU,EAAE,SAAS;IACrB,QAAQ,EAAE,SAAS;CACpB,CAAC,CAAC;AAGH,kFAAkF;AAClF,MAAM,UAAU,qBAAqB,CACnC,KAAyB,EACzB,KAAa,EACb,UAAkB,EAClB,OAAyB;IAEzB,OAAO,WAAW,CAChB;QACE,KAAK;QACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,UAAU;QACV,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,EACD,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CACpC,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Provider, ThinkingLevel } from "@prestyj/ai";
|
|
2
|
+
import type { NolanModelPref } from "../core/nolan-model.js";
|
|
3
|
+
export declare const ALL_PROVIDERS: Provider[];
|
|
4
|
+
/** Per-project model + thinking preferences. Persisted so each window (one
|
|
5
|
+
* project cwd) restores its OWN model across app restarts — instead of every
|
|
6
|
+
* window reading the same single global slot that the last writer clobbered. */
|
|
7
|
+
export interface ProjectModelPrefs {
|
|
8
|
+
provider: Provider;
|
|
9
|
+
model: string;
|
|
10
|
+
thinkingEnabled?: boolean;
|
|
11
|
+
thinkingLevel?: ThinkingLevel;
|
|
12
|
+
}
|
|
13
|
+
export interface AppSettings {
|
|
14
|
+
/** Folder new projects are created inside. Defaults to ~/ez-projects. */
|
|
15
|
+
projectsRoot: string;
|
|
16
|
+
/** Model + thinking prefs keyed by normalized project cwd. A window restores
|
|
17
|
+
* its own entry on boot; absent → global settings.json → provider default. */
|
|
18
|
+
projectModels?: Record<string, ProjectModelPrefs>;
|
|
19
|
+
/** Autopilot (auto-review) on/off keyed by normalized project cwd. Per-window
|
|
20
|
+
* (one window = one cwd); absent/false → off. Restored on boot. */
|
|
21
|
+
autopilot?: Record<string, boolean>;
|
|
22
|
+
/** Nolan model override keyed by normalized project cwd. */
|
|
23
|
+
nolanModels?: Record<string, NolanModelPref>;
|
|
24
|
+
/** Extra folders scanned for projects alongside `projectsRoot`. */
|
|
25
|
+
projectRoots?: string[];
|
|
26
|
+
/** Project paths dismissed from the picker, as normalized cwds. */
|
|
27
|
+
hiddenProjects?: string[];
|
|
28
|
+
}
|
|
29
|
+
export declare function stringArray(value: unknown): string[] | undefined;
|
|
30
|
+
export declare function appSettingsFile(): string;
|
|
31
|
+
export declare function defaultProjectsRoot(): string;
|
|
32
|
+
/** Normalize a project cwd to a stable settings key so trailing slashes /
|
|
33
|
+
* relative segments collapse — the same project always maps to one entry. */
|
|
34
|
+
export declare function projectModelKey(cwd: string): string;
|
|
35
|
+
export declare function loadAppSettings(): Promise<AppSettings>;
|
|
36
|
+
export declare function saveAppSettings(settings: AppSettings): Promise<void>;
|
|
37
|
+
/** Read this project's persisted model/thinking prefs, if any. */
|
|
38
|
+
export declare function loadProjectModelPrefs(cwd: string): Promise<ProjectModelPrefs | undefined>;
|
|
39
|
+
/** Persist this project's model/thinking prefs via read-modify-write so the rest
|
|
40
|
+
* of the settings file (projectsRoot, other projects' entries) is preserved. */
|
|
41
|
+
export declare function saveProjectModelPrefs(cwd: string, prefs: ProjectModelPrefs): Promise<void>;
|
|
42
|
+
/** Read this project's persisted Nolan model override, if any. */
|
|
43
|
+
export declare function loadNolanModelPref(cwd: string): Promise<NolanModelPref | undefined>;
|
|
44
|
+
/** Persist (or with null, clear) this project's Nolan model override via
|
|
45
|
+
* read-modify-write so the rest of the settings file is preserved. */
|
|
46
|
+
export declare function saveNolanModelPref(cwd: string, pref: NolanModelPref | null): Promise<void>;
|
|
47
|
+
/** Read this project's persisted autopilot flag (default off). */
|
|
48
|
+
export declare function loadAutopilot(cwd: string): Promise<boolean>;
|
|
49
|
+
/** Persist this project's autopilot flag via read-modify-write so the rest of
|
|
50
|
+
* the settings file (projectsRoot, model map, other projects) is preserved. */
|
|
51
|
+
export declare function saveAutopilot(cwd: string, enabled: boolean): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Persist the active model selection to ~/.ezcoder/settings.json so it survives app
|
|
54
|
+
* restarts. Mirrors the CLI's handleModelSelect persistence (App.tsx).
|
|
55
|
+
*/
|
|
56
|
+
export declare function persistModelSelection(settingsFile: string, provider: Provider, model: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Persist the thinking level to ~/.ezcoder/settings.json so it survives app restarts.
|
|
59
|
+
* Mirrors the CLI's handleToggleThinking persistence (App.tsx).
|
|
60
|
+
*/
|
|
61
|
+
export declare function persistThinkingLevel(settingsFile: string, level: ThinkingLevel | undefined): Promise<void>;
|
|
62
|
+
/** Validate a project folder name: lowercase letters, digits, dashes only. */
|
|
63
|
+
export declare function isValidProjectName(name: string): boolean;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { SettingsManager } from "../core/settings-manager.js";
|
|
5
|
+
import { log } from "../core/logger.js";
|
|
6
|
+
export const ALL_PROVIDERS = [
|
|
7
|
+
// US
|
|
8
|
+
"anthropic",
|
|
9
|
+
"openai",
|
|
10
|
+
"gemini",
|
|
11
|
+
"xai",
|
|
12
|
+
// China
|
|
13
|
+
"moonshot",
|
|
14
|
+
"glm",
|
|
15
|
+
"minimax",
|
|
16
|
+
"xiaomi",
|
|
17
|
+
"deepseek",
|
|
18
|
+
// Open-community gateway, before the provider-agnostic one
|
|
19
|
+
"huggingface",
|
|
20
|
+
// Japan, then provider-agnostic gateway last
|
|
21
|
+
"sakana",
|
|
22
|
+
"openrouter",
|
|
23
|
+
];
|
|
24
|
+
export function stringArray(value) {
|
|
25
|
+
if (!Array.isArray(value))
|
|
26
|
+
return undefined;
|
|
27
|
+
const out = value.filter((v) => typeof v === "string" && v.trim().length > 0);
|
|
28
|
+
return out.length > 0 ? out : undefined;
|
|
29
|
+
}
|
|
30
|
+
export function appSettingsFile() {
|
|
31
|
+
return path.join(os.homedir(), ".ezcoder", "ezcoder-app.json");
|
|
32
|
+
}
|
|
33
|
+
export function defaultProjectsRoot() {
|
|
34
|
+
return path.join(os.homedir(), "ez-projects");
|
|
35
|
+
}
|
|
36
|
+
/** Normalize a project cwd to a stable settings key so trailing slashes /
|
|
37
|
+
* relative segments collapse — the same project always maps to one entry. */
|
|
38
|
+
export function projectModelKey(cwd) {
|
|
39
|
+
return path.resolve(cwd);
|
|
40
|
+
}
|
|
41
|
+
export async function loadAppSettings() {
|
|
42
|
+
try {
|
|
43
|
+
const raw = JSON.parse(await fs.readFile(appSettingsFile(), "utf-8"));
|
|
44
|
+
return {
|
|
45
|
+
projectsRoot: typeof raw.projectsRoot === "string" && raw.projectsRoot.trim()
|
|
46
|
+
? raw.projectsRoot
|
|
47
|
+
: defaultProjectsRoot(),
|
|
48
|
+
// Preserve the per-project map verbatim (validated + written by the
|
|
49
|
+
// model/thinking handlers below).
|
|
50
|
+
projectModels: raw.projectModels && typeof raw.projectModels === "object" ? raw.projectModels : undefined,
|
|
51
|
+
autopilot: raw.autopilot && typeof raw.autopilot === "object" ? raw.autopilot : undefined,
|
|
52
|
+
nolanModels: raw.nolanModels && typeof raw.nolanModels === "object" ? raw.nolanModels : undefined,
|
|
53
|
+
projectRoots: stringArray(raw.projectRoots),
|
|
54
|
+
hiddenProjects: stringArray(raw.hiddenProjects),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return { projectsRoot: defaultProjectsRoot() };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export async function saveAppSettings(settings) {
|
|
62
|
+
await fs.mkdir(path.dirname(appSettingsFile()), { recursive: true });
|
|
63
|
+
await fs.writeFile(appSettingsFile(), JSON.stringify(settings, null, 2), "utf-8");
|
|
64
|
+
}
|
|
65
|
+
/** Read this project's persisted model/thinking prefs, if any. */
|
|
66
|
+
export async function loadProjectModelPrefs(cwd) {
|
|
67
|
+
const s = await loadAppSettings();
|
|
68
|
+
return s.projectModels?.[projectModelKey(cwd)];
|
|
69
|
+
}
|
|
70
|
+
/** Persist this project's model/thinking prefs via read-modify-write so the rest
|
|
71
|
+
* of the settings file (projectsRoot, other projects' entries) is preserved. */
|
|
72
|
+
export async function saveProjectModelPrefs(cwd, prefs) {
|
|
73
|
+
const s = await loadAppSettings();
|
|
74
|
+
const key = projectModelKey(cwd);
|
|
75
|
+
s.projectModels = { ...(s.projectModels ?? {}), [key]: prefs };
|
|
76
|
+
await saveAppSettings(s);
|
|
77
|
+
}
|
|
78
|
+
/** Read this project's persisted Nolan model override, if any. */
|
|
79
|
+
export async function loadNolanModelPref(cwd) {
|
|
80
|
+
const s = await loadAppSettings();
|
|
81
|
+
return s.nolanModels?.[projectModelKey(cwd)];
|
|
82
|
+
}
|
|
83
|
+
/** Persist (or with null, clear) this project's Nolan model override via
|
|
84
|
+
* read-modify-write so the rest of the settings file is preserved. */
|
|
85
|
+
export async function saveNolanModelPref(cwd, pref) {
|
|
86
|
+
const s = await loadAppSettings();
|
|
87
|
+
const key = projectModelKey(cwd);
|
|
88
|
+
const next = { ...(s.nolanModels ?? {}) };
|
|
89
|
+
if (pref)
|
|
90
|
+
next[key] = pref;
|
|
91
|
+
else
|
|
92
|
+
delete next[key];
|
|
93
|
+
s.nolanModels = next;
|
|
94
|
+
await saveAppSettings(s);
|
|
95
|
+
}
|
|
96
|
+
/** Read this project's persisted autopilot flag (default off). */
|
|
97
|
+
export async function loadAutopilot(cwd) {
|
|
98
|
+
const s = await loadAppSettings();
|
|
99
|
+
return s.autopilot?.[projectModelKey(cwd)] ?? false;
|
|
100
|
+
}
|
|
101
|
+
/** Persist this project's autopilot flag via read-modify-write so the rest of
|
|
102
|
+
* the settings file (projectsRoot, model map, other projects) is preserved. */
|
|
103
|
+
export async function saveAutopilot(cwd, enabled) {
|
|
104
|
+
const s = await loadAppSettings();
|
|
105
|
+
const key = projectModelKey(cwd);
|
|
106
|
+
s.autopilot = { ...(s.autopilot ?? {}), [key]: enabled };
|
|
107
|
+
await saveAppSettings(s);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Persist the active model selection to ~/.ezcoder/settings.json so it survives app
|
|
111
|
+
* restarts. Mirrors the CLI's handleModelSelect persistence (App.tsx).
|
|
112
|
+
*/
|
|
113
|
+
export async function persistModelSelection(settingsFile, provider, model) {
|
|
114
|
+
try {
|
|
115
|
+
const sm = new SettingsManager(settingsFile);
|
|
116
|
+
await sm.load();
|
|
117
|
+
await sm.set("defaultProvider", provider);
|
|
118
|
+
await sm.set("defaultModel", model);
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
log("WARN", "app-sidecar", "failed to persist model selection", { err: String(err) });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Persist the thinking level to ~/.ezcoder/settings.json so it survives app restarts.
|
|
126
|
+
* Mirrors the CLI's handleToggleThinking persistence (App.tsx).
|
|
127
|
+
*/
|
|
128
|
+
export async function persistThinkingLevel(settingsFile, level) {
|
|
129
|
+
try {
|
|
130
|
+
const sm = new SettingsManager(settingsFile);
|
|
131
|
+
await sm.load();
|
|
132
|
+
await sm.set("thinkingEnabled", !!level);
|
|
133
|
+
if (level)
|
|
134
|
+
await sm.set("thinkingLevel", level);
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
log("WARN", "app-sidecar", "failed to persist thinking level", { err: String(err) });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/** Validate a project folder name: lowercase letters, digits, dashes only. */
|
|
141
|
+
export function isValidProjectName(name) {
|
|
142
|
+
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name);
|
|
143
|
+
}
|
|
144
|
+
// ── History reconstruction types ──────────────────────────
|
|
145
|
+
// Mirrors HistoryEntry in ezcoder-app/src/agent.ts — the wire shape the webview
|
|
146
|
+
// receives from GET /history. Fields beyond role/text carry the transcript
|
|
147
|
+
//# sourceMappingURL=app-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-settings.js","sourceRoot":"","sources":["../../src/app-sidecar/app-settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface AppAttachment {
|
|
2
|
+
kind: "image" | "video" | "file";
|
|
3
|
+
name: string;
|
|
4
|
+
mediaType: string;
|
|
5
|
+
/** base64 (no data: prefix). */
|
|
6
|
+
data: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PreparedAttachment extends AppAttachment {
|
|
9
|
+
path?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function prepareAttachments(cwd: string, attachments: AppAttachment[]): Promise<PreparedAttachment[]>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { shrinkToFit, validateVisionImage } from "../utils/image.js";
|
|
4
|
+
export async function prepareAttachments(cwd, attachments) {
|
|
5
|
+
const dir = path.join(cwd, ".ezcoder", "uploads");
|
|
6
|
+
await fs.mkdir(dir, { recursive: true }).catch(() => { });
|
|
7
|
+
const out = [];
|
|
8
|
+
for (const a of attachments) {
|
|
9
|
+
// Sanitize the filename and prefix with a short timestamp to avoid clobber.
|
|
10
|
+
const safe = a.name.replace(/[^\w.-]+/g, "_").slice(-80) || "file";
|
|
11
|
+
const fileName = `${Date.now().toString(36)}-${safe}`;
|
|
12
|
+
const filePath = path.join(dir, fileName);
|
|
13
|
+
const buf = Buffer.from(a.data, "base64");
|
|
14
|
+
// Validate and cap image attachments before they become native image content
|
|
15
|
+
// blocks. Anthropic applies a 2000 px per-dimension cap once conversation
|
|
16
|
+
// history contains more than 20 images, so every attachment must be safe for
|
|
17
|
+
// later turns too. Keep the original on disk, but send the resized bytes.
|
|
18
|
+
// Corrupt or unsupported images become plain files so they cannot reject the
|
|
19
|
+
// entire provider request.
|
|
20
|
+
let prepared = { ...a };
|
|
21
|
+
if (a.kind === "image") {
|
|
22
|
+
try {
|
|
23
|
+
const resized = await shrinkToFit(buf, a.mediaType);
|
|
24
|
+
const validatedType = await validateVisionImage(resized.buffer);
|
|
25
|
+
prepared = validatedType
|
|
26
|
+
? {
|
|
27
|
+
...a,
|
|
28
|
+
mediaType: validatedType,
|
|
29
|
+
data: resized.buffer.toString("base64"),
|
|
30
|
+
}
|
|
31
|
+
: { ...a, kind: "file" };
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
prepared = { ...a, kind: "file" };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
await fs.writeFile(filePath, buf);
|
|
39
|
+
out.push({ ...prepared, path: filePath });
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
out.push({ ...prepared });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/app-sidecar/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAiBrE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAW,EACX,WAA4B;IAE5B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzD,MAAM,GAAG,GAAyB,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,4EAA4E;QAC5E,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC;QACnE,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1C,6EAA6E;QAC7E,0EAA0E;QAC1E,6EAA6E;QAC7E,0EAA0E;QAC1E,6EAA6E;QAC7E,2BAA2B;QAC3B,IAAI,QAAQ,GAAuB,EAAE,GAAG,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;gBACpD,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAChE,QAAQ,GAAG,aAAa;oBACtB,CAAC,CAAC;wBACE,GAAG,CAAC;wBACJ,SAAS,EAAE,aAAa;wBACxB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;qBACxC;oBACH,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACpC,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|