viepilot 1.14.0 → 2.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 +98 -0
- package/README.md +3 -3
- package/bin/viepilot.cjs +7 -5
- package/bin/vp-tools.cjs +193 -0
- package/dev-install.sh +34 -13
- package/docs/user/features/hooks.md +93 -0
- package/lib/adapters/claude-code.cjs +42 -0
- package/lib/adapters/cursor.cjs +31 -0
- package/lib/adapters/index.cjs +26 -0
- package/lib/hooks/brainstorm-staleness.cjs +231 -0
- package/lib/viepilot-config.cjs +103 -0
- package/lib/viepilot-install.cjs +128 -153
- package/package.json +1 -1
- package/skills/vp-audit/SKILL.md +21 -21
- package/skills/vp-auto/SKILL.md +21 -7
- package/skills/vp-brainstorm/SKILL.md +42 -36
- package/skills/vp-crystallize/SKILL.md +22 -16
- package/skills/vp-debug/SKILL.md +2 -2
- package/skills/vp-docs/SKILL.md +7 -7
- package/skills/vp-evolve/SKILL.md +25 -12
- package/skills/vp-info/SKILL.md +23 -23
- package/skills/vp-pause/SKILL.md +5 -5
- package/skills/vp-request/SKILL.md +12 -12
- package/skills/vp-resume/SKILL.md +4 -4
- package/skills/vp-rollback/SKILL.md +3 -3
- package/skills/vp-status/SKILL.md +4 -4
- package/skills/vp-task/SKILL.md +2 -2
- package/skills/vp-ui-components/SKILL.md +12 -12
- package/skills/vp-update/SKILL.md +17 -17
- package/templates/architect/apis.html +11 -10
- package/templates/architect/architect-actions.js +217 -0
- package/templates/architect/architecture.html +8 -7
- package/templates/architect/data-flow.html +5 -4
- package/templates/architect/decisions.html +4 -3
- package/templates/architect/deployment.html +10 -9
- package/templates/architect/erd.html +7 -6
- package/templates/architect/feature-map.html +5 -4
- package/templates/architect/sequence-diagram.html +6 -5
- package/templates/architect/style.css +146 -0
- package/templates/architect/tech-notes.html +3 -2
- package/templates/architect/tech-stack.html +8 -7
- package/templates/architect/user-use-cases.html +8 -7
- package/templates/project/AI-GUIDE.md +49 -49
- package/workflows/audit.md +3 -3
- package/workflows/autonomous.md +38 -5
- package/workflows/brainstorm.md +398 -222
- package/workflows/crystallize.md +46 -33
- package/workflows/debug.md +9 -9
- package/workflows/documentation.md +5 -5
- package/workflows/evolve.md +44 -12
- package/workflows/pause-work.md +2 -2
- package/workflows/request.md +8 -8
- package/workflows/resume-work.md +1 -1
- package/workflows/rollback.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vp-resume
|
|
3
|
-
description: "Resume work
|
|
3
|
+
description: "Resume work from previous session with full context restoration"
|
|
4
4
|
version: 0.1.1
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ version: 0.1.1
|
|
|
10
10
|
- Treat all user text after the skill mention as `{{VP_ARGS}}`
|
|
11
11
|
|
|
12
12
|
## B. User Prompting
|
|
13
|
-
Prompt user conversationally
|
|
13
|
+
Prompt user conversationally with options.
|
|
14
14
|
|
|
15
15
|
## C. Tool Usage
|
|
16
16
|
Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`, `WebFetch`, `Subagent`
|
|
@@ -25,12 +25,12 @@ Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`,
|
|
|
25
25
|
<implementation_routing_guard>
|
|
26
26
|
## Implementation routing guard (ENH-021)
|
|
27
27
|
|
|
28
|
-
- **
|
|
28
|
+
- **Restore context** — does not implement default shipping; continue with **`/vp-auto`** when a task plan exists. See `workflows/request.md`.
|
|
29
29
|
</implementation_routing_guard>
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<objective>
|
|
33
|
-
Restore complete project context
|
|
33
|
+
Restore complete project context and resume work seamlessly.
|
|
34
34
|
|
|
35
35
|
**Reads:**
|
|
36
36
|
- `.viepilot/HANDOFF.json`
|
|
@@ -25,14 +25,14 @@ Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`,
|
|
|
25
25
|
<implementation_routing_guard>
|
|
26
26
|
## Implementation routing guard (ENH-021)
|
|
27
27
|
|
|
28
|
-
- **Checkpoint / revert** —
|
|
28
|
+
- **Checkpoint / revert** — does not replace **`/vp-auto`** for new work; after rollback use **`/vp-evolve`** / **`/vp-auto`** per workflow. See `workflows/request.md`.
|
|
29
29
|
</implementation_routing_guard>
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<objective>
|
|
33
|
-
Rollback
|
|
33
|
+
Rollback to any checkpoint safely, with backup and state preservation.
|
|
34
34
|
|
|
35
|
-
**Checkpoints:** Git tags
|
|
35
|
+
**Checkpoints:** Git tags with prefix `vp-`
|
|
36
36
|
- `vp-p{N}-t{M}` - Start of task M in phase N
|
|
37
37
|
- `vp-p{N}-t{M}-done` - Task M complete
|
|
38
38
|
- `vp-p{N}-complete` - Phase N complete
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vp-status
|
|
3
|
-
description: "
|
|
3
|
+
description: "Display progress dashboard and actionable insights"
|
|
4
4
|
version: 0.1.1
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -22,12 +22,12 @@ Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`,
|
|
|
22
22
|
<implementation_routing_guard>
|
|
23
23
|
## Implementation routing guard (ENH-021)
|
|
24
24
|
|
|
25
|
-
- **Read-only / dashboard** —
|
|
25
|
+
- **Read-only / dashboard** — does not implement shipping; **`/vp-evolve`** → **`/vp-auto`**. See `workflows/request.md`.
|
|
26
26
|
</implementation_routing_guard>
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
<objective>
|
|
30
|
-
|
|
30
|
+
Display a visual progress dashboard with actionable insights.
|
|
31
31
|
|
|
32
32
|
**Reads:**
|
|
33
33
|
- `.viepilot/TRACKER.md`
|
|
@@ -35,7 +35,7 @@ Hiển thị visual progress dashboard với actionable insights.
|
|
|
35
35
|
- `.viepilot/phases/*/PHASE-STATE.md`
|
|
36
36
|
- `CHANGELOG.md`
|
|
37
37
|
|
|
38
|
-
**Output:** Dashboard display
|
|
38
|
+
**Output:** Dashboard display with next action suggestions.
|
|
39
39
|
</objective>
|
|
40
40
|
|
|
41
41
|
<process>
|
package/skills/vp-task/SKILL.md
CHANGED
|
@@ -22,12 +22,12 @@ Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`,
|
|
|
22
22
|
<implementation_routing_guard>
|
|
23
23
|
## Implementation routing guard (ENH-021)
|
|
24
24
|
|
|
25
|
-
-
|
|
25
|
+
- This skill **only** manages **state/tag/task** in `.viepilot/` — does **not** replace **`/vp-auto`** for implementing shipping code. To implement: use **`/vp-auto`** or user **explicit** override. Plan chain: **`/vp-evolve`** first. See `workflows/request.md`.
|
|
26
26
|
</implementation_routing_guard>
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
<objective>
|
|
30
|
-
Manual control over tasks
|
|
30
|
+
Manual control over tasks when fine-grained management is needed.
|
|
31
31
|
|
|
32
32
|
**Commands:**
|
|
33
33
|
- `list` - List tasks in current phase
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vp-ui-components
|
|
3
|
-
description: "
|
|
3
|
+
description: "Manage workflow for collecting and reusing UI components"
|
|
4
4
|
version: 0.1.1
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ version: 0.1.1
|
|
|
10
10
|
- Treat all user text after the skill mention as `{{VP_ARGS}}`
|
|
11
11
|
|
|
12
12
|
## B. User Prompting
|
|
13
|
-
Prompt user conversationally
|
|
13
|
+
Prompt user conversationally with numbered list options.
|
|
14
14
|
|
|
15
15
|
## C. Tool Usage
|
|
16
16
|
Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`, `WebFetch`, `Subagent`
|
|
@@ -25,23 +25,23 @@ Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`,
|
|
|
25
25
|
<implementation_routing_guard>
|
|
26
26
|
## Implementation routing guard (ENH-021)
|
|
27
27
|
|
|
28
|
-
- **Curation** `ui-components/` + metadata —
|
|
28
|
+
- **Curation** `ui-components/` + metadata — does not implement full app feature / default framework shipping; large changes go through **`/vp-evolve`** → **`/vp-auto`**. See `workflows/request.md`.
|
|
29
29
|
</implementation_routing_guard>
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<objective>
|
|
33
|
-
|
|
33
|
+
Collect, classify, and store UI components for reuse:
|
|
34
34
|
- Global library: `~/.viepilot/ui-components/`
|
|
35
35
|
- Project library: `.viepilot/ui-components/`
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Sources can come from prompt/link/snippet (especially 21st.dev), then normalized into artifacts with metadata.
|
|
38
38
|
|
|
39
39
|
**Creates/Updates:**
|
|
40
40
|
- `~/.viepilot/ui-components/{category}/{component-id}/...`
|
|
41
41
|
- `.viepilot/ui-components/{category}/{component-id}/...`
|
|
42
|
-
- `INDEX.md`
|
|
42
|
+
- `INDEX.md` for global + local store
|
|
43
43
|
|
|
44
|
-
**After:** Component
|
|
44
|
+
**After:** Component is reusable for `/vp-brainstorm --ui` and `/vp-crystallize`.
|
|
45
45
|
</objective>
|
|
46
46
|
|
|
47
47
|
<execution_context>
|
|
@@ -50,11 +50,11 @@ Nguồn có thể đến từ prompt/link/snippet (đặc biệt 21st.dev), sau
|
|
|
50
50
|
|
|
51
51
|
<context>
|
|
52
52
|
Optional flags:
|
|
53
|
-
- `--add` : Add/capture component
|
|
54
|
-
- `--list` :
|
|
55
|
-
- `--sync` :
|
|
56
|
-
- `--from-21st` :
|
|
57
|
-
- `--approve` : Mark component status
|
|
53
|
+
- `--add` : Add/capture new component
|
|
54
|
+
- `--list` : List components by category
|
|
55
|
+
- `--sync` : Sync global ↔ local index
|
|
56
|
+
- `--from-21st` : Prioritize ingest flow from 21st.dev references
|
|
57
|
+
- `--approve` : Mark component status as approved
|
|
58
58
|
</context>
|
|
59
59
|
|
|
60
60
|
<process>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vp-update
|
|
3
|
-
description: "
|
|
3
|
+
description: "Upgrade viepilot package via npm (dry-run, --yes, --global) via vp-tools"
|
|
4
4
|
version: 0.1.1
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -22,18 +22,18 @@ Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`,
|
|
|
22
22
|
<implementation_routing_guard>
|
|
23
23
|
## Implementation routing guard (ENH-021)
|
|
24
24
|
|
|
25
|
-
- **
|
|
25
|
+
- **Upgrade ViePilot package** (npm) — does not implement product features in the working repo by default; feature code goes through **`/vp-auto`**. See `workflows/request.md`.
|
|
26
26
|
</implementation_routing_guard>
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
<objective>
|
|
30
|
-
|
|
30
|
+
Run **`vp-tools update`** to plan and (when confirmed) execute the `npm` upgrade of `viepilot`.
|
|
31
31
|
|
|
32
|
-
**
|
|
33
|
-
- **Non-interactive** (CI, agent
|
|
34
|
-
-
|
|
32
|
+
**Safety constraints:**
|
|
33
|
+
- **Non-interactive** (CI, agent without TTY): **`--dry-run`** or **`--yes`** is required; otherwise exits with an error.
|
|
34
|
+
- Always prefer **`--dry-run`** before applying, unless the user has explicitly requested to apply.
|
|
35
35
|
|
|
36
|
-
**
|
|
36
|
+
**Target distinction:** in a repo that is **not** ViePilot but has `node_modules/viepilot`, the command may update the **local dependency**. To upgrade only the **global** install, add **`--global`**.
|
|
37
37
|
</objective>
|
|
38
38
|
|
|
39
39
|
<execution_context>
|
|
@@ -42,31 +42,31 @@ Chạy **`vp-tools update`** để lên kế hoạch và (khi được xác nh
|
|
|
42
42
|
|
|
43
43
|
<process>
|
|
44
44
|
|
|
45
|
-
### Step 1: Dry run (
|
|
45
|
+
### Step 1: Dry run (default when automated)
|
|
46
46
|
```bash
|
|
47
47
|
vp-tools update --dry-run
|
|
48
48
|
```
|
|
49
|
-
|
|
49
|
+
Read output: planned npm command, current version vs latest, ambiguous/global warnings.
|
|
50
50
|
|
|
51
|
-
### Step 2: Apply (
|
|
51
|
+
### Step 2: Apply (after user confirms or explicitly requests it)
|
|
52
52
|
```bash
|
|
53
53
|
vp-tools update --yes
|
|
54
54
|
```
|
|
55
|
-
|
|
55
|
+
Or force global:
|
|
56
56
|
```bash
|
|
57
57
|
vp-tools update --global --dry-run
|
|
58
58
|
vp-tools update --global --yes
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
### Step 3: Interactive
|
|
62
|
-
|
|
62
|
+
If the terminal is interactive and **no** `--yes` flag is present, the CLI may prompt for confirmation before running npm.
|
|
63
63
|
|
|
64
|
-
### Step 4:
|
|
65
|
-
|
|
64
|
+
### Step 4: Suggested rollback
|
|
65
|
+
Dry-run/update output typically suggests `npm install -g viepilot@<previous>` — keep the previous version from `vp-tools info` in case a rollback is needed.
|
|
66
66
|
</process>
|
|
67
67
|
|
|
68
68
|
<success_criteria>
|
|
69
|
-
- [ ]
|
|
70
|
-
- [ ]
|
|
71
|
-
- [ ]
|
|
69
|
+
- [ ] Do not run apply in non-interactive mode without `--yes`
|
|
70
|
+
- [ ] Clearly state target (local vs global) when user is in an external project
|
|
71
|
+
- [ ] Acknowledge when `already up to date` (successful no-op)
|
|
72
72
|
</success_criteria>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>APIs — {project}</title>
|
|
7
7
|
<link rel="stylesheet" href="style.css" />
|
|
8
8
|
</head>
|
|
9
|
-
<body>
|
|
9
|
+
<body data-arch-slug="apis">
|
|
10
10
|
<nav class="nav-sidebar">
|
|
11
11
|
<div class="logo">
|
|
12
12
|
<span>ViePilot Architect Mode</span>
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
</tr>
|
|
53
53
|
</thead>
|
|
54
54
|
<tbody>
|
|
55
|
-
<tr>
|
|
55
|
+
<tr data-arch-id="A1">
|
|
56
56
|
<td><span class="badge method-get">GET</span></td>
|
|
57
57
|
<td>/api/resource</td>
|
|
58
58
|
<td>Yes</td>
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
<td>200, 401, 500</td>
|
|
62
62
|
<td>{Notes}</td>
|
|
63
63
|
</tr>
|
|
64
|
-
<tr>
|
|
64
|
+
<tr data-arch-id="A2">
|
|
65
65
|
<td><span class="badge method-post">POST</span></td>
|
|
66
66
|
<td>/api/resource</td>
|
|
67
67
|
<td>Yes</td>
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
<td>201, 400, 401</td>
|
|
71
71
|
<td>{Notes}</td>
|
|
72
72
|
</tr>
|
|
73
|
-
<tr>
|
|
73
|
+
<tr data-arch-id="A3">
|
|
74
74
|
<td><span class="badge method-put">PUT</span></td>
|
|
75
75
|
<td>/api/resource/:id</td>
|
|
76
76
|
<td>Yes</td>
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
<td>200, 400, 404</td>
|
|
80
80
|
<td>{Notes}</td>
|
|
81
81
|
</tr>
|
|
82
|
-
<tr>
|
|
82
|
+
<tr data-arch-id="A4">
|
|
83
83
|
<td><span class="badge method-delete">DELETE</span></td>
|
|
84
84
|
<td>/api/resource/:id</td>
|
|
85
85
|
<td>Yes</td>
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
<td>200, 404</td>
|
|
89
89
|
<td>{Notes}</td>
|
|
90
90
|
</tr>
|
|
91
|
-
<tr>
|
|
91
|
+
<tr data-arch-id="A5">
|
|
92
92
|
<td><span class="badge method-patch">PATCH</span></td>
|
|
93
93
|
<td>/api/resource/:id</td>
|
|
94
94
|
<td>Yes</td>
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
</tr>
|
|
114
114
|
</thead>
|
|
115
115
|
<tbody>
|
|
116
|
-
<tr>
|
|
116
|
+
<tr data-arch-id="A6">
|
|
117
117
|
<td>API Style</td>
|
|
118
118
|
<td>
|
|
119
119
|
<span class="badge method-get">REST</span>
|
|
@@ -124,19 +124,19 @@
|
|
|
124
124
|
<td>{Rationale}</td>
|
|
125
125
|
<td>{Notes}</td>
|
|
126
126
|
</tr>
|
|
127
|
-
<tr>
|
|
127
|
+
<tr data-arch-id="A7">
|
|
128
128
|
<td>Authentication</td>
|
|
129
129
|
<td>{JWT / Session / OAuth2 / API Key}</td>
|
|
130
130
|
<td>{Rationale}</td>
|
|
131
131
|
<td>{Notes}</td>
|
|
132
132
|
</tr>
|
|
133
|
-
<tr>
|
|
133
|
+
<tr data-arch-id="A8">
|
|
134
134
|
<td>Versioning</td>
|
|
135
135
|
<td>{URL path / Header / None}</td>
|
|
136
136
|
<td>{Rationale}</td>
|
|
137
137
|
<td>{Notes}</td>
|
|
138
138
|
</tr>
|
|
139
|
-
<tr>
|
|
139
|
+
<tr data-arch-id="A9">
|
|
140
140
|
<td>Rate limiting</td>
|
|
141
141
|
<td>{Strategy}</td>
|
|
142
142
|
<td>{Rationale}</td>
|
|
@@ -154,5 +154,6 @@
|
|
|
154
154
|
document.getElementById('theme-toggle').textContent = isLight ? '🌙 Dark' : '☀️ Light';
|
|
155
155
|
}
|
|
156
156
|
</script>
|
|
157
|
+
<script src="architect-actions.js"></script>
|
|
157
158
|
</body>
|
|
158
159
|
</html>
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ViePilot Architect Item Actions (ENH-033)
|
|
3
|
+
*
|
|
4
|
+
* Injects per-item Approve / Edit prompt-copy buttons into every element
|
|
5
|
+
* marked with [data-arch-id] in the Architect HTML workspace.
|
|
6
|
+
*
|
|
7
|
+
* ISOLATION RULE: Each action is scoped exclusively to the identified item
|
|
8
|
+
* on the identified page. Approving one item does NOT imply approval of any
|
|
9
|
+
* related item on any other page. Cross-page updates require separate prompts.
|
|
10
|
+
*
|
|
11
|
+
* Prompt formats:
|
|
12
|
+
* APPROVE: [ARCH:{slug}:{id}] APPROVE — "{title}" on {slug} page. No changes needed.
|
|
13
|
+
* EDIT: [ARCH:{slug}:{id}] EDIT — "{title}" on {slug} page. Current: "{excerpt}". What should I change?
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
(function () {
|
|
17
|
+
'use strict';
|
|
18
|
+
|
|
19
|
+
// ── Prompt templates ──────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
function approvePrompt(slug, id, title) {
|
|
22
|
+
return '[ARCH:' + slug + ':' + id + '] APPROVE — "' + title + '" on ' + slug + ' page. No changes needed.';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function editPrompt(slug, id, title, excerpt) {
|
|
26
|
+
var body = excerpt ? ' Current: "' + excerpt + '".' : '';
|
|
27
|
+
return '[ARCH:' + slug + ':' + id + '] EDIT — "' + title + '" on ' + slug + ' page.' + body + ' What should I change?';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ── Clipboard helper ─────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
function copyText(text, btn) {
|
|
33
|
+
var original = btn.textContent;
|
|
34
|
+
function onDone() {
|
|
35
|
+
btn.textContent = 'Copied!';
|
|
36
|
+
btn.classList.add('copied');
|
|
37
|
+
setTimeout(function () {
|
|
38
|
+
btn.textContent = original;
|
|
39
|
+
btn.classList.remove('copied');
|
|
40
|
+
}, 1500);
|
|
41
|
+
}
|
|
42
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
43
|
+
navigator.clipboard.writeText(text).then(onDone).catch(function () {
|
|
44
|
+
legacyCopy(text);
|
|
45
|
+
onDone();
|
|
46
|
+
});
|
|
47
|
+
} else {
|
|
48
|
+
legacyCopy(text);
|
|
49
|
+
onDone();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function legacyCopy(text) {
|
|
54
|
+
var ta = document.createElement('textarea');
|
|
55
|
+
ta.value = text;
|
|
56
|
+
ta.style.cssText = 'position:fixed;top:0;left:0;opacity:0;pointer-events:none;';
|
|
57
|
+
document.body.appendChild(ta);
|
|
58
|
+
ta.focus();
|
|
59
|
+
ta.select();
|
|
60
|
+
try { document.execCommand('copy'); } catch (e) { /* silent */ }
|
|
61
|
+
document.body.removeChild(ta);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ── Text extraction ───────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
function getTitle(el) {
|
|
67
|
+
if (el.dataset.archTitle) return el.dataset.archTitle.trim().slice(0, 80);
|
|
68
|
+
// Table row: first <td>
|
|
69
|
+
if (el.tagName === 'TR') {
|
|
70
|
+
var td = el.querySelector('td');
|
|
71
|
+
if (td) return td.textContent.trim().slice(0, 80);
|
|
72
|
+
}
|
|
73
|
+
// Card/div: heading
|
|
74
|
+
var h = el.querySelector('h2,h3,h4,h5');
|
|
75
|
+
if (h) return h.textContent.trim().slice(0, 80);
|
|
76
|
+
return el.textContent.trim().slice(0, 80);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function getExcerpt(el) {
|
|
80
|
+
if (el.dataset.archExcerpt) return el.dataset.archExcerpt.trim().slice(0, 100);
|
|
81
|
+
// Table row: second <td>
|
|
82
|
+
if (el.tagName === 'TR') {
|
|
83
|
+
var tds = el.querySelectorAll('td');
|
|
84
|
+
if (tds.length >= 2) return tds[1].textContent.trim().slice(0, 100);
|
|
85
|
+
}
|
|
86
|
+
// Card/div: first <p>
|
|
87
|
+
var p = el.querySelector('p');
|
|
88
|
+
if (p) return p.textContent.trim().slice(0, 100);
|
|
89
|
+
return '';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ── Build actions DOM ─────────────────────────────────────────────────────
|
|
93
|
+
|
|
94
|
+
function makeActionsEl(slug, id, title, excerpt) {
|
|
95
|
+
var wrap = document.createElement('div');
|
|
96
|
+
wrap.className = 'arch-item-actions';
|
|
97
|
+
|
|
98
|
+
var badge = document.createElement('span');
|
|
99
|
+
badge.className = 'arch-id-badge';
|
|
100
|
+
badge.textContent = id;
|
|
101
|
+
badge.title = 'Item ID: [ARCH:' + slug + ':' + id + ']';
|
|
102
|
+
|
|
103
|
+
var btnApprove = document.createElement('button');
|
|
104
|
+
btnApprove.className = 'arch-btn arch-btn-approve';
|
|
105
|
+
btnApprove.textContent = '✅ Approve';
|
|
106
|
+
btnApprove.title = 'Copy APPROVE prompt — scoped to this item only';
|
|
107
|
+
btnApprove.type = 'button';
|
|
108
|
+
btnApprove.addEventListener('click', function (e) {
|
|
109
|
+
e.stopPropagation();
|
|
110
|
+
copyText(approvePrompt(slug, id, title), btnApprove);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
var btnEdit = document.createElement('button');
|
|
114
|
+
btnEdit.className = 'arch-btn arch-btn-edit';
|
|
115
|
+
btnEdit.textContent = '✏️ Edit';
|
|
116
|
+
btnEdit.title = 'Copy EDIT prompt — scoped to this item only';
|
|
117
|
+
btnEdit.type = 'button';
|
|
118
|
+
btnEdit.addEventListener('click', function (e) {
|
|
119
|
+
e.stopPropagation();
|
|
120
|
+
copyText(editPrompt(slug, id, title, excerpt), btnEdit);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
wrap.appendChild(badge);
|
|
124
|
+
wrap.appendChild(btnApprove);
|
|
125
|
+
wrap.appendChild(btnEdit);
|
|
126
|
+
return wrap;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ── Inject into page ──────────────────────────────────────────────────────
|
|
130
|
+
|
|
131
|
+
function inject() {
|
|
132
|
+
var slug = (document.body.dataset.archSlug || 'unknown').trim();
|
|
133
|
+
var items = document.querySelectorAll('[data-arch-id]');
|
|
134
|
+
|
|
135
|
+
items.forEach(function (el) {
|
|
136
|
+
var id = el.dataset.archId;
|
|
137
|
+
if (!id) return;
|
|
138
|
+
var title = getTitle(el);
|
|
139
|
+
var excerpt = getExcerpt(el);
|
|
140
|
+
var actionsEl = makeActionsEl(slug, id, title, excerpt);
|
|
141
|
+
|
|
142
|
+
if (el.tagName === 'TR') {
|
|
143
|
+
// Ensure thead gets an empty actions header column (once per table)
|
|
144
|
+
var table = el.closest('table');
|
|
145
|
+
if (table) {
|
|
146
|
+
var theadRow = table.querySelector('thead tr');
|
|
147
|
+
if (theadRow && !theadRow.querySelector('.arch-actions-th')) {
|
|
148
|
+
var th = document.createElement('th');
|
|
149
|
+
th.className = 'arch-actions-th';
|
|
150
|
+
theadRow.appendChild(th);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
var td = document.createElement('td');
|
|
154
|
+
td.className = 'arch-actions-cell';
|
|
155
|
+
td.appendChild(actionsEl);
|
|
156
|
+
el.appendChild(td);
|
|
157
|
+
} else {
|
|
158
|
+
// Card / div: insert after first child (heading area)
|
|
159
|
+
var first = el.firstElementChild;
|
|
160
|
+
if (first && first.nextSibling) {
|
|
161
|
+
el.insertBefore(actionsEl, first.nextSibling);
|
|
162
|
+
} else if (first) {
|
|
163
|
+
el.appendChild(actionsEl);
|
|
164
|
+
} else {
|
|
165
|
+
el.prepend(actionsEl);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ── Stale / gap badge injection (ENH-034) ────────────────────────────────
|
|
172
|
+
// Items with data-arch-stale="true" get an amber "⚠ gap" badge.
|
|
173
|
+
// Stale means: brainstorm detected a gap here; HTML not yet synced.
|
|
174
|
+
|
|
175
|
+
function injectStaleBadges() {
|
|
176
|
+
document.querySelectorAll('[data-arch-stale="true"]').forEach(function (el) {
|
|
177
|
+
var reason = el.getAttribute('data-arch-stale-note') || 'gap detected in brainstorm';
|
|
178
|
+
var badge = document.createElement('span');
|
|
179
|
+
badge.className = 'arch-gap-badge';
|
|
180
|
+
badge.textContent = '⚠ gap';
|
|
181
|
+
badge.title = reason;
|
|
182
|
+
|
|
183
|
+
if (el.tagName === 'TR') {
|
|
184
|
+
var firstTd = el.querySelector('td');
|
|
185
|
+
if (firstTd && !firstTd.querySelector('.arch-gap-badge')) {
|
|
186
|
+
firstTd.appendChild(badge);
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
var h = el.querySelector('h2,h3,h4');
|
|
190
|
+
if (h && !h.querySelector('.arch-gap-badge')) {
|
|
191
|
+
h.appendChild(badge);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function markStale(id, reason) {
|
|
198
|
+
var el = document.querySelector('[data-arch-id="' + id + '"]');
|
|
199
|
+
if (!el) return;
|
|
200
|
+
el.setAttribute('data-arch-stale', 'true');
|
|
201
|
+
if (reason) el.setAttribute('data-arch-stale-note', reason);
|
|
202
|
+
injectStaleBadges();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Expose for browser console use during architect review sessions
|
|
206
|
+
window.vpMarkStale = markStale;
|
|
207
|
+
|
|
208
|
+
if (document.readyState === 'loading') {
|
|
209
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
210
|
+
inject();
|
|
211
|
+
injectStaleBadges();
|
|
212
|
+
});
|
|
213
|
+
} else {
|
|
214
|
+
inject();
|
|
215
|
+
injectStaleBadges();
|
|
216
|
+
}
|
|
217
|
+
})();
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>Architecture — {project}</title>
|
|
7
7
|
<link rel="stylesheet" href="style.css" />
|
|
8
8
|
</head>
|
|
9
|
-
<body>
|
|
9
|
+
<body data-arch-slug="architecture">
|
|
10
10
|
<nav class="nav-sidebar">
|
|
11
11
|
<div class="logo">
|
|
12
12
|
<span>ViePilot Architect Mode</span>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<button id="theme-toggle" onclick="toggleTheme()">☀️ Light</button>
|
|
38
38
|
</div>
|
|
39
39
|
|
|
40
|
-
<div class="card">
|
|
40
|
+
<div class="card" data-arch-id="ARCH-DIAG1" data-arch-title="C4 Context Diagram">
|
|
41
41
|
<h2>C4 Context Diagram</h2>
|
|
42
42
|
<div class="mermaid-wrap">
|
|
43
43
|
<div class="mermaid">
|
|
@@ -55,7 +55,7 @@ C4Context
|
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
57
57
|
|
|
58
|
-
<div class="card">
|
|
58
|
+
<div class="card" data-arch-id="ARCH-DIAG2" data-arch-title="System Diagram">
|
|
59
59
|
<h2>System Diagram</h2>
|
|
60
60
|
<div class="mermaid-wrap">
|
|
61
61
|
<div class="mermaid">
|
|
@@ -89,13 +89,13 @@ graph TD
|
|
|
89
89
|
</tr>
|
|
90
90
|
</thead>
|
|
91
91
|
<tbody>
|
|
92
|
-
<tr>
|
|
92
|
+
<tr data-arch-id="C1">
|
|
93
93
|
<td>{Component 1}</td>
|
|
94
94
|
<td>{Responsibility}</td>
|
|
95
95
|
<td>{Technology}</td>
|
|
96
96
|
<td>{Notes}</td>
|
|
97
97
|
</tr>
|
|
98
|
-
<tr>
|
|
98
|
+
<tr data-arch-id="C2">
|
|
99
99
|
<td>{Component 2}</td>
|
|
100
100
|
<td>{Responsibility}</td>
|
|
101
101
|
<td>{Technology}</td>
|
|
@@ -124,7 +124,7 @@ graph TD
|
|
|
124
124
|
</tr>
|
|
125
125
|
</thead>
|
|
126
126
|
<tbody>
|
|
127
|
-
<tr>
|
|
127
|
+
<tr data-arch-id="C3">
|
|
128
128
|
<td>{External System 1}</td>
|
|
129
129
|
<td>{SaaS / Internal / 3rd party}</td>
|
|
130
130
|
<td>{What it does}</td>
|
|
@@ -132,7 +132,7 @@ graph TD
|
|
|
132
132
|
<td>{Team / Vendor}</td>
|
|
133
133
|
<td>{Notes}</td>
|
|
134
134
|
</tr>
|
|
135
|
-
<tr>
|
|
135
|
+
<tr data-arch-id="C4">
|
|
136
136
|
<td>{External System 2}</td>
|
|
137
137
|
<td>{SaaS / Internal / 3rd party}</td>
|
|
138
138
|
<td>{What it does}</td>
|
|
@@ -155,5 +155,6 @@ graph TD
|
|
|
155
155
|
mermaid.initialize({ startOnLoad: false, theme: isLight ? 'default' : 'dark' });
|
|
156
156
|
}
|
|
157
157
|
</script>
|
|
158
|
+
<script src="architect-actions.js"></script>
|
|
158
159
|
</body>
|
|
159
160
|
</html>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>Data Flow — {project}</title>
|
|
7
7
|
<link rel="stylesheet" href="style.css" />
|
|
8
8
|
</head>
|
|
9
|
-
<body>
|
|
9
|
+
<body data-arch-slug="data-flow">
|
|
10
10
|
<nav class="nav-sidebar">
|
|
11
11
|
<div class="logo">
|
|
12
12
|
<span>ViePilot Architect Mode</span>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<button id="theme-toggle" onclick="toggleTheme()">☀️ Light</button>
|
|
38
38
|
</div>
|
|
39
39
|
|
|
40
|
-
<div class="card">
|
|
40
|
+
<div class="card" data-arch-id="DF-DIAG1" data-arch-title="Primary Request Flow">
|
|
41
41
|
<h2>Primary Request Flow</h2>
|
|
42
42
|
<div class="mermaid-wrap">
|
|
43
43
|
<div class="mermaid">
|
|
@@ -58,7 +58,7 @@ sequenceDiagram
|
|
|
58
58
|
</div>
|
|
59
59
|
</div>
|
|
60
60
|
|
|
61
|
-
<div class="card">
|
|
61
|
+
<div class="card" data-arch-id="DF-DIAG2" data-arch-title="Event Flow (Async)">
|
|
62
62
|
<h2>Event Flow (Async)</h2>
|
|
63
63
|
<div class="mermaid-wrap">
|
|
64
64
|
<div class="mermaid">
|
|
@@ -83,7 +83,7 @@ flowchart LR
|
|
|
83
83
|
</tr>
|
|
84
84
|
</thead>
|
|
85
85
|
<tbody>
|
|
86
|
-
<tr>
|
|
86
|
+
<tr data-arch-id="DF1">
|
|
87
87
|
<td>{Flow name}</td>
|
|
88
88
|
<td>{Trigger}</td>
|
|
89
89
|
<td>{Steps}</td>
|
|
@@ -104,5 +104,6 @@ flowchart LR
|
|
|
104
104
|
mermaid.initialize({ startOnLoad: false, theme: isLight ? 'default' : 'dark' });
|
|
105
105
|
}
|
|
106
106
|
</script>
|
|
107
|
+
<script src="architect-actions.js"></script>
|
|
107
108
|
</body>
|
|
108
109
|
</html>
|