@shepai/cli 1.47.0 → 1.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/apis/json-schema/ApprovalGateDefaults.yaml +26 -0
  2. package/apis/json-schema/Feature.yaml +3 -0
  3. package/apis/json-schema/Repository.yaml +16 -0
  4. package/apis/json-schema/Settings.yaml +5 -0
  5. package/apis/json-schema/WorkflowConfig.yaml +4 -20
  6. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +17 -0
  7. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts +11 -1
  9. package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +3 -1
  11. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  12. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +11 -4
  13. package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.d.ts +19 -0
  14. package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.d.ts.map +1 -0
  15. package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.js +52 -0
  16. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  17. package/dist/packages/core/src/infrastructure/di/container.js +5 -0
  18. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  19. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +2 -0
  20. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts +2 -0
  21. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +1 -1
  22. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +10 -3
  23. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  24. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +15 -7
  25. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +2 -0
  26. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
  27. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +41 -0
  28. package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts +2 -1
  29. package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
  30. package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +29 -4
  31. package/dist/src/presentation/cli/ui/messages.d.ts.map +1 -1
  32. package/dist/src/presentation/cli/ui/messages.js +1 -7
  33. package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts +7 -0
  34. package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts.map +1 -0
  35. package/dist/src/presentation/web/app/actions/get-merge-review-data.js +49 -0
  36. package/dist/src/presentation/web/app/page.d.ts.map +1 -1
  37. package/dist/src/presentation/web/app/page.js +1 -0
  38. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  39. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +8 -1
  40. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +1 -0
  41. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  42. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +22 -1
  43. package/dist/src/presentation/web/components/common/merge-review/index.d.ts +4 -0
  44. package/dist/src/presentation/web/components/common/merge-review/index.d.ts.map +1 -0
  45. package/dist/src/presentation/web/components/common/merge-review/index.js +2 -0
  46. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts +75 -0
  47. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts.map +1 -0
  48. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.js +1 -0
  49. package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts +3 -0
  50. package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts.map +1 -0
  51. package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.js +7 -0
  52. package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts +3 -0
  53. package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts.map +1 -0
  54. package/dist/src/presentation/web/components/common/merge-review/merge-review.js +36 -0
  55. package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts +32 -0
  56. package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts.map +1 -0
  57. package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.js +165 -0
  58. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  59. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +55 -1
  60. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
  61. package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +15 -0
  62. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  63. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +37 -15
  64. package/dist/tsconfig.build.tsbuildinfo +1 -1
  65. package/package.json +1 -1
  66. package/web/.next/BUILD_ID +1 -1
  67. package/web/.next/build-manifest.json +2 -2
  68. package/web/.next/cache/.previewinfo +1 -1
  69. package/web/.next/cache/.rscinfo +1 -1
  70. package/web/.next/cache/.tsbuildinfo +1 -1
  71. package/web/.next/cache/config.json +3 -3
  72. package/web/.next/fallback-build-manifest.json +2 -2
  73. package/web/.next/prerender-manifest.json +3 -3
  74. package/web/.next/required-server-files.js +1 -1
  75. package/web/.next/required-server-files.json +1 -1
  76. package/web/.next/server/app/_global-error.html +2 -2
  77. package/web/.next/server/app/_global-error.rsc +1 -1
  78. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  79. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  80. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  81. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  82. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  83. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  84. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  85. package/web/.next/server/app/page/server-reference-manifest.json +39 -24
  86. package/web/.next/server/app/page.js +1 -1
  87. package/web/.next/server/app/page.js.nft.json +1 -1
  88. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  89. package/web/.next/server/app/version/page.js.nft.json +1 -1
  90. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  91. package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +4 -4
  92. package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js.map +1 -1
  93. package/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js +9 -0
  94. package/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js.map +1 -0
  95. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  96. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/_3ac3601c._.js → server/chunks/ssr/_1fafa9db._.js} +2 -2
  97. package/web/.next/server/chunks/ssr/_1fafa9db._.js.map +1 -0
  98. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  99. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  100. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  101. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
  102. package/web/.next/server/pages/500.html +2 -2
  103. package/web/.next/server/server-reference-manifest.js +1 -1
  104. package/web/.next/server/server-reference-manifest.json +40 -25
  105. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  106. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  107. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  108. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  109. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  110. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  111. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  112. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  113. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  114. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  115. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  116. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  117. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  118. package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +39 -24
  119. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js +1 -1
  120. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
  121. package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
  122. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
  123. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  124. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +4 -4
  125. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js +9 -0
  126. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  127. package/web/.next/{server/chunks/ssr/_3ac3601c._.js → standalone/src/presentation/web/.next/server/chunks/ssr/_1fafa9db._.js} +2 -2
  128. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  129. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  130. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  131. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  132. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +40 -25
  133. package/web/.next/standalone/src/presentation/web/app/actions/get-merge-review-data.ts +64 -0
  134. package/web/.next/standalone/src/presentation/web/app/page.tsx +1 -0
  135. package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.stories.tsx +23 -1
  136. package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.tsx +6 -1
  137. package/web/.next/standalone/src/presentation/web/components/common/merge-review/index.ts +7 -0
  138. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review-config.ts +81 -0
  139. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review-drawer.tsx +34 -0
  140. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.stories.tsx +240 -0
  141. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.tsx +252 -0
  142. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +82 -1
  143. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center.stories.tsx +15 -0
  144. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +47 -17
  145. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  146. package/web/.next/static/chunks/{9f8e71029fb04681.js → 0da7a9860fa6ae05.js} +2 -2
  147. package/web/.next/static/chunks/22f30ce91a3c79c1.js +1 -0
  148. package/web/.next/static/chunks/66378a6c055c4e67.js +10 -0
  149. package/web/.next/static/chunks/8668962d3e682263.css +2 -0
  150. package/web/.next/trace +1 -1
  151. package/web/.next/trace-build +1 -1
  152. package/web/.next/server/chunks/ssr/[root-of-the-server]__d6d75c22._.js +0 -9
  153. package/web/.next/server/chunks/ssr/[root-of-the-server]__d6d75c22._.js.map +0 -1
  154. package/web/.next/server/chunks/ssr/_3ac3601c._.js.map +0 -1
  155. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__d6d75c22._.js +0 -9
  156. package/web/.next/static/chunks/779c99975c85389e.js +0 -10
  157. package/web/.next/static/chunks/83ff3b6bbee54bce.js +0 -1
  158. package/web/.next/static/chunks/b7b7abe79e05b229.css +0 -2
  159. /package/web/.next/static/{wQ3vPV9I8JeacVNyp4HFg → 1kZFDMQ0i-Y8dy1KkHlzv}/_buildManifest.js +0 -0
  160. /package/web/.next/static/{wQ3vPV9I8JeacVNyp4HFg → 1kZFDMQ0i-Y8dy1KkHlzv}/_clientMiddlewareManifest.json +0 -0
  161. /package/web/.next/static/{wQ3vPV9I8JeacVNyp4HFg → 1kZFDMQ0i-Y8dy1KkHlzv}/_ssgManifest.js +0 -0
@@ -0,0 +1,26 @@
1
+ $schema: https://json-schema.org/draft/2020-12/schema
2
+ $id: ApprovalGateDefaults.yaml
3
+ type: object
4
+ properties:
5
+ allowPrd:
6
+ type: boolean
7
+ default: false
8
+ description: "Auto-approve requirements phase (default: false)"
9
+ allowPlan:
10
+ type: boolean
11
+ default: false
12
+ description: "Auto-approve planning phase (default: false)"
13
+ allowMerge:
14
+ type: boolean
15
+ default: false
16
+ description: "Auto-approve merge phase (default: false)"
17
+ pushOnImplementationComplete:
18
+ type: boolean
19
+ default: false
20
+ description: "Push branch to remote on implementation complete (default: false)"
21
+ required:
22
+ - allowPrd
23
+ - allowPlan
24
+ - allowMerge
25
+ - pushOnImplementationComplete
26
+ description: Default approval gate settings for new features
@@ -42,6 +42,9 @@ properties:
42
42
  specPath:
43
43
  type: string
44
44
  description: Absolute path to the feature spec directory inside the worktree
45
+ repositoryId:
46
+ $ref: UUID.yaml
47
+ description: ID of the Repository entity this feature belongs to
45
48
  push:
46
49
  type: boolean
47
50
  default: false
@@ -0,0 +1,16 @@
1
+ $schema: https://json-schema.org/draft/2020-12/schema
2
+ $id: Repository.yaml
3
+ type: object
4
+ properties:
5
+ name:
6
+ type: string
7
+ description: Human-readable name for the repository (typically the directory name)
8
+ path:
9
+ type: string
10
+ description: Absolute file system path to the repository root (unique)
11
+ required:
12
+ - name
13
+ - path
14
+ allOf:
15
+ - $ref: SoftDeletableEntity.yaml
16
+ description: A code repository tracked by the Shep platform
@@ -23,6 +23,10 @@ properties:
23
23
  workflow:
24
24
  $ref: WorkflowConfig.yaml
25
25
  description: Global workflow configuration defaults
26
+ onboardingComplete:
27
+ type: boolean
28
+ default: false
29
+ description: "Whether first-run onboarding has been completed (default: false)"
26
30
  required:
27
31
  - models
28
32
  - user
@@ -31,6 +35,7 @@ required:
31
35
  - agent
32
36
  - notifications
33
37
  - workflow
38
+ - onboardingComplete
34
39
  allOf:
35
40
  - $ref: BaseEntity.yaml
36
41
  description: Global Shep platform settings (singleton)
@@ -6,26 +6,10 @@ properties:
6
6
  type: boolean
7
7
  default: false
8
8
  description: "Create PR on implementation complete (default: false)"
9
- pushOnImplementationComplete:
10
- type: boolean
11
- default: false
12
- description: "Push branch on implementation complete (default: false)"
13
- allowPrd:
14
- type: boolean
15
- default: false
16
- description: "Auto-approve requirements phase (default: false)"
17
- allowPlan:
18
- type: boolean
19
- default: false
20
- description: "Auto-approve planning phase (default: false)"
21
- autoMergeOnImplementationComplete:
22
- type: boolean
23
- default: false
24
- description: "Auto-merge on implementation complete (default: false)"
9
+ approvalGateDefaults:
10
+ $ref: ApprovalGateDefaults.yaml
11
+ description: Default approval gate preferences for new features
25
12
  required:
26
13
  - openPrOnImplementationComplete
27
- - pushOnImplementationComplete
28
- - allowPrd
29
- - allowPlan
30
- - autoMergeOnImplementationComplete
14
+ - approvalGateDefaults
31
15
  description: Global workflow configuration defaults
@@ -71,6 +71,23 @@ export type MergeStrategy = 'squash' | 'merge' | 'rebase';
71
71
  * Service interface for git PR and merge operations.
72
72
  */
73
73
  export interface IGitPrService {
74
+ /**
75
+ * Check if the repository has any configured git remotes.
76
+ *
77
+ * @param cwd - Working directory path
78
+ * @returns True if at least one remote is configured
79
+ */
80
+ hasRemote(cwd: string): Promise<boolean>;
81
+ /**
82
+ * Detect the repository's default branch with robust fallback chain:
83
+ * 1. Remote HEAD (git symbolic-ref refs/remotes/origin/HEAD)
84
+ * 2. Local branches named main or master (in that order)
85
+ * 3. Current branch (git symbolic-ref HEAD)
86
+ *
87
+ * @param cwd - Working directory path
88
+ * @returns The default branch name (e.g. "main", "master", "develop")
89
+ */
90
+ getDefaultBranch(cwd: string): Promise<string>;
74
91
  /**
75
92
  * Check if the working directory has uncommitted changes.
76
93
  *
@@ -1 +1 @@
1
- {"version":3,"file":"git-pr-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/git-pr-service.interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git-pr-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/git-pr-service.interface.ts"],"names":[],"mappings":"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"}
@@ -45,10 +45,11 @@ export interface IWorktreeService {
45
45
  * @param repoPath - Path to the git repository
46
46
  * @param branch - Branch name to create
47
47
  * @param worktreePath - Path for the new worktree directory
48
+ * @param startPoint - Optional commit/branch to start from (defaults to HEAD)
48
49
  * @returns Information about the created worktree
49
50
  * @throws WorktreeError with appropriate code
50
51
  */
51
- create(repoPath: string, branch: string, worktreePath: string): Promise<WorktreeInfo>;
52
+ create(repoPath: string, branch: string, worktreePath: string, startPoint?: string): Promise<WorktreeInfo>;
52
53
  /**
53
54
  * Remove an existing worktree.
54
55
  *
@@ -87,5 +88,14 @@ export interface IWorktreeService {
87
88
  * @returns Computed worktree path (e.g., /repo/.worktrees/branch-name)
88
89
  */
89
90
  getWorktreePath(repoPath: string, branch: string): string;
91
+ /**
92
+ * Ensure a directory is a valid git repository with at least one commit.
93
+ * If the directory is not a git repo, initializes it with `git init`
94
+ * and creates an empty initial commit. No-ops for existing repos.
95
+ *
96
+ * @param repoPath - Path to the directory to check/initialize
97
+ * @throws WorktreeError if git initialization fails
98
+ */
99
+ ensureGitRepository(repoPath: string): Promise<void>;
90
100
  }
91
101
  //# sourceMappingURL=worktree-service.interface.d.ts.map
@@ -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;;;;;;;;OAQG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAEtF;;;;;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;CAC3D"}
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"}
@@ -21,6 +21,7 @@ import type { IFeatureAgentProcessService } from '../../../ports/output/agents/f
21
21
  import type { IAgentRunRepository } from '../../../ports/output/agents/agent-run-repository.interface.js';
22
22
  import type { ISpecInitializerService } from '../../../ports/output/services/spec-initializer.interface.js';
23
23
  import type { IRepositoryRepository } from '../../../ports/output/repositories/repository-repository.interface.js';
24
+ import type { IGitPrService } from '../../../ports/output/services/git-pr-service.interface.js';
24
25
  import { MetadataGenerator } from './metadata-generator.js';
25
26
  import { SlugResolver } from './slug-resolver.js';
26
27
  import type { CreateFeatureInput, CreateFeatureResult } from './types.js';
@@ -33,7 +34,8 @@ export declare class CreateFeatureUseCase {
33
34
  private readonly metadataGenerator;
34
35
  private readonly slugResolver;
35
36
  private readonly repositoryRepo;
36
- constructor(featureRepo: IFeatureRepository, worktreeService: IWorktreeService, agentProcess: IFeatureAgentProcessService, runRepository: IAgentRunRepository, specInitializer: ISpecInitializerService, metadataGenerator: MetadataGenerator, slugResolver: SlugResolver, repositoryRepo: IRepositoryRepository);
37
+ private readonly gitPrService;
38
+ constructor(featureRepo: IFeatureRepository, worktreeService: IWorktreeService, agentProcess: IFeatureAgentProcessService, runRepository: IAgentRunRepository, specInitializer: ISpecInitializerService, metadataGenerator: MetadataGenerator, slugResolver: SlugResolver, repositoryRepo: IRepositoryRepository, gitPrService: IGitPrService);
37
39
  execute(input: CreateFeatureInput): Promise<CreateFeatureResult>;
38
40
  }
39
41
  //# sourceMappingURL=create-feature.use-case.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/use-cases/features/create/create-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oEAAoE,CAAC;AAC7G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8DAA8D,CAAC;AACrG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iEAAiE,CAAC;AACnH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gEAAgE,CAAC;AAC1G,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8DAA8D,CAAC;AAC5G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uEAAuE,CAAC;AAEnH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAEhC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAdd,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;IAGlD,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAmGvE"}
1
+ {"version":3,"file":"create-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/use-cases/features/create/create-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oEAAoE,CAAC;AAC7G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8DAA8D,CAAC;AACrG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iEAAiE,CAAC;AACnH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gEAAgE,CAAC;AAC1G,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8DAA8D,CAAC;AAC5G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uEAAuE,CAAC;AACnH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4DAA4D,CAAC;AAEhG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAEhC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAhBZ,WAAW,EAAE,kBAAkB,EAE/B,eAAe,EAAE,gBAAgB,EAEjC,YAAY,EAAE,2BAA2B,EAEzC,aAAa,EAAE,mBAAmB,EAElC,eAAe,EAAE,uBAAuB,EAExC,iBAAiB,EAAE,iBAAiB,EAEpC,YAAY,EAAE,YAAY,EAE1B,cAAc,EAAE,qBAAqB,EAErC,YAAY,EAAE,aAAa;IAGxC,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAwGvE"}
@@ -42,7 +42,8 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
42
42
  metadataGenerator;
43
43
  slugResolver;
44
44
  repositoryRepo;
45
- constructor(featureRepo, worktreeService, agentProcess, runRepository, specInitializer, metadataGenerator, slugResolver, repositoryRepo) {
45
+ gitPrService;
46
+ constructor(featureRepo, worktreeService, agentProcess, runRepository, specInitializer, metadataGenerator, slugResolver, repositoryRepo, gitPrService) {
46
47
  this.featureRepo = featureRepo;
47
48
  this.worktreeService = worktreeService;
48
49
  this.agentProcess = agentProcess;
@@ -51,8 +52,12 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
51
52
  this.metadataGenerator = metadataGenerator;
52
53
  this.slugResolver = slugResolver;
53
54
  this.repositoryRepo = repositoryRepo;
55
+ this.gitPrService = gitPrService;
54
56
  }
55
57
  async execute(input) {
58
+ // Ensure the target directory is a git repository (auto-init if needed)
59
+ // Must run before slug resolution which needs git commands
60
+ await this.worktreeService.ensureGitRepository(input.repositoryPath);
56
61
  const metadata = await this.metadataGenerator.generateMetadata(input.userInput);
57
62
  const originalSlug = metadata.slug;
58
63
  // Find a unique slug — the branch may exist from a previous (deleted) feature
@@ -64,9 +69,10 @@ let CreateFeatureUseCase = class CreateFeatureUseCase {
64
69
  const featureNumber = existingFeatures.length + 1;
65
70
  const now = new Date();
66
71
  const runId = randomUUID();
67
- // Create git worktree for isolated development
72
+ // Create git worktree branching from the repo's default branch
73
+ const defaultBranch = await this.gitPrService.getDefaultBranch(input.repositoryPath);
68
74
  const worktreePath = this.worktreeService.getWorktreePath(input.repositoryPath, branch);
69
- await this.worktreeService.create(input.repositoryPath, branch, worktreePath);
75
+ await this.worktreeService.create(input.repositoryPath, branch, worktreePath, defaultBranch);
70
76
  // Initialize spec directory — full user input goes into spec.yaml as-is
71
77
  const { specDir } = await this.specInitializer.initialize(worktreePath, slug, featureNumber, input.userInput);
72
78
  // Resolve or create repository entity for this path
@@ -143,7 +149,8 @@ CreateFeatureUseCase = __decorate([
143
149
  __param(5, inject(MetadataGenerator)),
144
150
  __param(6, inject(SlugResolver)),
145
151
  __param(7, inject('IRepositoryRepository')),
152
+ __param(8, inject('IGitPrService')),
146
153
  __metadata("design:paramtypes", [Object, Object, Object, Object, Object, MetadataGenerator,
147
- SlugResolver, Object])
154
+ SlugResolver, Object, Object])
148
155
  ], CreateFeatureUseCase);
149
156
  export { CreateFeatureUseCase };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Get Plan Artifact Use Case
3
+ *
4
+ * Retrieves the parsed TechnicalPlanArtifact for a given feature by
5
+ * reading and parsing the plan.yaml from the feature's spec directory.
6
+ *
7
+ * Business Rules:
8
+ * - Throws if the feature does not exist
9
+ * - Throws if the feature has no specPath
10
+ * - Throws if plan.yaml cannot be read or parsed
11
+ */
12
+ import type { TechnicalPlanArtifact } from '../../../domain/generated/output.js';
13
+ import type { IFeatureRepository } from '../../ports/output/repositories/feature-repository.interface.js';
14
+ export declare class GetPlanArtifactUseCase {
15
+ private readonly featureRepo;
16
+ constructor(featureRepo: IFeatureRepository);
17
+ execute(featureId: string): Promise<TechnicalPlanArtifact>;
18
+ }
19
+ //# sourceMappingURL=get-plan-artifact.use-case.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-plan-artifact.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/get-plan-artifact.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAEjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAE1G,qBACa,sBAAsB;IAG/B,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,kBAAkB;IAG5C,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAgBjE"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Get Plan Artifact Use Case
3
+ *
4
+ * Retrieves the parsed TechnicalPlanArtifact for a given feature by
5
+ * reading and parsing the plan.yaml from the feature's spec directory.
6
+ *
7
+ * Business Rules:
8
+ * - Throws if the feature does not exist
9
+ * - Throws if the feature has no specPath
10
+ * - Throws if plan.yaml cannot be read or parsed
11
+ */
12
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
13
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
15
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
16
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
17
+ };
18
+ var __metadata = (this && this.__metadata) || function (k, v) {
19
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
20
+ };
21
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
22
+ return function (target, key) { decorator(target, key, paramIndex); }
23
+ };
24
+ import { injectable, inject } from 'tsyringe';
25
+ import { readFile } from 'node:fs/promises';
26
+ import { join } from 'node:path';
27
+ import { parsePlanYaml } from '../../../domain/factories/spec-yaml-parser.js';
28
+ let GetPlanArtifactUseCase = class GetPlanArtifactUseCase {
29
+ featureRepo;
30
+ constructor(featureRepo) {
31
+ this.featureRepo = featureRepo;
32
+ }
33
+ async execute(featureId) {
34
+ const feature = (await this.featureRepo.findById(featureId)) ??
35
+ (await this.featureRepo.findByIdPrefix(featureId));
36
+ if (!feature) {
37
+ throw new Error(`Feature not found: "${featureId}"`);
38
+ }
39
+ if (!feature.specPath) {
40
+ throw new Error(`Feature "${featureId}" has no spec path`);
41
+ }
42
+ const planYamlPath = join(feature.specPath, 'plan.yaml');
43
+ const content = await readFile(planYamlPath, 'utf-8');
44
+ return parsePlanYaml(content);
45
+ }
46
+ };
47
+ GetPlanArtifactUseCase = __decorate([
48
+ injectable(),
49
+ __param(0, inject('IFeatureRepository')),
50
+ __metadata("design:paramtypes", [Object])
51
+ ], GetPlanArtifactUseCase);
52
+ export { GetPlanArtifactUseCase };
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAgGrC;;;;;;GAMG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,SAAS,CAAC,CAsNrE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAiGrC;;;;;;GAMG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,SAAS,CAAC,CA0NrE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -63,6 +63,7 @@ import { DeleteFeatureUseCase } from '../../application/use-cases/features/delet
63
63
  import { ResumeFeatureUseCase } from '../../application/use-cases/features/resume-feature.use-case.js';
64
64
  import { GetFeatureArtifactUseCase } from '../../application/use-cases/features/get-feature-artifact.use-case.js';
65
65
  import { GetResearchArtifactUseCase } from '../../application/use-cases/features/get-research-artifact.use-case.js';
66
+ import { GetPlanArtifactUseCase } from '../../application/use-cases/features/get-plan-artifact.use-case.js';
66
67
  import { ValidateToolAvailabilityUseCase } from '../../application/use-cases/tools/validate-tool-availability.use-case.js';
67
68
  import { InstallToolUseCase } from '../../application/use-cases/tools/install-tool.use-case.js';
68
69
  import { LaunchIdeUseCase } from '../../application/use-cases/ide/launch-ide.use-case.js';
@@ -224,6 +225,7 @@ export async function initializeContainer() {
224
225
  container.registerSingleton(ResumeFeatureUseCase);
225
226
  container.registerSingleton(GetFeatureArtifactUseCase);
226
227
  container.registerSingleton(GetResearchArtifactUseCase);
228
+ container.registerSingleton(GetPlanArtifactUseCase);
227
229
  container.registerSingleton(ValidateToolAvailabilityUseCase);
228
230
  container.registerSingleton(InstallToolUseCase);
229
231
  container.registerSingleton(LaunchIdeUseCase);
@@ -250,6 +252,9 @@ export async function initializeContainer() {
250
252
  container.register('GetResearchArtifactUseCase', {
251
253
  useFactory: (c) => c.resolve(GetResearchArtifactUseCase),
252
254
  });
255
+ container.register('GetPlanArtifactUseCase', {
256
+ useFactory: (c) => c.resolve(GetPlanArtifactUseCase),
257
+ });
253
258
  container.register('LaunchIdeUseCase', {
254
259
  useFactory: (c) => c.resolve(LaunchIdeUseCase),
255
260
  });
@@ -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;AAoB1B,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;CACxB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAoD1D;AAgCD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkM/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;AAoB1B,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;CACxB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAoD1D;AAgCD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAoM/D"}
@@ -128,6 +128,8 @@ export async function runWorker(args) {
128
128
  executor,
129
129
  mergeNodeDeps: {
130
130
  getDiffSummary: (cwd, baseBranch) => gitPrService.getPrDiffSummary(cwd, baseBranch),
131
+ hasRemote: (cwd) => gitPrService.hasRemote(cwd),
132
+ getDefaultBranch: (cwd) => gitPrService.getDefaultBranch(cwd),
131
133
  featureRepository,
132
134
  },
133
135
  };
@@ -14,6 +14,8 @@ import type { DiffSummary } from '../../../../../application/ports/output/servic
14
14
  export interface MergeNodeDeps {
15
15
  executor: IAgentExecutor;
16
16
  getDiffSummary: (cwd: string, baseBranch: string) => Promise<DiffSummary>;
17
+ hasRemote: (cwd: string) => Promise<boolean>;
18
+ getDefaultBranch: (cwd: string) => Promise<string>;
17
19
  featureRepository: Pick<IFeatureRepository, 'findById' | 'update'>;
18
20
  }
19
21
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iEAAiE,CAAC;AAkBnG,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1E,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;CACpE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAGnC,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CA2H7E"}
1
+ {"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iEAAiE,CAAC;AAkBnG,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1E,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;CACpE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAGnC,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAoI7E"}
@@ -37,11 +37,18 @@ export function createMergeNode(deps) {
37
37
  // Resolve branch name from feature
38
38
  const feature = await deps.featureRepository.findById(state.featureId);
39
39
  const branch = feature?.branch ?? `feat/${state.featureId}`;
40
- const baseBranch = 'main';
40
+ const baseBranch = await deps.getDefaultBranch(cwd);
41
41
  const options = buildExecutorOptions(state);
42
+ // --- Check for git remote ---
43
+ const remoteAvailable = await deps.hasRemote(cwd);
44
+ if (!remoteAvailable) {
45
+ log.info('No git remote configured — skipping push and PR, will merge locally');
46
+ }
47
+ // Override push/openPr when no remote is available
48
+ const effectiveState = remoteAvailable ? state : { ...state, push: false, openPr: false };
42
49
  // --- Agent Call 1: Commit + Push + PR ---
43
50
  log.info('Agent call 1: commit + push + PR');
44
- const commitPushPrPrompt = buildCommitPushPrPrompt(state, branch, baseBranch);
51
+ const commitPushPrPrompt = buildCommitPushPrPrompt(effectiveState, branch, baseBranch);
45
52
  const commitResult = await retryExecute(executor, commitPushPrPrompt, options, {
46
53
  logger: log,
47
54
  });
@@ -51,7 +58,7 @@ export function createMergeNode(deps) {
51
58
  let prUrl = state.prUrl;
52
59
  let prNumber = state.prNumber;
53
60
  const ciStatus = state.ciStatus;
54
- if (state.openPr) {
61
+ if (effectiveState.openPr) {
55
62
  const prResult = parsePrUrl(commitResult.result);
56
63
  if (prResult) {
57
64
  prUrl = prResult.url;
@@ -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;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,MAAM,CAwDR;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,MAAM,CAwDR"}
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;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,MAAM,CAwDR;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,MAAM,CAiER"}
@@ -94,6 +94,20 @@ export function buildMergeSquashPrompt(state, branch, baseBranch) {
94
94
  }
95
95
  // Non-PR path: local merge in the ORIGINAL repo (not the worktree)
96
96
  const originalRepo = state.repositoryPath;
97
+ const hasRemote = state.push || state.openPr;
98
+ const fetchSteps = hasRemote
99
+ ? `2. Fetch latest: \`git fetch origin\`
100
+ 3. Checkout the base branch: \`git checkout ${baseBranch}\`
101
+ 4. Pull latest base: \`git pull origin ${baseBranch}\`
102
+ 5. Merge the feature branch: \`git merge --squash ${branch}\`
103
+ 6. If merge conflicts are encountered, resolve them manually and complete the merge
104
+ 7. Commit the squash merge with a descriptive conventional commit message
105
+ 8. Delete the feature branch after successful merge: \`git branch -d ${branch}\``
106
+ : `2. Checkout the base branch: \`git checkout ${baseBranch}\`
107
+ 3. Merge the feature branch: \`git merge --squash ${branch}\`
108
+ 4. If merge conflicts are encountered, resolve them manually and complete the merge
109
+ 5. Commit the squash merge with a descriptive conventional commit message
110
+ 6. Delete the feature branch after successful merge: \`git branch -d ${branch}\``;
97
111
  return `You are performing a local merge in the original repository directory.
98
112
 
99
113
  IMPORTANT: You MUST run all git commands in the original repository directory, NOT in any worktree.
@@ -110,13 +124,7 @@ ${originalRepo}
110
124
  ## Instructions
111
125
 
112
126
  1. Change to the original repository: \`cd ${originalRepo}\`
113
- 2. Fetch latest: \`git fetch origin\`
114
- 3. Checkout the base branch: \`git checkout ${baseBranch}\`
115
- 4. Pull latest base: \`git pull origin ${baseBranch}\`
116
- 5. Merge the feature branch: \`git merge --squash ${branch}\`
117
- 6. If merge conflicts are encountered, resolve them manually and complete the merge
118
- 7. Commit the squash merge with a descriptive conventional commit message
119
- 8. Delete the feature branch after successful merge: \`git branch -d ${branch}\`
127
+ ${fetchSteps}
120
128
 
121
129
  ## Constraints
122
130
 
@@ -10,6 +10,8 @@ import type { ExecFunction } from './worktree.service.js';
10
10
  export declare class GitPrService implements IGitPrService {
11
11
  private readonly execFile;
12
12
  constructor(execFile: ExecFunction);
13
+ hasRemote(cwd: string): Promise<boolean>;
14
+ getDefaultBranch(cwd: string): Promise<string>;
13
15
  hasUncommittedChanges(cwd: string): Promise<boolean>;
14
16
  commitAll(cwd: string, message: string): Promise<string>;
15
17
  push(cwd: string, branch: string, setUpstream?: boolean): Promise<void>;
@@ -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,EACf,MAAM,wEAAwE,CAAC;AAOhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,qBACa,YAAa,YAAW,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,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;IAuBjF,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;IAe7E,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,EACf,MAAM,wEAAwE,CAAC;AAOhF,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;IAuBjF,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;IAe7E,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,aAAa;CAiBtB"}
@@ -25,6 +25,47 @@ let GitPrService = class GitPrService {
25
25
  constructor(execFile) {
26
26
  this.execFile = execFile;
27
27
  }
28
+ async hasRemote(cwd) {
29
+ const { stdout } = await this.execFile('git', ['remote'], { cwd });
30
+ return stdout.trim().length > 0;
31
+ }
32
+ async getDefaultBranch(cwd) {
33
+ // 1. Try remote HEAD reference (most reliable when remote exists)
34
+ try {
35
+ const { stdout } = await this.execFile('git', ['symbolic-ref', 'refs/remotes/origin/HEAD'], {
36
+ cwd,
37
+ });
38
+ const ref = stdout.trim(); // e.g. "refs/remotes/origin/main"
39
+ if (ref)
40
+ return ref.replace('refs/remotes/origin/', '');
41
+ }
42
+ catch {
43
+ // No remote HEAD configured — continue to fallbacks
44
+ }
45
+ // 2. Check for common default branch names locally
46
+ for (const candidate of ['main', 'master']) {
47
+ try {
48
+ const { stdout } = await this.execFile('git', ['rev-parse', '--verify', `refs/heads/${candidate}`], { cwd });
49
+ if (stdout.trim())
50
+ return candidate;
51
+ }
52
+ catch {
53
+ // Branch doesn't exist — try next
54
+ }
55
+ }
56
+ // 3. Fall back to current branch (works for single-branch / fresh repos)
57
+ try {
58
+ const { stdout } = await this.execFile('git', ['symbolic-ref', '--short', 'HEAD'], { cwd });
59
+ const branch = stdout.trim();
60
+ if (branch)
61
+ return branch;
62
+ }
63
+ catch {
64
+ // Detached HEAD — continue
65
+ }
66
+ // 4. Ultimate fallback
67
+ return 'main';
68
+ }
28
69
  async hasUncommittedChanges(cwd) {
29
70
  const { stdout } = await this.execFile('git', ['status', '--porcelain'], { cwd });
30
71
  return stdout.trim().length > 0;
@@ -17,11 +17,12 @@ export type ExecFunction = (file: string, args: string[], options?: object) => P
17
17
  export declare class WorktreeService implements IWorktreeService {
18
18
  private readonly execFile;
19
19
  constructor(execFile: ExecFunction);
20
- create(repoPath: string, branch: string, worktreePath: string): Promise<WorktreeInfo>;
20
+ create(repoPath: string, branch: string, worktreePath: string, startPoint?: string): Promise<WorktreeInfo>;
21
21
  remove(worktreePath: string): Promise<void>;
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
+ ensureGitRepository(repoPath: string): Promise<void>;
25
26
  getWorktreePath(repoPath: string, branch: string): string;
26
27
  private parseWorktreeOutput;
27
28
  private parseGitError;
@@ -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;AAKH,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,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAqBrF,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;IAWtE,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,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB1D,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"}
@@ -18,8 +18,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
18
18
  return function (target, key) { decorator(target, key, paramIndex); }
19
19
  };
20
20
  import { createHash } from 'node:crypto';
21
+ import { mkdirSync } from 'node:fs';
21
22
  import path from 'node:path';
22
23
  import { injectable, inject } from 'tsyringe';
24
+ const GIT_AUTO_INIT_USER = 'shep-ai[bot]';
25
+ const GIT_AUTO_INIT_EMAIL = 'bot@shep.bot';
23
26
  import { WorktreeError, WorktreeErrorCode, } from '../../../application/ports/output/services/worktree-service.interface.js';
24
27
  import { getShepHomeDir } from '../filesystem/shep-directory.service.js';
25
28
  let WorktreeService = class WorktreeService {
@@ -27,11 +30,12 @@ let WorktreeService = class WorktreeService {
27
30
  constructor(execFile) {
28
31
  this.execFile = execFile;
29
32
  }
30
- async create(repoPath, branch, worktreePath) {
33
+ async create(repoPath, branch, worktreePath, startPoint) {
31
34
  try {
32
- await this.execFile('git', ['worktree', 'add', worktreePath, '-b', branch], {
33
- cwd: repoPath,
34
- });
35
+ const args = ['worktree', 'add', worktreePath, '-b', branch];
36
+ if (startPoint)
37
+ args.push(startPoint);
38
+ await this.execFile('git', args, { cwd: repoPath });
35
39
  }
36
40
  catch (error) {
37
41
  throw this.parseGitError(error);
@@ -73,6 +77,27 @@ let WorktreeService = class WorktreeService {
73
77
  return false;
74
78
  }
75
79
  }
80
+ async ensureGitRepository(repoPath) {
81
+ try {
82
+ await this.execFile('git', ['rev-parse', '--is-inside-work-tree'], { cwd: repoPath });
83
+ return; // Already a git repo
84
+ }
85
+ catch {
86
+ // Not a git repo — initialize it
87
+ }
88
+ try {
89
+ mkdirSync(repoPath, { recursive: true });
90
+ await this.execFile('git', ['init'], { cwd: repoPath });
91
+ await this.execFile('git', ['config', 'user.name', GIT_AUTO_INIT_USER], { cwd: repoPath });
92
+ await this.execFile('git', ['config', 'user.email', GIT_AUTO_INIT_EMAIL], { cwd: repoPath });
93
+ await this.execFile('git', ['commit', '--allow-empty', '-m', 'Initial commit'], {
94
+ cwd: repoPath,
95
+ });
96
+ }
97
+ catch (error) {
98
+ throw this.parseGitError(error);
99
+ }
100
+ }
76
101
  getWorktreePath(repoPath, branch) {
77
102
  const repoHash = createHash('sha256').update(repoPath).digest('hex').slice(0, 16);
78
103
  const slug = branch.replace(/\//g, '-');