@shepai/cli 1.115.0 → 1.116.0-pr362.c0ee15c

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 (141) hide show
  1. package/dist/packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.d.ts.map +1 -1
  2. package/dist/packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.js +5 -0
  3. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +3 -1
  4. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  5. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +30 -2
  6. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
  7. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +6 -1
  8. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -1
  9. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +6 -1
  10. package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.d.ts.map +1 -1
  11. package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.js +6 -1
  12. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  13. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +17 -1
  14. package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.d.ts.map +1 -1
  15. package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.js +12 -0
  16. package/dist/tsconfig.build.tsbuildinfo +1 -1
  17. package/package.json +1 -1
  18. package/web/.next/BUILD_ID +1 -1
  19. package/web/.next/build-manifest.json +2 -2
  20. package/web/.next/fallback-build-manifest.json +2 -2
  21. package/web/.next/prerender-manifest.json +3 -3
  22. package/web/.next/required-server-files.js +3 -3
  23. package/web/.next/required-server-files.json +3 -3
  24. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +20 -20
  25. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  26. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  27. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +26 -26
  28. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  29. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  30. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +26 -26
  31. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  32. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  33. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +18 -18
  34. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  35. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  36. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +20 -20
  37. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  38. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  39. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +26 -26
  40. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  41. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  42. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +26 -26
  43. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  44. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  45. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +18 -18
  46. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  47. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  48. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +18 -18
  49. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  50. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  51. package/web/.next/server/app/_global-error.html +2 -2
  52. package/web/.next/server/app/_global-error.rsc +1 -1
  53. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  54. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  55. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  56. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  57. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  58. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  59. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  60. package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
  61. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  62. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  63. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  64. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  66. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  67. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  68. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  69. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  70. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  71. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  72. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_a1104008.js +1 -1
  73. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_a1104008.js.map +1 -1
  74. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js +1 -1
  75. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js.map +1 -1
  76. package/web/.next/server/chunks/ssr/[root-of-the-server]__039967e3._.js +1 -1
  77. package/web/.next/server/chunks/ssr/[root-of-the-server]__039967e3._.js.map +1 -1
  78. package/web/.next/server/chunks/ssr/[root-of-the-server]__07a39ff2._.js +1 -1
  79. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
  80. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
  81. package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +2 -2
  82. package/web/.next/server/chunks/ssr/[root-of-the-server]__2773312c._.js +1 -1
  83. package/web/.next/server/chunks/ssr/[root-of-the-server]__2773312c._.js.map +1 -1
  84. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
  85. package/web/.next/server/chunks/ssr/[root-of-the-server]__6367aea0._.js +1 -1
  86. package/web/.next/server/chunks/ssr/[root-of-the-server]__6367aea0._.js.map +1 -1
  87. package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
  88. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
  89. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  90. package/web/.next/server/chunks/ssr/[root-of-the-server]__cbd8062c._.js +1 -1
  91. package/web/.next/server/chunks/ssr/[root-of-the-server]__cbd8062c._.js.map +1 -1
  92. package/web/.next/server/chunks/ssr/[root-of-the-server]__e70c5627._.js +1 -1
  93. package/web/.next/server/chunks/ssr/[root-of-the-server]__e70c5627._.js.map +1 -1
  94. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
  95. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
  96. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  97. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  98. package/web/.next/server/chunks/ssr/{_7d4c400f._.js → _37f9b23b._.js} +2 -2
  99. package/web/.next/server/chunks/ssr/{_7d4c400f._.js.map → _37f9b23b._.js.map} +1 -1
  100. package/web/.next/server/chunks/ssr/{_f166a7ed._.js → _871373f7._.js} +2 -2
  101. package/web/.next/server/chunks/ssr/{_f166a7ed._.js.map → _871373f7._.js.map} +1 -1
  102. package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
  103. package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
  104. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  105. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  106. package/web/.next/server/chunks/ssr/{_d6fedbbf._.js → _f7926f23._.js} +2 -2
  107. package/web/.next/server/chunks/ssr/{_d6fedbbf._.js.map → _f7926f23._.js.map} +1 -1
  108. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  109. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  110. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_888633e1.js +1 -1
  111. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_888633e1.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  113. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  114. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  115. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/src_presentation_web_ce7cbc3c._.js +2 -2
  117. package/web/.next/server/chunks/ssr/src_presentation_web_ce7cbc3c._.js.map +1 -1
  118. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  119. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  120. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  121. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  122. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  123. package/web/.next/server/chunks/ssr/src_presentation_web_e2604413._.js +2 -2
  124. package/web/.next/server/chunks/ssr/src_presentation_web_e2604413._.js.map +1 -1
  125. package/web/.next/server/pages/500.html +2 -2
  126. package/web/.next/server/server-reference-manifest.js +1 -1
  127. package/web/.next/server/server-reference-manifest.json +31 -31
  128. package/web/.next/static/chunks/{d4bebfde2bed6130.js → 489412a4676a1d14.js} +1 -1
  129. package/web/.next/static/chunks/{36e2bf6ac6e90282.js → 4e46e9e2ec8bcce2.js} +1 -1
  130. package/web/.next/static/chunks/{c62c393c5d0912b7.js → 82cf0022cbfd40cb.js} +1 -1
  131. package/web/.next/static/chunks/{b6d30842eaeb3166.js → 8392a79c0bd9956b.js} +2 -2
  132. package/web/.next/static/chunks/84c9b04d5397cc46.js +2 -0
  133. package/web/.next/static/chunks/{08c3f6e304e8d7b4.js → 9f61c4cc4813cbc1.js} +1 -1
  134. package/web/.next/static/chunks/{d4350f1fe1625279.js → a1cb1cf624ae4986.js} +1 -1
  135. package/web/.next/static/chunks/{36ff38fd6b9d647d.js → df558fa5a59ef099.js} +1 -1
  136. package/web/.next/static/chunks/{c50772767c14f013.js → ee6d0ebf271c7b4c.js} +1 -1
  137. package/web/.next/static/chunks/{29a45df76aba845e.js → f3ba96e4b2c8be37.js} +1 -1
  138. package/web/.next/static/chunks/ea784857fcad9e04.js +0 -2
  139. /package/web/.next/static/{8fO4nSkLwXorpa4D0V82M → d6lJHy_7WaSuAS7PMm2hW}/_buildManifest.js +0 -0
  140. /package/web/.next/static/{8fO4nSkLwXorpa4D0V82M → d6lJHy_7WaSuAS7PMm2hW}/_clientMiddlewareManifest.json +0 -0
  141. /package/web/.next/static/{8fO4nSkLwXorpa4D0V82M → d6lJHy_7WaSuAS7PMm2hW}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup-feature-worktree.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAE7F,qBACa,6BAA6B;IAER,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAFP,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EACpC,YAAY,EAAE,aAAa;IAGjE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4ChD"}
1
+ {"version":3,"file":"cleanup-feature-worktree.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAE7F,qBACa,6BAA6B;IAER,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAFP,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EACpC,YAAY,EAAE,aAAa;IAGjE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAgDhD"}
@@ -22,6 +22,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
22
22
  return function (target, key) { decorator(target, key, paramIndex); }
23
23
  };
24
24
  import { injectable, inject } from 'tsyringe';
25
+ import { SdlcLifecycle } from '../../../domain/generated/output.js';
25
26
  let CleanupFeatureWorktreeUseCase = class CleanupFeatureWorktreeUseCase {
26
27
  featureRepo;
27
28
  worktreeService;
@@ -35,6 +36,10 @@ let CleanupFeatureWorktreeUseCase = class CleanupFeatureWorktreeUseCase {
35
36
  const feature = await this.featureRepo.findById(featureId);
36
37
  if (!feature)
37
38
  return;
39
+ // Idempotency guard: skip cleanup if already in Deleting lifecycle
40
+ // (another code path — e.g. DeleteFeatureUseCase — already handles cleanup)
41
+ if (feature.lifecycle === SdlcLifecycle.Deleting)
42
+ return;
38
43
  // Step 1: Unlink the git worktree (directory contents are preserved on disk)
39
44
  const worktreePath = feature.worktreePath ??
40
45
  this.worktreeService.getWorktreePath(feature.repositoryPath, feature.branch);
@@ -23,6 +23,7 @@ import type { IAgentRunRepository } from '../../../ports/output/agents/agent-run
23
23
  import type { ISpecInitializerService } from '../../../ports/output/services/spec-initializer.interface.js';
24
24
  import type { IRepositoryRepository } from '../../../ports/output/repositories/repository-repository.interface.js';
25
25
  import type { IGitPrService } from '../../../ports/output/services/git-pr-service.interface.js';
26
+ import type { IAgentValidator } from '../../../ports/output/agents/agent-validator.interface.js';
26
27
  import { AttachmentStorageService } from '../../../../infrastructure/services/attachment-storage.service.js';
27
28
  import { MetadataGenerator } from './metadata-generator.js';
28
29
  import { SlugResolver } from './slug-resolver.js';
@@ -38,7 +39,8 @@ export declare class CreateFeatureUseCase {
38
39
  private readonly repositoryRepo;
39
40
  private readonly gitPrService;
40
41
  private readonly attachmentStorage;
41
- constructor(featureRepo: IFeatureRepository, worktreeService: IWorktreeService, agentProcess: IFeatureAgentProcessService, runRepository: IAgentRunRepository, specInitializer: ISpecInitializerService, metadataGenerator: MetadataGenerator, slugResolver: SlugResolver, repositoryRepo: IRepositoryRepository, gitPrService: IGitPrService, attachmentStorage: AttachmentStorageService);
42
+ private readonly agentValidator;
43
+ constructor(featureRepo: IFeatureRepository, worktreeService: IWorktreeService, agentProcess: IFeatureAgentProcessService, runRepository: IAgentRunRepository, specInitializer: ISpecInitializerService, metadataGenerator: MetadataGenerator, slugResolver: SlugResolver, repositoryRepo: IRepositoryRepository, gitPrService: IGitPrService, attachmentStorage: AttachmentStorageService, agentValidator: IAgentValidator);
42
44
  /**
43
45
  * Full synchronous execution: creates record, initializes worktree/spec, spawns agent.
44
46
  * Used by the CLI which shows a spinner and needs everything done before returning.
@@ -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;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AAMtE,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,wBAAwB,EAAE,MAAM,mEAAmE,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE9F,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;IAE7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAlBjB,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,EAE3B,iBAAiB,EAAE,wBAAwB;IAG9D;;;OAGG;IACG,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAMtE;;;;OAIG;IACG,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAyH1E;;;OAGG;IACG,kBAAkB,CACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,kBAAkB,EACzB,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;CAoG1D"}
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;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AAMtE,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;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2DAA2D,CAAC;AAGjG,OAAO,EAAE,wBAAwB,EAAE,MAAM,mEAAmE,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE9F,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;IAE7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,cAAc;gBApBd,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,EAE3B,iBAAiB,EAAE,wBAAwB,EAE3C,cAAc,EAAE,eAAe;IAGlD;;;OAGG;IACG,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAMtE;;;;OAIG;IACG,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAyH1E;;;OAGG;IACG,kBAAkB,CACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,kBAAkB,EACzB,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;CAgI1D"}
@@ -46,7 +46,8 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
46
46
  repositoryRepo;
47
47
  gitPrService;
48
48
  attachmentStorage;
49
- constructor(featureRepo, worktreeService, agentProcess, runRepository, specInitializer, metadataGenerator, slugResolver, repositoryRepo, gitPrService, attachmentStorage) {
49
+ agentValidator;
50
+ constructor(featureRepo, worktreeService, agentProcess, runRepository, specInitializer, metadataGenerator, slugResolver, repositoryRepo, gitPrService, attachmentStorage, agentValidator) {
50
51
  this.featureRepo = featureRepo;
51
52
  this.worktreeService = worktreeService;
52
53
  this.agentProcess = agentProcess;
@@ -57,6 +58,7 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
57
58
  this.repositoryRepo = repositoryRepo;
58
59
  this.gitPrService = gitPrService;
59
60
  this.attachmentStorage = attachmentStorage;
61
+ this.agentValidator = agentValidator;
60
62
  }
61
63
  /**
62
64
  * Full synchronous execution: creates record, initializes worktree/spec, spawns agent.
@@ -241,6 +243,31 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
241
243
  await this.featureRepo.update(updatedFeature);
242
244
  // Spawn agent if not blocked
243
245
  if (shouldSpawn) {
246
+ // Validate that the configured agent is available before spawning
247
+ // a background worker — prevents the feature from getting stuck
248
+ // with a silent failure in the detached worker process.
249
+ // Skip validation when using mock executor (E2E tests, CI without real agents).
250
+ const settings = getSettings();
251
+ const effectiveAgentType = input.agentType ?? settings.agent.type;
252
+ const isMockExecutor = process.env.SHEP_MOCK_EXECUTOR === '1';
253
+ const validation = isMockExecutor
254
+ ? { available: true }
255
+ : await this.agentValidator.isAvailable(effectiveAgentType);
256
+ if (!validation.available) {
257
+ // Mark the agent run as failed so the UI shows the error
258
+ await this.runRepository.updateStatus(feature.agentRunId, AgentRunStatus.failed, {
259
+ error: `Agent "${effectiveAgentType}" is not available: ${validation.error}`,
260
+ completedAt: new Date(),
261
+ updatedAt: new Date(),
262
+ });
263
+ // Update feature lifecycle to Started so it doesn't appear as actively running
264
+ await this.featureRepo.update({
265
+ ...updatedFeature,
266
+ lifecycle: SdlcLifecycle.Started,
267
+ updatedAt: new Date(),
268
+ });
269
+ throw new Error(`Agent "${effectiveAgentType}" is not available. ${validation.error ?? 'Please install it and try again.'}`);
270
+ }
244
271
  const agentRun = await this.runRepository.findById(feature.agentRunId);
245
272
  this.agentProcess.spawn(feature.id, feature.agentRunId, effectiveRepoPath, specDir, worktreePath, {
246
273
  ...(input.approvalGates ? { approvalGates: input.approvalGates } : {}),
@@ -267,7 +294,8 @@ CreateFeatureUseCase = __decorate([
267
294
  __param(7, inject('IRepositoryRepository')),
268
295
  __param(8, inject('IGitPrService')),
269
296
  __param(9, inject(AttachmentStorageService)),
297
+ __param(10, inject('IAgentValidator')),
270
298
  __metadata("design:paramtypes", [Object, Object, Object, Object, Object, MetadataGenerator,
271
- SlugResolver, Object, Object, AttachmentStorageService])
299
+ SlugResolver, Object, Object, AttachmentStorageService, Object])
272
300
  ], CreateFeatureUseCase);
273
301
  export { CreateFeatureUseCase };
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAajD;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,cAAc;IAMlD,OAAO,CAAC,QAAQ,CAAC,KAAK;IALlC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAA8B;IAE3D,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;gBAEM,KAAK,EAAE,aAAa;IAEjD,4EAA4E;IAC5E,OAAO,CAAC,GAAG;IAML,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAmHtF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IA+F3C;;;OAGG;IACH,OAAO,CAAC,cAAc;IAmCtB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAI/C,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAyBzB,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,eAAe;CAkExB"}
1
+ {"version":3,"file":"claude-code-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAajD;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,cAAc;IAMlD,OAAO,CAAC,QAAQ,CAAC,KAAK;IALlC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAA8B;IAE3D,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;gBAEM,KAAK,EAAE,aAAa;IAEjD,4EAA4E;IAC5E,OAAO,CAAC,GAAG;IAML,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA2HtF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IA+F3C;;;OAGG;IACH,OAAO,CAAC,cAAc;IAmCtB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAI/C,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAyBzB,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,eAAe;CAkExB"}
@@ -107,7 +107,12 @@ export class ClaudeCodeExecutorService {
107
107
  this.log(`Process error event: ${error.message}`);
108
108
  if (timeoutId)
109
109
  clearTimeout(timeoutId);
110
- reject(error);
110
+ if (error.code === 'ENOENT') {
111
+ reject(new Error('Claude Code CLI ("claude") not found. Please install it: https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview'));
112
+ }
113
+ else {
114
+ reject(error);
115
+ }
111
116
  });
112
117
  proc.on('close', (code) => {
113
118
  // Flush remaining buffer
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuBjD;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,cAAc;IAM9C,OAAO,CAAC,QAAQ,CAAC,KAAK;IALlC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAyB;IAEtD,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;gBAEM,KAAK,EAAE,aAAa;IAEjD,4EAA4E;IAC5E,OAAO,CAAC,GAAG;IAMX,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAIzC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA0GtF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IA8E3C;;OAEG;IACH,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,eAAe;CAgDxB"}
1
+ {"version":3,"file":"cursor-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuBjD;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,cAAc;IAM9C,OAAO,CAAC,QAAQ,CAAC,KAAK;IALlC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAyB;IAEtD,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;gBAEM,KAAK,EAAE,aAAa;IAEjD,4EAA4E;IAC5E,OAAO,CAAC,GAAG;IAMX,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAIzC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAkHtF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IA8E3C;;OAEG;IACH,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,eAAe;CAgDxB"}
@@ -123,7 +123,12 @@ export class CursorExecutorService {
123
123
  this.log(`Process error event: ${error.message}`);
124
124
  if (timeoutId)
125
125
  clearTimeout(timeoutId);
126
- reject(error);
126
+ if (error.code === 'ENOENT') {
127
+ reject(new Error('Cursor agent CLI not found. Please install Cursor and ensure the "cursor" command is available on PATH.'));
128
+ }
129
+ else {
130
+ reject(error);
131
+ }
127
132
  });
128
133
  proc.on('close', (code) => {
129
134
  if (lineBuffer.trim())
@@ -1 +1 @@
1
- {"version":3,"file":"gemini-cli-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACZ,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,cAAc;IAO3D,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAP9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAA6B;IAE1D,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;gBAGJ,KAAK,EAAE,aAAa,EACpB,UAAU,CAAC,EAAE,WAAW,YAAA;IAG3C,4EAA4E;IAC5E,OAAO,CAAC,GAAG;IAMX,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAIzC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAsFtF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IAsG3C;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAmDxB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAI3C;IAEF;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;;OAGG;IACH,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,iBAAiB;CAiB1B"}
1
+ {"version":3,"file":"gemini-cli-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACZ,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,cAAc;IAO3D,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAP9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAA6B;IAE1D,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;gBAGJ,KAAK,EAAE,aAAa,EACpB,UAAU,CAAC,EAAE,WAAW,YAAA;IAG3C,4EAA4E;IAC5E,OAAO,CAAC,GAAG;IAMX,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAIzC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA8FtF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IAsG3C;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAmDxB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAI3C;IAEF;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;;OAGG;IACH,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,iBAAiB;CAiB1B"}
@@ -67,7 +67,12 @@ export class GeminiCliExecutorService {
67
67
  this.log(`Process error event: ${error.message}`);
68
68
  if (timeoutId)
69
69
  clearTimeout(timeoutId);
70
- reject(error);
70
+ if (error.code === 'ENOENT') {
71
+ reject(new Error('Gemini CLI ("gemini") not found. Please install it: https://github.com/google-gemini/gemini-cli'));
72
+ }
73
+ else {
74
+ reject(error);
75
+ }
71
76
  });
72
77
  proc.on('close', (code) => {
73
78
  this.log(`Process closed with code ${code}, stdout=${stdout.length} chars`);
@@ -1 +1 @@
1
- {"version":3,"file":"feature-agent-worker.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,kBAAkB,CAAC;AAe1B,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAW9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAwE1D;AAgCD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgQ/D"}
1
+ {"version":3,"file":"feature-agent-worker.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,kBAAkB,CAAC;AAe1B,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAW7F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAwE1D;AAgCD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmR/D"}
@@ -16,7 +16,7 @@ import { initializeContainer, container } from '../../../di/container.js';
16
16
  import { createFeatureAgentGraph } from './feature-agent-graph.js';
17
17
  import { createFastFeatureAgentGraph } from './fast-feature-agent-graph.js';
18
18
  import { createCheckpointer } from '../common/checkpointer.js';
19
- import { AgentRunStatus } from '../../../../domain/generated/output.js';
19
+ import { AgentRunStatus, SdlcLifecycle } from '../../../../domain/generated/output.js';
20
20
  import { initializeSettings } from '../../../services/settings.service.js';
21
21
  import { InitializeSettingsUseCase } from '../../../../application/use-cases/settings/initialize-settings.use-case.js';
22
22
  import { setHeartbeatContext } from './heartbeat.js';
@@ -336,6 +336,22 @@ export async function runWorker(args) {
336
336
  completedAt: failedAt,
337
337
  updatedAt: failedAt,
338
338
  });
339
+ // Reset the feature lifecycle to Started so it doesn't appear stuck
340
+ // in a running phase (e.g., Requirements, Implementation) when the agent has failed.
341
+ try {
342
+ const feature = await featureRepository.findById(args.featureId);
343
+ if (feature && feature.lifecycle !== SdlcLifecycle.Maintain) {
344
+ await featureRepository.update({
345
+ ...feature,
346
+ lifecycle: SdlcLifecycle.Started,
347
+ updatedAt: failedAt,
348
+ });
349
+ log('Feature lifecycle reset to Started');
350
+ }
351
+ }
352
+ catch (resetErr) {
353
+ log(`Failed to reset feature lifecycle: ${resetErr instanceof Error ? resetErr.message : String(resetErr)}`);
354
+ }
339
355
  await recordLifecycleEvent('run:failed');
340
356
  log('Run marked as failed');
341
357
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pr-sync-watcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gFAAgF,CAAC;AACzH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4EAA4E,CAAC;AACtH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAK5G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8EAA8E,CAAC;AACzH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAqB3C,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuB;IAC3D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAA2B;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,SAAS,CAAK;gBAGpB,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,GAAE,MAAiC,EACjD,EAAE,GAAE,QAAQ,CAAC,QAAQ,GAAG,IAAW;IAWrC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,IAAI;IAcb,IAAI,IAAI,IAAI;IASZ,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAiBtB,0FAA0F;IAC1F,OAAO,CAAC,iBAAiB;YAUX,IAAI;IA6ClB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,oBAAoB;YAYd,iBAAiB;YA+CjB,cAAc;IAoL5B,8EAA8E;YAChE,gBAAgB;IAW9B,OAAO,CAAC,gBAAgB;CAoBzB;AAMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,CAAC,EAAE,MAAM,EACvB,EAAE,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAC5B,IAAI,CAaN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,oBAAoB,CAQvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC"}
1
+ {"version":3,"file":"pr-sync-watcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gFAAgF,CAAC;AACzH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4EAA4E,CAAC;AACtH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAK5G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8EAA8E,CAAC;AACzH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAqB3C,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuB;IAC3D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAA2B;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,SAAS,CAAK;gBAGpB,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,GAAE,MAAiC,EACjD,EAAE,GAAE,QAAQ,CAAC,QAAQ,GAAG,IAAW;IAWrC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,IAAI;IAcb,IAAI,IAAI,IAAI;IASZ,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAiBtB,0FAA0F;IAC1F,OAAO,CAAC,iBAAiB;YAUX,IAAI;IA6ClB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,oBAAoB;YAYd,iBAAiB;YA+CjB,cAAc;IAkM5B,8EAA8E;YAChE,gBAAgB;IAW9B,OAAO,CAAC,gBAAgB;CAoBzB;AAMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,CAAC,EAAE,MAAM,EACvB,EAAE,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAC5B,IAAI,CAaN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,oBAAoB,CAQvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC"}
@@ -250,6 +250,18 @@ export class PrSyncWatcherService {
250
250
  console.log(`${TAG} PR #${pr.number} status changed: ${tracked.prStatus} -> ${newPrStatus} for "${feature.name}"`);
251
251
  feature.pr = { ...pr, status: newPrStatus };
252
252
  if (newPrStatus === PrStatus.Merged) {
253
+ // Re-fetch to avoid racing with the merge node which may have already
254
+ // transitioned this feature to Maintain and performed cleanup.
255
+ const freshFeature = await this.featureRepo.findById(feature.id);
256
+ if (freshFeature?.lifecycle === SdlcLifecycle.Maintain) {
257
+ // eslint-disable-next-line no-console
258
+ console.log(`${TAG} Feature "${feature.name}" already in Maintain — skipping duplicate transition`);
259
+ tracked.prStatus = newPrStatus;
260
+ // Still update the PR status on the record so it reflects Merged
261
+ feature.pr = { ...(freshFeature.pr ?? pr), status: PrStatus.Merged };
262
+ await this.featureRepo.update({ ...freshFeature, pr: feature.pr, updatedAt: new Date() });
263
+ return;
264
+ }
253
265
  feature.lifecycle = SdlcLifecycle.Maintain;
254
266
  await this.completeAgentRun(feature);
255
267
  this.emitNotification(NotificationEventType.PrMerged, feature.id, feature.agentRunId ?? '', feature.name, `PR #${pr.number} merged for ${feature.name}`, NotificationSeverity.Success);