@winton979/task-cli 1.0.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/bin/task.js +3 -0
- package/package.json +19 -0
- package/src/cli.js +36 -0
- package/src/init.js +484 -0
package/bin/task.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@winton979/task-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Lightweight task workflow CLI for AI-assisted development",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"task": "./bin/task.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"src"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"chalk": "^5.5.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { init } from './init.js';
|
|
5
|
+
|
|
6
|
+
const cwd = process.cwd();
|
|
7
|
+
const cmd = process.argv[2];
|
|
8
|
+
|
|
9
|
+
const log = {
|
|
10
|
+
info(msg) { console.log(msg); },
|
|
11
|
+
chalk: {
|
|
12
|
+
green(msg) { console.log(chalk.green(msg)); },
|
|
13
|
+
dim(msg) { console.log(chalk.dim(msg)); },
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function showHelp() {
|
|
18
|
+
console.log(`\
|
|
19
|
+
task - Lightweight AI-assisted task workflow
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
task init Initialize task workflow in current directory
|
|
23
|
+
task --help Show this help`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
switch (cmd) {
|
|
27
|
+
case 'init':
|
|
28
|
+
init(cwd, { fs, path, log });
|
|
29
|
+
break;
|
|
30
|
+
case undefined:
|
|
31
|
+
case '--help':
|
|
32
|
+
case '-h':
|
|
33
|
+
default:
|
|
34
|
+
showHelp();
|
|
35
|
+
break;
|
|
36
|
+
}
|
package/src/init.js
ADDED
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
|
|
3
|
+
const SKILLS = {
|
|
4
|
+
'task-fast': {
|
|
5
|
+
name: 'task-fast',
|
|
6
|
+
description: 'Fast path for small requirements. Invoke Grill Me, generate task brief, save to .ai/tasks/active/.',
|
|
7
|
+
content: `---
|
|
8
|
+
name: task-fast
|
|
9
|
+
description: Fast path for small requirements. Invoke Grill Me, generate task brief, save to .ai/tasks/active/.
|
|
10
|
+
user-invocable: true
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
Purpose
|
|
14
|
+
|
|
15
|
+
Fast path for small requirements and optimizations.
|
|
16
|
+
|
|
17
|
+
Workflow
|
|
18
|
+
|
|
19
|
+
1. Invoke the installed Grill Me skill.
|
|
20
|
+
2. Continue requirement clarification until Grill Me completes.
|
|
21
|
+
3. Generate a task brief automatically.
|
|
22
|
+
4. Save the brief to:
|
|
23
|
+
|
|
24
|
+
.ai/tasks/active/YYYY-MM-DD-task-name.md
|
|
25
|
+
|
|
26
|
+
5. Present the brief.
|
|
27
|
+
6. Wait for approval before implementation.
|
|
28
|
+
|
|
29
|
+
Output
|
|
30
|
+
|
|
31
|
+
TASK_BRIEF_READY
|
|
32
|
+
`,
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
'task-explore': {
|
|
36
|
+
name: 'task-explore',
|
|
37
|
+
description: 'Clarify requirements before implementation. Invoke Grill Me until the task is understood.',
|
|
38
|
+
content: `---
|
|
39
|
+
name: task-explore
|
|
40
|
+
description: Clarify requirements before implementation. Invoke Grill Me until the task is understood.
|
|
41
|
+
user-invocable: true
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
Purpose
|
|
45
|
+
|
|
46
|
+
Clarify requirements before implementation.
|
|
47
|
+
|
|
48
|
+
Workflow
|
|
49
|
+
|
|
50
|
+
1. Invoke the installed Grill Me skill.
|
|
51
|
+
2. Continue until Grill Me determines the task is sufficiently understood.
|
|
52
|
+
3. Do not write code.
|
|
53
|
+
4. Do not create implementation plans.
|
|
54
|
+
5. Focus only on requirement clarification.
|
|
55
|
+
|
|
56
|
+
When complete output:
|
|
57
|
+
|
|
58
|
+
TASK_READY
|
|
59
|
+
`,
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
'task-brief': {
|
|
63
|
+
name: 'task-brief',
|
|
64
|
+
description: 'Convert a completed Grill Me discussion into a concise task brief saved to .ai/tasks/active/.',
|
|
65
|
+
content: `---
|
|
66
|
+
name: task-brief
|
|
67
|
+
description: Convert a completed Grill Me discussion into a concise task brief saved to .ai/tasks/active/.
|
|
68
|
+
user-invocable: true
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
Purpose
|
|
72
|
+
|
|
73
|
+
Convert the completed Grill Me discussion into a concise execution brief.
|
|
74
|
+
|
|
75
|
+
Save Location
|
|
76
|
+
|
|
77
|
+
.ai/tasks/active/YYYY-MM-DD-task-name.md
|
|
78
|
+
|
|
79
|
+
Naming Convention
|
|
80
|
+
|
|
81
|
+
YYYY-MM-DD-short-task-name.md
|
|
82
|
+
|
|
83
|
+
Example
|
|
84
|
+
|
|
85
|
+
2026-06-10-resize-handle.md
|
|
86
|
+
|
|
87
|
+
Output Format
|
|
88
|
+
|
|
89
|
+
# Goal
|
|
90
|
+
|
|
91
|
+
What should be achieved.
|
|
92
|
+
|
|
93
|
+
# Context
|
|
94
|
+
|
|
95
|
+
Relevant project background.
|
|
96
|
+
|
|
97
|
+
# Constraints
|
|
98
|
+
|
|
99
|
+
Business or technical limitations.
|
|
100
|
+
|
|
101
|
+
# Risks
|
|
102
|
+
|
|
103
|
+
Potential pitfalls.
|
|
104
|
+
|
|
105
|
+
# Acceptance Criteria
|
|
106
|
+
|
|
107
|
+
Clear success conditions.
|
|
108
|
+
|
|
109
|
+
Requirements
|
|
110
|
+
|
|
111
|
+
* Maximum 500 words
|
|
112
|
+
* No code
|
|
113
|
+
* No implementation details
|
|
114
|
+
* No architecture design
|
|
115
|
+
* Only information required for execution
|
|
116
|
+
|
|
117
|
+
After generation:
|
|
118
|
+
|
|
119
|
+
1. Save the file.
|
|
120
|
+
2. Show the content.
|
|
121
|
+
3. Wait for approval.
|
|
122
|
+
`,
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
'task-implement': {
|
|
126
|
+
name: 'task-implement',
|
|
127
|
+
description: 'Implement the task using task.md. Follow acceptance criteria strictly.',
|
|
128
|
+
content: `---
|
|
129
|
+
name: task-implement
|
|
130
|
+
description: Implement the task using task.md. Follow acceptance criteria strictly.
|
|
131
|
+
user-invocable: true
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
Purpose
|
|
135
|
+
|
|
136
|
+
Implement the task using task.md.
|
|
137
|
+
|
|
138
|
+
Rules
|
|
139
|
+
|
|
140
|
+
1. Follow task.md strictly.
|
|
141
|
+
2. Follow acceptance criteria strictly.
|
|
142
|
+
3. Prefer minimal changes.
|
|
143
|
+
4. Respect existing project conventions.
|
|
144
|
+
5. Avoid unnecessary refactoring.
|
|
145
|
+
6. State assumptions explicitly.
|
|
146
|
+
7. Keep implementation focused.
|
|
147
|
+
|
|
148
|
+
Output
|
|
149
|
+
|
|
150
|
+
## Plan
|
|
151
|
+
|
|
152
|
+
Short implementation plan.
|
|
153
|
+
|
|
154
|
+
## Changes
|
|
155
|
+
|
|
156
|
+
Files modified.
|
|
157
|
+
|
|
158
|
+
## Validation
|
|
159
|
+
|
|
160
|
+
How acceptance criteria were satisfied.
|
|
161
|
+
`,
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
'task-review': {
|
|
165
|
+
name: 'task-review',
|
|
166
|
+
description: 'Review implementation against task.md. Evaluate completion, edge cases, maintainability, and risks.',
|
|
167
|
+
content: `---
|
|
168
|
+
name: task-review
|
|
169
|
+
description: Review implementation against task.md. Evaluate completion, edge cases, maintainability, and risks.
|
|
170
|
+
user-invocable: true
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
Purpose
|
|
174
|
+
|
|
175
|
+
Review implementation against task.md.
|
|
176
|
+
|
|
177
|
+
Evaluate
|
|
178
|
+
|
|
179
|
+
1. Goal completion
|
|
180
|
+
2. Acceptance criteria coverage
|
|
181
|
+
3. Edge cases
|
|
182
|
+
4. Maintainability
|
|
183
|
+
5. Performance impact
|
|
184
|
+
6. Security impact
|
|
185
|
+
7. Regression risks
|
|
186
|
+
|
|
187
|
+
Output
|
|
188
|
+
|
|
189
|
+
## Pass/Fail
|
|
190
|
+
|
|
191
|
+
Overall assessment.
|
|
192
|
+
|
|
193
|
+
## Findings
|
|
194
|
+
|
|
195
|
+
Issues found.
|
|
196
|
+
|
|
197
|
+
## Suggestions
|
|
198
|
+
|
|
199
|
+
Optional improvements.
|
|
200
|
+
|
|
201
|
+
## Missing Acceptance Criteria
|
|
202
|
+
|
|
203
|
+
Anything not fully implemented.
|
|
204
|
+
`,
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
'bug-explore': {
|
|
208
|
+
name: 'bug-explore',
|
|
209
|
+
description: 'Investigate a bug before fixing it. Identify root cause candidates, separate observed vs expected behavior.',
|
|
210
|
+
content: `---
|
|
211
|
+
name: bug-explore
|
|
212
|
+
description: Investigate a bug before fixing it. Identify root cause candidates, separate observed vs expected behavior.
|
|
213
|
+
user-invocable: true
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
Purpose
|
|
217
|
+
|
|
218
|
+
Investigate a bug before fixing it.
|
|
219
|
+
|
|
220
|
+
Rules
|
|
221
|
+
|
|
222
|
+
1. Do not write code.
|
|
223
|
+
2. Do not suggest fixes immediately.
|
|
224
|
+
3. Identify root cause candidates.
|
|
225
|
+
4. Ask one question at a time.
|
|
226
|
+
5. Request evidence whenever possible.
|
|
227
|
+
6. Separate:
|
|
228
|
+
|
|
229
|
+
* observed behavior
|
|
230
|
+
* expected behavior
|
|
231
|
+
* assumptions
|
|
232
|
+
|
|
233
|
+
When sufficient evidence exists output:
|
|
234
|
+
|
|
235
|
+
BUG_READY
|
|
236
|
+
`,
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
'bug-brief': {
|
|
240
|
+
name: 'bug-brief',
|
|
241
|
+
description: 'Summarize bug investigation into a brief saved to .ai/bugs/active/.',
|
|
242
|
+
content: `---
|
|
243
|
+
name: bug-brief
|
|
244
|
+
description: Summarize bug investigation into a brief saved to .ai/bugs/active/.
|
|
245
|
+
user-invocable: true
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
Purpose
|
|
249
|
+
|
|
250
|
+
Summarize bug investigation.
|
|
251
|
+
|
|
252
|
+
Save Location
|
|
253
|
+
|
|
254
|
+
.ai/bugs/active/YYYY-MM-DD-bug-name.md
|
|
255
|
+
|
|
256
|
+
Naming Convention
|
|
257
|
+
|
|
258
|
+
YYYY-MM-DD-short-bug-name.md
|
|
259
|
+
|
|
260
|
+
Example
|
|
261
|
+
|
|
262
|
+
2026-06-10-iframe-resize.md
|
|
263
|
+
|
|
264
|
+
Output Format
|
|
265
|
+
|
|
266
|
+
# Problem
|
|
267
|
+
|
|
268
|
+
Observed issue.
|
|
269
|
+
|
|
270
|
+
# Expected Behavior
|
|
271
|
+
|
|
272
|
+
Expected result.
|
|
273
|
+
|
|
274
|
+
# Suspected Root Cause
|
|
275
|
+
|
|
276
|
+
Most likely cause.
|
|
277
|
+
|
|
278
|
+
# Evidence
|
|
279
|
+
|
|
280
|
+
Supporting observations.
|
|
281
|
+
|
|
282
|
+
# Constraints
|
|
283
|
+
|
|
284
|
+
Technical limitations.
|
|
285
|
+
|
|
286
|
+
# Acceptance Criteria
|
|
287
|
+
|
|
288
|
+
Conditions proving the bug is fixed.
|
|
289
|
+
|
|
290
|
+
After generation
|
|
291
|
+
|
|
292
|
+
1. Save the file.
|
|
293
|
+
2. Show the content.
|
|
294
|
+
3. Wait for approval.
|
|
295
|
+
`,
|
|
296
|
+
},
|
|
297
|
+
|
|
298
|
+
'bug-fix': {
|
|
299
|
+
name: 'bug-fix',
|
|
300
|
+
description: 'Fix the bug using bug.md. Minimize changes, fix root cause not symptoms.',
|
|
301
|
+
content: `---
|
|
302
|
+
name: bug-fix
|
|
303
|
+
description: Fix the bug using bug.md. Minimize changes, fix root cause not symptoms.
|
|
304
|
+
user-invocable: true
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
Purpose
|
|
308
|
+
|
|
309
|
+
Fix the bug using bug.md.
|
|
310
|
+
|
|
311
|
+
Rules
|
|
312
|
+
|
|
313
|
+
1. Minimize changes.
|
|
314
|
+
2. Avoid unrelated refactoring.
|
|
315
|
+
3. Fix root cause, not symptoms.
|
|
316
|
+
4. Preserve existing behavior.
|
|
317
|
+
5. Explain reasoning.
|
|
318
|
+
|
|
319
|
+
Output
|
|
320
|
+
|
|
321
|
+
## Root Cause
|
|
322
|
+
|
|
323
|
+
Confirmed cause.
|
|
324
|
+
|
|
325
|
+
## Fix
|
|
326
|
+
|
|
327
|
+
Changes made.
|
|
328
|
+
|
|
329
|
+
## Validation
|
|
330
|
+
|
|
331
|
+
Verification performed.
|
|
332
|
+
`,
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
'bug-review': {
|
|
336
|
+
name: 'bug-review',
|
|
337
|
+
description: 'Review bug fix against bug.md. Check root cause, regression risks, side effects.',
|
|
338
|
+
content: `---
|
|
339
|
+
name: bug-review
|
|
340
|
+
description: Review bug fix against bug.md. Check root cause, regression risks, side effects.
|
|
341
|
+
user-invocable: true
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
Purpose
|
|
345
|
+
|
|
346
|
+
Review implementation against bug.md.
|
|
347
|
+
|
|
348
|
+
Check
|
|
349
|
+
|
|
350
|
+
1. Root cause addressed
|
|
351
|
+
2. Regression risks
|
|
352
|
+
3. Side effects
|
|
353
|
+
4. Edge cases
|
|
354
|
+
5. Test coverage
|
|
355
|
+
|
|
356
|
+
Output
|
|
357
|
+
|
|
358
|
+
## Pass/Fail
|
|
359
|
+
|
|
360
|
+
Assessment.
|
|
361
|
+
|
|
362
|
+
## Risks
|
|
363
|
+
|
|
364
|
+
Potential issues.
|
|
365
|
+
|
|
366
|
+
## Recommendations
|
|
367
|
+
|
|
368
|
+
Further improvements.
|
|
369
|
+
`,
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
'decision-log': {
|
|
373
|
+
name: 'decision-log',
|
|
374
|
+
description: 'Record implementation decisions to .ai/decisions/decisions.md. Append-only, max 10 lines per entry.',
|
|
375
|
+
content: `---
|
|
376
|
+
name: decision-log
|
|
377
|
+
description: Record implementation decisions to .ai/decisions/decisions.md. Append-only, max 10 lines per entry.
|
|
378
|
+
user-invocable: true
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
Purpose
|
|
382
|
+
|
|
383
|
+
Record important implementation decisions.
|
|
384
|
+
|
|
385
|
+
Save Location
|
|
386
|
+
|
|
387
|
+
.ai/decisions/decisions.md
|
|
388
|
+
|
|
389
|
+
Append Format
|
|
390
|
+
|
|
391
|
+
## YYYY-MM-DD
|
|
392
|
+
|
|
393
|
+
### Problem
|
|
394
|
+
|
|
395
|
+
What issue was encountered.
|
|
396
|
+
|
|
397
|
+
### Decision
|
|
398
|
+
|
|
399
|
+
What was chosen.
|
|
400
|
+
|
|
401
|
+
### Reason
|
|
402
|
+
|
|
403
|
+
Why this choice was made.
|
|
404
|
+
|
|
405
|
+
### Alternatives Considered
|
|
406
|
+
|
|
407
|
+
What alternatives were rejected.
|
|
408
|
+
|
|
409
|
+
Requirements
|
|
410
|
+
|
|
411
|
+
* Maximum 10 lines per decision
|
|
412
|
+
* Append only
|
|
413
|
+
* Keep concise
|
|
414
|
+
`,
|
|
415
|
+
},
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
export function init(cwd, { fs, path, log }) {
|
|
419
|
+
// Directory structure
|
|
420
|
+
const dirs = [
|
|
421
|
+
'.ai',
|
|
422
|
+
'.ai/tasks/active',
|
|
423
|
+
'.ai/tasks/archive',
|
|
424
|
+
'.ai/bugs/active',
|
|
425
|
+
'.ai/bugs/archive',
|
|
426
|
+
'.ai/decisions',
|
|
427
|
+
'.claude/skills',
|
|
428
|
+
];
|
|
429
|
+
|
|
430
|
+
log.info('Creating directory structure...');
|
|
431
|
+
for (const dir of dirs) {
|
|
432
|
+
const full = path.join(cwd, dir);
|
|
433
|
+
if (!fs.existsSync(full)) {
|
|
434
|
+
fs.mkdirSync(full, { recursive: true });
|
|
435
|
+
log.chalk.green(` ✓ ${dir}`);
|
|
436
|
+
} else {
|
|
437
|
+
log.chalk.dim(` - ${dir} (exists)`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Create decisions.md placeholder
|
|
442
|
+
const decisionsPath = path.join(cwd, '.ai/decisions/decisions.md');
|
|
443
|
+
if (!fs.existsSync(decisionsPath)) {
|
|
444
|
+
fs.writeFileSync(decisionsPath, '# Decisions Log\n\n');
|
|
445
|
+
log.chalk.green(' ✓ .ai/decisions/decisions.md');
|
|
446
|
+
} else {
|
|
447
|
+
log.chalk.dim(' - .ai/decisions/decisions.md (exists)');
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Create skill files
|
|
451
|
+
log.info('\nInstalling workflow skills...');
|
|
452
|
+
for (const [key, skill] of Object.entries(SKILLS)) {
|
|
453
|
+
const skillDir = path.join(cwd, '.claude/skills', skill.name);
|
|
454
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
455
|
+
|
|
456
|
+
if (!fs.existsSync(skillDir)) {
|
|
457
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
if (!fs.existsSync(skillFile)) {
|
|
461
|
+
fs.writeFileSync(skillFile, skill.content);
|
|
462
|
+
log.chalk.green(` ✓ ${skill.name}`);
|
|
463
|
+
} else {
|
|
464
|
+
log.chalk.dim(` - ${skill.name} (exists)`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Create or append .gitignore
|
|
469
|
+
const gitignorePath = path.join(cwd, '.gitignore');
|
|
470
|
+
const gitignoreEntry = '\n# task workflow\n.ai/tasks/active/*.md\n.ai/bugs/active/*.md\n';
|
|
471
|
+
let existing = '';
|
|
472
|
+
if (fs.existsSync(gitignorePath)) {
|
|
473
|
+
existing = fs.readFileSync(gitignorePath, 'utf-8');
|
|
474
|
+
}
|
|
475
|
+
if (!existing.includes('# task workflow')) {
|
|
476
|
+
fs.writeFileSync(gitignorePath, existing.trimEnd() + gitignoreEntry);
|
|
477
|
+
log.chalk.green(' ✓ .gitignore updated');
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
log.info(`\nTask workflow initialized. Skills available:
|
|
481
|
+
task: fast, explore, brief, implement, review
|
|
482
|
+
bug: explore, brief, fix, review
|
|
483
|
+
other: decision-log`);
|
|
484
|
+
}
|