warp-os 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +327 -0
- package/LICENSE +21 -0
- package/README.md +308 -0
- package/VERSION +1 -0
- package/agents/warp-browse.md +715 -0
- package/agents/warp-build-code.md +1299 -0
- package/agents/warp-orchestrator.md +515 -0
- package/agents/warp-plan-architect.md +929 -0
- package/agents/warp-plan-brainstorm.md +876 -0
- package/agents/warp-plan-design.md +1458 -0
- package/agents/warp-plan-onboarding.md +732 -0
- package/agents/warp-plan-optimize-adversarial.md +81 -0
- package/agents/warp-plan-optimize.md +354 -0
- package/agents/warp-plan-scope.md +806 -0
- package/agents/warp-plan-security.md +1274 -0
- package/agents/warp-plan-testdesign.md +1228 -0
- package/agents/warp-qa-debug-adversarial.md +90 -0
- package/agents/warp-qa-debug.md +793 -0
- package/agents/warp-qa-test-adversarial.md +89 -0
- package/agents/warp-qa-test.md +1054 -0
- package/agents/warp-release-update.md +1189 -0
- package/agents/warp-setup.md +1216 -0
- package/agents/warp-upgrade.md +334 -0
- package/bin/cli.js +44 -0
- package/bin/hooks/_warp_html.sh +291 -0
- package/bin/hooks/_warp_json.sh +67 -0
- package/bin/hooks/consistency-check.sh +92 -0
- package/bin/hooks/identity-briefing.sh +89 -0
- package/bin/hooks/identity-foundation.sh +37 -0
- package/bin/install.js +343 -0
- package/dist/warp-browse/SKILL.md +727 -0
- package/dist/warp-build-code/SKILL.md +1316 -0
- package/dist/warp-orchestrator/SKILL.md +527 -0
- package/dist/warp-plan-architect/SKILL.md +943 -0
- package/dist/warp-plan-brainstorm/SKILL.md +890 -0
- package/dist/warp-plan-design/SKILL.md +1473 -0
- package/dist/warp-plan-onboarding/SKILL.md +742 -0
- package/dist/warp-plan-optimize/SKILL.md +364 -0
- package/dist/warp-plan-scope/SKILL.md +820 -0
- package/dist/warp-plan-security/SKILL.md +1286 -0
- package/dist/warp-plan-testdesign/SKILL.md +1244 -0
- package/dist/warp-qa-debug/SKILL.md +805 -0
- package/dist/warp-qa-test/SKILL.md +1070 -0
- package/dist/warp-release-update/SKILL.md +1211 -0
- package/dist/warp-setup/SKILL.md +1229 -0
- package/dist/warp-upgrade/SKILL.md +345 -0
- package/package.json +40 -0
- package/shared/project-hooks.json +32 -0
- package/shared/tier1-engineering-constitution.md +176 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: warp-upgrade
|
|
3
|
+
description: >-
|
|
4
|
+
One-command Warp upgrade from inside Claude Code. Pulls latest, rebuilds, reinstalls, shows changelog, detects migration requirements, and offers to re-run /warp-setup on the current project. No terminal switching needed.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
8
|
+
<!-- TIER 1 — Engineering Foundation. Generated by build.sh -->
|
|
9
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Warp Engineering Foundation
|
|
13
|
+
|
|
14
|
+
Universal principles for every agent in the Warp pipeline. Tier 1: highest authority.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Core Principles
|
|
19
|
+
|
|
20
|
+
**Clarity over cleverness.** Optimize for "I can understand this in six months."
|
|
21
|
+
|
|
22
|
+
**Explicit contracts between layers.** Modules communicate through defined interfaces. Swap persistence without touching the service layer.
|
|
23
|
+
|
|
24
|
+
**Every component earns its place.** No speculative code. If a feature isn't in the current or next phase, it doesn't exist in code.
|
|
25
|
+
|
|
26
|
+
**Fail loud, recover gracefully.** Never swallow errors silently. User-facing experience degrades gracefully — stale-data indicator, not a crash.
|
|
27
|
+
|
|
28
|
+
**Prefer reversible decisions.** When two approaches are equivalent, choose the one that can be undone.
|
|
29
|
+
|
|
30
|
+
**Security is structural.** Designed for the most restrictive phase, enforced from the earliest.
|
|
31
|
+
|
|
32
|
+
**AI is a tool, not an authority.** AI agents accelerate development but do not make architectural decisions autonomously. Every significant design decision is reviewed by the user before it ships.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Bias Classification
|
|
37
|
+
|
|
38
|
+
When the same AI system writes code, writes tests, and evaluates its own output, shared biases create blind spots.
|
|
39
|
+
|
|
40
|
+
| Level | Definition | Trust |
|
|
41
|
+
|-------|-----------|-------|
|
|
42
|
+
| **L1** | Deterministic. Binary pass/fail. Zero AI judgment. | Highest |
|
|
43
|
+
| **L2** | AI interpretation anchored to verifiable external source. | Medium |
|
|
44
|
+
| **L3** | AI evaluating AI. Both sides share training biases. | Lowest |
|
|
45
|
+
|
|
46
|
+
**L1 Imperative:** Every quality gate that CAN be L1 MUST be L1. L3 is the outer layer, never the only layer. When L1 is unavailable, use L2 (grounded in external docs). Fall back to L3 only when no external anchor exists.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Completeness
|
|
51
|
+
|
|
52
|
+
AI compresses implementation 10-100x. Always choose the complete option. Full coverage, hardened behavior, robust edge cases. The delta between "good enough" and "complete" is minutes, not days.
|
|
53
|
+
|
|
54
|
+
Never recommend the less-complete option. Never skip edge cases. Never defer what can be done now.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Quality Gates
|
|
59
|
+
|
|
60
|
+
**Hard Gate** — blocks progression. Between major phases. Present output, ask the user: A) Approve, B) Revise, C) Restart. MUST get user input.
|
|
61
|
+
|
|
62
|
+
**Soft Gate** — warns but allows. Between minor steps. Proceed if quality criteria met; warn and get input if not.
|
|
63
|
+
|
|
64
|
+
**Completeness Gate** — final check before artifact write. Verify no empty sections, key decisions explicit. Fix before writing.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Escalation
|
|
69
|
+
|
|
70
|
+
Always OK to stop and escalate. Bad work is worse than no work.
|
|
71
|
+
|
|
72
|
+
**STOP if:** 3 failed attempts at the same problem, uncertain about security-sensitive changes, scope exceeds what you can verify, or a decision requires domain knowledge you don't have.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## External Data Gate
|
|
77
|
+
|
|
78
|
+
When a task requires real-world data or domain knowledge that cannot be derived from code, docs, or git history — PAUSE and ask the user. Never hallucinate fixtures or APIs. Check docs via Context7 or saved files before writing code that touches external services.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Error Severity
|
|
83
|
+
|
|
84
|
+
| Tier | Definition | Response |
|
|
85
|
+
|------|-----------|----------|
|
|
86
|
+
| T1 | Normal variance (cache miss, retry succeeded) | Log, no action |
|
|
87
|
+
| T2 | Degraded capability (stale data served, fallback active) | Log, degrade visibly |
|
|
88
|
+
| T3 | Operation failed (invalid input, auth rejected) | Log, return error, continue |
|
|
89
|
+
| T4 | Subsystem non-functional (DB unreachable, corrupt state) | Log, halt subsystem, alert |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Universal Engineering Principles
|
|
94
|
+
|
|
95
|
+
- Assert outcomes, not implementation. Test "input produces output" — not "function X calls Y."
|
|
96
|
+
- Each test is independent. No shared state or execution order dependencies.
|
|
97
|
+
- Mock at the system boundary, not internal helpers.
|
|
98
|
+
- Expected values are hardcoded from the spec, never recalculated using production logic.
|
|
99
|
+
- Every bug fix ships with a regression test.
|
|
100
|
+
- Every error has two audiences: the system (full diagnostics) and the consumer (only actionable info). Never the same message.
|
|
101
|
+
- Errors change shape at every module boundary. No error propagates without translation.
|
|
102
|
+
- Errors never reveal system internals to consumers. No stack traces, file paths, or queries in responses.
|
|
103
|
+
- Graceful degradation: live data → cached → static fallback → feature unavailable.
|
|
104
|
+
- Every input is hostile until validated.
|
|
105
|
+
- Default deny. Any permission not explicitly granted is denied.
|
|
106
|
+
- Secrets never logged, never in error messages, never in responses, never committed.
|
|
107
|
+
- Dependencies flow downward only. Never import from a layer above.
|
|
108
|
+
- Each external service has exactly one integration module that owns its boundary.
|
|
109
|
+
- Data crosses boundaries as plain values. Never pass ORM instances or SDK types between layers.
|
|
110
|
+
- ASCII diagrams for data flow, state machines, and architecture. Use box-drawing characters (─│┌┐└┘├┤┬┴┼) and arrows (→←↑↓).
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Shell Execution
|
|
115
|
+
|
|
116
|
+
Shell commands use Unix syntax (Git Bash). Never use CMD (`dir`, `type`, `del`) or backslash paths in Bash tool calls. On Windows, use forward slashes, `ls`, `grep`, `rm`, `cat`.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## AskUserQuestion
|
|
121
|
+
|
|
122
|
+
**Contract:**
|
|
123
|
+
1. **Re-ground:** Project name, branch, current task. (1-2 sentences.)
|
|
124
|
+
2. **Simplify:** Plain English a smart 16-year-old could follow.
|
|
125
|
+
3. **Recommend:** Name the recommended option and why.
|
|
126
|
+
4. **Options:** Ordered by completeness descending.
|
|
127
|
+
5. **One decision per question.**
|
|
128
|
+
|
|
129
|
+
**When to ask (mandatory):**
|
|
130
|
+
1. Design/UX choice not resolved in artifacts
|
|
131
|
+
2. Trade-off with more than one viable option
|
|
132
|
+
3. Before writing to files outside .warp/
|
|
133
|
+
4. Deviating from architecture or design spec
|
|
134
|
+
5. Skipping or deferring an acceptance criterion
|
|
135
|
+
6. Before any destructive or irreversible action
|
|
136
|
+
7. Ambiguous or underspecified requirement
|
|
137
|
+
8. Choosing between competing library/tool options
|
|
138
|
+
|
|
139
|
+
**Completeness scores in labels (mandatory):**
|
|
140
|
+
Format: `"Option name — X/10 🟢"` (or 🟡 or 🔴). In the label, not the description.
|
|
141
|
+
Rate: 🟢 9-10 complete, 🟡 6-8 adequate, 🔴 1-5 shortcuts.
|
|
142
|
+
|
|
143
|
+
**Formatting:**
|
|
144
|
+
- *Italics* for emphasis, not **bold** (bold for headers only).
|
|
145
|
+
- After each answer: `✔ Decision {N} recorded [quicksave updated]`
|
|
146
|
+
- Previews under 8 lines. Full mockups go in conversation text before the question.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Scale Detection
|
|
151
|
+
|
|
152
|
+
- **Feature:** One capability/screen/endpoint. Lean phases, fewer questions.
|
|
153
|
+
- **Module:** A package or subsystem. Full depth, multiple concerns.
|
|
154
|
+
- **System:** Whole product or greenfield. Maximum depth, every edge case.
|
|
155
|
+
|
|
156
|
+
Detection: Single behavior change → feature. 3+ files → module. Cross-package → system.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Artifact I/O
|
|
161
|
+
|
|
162
|
+
Header: `<!-- Pipeline: {skill-name} | {date} | Scale: {scale} | Inputs: {prerequisites} -->`
|
|
163
|
+
|
|
164
|
+
Validation: all schema sections present, no empty sections, key decisions explicit.
|
|
165
|
+
Preview: show first 8-10 lines + total line count before writing.
|
|
166
|
+
HTML preview: use `_warp_html.sh` if available. Open in browser at hard gates only.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Completion Banner
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
174
|
+
WARP │ {skill-name} │ {STATUS}
|
|
175
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
176
|
+
Wrote: {artifact path(s)}
|
|
177
|
+
Decisions: {N} recorded
|
|
178
|
+
Next: /{next-skill}
|
|
179
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Status values: **DONE**, **DONE_WITH_CONCERNS** (list concerns), **BLOCKED** (state blocker + what was tried + next steps), **NEEDS_CONTEXT** (state exactly what's needed).
|
|
183
|
+
|
|
184
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
185
|
+
<!-- Skill-Specific Content. -->
|
|
186
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# Upgrade
|
|
190
|
+
|
|
191
|
+
Meta skill. Upgrades WarpOS from inside Claude Code — no terminal switching.
|
|
192
|
+
|
|
193
|
+
**The upgrade is ONE COMMAND.** Do not decompose into manual steps. The upgrade
|
|
194
|
+
script handles pull, build, install, auto-patch, changelog, and migration detection.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## STEP 1: Locate the WarpOS Repo
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
WARP_REPO=""
|
|
202
|
+
for candidate in \
|
|
203
|
+
"$(cat "$HOME/.warp/repo-path" 2>/dev/null)" \
|
|
204
|
+
"$(readlink -f ~/.claude/skills/warp-setup 2>/dev/null)/../../../.." \
|
|
205
|
+
"$(dirname "$(readlink -f ~/.warp/hooks/identity-briefing.sh 2>/dev/null)")/../.." \
|
|
206
|
+
"$HOME/Projects/warp" \
|
|
207
|
+
"$HOME/warp" \
|
|
208
|
+
; do
|
|
209
|
+
[ -z "$candidate" ] && continue
|
|
210
|
+
if [ -d "$candidate/.git" ] && [ -f "$candidate/VERSION" ] && [ -f "$candidate/build.sh" ]; then
|
|
211
|
+
WARP_REPO="$(cd "$candidate" && pwd)"
|
|
212
|
+
break
|
|
213
|
+
fi
|
|
214
|
+
done
|
|
215
|
+
echo "Warp repo: ${WARP_REPO:-NOT FOUND}"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
If not found, ask the user for the path.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## STEP 2: Run the Upgrade Script
|
|
223
|
+
|
|
224
|
+
**Run `bin/warp-upgrade.sh` as a single command. Do NOT decompose into manual steps.**
|
|
225
|
+
|
|
226
|
+
The script handles everything: fetch, version check, pull, build, install, auto-patch
|
|
227
|
+
project hooks, changelog display, migration detection, and restart recommendation.
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
cd "$WARP_REPO" && bash bin/warp-upgrade.sh
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**IMPORTANT — Timeout:** On Windows (Git Bash), build + install can take 2-4 minutes.
|
|
234
|
+
Use a Bash timeout of at least 300000ms (5 minutes). If the default timeout is shorter,
|
|
235
|
+
set it explicitly. A timed-out upgrade leaves a half-installed state.
|
|
236
|
+
|
|
237
|
+
**If the script succeeds:** Read its output, summarize what changed, and remind the user
|
|
238
|
+
to restart Claude Code.
|
|
239
|
+
|
|
240
|
+
**If the script fails:** Read the error output. Common failures:
|
|
241
|
+
- Network error on git pull → "Check your connection and try again"
|
|
242
|
+
- Build error → "build.sh failed — check the error above"
|
|
243
|
+
- Install error (Windows file locks) → "Close other Claude Code instances and retry"
|
|
244
|
+
- Git conflicts → "Your local Warp repo has changes. Run `git stash` first."
|
|
245
|
+
|
|
246
|
+
Only if the script itself is missing or broken should you fall back to manual steps.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## STEP 3: Verify Auto-Patch (if script completed)
|
|
251
|
+
|
|
252
|
+
The upgrade script auto-patches `.claude/settings.local.json` in the current project
|
|
253
|
+
directory with the latest hook config from `~/.warp/project-hooks.json`.
|
|
254
|
+
|
|
255
|
+
Verify the patch applied:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Check that settings.local.json references new hook names
|
|
259
|
+
grep -c 'identity-foundation\|identity-briefing\|consistency-check' .claude/settings.local.json 2>/dev/null && echo "hooks patched" || echo "hooks NOT patched"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
If NOT patched (script ran from a different directory, or no settings.local.json):
|
|
263
|
+
- If `settings.local.json` exists but has old hook names → patch it manually using
|
|
264
|
+
`~/.warp/project-hooks.json` as the source. Preserve `permissions` and `enabledMcpjsonServers`.
|
|
265
|
+
- If no `settings.local.json` → tell user to run `/warp-setup` (first-time setup, not upgrade).
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## FALLBACK: Manual Steps (only if warp-upgrade.sh is missing/broken)
|
|
270
|
+
|
|
271
|
+
If `bin/warp-upgrade.sh` does not exist or crashes on invocation, fall back to manual:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
cd "$WARP_REPO"
|
|
275
|
+
git fetch origin --quiet
|
|
276
|
+
git pull --rebase origin master
|
|
277
|
+
bash build.sh
|
|
278
|
+
bash install.sh
|
|
279
|
+
cat CHANGELOG.md | head -60
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Then manually patch project hooks:
|
|
283
|
+
```bash
|
|
284
|
+
# Read template and patch settings.local.json
|
|
285
|
+
python3 -c "
|
|
286
|
+
import json
|
|
287
|
+
t = json.load(open('$HOME/.warp/project-hooks.json'))
|
|
288
|
+
s = json.load(open('.claude/settings.local.json'))
|
|
289
|
+
s['agent'] = t['agent']
|
|
290
|
+
s['hooks'] = t['hooks']
|
|
291
|
+
json.dump(s, open('.claude/settings.local.json','w'), indent=2)
|
|
292
|
+
print('Patched.')
|
|
293
|
+
"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**This fallback exists for emergencies only.** The script is the primary path.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## OUTPUT FORMAT
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
304
|
+
WARP │ UPGRADE
|
|
305
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
306
|
+
Repo: {path}
|
|
307
|
+
Upgrade: v{old} → v{new}
|
|
308
|
+
|
|
309
|
+
{changelog excerpt — Added/Changed/Removed}
|
|
310
|
+
|
|
311
|
+
Hooks: auto-patched ✓
|
|
312
|
+
Restart: required (new hooks + skills)
|
|
313
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Always remind:** "Restart Claude Code to pick up the new skills and hooks."
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## MUST / MUST NOT
|
|
321
|
+
|
|
322
|
+
**MUST:**
|
|
323
|
+
- Run `bin/warp-upgrade.sh` as a single command (not decomposed steps)
|
|
324
|
+
- Use a 5-minute timeout for the upgrade script on Windows
|
|
325
|
+
- Verify hooks auto-patched after script completes
|
|
326
|
+
- Show changelog summary
|
|
327
|
+
- Remind user to restart Claude Code
|
|
328
|
+
|
|
329
|
+
**MUST NOT:**
|
|
330
|
+
- Decompose the upgrade into individual git/build/install commands when the script works
|
|
331
|
+
- Use default Bash timeout (2 minutes is too short on Windows)
|
|
332
|
+
- Proceed to install if build fails
|
|
333
|
+
- Require the user to re-run `/warp-setup` after a normal upgrade
|
|
334
|
+
- Force-push, reset, or destructively modify the Warp repo without consent
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// cli.js — Warp CLI entry point
|
|
3
|
+
// Usage: npx warp-os install | upgrade | version | uninstall
|
|
4
|
+
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
const command = process.argv[2];
|
|
9
|
+
|
|
10
|
+
if (!command || command === '--help' || command === '-h') {
|
|
11
|
+
console.log(`
|
|
12
|
+
warp-os — A development operating system for Claude Code
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
npx warp-os install Install Warp (skills, agents, hooks, claude-mem)
|
|
16
|
+
npx warp-os upgrade Upgrade to the latest version
|
|
17
|
+
npx warp-os uninstall Remove Warp from this machine
|
|
18
|
+
npx warp-os version Show installed version
|
|
19
|
+
npx warp-os doctor Check installation health
|
|
20
|
+
`);
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (command === 'version' || command === '--version' || command === '-v') {
|
|
25
|
+
const version = require('../package.json').version;
|
|
26
|
+
console.log(`warp-os v${version}`);
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (command === 'install' || command === 'upgrade') {
|
|
31
|
+
require('./install.js');
|
|
32
|
+
} else if (command === 'uninstall') {
|
|
33
|
+
console.log('Uninstall not yet implemented. Remove manually:');
|
|
34
|
+
console.log(' rm -rf ~/.claude/skills/warp-*');
|
|
35
|
+
console.log(' rm -rf ~/.claude/agents/warp-*.md');
|
|
36
|
+
console.log(' rm -rf ~/.warp/');
|
|
37
|
+
process.exit(0);
|
|
38
|
+
} else if (command === 'doctor') {
|
|
39
|
+
require('./install.js');
|
|
40
|
+
} else {
|
|
41
|
+
console.error(`Unknown command: ${command}`);
|
|
42
|
+
console.error('Run "npx warp-os --help" for usage.');
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# _warp_html.sh — Shared utility for markdown-to-HTML conversion
|
|
3
|
+
# Source this file in skills/hooks that need HTML preview generation.
|
|
4
|
+
# Provides:
|
|
5
|
+
# _warp_md_to_html "input.md" "artifact_name" "output.html"
|
|
6
|
+
# _warp_open_preview "file.html"
|
|
7
|
+
#
|
|
8
|
+
# Uses the warp streak CSS palette. Sanitizes HTML tags to prevent XSS (F-1).
|
|
9
|
+
# No external dependencies — pure bash + sed.
|
|
10
|
+
|
|
11
|
+
# Convert markdown to HTML with warp streak CSS
|
|
12
|
+
# Usage: _warp_md_to_html "input.md" "Artifact Name" "output.html"
|
|
13
|
+
_warp_md_to_html() {
|
|
14
|
+
local input="$1"
|
|
15
|
+
local artifact_name="$2"
|
|
16
|
+
local output="$3"
|
|
17
|
+
|
|
18
|
+
if [ ! -f "$input" ]; then
|
|
19
|
+
echo "[WARP WARNING] _warp_md_to_html: input file not found: $input" >&2
|
|
20
|
+
return 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Ensure output directory exists
|
|
24
|
+
mkdir -p "$(dirname "$output")" 2>/dev/null || true
|
|
25
|
+
|
|
26
|
+
# Convert markdown to HTML with state tracking for code blocks and comments
|
|
27
|
+
local body=""
|
|
28
|
+
local in_code=false
|
|
29
|
+
local in_comment=false
|
|
30
|
+
|
|
31
|
+
while IFS= read -r line || [ -n "$line" ]; do
|
|
32
|
+
# --- HTML comment handling: skip entirely ---
|
|
33
|
+
if [[ "$line" == *"<!--"* ]]; then
|
|
34
|
+
if [[ "$line" == *"-->"* ]]; then
|
|
35
|
+
continue # single-line comment — skip
|
|
36
|
+
fi
|
|
37
|
+
in_comment=true
|
|
38
|
+
continue
|
|
39
|
+
fi
|
|
40
|
+
if $in_comment; then
|
|
41
|
+
if [[ "$line" == *"-->"* ]]; then
|
|
42
|
+
in_comment=false
|
|
43
|
+
fi
|
|
44
|
+
continue
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# --- Fenced code blocks ---
|
|
48
|
+
if [[ "$line" =~ ^\`\`\` ]]; then
|
|
49
|
+
if $in_code; then
|
|
50
|
+
body+="</code></pre>"$'\n'
|
|
51
|
+
in_code=false
|
|
52
|
+
else
|
|
53
|
+
body+="<pre><code>"
|
|
54
|
+
in_code=true
|
|
55
|
+
fi
|
|
56
|
+
continue
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if $in_code; then
|
|
60
|
+
# Inside code block: escape HTML but preserve whitespace exactly
|
|
61
|
+
line="${line//&/&}"
|
|
62
|
+
line="${line//</<}"
|
|
63
|
+
line="${line//>/>}"
|
|
64
|
+
body+="$line"$'\n'
|
|
65
|
+
continue
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# --- Normal markdown conversion (outside code blocks) ---
|
|
69
|
+
# Escape HTML entities
|
|
70
|
+
line="${line//&/&}"
|
|
71
|
+
line="${line//</<}"
|
|
72
|
+
line="${line//>/>}"
|
|
73
|
+
|
|
74
|
+
# Headings
|
|
75
|
+
if [[ "$line" =~ ^###\ ]]; then
|
|
76
|
+
line="<h3>${line#\#\#\# }</h3>"
|
|
77
|
+
elif [[ "$line" =~ ^##\ ]]; then
|
|
78
|
+
line="<h2>${line#\#\# }</h2>"
|
|
79
|
+
elif [[ "$line" =~ ^#\ ]]; then
|
|
80
|
+
line="<h1>${line#\# }</h1>"
|
|
81
|
+
# Horizontal rule
|
|
82
|
+
elif [[ "$line" == "---" ]]; then
|
|
83
|
+
line="<hr>"
|
|
84
|
+
# List items
|
|
85
|
+
elif [[ "$line" =~ ^-\ ]]; then
|
|
86
|
+
line="<li>${line#- }</li>"
|
|
87
|
+
elif [[ "$line" =~ ^[0-9]+\.\ ]]; then
|
|
88
|
+
line="<li>${line#*. }</li>"
|
|
89
|
+
# Blank line
|
|
90
|
+
elif [[ -z "$line" ]]; then
|
|
91
|
+
line="<br>"
|
|
92
|
+
# Table rows (pipe-delimited)
|
|
93
|
+
elif [[ "$line" == *"|"* ]] && [[ "$line" =~ ^\|.*\|$ ]]; then
|
|
94
|
+
# Skip separator rows (|---|---|)
|
|
95
|
+
if [[ "$line" =~ ^[[:space:]]*\|[-[:space:]|]+\|[[:space:]]*$ ]]; then
|
|
96
|
+
continue
|
|
97
|
+
fi
|
|
98
|
+
local cells=""
|
|
99
|
+
local tag="td"
|
|
100
|
+
# Simple heuristic: if all cells are bold, use th
|
|
101
|
+
if [[ "$line" == *"**"* ]] && [[ $(echo "$line" | grep -o '\*\*' | wc -l) -ge 4 ]]; then
|
|
102
|
+
tag="th"
|
|
103
|
+
fi
|
|
104
|
+
IFS='|' read -ra PARTS <<< "$line"
|
|
105
|
+
for part in "${PARTS[@]}"; do
|
|
106
|
+
part=$(echo "$part" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
107
|
+
[ -z "$part" ] && continue
|
|
108
|
+
cells+="<$tag>$part</$tag>"
|
|
109
|
+
done
|
|
110
|
+
line="<tr>$cells</tr>"
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# Inline formatting (outside headings processing)
|
|
114
|
+
line=$(echo "$line" | sed 's/\*\*\([^*]*\)\*\*/<strong>\1<\/strong>/g')
|
|
115
|
+
line=$(echo "$line" | sed 's/\*\([^*]*\)\*/<em>\1<\/em>/g')
|
|
116
|
+
line=$(echo "$line" | sed 's/`\([^`]*\)`/<code>\1<\/code>/g')
|
|
117
|
+
|
|
118
|
+
body+="$line"$'\n'
|
|
119
|
+
done < "$input"
|
|
120
|
+
|
|
121
|
+
# Close unclosed code block
|
|
122
|
+
if $in_code; then
|
|
123
|
+
body+="</code></pre>"$'\n'
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
# Wrap consecutive <tr> rows in <table> tags
|
|
127
|
+
body=$(echo "$body" | awk '
|
|
128
|
+
/<tr>/ && !intable { print "<table>"; intable=1 }
|
|
129
|
+
!/<tr>/ && intable { print "</table>"; intable=0 }
|
|
130
|
+
{ print }
|
|
131
|
+
END { if (intable) print "</table>" }
|
|
132
|
+
')
|
|
133
|
+
|
|
134
|
+
# Write the full HTML file
|
|
135
|
+
cat > "$output" << HTMLEOF
|
|
136
|
+
<!DOCTYPE html>
|
|
137
|
+
<html lang="en">
|
|
138
|
+
<head>
|
|
139
|
+
<meta charset="utf-8">
|
|
140
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
141
|
+
<title>Warp │ ${artifact_name}</title>
|
|
142
|
+
<style>
|
|
143
|
+
:root {
|
|
144
|
+
--space-deep: #0d0d14;
|
|
145
|
+
--space-surface: #1a1528;
|
|
146
|
+
--uv-border: #2d2444;
|
|
147
|
+
--uv-glow: #6b5ce7;
|
|
148
|
+
--streak-primary: #e8e6f0;
|
|
149
|
+
--streak-bright: #f5f4f8;
|
|
150
|
+
--streak-dim: #a9a5b8;
|
|
151
|
+
--flare-cyan: #58e8ff;
|
|
152
|
+
--flare-magenta: #ff58e4;
|
|
153
|
+
--flare-amber: #ffc858;
|
|
154
|
+
--flare-red: #ff5878;
|
|
155
|
+
--flare-green: #58ff9e;
|
|
156
|
+
}
|
|
157
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
158
|
+
body {
|
|
159
|
+
font: 16px/1.8 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
160
|
+
background: var(--space-deep); color: var(--streak-primary);
|
|
161
|
+
max-width: 860px; margin: 0 auto; padding: 0 1.5rem 4rem;
|
|
162
|
+
/* Subtle radial glow from top center */
|
|
163
|
+
background-image: radial-gradient(ellipse 80% 50% at 50% -5%, rgba(107, 92, 231, 0.12) 0%, transparent 70%);
|
|
164
|
+
background-attachment: fixed;
|
|
165
|
+
}
|
|
166
|
+
/* Hero header — full-width gradient bar with glow */
|
|
167
|
+
.warp-header {
|
|
168
|
+
font: 700 0.8rem/1 'JetBrains Mono', 'Fira Code', monospace;
|
|
169
|
+
letter-spacing: 0.2em; text-transform: uppercase;
|
|
170
|
+
padding: 1.5rem 0;
|
|
171
|
+
margin: 0 -1.5rem 3rem;
|
|
172
|
+
padding-left: 1.5rem;
|
|
173
|
+
border-bottom: 2px solid transparent;
|
|
174
|
+
border-image: linear-gradient(90deg, var(--flare-cyan), var(--flare-magenta), var(--flare-amber), var(--flare-green), var(--flare-cyan)) 1;
|
|
175
|
+
background: linear-gradient(180deg, rgba(107, 92, 231, 0.08) 0%, transparent 100%);
|
|
176
|
+
color: var(--streak-dim);
|
|
177
|
+
}
|
|
178
|
+
.warp-header span {
|
|
179
|
+
background: linear-gradient(90deg, var(--flare-cyan), var(--flare-magenta), var(--flare-amber), var(--flare-green));
|
|
180
|
+
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
|
181
|
+
background-clip: text;
|
|
182
|
+
}
|
|
183
|
+
/* H1 — large with rainbow underline accent */
|
|
184
|
+
h1 {
|
|
185
|
+
color: var(--streak-bright); font-size: 1.6rem; font-weight: 700;
|
|
186
|
+
margin: 2.5rem 0 1.2rem; padding-bottom: 0.6rem;
|
|
187
|
+
border-bottom: 2px solid transparent;
|
|
188
|
+
border-image: linear-gradient(90deg, var(--flare-cyan), var(--flare-magenta), transparent 80%) 1;
|
|
189
|
+
}
|
|
190
|
+
/* H2 — section cards */
|
|
191
|
+
h2 {
|
|
192
|
+
color: var(--streak-bright); font-size: 1.15rem; font-weight: 600;
|
|
193
|
+
margin: 2.5rem -1rem 1rem; padding: 0.7rem 1rem;
|
|
194
|
+
background: linear-gradient(135deg, rgba(107, 92, 231, 0.1) 0%, rgba(26, 21, 40, 0.6) 100%);
|
|
195
|
+
border-left: 3px solid var(--uv-glow);
|
|
196
|
+
border-radius: 0 8px 8px 0;
|
|
197
|
+
}
|
|
198
|
+
h3 {
|
|
199
|
+
color: var(--streak-bright); font-size: 1rem; font-weight: 600;
|
|
200
|
+
margin: 1.8rem 0 0.5rem; padding-left: 0.8rem;
|
|
201
|
+
border-left: 2px solid var(--uv-glow);
|
|
202
|
+
}
|
|
203
|
+
p { margin: 0.7rem 0; }
|
|
204
|
+
a { color: var(--flare-cyan); text-decoration: none; border-bottom: 1px solid rgba(88, 232, 255, 0.3);
|
|
205
|
+
transition: border-color 0.2s; }
|
|
206
|
+
a:hover { border-bottom-color: var(--flare-cyan); }
|
|
207
|
+
strong { color: var(--streak-bright); }
|
|
208
|
+
em { color: var(--streak-dim); font-style: italic; }
|
|
209
|
+
/* Inline code — pill with glow */
|
|
210
|
+
code {
|
|
211
|
+
font-family: 'JetBrains Mono', 'Fira Code', monospace;
|
|
212
|
+
background: rgba(107, 92, 231, 0.1); padding: 2px 8px; border-radius: 4px;
|
|
213
|
+
font-size: 0.86em; border: 1px solid rgba(107, 92, 231, 0.25);
|
|
214
|
+
color: var(--streak-bright);
|
|
215
|
+
}
|
|
216
|
+
/* Code blocks — elevated card with UV border glow */
|
|
217
|
+
pre {
|
|
218
|
+
background: linear-gradient(180deg, var(--space-surface) 0%, rgba(13, 13, 20, 0.95) 100%);
|
|
219
|
+
padding: 1.4rem 1.6rem; border-radius: 10px;
|
|
220
|
+
border: 1px solid var(--uv-border); overflow-x: auto; margin: 1.4rem 0;
|
|
221
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 1px rgba(107, 92, 231, 0.3);
|
|
222
|
+
position: relative;
|
|
223
|
+
}
|
|
224
|
+
pre::before {
|
|
225
|
+
content: ''; position: absolute; top: -1px; left: 20%; right: 20%; height: 1px;
|
|
226
|
+
background: linear-gradient(90deg, transparent, var(--uv-glow), transparent);
|
|
227
|
+
}
|
|
228
|
+
pre code { background: none; padding: 0; font-size: 0.84em; line-height: 1.6;
|
|
229
|
+
border: none; color: var(--streak-primary); }
|
|
230
|
+
/* Tables — frosted glass effect */
|
|
231
|
+
table {
|
|
232
|
+
border-collapse: separate; border-spacing: 0; width: 100%; margin: 1.4rem 0;
|
|
233
|
+
font-size: 0.92em; border-radius: 8px; overflow: hidden;
|
|
234
|
+
border: 1px solid var(--uv-border);
|
|
235
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
|
236
|
+
}
|
|
237
|
+
th, td { border-bottom: 1px solid var(--uv-border); padding: 0.6rem 0.85rem; text-align: left; }
|
|
238
|
+
td { border-right: 1px solid rgba(45, 36, 68, 0.5); }
|
|
239
|
+
td:last-child { border-right: none; }
|
|
240
|
+
th {
|
|
241
|
+
background: rgba(107, 92, 231, 0.12);
|
|
242
|
+
color: var(--streak-bright); font-weight: 600; font-size: 0.8em;
|
|
243
|
+
text-transform: uppercase; letter-spacing: 0.06em;
|
|
244
|
+
border-bottom: 2px solid var(--uv-border);
|
|
245
|
+
}
|
|
246
|
+
tr:last-child td { border-bottom: none; }
|
|
247
|
+
tr:hover td { background: rgba(107, 92, 231, 0.06); transition: background 0.15s; }
|
|
248
|
+
blockquote {
|
|
249
|
+
border-left: 3px solid var(--uv-glow); padding: 0.8rem 1.2rem;
|
|
250
|
+
color: var(--streak-dim); margin: 1.2rem 0;
|
|
251
|
+
background: rgba(107, 92, 231, 0.04); border-radius: 0 8px 8px 0;
|
|
252
|
+
}
|
|
253
|
+
li { margin: 0.35rem 0; margin-left: 1.5rem; }
|
|
254
|
+
li::marker { color: var(--uv-glow); }
|
|
255
|
+
/* HR — rainbow streak */
|
|
256
|
+
hr {
|
|
257
|
+
border: none; height: 1px; margin: 3rem 0;
|
|
258
|
+
background: linear-gradient(90deg, transparent 5%, var(--flare-cyan) 20%, var(--flare-magenta) 50%, var(--flare-amber) 80%, transparent 95%);
|
|
259
|
+
opacity: 0.4;
|
|
260
|
+
}
|
|
261
|
+
/* Scrollbar */
|
|
262
|
+
::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
263
|
+
::-webkit-scrollbar-track { background: var(--space-deep); }
|
|
264
|
+
::-webkit-scrollbar-thumb { background: var(--uv-border); border-radius: 3px; }
|
|
265
|
+
::-webkit-scrollbar-thumb:hover { background: var(--uv-glow); }
|
|
266
|
+
</style>
|
|
267
|
+
</head>
|
|
268
|
+
<body>
|
|
269
|
+
<div class="warp-header"><span>Warp</span> │ ${artifact_name}</div>
|
|
270
|
+
${body}
|
|
271
|
+
</body>
|
|
272
|
+
</html>
|
|
273
|
+
HTMLEOF
|
|
274
|
+
|
|
275
|
+
# Set restrictive permissions (security.md recommendation)
|
|
276
|
+
chmod 600 "$output" 2>/dev/null || true
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
# Open a file in the user's default browser (cross-platform)
|
|
280
|
+
# Usage: _warp_open_preview "file.html"
|
|
281
|
+
_warp_open_preview() {
|
|
282
|
+
local file="$1"
|
|
283
|
+
if [ ! -f "$file" ]; then
|
|
284
|
+
return 0
|
|
285
|
+
fi
|
|
286
|
+
case "$(uname -s)" in
|
|
287
|
+
MINGW*|MSYS*|CYGWIN*) start "" "$file" 2>/dev/null || true ;;
|
|
288
|
+
Darwin) open "$file" 2>/dev/null || true ;;
|
|
289
|
+
*) xdg-open "$file" 2>/dev/null || true ;;
|
|
290
|
+
esac
|
|
291
|
+
}
|