viepilot 2.47.0 → 2.49.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.
@@ -0,0 +1,236 @@
1
+ ---
2
+ name: vp-intake
3
+ description: "Import and triage tickets from Excel/M365 Online, Google Sheets, or CSV/TSV files — classify as BUG/ENH, accept/decline via AskUserQuestion, write back to source, generate TRIAGE report"
4
+ version: 1.0.0
5
+ ---
6
+
7
+ <greeting>
8
+ ## Invocation Banner
9
+
10
+ Output this banner as the **first** thing on every invocation — before questions, work, or any other output:
11
+
12
+ ```
13
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
14
+ VIEPILOT ► VP-INTAKE v1.0.0 (fw 2.48.0)
15
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
16
+ ```
17
+ </greeting>
18
+ <version_check>
19
+ ## Version Update Check (ENH-072)
20
+
21
+ After displaying the greeting banner, run:
22
+ ```bash
23
+ node "$HOME/.claude/viepilot/bin/vp-tools.cjs" check-update --silent
24
+ ```
25
+
26
+ **If exit code = 1** (update available — new version printed to stdout):
27
+ Display the update notice banner before continuing. Silent otherwise.
28
+ </version_check>
29
+ <persona_context>
30
+ ## Persona Context Injection (ENH-073)
31
+ At skill start, run:
32
+ ```bash
33
+ node "$HOME/.claude/viepilot/bin/vp-tools.cjs" persona auto-switch
34
+ node "$HOME/.claude/viepilot/bin/vp-tools.cjs" persona context
35
+ ```
36
+ Inject the output as `## User Persona` context before any task execution.
37
+ Silent if command unavailable or errors.
38
+ </persona_context>
39
+
40
+ <cursor_skill_adapter>
41
+ ## A. Skill Invocation
42
+ - Skill được gọi khi user mention `vp-intake`, `/vp-intake`, "import tickets", "nhập ticket", "đọc ticket từ", "triage ticket"
43
+ - Treat all user text after the skill mention as `{{VP_ARGS}}`
44
+
45
+ ## B. User Prompting
46
+ Prompt user conversationally with options.
47
+
48
+ ## C. Tool Usage
49
+ Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`, `WebFetch`, `Subagent`
50
+ </cursor_skill_adapter>
51
+ <scope_policy>
52
+ ## ViePilot Namespace Guard (BUG-004)
53
+ - Default mode: only use and reference `vp-*` skills in ViePilot workflows.
54
+ - External skills (`non vp-*`) are out of framework scope unless user explicitly opts in.
55
+ - If external skills appear in runtime context, ignore them and route with the closest built-in `vp-*` skill.
56
+ </scope_policy>
57
+ <implementation_routing_guard>
58
+ ## Implementation routing guard (ENH-021)
59
+
60
+ - This skill **reads, classifies, and triages** external tickets — does not implement code.
61
+ - Accepted tickets create `.viepilot/requests/` files for planning via **`/vp-evolve`** → **`/vp-auto`**.
62
+ - **Exception:** User **explicit** bypass — state clearly in chat.
63
+ </implementation_routing_guard>
64
+
65
+ <objective>
66
+ Import tickets from external sources (Excel/Microsoft 365 Online, Google Sheets, CSV/TSV files),
67
+ classify them automatically as BUG/ENH/UNCLEAR, let the user triage each ticket via
68
+ AskUserQuestion (multi-select), write decisions back to the source, and generate a TRIAGE
69
+ session report.
70
+
71
+ **Creates/Updates:**
72
+ - `.viepilot/requests/BUG-N.md` or `ENH-N.md` for accepted tickets
73
+ - Source file: `VP_Status`, `VP_Comment`, `VP_RequestID` columns updated
74
+ - `.viepilot/intake/TRIAGE-{timestamp}.md` — session report
75
+ </objective>
76
+
77
+ <context>
78
+ Optional flags:
79
+ - `--channel <id>` : Skip channel selection, use this channel ID directly
80
+ - `--dry-run` : Classify and show tickets without creating requests or writing back
81
+
82
+ **Supported channel types:**
83
+ | Type | Auth | Config field |
84
+ |------|------|-------------|
85
+ | `csv` | None | `path` (local file) |
86
+ | `google_sheets` | Service Account JSON | `spreadsheet_id` + `sheet_name` |
87
+ | `excel_m365` | Azure App Registration | `workbook_id` + `sheet_name` |
88
+
89
+ **Config file:** `.viepilot/intake/channels.json`
90
+ **Credentials dir:** `.viepilot/.credentials/` (gitignored)
91
+ </context>
92
+
93
+ <process>
94
+
95
+ ### Step 1: Init intake directory
96
+
97
+ ```bash
98
+ node "$HOME/.claude/viepilot/bin/vp-tools.cjs" intake-init
99
+ ```
100
+
101
+ This creates `.viepilot/intake/channels.json` (scaffold) and `.viepilot/.credentials/` if missing.
102
+
103
+ ### Step 2: Load channels
104
+
105
+ Read `.viepilot/intake/channels.json`. If no channels configured (only example stubs remain),
106
+ tell the user:
107
+
108
+ ```
109
+ No channels configured yet.
110
+ Edit .viepilot/intake/channels.json to add your ticket sources.
111
+ Run vp-tools intake-init to see the config scaffold.
112
+ ```
113
+
114
+ ### Step 3: Select channel (AUQ single-select)
115
+
116
+ ```
117
+ question: "Which ticket channel do you want to import from?"
118
+ header: "Channel"
119
+ options: one per channel — label: "{channel.name} ({channel.type})", description: "{channel.id}"
120
+ ```
121
+
122
+ ### Step 4: Read and classify tickets
123
+
124
+ Dispatch to the correct adapter based on `channel.type`:
125
+ - `csv` → `lib/intake/adapters/csv.cjs` → `readCsv(channel, projectRoot)`
126
+ - `google_sheets` → `lib/intake/adapters/google-sheets.cjs` → `readGoogleSheet(channel, projectRoot)`
127
+ - `excel_m365` → `lib/intake/adapters/excel-m365.cjs` → `readExcelM365(channel, projectRoot)`
128
+
129
+ For each ticket, call `classifyTicket(ticket)` from `lib/intake/classifier.cjs`.
130
+ Attach `ticket._classified = 'BUG' | 'ENH' | 'UNCLEAR'`.
131
+
132
+ Display classification summary:
133
+ ```
134
+ Read {N} tickets from {channel.name}
135
+ BUG: {N} ENH: {N} UNCLEAR: {N}
136
+ ```
137
+
138
+ If 0 tickets found, exit with message "No tickets found in this channel."
139
+
140
+ ### Step 5: Triage (AUQ multi-select)
141
+
142
+ Call `runTriage(tickets, channel, projectRoot, askFn)` from `lib/intake/triage-ux.cjs`.
143
+
144
+ `askFn` is a wrapper around `AskUserQuestion`:
145
+ ```js
146
+ async function askFn(question, options, multiSelect) {
147
+ // calls AskUserQuestion tool → returns selected label(s)
148
+ }
149
+ ```
150
+
151
+ For each ticket: AUQ multi-select to accept/decline, then AUQ single-select for decline reason.
152
+ UNCLEAR tickets get a 3-choice prompt: "Accept as BUG / Accept as ENH / Decline".
153
+
154
+ ### Step 6: Write-back + Report
155
+
156
+ ```js
157
+ await writeback(channel, triageResult, projectRoot); // lib/intake/writeback.cjs
158
+ const reportPath = generateTriageReport(channel, triageResult, projectRoot); // lib/intake/report.cjs
159
+ ```
160
+
161
+ Write-back failure → warn (non-fatal), report is still generated.
162
+
163
+ ### Step 7: Completion banner
164
+
165
+ ```
166
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
167
+ VIEPILOT ► INTAKE COMPLETE ✓
168
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
169
+
170
+ Channel: {channel.name}
171
+ Accepted: {N} → {request IDs}
172
+ Declined: {N}
173
+ Report: .viepilot/intake/TRIAGE-{timestamp}.md
174
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
175
+ ```
176
+
177
+ ### Step 8: Next action (AUQ single-select)
178
+
179
+ ```
180
+ question: "Triage complete. What would you like to do next?"
181
+ options:
182
+ - "Execute accepted requests → /vp-auto" (Recommended)
183
+ - "Plan phase/tasks → /vp-evolve"
184
+ - "Import from another channel → /vp-intake"
185
+ - "Done for now"
186
+ ```
187
+
188
+ </process>
189
+
190
+ <success_criteria>
191
+ - [ ] Channels loaded from `.viepilot/intake/channels.json`
192
+ - [ ] Correct adapter dispatched based on channel type
193
+ - [ ] Tickets classified as BUG / ENH / UNCLEAR
194
+ - [ ] AUQ multi-select triage completed with accept/decline per ticket
195
+ - [ ] Decline reasons collected and attached
196
+ - [ ] Accepted tickets auto-create `.viepilot/requests/` files
197
+ - [ ] Write-back updates source (non-fatal on failure)
198
+ - [ ] TRIAGE session report generated at `.viepilot/intake/TRIAGE-{timestamp}.md`
199
+ </success_criteria>
200
+
201
+ ## Adapter Compatibility
202
+
203
+ ### AskUserQuestion Tool (ENH-059)
204
+
205
+ | Adapter | Interactive Prompts | Notes |
206
+ |---------|---------------------|-------|
207
+ | Claude Code (terminal) | ✅ `AskUserQuestion` — REQUIRED | Preload via ToolSearch before first call |
208
+ | Cursor (Agent/Skills) | ❌ Text fallback | Plain numbered list |
209
+ | Codex CLI | ❌ Text fallback | N/A |
210
+ | Antigravity | ❌ Text fallback | N/A |
211
+ | GitHub Copilot | ✅ Text fallback | Via `.agent.md` |
212
+
213
+ **Prompts in this skill:**
214
+ - Channel selection (Step 3)
215
+ - Ticket accept/decline multi-select (Step 5)
216
+ - Decline reason (Step 5)
217
+ - UNCLEAR handling (Step 5)
218
+ - Next action (Step 8)
219
+
220
+ ## Capabilities
221
+ - Read tickets from Excel/Microsoft 365 Online via Microsoft Graph API
222
+ - Read tickets from Google Sheets via Sheets API v4
223
+ - Read tickets from local CSV/TSV files
224
+ - Auto-classify tickets as BUG/ENH/UNCLEAR with Vietnamese keyword support
225
+ - Interactive triage with AskUserQuestion (multi-select, paginated)
226
+ - Write-back VP_Status/VP_Comment/VP_RequestID to source
227
+ - Generate TRIAGE session report in .viepilot/intake/
228
+
229
+ ## Tags
230
+ intake, tickets, triage, excel, google-sheets, csv, bug-import, enh-import, external-sources
231
+
232
+ ## Best Practices
233
+ - Always run `intake-init` before first use to scaffold the config
234
+ - Store credentials in `.viepilot/.credentials/` — never commit them
235
+ - Review the TRIAGE report after each session for audit trail
236
+ - Use `--dry-run` to preview classification before creating requests