@shepai/cli 1.30.0 → 1.32.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 (154) hide show
  1. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +4 -0
  2. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +165 -0
  4. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -0
  5. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.js +34 -0
  6. package/dist/packages/core/src/application/ports/output/services/index.d.ts +2 -0
  7. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/ports/output/services/index.js +1 -0
  9. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +5 -0
  11. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
  12. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  13. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
  14. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +3 -0
  15. package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
  16. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +5 -0
  17. package/dist/packages/core/src/domain/generated/output.d.ts +70 -1
  18. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  19. package/dist/packages/core/src/domain/generated/output.js +15 -1
  20. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  21. package/dist/packages/core/src/infrastructure/di/container.js +2 -0
  22. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +10 -0
  23. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
  24. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +24 -0
  25. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +2 -0
  26. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  27. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +10 -0
  28. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
  29. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +27 -0
  30. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
  31. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +18 -2
  32. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
  33. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +7 -3
  34. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
  35. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +5 -0
  36. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -1
  37. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +4 -0
  38. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +148 -3
  39. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
  40. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js +20 -5
  41. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +4 -0
  42. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
  43. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +12 -0
  44. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +4 -0
  45. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  46. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +29 -1
  47. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts +27 -0
  48. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +1 -0
  49. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +146 -0
  50. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +5 -2
  51. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
  52. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +9 -3
  53. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.d.ts +17 -0
  54. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.d.ts.map +1 -0
  55. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.js +43 -0
  56. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.d.ts +17 -0
  57. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.d.ts.map +1 -0
  58. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.js +42 -0
  59. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +8 -0
  60. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts.map +1 -1
  61. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.js +33 -0
  62. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +28 -0
  63. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -0
  64. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +182 -0
  65. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  66. package/dist/src/presentation/cli/commands/feat/new.command.js +33 -2
  67. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +13 -2
  68. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  69. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +4 -13
  70. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +4 -10
  71. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  72. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +7 -19
  73. package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts +1 -1
  74. package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts.map +1 -1
  75. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.d.ts.map +1 -1
  76. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.js +11 -0
  77. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +1 -1
  78. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  79. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.js +10 -0
  80. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  81. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +4 -2
  82. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +1 -0
  83. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  84. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +21 -0
  85. package/dist/src/presentation/web/components/common/index.d.ts +1 -1
  86. package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
  87. package/dist/src/presentation/web/components/common/index.js +1 -1
  88. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  89. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +2 -2
  90. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -3
  91. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  92. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +76 -23
  93. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  94. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +2 -1
  95. package/dist/tsconfig.build.tsbuildinfo +1 -1
  96. package/package.json +5 -3
  97. package/web/.next/BUILD_ID +1 -1
  98. package/web/.next/build-manifest.json +2 -2
  99. package/web/.next/cache/.previewinfo +1 -1
  100. package/web/.next/cache/.rscinfo +1 -1
  101. package/web/.next/cache/.tsbuildinfo +1 -1
  102. package/web/.next/cache/config.json +3 -3
  103. package/web/.next/fallback-build-manifest.json +2 -2
  104. package/web/.next/prerender-manifest.json +3 -3
  105. package/web/.next/required-server-files.js +1 -1
  106. package/web/.next/required-server-files.json +1 -1
  107. package/web/.next/server/app/_global-error.html +2 -2
  108. package/web/.next/server/app/_global-error.rsc +1 -1
  109. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  110. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  111. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  112. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  113. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  114. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  115. package/web/.next/server/app/_not-found.html +2 -2
  116. package/web/.next/server/app/_not-found.rsc +10 -10
  117. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +10 -10
  118. package/web/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
  119. package/web/.next/server/app/_not-found.segments/_index.segment.rsc +6 -6
  120. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  121. package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  122. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  123. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  124. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  125. package/web/.next/server/app/version.html +2 -2
  126. package/web/.next/server/app/version.rsc +5 -5
  127. package/web/.next/server/app/version.segments/_full.segment.rsc +5 -5
  128. package/web/.next/server/app/version.segments/_head.segment.rsc +1 -1
  129. package/web/.next/server/app/version.segments/_index.segment.rsc +4 -4
  130. package/web/.next/server/app/version.segments/_tree.segment.rsc +2 -2
  131. package/web/.next/server/app/version.segments/version/__PAGE__.segment.rsc +2 -2
  132. package/web/.next/server/app/version.segments/version.segment.rsc +1 -1
  133. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js +1 -1
  134. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js.map +1 -1
  135. package/web/.next/server/chunks/ssr/[root-of-the-server]__f12b60be._.js +1 -1
  136. package/web/.next/server/chunks/ssr/_09afa42a._.js +2 -7
  137. package/web/.next/server/chunks/ssr/_09afa42a._.js.map +1 -1
  138. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  139. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  140. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  141. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
  142. package/web/.next/server/pages/404.html +2 -2
  143. package/web/.next/server/pages/500.html +2 -2
  144. package/web/.next/server/server-reference-manifest.js +1 -1
  145. package/web/.next/server/server-reference-manifest.json +1 -1
  146. package/web/.next/static/chunks/{daacb9d30e4fc428.js → 48b2cea957bfe6ab.js} +2 -7
  147. package/web/.next/static/chunks/9993505b2a26c454.js +1 -0
  148. package/web/.next/static/chunks/{fd816afd85fd9a19.css → b98242e5ef2a1bd3.css} +1 -1
  149. package/web/.next/trace +1 -1
  150. package/web/.next/trace-build +1 -1
  151. package/web/.next/static/chunks/b32b17f102226f32.js +0 -1
  152. /package/web/.next/static/{C_QsuOPQWDrYc18EOtMAm → 9kF5HqLN2Pcx3uc1dCFjr}/_buildManifest.js +0 -0
  153. /package/web/.next/static/{C_QsuOPQWDrYc18EOtMAm → 9kF5HqLN2Pcx3uc1dCFjr}/_clientMiddlewareManifest.json +0 -0
  154. /package/web/.next/static/{C_QsuOPQWDrYc18EOtMAm → 9kF5HqLN2Pcx3uc1dCFjr}/_ssgManifest.js +0 -0
@@ -20,6 +20,7 @@ import { initializeSettings } from '../../../services/settings.service.js';
20
20
  import { InitializeSettingsUseCase } from '../../../../application/use-cases/settings/initialize-settings.use-case.js';
21
21
  import { setHeartbeatContext } from './heartbeat.js';
22
22
  import { setPhaseTimingContext } from './phase-timing-context.js';
23
+ import { generatePrYaml } from './nodes/pr-yaml-generator.js';
23
24
  /**
24
25
  * Parse CLI arguments into a WorkerArgs object.
25
26
  * Throws if any required argument is missing.
@@ -47,6 +48,10 @@ export function parseWorkerArgs(args) {
47
48
  }
48
49
  const resume = args.includes('--resume');
49
50
  const resumeFromInterrupt = args.includes('--resume-from-interrupt');
51
+ const push = args.includes('--push');
52
+ const openPr = args.includes('--open-pr');
53
+ const autoMerge = args.includes('--auto-merge');
54
+ const allowMerge = args.includes('--allow-merge');
50
55
  const threadIdx = args.indexOf('--thread-id');
51
56
  const threadId = threadIdx !== -1 && threadIdx + 1 < args.length ? args[threadIdx + 1] : undefined;
52
57
  return {
@@ -59,6 +64,10 @@ export function parseWorkerArgs(args) {
59
64
  resume,
60
65
  threadId,
61
66
  resumeFromInterrupt,
67
+ push,
68
+ openPr,
69
+ autoMerge,
70
+ allowMerge,
62
71
  };
63
72
  }
64
73
  /** Simple worker logger — writes to stdout which is redirected to log file by the parent. */
@@ -111,13 +120,24 @@ export async function runWorker(args) {
111
120
  // Create executor from configured agent settings
112
121
  log('Creating executor from configured agent settings...');
113
122
  const executor = executorProvider.getExecutor();
123
+ // Resolve merge node dependencies
124
+ const gitPrService = container.resolve('IGitPrService');
125
+ const featureRepository = container.resolve('IFeatureRepository');
126
+ const graphDeps = {
127
+ executor,
128
+ mergeNodeDeps: {
129
+ gitPrService,
130
+ generatePrYaml,
131
+ featureRepository,
132
+ },
133
+ };
114
134
  // Use threadId for checkpoint path so resume runs share the same checkpoint DB.
115
135
  // Falls back to runId for backwards compatibility with existing runs.
116
136
  const checkpointId = args.threadId ?? args.runId;
117
137
  const checkpointPath = join(homedir(), '.shep', 'checkpoints', `${checkpointId}.db`);
118
138
  log(`Creating checkpointer at ${checkpointPath} (thread: ${checkpointId})`);
119
139
  const checkpointer = createCheckpointer(checkpointPath);
120
- const graph = createFeatureAgentGraph(executor, checkpointer);
140
+ const graph = createFeatureAgentGraph(graphDeps, checkpointer);
121
141
  // Mark the run as running with our PID
122
142
  const now = new Date();
123
143
  log(`Updating status to running (PID ${process.pid})...`);
@@ -153,6 +173,10 @@ export async function runWorker(args) {
153
173
  specDir: args.specDir,
154
174
  error: undefined, // Clear previous error state
155
175
  ...(args.approvalGates ? { approvalGates: args.approvalGates } : {}),
176
+ push: args.push ?? false,
177
+ openPr: args.openPr ?? false,
178
+ autoMerge: args.autoMerge ?? false,
179
+ allowMerge: args.allowMerge ?? false,
156
180
  }, graphConfig);
157
181
  }
158
182
  else {
@@ -163,6 +187,10 @@ export async function runWorker(args) {
163
187
  worktreePath: args.worktreePath ?? args.repo,
164
188
  specDir: args.specDir,
165
189
  ...(args.approvalGates ? { approvalGates: args.approvalGates } : {}),
190
+ push: args.push ?? false,
191
+ openPr: args.openPr ?? false,
192
+ autoMerge: args.autoMerge ?? false,
193
+ allowMerge: args.allowMerge ?? false,
166
194
  }, graphConfig);
167
195
  }
168
196
  log(`Graph invocation completed. Error: ${result.error ?? 'none'}`);
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Merge Node — Post-Implementation Merge Flow
3
+ *
4
+ * Handles the complete merge workflow after implementation:
5
+ * 1. Commit uncommitted changes and push
6
+ * 2. Generate pr.yaml (always) and optionally create PR
7
+ * 3. Optionally auto-merge (via PR or direct branch merge)
8
+ * 4. Update feature lifecycle and clean up
9
+ *
10
+ * Uses interrupt() for the merge approval gate when allowMerge=false.
11
+ */
12
+ import type { FeatureAgentState } from '../state.js';
13
+ import type { IGitPrService } from '../../../../../application/ports/output/services/git-pr-service.interface.js';
14
+ import type { IFeatureRepository } from '../../../../../application/ports/output/repositories/feature-repository.interface.js';
15
+ export interface MergeNodeDeps {
16
+ gitPrService: IGitPrService;
17
+ generatePrYaml: (specDir: string, branch: string, baseBranch: string) => string;
18
+ featureRepository: Pick<IFeatureRepository, 'findById' | 'update'>;
19
+ }
20
+ /**
21
+ * Factory that creates the merge node function.
22
+ *
23
+ * @param deps - External dependencies injected by the graph factory
24
+ * @returns A LangGraph node function
25
+ */
26
+ export declare function createMergeNode(deps: MergeNodeDeps): (state: FeatureAgentState) => Promise<Partial<FeatureAgentState>>;
27
+ //# sourceMappingURL=merge.node.d.ts.map
@@ -0,0 +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;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iEAAiE,CAAC;AACrG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAKlH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,aAAa,CAAC;IAC5B,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAChF,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,CAwI7E"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Merge Node — Post-Implementation Merge Flow
3
+ *
4
+ * Handles the complete merge workflow after implementation:
5
+ * 1. Commit uncommitted changes and push
6
+ * 2. Generate pr.yaml (always) and optionally create PR
7
+ * 3. Optionally auto-merge (via PR or direct branch merge)
8
+ * 4. Update feature lifecycle and clean up
9
+ *
10
+ * Uses interrupt() for the merge approval gate when allowMerge=false.
11
+ */
12
+ import { interrupt, isGraphBubbleUp } from '@langchain/langgraph';
13
+ import { SdlcLifecycle } from '../../../../../domain/generated/output.js';
14
+ import { createNodeLogger, shouldInterrupt } from './node-helpers.js';
15
+ import { reportNodeStart } from '../heartbeat.js';
16
+ /**
17
+ * Factory that creates the merge node function.
18
+ *
19
+ * @param deps - External dependencies injected by the graph factory
20
+ * @returns A LangGraph node function
21
+ */
22
+ export function createMergeNode(deps) {
23
+ const log = createNodeLogger('merge');
24
+ return async (state) => {
25
+ log.info('Starting merge flow');
26
+ reportNodeStart('merge');
27
+ const messages = [];
28
+ const startTime = Date.now();
29
+ try {
30
+ const { gitPrService } = deps;
31
+ const cwd = state.worktreePath;
32
+ // Resolve branch name from feature
33
+ const feature = await deps.featureRepository.findById(state.featureId);
34
+ const branch = feature?.branch ?? `feat/${state.featureId}`;
35
+ const baseBranch = 'main';
36
+ // --- Step 1: Commit and Push ---
37
+ let commitHash = state.commitHash;
38
+ const hasChanges = await gitPrService.hasUncommittedChanges(cwd);
39
+ if (hasChanges) {
40
+ log.info('Uncommitted changes detected, committing...');
41
+ commitHash = await gitPrService.commitAll(cwd, `feat: implementation complete for ${state.featureId}`);
42
+ messages.push(`[merge] Committed changes: ${commitHash}`);
43
+ }
44
+ else {
45
+ log.info('No uncommitted changes');
46
+ messages.push('[merge] No uncommitted changes to commit');
47
+ }
48
+ // Push is controlled by the push flag (--push, or implied by --pr)
49
+ const shouldPush = state.push || state.openPr;
50
+ if (shouldPush) {
51
+ log.info('Pushing to remote...');
52
+ await gitPrService.push(cwd, branch, true);
53
+ messages.push(`[merge] Pushed branch ${branch}`);
54
+ }
55
+ else {
56
+ log.info('Push skipped (--push not set)');
57
+ messages.push('[merge] Push skipped (use --push to push to remote)');
58
+ }
59
+ // --- Step 2: Generate pr.yaml (always) ---
60
+ log.info('Generating pr.yaml...');
61
+ const prYamlPath = deps.generatePrYaml(state.specDir, branch, baseBranch);
62
+ messages.push(`[merge] Generated pr.yaml at ${prYamlPath}`);
63
+ // --- Step 3: Create PR (if openPr=true and not already created) ---
64
+ let prUrl = state.prUrl;
65
+ let prNumber = state.prNumber;
66
+ let ciStatus = state.ciStatus;
67
+ if (state.openPr && !state.prUrl) {
68
+ log.info('Creating pull request...');
69
+ const prResult = await gitPrService.createPr(cwd, prYamlPath);
70
+ prUrl = prResult.url;
71
+ prNumber = prResult.number;
72
+ messages.push(`[merge] PR created: ${prUrl}`);
73
+ // Watch CI if we're going to auto-merge
74
+ if (state.autoMerge) {
75
+ log.info('Watching CI...');
76
+ const ciResult = await gitPrService.watchCi(cwd, branch);
77
+ ciStatus = ciResult.status;
78
+ messages.push(`[merge] CI status: ${ciStatus}`);
79
+ }
80
+ }
81
+ // --- Step 4: Merge approval gate ---
82
+ if (shouldInterrupt('merge', state.approvalGates, state.autoMerge)) {
83
+ log.info('Interrupting for merge approval');
84
+ const diffSummary = await gitPrService.getPrDiffSummary(cwd, baseBranch);
85
+ interrupt({
86
+ node: 'merge',
87
+ message: 'Merge approval required. Review the changes and approve to continue.',
88
+ diffSummary,
89
+ prUrl,
90
+ prNumber,
91
+ });
92
+ }
93
+ // --- Step 5: Auto-merge (if enabled) ---
94
+ let merged = false;
95
+ if (state.autoMerge) {
96
+ if (state.openPr && prNumber) {
97
+ log.info(`Auto-merging PR #${prNumber}...`);
98
+ await gitPrService.mergePr(cwd, prNumber, 'squash');
99
+ messages.push(`[merge] PR #${prNumber} merged via squash`);
100
+ merged = true;
101
+ }
102
+ else {
103
+ log.info(`Auto-merging branch ${branch} into ${baseBranch}...`);
104
+ await gitPrService.mergeBranch(cwd, branch, baseBranch);
105
+ messages.push(`[merge] Branch ${branch} merged into ${baseBranch}`);
106
+ merged = true;
107
+ }
108
+ }
109
+ // --- Step 6: Update feature lifecycle ---
110
+ const newLifecycle = merged ? SdlcLifecycle.Maintain : SdlcLifecycle.Review;
111
+ if (feature) {
112
+ await deps.featureRepository.update({
113
+ ...feature,
114
+ lifecycle: newLifecycle,
115
+ prUrl: prUrl ?? undefined,
116
+ prNumber: prNumber ?? undefined,
117
+ updatedAt: new Date(),
118
+ });
119
+ messages.push(`[merge] Feature lifecycle → ${newLifecycle}`);
120
+ }
121
+ const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
122
+ messages.push(`[merge] Complete (${elapsed}s)`);
123
+ log.info(`Merge flow complete (${elapsed}s)`);
124
+ return {
125
+ currentNode: 'merge',
126
+ messages,
127
+ commitHash,
128
+ prUrl,
129
+ prNumber,
130
+ ciStatus,
131
+ };
132
+ }
133
+ catch (err) {
134
+ // Re-throw LangGraph control-flow exceptions (interrupt, etc.)
135
+ if (isGraphBubbleUp(err))
136
+ throw err;
137
+ const message = err instanceof Error ? err.message : String(err);
138
+ const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
139
+ log.error(`Merge failed: ${message} (${elapsed}s)`);
140
+ // Re-throw so LangGraph does NOT checkpoint this node as completed.
141
+ // This allows `feat resume` to retry the merge node instead of
142
+ // restarting the entire graph from scratch.
143
+ throw err;
144
+ }
145
+ };
146
+ }
@@ -37,12 +37,15 @@ export declare function safeYamlLoad(content: string): unknown;
37
37
  * Gates control which phases auto-approve:
38
38
  * - allowPrd: when true, skip interrupt after requirements phase
39
39
  * - allowPlan: when true, skip interrupt after plan phase
40
+ * - allowMerge: when true, skip interrupt after merge phase
40
41
  *
41
42
  * Nodes not covered by a gate (analyze, research) never interrupt.
42
43
  * The implement node always interrupts when gates are present
43
- * (unless both gates are true, meaning fully autonomous).
44
+ * (unless all three gates are true, meaning fully autonomous).
45
+ *
46
+ * @param autoMerge - When true, overrides allowMerge to treat merge as approved.
44
47
  */
45
- export declare function shouldInterrupt(nodeName: string, gates: ApprovalGates | undefined): boolean;
48
+ export declare function shouldInterrupt(nodeName: string, gates: ApprovalGates | undefined, autoMerge?: boolean): boolean;
46
49
  export type ErrorCategory = 'retryable-api' | 'retryable-network' | 'non-retryable' | 'unknown';
47
50
  /**
48
51
  * Classify an error message into a retry category.
@@ -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;AAIrD;;;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;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAO3F;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;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAwB1F;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,CA4EnE"}
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;AAIrD;;;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;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,GAAG,SAAS,EAChC,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAWT;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;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAwB1F;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,CA4EnE"}
@@ -78,20 +78,26 @@ export function safeYamlLoad(content) {
78
78
  * Gates control which phases auto-approve:
79
79
  * - allowPrd: when true, skip interrupt after requirements phase
80
80
  * - allowPlan: when true, skip interrupt after plan phase
81
+ * - allowMerge: when true, skip interrupt after merge phase
81
82
  *
82
83
  * Nodes not covered by a gate (analyze, research) never interrupt.
83
84
  * The implement node always interrupts when gates are present
84
- * (unless both gates are true, meaning fully autonomous).
85
+ * (unless all three gates are true, meaning fully autonomous).
86
+ *
87
+ * @param autoMerge - When true, overrides allowMerge to treat merge as approved.
85
88
  */
86
- export function shouldInterrupt(nodeName, gates) {
89
+ export function shouldInterrupt(nodeName, gates, autoMerge) {
87
90
  if (!gates)
88
91
  return false;
89
- if (gates.allowPrd && gates.allowPlan)
92
+ const effectiveAllowMerge = autoMerge ?? gates.allowMerge;
93
+ if (gates.allowPrd && gates.allowPlan && effectiveAllowMerge)
90
94
  return false;
91
95
  if (nodeName === 'requirements')
92
96
  return !gates.allowPrd;
93
97
  if (nodeName === 'plan')
94
98
  return !gates.allowPlan;
99
+ if (nodeName === 'merge')
100
+ return !effectiveAllowMerge;
95
101
  if (nodeName === 'implement')
96
102
  return true;
97
103
  return false;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Generates a pr.yaml file from spec metadata for pull request creation.
3
+ *
4
+ * Reads spec.yaml from the spec directory, extracts feature name, description,
5
+ * scope, and success criteria, then writes a pr.yaml with PR metadata in
6
+ * conventional commit format.
7
+ */
8
+ /**
9
+ * Generate a pr.yaml file in the spec directory with PR metadata.
10
+ *
11
+ * @param specDir - Path to the spec directory containing spec.yaml
12
+ * @param branch - Feature branch name (used as headBranch)
13
+ * @param baseBranch - Target branch for the PR (default: 'main')
14
+ * @returns Path to the generated pr.yaml file
15
+ */
16
+ export declare function generatePrYaml(specDir: string, branch: string, baseBranch?: string): string;
17
+ //# sourceMappingURL=pr-yaml-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-yaml-generator.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,SAAS,GAAG,MAAM,CA+B3F"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Generates a pr.yaml file from spec metadata for pull request creation.
3
+ *
4
+ * Reads spec.yaml from the spec directory, extracts feature name, description,
5
+ * scope, and success criteria, then writes a pr.yaml with PR metadata in
6
+ * conventional commit format.
7
+ */
8
+ import yaml from 'js-yaml';
9
+ import { readFileSync, writeFileSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ /**
12
+ * Generate a pr.yaml file in the spec directory with PR metadata.
13
+ *
14
+ * @param specDir - Path to the spec directory containing spec.yaml
15
+ * @param branch - Feature branch name (used as headBranch)
16
+ * @param baseBranch - Target branch for the PR (default: 'main')
17
+ * @returns Path to the generated pr.yaml file
18
+ */
19
+ export function generatePrYaml(specDir, branch, baseBranch = 'main') {
20
+ const specContent = readFileSync(join(specDir, 'spec.yaml'), 'utf-8');
21
+ const spec = yaml.load(specContent);
22
+ const name = spec.name ?? 'Untitled feature';
23
+ const description = spec.description ?? '';
24
+ const scope = spec.scope;
25
+ const successCriteria = spec.successCriteria ?? [];
26
+ const title = scope ? `feat(${scope}): ${name}` : `feat: ${name}`;
27
+ const bodyParts = [];
28
+ bodyParts.push(`## Summary\n\n${description}`);
29
+ if (successCriteria.length > 0) {
30
+ bodyParts.push(`## Test Criteria\n\n${successCriteria.map((c) => `- ${c}`).join('\n')}`);
31
+ }
32
+ const prData = {
33
+ title,
34
+ body: bodyParts.join('\n\n'),
35
+ baseBranch,
36
+ headBranch: branch,
37
+ labels: ['feature'],
38
+ draft: false,
39
+ };
40
+ const outputPath = join(specDir, 'pr.yaml');
41
+ writeFileSync(outputPath, yaml.dump(prData, { indent: 2, lineWidth: -1 }), 'utf-8');
42
+ return outputPath;
43
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Merge Node Prompts
3
+ *
4
+ * Prompt builders for the merge node: CI fix instructions.
5
+ */
6
+ export interface CiFixPromptParams {
7
+ logExcerpt: string;
8
+ specSummary: string;
9
+ attempt: number;
10
+ maxAttempts: number;
11
+ }
12
+ /**
13
+ * Build a constrained prompt for the AI agent when CI fails.
14
+ * Instructs the agent to fix the specific CI failure within bounded scope.
15
+ */
16
+ export declare function buildCiFixPrompt(params: CiFixPromptParams): string;
17
+ //# sourceMappingURL=merge.prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAkClE"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Merge Node Prompts
3
+ *
4
+ * Prompt builders for the merge node: CI fix instructions.
5
+ */
6
+ const MAX_LOG_EXCERPT_LENGTH = 6000;
7
+ /**
8
+ * Build a constrained prompt for the AI agent when CI fails.
9
+ * Instructs the agent to fix the specific CI failure within bounded scope.
10
+ */
11
+ export function buildCiFixPrompt(params) {
12
+ const { specSummary, attempt, maxAttempts } = params;
13
+ const truncatedLog = params.logExcerpt.length > MAX_LOG_EXCERPT_LENGTH
14
+ ? `${params.logExcerpt.slice(0, MAX_LOG_EXCERPT_LENGTH)}\n... (truncated)`
15
+ : params.logExcerpt;
16
+ return `You are a senior software engineer fixing a CI failure.
17
+ This is attempt ${attempt} of ${maxAttempts}.
18
+
19
+ ## Feature Context
20
+
21
+ ${specSummary}
22
+
23
+ ## CI Failure Log
24
+
25
+ \`\`\`
26
+ ${truncatedLog}
27
+ \`\`\`
28
+
29
+ ## Instructions
30
+
31
+ 1. Analyze the CI failure log above carefully
32
+ 2. Identify the root cause of the failure
33
+ 3. Apply the minimal fix to resolve the CI issue
34
+ 4. Run the failing checks locally to verify your fix
35
+
36
+ ## Constraints
37
+
38
+ - Fix ONLY the issue shown in the CI log — do not refactor or improve unrelated code
39
+ - Do not add new features or change behavior beyond what is needed to pass CI
40
+ - Keep changes as small and focused as possible
41
+ - Commit with a conventional commit message (e.g. \`fix(scope): resolve CI failure\`)`;
42
+ }
@@ -38,6 +38,14 @@ export declare const FeatureAgentAnnotation: import("@langchain/langgraph").Anno
38
38
  validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
39
39
  lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
40
40
  lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
41
+ prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
42
+ prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
43
+ commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
44
+ ciStatus: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
45
+ push: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
46
+ openPr: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
47
+ autoMerge: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
48
+ allowMerge: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
41
49
  }>;
42
50
  export type FeatureAgentState = typeof FeatureAgentAnnotation.State;
43
51
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BjC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,OAAO,sBAAsB,CAAC,KAAK,CAAC"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgEjC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,OAAO,sBAAsB,CAAC,KAAK,CAAC"}
@@ -37,4 +37,37 @@ export const FeatureAgentAnnotation = Annotation.Root({
37
37
  reducer: (_prev, next) => next,
38
38
  default: () => [],
39
39
  }),
40
+ // --- Merge and workflow state channels ---
41
+ prUrl: Annotation({
42
+ reducer: (_prev, next) => (next !== undefined ? next : _prev),
43
+ default: () => null,
44
+ }),
45
+ prNumber: Annotation({
46
+ reducer: (_prev, next) => (next !== undefined ? next : _prev),
47
+ default: () => null,
48
+ }),
49
+ commitHash: Annotation({
50
+ reducer: (_prev, next) => (next !== undefined ? next : _prev),
51
+ default: () => null,
52
+ }),
53
+ ciStatus: Annotation({
54
+ reducer: (_prev, next) => (next !== undefined ? next : _prev),
55
+ default: () => null,
56
+ }),
57
+ push: Annotation({
58
+ reducer: (_prev, next) => next,
59
+ default: () => false,
60
+ }),
61
+ openPr: Annotation({
62
+ reducer: (_prev, next) => next,
63
+ default: () => false,
64
+ }),
65
+ autoMerge: Annotation({
66
+ reducer: (_prev, next) => next,
67
+ default: () => false,
68
+ }),
69
+ allowMerge: Annotation({
70
+ reducer: (_prev, next) => next,
71
+ default: () => false,
72
+ }),
40
73
  });
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Git PR Service Implementation
3
+ *
4
+ * Manages git operations for PR creation, merging, and CI status checks.
5
+ * Uses constructor dependency injection for the command executor.
6
+ */
7
+ import type { IGitPrService } from '../../../application/ports/output/services/git-pr-service.interface.js';
8
+ import type { CiStatusResult, DiffSummary, MergeStrategy, PrCreateResult } from '../../../application/ports/output/services/git-pr-service.interface.js';
9
+ import type { ExecFunction } from './worktree.service.js';
10
+ export declare class GitPrService implements IGitPrService {
11
+ private readonly execFile;
12
+ constructor(execFile: ExecFunction);
13
+ hasUncommittedChanges(cwd: string): Promise<boolean>;
14
+ commitAll(cwd: string, message: string): Promise<string>;
15
+ push(cwd: string, branch: string, setUpstream?: boolean): Promise<void>;
16
+ createPr(cwd: string, prYamlPath: string): Promise<PrCreateResult>;
17
+ mergePr(cwd: string, prNumber: number, strategy?: MergeStrategy): Promise<void>;
18
+ mergeBranch(cwd: string, sourceBranch: string, targetBranch: string): Promise<void>;
19
+ getCiStatus(cwd: string, branch: string): Promise<CiStatusResult>;
20
+ watchCi(cwd: string, branch: string, timeoutMs?: number): Promise<CiStatusResult>;
21
+ deleteBranch(cwd: string, branch: string, deleteRemote?: boolean): Promise<void>;
22
+ getPrDiffSummary(cwd: string, baseBranch: string): Promise<DiffSummary>;
23
+ private parseGitError;
24
+ private parseGhError;
25
+ private parsePrNumberFromUrl;
26
+ private parseDiffStat;
27
+ }
28
+ //# sourceMappingURL=git-pr.service.d.ts.map
@@ -0,0 +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;AAKhF,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;IAelE,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"}