@shepai/cli 1.52.2 → 1.53.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 (179) hide show
  1. package/apis/json-schema/CiFixRecord.yaml +24 -0
  2. package/apis/json-schema/Feature.yaml +3 -0
  3. package/apis/json-schema/PullRequest.yaml +10 -0
  4. package/apis/json-schema/SdlcLifecycle.yaml +1 -0
  5. package/apis/json-schema/WorkflowConfig.yaml +15 -0
  6. package/dist/packages/core/src/application/ports/output/repositories/feature-repository.interface.d.ts +8 -0
  7. package/dist/packages/core/src/application/ports/output/repositories/feature-repository.interface.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +12 -0
  9. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/use-cases/features/check-and-unblock-features.use-case.d.ts +30 -0
  11. package/dist/packages/core/src/application/use-cases/features/check-and-unblock-features.use-case.d.ts.map +1 -0
  12. package/dist/packages/core/src/application/use-cases/features/check-and-unblock-features.use-case.js +74 -0
  13. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  14. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +60 -16
  15. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
  16. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  17. package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts.map +1 -1
  18. package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.js +11 -4
  19. package/dist/packages/core/src/application/use-cases/features/update/update-feature-lifecycle.use-case.d.ts +28 -0
  20. package/dist/packages/core/src/application/use-cases/features/update/update-feature-lifecycle.use-case.d.ts.map +1 -0
  21. package/dist/packages/core/src/application/use-cases/features/update/update-feature-lifecycle.use-case.js +53 -0
  22. package/dist/packages/core/src/domain/generated/output.d.ts +47 -1
  23. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  24. package/dist/packages/core/src/domain/generated/output.js +1 -0
  25. package/dist/packages/core/src/domain/lifecycle-gates.d.ts +16 -0
  26. package/dist/packages/core/src/domain/lifecycle-gates.d.ts.map +1 -0
  27. package/dist/packages/core/src/domain/lifecycle-gates.js +19 -0
  28. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  29. package/dist/packages/core/src/infrastructure/di/container.js +12 -0
  30. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +3 -0
  31. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
  32. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +8 -0
  33. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
  34. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +28 -1
  35. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts +1 -0
  36. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
  37. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +12 -0
  38. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +52 -1
  39. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
  40. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js +1 -1
  41. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  42. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +7 -2
  43. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/lifecycle-context.d.ts +27 -5
  44. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/lifecycle-context.d.ts.map +1 -1
  45. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/lifecycle-context.js +19 -16
  46. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-helpers.d.ts +24 -0
  47. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-helpers.d.ts.map +1 -0
  48. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-helpers.js +47 -0
  49. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.d.ts +43 -0
  50. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.d.ts.map +1 -0
  51. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.js +118 -0
  52. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.d.ts.map +1 -0
  53. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/{merge.node.d.ts → merge/merge.node.d.ts} +10 -4
  54. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -0
  55. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/{merge.node.js → merge/merge.node.js} +44 -17
  56. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts +12 -0
  57. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  58. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +38 -0
  59. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +4 -1
  60. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts.map +1 -1
  61. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.js +13 -0
  62. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +2 -0
  63. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
  64. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +29 -1
  65. package/dist/src/presentation/cli/commands/feat/ls.command.d.ts.map +1 -1
  66. package/dist/src/presentation/cli/commands/feat/ls.command.js +39 -3
  67. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  68. package/dist/src/presentation/cli/commands/feat/new.command.js +18 -0
  69. package/dist/src/presentation/cli/commands/feat/show.command.d.ts.map +1 -1
  70. package/dist/src/presentation/cli/commands/feat/show.command.js +20 -0
  71. package/dist/src/presentation/web/app/actions/create-feature.d.ts +1 -0
  72. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  73. package/dist/src/presentation/web/app/actions/create-feature.js +2 -1
  74. package/dist/src/presentation/web/app/page.d.ts.map +1 -1
  75. package/dist/src/presentation/web/app/page.js +34 -6
  76. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +11 -1
  77. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  78. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +52 -5
  79. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
  80. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +4 -0
  81. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +1 -1
  82. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  83. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +13 -4
  84. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +2 -0
  85. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  86. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +26 -8
  87. package/dist/src/presentation/web/components/features/features-canvas/dependency-edge.d.ts +7 -0
  88. package/dist/src/presentation/web/components/features/features-canvas/dependency-edge.d.ts.map +1 -0
  89. package/dist/src/presentation/web/components/features/features-canvas/dependency-edge.js +20 -0
  90. package/dist/src/presentation/web/components/features/features-canvas/dependency-edge.stories.d.ts +6 -0
  91. package/dist/src/presentation/web/components/features/features-canvas/dependency-edge.stories.d.ts.map +1 -0
  92. package/dist/src/presentation/web/components/features/features-canvas/dependency-edge.stories.js +58 -0
  93. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  94. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +5 -1
  95. package/dist/tsconfig.build.tsbuildinfo +1 -1
  96. package/package.json +1 -1
  97. package/web/.next/BUILD_ID +1 -1
  98. package/web/.next/build-manifest.json +2 -2
  99. package/web/.next/cache/.previewinfo +1 -1
  100. package/web/.next/cache/.rscinfo +1 -1
  101. package/web/.next/cache/.tsbuildinfo +1 -1
  102. package/web/.next/cache/config.json +3 -3
  103. package/web/.next/fallback-build-manifest.json +2 -2
  104. package/web/.next/prerender-manifest.json +3 -3
  105. package/web/.next/required-server-files.js +1 -1
  106. package/web/.next/required-server-files.json +1 -1
  107. package/web/.next/server/app/_global-error.html +2 -2
  108. package/web/.next/server/app/_global-error.rsc +1 -1
  109. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  110. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  111. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  112. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  113. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  114. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  115. package/web/.next/server/app/page/server-reference-manifest.json +14 -14
  116. package/web/.next/server/app/page.js.nft.json +1 -1
  117. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  118. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  119. package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +2 -2
  120. package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js.map +1 -1
  121. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  122. package/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js +2 -2
  123. package/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/_1fafa9db._.js +1 -1
  125. package/web/.next/server/chunks/ssr/_1fafa9db._.js.map +1 -1
  126. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  127. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
  128. package/web/.next/server/pages/500.html +2 -2
  129. package/web/.next/server/server-reference-manifest.js +1 -1
  130. package/web/.next/server/server-reference-manifest.json +15 -15
  131. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  132. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  133. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  134. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  135. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  136. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  137. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  138. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  139. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  140. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  141. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  142. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  143. package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +14 -14
  144. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
  145. package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
  146. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  147. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +2 -2
  148. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  149. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js +2 -2
  150. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_1fafa9db._.js +1 -1
  151. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  152. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  153. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  154. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +15 -15
  155. package/web/.next/standalone/src/presentation/web/app/actions/create-feature.ts +4 -1
  156. package/web/.next/standalone/src/presentation/web/app/page.tsx +36 -6
  157. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +199 -2
  158. package/web/.next/standalone/src/presentation/web/components/common/feature-node/derive-feature-state.ts +5 -0
  159. package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.tsx +1 -1
  160. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +20 -1
  161. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +43 -12
  162. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/dependency-edge.stories.tsx +81 -0
  163. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/dependency-edge.tsx +29 -0
  164. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +9 -0
  165. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  166. package/web/.next/static/chunks/48309f9ad2a84b15.css +2 -0
  167. package/web/.next/static/chunks/5123ae1490fd2606.js +10 -0
  168. package/web/.next/static/chunks/{31e5030eed01a941.js → 68fb91b6eca14536.js} +1 -1
  169. package/web/.next/trace +1 -1
  170. package/web/.next/trace-build +1 -1
  171. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge-output-parser.d.ts.map +0 -1
  172. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +0 -1
  173. package/web/.next/static/chunks/23cae32e6f42833d.js +0 -10
  174. package/web/.next/static/chunks/59b8bd47023e0249.css +0 -2
  175. /package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/{merge-output-parser.d.ts → merge/merge-output-parser.d.ts} +0 -0
  176. /package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/{merge-output-parser.js → merge/merge-output-parser.js} +0 -0
  177. /package/web/.next/static/{-c2lwSbfsfZHNnfB5CogT → OXSWdTgy-1XJBN9IJtQPz}/_buildManifest.js +0 -0
  178. /package/web/.next/static/{-c2lwSbfsfZHNnfB5CogT → OXSWdTgy-1XJBN9IJtQPz}/_clientMiddlewareManifest.json +0 -0
  179. /package/web/.next/static/{-c2lwSbfsfZHNnfB5CogT → OXSWdTgy-1XJBN9IJtQPz}/_ssgManifest.js +0 -0
@@ -0,0 +1,24 @@
1
+ $schema: https://json-schema.org/draft/2020-12/schema
2
+ $id: CiFixRecord.yaml
3
+ type: object
4
+ properties:
5
+ attempt:
6
+ type: integer
7
+ minimum: -2147483648
8
+ maximum: 2147483647
9
+ description: 1-based attempt number
10
+ startedAt:
11
+ type: string
12
+ description: ISO timestamp when this attempt started
13
+ failureSummary:
14
+ type: string
15
+ description: First 500 chars of failure logs for this attempt
16
+ outcome:
17
+ type: string
18
+ description: "Outcome of this attempt: fixed, failed, or timeout"
19
+ required:
20
+ - attempt
21
+ - startedAt
22
+ - failureSummary
23
+ - outcome
24
+ description: Record of one CI fix attempt in the watch/fix loop
@@ -62,6 +62,9 @@ properties:
62
62
  pr:
63
63
  $ref: PullRequest.yaml
64
64
  description: Pull request data (null until PR created)
65
+ parentId:
66
+ $ref: UUID.yaml
67
+ description: Parent feature ID for dependency tracking (optional)
65
68
  required:
66
69
  - name
67
70
  - userQuery
@@ -19,6 +19,16 @@ properties:
19
19
  ciStatus:
20
20
  $ref: CiStatus.yaml
21
21
  description: CI pipeline status
22
+ ciFixAttempts:
23
+ type: integer
24
+ minimum: -2147483648
25
+ maximum: 2147483647
26
+ description: Number of CI fix attempts made
27
+ ciFixHistory:
28
+ type: array
29
+ items:
30
+ $ref: CiFixRecord.yaml
31
+ description: History of CI fix attempts
22
32
  required:
23
33
  - url
24
34
  - number
@@ -10,4 +10,5 @@ enum:
10
10
  - Implementation
11
11
  - Review
12
12
  - Maintain
13
+ - Blocked
13
14
  description: Software Development Lifecycle stages for feature progression
@@ -9,6 +9,21 @@ properties:
9
9
  approvalGateDefaults:
10
10
  $ref: ApprovalGateDefaults.yaml
11
11
  description: Default approval gate preferences for new features
12
+ ciMaxFixAttempts:
13
+ type: integer
14
+ minimum: -2147483648
15
+ maximum: 2147483647
16
+ description: "Maximum number of CI fix/push/watch iterations before giving up (default: 3)"
17
+ ciWatchTimeoutMs:
18
+ type: integer
19
+ minimum: -2147483648
20
+ maximum: 2147483647
21
+ description: "Timeout in milliseconds for watching a CI run (default: 600000 = 10 minutes)"
22
+ ciLogMaxChars:
23
+ type: integer
24
+ minimum: -2147483648
25
+ maximum: 2147483647
26
+ description: "Maximum characters of CI failure logs to pass to the executor (default: 50000)"
12
27
  required:
13
28
  - openPrOnImplementationComplete
14
29
  - approvalGateDefaults
@@ -66,6 +66,14 @@ export interface IFeatureRepository {
66
66
  * @param feature - The feature with updated fields
67
67
  */
68
68
  update(feature: Feature): Promise<void>;
69
+ /**
70
+ * Returns all direct (non-recursive) children of the given parent feature ID.
71
+ * Children are ordered by creation time ascending.
72
+ *
73
+ * @param parentId - The parent feature ID
74
+ * @returns Array of direct child features
75
+ */
76
+ findByParentId(parentId: string): Promise<Feature[]>;
69
77
  /**
70
78
  * Delete a feature by ID.
71
79
  *
@@ -1 +1 @@
1
- {"version":3,"file":"feature-repository.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/repositories/feature-repository.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAErF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAExD;;;;;;OAMG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE1E;;;;;OAKG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEvD;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC"}
1
+ {"version":3,"file":"feature-repository.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/repositories/feature-repository.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAErF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAExD;;;;;;OAMG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE1E;;;;;OAKG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEvD;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;;;OAMG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAErD;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC"}
@@ -189,5 +189,17 @@ export interface IGitPrService {
189
189
  * @returns True if featureBranch is an ancestor of baseBranch
190
190
  */
191
191
  verifyMerge(cwd: string, featureBranch: string, baseBranch: string): Promise<boolean>;
192
+ /**
193
+ * Retrieve failure logs for a CI run via `gh run view --log-failed`.
194
+ * Output is truncated to the first `logMaxChars` characters (head truncation).
195
+ * A notice is appended when truncation occurs.
196
+ *
197
+ * @param runId - GitHub Actions run ID (numeric string)
198
+ * @param branch - Branch name (informational, used in truncation notice)
199
+ * @param logMaxChars - Maximum characters to return (default 50_000)
200
+ * @returns Truncated failure log output
201
+ * @throws GitPrError with GH_NOT_FOUND or GIT_ERROR code on failure
202
+ */
203
+ getFailureLogs(runId: string, branch: string, logMaxChars?: number): Promise<string>;
192
204
  }
193
205
  //# sourceMappingURL=git-pr-service.interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-pr-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/git-pr-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,oBAAY,cAAc;IACxB,cAAc,mBAAmB;IACjC,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,UAAU,eAAe;IACzB,gBAAgB,qBAAqB;IACrC,SAAS,cAAc;IACvB,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;CAC9B;AAED;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;aAGjB,IAAI,EAAE,cAAc;aACpB,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,cAAc,EACpB,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,MAAM,EAAE,QAAQ,CAAC;IACjB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEzC;;;;;;;;OAQG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/C;;;;;;OAMG;IACH,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAErD;;;;;;;OAOG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzD;;;;;;;OAOG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExE;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEnE;;;;;;;OAOG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhF;;;;;;;OAOG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpF;;;;;;;OAOG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAElE;;;;;;;;OAQG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAElF;;;;;;;OAOG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjF;;;;;;;OAOG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAExE;;;;;;;;;OASG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvF"}
1
+ {"version":3,"file":"git-pr-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/git-pr-service.interface.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * CheckAndUnblockFeaturesUseCase
3
+ *
4
+ * Evaluates whether blocked direct children of a parent feature are now
5
+ * eligible to start, and if so transitions them to Started and spawns their
6
+ * agents.
7
+ *
8
+ * Business Rules:
9
+ * - Only direct children of parentFeatureId are evaluated (no recursive traversal).
10
+ * Grandchildren stay Blocked until their own direct parent progresses.
11
+ * - Gate: parent lifecycle must be in POST_IMPLEMENTATION (Implementation, Review, Maintain).
12
+ * - Idempotent: already-Started children are not touched; calling execute() twice is safe.
13
+ * - spawn() is skipped for children missing agentRunId or specPath (defensive guard).
14
+ *
15
+ * Called from: UpdateFeatureLifecycleUseCase after every lifecycle transition.
16
+ */
17
+ import type { IFeatureRepository } from '../../ports/output/repositories/feature-repository.interface.js';
18
+ import type { IFeatureAgentProcessService } from '../../ports/output/agents/feature-agent-process.interface.js';
19
+ export declare class CheckAndUnblockFeaturesUseCase {
20
+ private readonly featureRepo;
21
+ private readonly agentProcess;
22
+ constructor(featureRepo: IFeatureRepository, agentProcess: IFeatureAgentProcessService);
23
+ /**
24
+ * Check and unblock direct children of the given parent feature.
25
+ *
26
+ * @param parentFeatureId - ID of the feature whose children should be evaluated.
27
+ */
28
+ execute(parentFeatureId: string): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=check-and-unblock-features.use-case.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-and-unblock-features.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/check-and-unblock-features.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAGhH,qBACa,8BAA8B;IAET,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE1D,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAFkB,WAAW,EAAE,kBAAkB,EAE7D,YAAY,EAAE,2BAA2B;IAG5D;;;;OAIG;IACG,OAAO,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiCtD"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * CheckAndUnblockFeaturesUseCase
3
+ *
4
+ * Evaluates whether blocked direct children of a parent feature are now
5
+ * eligible to start, and if so transitions them to Started and spawns their
6
+ * agents.
7
+ *
8
+ * Business Rules:
9
+ * - Only direct children of parentFeatureId are evaluated (no recursive traversal).
10
+ * Grandchildren stay Blocked until their own direct parent progresses.
11
+ * - Gate: parent lifecycle must be in POST_IMPLEMENTATION (Implementation, Review, Maintain).
12
+ * - Idempotent: already-Started children are not touched; calling execute() twice is safe.
13
+ * - spawn() is skipped for children missing agentRunId or specPath (defensive guard).
14
+ *
15
+ * Called from: UpdateFeatureLifecycleUseCase after every lifecycle transition.
16
+ */
17
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
18
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
22
+ };
23
+ var __metadata = (this && this.__metadata) || function (k, v) {
24
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25
+ };
26
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
27
+ return function (target, key) { decorator(target, key, paramIndex); }
28
+ };
29
+ import { injectable, inject } from 'tsyringe';
30
+ import { SdlcLifecycle } from '../../../domain/generated/output.js';
31
+ import { POST_IMPLEMENTATION } from '../../../domain/lifecycle-gates.js';
32
+ let CheckAndUnblockFeaturesUseCase = class CheckAndUnblockFeaturesUseCase {
33
+ featureRepo;
34
+ agentProcess;
35
+ constructor(featureRepo, agentProcess) {
36
+ this.featureRepo = featureRepo;
37
+ this.agentProcess = agentProcess;
38
+ }
39
+ /**
40
+ * Check and unblock direct children of the given parent feature.
41
+ *
42
+ * @param parentFeatureId - ID of the feature whose children should be evaluated.
43
+ */
44
+ async execute(parentFeatureId) {
45
+ // Load parent and verify gate
46
+ const parent = await this.featureRepo.findById(parentFeatureId);
47
+ if (!parent || !POST_IMPLEMENTATION.has(parent.lifecycle)) {
48
+ return;
49
+ }
50
+ // Load direct children
51
+ const children = await this.featureRepo.findByParentId(parentFeatureId);
52
+ // Unblock each blocked child
53
+ for (const child of children) {
54
+ if (child.lifecycle !== SdlcLifecycle.Blocked) {
55
+ continue;
56
+ }
57
+ // Transition to Started
58
+ child.lifecycle = SdlcLifecycle.Started;
59
+ child.updatedAt = new Date();
60
+ await this.featureRepo.update(child);
61
+ // Spawn agent using fields set at feature creation time
62
+ if (child.agentRunId && child.specPath) {
63
+ this.agentProcess.spawn(child.id, child.agentRunId, child.repositoryPath, child.specPath, child.worktreePath);
64
+ }
65
+ }
66
+ }
67
+ };
68
+ CheckAndUnblockFeaturesUseCase = __decorate([
69
+ injectable(),
70
+ __param(0, inject('IFeatureRepository')),
71
+ __param(1, inject('IFeatureAgentProcessService')),
72
+ __metadata("design:paramtypes", [Object, Object])
73
+ ], CheckAndUnblockFeaturesUseCase);
74
+ export { CheckAndUnblockFeaturesUseCase };
@@ -1 +1 @@
1
- {"version":3,"file":"create-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/use-cases/features/create/create-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oEAAoE,CAAC;AAC7G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8DAA8D,CAAC;AACrG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iEAAiE,CAAC;AACnH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gEAAgE,CAAC;AAC1G,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8DAA8D,CAAC;AAC5G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uEAAuE,CAAC;AACnH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4DAA4D,CAAC;AAEhG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAEhC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAhBZ,WAAW,EAAE,kBAAkB,EAE/B,eAAe,EAAE,gBAAgB,EAEjC,YAAY,EAAE,2BAA2B,EAEzC,aAAa,EAAE,mBAAmB,EAElC,eAAe,EAAE,uBAAuB,EAExC,iBAAiB,EAAE,iBAAiB,EAEpC,YAAY,EAAE,YAAY,EAE1B,cAAc,EAAE,qBAAqB,EAErC,YAAY,EAAE,aAAa;IAGxC,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAwGvE"}
1
+ {"version":3,"file":"create-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/use-cases/features/create/create-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oEAAoE,CAAC;AAC7G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8DAA8D,CAAC;AACrG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iEAAiE,CAAC;AACnH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gEAAgE,CAAC;AAC1G,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8DAA8D,CAAC;AAC5G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uEAAuE,CAAC;AACnH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4DAA4D,CAAC;AAGhG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAEhC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAhBZ,WAAW,EAAE,kBAAkB,EAE/B,eAAe,EAAE,gBAAgB,EAEjC,YAAY,EAAE,2BAA2B,EAEzC,aAAa,EAAE,mBAAmB,EAElC,eAAe,EAAE,uBAAuB,EAExC,iBAAiB,EAAE,iBAAiB,EAEpC,YAAY,EAAE,YAAY,EAE1B,cAAc,EAAE,qBAAqB,EAErC,YAAY,EAAE,aAAa;IAGxC,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAyJvE"}
@@ -31,6 +31,7 @@ import { injectable, inject } from 'tsyringe';
31
31
  import { randomUUID } from 'node:crypto';
32
32
  import { SdlcLifecycle, AgentRunStatus } from '../../../../domain/generated/output.js';
33
33
  import { getSettings } from '../../../../infrastructure/services/settings.service.js';
34
+ import { POST_IMPLEMENTATION } from '../../../../domain/lifecycle-gates.js';
34
35
  import { MetadataGenerator } from './metadata-generator.js';
35
36
  import { SlugResolver } from './slug-resolver.js';
36
37
  let CreateFeatureUseCase = class CreateFeatureUseCase {
@@ -55,28 +56,67 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
55
56
  this.gitPrService = gitPrService;
56
57
  }
57
58
  async execute(input) {
59
+ // Resolve parent feature and determine child initial lifecycle (FR-8, FR-9, FR-12, FR-19)
60
+ let initialLifecycle = SdlcLifecycle.Requirements;
61
+ let shouldSpawn = true;
62
+ // When creating a child feature, always use the parent's repositoryPath (the
63
+ // original repo root), not the caller's cwd which may be a worktree (FR-10).
64
+ let effectiveRepoPath = input.repositoryPath;
65
+ if (input.parentId) {
66
+ const parent = await this.featureRepo.findById(input.parentId);
67
+ if (!parent) {
68
+ throw new Error(`Parent feature not found: ${input.parentId}`);
69
+ }
70
+ // Use the parent's repositoryPath so the child worktree branches from the
71
+ // original repo, not from inside another worktree.
72
+ effectiveRepoPath = parent.repositoryPath;
73
+ // Cycle detection — O(depth) upward walk through ancestor chain (FR-19)
74
+ const visited = new Set([input.parentId]);
75
+ let cursor = parent.parentId;
76
+ while (cursor) {
77
+ if (visited.has(cursor)) {
78
+ throw new Error(`Cycle detected in feature dependency chain at feature: ${cursor}`);
79
+ }
80
+ visited.add(cursor);
81
+ const ancestor = await this.featureRepo.findById(cursor);
82
+ cursor = ancestor?.parentId ?? undefined;
83
+ }
84
+ // Two-gate lifecycle logic (FR-9):
85
+ // parent.lifecycle === Blocked → cascade block (FR-12)
86
+ // parent.lifecycle not in POST_IMPLEMENTATION → early gate not met → Blocked
87
+ // parent.lifecycle in POST_IMPLEMENTATION → gate satisfied → Started
88
+ if (parent.lifecycle === SdlcLifecycle.Blocked ||
89
+ !POST_IMPLEMENTATION.has(parent.lifecycle)) {
90
+ initialLifecycle = SdlcLifecycle.Blocked;
91
+ shouldSpawn = false;
92
+ }
93
+ else {
94
+ initialLifecycle = SdlcLifecycle.Started;
95
+ shouldSpawn = true;
96
+ }
97
+ }
58
98
  // Ensure the target directory is a git repository (auto-init if needed)
59
99
  // Must run before slug resolution which needs git commands
60
- await this.worktreeService.ensureGitRepository(input.repositoryPath);
100
+ await this.worktreeService.ensureGitRepository(effectiveRepoPath);
61
101
  const metadata = await this.metadataGenerator.generateMetadata(input.userInput);
62
102
  const originalSlug = metadata.slug;
63
103
  // Find a unique slug — the branch may exist from a previous (deleted) feature
64
- const { slug, branch, warning } = await this.slugResolver.resolveUniqueSlug(originalSlug, input.repositoryPath);
104
+ const { slug, branch, warning } = await this.slugResolver.resolveUniqueSlug(originalSlug, effectiveRepoPath);
65
105
  // Determine next feature number for this repo
66
106
  const existingFeatures = await this.featureRepo.list({
67
- repositoryPath: input.repositoryPath,
107
+ repositoryPath: effectiveRepoPath,
68
108
  });
69
109
  const featureNumber = existingFeatures.length + 1;
70
110
  const now = new Date();
71
111
  const runId = randomUUID();
72
112
  // Create git worktree branching from the repo's default branch
73
- const defaultBranch = await this.gitPrService.getDefaultBranch(input.repositoryPath);
74
- const worktreePath = this.worktreeService.getWorktreePath(input.repositoryPath, branch);
75
- await this.worktreeService.create(input.repositoryPath, branch, worktreePath, defaultBranch);
113
+ const defaultBranch = await this.gitPrService.getDefaultBranch(effectiveRepoPath);
114
+ const worktreePath = this.worktreeService.getWorktreePath(effectiveRepoPath, branch);
115
+ await this.worktreeService.create(effectiveRepoPath, branch, worktreePath, defaultBranch);
76
116
  // Initialize spec directory — full user input goes into spec.yaml as-is
77
117
  const { specDir } = await this.specInitializer.initialize(worktreePath, slug, featureNumber, input.userInput);
78
118
  // Resolve or create repository entity for this path
79
- const normalizedPath = input.repositoryPath.replace(/\/+$/, '') || input.repositoryPath;
119
+ const normalizedPath = effectiveRepoPath.replace(/\/+$/, '') || effectiveRepoPath;
80
120
  let repository = await this.repositoryRepo.findByPath(normalizedPath);
81
121
  if (!repository) {
82
122
  const repoName = normalizedPath.split('/').pop() ?? normalizedPath;
@@ -95,9 +135,9 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
95
135
  slug,
96
136
  description: metadata.description,
97
137
  userQuery: input.userInput,
98
- repositoryPath: input.repositoryPath,
138
+ repositoryPath: effectiveRepoPath,
99
139
  branch,
100
- lifecycle: SdlcLifecycle.Requirements,
140
+ lifecycle: initialLifecycle,
101
141
  messages: [],
102
142
  relatedArtifacts: [],
103
143
  push: input.push ?? false,
@@ -110,6 +150,7 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
110
150
  agentRunId: runId,
111
151
  specPath: specDir,
112
152
  repositoryId: repository.id,
153
+ ...(input.parentId ? { parentId: input.parentId } : {}),
113
154
  createdAt: now,
114
155
  updatedAt: now,
115
156
  };
@@ -124,18 +165,21 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
124
165
  prompt: input.userInput,
125
166
  threadId: randomUUID(),
126
167
  featureId: feature.id,
127
- repositoryPath: input.repositoryPath,
168
+ repositoryPath: effectiveRepoPath,
128
169
  ...(input.approvalGates ? { approvalGates: input.approvalGates } : {}),
129
170
  createdAt: now.toISOString(),
130
171
  updatedAt: now.toISOString(),
131
172
  };
132
173
  await this.runRepository.create(agentRun);
133
- this.agentProcess.spawn(feature.id, runId, input.repositoryPath, specDir, worktreePath, {
134
- ...(input.approvalGates ? { approvalGates: input.approvalGates } : {}),
135
- threadId: agentRun.threadId,
136
- push: input.push ?? false,
137
- openPr: input.openPr ?? false,
138
- });
174
+ // Only spawn the agent immediately if the child is not blocked (FR-9, FR-16)
175
+ if (shouldSpawn) {
176
+ this.agentProcess.spawn(feature.id, runId, effectiveRepoPath, specDir, worktreePath, {
177
+ ...(input.approvalGates ? { approvalGates: input.approvalGates } : {}),
178
+ threadId: agentRun.threadId,
179
+ push: input.push ?? false,
180
+ openPr: input.openPr ?? false,
181
+ });
182
+ }
139
183
  return { feature, warning };
140
184
  }
141
185
  };
@@ -5,6 +5,8 @@ export interface CreateFeatureInput {
5
5
  approvalGates?: ApprovalGates;
6
6
  push?: boolean;
7
7
  openPr?: boolean;
8
+ /** Optional ID of the parent feature. When set, child may be created in Blocked state. */
9
+ parentId?: string;
8
10
  }
9
11
  export interface CreateFeatureResult {
10
12
  feature: Feature;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/use-cases/features/create/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AAErF,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/use-cases/features/create/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AAErF,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -1 +1 @@
1
- {"version":3,"file":"delete-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/delete-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AAEvG,qBACa,oBAAoB;IAEC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAE5D,OAAO,CAAC,QAAQ,CAAC,cAAc;IACA,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAJR,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EAE7D,cAAc,EAAE,2BAA2B,EACZ,OAAO,EAAE,mBAAmB;IAGxE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAyCnD"}
1
+ {"version":3,"file":"delete-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/delete-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AAEvG,qBACa,oBAAoB;IAEC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAE5D,OAAO,CAAC,QAAQ,CAAC,cAAc;IACA,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAJR,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EAE7D,cAAc,EAAE,2BAA2B,EACZ,OAAO,EAAE,mBAAmB;IAGxE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAqDnD"}
@@ -24,7 +24,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
24
24
  return function (target, key) { decorator(target, key, paramIndex); }
25
25
  };
26
26
  import { injectable, inject } from 'tsyringe';
27
- import { AgentRunStatus } from '../../../domain/generated/output.js';
27
+ import { AgentRunStatus, SdlcLifecycle } from '../../../domain/generated/output.js';
28
28
  let DeleteFeatureUseCase = class DeleteFeatureUseCase {
29
29
  featureRepo;
30
30
  worktreeService;
@@ -43,7 +43,14 @@ let DeleteFeatureUseCase = class DeleteFeatureUseCase {
43
43
  if (!feature) {
44
44
  throw new Error(`Feature not found: "${featureId}"`);
45
45
  }
46
- // 2. Cancel running/pending agent run if present
46
+ // 2. Guard: reject deletion if blocked children exist (FR-29)
47
+ const blockedChildren = (await this.featureRepo.findByParentId(feature.id)).filter((child) => child.lifecycle === SdlcLifecycle.Blocked);
48
+ if (blockedChildren.length > 0) {
49
+ const list = blockedChildren.map((c) => `${c.id} (${c.name})`).join(', ');
50
+ throw new Error(`Cannot delete feature "${feature.name}" because it has blocked children: ${list}. ` +
51
+ `Remove or re-parent the blocked children before deleting this feature.`);
52
+ }
53
+ // 3. Cancel running/pending agent run if present
47
54
  if (feature.agentRunId) {
48
55
  const run = await this.runRepo.findById(feature.agentRunId);
49
56
  if (run && (run.status === AgentRunStatus.running || run.status === AgentRunStatus.pending)) {
@@ -59,7 +66,7 @@ let DeleteFeatureUseCase = class DeleteFeatureUseCase {
59
66
  await this.runRepo.updateStatus(run.id, AgentRunStatus.cancelled);
60
67
  }
61
68
  }
62
- // 3. Remove worktree (ignore errors if already removed)
69
+ // 4. Remove worktree (ignore errors if already removed)
63
70
  const worktreePath = this.worktreeService.getWorktreePath(feature.repositoryPath, feature.branch);
64
71
  try {
65
72
  await this.worktreeService.remove(worktreePath);
@@ -67,7 +74,7 @@ let DeleteFeatureUseCase = class DeleteFeatureUseCase {
67
74
  catch {
68
75
  // Worktree might already be removed - that's fine
69
76
  }
70
- // 4. Delete feature record
77
+ // 5. Delete feature record
71
78
  await this.featureRepo.delete(feature.id);
72
79
  return feature;
73
80
  }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * UpdateFeatureLifecycleUseCase
3
+ *
4
+ * Centralises all feature lifecycle transitions. Every call to this use case:
5
+ * 1. Persists the new lifecycle value via the feature repository.
6
+ * 2. Immediately calls CheckAndUnblockFeaturesUseCase to evaluate whether
7
+ * any blocked children can now be unblocked.
8
+ *
9
+ * This is the single hook point that ensures auto-unblocking fires on every
10
+ * lifecycle transition made by the feature agent, satisfying FR-17.
11
+ *
12
+ * No-op when the feature is not found (swallowed gracefully so agent nodes
13
+ * do not crash on a missing feature record).
14
+ */
15
+ import type { SdlcLifecycle } from '../../../../domain/generated/output.js';
16
+ import type { IFeatureRepository } from '../../../ports/output/repositories/feature-repository.interface.js';
17
+ import { CheckAndUnblockFeaturesUseCase } from '../check-and-unblock-features.use-case.js';
18
+ export interface UpdateFeatureLifecycleInput {
19
+ featureId: string;
20
+ lifecycle: SdlcLifecycle;
21
+ }
22
+ export declare class UpdateFeatureLifecycleUseCase {
23
+ private readonly featureRepo;
24
+ private readonly checkAndUnblock;
25
+ constructor(featureRepo: IFeatureRepository, checkAndUnblock: CheckAndUnblockFeaturesUseCase);
26
+ execute(input: UpdateFeatureLifecycleInput): Promise<void>;
27
+ }
28
+ //# sourceMappingURL=update-feature-lifecycle.use-case.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-feature-lifecycle.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/use-cases/features/update/update-feature-lifecycle.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oEAAoE,CAAC;AAC7G,OAAO,EAAE,8BAA8B,EAAE,MAAM,2CAA2C,CAAC;AAE3F,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,aAAa,CAAC;CAC1B;AAED,qBACa,6BAA6B;IAER,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE1D,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAFe,WAAW,EAAE,kBAAkB,EAE7D,eAAe,EAAE,8BAA8B;IAG5D,OAAO,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;CAYjE"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * UpdateFeatureLifecycleUseCase
3
+ *
4
+ * Centralises all feature lifecycle transitions. Every call to this use case:
5
+ * 1. Persists the new lifecycle value via the feature repository.
6
+ * 2. Immediately calls CheckAndUnblockFeaturesUseCase to evaluate whether
7
+ * any blocked children can now be unblocked.
8
+ *
9
+ * This is the single hook point that ensures auto-unblocking fires on every
10
+ * lifecycle transition made by the feature agent, satisfying FR-17.
11
+ *
12
+ * No-op when the feature is not found (swallowed gracefully so agent nodes
13
+ * do not crash on a missing feature record).
14
+ */
15
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
16
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
17
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
18
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
19
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
20
+ };
21
+ var __metadata = (this && this.__metadata) || function (k, v) {
22
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
23
+ };
24
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
25
+ return function (target, key) { decorator(target, key, paramIndex); }
26
+ };
27
+ import { injectable, inject } from 'tsyringe';
28
+ import { CheckAndUnblockFeaturesUseCase } from '../check-and-unblock-features.use-case.js';
29
+ let UpdateFeatureLifecycleUseCase = class UpdateFeatureLifecycleUseCase {
30
+ featureRepo;
31
+ checkAndUnblock;
32
+ constructor(featureRepo, checkAndUnblock) {
33
+ this.featureRepo = featureRepo;
34
+ this.checkAndUnblock = checkAndUnblock;
35
+ }
36
+ async execute(input) {
37
+ const feature = await this.featureRepo.findById(input.featureId);
38
+ if (!feature) {
39
+ return;
40
+ }
41
+ feature.lifecycle = input.lifecycle;
42
+ feature.updatedAt = new Date();
43
+ await this.featureRepo.update(feature);
44
+ await this.checkAndUnblock.execute(input.featureId);
45
+ }
46
+ };
47
+ UpdateFeatureLifecycleUseCase = __decorate([
48
+ injectable(),
49
+ __param(0, inject('IFeatureRepository')),
50
+ __param(1, inject(CheckAndUnblockFeaturesUseCase)),
51
+ __metadata("design:paramtypes", [Object, CheckAndUnblockFeaturesUseCase])
52
+ ], UpdateFeatureLifecycleUseCase);
53
+ export { UpdateFeatureLifecycleUseCase };
@@ -332,6 +332,18 @@ export type WorkflowConfig = {
332
332
  * Default approval gate preferences for new features
333
333
  */
334
334
  approvalGateDefaults: ApprovalGateDefaults;
335
+ /**
336
+ * Maximum number of CI fix/push/watch iterations before giving up (default: 3)
337
+ */
338
+ ciMaxFixAttempts?: number;
339
+ /**
340
+ * Timeout in milliseconds for watching a CI run (default: 600000 = 10 minutes)
341
+ */
342
+ ciWatchTimeoutMs?: number;
343
+ /**
344
+ * Maximum characters of CI failure logs to pass to the executor (default: 50000)
345
+ */
346
+ ciLogMaxChars?: number;
335
347
  };
336
348
  export declare enum AgentType {
337
349
  ClaudeCode = "claude-code",
@@ -594,7 +606,8 @@ export declare enum SdlcLifecycle {
594
606
  Planning = "Planning",
595
607
  Implementation = "Implementation",
596
608
  Review = "Review",
597
- Maintain = "Maintain"
609
+ Maintain = "Maintain",
610
+ Blocked = "Blocked"
598
611
  }
599
612
  /**
600
613
  * Configuration for human-in-the-loop approval gates
@@ -623,6 +636,27 @@ export declare enum CiStatus {
623
636
  Success = "Success",
624
637
  Failure = "Failure"
625
638
  }
639
+ /**
640
+ * Record of one CI fix attempt in the watch/fix loop
641
+ */
642
+ export type CiFixRecord = {
643
+ /**
644
+ * 1-based attempt number
645
+ */
646
+ attempt: number;
647
+ /**
648
+ * ISO timestamp when this attempt started
649
+ */
650
+ startedAt: string;
651
+ /**
652
+ * First 500 chars of failure logs for this attempt
653
+ */
654
+ failureSummary: string;
655
+ /**
656
+ * Outcome of this attempt: fixed, failed, or timeout
657
+ */
658
+ outcome: string;
659
+ };
626
660
  /**
627
661
  * Pull request tracking data for a feature
628
662
  */
@@ -647,6 +681,14 @@ export type PullRequest = {
647
681
  * CI pipeline status
648
682
  */
649
683
  ciStatus?: CiStatus;
684
+ /**
685
+ * Number of CI fix attempts made
686
+ */
687
+ ciFixAttempts?: number;
688
+ /**
689
+ * History of CI fix attempts
690
+ */
691
+ ciFixHistory?: CiFixRecord[];
650
692
  };
651
693
  /**
652
694
  * Central entity tracking a piece of work through the SDLC lifecycle (Aggregate Root)
@@ -724,6 +766,10 @@ export type Feature = BaseEntity & {
724
766
  * Pull request data (null until PR created)
725
767
  */
726
768
  pr?: PullRequest;
769
+ /**
770
+ * Parent feature ID for dependency tracking (optional)
771
+ */
772
+ parentId?: UUID;
727
773
  };
728
774
  /**
729
775
  * Option for resolving an open question