@winton979/task-cli 1.5.0 → 1.6.1

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 CHANGED
@@ -84,16 +84,27 @@ After initialization, Task CLI creates the `.ai/` workspace and installs workflo
84
84
 
85
85
  ### Exploration Protocol
86
86
 
87
- Task CLI embeds the `grilling` primitive from [Matt Pocock's skills collection](https://github.com/mattpocock/skills.git). Its wording is the methodological foundation for exploration, not a runtime dependency.
87
+ Task CLI embeds the `grilling` primitive from [Matt Pocock's skills collection](https://github.com/mattpocock/skills.git). Its wording is the methodological foundation for decision-driven exploration, not a runtime dependency.
88
88
 
89
89
  `task-explore` and `bug-explore` preserve the primitive's body verbatim. Their only workflow-specific interpretation of it is that "act on it" means creating the brief. `task-fast` uses a narrower clarification loop so the fast path remains fast.
90
90
 
91
+ `project-explore` is explicitly invoked, read-only, and evidence-driven. It answers when the available evidence supports a bounded conclusion and asks a question only when ambiguity would materially change the answer.
92
+
91
93
  Task CLI neither requires nor installs a companion interviewing skill.
92
94
 
93
95
  ---
94
96
 
95
- ## Quick Start
96
-
97
+ ## Quick Start
98
+
99
+ ### Project Understanding
100
+
101
+ ```text
102
+ Claude Code: /project-explore
103
+ Codex CLI: $project-explore
104
+
105
+ evidence-based explanation → no artifacts or changes
106
+ ```
107
+
97
108
  ### Small Feature / Enhancement
98
109
 
99
110
  ```text
@@ -110,6 +121,10 @@ archive automatically
110
121
  /task-explore → TASK_READY → /task-implement → optional /task-audit
111
122
  ```
112
123
 
124
+ `task-explore` writes the brief for a fresh-session handoff. Briefs should stay within 500 words; they may extend to 1000 only when a shorter contract would omit execution-critical information. Requirements that still do not fit should be split before implementation.
125
+
126
+ When more than one active brief could match, identify the intended brief when invoking `task-implement`. The implementing agent rechecks repository facts and resolves local, reversible choices from existing conventions. It asks the user only for unresolved decisions that materially affect the contract, records confirmed narrow clarifications in the active brief, and returns material goal, scope, or acceptance changes to `task-explore`.
127
+
113
128
  ### Bug Fix
114
129
 
115
130
  ```text
@@ -167,9 +182,13 @@ The workflow encourages the simplest acceptable implementation instead of the mo
167
182
 
168
183
  ---
169
184
 
170
- ## Available Skills
171
-
172
- **Task Workflow**
185
+ ## Available Skills
186
+
187
+ **Project Understanding**
188
+
189
+ * `project-explore`
190
+
191
+ **Task Workflow**
173
192
 
174
193
  * `task-fast`
175
194
  * `task-explore`
@@ -305,7 +324,7 @@ task refresh
305
324
  This will:
306
325
 
307
326
  * keep `.ai/tasks`, `.ai/bugs`, and `.ai/decisions`
308
- * remove only managed skills from `.claude/skills/` and `.codex/skills/`, including legacy `task-review` and `bug-review`, then reinstall the current set: `task-fast`, `task-explore`, `task-implement`, `task-audit`, `task-cancel`, `bug-explore`, `bug-fix`, `bug-audit`, `bug-cancel`, `decision-log`, `decision-sweep-weekly`, `decision-curate`
327
+ * remove only managed skills from `.claude/skills/` and `.codex/skills/`, including legacy `task-review` and `bug-review`, then reinstall the current set: `project-explore`, `task-fast`, `task-explore`, `task-implement`, `task-audit`, `task-cancel`, `bug-explore`, `bug-fix`, `bug-audit`, `bug-cancel`, `decision-log`, `decision-sweep-weekly`, `decision-curate`
309
328
  * reinstall the latest versions of those skills
310
329
 
311
330
  Unrelated custom skills in the same project are left untouched. Inspect the current setup first with `task doctor`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@winton979/task-cli",
3
- "version": "1.5.0",
3
+ "version": "1.6.1",
4
4
  "description": "Lightweight task workflow CLI for AI-assisted development",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/cli.js CHANGED
@@ -25,6 +25,7 @@ Usage:
25
25
  task --help Show this help
26
26
 
27
27
  Recommended flows after init:
28
+ explore: project-explore
28
29
  fast: task-fast
29
30
  task: task-explore -> task-implement -> task-audit (optional, risk-triggered)
30
31
  bug: bug-explore -> bug-fix -> bug-audit (optional, risk-triggered)
package/src/init.js CHANGED
@@ -48,7 +48,128 @@ Before finalizing the brief, assess whether the requirement justifies added comp
48
48
  as a Risk, not a plan.
49
49
  * When complexity appears justified, do not design the solution here. Simply record that additional implementation effort is likely required.`;
50
50
 
51
+ const PROJECT_EXPLORE_DESCRIPTION = 'Build an evidence-based understanding of the existing project without changing it. Use only when the user explicitly invokes project-explore; do not use for implementation, bug investigation, or formal review.';
52
+ const PROJECT_EXPLORE_BODY = `Purpose
53
+
54
+ Establish a shared, evidence-based understanding of the existing project within the current conversation.
55
+
56
+ Explain behavior, structure, design intent, constraints, and trade-offs. Do not create change work.
57
+
58
+ Workflow
59
+
60
+ 1. Classify the user's primary intent. If it matches a case under Transitions, state the boundary and stop.
61
+ 2. Identify the question or project area to understand.
62
+ 3. Inspect the relevant code, tests, configuration, documentation, decisions, and repository history. Look up repository facts instead of asking the user for them.
63
+ 4. Build the answer from evidence. Separate:
64
+
65
+ * observed facts
66
+ * recorded intent
67
+ * inferred rationale
68
+ * assumptions and unknowns
69
+ * trade-offs
70
+
71
+ 5. Answer when the evidence supports a bounded conclusion. Do not prolong exploration to remove immaterial uncertainty.
72
+ 6. Ask one focused question at a time only when ambiguity would materially change the answer. Recommend an answer only for a user-owned choice.
73
+ 7. Stop when the question is answered or the remaining uncertainty is stated precisely.
74
+
75
+ Evidence Discipline
76
+
77
+ * Treat current code, tests, configuration, and direct observations as evidence of behavior.
78
+ * Treat documentation, decisions, archives, and repository history as evidence of context or intent. Do not let them override contradictory current behavior.
79
+ * Cite file paths and line numbers when practical.
80
+ * Treat missing rationale as unknown. Do not infer that no rationale existed.
81
+ * When sources conflict, report the conflict and identify which claim each source supports.
82
+ * Do not treat unfamiliar design as defective. If evidence indicates incorrect behavior, label it as a possible issue rather than diagnosing it here.
83
+
84
+ Decision Discussion
85
+
86
+ When discussing a design choice:
87
+
88
+ * identify the decision and its constraints
89
+ * compare only relevant alternatives
90
+ * state the benefits, costs, and assumptions of each alternative
91
+ * recommend a direction only when the user explicitly requests a recommendation and the available evidence is sufficient
92
+
93
+ Keep recommendations conceptual. Do not provide code, file-by-file changes, implementation steps, acceptance criteria, or estimates. Do not present exploration as architecture approval.
94
+
95
+ Project Memory
96
+
97
+ Before explaining a project decision, inspect .ai/decisions/decisions.md if it exists and contains entries beyond the title.
98
+
99
+ Use it narrowly:
100
+
101
+ * extract only decisions relevant to the question
102
+ * treat them as durable constraints, not complete documentation
103
+ * verify that current project evidence does not contradict them
104
+ * omit unrelated history
105
+
106
+ Transitions
107
+
108
+ If the user's primary intent becomes:
109
+
110
+ * new or changed behavior: recommend task-fast or task-explore
111
+ * suspected incorrect behavior: recommend bug-explore
112
+ * recording an approved durable decision: recommend decision-log
113
+ * review of a completed task or bug with a brief: recommend task-audit or bug-audit
114
+ * standalone architecture or quality review: state that no managed workflow covers it; do not issue findings, ratings, approval, or a release verdict
115
+
116
+ After routing, stop. Do not inspect the project to fulfill the out-of-scope request. Do not invoke another workflow or create its artifacts unless the user explicitly requests it.
117
+
118
+ Boundaries
119
+
120
+ Do not:
121
+
122
+ * modify code, documentation, or project state
123
+ * create task, bug, or decision artifacts
124
+ * design an implementation
125
+ * perform a formal architecture review or audit
126
+ * treat exploration findings as approved decisions
127
+
128
+ Output
129
+
130
+ Answer directly. Use only the sections that improve clarity:
131
+
132
+ ## Understanding
133
+
134
+ ## Evidence
135
+
136
+ ## Intent and Uncertainty
137
+
138
+ ## Trade-offs
139
+
140
+ ## Open Questions
141
+
142
+ Omit empty sections. For a simple question, prefer concise prose without headings.
143
+ `;
144
+
51
145
  const SKILLS = {
146
+ 'project-explore': {
147
+ name: 'project-explore',
148
+ description: PROJECT_EXPLORE_DESCRIPTION,
149
+ content: `---
150
+ name: project-explore
151
+ description: ${PROJECT_EXPLORE_DESCRIPTION}
152
+ user-invocable: true
153
+ disable-model-invocation: true
154
+ ---
155
+
156
+ ${PROJECT_EXPLORE_BODY}`,
157
+ codexContent: `---
158
+ name: project-explore
159
+ description: ${PROJECT_EXPLORE_DESCRIPTION}
160
+ ---
161
+
162
+ ${PROJECT_EXPLORE_BODY}`,
163
+ codexAgentContent: `interface:
164
+ display_name: "Project Explore"
165
+ short_description: "Explore existing projects from repository evidence"
166
+ default_prompt: "Use $project-explore to explain the current project from repository evidence."
167
+
168
+ policy:
169
+ allow_implicit_invocation: false
170
+ `,
171
+ },
172
+
52
173
  'task-fast': {
53
174
  name: 'task-fast',
54
175
  description: 'Fast path for small requirements. Clarify quickly, create the brief, implement, and verify. Archive automatically on completion.',
@@ -157,6 +278,15 @@ ${DECISIONS_READ_GUIDANCE}
157
278
 
158
279
  ${COMPLEXITY_ASSESSMENT_GUIDANCE}
159
280
 
281
+ Cross-session Readiness
282
+
283
+ Before finalizing the brief, assume implementation will start in a fresh session without the exploration conversation.
284
+
285
+ * Record every confirmed user decision that materially constrains behavior, scope, compatibility, security, data handling, or acceptance.
286
+ * Record material exclusions when omitting them could cause plausible scope expansion.
287
+ * Do not copy repository facts the implementing agent can discover. Include only context needed to interpret the contract.
288
+ * Do not output TASK_READY while a material user-owned decision remains unresolved.
289
+
160
290
  Task Brief Format
161
291
 
162
292
  # Goal
@@ -185,7 +315,9 @@ Clear success conditions.
185
315
 
186
316
  Requirements
187
317
 
188
- * Maximum 500 words
318
+ * Aim for 500 words or fewer
319
+ * Extend to at most 1000 words only when required to preserve execution-critical scope, constraints, risks, or acceptance criteria
320
+ * If a coherent contract cannot fit within 1000 words, split the requirement and complete exploration for one independently executable task at a time
189
321
  * No code
190
322
  * No architecture design
191
323
  * Stay implementation-agnostic; describe constraints, not solutions
@@ -199,27 +331,39 @@ TASK_READY
199
331
 
200
332
  'task-implement': {
201
333
  name: 'task-implement',
202
- description: 'Implement the latest active task brief and validate it. Archive automatically when complete.',
334
+ description: 'Implement a selected active task brief and validate it. Archive automatically when complete.',
203
335
  content: `---
204
336
  name: task-implement
205
- description: Implement the latest active task brief and validate it. Archive automatically when complete.
337
+ description: Implement a selected active task brief and validate it. Archive automatically when complete.
206
338
  user-invocable: true
207
339
  ---
208
340
 
209
341
  Purpose
210
342
 
211
- Implement a task from the latest file in .ai/tasks/active/.
343
+ Implement the intended task from .ai/tasks/active/.
212
344
 
213
345
  Rules
214
346
 
215
- 1. Read the latest relevant brief from .ai/tasks/active/.
216
- 2. Follow the acceptance criteria strictly.
217
- 3. Prefer minimal changes.
218
- 4. Respect existing project conventions.
219
- 5. Avoid unnecessary refactoring.
220
- 6. State assumptions explicitly.
221
- 7. Validate the result before stopping.
222
- 8. If the work is complete, archive the brief automatically by moving it to .ai/tasks/archive/.
347
+ 1. Identify the intended brief in .ai/tasks/active/. Use a user-specified name or path when provided. Without one, proceed only when a single brief is the clear match. Ask the user when multiple briefs are plausible; do not choose by recency alone.
348
+ 2. Read the selected brief and inspect the relevant current code before planning.
349
+ 3. Follow the acceptance criteria strictly.
350
+ 4. Prefer minimal changes.
351
+ 5. Respect existing project conventions.
352
+ 6. Avoid unnecessary refactoring.
353
+ 7. State assumptions explicitly.
354
+ 8. Validate the result before stopping.
355
+ 9. If the work is complete, archive the selected brief automatically by moving it to .ai/tasks/archive/.
356
+
357
+ Brief Sufficiency
358
+
359
+ Before changing code, and whenever implementation reveals an ambiguity, determine whether the selected brief remains executable against the current project state.
360
+
361
+ * Investigate facts available from the repository or environment instead of asking the user.
362
+ * For a local, reversible implementation choice that does not materially affect behavior, scope, compatibility, security, data, or acceptance, follow existing conventions and choose the simplest option.
363
+ * Do not infer an unresolved user decision that materially affects those concerns. Ask one focused question at a time, include a recommended answer, and wait.
364
+ * After explicit confirmation of a narrow clarification, record it in the selected active brief before continuing implementation.
365
+ * If clarification materially changes the Goal, accepted scope, or Acceptance Criteria, or the unresolved decisions collectively require material contract revision, stop and require renewed task-explore. Do not implement against an outdated brief.
366
+ * If current project state materially contradicts the brief's context, surface the conflict and resolve it under the same rules.
223
367
 
224
368
  When making implementation decisions
225
369
 
@@ -804,8 +948,22 @@ const MANAGED_SKILL_NAMES = [
804
948
  ...LEGACY_MANAGED_SKILL_NAMES,
805
949
  ];
806
950
 
807
- function skillFilePath(path, cwd, skillRoot, skillName) {
808
- return path.join(cwd, skillRoot, skillName, 'SKILL.md');
951
+ function skillArtifacts(skillRoot, skill) {
952
+ const artifacts = [{
953
+ relativePath: 'SKILL.md',
954
+ content: skillRoot === CODEX_SKILLS_DIR && skill.codexContent
955
+ ? skill.codexContent
956
+ : skill.content,
957
+ }];
958
+
959
+ if (skillRoot === CODEX_SKILLS_DIR && skill.codexAgentContent) {
960
+ artifacts.push({
961
+ relativePath: 'agents/openai.yaml',
962
+ content: skill.codexAgentContent,
963
+ });
964
+ }
965
+
966
+ return artifacts;
809
967
  }
810
968
 
811
969
  function logCheck(log, ok, label, detail) {
@@ -839,18 +997,24 @@ function installSkills(fs, path, cwd, skillRoot, log) {
839
997
  ensureDir(fs, path, cwd, skillRoot, log);
840
998
  for (const skill of Object.values(SKILLS)) {
841
999
  const skillDir = path.join(cwd, skillRoot, skill.name);
842
- const skillFile = skillFilePath(path, cwd, skillRoot, skill.name);
843
-
844
1000
  if (!fs.existsSync(skillDir)) {
845
1001
  fs.mkdirSync(skillDir, { recursive: true });
846
1002
  }
847
1003
 
848
- if (!fs.existsSync(skillFile)) {
849
- fs.writeFileSync(skillFile, skill.content);
850
- log.chalk.green(` ✓ ${skillRoot}/${skill.name}`);
851
- } else {
852
- log.chalk.dim(` - ${skillRoot}/${skill.name} (exists)`);
1004
+ let created = false;
1005
+ for (const artifact of skillArtifacts(skillRoot, skill)) {
1006
+ const artifactPath = path.join(skillDir, artifact.relativePath);
1007
+ if (fs.existsSync(artifactPath)) {
1008
+ continue;
1009
+ }
1010
+
1011
+ fs.mkdirSync(path.dirname(artifactPath), { recursive: true });
1012
+ fs.writeFileSync(artifactPath, artifact.content);
1013
+ created = true;
853
1014
  }
1015
+
1016
+ const label = `${skillRoot}/${skill.name}`;
1017
+ created ? log.chalk.green(` ✓ ${label}`) : log.chalk.dim(` - ${label} (exists)`);
854
1018
  }
855
1019
  }
856
1020
 
@@ -916,6 +1080,7 @@ export function init(cwd, { fs, path, log }) {
916
1080
  updateGitignore(fs, path, cwd, log);
917
1081
 
918
1082
  log.info(`\nTask workflow initialized. Recommended flows:
1083
+ explore: project-explore
919
1084
  fast: task-fast
920
1085
  task: task-explore -> task-implement -> task-audit (optional, risk-triggered)
921
1086
  bug: bug-explore -> bug-fix -> bug-audit (optional, risk-triggered)
@@ -952,6 +1117,7 @@ export function refresh(cwd, { fs, path, log }) {
952
1117
  updateGitignore(fs, path, cwd, log);
953
1118
 
954
1119
  log.info(`\nTask workflow refreshed. Managed skills reinstalled:
1120
+ explore: project-explore
955
1121
  fast: task-fast
956
1122
  task: task-explore -> task-implement -> task-audit (optional, risk-triggered)
957
1123
  bug: bug-explore -> bug-fix -> bug-audit (optional, risk-triggered)
@@ -989,22 +1155,27 @@ export function doctor(cwd, { fs, path, log }) {
989
1155
 
990
1156
  for (const skillRoot of [CLAUDE_SKILLS_DIR, CODEX_SKILLS_DIR]) {
991
1157
  for (const skill of Object.values(SKILLS)) {
992
- const skillPath = skillFilePath(path, cwd, skillRoot, skill.name);
993
- if (!fs.existsSync(skillPath)) {
994
- checks.push(false);
995
- logCheck(log, false, `${skillRoot}/${skill.name}`, 'missing');
996
- continue;
1158
+ for (const artifact of skillArtifacts(skillRoot, skill)) {
1159
+ const artifactPath = path.join(cwd, skillRoot, skill.name, artifact.relativePath);
1160
+ const label = artifact.relativePath === 'SKILL.md'
1161
+ ? `${skillRoot}/${skill.name}`
1162
+ : `${skillRoot}/${skill.name}/${artifact.relativePath}`;
1163
+ if (!fs.existsSync(artifactPath)) {
1164
+ checks.push(false);
1165
+ logCheck(log, false, label, 'missing');
1166
+ continue;
1167
+ }
1168
+
1169
+ const content = fs.readFileSync(artifactPath, 'utf-8');
1170
+ const matches = content === artifact.content;
1171
+ checks.push(matches);
1172
+ logCheck(
1173
+ log,
1174
+ matches,
1175
+ label,
1176
+ matches ? 'current' : 'outdated, run `task refresh`'
1177
+ );
997
1178
  }
998
-
999
- const content = fs.readFileSync(skillPath, 'utf-8');
1000
- const matches = content === skill.content;
1001
- checks.push(matches);
1002
- logCheck(
1003
- log,
1004
- matches,
1005
- `${skillRoot}/${skill.name}`,
1006
- matches ? 'current' : 'outdated, run `task refresh`'
1007
- );
1008
1179
  }
1009
1180
 
1010
1181
  for (const skillName of LEGACY_MANAGED_SKILL_NAMES) {