@shepai/cli 1.66.1 → 1.66.3

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 (123) hide show
  1. package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts +8 -0
  2. package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.js +8 -1
  5. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.d.ts.map +1 -1
  6. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.js +5 -1
  7. package/dist/packages/core/src/application/use-cases/features/create/slug-resolver.d.ts +5 -3
  8. package/dist/packages/core/src/application/use-cases/features/create/slug-resolver.d.ts.map +1 -1
  9. package/dist/packages/core/src/application/use-cases/features/create/slug-resolver.js +35 -29
  10. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +11 -0
  11. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
  12. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +22 -0
  13. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/analyze.prompt.d.ts.map +1 -1
  14. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/analyze.prompt.js +8 -2
  15. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/implement.prompt.js +1 -1
  16. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  17. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +2 -1
  18. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.d.ts.map +1 -1
  19. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.js +8 -2
  20. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.d.ts.map +1 -1
  21. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.js +8 -2
  22. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/research.prompt.d.ts.map +1 -1
  23. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/research.prompt.js +8 -2
  24. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
  25. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +51 -12
  26. package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts +1 -0
  27. package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
  28. package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +11 -0
  29. package/dist/tsconfig.build.tsbuildinfo +1 -1
  30. package/package.json +1 -1
  31. package/web/.next/BUILD_ID +1 -1
  32. package/web/.next/build-manifest.json +2 -2
  33. package/web/.next/cache/.previewinfo +1 -1
  34. package/web/.next/cache/.rscinfo +1 -1
  35. package/web/.next/cache/.tsbuildinfo +1 -1
  36. package/web/.next/cache/config.json +3 -3
  37. package/web/.next/fallback-build-manifest.json +2 -2
  38. package/web/.next/prerender-manifest.json +3 -3
  39. package/web/.next/required-server-files.js +1 -1
  40. package/web/.next/required-server-files.json +1 -1
  41. package/web/.next/server/app/_global-error.html +2 -2
  42. package/web/.next/server/app/_global-error.rsc +1 -1
  43. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  44. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  45. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  46. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  47. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  48. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  49. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  50. package/web/.next/server/app/page/server-reference-manifest.json +18 -18
  51. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/skills/page/server-reference-manifest.json +5 -5
  53. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  54. package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  55. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  57. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  58. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  59. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
  60. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  61. package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js +1 -1
  62. package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js.map +1 -1
  63. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  64. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  65. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  66. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  67. package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +2 -2
  68. package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js.map +1 -1
  69. package/web/.next/server/chunks/ssr/[root-of-the-server]__f648005b._.js +2 -2
  70. package/web/.next/server/chunks/ssr/[root-of-the-server]__f648005b._.js.map +1 -1
  71. package/web/.next/server/chunks/ssr/_6978d868._.js +1 -1
  72. package/web/.next/server/chunks/ssr/_6978d868._.js.map +1 -1
  73. package/web/.next/server/chunks/ssr/_85965278._.js +1 -1
  74. package/web/.next/server/chunks/ssr/_85965278._.js.map +1 -1
  75. package/web/.next/server/chunks/ssr/_c52cace8._.js +1 -1
  76. package/web/.next/server/chunks/ssr/_c52cace8._.js.map +1 -1
  77. package/web/.next/server/pages/500.html +2 -2
  78. package/web/.next/server/server-reference-manifest.js +1 -1
  79. package/web/.next/server/server-reference-manifest.json +19 -19
  80. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  81. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  82. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  83. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  84. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  85. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  86. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  87. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  88. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  89. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  90. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  91. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  92. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  93. package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +18 -18
  94. package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
  95. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +5 -5
  96. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  97. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  98. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  99. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  100. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  101. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  102. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  103. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js +1 -1
  104. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  105. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  106. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +2 -2
  107. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__f648005b._.js +2 -2
  108. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_6978d868._.js +1 -1
  109. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_85965278._.js +1 -1
  110. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_c52cace8._.js +1 -1
  111. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  112. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  113. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +19 -19
  114. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  115. package/web/.next/static/chunks/{fffaa0530ef1686d.js → 7bcbfc56e5733034.js} +1 -1
  116. package/web/.next/static/chunks/{86a68ddb0ac40c02.js → 86c0cc1097427f74.js} +2 -2
  117. package/web/.next/static/chunks/{faf6eb7311aa7529.js → c0f7284a71378f26.js} +1 -1
  118. package/web/.next/static/chunks/{2ec0c24b265971c3.js → ed887cce7b31c91b.js} +1 -1
  119. package/web/.next/trace +1 -1
  120. package/web/.next/trace-build +1 -1
  121. /package/web/.next/static/{VQhryfJCxF8IeQiBJFQyJ → Cp8hg2DFpA4DyEezlBYOw}/_buildManifest.js +0 -0
  122. /package/web/.next/static/{VQhryfJCxF8IeQiBJFQyJ → Cp8hg2DFpA4DyEezlBYOw}/_clientMiddlewareManifest.json +0 -0
  123. /package/web/.next/static/{VQhryfJCxF8IeQiBJFQyJ → Cp8hg2DFpA4DyEezlBYOw}/_ssgManifest.js +0 -0
@@ -80,6 +80,14 @@ export interface IWorktreeService {
80
80
  * @returns True if the branch exists
81
81
  */
82
82
  branchExists(repoPath: string, branch: string): Promise<boolean>;
83
+ /**
84
+ * Check if a remote branch exists (e.g., on origin).
85
+ *
86
+ * @param repoPath - Path to the git repository
87
+ * @param branch - Branch name to check (without remote prefix)
88
+ * @returns True if the remote branch exists
89
+ */
90
+ remoteBranchExists(repoPath: string, branch: string): Promise<boolean>;
83
91
  /**
84
92
  * Get the conventional worktree path for a branch.
85
93
  *
@@ -1 +1 @@
1
- {"version":3,"file":"worktree-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/worktree-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,oBAAY,iBAAiB;IAC3B,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,SAAS,cAAc;IACvB,cAAc,mBAAmB;IACjC,SAAS,cAAc;CACxB;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,EAAE,iBAAiB;aACvB,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,iBAAiB,EACvB,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;OASG;IACH,MAAM,CACJ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzB;;;;;OAKG;IACH,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAEhD;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D;;;;;;OAMG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjE;;;;;;OAMG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1D;;;;;;;OAOG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD"}
1
+ {"version":3,"file":"worktree-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/worktree-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,oBAAY,iBAAiB;IAC3B,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,SAAS,cAAc;IACvB,cAAc,mBAAmB;IACjC,SAAS,cAAc;CACxB;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,EAAE,iBAAiB;aACvB,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,iBAAiB,EACvB,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;OASG;IACH,MAAM,CACJ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzB;;;;;OAKG;IACH,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAEhD;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D;;;;;;OAMG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjE;;;;;;OAMG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvE;;;;;;OAMG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1D;;;;;;;OAOG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD"}
@@ -1 +1 @@
1
- {"version":3,"file":"approve-agent-run.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/agents/approve-agent-run.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gEAAgE,CAAC;AAC7G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAE1G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAG9E,qBACa,sBAAsB;IAG/B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBANrB,kBAAkB,EAAE,mBAAmB,EAEvC,cAAc,EAAE,2BAA2B,EAE3C,iBAAiB,EAAE,kBAAkB,EAErC,qBAAqB,EAAE,sBAAsB;IAG1D,OAAO,CACX,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAqFlD"}
1
+ {"version":3,"file":"approve-agent-run.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/agents/approve-agent-run.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gEAAgE,CAAC;AAC7G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAE1G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAI9E,qBACa,sBAAsB;IAG/B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBANrB,kBAAkB,EAAE,mBAAmB,EAEvC,cAAc,EAAE,2BAA2B,EAE3C,iBAAiB,EAAE,kBAAkB,EAErC,qBAAqB,EAAE,sBAAsB;IAG1D,OAAO,CACX,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CA6FlD"}
@@ -24,6 +24,7 @@ import { readFileSync } from 'node:fs';
24
24
  import { join } from 'node:path';
25
25
  import { AgentRunStatus } from '../../../domain/generated/output.js';
26
26
  import { writeSpecFileAtomic } from '../../../infrastructure/services/agents/feature-agent/nodes/node-helpers.js';
27
+ import { computeWorktreePath } from '../../../infrastructure/services/ide-launchers/compute-worktree-path.js';
27
28
  let ApproveAgentRunUseCase = class ApproveAgentRunUseCase {
28
29
  agentRunRepository;
29
30
  processService;
@@ -92,7 +93,13 @@ let ApproveAgentRunUseCase = class ApproveAgentRunUseCase {
92
93
  catch {
93
94
  // Non-fatal: approval wait timing failure should not block approval
94
95
  }
95
- this.processService.spawn(run.featureId ?? '', id, feature?.repositoryPath ?? run.repositoryPath ?? '', feature?.specPath ?? '', feature?.worktreePath, {
96
+ // Derive worktree path with fallback the mapper conditionally sets
97
+ // worktreePath only when the DB column is non-null, so compute it if missing.
98
+ const worktreePath = feature?.worktreePath ??
99
+ (feature?.repositoryPath && feature?.branch
100
+ ? computeWorktreePath(feature.repositoryPath, feature.branch)
101
+ : undefined);
102
+ this.processService.spawn(run.featureId ?? '', id, feature?.repositoryPath ?? run.repositoryPath ?? '', feature?.specPath ?? '', worktreePath, {
96
103
  resume: true,
97
104
  approvalGates: run.approvalGates,
98
105
  threadId: run.threadId,
@@ -1 +1 @@
1
- {"version":3,"file":"reject-agent-run.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/agents/reject-agent-run.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gEAAgE,CAAC;AAC7G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAQ1G,qBACa,qBAAqB;IAG9B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBANrB,kBAAkB,EAAE,mBAAmB,EAEvC,cAAc,EAAE,2BAA2B,EAE3C,iBAAiB,EAAE,kBAAkB,EAErC,qBAAqB,EAAE,sBAAsB;IAG1D,OAAO,CACX,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QACT,QAAQ,EAAE,OAAO,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;CA2GH"}
1
+ {"version":3,"file":"reject-agent-run.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/agents/reject-agent-run.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gEAAgE,CAAC;AAC7G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAS1G,qBACa,qBAAqB;IAG9B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBANrB,kBAAkB,EAAE,mBAAmB,EAEvC,cAAc,EAAE,2BAA2B,EAE3C,iBAAiB,EAAE,kBAAkB,EAErC,qBAAqB,EAAE,sBAAsB;IAG1D,OAAO,CACX,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QACT,QAAQ,EAAE,OAAO,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;CAgHH"}
@@ -23,6 +23,7 @@ import { readFileSync } from 'node:fs';
23
23
  import { join } from 'node:path';
24
24
  import { AgentRunStatus } from '../../../domain/generated/output.js';
25
25
  import { writeSpecFileAtomic } from '../../../infrastructure/services/agents/feature-agent/nodes/node-helpers.js';
26
+ import { computeWorktreePath } from '../../../infrastructure/services/ide-launchers/compute-worktree-path.js';
26
27
  let RejectAgentRunUseCase = class RejectAgentRunUseCase {
27
28
  agentRunRepository;
28
29
  processService;
@@ -106,7 +107,10 @@ let RejectAgentRunUseCase = class RejectAgentRunUseCase {
106
107
  feedback,
107
108
  iteration,
108
109
  };
109
- this.processService.spawn(run.featureId ?? '', id, feature.repositoryPath, feature.specPath, feature.worktreePath, {
110
+ // Derive worktree path with fallback the mapper conditionally sets
111
+ // worktreePath only when the DB column is non-null, so compute it if missing.
112
+ const worktreePath = feature.worktreePath ?? computeWorktreePath(feature.repositoryPath, feature.branch);
113
+ this.processService.spawn(run.featureId ?? '', id, feature.repositoryPath, feature.specPath, worktreePath, {
110
114
  resume: true,
111
115
  approvalGates: run.approvalGates,
112
116
  threadId: run.threadId,
@@ -2,7 +2,8 @@
2
2
  * SlugResolver
3
3
  *
4
4
  * Resolves unique slugs by checking against database and git branches.
5
- * Ensures no slug collision by appending numeric suffixes (-2, -3, etc.)
5
+ * On collision, appends a short random suffix to guarantee uniqueness
6
+ * without arbitrary iteration limits.
6
7
  */
7
8
  import type { IFeatureRepository } from '../../../ports/output/repositories/feature-repository.interface.js';
8
9
  import type { IWorktreeService } from '../../../ports/output/services/worktree-service.interface.js';
@@ -16,9 +17,10 @@ export declare class SlugResolver {
16
17
  private readonly worktreeService;
17
18
  constructor(featureRepo: IFeatureRepository, worktreeService: IWorktreeService);
18
19
  /**
19
- * Find a unique slug by checking both the feature DB and git branches.
20
- * If the original slug conflicts, appends -2, -3, etc. until a free one is found.
20
+ * Find a unique slug by checking the feature DB, local branches, and remote branches.
21
+ * If the original slug conflicts, appends a short random hex suffix (e.g., -a3f1).
21
22
  */
22
23
  resolveUniqueSlug(originalSlug: string, repositoryPath: string): Promise<SlugResolutionResult>;
24
+ private isSlugAvailable;
23
25
  }
24
26
  //# sourceMappingURL=slug-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slug-resolver.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/use-cases/features/create/slug-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oEAAoE,CAAC;AAC7G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8DAA8D,CAAC;AAKrG,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBACa,YAAY;IAGrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAFf,WAAW,EAAE,kBAAkB,EAE/B,eAAe,EAAE,gBAAgB;IAGpD;;;OAGG;IACG,iBAAiB,CACrB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,oBAAoB,CAAC;CAgCjC"}
1
+ {"version":3,"file":"slug-resolver.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/use-cases/features/create/slug-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oEAAoE,CAAC;AAC7G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8DAA8D,CAAC;AAErG,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBACa,YAAY;IAGrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAFf,WAAW,EAAE,kBAAkB,EAE/B,eAAe,EAAE,gBAAgB;IAGpD;;;OAGG;IACG,iBAAiB,CACrB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,oBAAoB,CAAC;YAkBlB,eAAe;CAsB9B"}
@@ -2,7 +2,8 @@
2
2
  * SlugResolver
3
3
  *
4
4
  * Resolves unique slugs by checking against database and git branches.
5
- * Ensures no slug collision by appending numeric suffixes (-2, -3, etc.)
5
+ * On collision, appends a short random suffix to guarantee uniqueness
6
+ * without arbitrary iteration limits.
6
7
  */
7
8
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
8
9
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -16,9 +17,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
16
17
  var __param = (this && this.__param) || function (paramIndex, decorator) {
17
18
  return function (target, key) { decorator(target, key, paramIndex); }
18
19
  };
20
+ import { randomBytes } from 'node:crypto';
19
21
  import { injectable, inject } from 'tsyringe';
20
- /** Maximum number of suffix attempts before giving up */
21
- const MAX_SUFFIX = 10;
22
22
  let SlugResolver = class SlugResolver {
23
23
  featureRepo;
24
24
  worktreeService;
@@ -27,35 +27,41 @@ let SlugResolver = class SlugResolver {
27
27
  this.worktreeService = worktreeService;
28
28
  }
29
29
  /**
30
- * Find a unique slug by checking both the feature DB and git branches.
31
- * If the original slug conflicts, appends -2, -3, etc. until a free one is found.
30
+ * Find a unique slug by checking the feature DB, local branches, and remote branches.
31
+ * If the original slug conflicts, appends a short random hex suffix (e.g., -a3f1).
32
32
  */
33
33
  async resolveUniqueSlug(originalSlug, repositoryPath) {
34
- for (let suffix = 0; suffix <= MAX_SUFFIX; suffix++) {
35
- const slug = suffix === 0 ? originalSlug : `${originalSlug}-${suffix + 1}`;
36
- const branch = `feat/${slug}`;
37
- // Check if a feature with this slug already exists in the DB
38
- const existing = await this.featureRepo.findBySlug(slug, repositoryPath);
39
- if (existing) {
40
- if (suffix === 0)
41
- continue; // try suffixed version
42
- continue;
43
- }
44
- // Check if the git branch already exists (worktree or standalone branch)
45
- const branchInUse = await this.worktreeService.exists(repositoryPath, branch);
46
- const branchExists = await this.worktreeService.branchExists(repositoryPath, branch);
47
- if (branchInUse || branchExists)
48
- continue;
49
- if (suffix > 0) {
50
- return {
51
- slug,
52
- branch,
53
- warning: `Branch "feat/${originalSlug}" already exists, using "${branch}" instead`,
54
- };
55
- }
56
- return { slug, branch };
34
+ // First try the original slug as-is
35
+ if (await this.isSlugAvailable(originalSlug, repositoryPath)) {
36
+ return { slug: originalSlug, branch: `feat/${originalSlug}` };
57
37
  }
58
- throw new Error(`Could not find a unique slug for "${originalSlug}" after ${MAX_SUFFIX} attempts`);
38
+ // Collision generate a random suffix
39
+ const suffix = randomBytes(3).toString('hex'); // 6 hex chars, e.g. "a3f1b2"
40
+ const slug = `${originalSlug}-${suffix}`;
41
+ const branch = `feat/${slug}`;
42
+ return {
43
+ slug,
44
+ branch,
45
+ warning: `Branch "feat/${originalSlug}" already exists, using "${branch}" instead`,
46
+ };
47
+ }
48
+ async isSlugAvailable(slug, repositoryPath) {
49
+ const branch = `feat/${slug}`;
50
+ // Check if a feature with this slug already exists in the DB
51
+ const existing = await this.featureRepo.findBySlug(slug, repositoryPath);
52
+ if (existing)
53
+ return false;
54
+ // Check if the git branch already exists (worktree, local, or remote)
55
+ const branchInUse = await this.worktreeService.exists(repositoryPath, branch);
56
+ if (branchInUse)
57
+ return false;
58
+ const branchExists = await this.worktreeService.branchExists(repositoryPath, branch);
59
+ if (branchExists)
60
+ return false;
61
+ const remoteBranchExists = await this.worktreeService.remoteBranchExists(repositoryPath, branch);
62
+ if (remoteBranchExists)
63
+ return false;
64
+ return true;
59
65
  }
60
66
  };
61
67
  SlugResolver = __decorate([
@@ -95,6 +95,17 @@ export declare function markPhaseComplete(specDir: string, phaseId: string, log?
95
95
  * Prevents corruption on crash mid-write.
96
96
  */
97
97
  export declare function writeSpecFileAtomic(specDir: string, filename: string, content: string): void;
98
+ /**
99
+ * Build a commit + optional push instruction block for prompt suffixes.
100
+ *
101
+ * Used by phase prompts to instruct the agent to commit spec/code changes
102
+ * at the end of each step, and optionally push when the --push flag is set.
103
+ */
104
+ export declare function buildCommitPushBlock(opts: {
105
+ push: boolean;
106
+ files: string[];
107
+ commitHint: string;
108
+ }): string;
98
109
  /**
99
110
  * Execute a node with consistent logging and error handling.
100
111
  *
@@ -1 +1 @@
1
- {"version":3,"file":"node-helpers.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,+DAA+D,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASrD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM;kBAE/B,MAAM,GAAG,IAAI;mBAIZ,MAAM,GAAG,IAAI;EAK/B;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7D;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,qBAAqB,CAMpF;AAeD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAQ3F;AAMD,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,mBAAmB,GAAG,eAAe,GAAG,SAAS,CAAC;AAMhG;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,CAKjE;AAED,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,EAC9B,SAAS,CAAC,EAAE,YAAY,GACvB,OAAO,CAAC,oBAAoB,CAAC,CA6B/B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAW5D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAqB5F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAOhG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAwB1F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAa5F;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,UAAU,KAAK,MAAM,GACjE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAmHnE"}
1
+ {"version":3,"file":"node-helpers.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,+DAA+D,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASrD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM;kBAE/B,MAAM,GAAG,IAAI;mBAIZ,MAAM,GAAG,IAAI;EAK/B;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7D;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,qBAAqB,CAMpF;AAeD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAQ3F;AAMD,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,mBAAmB,GAAG,eAAe,GAAG,SAAS,CAAC;AAMhG;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,CAKjE;AAED,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,EAC9B,SAAS,CAAC,EAAE,YAAY,GACvB,OAAO,CAAC,oBAAoB,CAAC,CA6B/B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAW5D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAqB5F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAOhG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAwB1F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAa5F;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAeT;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,UAAU,KAAK,MAAM,GACjE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAmHnE"}
@@ -243,6 +243,28 @@ export function writeSpecFileAtomic(specDir, filename, content) {
243
243
  }
244
244
  }
245
245
  }
246
+ /**
247
+ * Build a commit + optional push instruction block for prompt suffixes.
248
+ *
249
+ * Used by phase prompts to instruct the agent to commit spec/code changes
250
+ * at the end of each step, and optionally push when the --push flag is set.
251
+ */
252
+ export function buildCommitPushBlock(opts) {
253
+ const fileList = opts.files.map((f) => `\`${f}\``).join(', ');
254
+ const lines = [
255
+ `## Final Step — Commit Your Work`,
256
+ ``,
257
+ `After completing all tasks above:`,
258
+ `1. Stage the changed files: ${fileList} (use \`git add\` with the specific paths)`,
259
+ `2. Commit with a conventional commit message — e.g. \`${opts.commitHint}\``,
260
+ ` - The message should accurately describe what changed`,
261
+ ];
262
+ if (opts.push) {
263
+ lines.push(`3. Push to remote: \`git push -u origin HEAD\``);
264
+ lines.push(` - Do NOT wait for or watch CI — just push and finish`);
265
+ }
266
+ return lines.join('\n');
267
+ }
246
268
  /**
247
269
  * Execute a node with consistent logging and error handling.
248
270
  *
@@ -1 +1 @@
1
- {"version":3,"file":"analyze.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/analyze.prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAuFnE"}
1
+ {"version":3,"file":"analyze.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/analyze.prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CA6FnE"}
@@ -4,7 +4,7 @@
4
4
  * Instructs the agent to analyze the repository and user query,
5
5
  * then write findings to spec.yaml with complexity estimate and affected areas.
6
6
  */
7
- import { readSpecFile } from '../node-helpers.js';
7
+ import { readSpecFile, buildCommitPushBlock } from '../node-helpers.js';
8
8
  export function buildAnalyzePrompt(state) {
9
9
  const existingSpec = readSpecFile(state.specDir, 'spec.yaml');
10
10
  return `You are a senior software architect performing the ANALYSIS phase of feature development.
@@ -90,5 +90,11 @@ You MUST write the COMPLETE file (not a partial update). Preserve the existing n
90
90
  - Do NOT create any other files
91
91
  - Do NOT modify any source code
92
92
  - Do NOT start implementing the feature
93
- - Keep your analysis thorough but concise`;
93
+ - Keep your analysis thorough but concise
94
+
95
+ ${buildCommitPushBlock({
96
+ push: state.push,
97
+ files: [`${state.specDir}/spec.yaml`],
98
+ commitHint: 'docs(specs): analyze repository and define spec',
99
+ })}`;
94
100
  }
@@ -74,7 +74,7 @@ ${taskSections}
74
74
  2. For tasks with TDD guidance: write tests alongside implementation following the hints provided — use them as guidance, not rigid steps
75
75
  3. Follow existing codebase conventions for file placement, naming patterns, and architecture layers
76
76
  ${verificationBlock}
77
- 5. Commit your work with descriptive conventional commit messages (e.g. \`feat(scope): description\`)
77
+ 5. Commit your work with descriptive conventional commit messages (e.g. \`feat(scope): description\`)${state.push ? `\n6. Push to remote after committing: \`git push -u origin HEAD\`\n - Do NOT wait for or watch CI — just push and finish` : ''}
78
78
 
79
79
  ## Working Directory
80
80
 
@@ -1 +1 @@
1
- {"version":3,"file":"merge-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwCxD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,MAAM,CAyDR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CA0BR;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,SAAS,UAAQ,GAChB,MAAM,CAkER"}
1
+ {"version":3,"file":"merge-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwCxD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,MAAM,CA0DR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CA0BR;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,SAAS,UAAQ,GAChB,MAAM,CAkER"}
@@ -97,8 +97,9 @@ ${steps.join('\n')}
97
97
  ## Constraints
98
98
 
99
99
  - Write a meaningful conventional commit message derived from the actual diff — do NOT use generic messages
100
- - Do NOT modify any source code files — only perform git operations
100
+ ${rejectionSection ? '- You MUST modify source code files to address the rejection feedback above BEFORE committing' : '- Do NOT modify any source code files — only perform git operations'}
101
101
  - Do NOT amend existing commits
102
+ - Do NOT run \`git pull\`, \`git rebase\`, or \`git merge\` — this is a fresh branch, push it directly
102
103
  - If there are no changes to commit, skip the commit step and report that no changes were found`;
103
104
  }
104
105
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"plan.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAqMhE"}
1
+ {"version":3,"file":"plan.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CA2MhE"}
@@ -7,7 +7,7 @@
7
7
  * The tasks cover concrete TDD work items.
8
8
  */
9
9
  import yaml from 'js-yaml';
10
- import { readSpecFile } from '../node-helpers.js';
10
+ import { readSpecFile, buildCommitPushBlock } from '../node-helpers.js';
11
11
  export function buildPlanPrompt(state) {
12
12
  const specContent = readSpecFile(state.specDir, 'spec.yaml');
13
13
  const researchContent = readSpecFile(state.specDir, 'research.yaml');
@@ -200,5 +200,11 @@ You MUST write TWO files:
200
200
  - Follow existing codebase conventions for file placement and naming
201
201
  - Do NOT create any other files
202
202
  - Do NOT modify any source code
203
- - Do NOT start implementing — planning only`;
203
+ - Do NOT start implementing — planning only
204
+
205
+ ${buildCommitPushBlock({
206
+ push: state.push,
207
+ files: [`${state.specDir}/plan.yaml`, `${state.specDir}/tasks.yaml`],
208
+ commitHint: 'docs(specs): create implementation plan and task breakdown',
209
+ })}`;
204
210
  }
@@ -1 +1 @@
1
- {"version":3,"file":"requirements.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CA4KxE"}
1
+ {"version":3,"file":"requirements.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAkLxE"}
@@ -7,7 +7,7 @@
7
7
  * Writes back to spec.yaml with full requirements.
8
8
  */
9
9
  import yaml from 'js-yaml';
10
- import { readSpecFile } from '../node-helpers.js';
10
+ import { readSpecFile, buildCommitPushBlock } from '../node-helpers.js';
11
11
  export function buildRequirementsPrompt(state) {
12
12
  const specContent = readSpecFile(state.specDir, 'spec.yaml');
13
13
  // Extract rejection feedback if present
@@ -170,5 +170,11 @@ Write the COMPLETE file. Preserve name/number/branch/technologies from analysis
170
170
  - Every open question MUST also have an \`answer\` field matching the selected option text
171
171
  - Requirements must be specific and testable, not vague
172
172
  - Do NOT create any other files
173
- - Do NOT modify any source code`;
173
+ - Do NOT modify any source code
174
+
175
+ ${buildCommitPushBlock({
176
+ push: state.push,
177
+ files: [`${state.specDir}/spec.yaml`],
178
+ commitHint: 'docs(specs): define requirements and product questions',
179
+ })}`;
174
180
  }
@@ -1 +1 @@
1
- {"version":3,"file":"research.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/research.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CA8HpE"}
1
+ {"version":3,"file":"research.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/research.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAoIpE"}
@@ -5,7 +5,7 @@
5
5
  * evaluate libraries, and document architecture decisions with rationale.
6
6
  * Writes to research.yaml.
7
7
  */
8
- import { readSpecFile } from '../node-helpers.js';
8
+ import { readSpecFile, buildCommitPushBlock } from '../node-helpers.js';
9
9
  export function buildResearchPrompt(state) {
10
10
  const specContent = readSpecFile(state.specDir, 'spec.yaml');
11
11
  const existingResearch = readSpecFile(state.specDir, 'research.yaml');
@@ -130,5 +130,11 @@ Use this YAML structure:
130
130
  - Every open question MUST have exactly 3 options to choose from
131
131
  - Prefer solutions that follow existing codebase patterns and conventions
132
132
  - Do NOT create any other files
133
- - Do NOT modify any source code`;
133
+ - Do NOT modify any source code
134
+
135
+ ${buildCommitPushBlock({
136
+ push: state.push,
137
+ files: [`${state.specDir}/research.yaml`],
138
+ commitHint: 'docs(specs): research technical decisions and library choices',
139
+ })}`;
134
140
  }
@@ -1 +1 @@
1
- {"version":3,"file":"git-pr.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-pr.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAC5G,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,YAAY,EACb,MAAM,wEAAwE,CAAC;AAQhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,qBACa,YAAa,YAAW,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuC9C,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvE,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAuClE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,aAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBjE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkDjF,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhF,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAevE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAkCpD,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWrF,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAW3F,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,aAAa;CAiBtB"}
1
+ {"version":3,"file":"git-pr.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-pr.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAC5G,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,YAAY,EACb,MAAM,wEAAwE,CAAC;AAQhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,qBACa,YAAa,YAAW,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgF9C,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvE,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAuClE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,aAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBjE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkDjF,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhF,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAevE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAkCpD,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWrF,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAW3F,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,aAAa;CAiBtB"}
@@ -42,29 +42,68 @@ let GitPrService = class GitPrService {
42
42
  catch {
43
43
  // No remote HEAD configured — continue to fallbacks
44
44
  }
45
- // 2. Check for common default branch names locally
46
- for (const candidate of ['main', 'master']) {
45
+ // 2. Check for common default branch names locally.
46
+ // If both exist, pick the one with the most recent commit.
47
+ const candidates = [];
48
+ for (const name of ['main', 'master']) {
47
49
  try {
48
- const { stdout } = await this.execFile('git', ['rev-parse', '--verify', `refs/heads/${candidate}`], { cwd });
50
+ const { stdout } = await this.execFile('git', ['rev-parse', '--verify', `refs/heads/${name}`], { cwd });
49
51
  if (stdout.trim())
50
- return candidate;
52
+ candidates.push(name);
51
53
  }
52
54
  catch {
53
55
  // Branch doesn't exist — try next
54
56
  }
55
57
  }
56
- // 3. Fall back to current branch (works for single-branch / fresh repos)
58
+ if (candidates.length === 1)
59
+ return candidates[0];
60
+ if (candidates.length > 1) {
61
+ // Pick the branch with the most recent commit
62
+ try {
63
+ const { stdout } = await this.execFile('git', [
64
+ 'for-each-ref',
65
+ '--sort=-committerdate',
66
+ '--format=%(refname:short)',
67
+ ...candidates.map((c) => `refs/heads/${c}`),
68
+ ], { cwd });
69
+ const newest = stdout.trim().split('\n')[0];
70
+ if (newest)
71
+ return newest;
72
+ }
73
+ catch {
74
+ // Fall through to first candidate
75
+ }
76
+ return candidates[0];
77
+ }
78
+ // 3. Check git config init.defaultBranch (user/system-level default)
57
79
  try {
58
- const { stdout } = await this.execFile('git', ['symbolic-ref', '--short', 'HEAD'], { cwd });
59
- const branch = stdout.trim();
60
- if (branch)
61
- return branch;
80
+ const { stdout } = await this.execFile('git', ['config', 'init.defaultBranch'], { cwd });
81
+ const configured = stdout.trim();
82
+ if (configured)
83
+ return configured;
84
+ }
85
+ catch {
86
+ // Not configured — continue
87
+ }
88
+ // 4. Fall back to current branch ONLY in the main worktree (not feature worktrees).
89
+ // In a feature worktree, symbolic-ref HEAD returns the feature branch, not the default.
90
+ try {
91
+ const gitDir = await this.execFile('git', ['rev-parse', '--git-dir'], { cwd });
92
+ const gitCommonDir = await this.execFile('git', ['rev-parse', '--git-common-dir'], { cwd });
93
+ const isMainWorktree = gitDir.stdout.trim() === gitCommonDir.stdout.trim();
94
+ if (isMainWorktree) {
95
+ const { stdout } = await this.execFile('git', ['symbolic-ref', '--short', 'HEAD'], { cwd });
96
+ const branch = stdout.trim();
97
+ if (branch)
98
+ return branch;
99
+ }
62
100
  }
63
101
  catch {
64
- // Detached HEAD — continue
102
+ // Detached HEAD or other error — continue
65
103
  }
66
- // 4. Ultimate fallback
67
- return 'main';
104
+ // 5. Ultimate fallback — throw instead of silently guessing
105
+ throw new Error(`Unable to determine default branch for repository at ${cwd}. ` +
106
+ `No remote HEAD, no main/master branch, and no init.defaultBranch configured.`);
68
107
  }
69
108
  async hasUncommittedChanges(cwd) {
70
109
  const { stdout } = await this.execFile('git', ['status', '--porcelain'], { cwd });
@@ -22,6 +22,7 @@ export declare class WorktreeService implements IWorktreeService {
22
22
  list(repoPath: string): Promise<WorktreeInfo[]>;
23
23
  exists(repoPath: string, branch: string): Promise<boolean>;
24
24
  branchExists(repoPath: string, branch: string): Promise<boolean>;
25
+ remoteBranchExists(repoPath: string, branch: string): Promise<boolean>;
25
26
  ensureGitRepository(repoPath: string): Promise<void>;
26
27
  getWorktreePath(repoPath: string, branch: string): string;
27
28
  private parseWorktreeOutput;
@@ -1 +1 @@
1
- {"version":3,"file":"worktree.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/worktree.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,0EAA0E,CAAC;AAOlF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjD,qBACa,eAAgB,YAAW,gBAAgB;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC;IAqBlB,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAO/C,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWhE,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC1D,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAMzD,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;CAU9B"}
1
+ {"version":3,"file":"worktree.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/worktree.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,0EAA0E,CAAC;AAOlF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjD,qBACa,eAAgB,YAAW,gBAAgB;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC;IAqBlB,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAO/C,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWhE,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWtE,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC1D,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAMzD,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;CAU9B"}
@@ -77,6 +77,17 @@ let WorktreeService = class WorktreeService {
77
77
  return false;
78
78
  }
79
79
  }
80
+ async remoteBranchExists(repoPath, branch) {
81
+ try {
82
+ const { stdout } = await this.execFile('git', ['ls-remote', '--heads', 'origin', branch], {
83
+ cwd: repoPath,
84
+ });
85
+ return stdout.trim().length > 0;
86
+ }
87
+ catch {
88
+ return false;
89
+ }
90
+ }
80
91
  async ensureGitRepository(repoPath) {
81
92
  let isExistingRepo = false;
82
93
  try {