@shepai/cli 1.15.1 → 1.17.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 (118) hide show
  1. package/README.md +168 -22
  2. package/dist/src/application/ports/output/agents/agent-executor-provider.interface.d.ts +5 -0
  3. package/dist/src/application/ports/output/agents/agent-executor-provider.interface.d.ts.map +1 -0
  4. package/dist/src/application/ports/output/agents/agent-executor-provider.interface.js +1 -0
  5. package/dist/src/application/ports/output/agents/agent-executor.interface.d.ts +2 -0
  6. package/dist/src/application/ports/output/agents/agent-executor.interface.d.ts.map +1 -1
  7. package/dist/src/application/ports/output/agents/feature-agent-process.interface.d.ts +2 -0
  8. package/dist/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
  9. package/dist/src/application/ports/output/agents/index.d.ts +1 -0
  10. package/dist/src/application/ports/output/agents/index.d.ts.map +1 -1
  11. package/dist/src/application/ports/output/index.d.ts +1 -1
  12. package/dist/src/application/ports/output/index.d.ts.map +1 -1
  13. package/dist/src/application/use-cases/features/create-feature.use-case.d.ts +3 -3
  14. package/dist/src/application/use-cases/features/create-feature.use-case.d.ts.map +1 -1
  15. package/dist/src/application/use-cases/features/create-feature.use-case.js +10 -7
  16. package/dist/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
  17. package/dist/src/application/use-cases/features/resume-feature.use-case.js +6 -1
  18. package/dist/src/infrastructure/di/container.d.ts.map +1 -1
  19. package/dist/src/infrastructure/di/container.js +9 -2
  20. package/dist/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts +1 -1
  21. package/dist/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts.map +1 -1
  22. package/dist/src/infrastructure/services/agents/common/agent-executor-factory.service.js +6 -2
  23. package/dist/src/infrastructure/services/agents/common/agent-executor-provider.service.d.ts +9 -0
  24. package/dist/src/infrastructure/services/agents/common/agent-executor-provider.service.d.ts.map +1 -0
  25. package/dist/src/infrastructure/services/agents/common/agent-executor-provider.service.js +11 -0
  26. package/dist/src/infrastructure/services/agents/common/agent-runner.service.d.ts +3 -3
  27. package/dist/src/infrastructure/services/agents/common/agent-runner.service.d.ts.map +1 -1
  28. package/dist/src/infrastructure/services/agents/common/agent-runner.service.js +4 -4
  29. package/dist/src/infrastructure/services/agents/common/agent-validator.service.d.ts +1 -9
  30. package/dist/src/infrastructure/services/agents/common/agent-validator.service.d.ts.map +1 -1
  31. package/dist/src/infrastructure/services/agents/common/agent-validator.service.js +1 -0
  32. package/dist/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts +3 -7
  33. package/dist/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
  34. package/dist/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +5 -0
  35. package/dist/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts +38 -0
  36. package/dist/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -0
  37. package/dist/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +296 -0
  38. package/dist/src/infrastructure/services/agents/common/types.d.ts +23 -0
  39. package/dist/src/infrastructure/services/agents/common/types.d.ts.map +1 -0
  40. package/dist/src/infrastructure/services/agents/common/types.js +7 -0
  41. package/dist/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +2 -0
  42. package/dist/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
  43. package/dist/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +6 -0
  44. package/dist/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +2 -0
  45. package/dist/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  46. package/dist/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +32 -12
  47. package/dist/src/infrastructure/services/agents/feature-agent/nodes/implement.node.d.ts +8 -7
  48. package/dist/src/infrastructure/services/agents/feature-agent/nodes/implement.node.d.ts.map +1 -1
  49. package/dist/src/infrastructure/services/agents/feature-agent/nodes/implement.node.js +139 -16
  50. package/dist/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +6 -0
  51. package/dist/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
  52. package/dist/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +29 -5
  53. package/dist/src/infrastructure/services/agents/feature-agent/nodes/prompts/implement.prompt.d.ts +44 -4
  54. package/dist/src/infrastructure/services/agents/feature-agent/nodes/prompts/implement.prompt.d.ts.map +1 -1
  55. package/dist/src/infrastructure/services/agents/feature-agent/nodes/prompts/implement.prompt.js +86 -14
  56. package/dist/src/presentation/cli/commands/feat/ls.command.d.ts.map +1 -1
  57. package/dist/src/presentation/cli/commands/feat/ls.command.js +42 -7
  58. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  59. package/dist/src/presentation/cli/commands/feat/new.command.js +3 -3
  60. package/dist/src/presentation/cli/ui/index.d.ts +1 -0
  61. package/dist/src/presentation/cli/ui/index.d.ts.map +1 -1
  62. package/dist/src/presentation/cli/ui/index.js +1 -0
  63. package/dist/src/presentation/cli/ui/spinner.d.ts +21 -0
  64. package/dist/src/presentation/cli/ui/spinner.d.ts.map +1 -0
  65. package/dist/src/presentation/cli/ui/spinner.js +45 -0
  66. package/dist/src/presentation/tui/prompts/agent-select.prompt.d.ts +1 -1
  67. package/dist/src/presentation/tui/prompts/agent-select.prompt.js +1 -1
  68. package/dist/tsconfig.build.tsbuildinfo +1 -1
  69. package/package.json +1 -1
  70. package/web/.next/BUILD_ID +1 -1
  71. package/web/.next/build-manifest.json +2 -2
  72. package/web/.next/cache/.previewinfo +1 -1
  73. package/web/.next/cache/.rscinfo +1 -1
  74. package/web/.next/cache/config.json +3 -3
  75. package/web/.next/fallback-build-manifest.json +2 -2
  76. package/web/.next/prerender-manifest.json +3 -3
  77. package/web/.next/required-server-files.js +1 -1
  78. package/web/.next/required-server-files.json +1 -1
  79. package/web/.next/server/app/_global-error.html +2 -2
  80. package/web/.next/server/app/_global-error.rsc +1 -1
  81. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  82. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  83. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  84. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  85. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  86. package/web/.next/server/app/_not-found.html +2 -2
  87. package/web/.next/server/app/_not-found.rsc +1 -1
  88. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  89. package/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  90. package/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  91. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  92. package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  93. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  94. package/web/.next/server/app/index.html +2 -2
  95. package/web/.next/server/app/index.rsc +1 -1
  96. package/web/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  97. package/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
  98. package/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  99. package/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  100. package/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  101. package/web/.next/server/app/version.html +2 -2
  102. package/web/.next/server/app/version.rsc +1 -1
  103. package/web/.next/server/app/version.segments/_full.segment.rsc +1 -1
  104. package/web/.next/server/app/version.segments/_head.segment.rsc +1 -1
  105. package/web/.next/server/app/version.segments/_index.segment.rsc +1 -1
  106. package/web/.next/server/app/version.segments/_tree.segment.rsc +1 -1
  107. package/web/.next/server/app/version.segments/version/__PAGE__.segment.rsc +1 -1
  108. package/web/.next/server/app/version.segments/version.segment.rsc +1 -1
  109. package/web/.next/server/chunks/ssr/_19be0743._.js +1 -1
  110. package/web/.next/server/pages/404.html +2 -2
  111. package/web/.next/server/pages/500.html +2 -2
  112. package/web/.next/server/server-reference-manifest.js +1 -1
  113. package/web/.next/server/server-reference-manifest.json +1 -1
  114. package/web/.next/trace +1 -1
  115. package/web/.next/trace-build +1 -1
  116. /package/web/.next/static/{iYaq62xFNOChDTbH3WMrr → Wgd1DC_QfVhpAi62LjpwI}/_buildManifest.js +0 -0
  117. /package/web/.next/static/{iYaq62xFNOChDTbH3WMrr → Wgd1DC_QfVhpAi62LjpwI}/_clientMiddlewareManifest.json +0 -0
  118. /package/web/.next/static/{iYaq62xFNOChDTbH3WMrr → Wgd1DC_QfVhpAi62LjpwI}/_ssgManifest.js +0 -0
@@ -8,15 +8,9 @@
8
8
  * Uses constructor dependency injection for the spawn function
9
9
  * to enable testability without mocking node:child_process directly.
10
10
  */
11
- import type { ChildProcess } from 'node:child_process';
12
11
  import type { AgentType, AgentFeature } from '../../../../../domain/generated/output.js';
13
12
  import type { IAgentExecutor, AgentExecutionOptions, AgentExecutionResult, AgentExecutionStreamEvent } from '../../../../../application/ports/output/agents/agent-executor.interface.js';
14
- /**
15
- * Type for the spawn dependency.
16
- * Matches the signature of child_process.spawn.
17
- * Injected via constructor to enable testability.
18
- */
19
- export type SpawnFunction = (command: string, args: string[], options?: object) => ChildProcess;
13
+ import type { SpawnFunction } from '../types.js';
20
14
  /**
21
15
  * Executor service for Claude Code agent.
22
16
  * Uses subprocess spawning to interact with the `claude` CLI.
@@ -24,6 +18,8 @@ export type SpawnFunction = (command: string, args: string[], options?: object)
24
18
  export declare class ClaudeCodeExecutorService implements IAgentExecutor {
25
19
  private readonly spawn;
26
20
  readonly agentType: AgentType;
21
+ /** When true, suppresses debug logging (set per-call via options.silent) */
22
+ private silent;
27
23
  constructor(spawn: SpawnFunction);
28
24
  /** Debug logging — writes to stdout so it appears in the worker log file */
29
25
  private log;
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../src/infrastructure/services/agents/common/executors/claude-code-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AAEpF;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC;AAUhG;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,cAAc;IAGlD,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAA8B;gBAE9B,KAAK,EAAE,aAAa;IAEjD,4EAA4E;IAC5E,OAAO,CAAC,GAAG;IAKL,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAkHtF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IA+F3C;;;OAGG;IACH,OAAO,CAAC,cAAc;IAmCtB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAI/C,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,eAAe;CAkExB"}
1
+ {"version":3,"file":"claude-code-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../src/infrastructure/services/agents/common/executors/claude-code-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAUjD;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,cAAc;IAMlD,OAAO,CAAC,QAAQ,CAAC,KAAK;IALlC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAA8B;IAE3D,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;gBAEM,KAAK,EAAE,aAAa;IAEjD,4EAA4E;IAC5E,OAAO,CAAC,GAAG;IAML,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAmHtF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IA+F3C;;;OAGG;IACH,OAAO,CAAC,cAAc;IAmCtB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAI/C,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,eAAe;CAkExB"}
@@ -22,15 +22,20 @@ const SUPPORTED_FEATURES = new Set([
22
22
  export class ClaudeCodeExecutorService {
23
23
  spawn;
24
24
  agentType = 'claude-code';
25
+ /** When true, suppresses debug logging (set per-call via options.silent) */
26
+ silent = false;
25
27
  constructor(spawn) {
26
28
  this.spawn = spawn;
27
29
  }
28
30
  /** Debug logging — writes to stdout so it appears in the worker log file */
29
31
  log(message) {
32
+ if (this.silent)
33
+ return;
30
34
  const ts = new Date().toISOString();
31
35
  process.stdout.write(`[${ts}] [claude-executor] ${message}\n`);
32
36
  }
33
37
  async execute(prompt, options) {
38
+ this.silent = options?.silent ?? false;
34
39
  // Use stream-json so we get real-time events in the worker log
35
40
  // instead of zero output for minutes with --output-format json
36
41
  const args = this.buildStreamArgs(prompt, options);
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Cursor Executor Service
3
+ *
4
+ * Infrastructure implementation of IAgentExecutor for the Cursor agent.
5
+ * Executes prompts via the `agent` CLI subprocess with JSON and stream-json
6
+ * output formats.
7
+ *
8
+ * Uses constructor dependency injection for the spawn function
9
+ * to enable testability without mocking node:child_process directly.
10
+ */
11
+ import type { AgentType, AgentFeature } from '../../../../../domain/generated/output.js';
12
+ import type { IAgentExecutor, AgentExecutionOptions, AgentExecutionResult, AgentExecutionStreamEvent } from '../../../../../application/ports/output/agents/agent-executor.interface.js';
13
+ import type { SpawnFunction } from '../types.js';
14
+ /**
15
+ * Executor service for Cursor agent.
16
+ * Uses subprocess spawning to interact with the `agent` CLI.
17
+ */
18
+ export declare class CursorExecutorService implements IAgentExecutor {
19
+ private readonly spawn;
20
+ readonly agentType: AgentType;
21
+ /** When true, suppresses debug logging (set per-call via options.silent) */
22
+ private silent;
23
+ constructor(spawn: SpawnFunction);
24
+ /** Debug logging — writes to stdout so it appears in the worker log file */
25
+ private log;
26
+ supportsFeature(feature: AgentFeature): boolean;
27
+ execute(prompt: string, options?: AgentExecutionOptions): Promise<AgentExecutionResult>;
28
+ executeStream(prompt: string, options?: AgentExecutionOptions): AsyncIterable<AgentExecutionStreamEvent>;
29
+ /**
30
+ * Log a stream-json line as a human-readable event in the worker log.
31
+ */
32
+ private logStreamEvent;
33
+ private buildArgs;
34
+ private buildStreamArgs;
35
+ private buildSpawnOptions;
36
+ private parseStreamLine;
37
+ }
38
+ //# sourceMappingURL=cursor-executor.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../src/infrastructure/services/agents/common/executors/cursor-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,cAAc;IAM9C,OAAO,CAAC,QAAQ,CAAC,KAAK;IALlC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAyB;IAEtD,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;gBAEM,KAAK,EAAE,aAAa;IAEjD,4EAA4E;IAC5E,OAAO,CAAC,GAAG;IAMX,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAIzC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAkGtF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IA8E3C;;OAEG;IACH,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;CAgDxB"}
@@ -0,0 +1,296 @@
1
+ /**
2
+ * Cursor Executor Service
3
+ *
4
+ * Infrastructure implementation of IAgentExecutor for the Cursor agent.
5
+ * Executes prompts via the `agent` CLI subprocess with JSON and stream-json
6
+ * output formats.
7
+ *
8
+ * Uses constructor dependency injection for the spawn function
9
+ * to enable testability without mocking node:child_process directly.
10
+ */
11
+ /** Features supported by Cursor CLI */
12
+ const SUPPORTED_FEATURES = new Set(['session-resume', 'streaming']);
13
+ /**
14
+ * Executor service for Cursor agent.
15
+ * Uses subprocess spawning to interact with the `agent` CLI.
16
+ */
17
+ export class CursorExecutorService {
18
+ spawn;
19
+ agentType = 'cursor';
20
+ /** When true, suppresses debug logging (set per-call via options.silent) */
21
+ silent = false;
22
+ constructor(spawn) {
23
+ this.spawn = spawn;
24
+ }
25
+ /** Debug logging — writes to stdout so it appears in the worker log file */
26
+ log(message) {
27
+ if (this.silent)
28
+ return;
29
+ const ts = new Date().toISOString();
30
+ process.stdout.write(`[${ts}] [cursor-executor] ${message}\n`);
31
+ }
32
+ supportsFeature(feature) {
33
+ return SUPPORTED_FEATURES.has(feature);
34
+ }
35
+ async execute(prompt, options) {
36
+ this.silent = options?.silent ?? false;
37
+ const args = this.buildStreamArgs(prompt, options);
38
+ const spawnOpts = this.buildSpawnOptions(options);
39
+ this.log(`Spawning: agent ${args.map((a) => (a.length > 80 ? `${a.slice(0, 77)}...` : a)).join(' ')}`);
40
+ this.log(`Spawn options: ${JSON.stringify(spawnOpts)}`);
41
+ const proc = this.spawn('agent', args, spawnOpts);
42
+ this.log(`Subprocess PID: ${proc.pid ?? 'undefined (spawn may have failed)'}`);
43
+ if (proc.stdin)
44
+ proc.stdin.end();
45
+ return new Promise((resolve, reject) => {
46
+ let lineBuffer = '';
47
+ let stderr = '';
48
+ let timedOut = false;
49
+ let timeoutId;
50
+ // Accumulated from assistant events
51
+ let resultText = '';
52
+ let sessionId;
53
+ let metadata;
54
+ if (options?.timeout) {
55
+ timeoutId = setTimeout(() => {
56
+ timedOut = true;
57
+ proc.kill();
58
+ }, options.timeout);
59
+ }
60
+ const processLine = (line) => {
61
+ this.logStreamEvent(line);
62
+ try {
63
+ const parsed = JSON.parse(line);
64
+ if (parsed.type === 'assistant' && Array.isArray(parsed.message?.content)) {
65
+ for (const block of parsed.message.content) {
66
+ if (block.type === 'text' && block.text)
67
+ resultText += block.text;
68
+ }
69
+ }
70
+ else if (parsed.type === 'result') {
71
+ if (parsed.session_id)
72
+ sessionId = parsed.session_id;
73
+ if (parsed.duration_ms !== undefined) {
74
+ metadata = { ...metadata, duration_ms: parsed.duration_ms };
75
+ }
76
+ }
77
+ // user events and tool_call events: logged but don't affect result
78
+ }
79
+ catch {
80
+ /* malformed JSON — already logged */
81
+ }
82
+ };
83
+ proc.stdout?.on('data', (chunk) => {
84
+ lineBuffer += chunk.toString();
85
+ const lines = lineBuffer.split('\n');
86
+ lineBuffer = lines.pop() ?? '';
87
+ for (const line of lines) {
88
+ const trimmed = line.trim();
89
+ if (trimmed)
90
+ processLine(trimmed);
91
+ }
92
+ });
93
+ proc.stderr?.on('data', (chunk) => {
94
+ const data = chunk.toString();
95
+ stderr += data;
96
+ this.log(`stderr: ${data.trimEnd()}`);
97
+ });
98
+ proc.on('error', (error) => {
99
+ this.log(`Process error event: ${error.message}`);
100
+ if (timeoutId)
101
+ clearTimeout(timeoutId);
102
+ reject(error);
103
+ });
104
+ proc.on('close', (code) => {
105
+ if (lineBuffer.trim())
106
+ processLine(lineBuffer.trim());
107
+ this.log(`Process closed with code ${code}, result=${resultText.length} chars`);
108
+ if (timeoutId)
109
+ clearTimeout(timeoutId);
110
+ if (timedOut) {
111
+ reject(new Error('Agent execution timed out'));
112
+ return;
113
+ }
114
+ if (code !== 0 && code !== null) {
115
+ reject(new Error(stderr.trim() || `Process exited with code ${code}`));
116
+ return;
117
+ }
118
+ const result = { result: resultText };
119
+ if (sessionId)
120
+ result.sessionId = sessionId;
121
+ if (metadata)
122
+ result.metadata = metadata;
123
+ resolve(result);
124
+ });
125
+ });
126
+ }
127
+ async *executeStream(prompt, options) {
128
+ const args = this.buildStreamArgs(prompt, options);
129
+ const spawnOpts = this.buildSpawnOptions(options);
130
+ const proc = this.spawn('agent', args, spawnOpts);
131
+ if (proc.stdin)
132
+ proc.stdin.end();
133
+ let lineBuffer = '';
134
+ let stderr = '';
135
+ const queue = [];
136
+ let resolve = null;
137
+ let error = null;
138
+ function enqueue(event) {
139
+ queue.push(event);
140
+ if (resolve) {
141
+ resolve();
142
+ resolve = null;
143
+ }
144
+ }
145
+ function waitForItem() {
146
+ if (queue.length > 0)
147
+ return Promise.resolve();
148
+ return new Promise((r) => {
149
+ resolve = r;
150
+ });
151
+ }
152
+ proc.stdout?.on('data', (chunk) => {
153
+ lineBuffer += chunk.toString();
154
+ const lines = lineBuffer.split('\n');
155
+ lineBuffer = lines.pop() ?? '';
156
+ for (const line of lines) {
157
+ const trimmed = line.trim();
158
+ if (!trimmed)
159
+ continue;
160
+ const event = this.parseStreamLine(trimmed);
161
+ if (event)
162
+ enqueue(event);
163
+ }
164
+ });
165
+ proc.stderr?.on('data', (chunk) => {
166
+ stderr += chunk.toString();
167
+ });
168
+ proc.on('error', (err) => {
169
+ error = err;
170
+ enqueue(null);
171
+ });
172
+ proc.on('close', (code) => {
173
+ if (lineBuffer.trim()) {
174
+ const event = this.parseStreamLine(lineBuffer.trim());
175
+ if (event)
176
+ enqueue(event);
177
+ }
178
+ if (code !== 0 && code !== null && stderr.trim()) {
179
+ enqueue({ type: 'error', content: stderr.trim(), timestamp: new Date() });
180
+ }
181
+ enqueue(null);
182
+ });
183
+ while (true) {
184
+ await waitForItem();
185
+ const item = queue.shift();
186
+ if (item === null || item === undefined) {
187
+ if (error !== null) {
188
+ yield {
189
+ type: 'error',
190
+ content: error.message,
191
+ timestamp: new Date(),
192
+ };
193
+ }
194
+ return;
195
+ }
196
+ yield item;
197
+ }
198
+ }
199
+ /**
200
+ * Log a stream-json line as a human-readable event in the worker log.
201
+ */
202
+ logStreamEvent(line) {
203
+ try {
204
+ const parsed = JSON.parse(line);
205
+ if (parsed.type === 'assistant' && Array.isArray(parsed.message?.content)) {
206
+ for (const block of parsed.message.content) {
207
+ if (block.type === 'text' && block.text?.trim()) {
208
+ this.log(`[text] ${block.text.trim().replace(/\n/g, ' ')}`);
209
+ }
210
+ }
211
+ return;
212
+ }
213
+ if (parsed.type === 'tool_call') {
214
+ const toolName = Object.keys(parsed).find((k) => k.endsWith('ToolCall') || k.endsWith('toolCall')) ??
215
+ 'unknown';
216
+ this.log(`[tool] ${parsed.subtype ?? 'call'}: ${toolName}`);
217
+ return;
218
+ }
219
+ if (parsed.type === 'result') {
220
+ this.log(`[result] session=${parsed.session_id ?? 'none'}, duration=${parsed.duration_ms ?? 'unknown'}ms`);
221
+ return;
222
+ }
223
+ if (parsed.type === 'user')
224
+ return; // Skip echoed input
225
+ }
226
+ catch {
227
+ if (line.length > 0)
228
+ this.log(`[raw] ${line}`);
229
+ }
230
+ }
231
+ buildArgs(prompt, options) {
232
+ const args = ['-p', prompt, '--output-format', 'json', '--force'];
233
+ if (options?.resumeSession)
234
+ args.push('--resume', options.resumeSession);
235
+ if (options?.model)
236
+ args.push('-m', options.model);
237
+ // Unsupported options silently omitted: systemPrompt, allowedTools, maxTurns, outputSchema
238
+ // No auth flags — binary handles its own auth
239
+ return args;
240
+ }
241
+ buildStreamArgs(prompt, options) {
242
+ const args = this.buildArgs(prompt, options);
243
+ const fmtIdx = args.indexOf('--output-format');
244
+ if (fmtIdx !== -1)
245
+ args[fmtIdx + 1] = 'stream-json';
246
+ return args;
247
+ }
248
+ buildSpawnOptions(options) {
249
+ const spawnOpts = {};
250
+ if (options?.cwd)
251
+ spawnOpts.cwd = options.cwd;
252
+ return spawnOpts;
253
+ }
254
+ parseStreamLine(line) {
255
+ try {
256
+ const parsed = JSON.parse(line);
257
+ if (parsed.type === 'assistant' && Array.isArray(parsed.message?.content)) {
258
+ const textParts = [];
259
+ for (const block of parsed.message.content) {
260
+ if (block.type === 'text' && block.text)
261
+ textParts.push(block.text);
262
+ }
263
+ if (textParts.length > 0) {
264
+ return { type: 'progress', content: textParts.join(''), timestamp: new Date() };
265
+ }
266
+ return null;
267
+ }
268
+ if (parsed.type === 'tool_call' && parsed.subtype === 'completed') {
269
+ const toolName = Object.keys(parsed).find((k) => k.endsWith('ToolCall') || k.endsWith('toolCall')) ??
270
+ 'tool';
271
+ return { type: 'progress', content: `Tool completed: ${toolName}`, timestamp: new Date() };
272
+ }
273
+ if (parsed.type === 'tool_call' && parsed.subtype === 'started') {
274
+ const toolName = Object.keys(parsed).find((k) => k.endsWith('ToolCall') || k.endsWith('toolCall')) ??
275
+ 'tool';
276
+ return { type: 'progress', content: `Tool started: ${toolName}`, timestamp: new Date() };
277
+ }
278
+ if (parsed.type === 'result') {
279
+ return { type: 'result', content: parsed.session_id ?? '', timestamp: new Date() };
280
+ }
281
+ if (parsed.type === 'user')
282
+ return null; // Skip echoed input
283
+ if (parsed.type === 'error') {
284
+ return {
285
+ type: 'error',
286
+ content: parsed.error ?? parsed.message ?? '',
287
+ timestamp: new Date(),
288
+ };
289
+ }
290
+ return null;
291
+ }
292
+ catch {
293
+ return { type: 'progress', content: line, timestamp: new Date() };
294
+ }
295
+ }
296
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shared Types for Agent Infrastructure
3
+ *
4
+ * Common type definitions used across agent executor implementations
5
+ * and the agent validator service.
6
+ */
7
+ import type { ChildProcess } from 'node:child_process';
8
+ /**
9
+ * Type for the spawn dependency.
10
+ * Matches the signature of child_process.spawn.
11
+ * Injected via constructor to enable testability.
12
+ */
13
+ export type SpawnFunction = (command: string, args: string[], options?: object) => ChildProcess;
14
+ /**
15
+ * Type for the command executor dependency.
16
+ * Matches the promisified signature of child_process.execFile.
17
+ * Injected via constructor to avoid direct node module mocking in tests.
18
+ */
19
+ export type ExecFunction = (file: string, args: string[]) => Promise<{
20
+ stdout: string;
21
+ stderr: string;
22
+ }>;
23
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/infrastructure/services/agents/common/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC;AAEhG;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,KACX,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Shared Types for Agent Infrastructure
3
+ *
4
+ * Common type definitions used across agent executor implementations
5
+ * and the agent validator service.
6
+ */
7
+ export {};
@@ -13,6 +13,8 @@ export declare class FeatureAgentProcessService implements IFeatureAgentProcessS
13
13
  spawn(featureId: string, runId: string, repoPath: string, specDir: string, worktreePath?: string, options?: {
14
14
  approvalMode?: string;
15
15
  resume?: boolean;
16
+ threadId?: string;
17
+ resumeFromInterrupt?: boolean;
16
18
  }): number;
17
19
  isAlive(pid: number): boolean;
18
20
  checkAndMarkCrashed(runId: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-agent-process.service.d.ts","sourceRoot":"","sources":["../../../../../../src/infrastructure/services/agents/feature-agent/feature-agent-process.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sEAAsE,CAAC;AACxH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qEAAqE,CAAC;AAa/G,qBAAa,0BAA2B,YAAW,2BAA2B;IAChE,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,mBAAmB;IAE/D,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GACpD,MAAM;IA4CT,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASvB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAexD"}
1
+ {"version":3,"file":"feature-agent-process.service.d.ts","sourceRoot":"","sources":["../../../../../../src/infrastructure/services/agents/feature-agent/feature-agent-process.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sEAAsE,CAAC;AACxH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qEAAqE,CAAC;AAa/G,qBAAa,0BAA2B,YAAW,2BAA2B;IAChE,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,mBAAmB;IAE/D,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;QACR,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B,GACA,MAAM;IAkDT,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASvB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAexD"}
@@ -44,9 +44,15 @@ export class FeatureAgentProcessService {
44
44
  if (options?.approvalMode) {
45
45
  args.push('--approval-mode', options.approvalMode);
46
46
  }
47
+ if (options?.threadId) {
48
+ args.push('--thread-id', options.threadId);
49
+ }
47
50
  if (options?.resume) {
48
51
  args.push('--resume');
49
52
  }
53
+ if (options?.resumeFromInterrupt) {
54
+ args.push('--resume-from-interrupt');
55
+ }
50
56
  // Create log file for worker output (for debugging)
51
57
  const logsDir = join(homedir(), '.shep', 'logs');
52
58
  mkdirSync(logsDir, { recursive: true });
@@ -17,6 +17,8 @@ export interface WorkerArgs {
17
17
  worktreePath?: string;
18
18
  approvalMode?: string;
19
19
  resume?: boolean;
20
+ threadId?: string;
21
+ resumeFromInterrupt?: boolean;
20
22
  }
21
23
  /**
22
24
  * Parse CLI arguments into a WorkerArgs object.
@@ -1 +1 @@
1
- {"version":3,"file":"feature-agent-worker.d.ts","sourceRoot":"","sources":["../../../../../../src/infrastructure/services/agents/feature-agent/feature-agent-worker.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,kBAAkB,CAAC;AAc1B,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,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA4B1D;AAgCD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAqH/D"}
1
+ {"version":3,"file":"feature-agent-worker.d.ts","sourceRoot":"","sources":["../../../../../../src/infrastructure/services/agents/feature-agent/feature-agent-worker.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,kBAAkB,CAAC;AAc1B,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,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAmC1D;AAgCD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmI/D"}
@@ -16,7 +16,7 @@ import { initializeContainer, container } from '../../../../infrastructure/di/co
16
16
  import { createFeatureAgentGraph } from './feature-agent-graph.js';
17
17
  import { createCheckpointer } from '../common/checkpointer.js';
18
18
  import { AgentRunStatus } from '../../../../domain/generated/output.js';
19
- import { getSettings, initializeSettings } from '../../../../infrastructure/services/settings.service.js';
19
+ import { initializeSettings } from '../../../../infrastructure/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
  /**
@@ -36,6 +36,9 @@ export function parseWorkerArgs(args) {
36
36
  const approvalIdx = args.indexOf('--approval-mode');
37
37
  const approvalMode = approvalIdx !== -1 && approvalIdx + 1 < args.length ? args[approvalIdx + 1] : undefined;
38
38
  const resume = args.includes('--resume');
39
+ const resumeFromInterrupt = args.includes('--resume-from-interrupt');
40
+ const threadIdx = args.indexOf('--thread-id');
41
+ const threadId = threadIdx !== -1 && threadIdx + 1 < args.length ? args[threadIdx + 1] : undefined;
39
42
  return {
40
43
  featureId: getArg('feature-id'),
41
44
  runId: getArg('run-id'),
@@ -44,6 +47,8 @@ export function parseWorkerArgs(args) {
44
47
  worktreePath,
45
48
  approvalMode,
46
49
  resume,
50
+ threadId,
51
+ resumeFromInterrupt,
47
52
  };
48
53
  }
49
54
  /** Simple worker logger — writes to stdout which is redirected to log file by the parent. */
@@ -92,14 +97,15 @@ export async function runWorker(args) {
92
97
  const settings = await initSettingsUseCase.execute();
93
98
  initializeSettings(settings);
94
99
  const runRepository = container.resolve('IAgentRunRepository');
95
- const executorFactory = container.resolve('IAgentExecutorFactory');
96
- // Create executor from configured agent settings (now settings are initialized)
97
- const configuredSettings = getSettings();
98
- log(`Creating executor for agent type: ${configuredSettings.agent.type}`);
99
- const executor = executorFactory.createExecutor(configuredSettings.agent.type, configuredSettings.agent);
100
- // Use a file-based checkpointer for persistence across restarts
101
- const checkpointPath = join(homedir(), '.shep', 'checkpoints', `${args.runId}.db`);
102
- log(`Creating checkpointer at ${checkpointPath}`);
100
+ const executorProvider = container.resolve('IAgentExecutorProvider');
101
+ // Create executor from configured agent settings
102
+ log('Creating executor from configured agent settings...');
103
+ const executor = executorProvider.getExecutor();
104
+ // Use threadId for checkpoint path so resume runs share the same checkpoint DB.
105
+ // Falls back to runId for backwards compatibility with existing runs.
106
+ const checkpointId = args.threadId ?? args.runId;
107
+ const checkpointPath = join(homedir(), '.shep', 'checkpoints', `${checkpointId}.db`);
108
+ log(`Creating checkpointer at ${checkpointPath} (thread: ${checkpointId})`);
103
109
  const checkpointer = createCheckpointer(checkpointPath);
104
110
  const graph = createFeatureAgentGraph(executor, checkpointer);
105
111
  // Mark the run as running with our PID
@@ -116,12 +122,26 @@ export async function runWorker(args) {
116
122
  // Set heartbeat context so node-helpers can update current node
117
123
  setHeartbeatContext(args.runId, runRepository);
118
124
  try {
119
- const graphConfig = { configurable: { thread_id: args.runId } };
125
+ const graphConfig = { configurable: { thread_id: checkpointId } };
120
126
  let result;
121
- if (args.resume) {
122
- log('Resuming graph from checkpoint...');
127
+ if (args.resume && args.resumeFromInterrupt) {
128
+ // Resume from an interrupt (human-in-the-loop approval)
129
+ log('Resuming graph from interrupt checkpoint...');
123
130
  result = await graph.invoke(new Command({ resume: { approved: true } }), graphConfig);
124
131
  }
132
+ else if (args.resume) {
133
+ // Resume from error — re-invoke with initial state; LangGraph continues
134
+ // from the last successfully checkpointed node.
135
+ log('Resuming graph from error checkpoint...');
136
+ result = await graph.invoke({
137
+ featureId: args.featureId,
138
+ repositoryPath: args.repo,
139
+ worktreePath: args.worktreePath ?? args.repo,
140
+ specDir: args.specDir,
141
+ error: undefined, // Clear previous error state
142
+ ...(args.approvalMode ? { approvalMode: args.approvalMode } : {}),
143
+ }, graphConfig);
144
+ }
125
145
  else {
126
146
  log('Starting graph invocation...');
127
147
  result = await graph.invoke({
@@ -1,11 +1,12 @@
1
- import type { IAgentExecutor } from '../../../../../application/ports/output/agents/agent-executor.interface.js';
2
- import type { FeatureAgentState } from '../state.js';
3
1
  /**
4
- * Creates the implement node — PLACEHOLDER.
2
+ * Implement Node Phase-Level Orchestrator
5
3
  *
6
- * Implementation execution is not yet wired up.
7
- * Returns a programming joke to clearly signal this is a placeholder
8
- * while keeping the graph pipeline intact.
4
+ * Reads plan.yaml and tasks.yaml, then executes each phase by building
5
+ * a focused implementation prompt and calling the executor. Parallel
6
+ * phases spawn concurrent executor calls. Progress is tracked in
7
+ * feature.yaml between phases.
9
8
  */
10
- export declare function createImplementNode(_executor: IAgentExecutor): (_state: FeatureAgentState) => Promise<Partial<FeatureAgentState>>;
9
+ import type { IAgentExecutor } from '../../../../../application/ports/output/agents/agent-executor.interface.js';
10
+ import type { FeatureAgentState } from '../state.js';
11
+ export declare function createImplementNode(executor: IAgentExecutor): (state: FeatureAgentState) => Promise<Partial<FeatureAgentState>>;
11
12
  //# sourceMappingURL=implement.node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../src/infrastructure/services/agents/feature-agent/nodes/implement.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKrD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,cAAc,IAG7C,QAAQ,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAY9E"}
1
+ {"version":3,"file":"implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../src/infrastructure/services/agents/feature-agent/nodes/implement.node.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA4DrD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,IAG5C,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAoJ7E"}