@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.
Files changed (3) hide show
  1. package/README.md +20 -5
  2. package/package.json +1 -1
  3. 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 (via Grill Me)
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 relies on a Grill Me compatible skill for requirement exploration.
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@winton979/task-cli",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Lightweight task workflow CLI for AI-assisted development",
5
5
  "license": "MIT",
6
6
  "type": "module",
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. Clarify the requirement just enough to remove ambiguity.
31
- 2. Create a concise task brief and save it to:
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
- 3. Show the brief before coding.
36
- 4. If the user does not object, implement immediately.
37
- 5. Verify the result against the acceptance criteria.
38
- 6. Archive the brief automatically by moving it to:
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
- 7. Summarize the outcome and any follow-up risks.
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. Explore the requirement through focused questions.
95
- 2. Continue until the task is sufficiently understood.
96
- 3. Do not write code.
97
- 4. Do not create implementation details.
98
- 5. Once the requirement is clear, generate a concise task brief and save it to:
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
- 6. Show the saved brief and stop.
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. Do not write code.
274
- 2. Do not suggest fixes before enough evidence exists.
275
- 3. Identify root cause candidates.
276
- 4. Ask focused questions.
277
- 5. Request evidence whenever possible.
278
- 6. Separate:
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
- 7. Once the bug is sufficiently understood, generate a brief and save it to:
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
- 8. Show the saved brief and stop.
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')