@winton979/task-cli 1.2.0 → 1.3.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/README.md +20 -5
- package/package.json +1 -1
- package/src/init.js +168 -23
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Designed for:
|
|
|
10
10
|
|
|
11
11
|
Task CLI provides a lightweight alternative to heavyweight spec-driven workflows by combining:
|
|
12
12
|
|
|
13
|
-
* Requirement clarification (
|
|
13
|
+
* Requirement clarification (prefer Grill Me, fallback built in)
|
|
14
14
|
* Brief generation
|
|
15
15
|
* Implementation
|
|
16
16
|
* Review
|
|
@@ -34,7 +34,7 @@ task init
|
|
|
34
34
|
|
|
35
35
|
## Prerequisites
|
|
36
36
|
|
|
37
|
-
Task CLI
|
|
37
|
+
Task CLI can use a Grill Me compatible skill for requirement and bug exploration.
|
|
38
38
|
|
|
39
39
|
Recommended:
|
|
40
40
|
|
|
@@ -44,6 +44,8 @@ npx add-skill PJ-SBN-593844/skill-grill-me
|
|
|
44
44
|
|
|
45
45
|
Compatible Grill Me implementations may also work.
|
|
46
46
|
|
|
47
|
+
If no Grill Me compatible skill is installed, `task-fast`, `task-explore`, and `bug-explore` fall back to built-in clarification prompts.
|
|
48
|
+
|
|
47
49
|
---
|
|
48
50
|
|
|
49
51
|
## Usage
|
|
@@ -59,7 +61,7 @@ After initialization, Task CLI creates the `.ai/` workspace and installs workflo
|
|
|
59
61
|
|
|
60
62
|
Use `task refresh` in existing projects to remove and reinstall only the workflow skills managed by task-cli. It does not delete your `.ai` briefs, internal archives, or decision log.
|
|
61
63
|
|
|
62
|
-
Use `task doctor` to check whether the required directories exist, whether managed skills are missing or outdated, and whether the `.gitignore` rules are present.
|
|
64
|
+
Use `task doctor` to check whether the required directories exist, whether managed skills are missing or outdated, whether a local Grill Me companion was detected, and whether the `.gitignore` rules are present.
|
|
63
65
|
|
|
64
66
|
---
|
|
65
67
|
|
|
@@ -127,6 +129,7 @@ BUG_READY
|
|
|
127
129
|
### Other
|
|
128
130
|
|
|
129
131
|
* decision-log
|
|
132
|
+
* decision-sweep-weekly
|
|
130
133
|
|
|
131
134
|
---
|
|
132
135
|
|
|
@@ -151,6 +154,18 @@ BUG_READY
|
|
|
151
154
|
|
|
152
155
|
---
|
|
153
156
|
|
|
157
|
+
## Weekly Decision Sweep
|
|
158
|
+
|
|
159
|
+
Calling `/decision-log` after every task is easy to forget. As a lower-friction alternative, run `decision-sweep-weekly` once per week (Friday is a natural fit):
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
/decision-sweep-weekly
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The skill scans archived task and bug briefs from the past 7 days, judges which ones contain a decision worth keeping (cross-task impact, rejected alternatives, counter-intuitive choices, externally driven calls, or instructive cancellations), drafts the entries, and waits for confirmation before appending to `.ai/decisions/decisions.md`.
|
|
166
|
+
|
|
167
|
+
Use `decision-log` for in-the-moment recording and `decision-sweep-weekly` for periodic cleanup. Either alone is enough; using both is fine.
|
|
168
|
+
|
|
154
169
|
## Philosophy
|
|
155
170
|
|
|
156
171
|
Task CLI is intentionally lightweight.
|
|
@@ -221,7 +236,7 @@ task refresh
|
|
|
221
236
|
This will:
|
|
222
237
|
|
|
223
238
|
* keep `.ai/tasks`, `.ai/bugs`, and `.ai/decisions`
|
|
224
|
-
* remove only these managed skills from `.claude/skills/` and `.codex/skills/`: `task-fast`, `task-explore`, `task-implement`, `task-review`, `task-cancel`, `bug-explore`, `bug-fix`, `bug-review`, `bug-cancel`, `decision-log`
|
|
239
|
+
* remove only these managed skills from `.claude/skills/` and `.codex/skills/`: `task-fast`, `task-explore`, `task-implement`, `task-review`, `task-cancel`, `bug-explore`, `bug-fix`, `bug-review`, `bug-cancel`, `decision-log`, `decision-sweep-weekly`
|
|
225
240
|
* reinstall the latest versions of those skills
|
|
226
241
|
|
|
227
242
|
This avoids touching unrelated custom skills in the same project.
|
|
@@ -237,4 +252,4 @@ task doctor
|
|
|
237
252
|
MIT
|
|
238
253
|
|
|
239
254
|
> Task CLI does not install Grill Me automatically.
|
|
240
|
-
> Users remain free to choose any Grill Me compatible implementation.
|
|
255
|
+
> Users remain free to choose any Grill Me compatible implementation, and the explore skills fall back to built-in clarification if none is installed.
|
package/package.json
CHANGED
package/src/init.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
|
|
1
3
|
const TASK_ACTIVE_DIR = '.ai/tasks/active';
|
|
2
4
|
const TASK_ARCHIVE_DIR = '.ai/tasks/archive';
|
|
3
5
|
const BUG_ACTIVE_DIR = '.ai/bugs/active';
|
|
@@ -11,6 +13,12 @@ const GITIGNORE_BLOCK = [
|
|
|
11
13
|
'.ai/bugs/active/*.md',
|
|
12
14
|
].join('\n');
|
|
13
15
|
|
|
16
|
+
const GRILL_ME_HINTS = [
|
|
17
|
+
'grill-me',
|
|
18
|
+
'skill-grill-me',
|
|
19
|
+
'grill me',
|
|
20
|
+
];
|
|
21
|
+
|
|
14
22
|
const SKILLS = {
|
|
15
23
|
'task-fast': {
|
|
16
24
|
name: 'task-fast',
|
|
@@ -27,19 +35,20 @@ Handle a small requirement in one continuous workflow with minimal ceremony.
|
|
|
27
35
|
|
|
28
36
|
Workflow
|
|
29
37
|
|
|
30
|
-
1.
|
|
31
|
-
2.
|
|
38
|
+
1. If a Grill Me compatible skill is available in the current environment, use it for requirement clarification.
|
|
39
|
+
2. If no Grill Me compatible skill is available, clarify the requirement yourself with focused questions just far enough to remove ambiguity.
|
|
40
|
+
3. Create a concise task brief and save it to:
|
|
32
41
|
|
|
33
42
|
.ai/tasks/active/YYYY-MM-DD-task-name.md
|
|
34
43
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
4. Show the brief before coding.
|
|
45
|
+
5. If the user does not object, implement immediately.
|
|
46
|
+
6. Verify the result against the acceptance criteria.
|
|
47
|
+
7. Archive the brief automatically by moving it to:
|
|
39
48
|
|
|
40
49
|
.ai/tasks/archive/YYYY-MM-DD-task-name.md
|
|
41
50
|
|
|
42
|
-
|
|
51
|
+
8. Summarize the outcome and any follow-up risks.
|
|
43
52
|
|
|
44
53
|
Task Brief Format
|
|
45
54
|
|
|
@@ -91,15 +100,16 @@ Clarify requirements and leave behind a ready-to-execute brief.
|
|
|
91
100
|
|
|
92
101
|
Workflow
|
|
93
102
|
|
|
94
|
-
1.
|
|
95
|
-
2.
|
|
96
|
-
3.
|
|
97
|
-
4. Do not
|
|
98
|
-
5.
|
|
103
|
+
1. If a Grill Me compatible skill is available in the current environment, use it for requirement exploration.
|
|
104
|
+
2. If no Grill Me compatible skill is available, explore the requirement yourself through focused questions.
|
|
105
|
+
3. Continue until the task is sufficiently understood.
|
|
106
|
+
4. Do not write code.
|
|
107
|
+
5. Do not create implementation details.
|
|
108
|
+
6. Once the requirement is clear, generate a concise task brief and save it to:
|
|
99
109
|
|
|
100
110
|
.ai/tasks/active/YYYY-MM-DD-task-name.md
|
|
101
111
|
|
|
102
|
-
|
|
112
|
+
7. Show the saved brief and stop.
|
|
103
113
|
|
|
104
114
|
Task Brief Format
|
|
105
115
|
|
|
@@ -270,22 +280,23 @@ Investigate a bug and leave behind a ready-to-fix brief.
|
|
|
270
280
|
|
|
271
281
|
Rules
|
|
272
282
|
|
|
273
|
-
1.
|
|
274
|
-
2.
|
|
275
|
-
3.
|
|
276
|
-
4.
|
|
277
|
-
5.
|
|
278
|
-
6.
|
|
283
|
+
1. If a Grill Me compatible skill is available in the current environment, use it for bug exploration.
|
|
284
|
+
2. If no Grill Me compatible skill is available, ask focused questions and drive the investigation yourself.
|
|
285
|
+
3. Do not write code.
|
|
286
|
+
4. Do not suggest fixes before enough evidence exists.
|
|
287
|
+
5. Identify root cause candidates.
|
|
288
|
+
6. Request evidence whenever possible.
|
|
289
|
+
7. Separate:
|
|
279
290
|
|
|
280
291
|
* observed behavior
|
|
281
292
|
* expected behavior
|
|
282
293
|
* assumptions
|
|
283
294
|
|
|
284
|
-
|
|
295
|
+
8. Once the bug is sufficiently understood, generate a brief and save it to:
|
|
285
296
|
|
|
286
297
|
.ai/bugs/active/YYYY-MM-DD-bug-name.md
|
|
287
298
|
|
|
288
|
-
|
|
299
|
+
9. Show the saved brief and stop.
|
|
289
300
|
|
|
290
301
|
Bug Brief Format
|
|
291
302
|
|
|
@@ -474,6 +485,79 @@ Requirements
|
|
|
474
485
|
* Maximum 10 lines per decision
|
|
475
486
|
* Append only
|
|
476
487
|
* Keep concise
|
|
488
|
+
`,
|
|
489
|
+
},
|
|
490
|
+
|
|
491
|
+
'decision-sweep-weekly': {
|
|
492
|
+
name: 'decision-sweep-weekly',
|
|
493
|
+
description: 'Weekly sweep of recent task and bug briefs to decide which deserve a decision-log entry. Proposes entries for confirmation before appending.',
|
|
494
|
+
content: `---
|
|
495
|
+
name: decision-sweep-weekly
|
|
496
|
+
description: Weekly sweep of recent task and bug briefs to decide which deserve a decision-log entry. Proposes entries for confirmation before appending.
|
|
497
|
+
user-invocable: true
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
Purpose
|
|
501
|
+
|
|
502
|
+
Batch-review the past week of work and sediment only the decisions that outlive a single task. Replaces per-task reminders with one weekly pass.
|
|
503
|
+
|
|
504
|
+
When to Run
|
|
505
|
+
|
|
506
|
+
Run once per week, ideally on Friday. May also run ad-hoc after a busy stretch.
|
|
507
|
+
|
|
508
|
+
Workflow
|
|
509
|
+
|
|
510
|
+
1. Scan briefs created in the last 7 days under .ai/tasks/archive/ and .ai/bugs/archive/. Filter by filename date prefix YYYY-MM-DD. If a brief lacks a date prefix, fall back to filesystem mtime.
|
|
511
|
+
2. For cancelled briefs in either archive, treat the abandonment itself as potential decision material.
|
|
512
|
+
3. Evaluate each brief against the Sediment Conditions below.
|
|
513
|
+
4. For each candidate, draft a decision entry using the four-section format.
|
|
514
|
+
5. Present a single review list: every scanned brief with a verdict (write / skip / insufficient info), then the proposed drafts grouped at the end.
|
|
515
|
+
6. Do NOT append anything yet. Wait for the user to confirm which drafts to keep, edit, or drop.
|
|
516
|
+
7. Only after confirmation, append the approved entries to .ai/decisions/decisions.md, oldest first, under the matching YYYY-MM-DD section heading.
|
|
517
|
+
8. Report what was appended and what was skipped.
|
|
518
|
+
|
|
519
|
+
Sediment Conditions
|
|
520
|
+
|
|
521
|
+
A brief becomes a decision entry if it satisfies any of:
|
|
522
|
+
|
|
523
|
+
* Cross-task impact: the choice constrains how future tasks must be written.
|
|
524
|
+
* A concrete alternative was rejected and someone could plausibly pick it later.
|
|
525
|
+
* Counter-intuitive choice: code reads like an anti-pattern but is intentional.
|
|
526
|
+
* Externally driven: compliance, performance, compatibility, or a third-party API limit forced the call.
|
|
527
|
+
* A cancelled attempt whose failure is itself a useful conclusion.
|
|
528
|
+
|
|
529
|
+
Skip Conditions
|
|
530
|
+
|
|
531
|
+
* Affects only the implementation detail of one task.
|
|
532
|
+
* A temporary or unsettled conclusion.
|
|
533
|
+
* A bare fact with no decision behind it.
|
|
534
|
+
|
|
535
|
+
Entry Format
|
|
536
|
+
|
|
537
|
+
## YYYY-MM-DD
|
|
538
|
+
|
|
539
|
+
### Problem
|
|
540
|
+
|
|
541
|
+
What issue was encountered.
|
|
542
|
+
|
|
543
|
+
### Decision
|
|
544
|
+
|
|
545
|
+
What was chosen.
|
|
546
|
+
|
|
547
|
+
### Reason
|
|
548
|
+
|
|
549
|
+
Why this choice was made.
|
|
550
|
+
|
|
551
|
+
### Alternatives Considered
|
|
552
|
+
|
|
553
|
+
What alternatives were rejected.
|
|
554
|
+
|
|
555
|
+
Requirements
|
|
556
|
+
|
|
557
|
+
* Maximum 10 lines per decision
|
|
558
|
+
* Append only
|
|
559
|
+
* One date section per day; multiple decisions on the same day stack under the same heading
|
|
560
|
+
* Never edit or delete prior entries
|
|
477
561
|
`,
|
|
478
562
|
},
|
|
479
563
|
};
|
|
@@ -484,6 +568,49 @@ function skillFilePath(path, cwd, skillRoot, skillName) {
|
|
|
484
568
|
return path.join(cwd, skillRoot, skillName, 'SKILL.md');
|
|
485
569
|
}
|
|
486
570
|
|
|
571
|
+
function hasGrillMeHint(value) {
|
|
572
|
+
const normalized = value.toLowerCase();
|
|
573
|
+
return GRILL_ME_HINTS.some((hint) => normalized.includes(hint));
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
function detectLocalGrillMeSkill(fs, path, cwd, skillRoot) {
|
|
577
|
+
const root = path.join(cwd, skillRoot);
|
|
578
|
+
if (!fs.existsSync(root)) {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
|
|
583
|
+
if (!entry.isDirectory()) {
|
|
584
|
+
continue;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
if (MANAGED_SKILL_NAMES.includes(entry.name)) {
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
if (hasGrillMeHint(entry.name)) {
|
|
592
|
+
return entry.name;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
const skillPath = path.join(root, entry.name, 'SKILL.md');
|
|
596
|
+
if (!fs.existsSync(skillPath)) {
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
const content = fs.readFileSync(skillPath, 'utf-8');
|
|
601
|
+
const metadata = content
|
|
602
|
+
.split('---')
|
|
603
|
+
.slice(1, 2)
|
|
604
|
+
.join('\n');
|
|
605
|
+
|
|
606
|
+
if (hasGrillMeHint(metadata)) {
|
|
607
|
+
return entry.name;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
return null;
|
|
612
|
+
}
|
|
613
|
+
|
|
487
614
|
function logCheck(log, ok, label, detail) {
|
|
488
615
|
if (ok) {
|
|
489
616
|
log.chalk.green(` OK ${label}${detail ? ` - ${detail}` : ''}`);
|
|
@@ -595,7 +722,8 @@ export function init(cwd, { fs, path, log }) {
|
|
|
595
722
|
fast: task-fast
|
|
596
723
|
task: task-explore -> task-implement -> task-review | task-cancel
|
|
597
724
|
bug: bug-explore -> bug-fix -> bug-review | bug-cancel
|
|
598
|
-
other: decision-log
|
|
725
|
+
other: decision-log
|
|
726
|
+
sweep: decision-sweep-weekly`);
|
|
599
727
|
}
|
|
600
728
|
|
|
601
729
|
export function refresh(cwd, { fs, path, log }) {
|
|
@@ -629,7 +757,8 @@ export function refresh(cwd, { fs, path, log }) {
|
|
|
629
757
|
fast: task-fast
|
|
630
758
|
task: task-explore -> task-implement -> task-review | task-cancel
|
|
631
759
|
bug: bug-explore -> bug-fix -> bug-review | bug-cancel
|
|
632
|
-
other: decision-log
|
|
760
|
+
other: decision-log
|
|
761
|
+
sweep: decision-sweep-weekly`);
|
|
633
762
|
}
|
|
634
763
|
|
|
635
764
|
export function doctor(cwd, { fs, path, log }) {
|
|
@@ -680,6 +809,22 @@ export function doctor(cwd, { fs, path, log }) {
|
|
|
680
809
|
}
|
|
681
810
|
}
|
|
682
811
|
|
|
812
|
+
const grillMeFindings = [
|
|
813
|
+
[CLAUDE_SKILLS_DIR, detectLocalGrillMeSkill(fs, path, cwd, CLAUDE_SKILLS_DIR)],
|
|
814
|
+
[CODEX_SKILLS_DIR, detectLocalGrillMeSkill(fs, path, cwd, CODEX_SKILLS_DIR)],
|
|
815
|
+
];
|
|
816
|
+
|
|
817
|
+
for (const [skillRoot, skillName] of grillMeFindings) {
|
|
818
|
+
if (skillName) {
|
|
819
|
+
logCheck(log, true, `${skillRoot} Grill Me companion`, `detected ${skillName}`);
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
console.log(chalk.yellow(
|
|
824
|
+
` WARN ${skillRoot} Grill Me companion - not detected locally; task-fast, task-explore, and bug-explore will use built-in clarification fallback`
|
|
825
|
+
));
|
|
826
|
+
}
|
|
827
|
+
|
|
683
828
|
const gitignorePath = path.join(cwd, '.gitignore');
|
|
684
829
|
const gitignore = fs.existsSync(gitignorePath)
|
|
685
830
|
? fs.readFileSync(gitignorePath, 'utf-8')
|