ace-task 0.31.9 → 0.36.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c67dcf6153b34a7d6a72bf8e58bba04945835c1af53ba458391c857f49260ad
4
- data.tar.gz: 68546adc536f8f70b260e6e7315bfa965112322e4e25dc737bde18b25169461d
3
+ metadata.gz: 34781c3bdaae6a3d794b1d2ff7654b80cd0c6df85377960ca85e6b9e3868bf20
4
+ data.tar.gz: a9da028f06155e0dfa3dd24f39c8d625d1768c965e26af2351f6f5e477d3510e
5
5
  SHA512:
6
- metadata.gz: dab5c187c7f4f6c031c3510b37b6f0322e8aa73d2aeb57290d7be2d46120ec7c2ea79f4dc18c37a4bfc2d004f760ba502e7f4c377e61cfaa0c83e901cb5668ae
7
- data.tar.gz: 7dd3dfd6cf4b25ea4180310ed6240ef0d421c9a724c6662bc95b926e846060b6b08cf8adf625648d878c35858268cb96ae702479c621c0398ceaf31287a22a1b
6
+ metadata.gz: '0189d7b62882f379f721d5c34a3e5e0ca4aad445631cddc9ab88ecb46c235eb500df1a633be1ccb9dff9aba5c4267935c037baded1d4a3bdc7a76568c2940a2e'
7
+ data.tar.gz: 755d4133499d1e4f005645affb13a8b723e1f1f48d5739072c25af44e29c172b3b7b068fc7def6e32ebf4a72af8cbcbf88f957e3f990c6fd4fd2711227561a0a
data/CHANGELOG.md CHANGED
@@ -7,6 +7,166 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.36.1] - 2026-04-19
11
+
12
+ ### Technical
13
+ - Decoupled retained create/list/show and archive E2E goals so task root-state evidence is captured before later archive movement.
14
+ - Clarified `TS-TASK-002` plan-path verification so bounded planner timeout diagnostics are accepted as actionable sandbox evidence.
15
+
16
+ ## [0.36.0] - 2026-04-16
17
+
18
+ ### Changed
19
+ - Added `ace-task plan --timeout` so path-based plan generation can be bounded explicitly from the public CLI.
20
+ - Documented bounded plan generation and timeout troubleshooting in the getting-started and usage guides.
21
+
22
+ ### Fixed
23
+ - Converted planner-provider timeout failures into actionable CLI errors instead of surfacing raw timeout backtraces.
24
+ - Updated `TS-TASK-002` path-mode verification to accept explicit timeout diagnostics when plan generation cannot complete within the requested bound.
25
+
26
+ ## [0.35.7] - 2026-04-16
27
+
28
+ ### Fixed
29
+ - Refined `TS-TASK-001` smoke verification around sandbox-root task trees, archive layout, and invalid-status doctor evidence so retained E2E goals track the current public CLI behavior.
30
+
31
+ ## [0.35.6] - 2026-04-15
32
+
33
+ ### Fixed
34
+ - Tightened `TS-TASK-002` plan-path verification to require at least one successful path-mode plan artifact while keeping explicit diagnostics for failed dependency paths.
35
+
36
+ ## [0.35.5] - 2026-04-15
37
+
38
+ ### Changed
39
+ - Reworked retained `TS-TASK-001` goal contracts to use deterministic task-ref handoff artifacts across create/show/update/archive smoke journeys.
40
+ - Added `TS-TASK-002` auxiliary public CLI journeys for `status` and `plan` command coverage, with explicit sandbox diagnostics for unavailable planning dependencies.
41
+ - Updated usage docs with E2E-safe `ace-task plan <ref>` path-mode guidance and `github-sync` precondition examples.
42
+ - Tightened spike-task drafting, review, and work-on-task guidance so spikes must declare whether they are design-contract or proof-of-concept work, define explicit follow-up tasks, and stop implementation flow when runtime work materially drifts from the promised spike contract.
43
+
44
+ ## [0.35.4] - 2026-04-13
45
+
46
+ ### Fixed
47
+ - Reworked `TS-TASK-001` smoke coverage to validate created and archived tasks from stable task-tree state plus runner observations instead of brittle helper files under `results/`.
48
+
49
+ ## [0.35.3] - 2026-04-13
50
+
51
+ ### Fixed
52
+ - Hardened `TS-TASK-001` task-ref capture so create/show/archive smoke coverage derives the persisted short ref from stable list/filesystem evidence instead of brittle prose parsing.
53
+
54
+ ## [0.35.2] - 2026-04-13
55
+
56
+ ### Technical
57
+ - Refreshed `TS-TASK-001` archive and doctor smoke scenario contracts to match the current `_archive` layout and isolate the invalid-status validation path.
58
+
59
+ ## [0.35.1] - 2026-04-13
60
+
61
+ ### Fixed
62
+ - Accepted subtask IDs in task frontmatter ID validation so doctor frontmatter checks no longer report false invalid-ID errors for valid subtasks.
63
+ - Added atomic task-ID reservation during create so concurrent creates treat lock contention as retryable collisions instead of racing through non-atomic prechecks.
64
+
65
+ ### Technical
66
+ - Narrowed task ID-existence scans to ID-prefixed glob matches and added regression coverage for subtask ID validation plus reservation-lock collision behavior.
67
+
68
+ ## [0.35.0] - 2026-04-13
69
+
70
+ ### Fixed
71
+ - Added duplicate persisted task-ID detection to doctor health checks, including subtask collisions and frontmatter-only doctor validation failures.
72
+ - Added bounded retry handling for standalone `ace-task create` ID collisions with clear retry-exhaustion failures and no partial-artifact leakage.
73
+
74
+ ### Technical
75
+ - Added regression coverage for duplicate-ID doctor failures, create-time retry semantics, and cleanup guarantees.
76
+
77
+ ## [0.34.3] - 2026-04-13
78
+
79
+ ### Fixed
80
+ - Added bounded retry handling for standalone `ace-task create` ID collisions so success is emitted only after a unique persisted task ID exists.
81
+ - Added clear retry-exhaustion failure messaging for create-time ID collisions.
82
+
83
+ ### Technical
84
+ - Added command and molecule regression coverage for task ID collision retries and partial-artifact cleanup guarantees.
85
+
86
+ ## [0.34.2] - 2026-04-13
87
+
88
+ ### Fixed
89
+ - Report duplicate persisted task IDs as explicit doctor health-check errors with file-path context, including top-level and subtask collisions.
90
+ - Include duplicate ID detection in `ace-task doctor --check frontmatter` and fail health status when duplicates are present.
91
+
92
+ ### Technical
93
+ - Added organism and CLI regression coverage for duplicate top-level/subtask ID failures and frontmatter-only doctor checks.
94
+
95
+ ## [0.34.1] - 2026-04-13
96
+
97
+ ### Changed
98
+ - Completed the batch i05 migration follow-through for this package and aligned it with the restarted `fast` / `feat` / `e2e` verification model.
99
+
100
+ ### Technical
101
+ - Included in the coordinated assignment-driven patch release for batch i05 package updates.
102
+
103
+
104
+ ### Changed
105
+ - Expanded canonical `as-task-plan` and `as-task-work` skill metadata so public `plan-task` and `work-on-task` assign-step discovery is skill-owned rather than catalog-owned.
106
+
107
+ ## [0.34.0] - 2026-04-12
108
+
109
+ ### Changed
110
+ - Migrated package tests to the restarted `fast` / `feat` / `e2e` model by moving deterministic coverage to `test/fast`, retaining `TS-TASK-001` as workflow-value E2E coverage, and updating package testing guidance.
111
+
112
+ ### Fixed
113
+ - Hardened `TS-TASK-001` sandbox bootstrap and doctor error-path runner setup so repeated E2E runs start from a clean healthy baseline before malformed-task injection.
114
+
115
+ ## [0.33.3] - 2026-04-07
116
+
117
+ ### Changed
118
+ - Added linked GitHub issue metadata handling as a single ownership model and kept task/task manager sync behavior aligned with linked-task life cycle updates.
119
+
120
+ ### Fixed
121
+ - Fixed GitHub sync dispatch and manual sync verification paths by routing through the reusable sync flow and tightening demo-task linkage checks.
122
+
123
+ ### Technical
124
+ - Expanded test coverage around GitHub sync assertions, frontmatter ownership validation, and workflow-level linked issue behavior.
125
+
126
+ ## [0.33.2] - 2026-04-07
127
+
128
+ ### Changed
129
+ - Updated the live GitHub sync demo tape to declare semantic verification expectations for exported issue/task refs, forbidden error output, and final closed-issue state.
130
+
131
+ ## [0.33.1] - 2026-04-07
132
+
133
+ ### Fixed
134
+ - Corrected create-time GitHub sync dispatch so `ace-task` resolves the reusable `sync_task` integration instead of the ownership-validator entrypoint.
135
+ - Fixed the live GitHub sync demo tape to recover the created task ref from slugified task filenames during recording.
136
+
137
+ ## [0.33.0] - 2026-04-07
138
+
139
+ ### Fixed
140
+ - Hardened linked-issue synchronization by loading `ace/git` on the main runtime path, reconciling previous/current issue ID sets during updates, and treating GitHub sync failures as non-blocking task warnings.
141
+ - Surfaced manual `github-sync` failures with per-task error details and an explicit non-zero CLI failure when requested sync work does not complete.
142
+ - Updated linked issue sync payloads to use task spec file paths for sticky comment links so GitHub issue references land on `.s.md` source-of-truth files.
143
+ - Updated `ace-task create` to print non-blocking GitHub sync warnings (`last_update_note`) so create-time linked-issue sync failures are visible to operators.
144
+ - Replaced array-style linked issue metadata with singular `github_issue` ownership and reject duplicate `--github-issue` flags.
145
+
146
+ ### Changed
147
+ - Updated ACE-linked GitHub issue lifecycle guidance to treat task metadata and ACE-managed sync as the canonical path, while keeping PR footer closure keywords as optional manual guidance.
148
+ - Updated linked GitHub issue storage and task-manager sync hooks to enforce one canonical owning task per GitHub issue.
149
+ - Reworked the GitHub sync demo to show live issue creation, task linkage, and automatic issue closure.
150
+
151
+ ### Technical
152
+ - Added linked-issue metadata contract checks to task draft/review workflow instructions and aligned related task spec examples for consistency.
153
+ - Expanded create/update/frontmatter/manager test coverage for singular `github_issue` ownership and conflict handling.
154
+
155
+ ## [0.32.0] - 2026-04-05
156
+
157
+ ### Added
158
+ - Added `ace-task github-sync` command for manual linked-issue synchronization by task reference or `--all`.
159
+ - Added `--github-issue` create-time linkage support for storing machine-readable `github_issue` task metadata.
160
+ - Added lifecycle sync orchestration through `TaskManager` and `GithubIssueSyncAdapter` for linked task create/update/reparent flows.
161
+
162
+ ### Changed
163
+ - Extended task frontmatter defaults to emit structured `github_issue` metadata when linked issues are provided.
164
+ - Updated `ace-task` usage documentation with linked issue create flags and manual sync command usage.
165
+
166
+ ### Technical
167
+ - Added validation rules for `github` and `github_issue` frontmatter structure and numeric issue IDs.
168
+ - Expanded command/organism/validator/defaults test coverage for linked issue metadata and sync behavior.
169
+
10
170
  ## [0.31.9] - 2026-03-31
11
171
 
12
172
  ### Changed
data/README.md CHANGED
@@ -26,6 +26,13 @@ Tasks are markdown specs living in git - attached to branches and worktrees, not
26
26
  2. Review and planning workflows refine scope before implementation.
27
27
  3. Oversee execution through worktrees and assignments until ship-ready.
28
28
 
29
+ ## Testing Model
30
+
31
+ - `ace-test ace-task` runs deterministic package tests (`test/fast`) for the default feedback loop.
32
+ - `ace-test ace-task feat` runs deterministic feature coverage when `test/feat` exists.
33
+ - `ace-test ace-task all` runs all deterministic lanes.
34
+ - `ace-test-e2e ace-task` runs retained real workflow scenarios from `test/e2e`.
35
+
29
36
  ## Use Cases
30
37
 
31
38
  **Draft and structure work** - create a task, split it into subtasks, add new subtasks as work reveals scope. Use `/as-task-draft` to draft from an earlier captured [idea](../ace-idea) or short note, or [`ace-task create`](docs/usage.md#ace-task-create-title) from the CLI.
@@ -3,7 +3,7 @@ name: as-task-draft
3
3
  description: Draft Task with Idea File Movement (SPECS ONLY - no code)
4
4
  # bundle: wfi://task/draft
5
5
  # context: no-fork
6
- # agent: general-purpose
6
+ # agent: Plan
7
7
  user-invocable: true
8
8
  allowed-tools:
9
9
  - Bash(ace-task:*)
@@ -22,3 +22,9 @@ skill:
22
22
  ---
23
23
 
24
24
  Load and run `ace-bundle wfi://task/draft` in the current project, then follow the loaded workflow as the source of truth and execute it end-to-end instead of only summarizing it.
25
+
26
+ This skill is for specification work only.
27
+
28
+ - Create or update draft task artifacts only.
29
+ - Do not implement package code, tests, or runtime behavior changes.
30
+ - If the user later says "implement", treat that as continuing the drafting/spec workflow unless they explicitly switch to `as-task-work` / `wfi://task/work`.
@@ -18,10 +18,15 @@ skill:
18
18
  execution:
19
19
  workflow: wfi://task/plan
20
20
  assign:
21
- source: wfi://task/plan
22
21
  steps:
23
22
  - name: plan-task
24
23
  description: Analyze task requirements and create an implementation plan
24
+ produces: [implementation-plan]
25
+ consumes: [project-base-context, task-spec]
26
+ when_to_skip:
27
+ - "Task is trivial and doesn't need a plan"
28
+ - "Implementation plan already exists"
29
+ effort: light
25
30
  tags: [planning, analysis]
26
31
  context:
27
32
  default: fork
@@ -17,7 +17,6 @@ argument-hint: [task-id like 123]
17
17
  last_modified: 2026-02-17
18
18
  source: ace-task
19
19
  assign:
20
- source: wfi://task/work
21
20
  steps:
22
21
  - name: work-on-task
23
22
  description: Implement task changes following project conventions
@@ -27,6 +26,12 @@ assign:
27
26
  - "implement task"
28
27
  - "task work"
29
28
  - "build feature"
29
+ produces: [code-changes, commits]
30
+ consumes: [project-base-context, task-spec]
31
+ when_to_skip:
32
+ - "Task is documentation-only"
33
+ - "Changes are already implemented"
34
+ effort: medium
30
35
  tags: [implementation, core-workflow]
31
36
  context:
32
37
  default: fork
@@ -185,8 +185,8 @@ Systematically analyze bug reports to identify root cause, verify reproduction,
185
185
  - Purpose: Verify [specific behavior] handles [edge case]
186
186
  - Scenario: When [condition], expect [result]
187
187
 
188
- **Integration Test: [test name]**
189
- - Location: test/integration/[flow]_test.rb
188
+ **Feature Test: [test name]**
189
+ - Location: test/feat/[flow]_test.rb
190
190
  - Purpose: Verify [workflow] completes correctly
191
191
  - Scenario: Given [setup], when [action], then [verification]
192
192
  ```
@@ -357,7 +357,7 @@ Present the analysis to the user in this format:
357
357
  - Purpose: [What it validates]
358
358
 
359
359
  2. **[Test Name]** (integration)
360
- - File: `test/integration/flow_test.rb`
360
+ - File: `test/feat/flow_test.rb`
361
361
  - Purpose: [What it validates]
362
362
 
363
363
  ### Fix Plan
@@ -420,7 +420,7 @@ This workflow provides systematic bug analysis that ensures proper investigation
420
420
  - Purpose: [What it validates]
421
421
 
422
422
  2. **[Test Name]** (integration)
423
- - File: `test/integration/flow_test.rb`
423
+ - File: `test/feat/flow_test.rb`
424
424
  - Purpose: [What it validates]
425
425
 
426
426
  ### Fix Plan
@@ -455,4 +455,4 @@ risks:
455
455
  - "Potential side effect description"
456
456
  rollback_plan: "How to revert if issues arise"
457
457
  </template>
458
- </documents>
458
+ </documents>
@@ -140,7 +140,7 @@ git checkout -b fix/[bug-description]
140
140
 
141
141
  2. **Create integration test if needed:**
142
142
  ```ruby
143
- # Example: test/integration/workflow_test.rb
143
+ # Example: test/feat/workflow_test.rb
144
144
  def test_complete_flow_with_missing_data
145
145
  # Test the full workflow that exhibited the bug
146
146
  end
@@ -509,4 +509,4 @@ The fix is ready for code review and merge.
509
509
  ### Notes
510
510
  [Any additional context about the fix]
511
511
  </template>
512
- </documents>
512
+ </documents>
@@ -172,6 +172,22 @@ This prevents decomposing into subtasks that add concepts the spike later proves
172
172
  **Anti-pattern**: 8 subtasks drafted upfront, each adding features, then a late subtask undoes half.
173
173
  **Correct pattern**: 1 spike subtask validates the end-state, then remaining subtasks build toward it.
174
174
 
175
+ Every spike-first draft must also declare the spike type:
176
+ - **Design-contract spike**: validates target behavior and ownership boundaries, but does not yet claim runnable proof
177
+ - **Proof-of-concept spike**: validates target behavior with runnable proof, not only a design contract
178
+
179
+ For both spike types, the draft must include:
180
+ 1. one **Validated End-State Scenario**
181
+ 2. one **Concept Inventory** with kept / changed / new / rejected outcomes
182
+ 3. one **Adopted Decisions / Rejected Decisions / Deferred Gaps** section
183
+ 4. one **Follow-up Tasks After Spike** section naming the next implementation or adoption work that must happen if the spike succeeds
184
+
185
+ For proof-of-concept spikes, the draft must additionally include:
186
+ 1. one concrete **Proof Artifact Plan** describing what runnable evidence will prove the spike
187
+ 2. success criteria that require the proof artifact, not only the concept inventory
188
+
189
+ Do not treat "we now understand the design" as sufficient spike completion when the spike affects a runtime, UX, or execution-path contract. A useful spike must also leave a clear proof path and explicit next task.
190
+
175
191
  8. **Complete Behavioral Specifications**
176
192
  * For each created draft task, populate with:
177
193
  * Behavioral Specification section with embedded template
@@ -242,6 +258,9 @@ This prevents decomposing into subtasks that add concepts the spike later proves
242
258
  * [ ] Draft is decision-complete: no unresolved behavior choices left for implementer
243
259
  * [ ] Defaults are explicit where behavior could otherwise be ambiguous
244
260
  * [ ] Usage documentation created in `ux/usage.md` (when task changes any API surface)
261
+ * [ ] Spike tasks declare whether they are `design-contract` or `proof-of-concept`
262
+ * [ ] Spike tasks include explicit follow-up task(s) after the spike
263
+ * [ ] Proof-of-concept spikes include a runnable proof artifact plan
245
264
 
246
265
  12. **Run Quality Pass (Better, Not More)**
247
266
  * Perform one concise quality pass before finalizing:
@@ -549,4 +568,4 @@ the decomposition was premature. Consider consolidating remaining subtasks.
549
568
  ## Notes for Implementer
550
569
  - Full usage documentation to be completed during work-on-task step using `wfi://docs/update-usage`
551
570
  </template>
552
- </documents>
571
+ </documents>
@@ -239,6 +239,27 @@ While review-task primarily serves as the draft-to-pending gate, it can provide
239
239
 
240
240
  For non-draft tasks, skip the Readiness Checklist and Promote/Block steps. Focus on content enhancement and question generation only.
241
241
 
242
+ ### Completed Spike Review
243
+
244
+ When the reviewed task is a completed spike, treat spike usefulness as a review target:
245
+
246
+ - Compare the archived spike contract against the shipped public/runtime contract instead of assuming the spike remained accurate.
247
+ - Classify every meaningful difference as exactly one of:
248
+ - **intentional and adopted**
249
+ - **intentional but deferred to follow-up**
250
+ - **spec miss that must be corrected**
251
+ - Verify that the spike left a reusable adoption path:
252
+ - explicit next task(s) exist
253
+ - deferred gaps are named, not implied
254
+ - any promised proof artifact exists if the spike was a proof-of-concept
255
+ - Fail closed on spike usefulness if the spike completed without an explicit follow-up task, even if later implementation succeeded through ad-hoc decisions.
256
+ - In the review summary for completed spikes, explicitly state whether the spike produced:
257
+ - a reusable contract
258
+ - a reusable proof artifact
259
+ - a reusable next-task decision
260
+
261
+ Treat "concept inventory exists" as insufficient by itself for a successful spike review when the spike was meant to guide real runtime or UX work.
262
+
242
263
  ## Decision Guidance
243
264
 
244
265
  ### When to Use This Workflow
@@ -270,6 +291,7 @@ For non-draft tasks, skip the Readiness Checklist and Promote/Block steps. Focus
270
291
  - No loss of existing information
271
292
  - Clear improvement in task clarity or completeness
272
293
  - User receives actionable list of questions to answer (if any)
294
+ - Completed spike reviews identify contract drift and verify explicit follow-up tasks
273
295
 
274
296
  ## Task Management Integration
275
297
 
@@ -41,6 +41,7 @@ To avoid known `--content` stalls in some environments:
41
41
  - `ace-task plan <ref>` (path mode, reuse cached plan when available)
42
42
  - The most recent plan artifact plus current task spec, documented in the step report
43
43
  4. If stalls repeat, add a follow-up fix task and capture evidence in the retrospective.
44
+ 5. If implementation reveals the spec or spike contract is materially wrong, stale, or missing an adoption path, stop and either update the spec or add a follow-up task before continuing.
44
45
 
45
46
  ## Primary Directive
46
47
 
@@ -58,6 +59,7 @@ Work through the plan checklist, step by step:
58
59
  - If the spec says X, implement X — don't gold-plate, don't simplify away requirements
59
60
  - If spec and plan conflict, spec wins — the plan is a HOW, not a WHAT
60
61
  - If the spec is ambiguous or incomplete: stop and ask, don't assume
62
+ - If runtime work materially changes a public contract promised by a spike (flags, naming, fallback behavior, proof surface, ownership boundary), do not silently drift. Update the task/spec or create a follow-up task before release or demo cleanup.
61
63
 
62
64
  **Prior implementation awareness:**
63
65
  - Before creating new modules, search for existing implementations of the same concern — especially spike or prototype code from prior subtasks
@@ -75,6 +77,7 @@ Work through the plan checklist, step by step:
75
77
  - `draft` status: warn the user that the spec hasn't been reviewed, then continue only with explicit confirmation. In unattended/fork contexts where interactive confirmation is not possible, proceed after marking in-progress — the assignment creation layer is responsible for blocking draft tasks before they reach this point.
76
78
  - Mark in-progress before first change, done after last verification
77
79
  - Never modify task frontmatter directly — use `ace-task update <ref> --set key=value`
80
+ - If the task implements a spike outcome, verify before marking done that deferred gaps and adoption follow-ups are explicit rather than left implicit in release notes or retrospectives.
78
81
 
79
82
  ## Code Conventions
80
83
 
@@ -18,7 +18,17 @@ module Ace
18
18
  # @param created_at [Time, nil] Creation time
19
19
  # @param parent [String, nil] Parent task ID for subtasks
20
20
  # @return [Hash] Frontmatter hash
21
- def self.build(id:, status: "pending", priority: nil, tags: [], dependencies: [], created_at: nil, parent: nil, estimate: nil)
21
+ def self.build(
22
+ id:,
23
+ status: "pending",
24
+ priority: nil,
25
+ tags: [],
26
+ dependencies: [],
27
+ created_at: nil,
28
+ parent: nil,
29
+ estimate: nil,
30
+ github_issue: nil
31
+ )
22
32
  fm = {
23
33
  "id" => id,
24
34
  "status" => status || "pending",
@@ -29,6 +39,7 @@ module Ace
29
39
  fm["dependencies"] = dependencies || []
30
40
  fm["tags"] = tags || []
31
41
  fm["parent"] = parent if parent
42
+ fm["github_issue"] = github_issue if github_issue
32
43
  fm
33
44
  end
34
45
 
@@ -19,7 +19,7 @@ module Ace
19
19
  end
20
20
 
21
21
  def self.valid_id?(id)
22
- id.to_s.match?(/^[0-9a-z]{3}\.[a-z]\.[0-9a-z]{3}$/)
22
+ id.to_s.match?(/\A[0-9a-z]{3}\.[a-z]\.[0-9a-z]{3}(?:\.[0-9a-z])?\z/)
23
23
  end
24
24
 
25
25
  def self.scope_consistent?(status, special_folder)
@@ -20,6 +20,7 @@ module Ace
20
20
  '"Fix login bug" # Create task with title',
21
21
  '"Fix auth" --priority high --tags auth,security # With priority and tags',
22
22
  '"Setup DB" --child-of q7w # Create as subtask',
23
+ '"Track issue" --github-issue 276 # Link GitHub issue',
23
24
  '"Quick task" --in maybe # Create in _maybe/ folder',
24
25
  '"Draft spec" --status draft --estimate TBD # Create as draft with estimate',
25
26
  '"Preview only" --dry-run # Show what would be created'
@@ -31,6 +32,7 @@ module Ace
31
32
  option :tags, type: :string, aliases: %w[-T], desc: "Tags (comma-separated)"
32
33
  option :status, type: :string, aliases: %w[-s], desc: "Initial status (draft, pending, blocked, ...)"
33
34
  option :estimate, type: :string, aliases: %w[-e], desc: "Effort estimate (e.g. TBD, 2h, 1d)"
35
+ option :"github-issue", type: :array, desc: "Linked GitHub issue number"
34
36
  option :"child-of", type: :string, desc: "Parent task reference (creates subtask)"
35
37
  option :in, type: :string, aliases: %w[-i], desc: "Target folder (e.g. next, maybe)"
36
38
  option :"dry-run", type: :boolean, aliases: %w[-n], desc: "Preview without writing"
@@ -48,6 +50,7 @@ module Ace
48
50
  tags = tags_str ? tags_str.split(",").map(&:strip).reject(&:empty?) : []
49
51
  status = options[:status]
50
52
  estimate = options[:estimate]
53
+ github_issue = parse_github_issue(options[:"github-issue"])
51
54
  child_of = options[:"child-of"]
52
55
  in_folder = options[:in]
53
56
 
@@ -64,6 +67,7 @@ module Ace
64
67
  puts " Status: #{status}" if status
65
68
  puts " Priority: #{priority}" if priority
66
69
  puts " Estimate: #{estimate}" if estimate
70
+ puts " GitHub: #{github_issue}" if github_issue
67
71
  puts " Tags: #{tags.join(", ")}" if tags.any?
68
72
  puts " Parent: #{child_of}" if child_of
69
73
  puts " Folder: #{in_folder}" if in_folder
@@ -72,10 +76,29 @@ module Ace
72
76
 
73
77
  manager = Ace::Task::Organisms::TaskManager.new
74
78
 
75
- task = if child_of
76
- manager.create_subtask(child_of, title, status: status, priority: priority, tags: tags, estimate: estimate)
77
- else
78
- manager.create(title, status: status, priority: priority, tags: tags, estimate: estimate)
79
+ task = begin
80
+ if child_of
81
+ manager.create_subtask(
82
+ child_of,
83
+ title,
84
+ status: status,
85
+ priority: priority,
86
+ tags: tags,
87
+ estimate: estimate,
88
+ github_issue: github_issue
89
+ )
90
+ else
91
+ manager.create(
92
+ title,
93
+ status: status,
94
+ priority: priority,
95
+ tags: tags,
96
+ estimate: estimate,
97
+ github_issue: github_issue
98
+ )
99
+ end
100
+ rescue Ace::Task::Organisms::TaskManager::CreateRetriesExhaustedError => e
101
+ raise Ace::Support::Cli::Error, e.message
79
102
  end
80
103
 
81
104
  unless task
@@ -90,6 +113,9 @@ module Ace
90
113
 
91
114
  puts "Created task #{task.id}"
92
115
  puts " Path: #{task.file_path}"
116
+ if manager.last_update_note && !manager.last_update_note.strip.empty?
117
+ puts "Info: #{manager.last_update_note}"
118
+ end
93
119
 
94
120
  if options[:git_commit]
95
121
  Ace::Support::Items::Molecules::GitCommitter.commit(
@@ -98,6 +124,22 @@ module Ace
98
124
  )
99
125
  end
100
126
  end
127
+
128
+ private
129
+
130
+ def parse_github_issue(raw_values)
131
+ values = Array(raw_values).flatten.compact
132
+ return nil if values.empty?
133
+ raise Ace::Support::Cli::Error.new("Only one --github-issue may be provided") if values.length > 1
134
+
135
+ candidate = values.first.to_s.strip
136
+ raise Ace::Support::Cli::Error.new("Invalid GitHub issue '#{values.first}': expected numeric ID") unless candidate.match?(/\A\d+\z/)
137
+
138
+ id = candidate.to_i
139
+ raise Ace::Support::Cli::Error.new("Invalid GitHub issue '#{values.first}': expected positive numeric ID") if id <= 0
140
+
141
+ id
142
+ end
101
143
  end
102
144
  end
103
145
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ace/support/cli"
4
+
5
+ module Ace
6
+ module Task
7
+ module CLI
8
+ module Commands
9
+ # ace-support-cli Command class for ace-task github-sync
10
+ class GithubSync < Ace::Support::Cli::Command
11
+ include Ace::Support::Cli::Base
12
+
13
+ desc <<~DESC.strip
14
+ Synchronize linked GitHub issues for a task or all linked tasks
15
+ DESC
16
+
17
+ example [
18
+ "q7w # Sync one task",
19
+ "--all # Sync all linked tasks"
20
+ ]
21
+
22
+ argument :ref, required: false, desc: "Task reference (full ID, short ref, or suffix)"
23
+ option :all, type: :boolean, aliases: %w[-a], desc: "Sync all linked tasks"
24
+
25
+ option :quiet, type: :boolean, aliases: %w[-q], desc: "Suppress non-essential output"
26
+ option :verbose, type: :boolean, aliases: %w[-v], desc: "Show verbose output"
27
+ option :debug, type: :boolean, aliases: %w[-d], desc: "Show debug output"
28
+
29
+ def call(ref: nil, **options)
30
+ all = options[:all]
31
+
32
+ if !all && (ref.nil? || ref.strip.empty?)
33
+ raise Ace::Support::Cli::Error.new("Provide a task reference or use --all")
34
+ end
35
+
36
+ manager = Ace::Task::Organisms::TaskManager.new
37
+ result = manager.github_sync(ref: ref, all: all)
38
+ raise Ace::Support::Cli::Error.new("Task '#{ref}' not found") if result.nil?
39
+ print_failures(result[:failures])
40
+
41
+ if result[:failed].to_i.positive?
42
+ raise Ace::Support::Cli::Error.new(
43
+ "GitHub sync incomplete: synced #{result[:synced]}, failed #{result[:failed]}, skipped #{result[:skipped]}"
44
+ )
45
+ elsif all
46
+ puts "GitHub sync complete: synced #{result[:synced]} linked task(s), skipped #{result[:skipped]} task(s)"
47
+ elsif result[:synced].positive?
48
+ puts "GitHub sync complete: #{result[:task_id]}"
49
+ else
50
+ puts "No linked GitHub issues for task #{result[:task_id]}"
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def print_failures(failures)
57
+ Array(failures).each do |failure|
58
+ warn "GitHub sync failed for #{failure[:task_id]}: #{failure[:error]}"
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -24,6 +24,7 @@ module Ace
24
24
  "q7w # Reuse fresh plan or generate new",
25
25
  "q7w --refresh # Force regeneration",
26
26
  "q7w --content # Print full plan content",
27
+ "q7w --timeout 30 # Fail fast if plan generation stalls",
27
28
  "q7w --model gemini:flash-latest # Override planning model"
28
29
  ]
29
30
 
@@ -32,6 +33,7 @@ module Ace
32
33
  option :refresh, type: :boolean, desc: "Force plan regeneration"
33
34
  option :content, type: :boolean, desc: "Print full plan content instead of path"
34
35
  option :model, type: :string, desc: "Provider:model override for plan generation"
36
+ option :timeout, type: :integer, desc: "LLM request timeout in seconds for plan generation"
35
37
 
36
38
  option :quiet, type: :boolean, aliases: %w[-q], desc: "Suppress non-essential output"
37
39
  option :verbose, type: :boolean, aliases: %w[-v], desc: "Show verbose output"
@@ -58,7 +60,7 @@ module Ace
58
60
 
59
61
  context_files = capture_context_files(task)
60
62
  model = options[:model] || default_model(config)
61
- generator = plan_generator(model)
63
+ generator = plan_generator(model, timeout: options[:timeout])
62
64
  content = generator.generate(
63
65
  task: task,
64
66
  context_files: context_files,
@@ -104,13 +106,15 @@ module Ace
104
106
  end
105
107
  end
106
108
 
107
- def plan_generator(model, cli_args: nil)
109
+ def plan_generator(model, cli_args: nil, timeout: nil)
108
110
  klass = self.class.generator_class || Molecules::TaskPlanGenerator
109
- klass.new(model: model, cli_args: cli_args)
111
+ kwargs = {model: model, cli_args: cli_args}
112
+ kwargs[:timeout] = timeout if timeout
113
+ klass.new(**kwargs)
110
114
  end
111
115
 
112
116
  def default_model(config)
113
- config.dig("task", "plan", "model") || "gemini:flash-latest"
117
+ config.dig("task", "plan", "model") || "role:planner"
114
118
  end
115
119
  end
116
120
  end