viepilot 1.14.0 → 2.4.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 +191 -0
- package/README.md +27 -17
- package/bin/viepilot.cjs +19 -9
- package/bin/vp-tools.cjs +193 -0
- package/docs/user/features/adapters.md +74 -0
- package/docs/user/features/hooks.md +93 -0
- package/lib/adapters/antigravity.cjs +33 -0
- package/lib/adapters/claude-code.cjs +42 -0
- package/lib/adapters/codex.cjs +34 -0
- package/lib/adapters/cursor.cjs +32 -0
- package/lib/adapters/index.cjs +28 -0
- package/lib/hooks/brainstorm-staleness.cjs +231 -0
- package/lib/viepilot-config.cjs +103 -0
- package/lib/viepilot-install.cjs +125 -152
- package/package.json +1 -3
- package/skills/vp-audit/SKILL.md +23 -23
- package/skills/vp-auto/SKILL.md +23 -9
- package/skills/vp-brainstorm/SKILL.md +44 -38
- package/skills/vp-crystallize/SKILL.md +25 -19
- package/skills/vp-debug/SKILL.md +4 -4
- package/skills/vp-docs/SKILL.md +8 -8
- package/skills/vp-evolve/SKILL.md +26 -13
- package/skills/vp-info/SKILL.md +24 -24
- package/skills/vp-pause/SKILL.md +7 -7
- package/skills/vp-request/SKILL.md +14 -14
- package/skills/vp-resume/SKILL.md +6 -6
- package/skills/vp-rollback/SKILL.md +4 -4
- package/skills/vp-status/SKILL.md +4 -4
- package/skills/vp-task/SKILL.md +2 -2
- package/skills/vp-ui-components/SKILL.md +14 -14
- package/skills/vp-update/SKILL.md +18 -18
- 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 +70 -5
- package/workflows/brainstorm.md +398 -222
- package/workflows/crystallize.md +51 -33
- package/workflows/debug.md +9 -9
- package/workflows/documentation.md +5 -5
- package/workflows/evolve.md +46 -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
- package/dev-install.sh +0 -150
- package/install.sh +0 -125
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vp-request
|
|
3
|
-
description: "
|
|
3
|
+
description: "Create new request: feature, bug fix, enhancement, or brainstorm continuation"
|
|
4
4
|
version: 0.2.0
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ version: 0.2.0
|
|
|
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,31 +25,31 @@ Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`,
|
|
|
25
25
|
<implementation_routing_guard>
|
|
26
26
|
## Implementation routing guard (ENH-021)
|
|
27
27
|
|
|
28
|
-
-
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
28
|
+
- This skill only **creates requests**, **backlog**, **triage** (`.viepilot/requests/*`, `TRACKER`, sometimes suggests ROADMAP) — does **not** implement default shipping code (`lib/`, `tests/`, `bin/`, `workflows/`, `skills/` of the repo, etc.).
|
|
29
|
+
- **After request:** **`/vp-evolve`** (ROADMAP + phase + tasks + plan) → **`/vp-auto`** (execute). See `workflows/request.md`.
|
|
30
|
+
- **Exception:** User **explicit** (*hotfix now*, *fix in this chat*, *bypass planning*) — must **state clearly** the bypass in chat.
|
|
31
|
+
- **Do not** suggest *”Start working now”* as direct implementation in this thread; use evolve → auto instead.
|
|
32
32
|
</implementation_routing_guard>
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
<objective>
|
|
36
|
-
|
|
37
|
-
- Bug report
|
|
36
|
+
Create and manage requests for the project under development:
|
|
37
|
+
- Bug report and fix
|
|
38
38
|
- Feature request
|
|
39
39
|
- Enhancement/Improvement
|
|
40
40
|
- Technical debt
|
|
41
|
-
- Brainstorm
|
|
41
|
+
- Brainstorm continuation for new ideas
|
|
42
42
|
|
|
43
43
|
**Creates/Updates:**
|
|
44
44
|
- `.viepilot/requests/{TYPE}-{NUMBER}.md`
|
|
45
|
-
- `.viepilot/TRACKER.md` (
|
|
46
|
-
- `.viepilot/ROADMAP.md` (
|
|
45
|
+
- `.viepilot/TRACKER.md` (add to backlog)
|
|
46
|
+
- `.viepilot/ROADMAP.md` (if approved)
|
|
47
47
|
|
|
48
|
-
**Routes to:** `/vp-auto`
|
|
48
|
+
**Routes to:** `/vp-auto` or `/vp-evolve` depending on request type
|
|
49
49
|
</objective>
|
|
50
50
|
|
|
51
51
|
<execution_context>
|
|
52
|
-
@$HOME
|
|
52
|
+
@$HOME/{envToolDir}/workflows/request.md
|
|
53
53
|
</execution_context>
|
|
54
54
|
|
|
55
55
|
<context>
|
|
@@ -64,7 +64,7 @@ Optional flags:
|
|
|
64
64
|
</context>
|
|
65
65
|
|
|
66
66
|
<process>
|
|
67
|
-
Execute workflow from `@$HOME
|
|
67
|
+
Execute workflow from `@$HOME/{envToolDir}/workflows/request.md`
|
|
68
68
|
|
|
69
69
|
### Step 1: Detect Request Type
|
|
70
70
|
|
|
@@ -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`
|
|
@@ -41,11 +41,11 @@ Restore complete project context và resume work seamlessly.
|
|
|
41
41
|
</objective>
|
|
42
42
|
|
|
43
43
|
<execution_context>
|
|
44
|
-
@$HOME
|
|
44
|
+
@$HOME/{envToolDir}/workflows/resume-work.md
|
|
45
45
|
</execution_context>
|
|
46
46
|
|
|
47
47
|
<process>
|
|
48
|
-
Execute workflow from `@$HOME
|
|
48
|
+
Execute workflow from `@$HOME/{envToolDir}/workflows/resume-work.md`
|
|
49
49
|
|
|
50
50
|
### Step 1: Check Project Exists
|
|
51
51
|
```bash
|
|
@@ -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
|
|
@@ -44,7 +44,7 @@ Rollback đến bất kỳ checkpoint nào một cách an toàn, với backup v
|
|
|
44
44
|
</objective>
|
|
45
45
|
|
|
46
46
|
<execution_context>
|
|
47
|
-
@$HOME
|
|
47
|
+
@$HOME/{envToolDir}/workflows/rollback.md
|
|
48
48
|
</execution_context>
|
|
49
49
|
|
|
50
50
|
<context>
|
|
@@ -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,40 +25,40 @@ 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>
|
|
48
|
-
@$HOME
|
|
48
|
+
@$HOME/{envToolDir}/workflows/ui-components.md
|
|
49
49
|
</execution_context>
|
|
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>
|
|
61
|
-
Execute workflow from `@$HOME
|
|
61
|
+
Execute workflow from `@$HOME/{envToolDir}/workflows/ui-components.md`
|
|
62
62
|
|
|
63
63
|
Key steps:
|
|
64
64
|
1. Prepare global + local component stores
|
|
@@ -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,51 +22,51 @@ 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>
|
|
40
|
-
@$HOME
|
|
40
|
+
@$HOME/{envToolDir}/bin/vp-tools.cjs
|
|
41
41
|
</execution_context>
|
|
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
|
+
})();
|