@su-record/vibe 2.5.21 → 2.6.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 (69) hide show
  1. package/CLAUDE.md +122 -2
  2. package/README.md +132 -2
  3. package/commands/vibe.run.md +69 -44
  4. package/commands/vibe.trace.md +161 -0
  5. package/dist/lib/IterationTracker.d.ts +3 -1
  6. package/dist/lib/IterationTracker.d.ts.map +1 -1
  7. package/dist/lib/IterationTracker.js +2 -1
  8. package/dist/lib/IterationTracker.js.map +1 -1
  9. package/dist/lib/constants.d.ts +14 -0
  10. package/dist/lib/constants.d.ts.map +1 -1
  11. package/dist/lib/constants.js +26 -0
  12. package/dist/lib/constants.js.map +1 -1
  13. package/dist/orchestrator/BackgroundManager.d.ts +109 -0
  14. package/dist/orchestrator/BackgroundManager.d.ts.map +1 -0
  15. package/dist/orchestrator/BackgroundManager.js +456 -0
  16. package/dist/orchestrator/BackgroundManager.js.map +1 -0
  17. package/dist/orchestrator/BackgroundManager.test.d.ts +6 -0
  18. package/dist/orchestrator/BackgroundManager.test.d.ts.map +1 -0
  19. package/dist/orchestrator/BackgroundManager.test.js +162 -0
  20. package/dist/orchestrator/BackgroundManager.test.js.map +1 -0
  21. package/dist/orchestrator/PhasePipeline.d.ts +106 -0
  22. package/dist/orchestrator/PhasePipeline.d.ts.map +1 -0
  23. package/dist/orchestrator/PhasePipeline.js +279 -0
  24. package/dist/orchestrator/PhasePipeline.js.map +1 -0
  25. package/dist/orchestrator/backgroundAgent.d.ts +2 -0
  26. package/dist/orchestrator/backgroundAgent.d.ts.map +1 -1
  27. package/dist/orchestrator/backgroundAgent.js +2 -0
  28. package/dist/orchestrator/backgroundAgent.js.map +1 -1
  29. package/dist/orchestrator/index.d.ts +4 -1
  30. package/dist/orchestrator/index.d.ts.map +1 -1
  31. package/dist/orchestrator/index.js +5 -1
  32. package/dist/orchestrator/index.js.map +1 -1
  33. package/dist/tools/index.d.ts +2 -0
  34. package/dist/tools/index.d.ts.map +1 -1
  35. package/dist/tools/index.js +12 -0
  36. package/dist/tools/index.js.map +1 -1
  37. package/dist/tools/spec/index.d.ts +14 -0
  38. package/dist/tools/spec/index.d.ts.map +1 -0
  39. package/dist/tools/spec/index.js +15 -0
  40. package/dist/tools/spec/index.js.map +1 -0
  41. package/dist/tools/spec/prdParser.d.ts +43 -0
  42. package/dist/tools/spec/prdParser.d.ts.map +1 -0
  43. package/dist/tools/spec/prdParser.js +291 -0
  44. package/dist/tools/spec/prdParser.js.map +1 -0
  45. package/dist/tools/spec/prdParser.test.d.ts +6 -0
  46. package/dist/tools/spec/prdParser.test.d.ts.map +1 -0
  47. package/dist/tools/spec/prdParser.test.js +332 -0
  48. package/dist/tools/spec/prdParser.test.js.map +1 -0
  49. package/dist/tools/spec/requirementId.d.ts +65 -0
  50. package/dist/tools/spec/requirementId.d.ts.map +1 -0
  51. package/dist/tools/spec/requirementId.js +161 -0
  52. package/dist/tools/spec/requirementId.js.map +1 -0
  53. package/dist/tools/spec/specGenerator.d.ts +39 -0
  54. package/dist/tools/spec/specGenerator.d.ts.map +1 -0
  55. package/dist/tools/spec/specGenerator.js +426 -0
  56. package/dist/tools/spec/specGenerator.js.map +1 -0
  57. package/dist/tools/spec/specVersioning.d.ts +77 -0
  58. package/dist/tools/spec/specVersioning.d.ts.map +1 -0
  59. package/dist/tools/spec/specVersioning.js +237 -0
  60. package/dist/tools/spec/specVersioning.js.map +1 -0
  61. package/dist/tools/spec/traceabilityMatrix.d.ts +55 -0
  62. package/dist/tools/spec/traceabilityMatrix.d.ts.map +1 -0
  63. package/dist/tools/spec/traceabilityMatrix.js +396 -0
  64. package/dist/tools/spec/traceabilityMatrix.js.map +1 -0
  65. package/dist/tools/spec/traceabilityMatrix.test.d.ts +6 -0
  66. package/dist/tools/spec/traceabilityMatrix.test.d.ts.map +1 -0
  67. package/dist/tools/spec/traceabilityMatrix.test.js +340 -0
  68. package/dist/tools/spec/traceabilityMatrix.test.js.map +1 -0
  69. package/package.json +1 -1
@@ -7,7 +7,7 @@ let currentState = null;
7
7
  /**
8
8
  * 새 작업 시작
9
9
  */
10
- export function startIteration(featureName, phaseNames, isUltrawork = false, maxRetries = 3) {
10
+ export function startIteration(featureName, phaseNames, isUltrawork = false, maxRetries = 3, pipelineEnabled = false) {
11
11
  currentState = {
12
12
  featureName,
13
13
  totalPhases: phaseNames.length,
@@ -21,6 +21,7 @@ export function startIteration(featureName, phaseNames, isUltrawork = false, max
21
21
  isUltrawork,
22
22
  maxRetries,
23
23
  startTime: new Date(),
24
+ pipelineEnabled,
24
25
  };
25
26
  return currentState;
26
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"IterationTracker.js","sourceRoot":"","sources":["../../src/lib/IterationTracker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"IterationTracker.js","sourceRoot":"","sources":["../../src/lib/IterationTracker.ts"],"names":[],"mappings":"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"}
@@ -28,4 +28,18 @@ export declare const AGENT: {
28
28
  MAX_CONCURRENCY: number;
29
29
  DEFAULT_ALLOWED_TOOLS: string[];
30
30
  };
31
+ export declare const CONCURRENCY: {
32
+ /** 모델별 동시 실행 제한 */
33
+ readonly MODEL_LIMITS: Record<string, number>;
34
+ /** 프로바이더별 동시 실행 제한 */
35
+ readonly PROVIDER_LIMITS: Record<string, number>;
36
+ /** 기본 동시 실행 제한 */
37
+ readonly DEFAULT: 5;
38
+ /** 큐 최대 크기 */
39
+ readonly QUEUE_MAX_SIZE: 100;
40
+ /** 개별 태스크 타임아웃 (ms) */
41
+ readonly TASK_TIMEOUT: 180000;
42
+ /** 전체 파이프라인 타임아웃 (ms) */
43
+ readonly PIPELINE_TIMEOUT: 600000;
44
+ };
31
45
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,aAAa;;;;;CAKhB,CAAC;AAGX,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAGX,eAAO,MAAM,QAAQ;;;;CAIX,CAAC;AAGX,eAAO,MAAM,KAAK;;;;;CAKR,CAAC;AAGX,eAAO,MAAM,KAAK;;;2BAG4D,MAAM,EAAE;CACrF,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,aAAa;;;;;CAKhB,CAAC;AAGX,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAGX,eAAO,MAAM,QAAQ;;;;CAIX,CAAC;AAGX,eAAO,MAAM,KAAK;;;;;CAKR,CAAC;AAGX,eAAO,MAAM,KAAK;;;2BAG4D,MAAM,EAAE;CACrF,CAAC;AAGF,eAAO,MAAM,WAAW;IACtB,mBAAmB;2BAOd,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAC3B,sBAAsB;8BAMjB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAC3B,kBAAkB;;IAElB,cAAc;;IAEd,uBAAuB;;IAEvB,yBAAyB;;CAEjB,CAAC"}
@@ -33,4 +33,30 @@ export const AGENT = {
33
33
  MAX_CONCURRENCY: 4,
34
34
  DEFAULT_ALLOWED_TOOLS: ['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash'],
35
35
  };
36
+ // Concurrency 설정 (v2.6.0)
37
+ export const CONCURRENCY = {
38
+ /** 모델별 동시 실행 제한 */
39
+ MODEL_LIMITS: {
40
+ 'claude-opus-4': 3,
41
+ 'claude-sonnet-4-5': 5,
42
+ 'claude-haiku-3-5': 8,
43
+ 'claude-haiku-4-5-20251001': 8,
44
+ 'default': 5,
45
+ },
46
+ /** 프로바이더별 동시 실행 제한 */
47
+ PROVIDER_LIMITS: {
48
+ 'claude': 10,
49
+ 'gpt': 5,
50
+ 'gemini': 5,
51
+ 'default': 10,
52
+ },
53
+ /** 기본 동시 실행 제한 */
54
+ DEFAULT: 5,
55
+ /** 큐 최대 크기 */
56
+ QUEUE_MAX_SIZE: 100,
57
+ /** 개별 태스크 타임아웃 (ms) */
58
+ TASK_TIMEOUT: 180000, // 3분
59
+ /** 전체 파이프라인 타임아웃 (ms) */
60
+ PIPELINE_TIMEOUT: 600000, // 10분
61
+ };
36
62
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,QAAQ;AACR,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,MAAM,EAAE,mBAAmB;IAC3B,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,kBAAkB;IACzB,YAAY,EAAE,2BAA2B;CACjC,CAAC;AAEX,WAAW;AACX,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,QAAQ,EAAE,aAAa,CAAC,YAAY,EAAG,aAAa;IACpD,MAAM,EAAE,aAAa,CAAC,KAAK,EAAY,YAAY;IACnD,UAAU,EAAE,aAAa,CAAC,MAAM,EAAO,eAAe;CAC9C,CAAC;AAEX,eAAe;AACf,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,MAAM,EAAO,KAAK;IAC5B,YAAY,EAAE,KAAK,EAAI,MAAM;IAC7B,OAAO,EAAE,MAAM,EAAQ,KAAK;CACpB,CAAC;AAEX,QAAQ;AACR,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,QAAQ,EAAE,CAAC;IACX,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAY,KAAK;IACnC,mBAAmB,EAAE,GAAG;IACxB,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAG,MAAM;CACjC,CAAC;AAEX,WAAW;AACX,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,SAAS,EAAE,EAAE;IACb,eAAe,EAAE,CAAC;IAClB,qBAAqB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAa;CACrF,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,QAAQ;AACR,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,MAAM,EAAE,mBAAmB;IAC3B,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,kBAAkB;IACzB,YAAY,EAAE,2BAA2B;CACjC,CAAC;AAEX,WAAW;AACX,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,QAAQ,EAAE,aAAa,CAAC,YAAY,EAAG,aAAa;IACpD,MAAM,EAAE,aAAa,CAAC,KAAK,EAAY,YAAY;IACnD,UAAU,EAAE,aAAa,CAAC,MAAM,EAAO,eAAe;CAC9C,CAAC;AAEX,eAAe;AACf,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,MAAM,EAAO,KAAK;IAC5B,YAAY,EAAE,KAAK,EAAI,MAAM;IAC7B,OAAO,EAAE,MAAM,EAAQ,KAAK;CACpB,CAAC;AAEX,QAAQ;AACR,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,QAAQ,EAAE,CAAC;IACX,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAY,KAAK;IACnC,mBAAmB,EAAE,GAAG;IACxB,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAG,MAAM;CACjC,CAAC;AAEX,WAAW;AACX,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,SAAS,EAAE,EAAE;IACb,eAAe,EAAE,CAAC;IAClB,qBAAqB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAa;CACrF,CAAC;AAEF,0BAA0B;AAC1B,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,mBAAmB;IACnB,YAAY,EAAE;QACZ,eAAe,EAAE,CAAC;QAClB,mBAAmB,EAAE,CAAC;QACtB,kBAAkB,EAAE,CAAC;QACrB,2BAA2B,EAAE,CAAC;QAC9B,SAAS,EAAE,CAAC;KACa;IAC3B,sBAAsB;IACtB,eAAe,EAAE;QACf,QAAQ,EAAE,EAAE;QACZ,KAAK,EAAE,CAAC;QACR,QAAQ,EAAE,CAAC;QACX,SAAS,EAAE,EAAE;KACY;IAC3B,kBAAkB;IAClB,OAAO,EAAE,CAAC;IACV,cAAc;IACd,cAAc,EAAE,GAAG;IACnB,uBAAuB;IACvB,YAAY,EAAE,MAAM,EAAE,KAAK;IAC3B,yBAAyB;IACzB,gBAAgB,EAAE,MAAM,EAAE,MAAM;CACxB,CAAC"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * BackgroundManager - Fire-and-forget 패턴 기반 백그라운드 에이전트 매니저
3
+ * v2.6.0: Concurrency Manager + TaskQueue 도입
4
+ */
5
+ import { BackgroundAgentArgs, BackgroundAgentHandle, AgentResult } from './types.js';
6
+ import { ToolResult } from '../types/tool.js';
7
+ /** 큐 용량 초과 에러 */
8
+ export declare class QueueOverflowError extends Error {
9
+ constructor(queueSize: number, maxSize: number);
10
+ }
11
+ /** 개별 태스크 타임아웃 에러 */
12
+ export declare class TaskTimeoutError extends Error {
13
+ constructor(taskId: string, timeout: number);
14
+ }
15
+ /** 전체 파이프라인 타임아웃 에러 */
16
+ export declare class PipelineTimeoutError extends Error {
17
+ constructor(timeout: number);
18
+ }
19
+ /** Agent 실행 실패 에러 */
20
+ export declare class AgentExecutionError extends Error {
21
+ constructor(agentName: string, reason: string);
22
+ }
23
+ /** 작업 상태 (SPEC Job Lifecycle) */
24
+ export type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
25
+ /** 작업 정보 */
26
+ export interface TaskInfo {
27
+ id: string;
28
+ args: BackgroundAgentArgs;
29
+ status: TaskStatus;
30
+ handle?: BackgroundAgentHandle;
31
+ result?: AgentResult;
32
+ error?: string;
33
+ createdAt: number;
34
+ startedAt?: number;
35
+ completedAt?: number;
36
+ model: string;
37
+ provider: string;
38
+ }
39
+ /** 큐 통계 */
40
+ export interface QueueStats {
41
+ total: number;
42
+ pending: number;
43
+ running: number;
44
+ completed: number;
45
+ failed: number;
46
+ cancelled: number;
47
+ queueSize: number;
48
+ maxQueueSize: number;
49
+ }
50
+ declare class BackgroundManagerImpl {
51
+ private readonly concurrency;
52
+ private readonly taskQueue;
53
+ private readonly tasks;
54
+ private processing;
55
+ private cleanupTimer;
56
+ constructor();
57
+ private startCleanupTimer;
58
+ /**
59
+ * Fire-and-forget 방식으로 백그라운드 에이전트 시작
60
+ * 즉시 handle 반환 (< 100ms)
61
+ */
62
+ launch(args: BackgroundAgentArgs): ToolResult & {
63
+ taskId: string;
64
+ handle?: BackgroundAgentHandle;
65
+ };
66
+ /**
67
+ * 결과 폴링 (비동기)
68
+ */
69
+ poll(taskId: string): Promise<ToolResult & {
70
+ task?: TaskInfo;
71
+ result?: AgentResult;
72
+ }>;
73
+ /**
74
+ * 태스크 취소
75
+ */
76
+ cancel(taskId: string): ToolResult;
77
+ /**
78
+ * 통계 조회
79
+ */
80
+ getStats(): ToolResult & {
81
+ stats: QueueStats;
82
+ };
83
+ /**
84
+ * 큐 처리 (내부)
85
+ */
86
+ private processQueue;
87
+ /**
88
+ * 태스크 실행 (내부)
89
+ */
90
+ private executeTask;
91
+ private extractProvider;
92
+ private getQueuePosition;
93
+ private formatDuration;
94
+ private sleep;
95
+ }
96
+ export declare const backgroundManager: BackgroundManagerImpl;
97
+ export declare function launch(args: BackgroundAgentArgs): ToolResult & {
98
+ taskId: string;
99
+ };
100
+ export declare function poll(taskId: string): Promise<ToolResult & {
101
+ task?: TaskInfo;
102
+ result?: AgentResult;
103
+ }>;
104
+ export declare function cancel(taskId: string): ToolResult;
105
+ export declare function getStats(): ToolResult & {
106
+ stats: QueueStats;
107
+ };
108
+ export {};
109
+ //# sourceMappingURL=BackgroundManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackgroundManager.d.ts","sourceRoot":"","sources":["../../src/orchestrator/BackgroundManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,WAAW,EAEZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAS9C,iBAAiB;AACjB,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAI/C;AAED,qBAAqB;AACrB,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAI5C;AAED,uBAAuB;AACvB,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAqB;AACrB,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI9C;AAMD,iCAAiC;AACjC,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEtF,YAAY;AACZ,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,mBAAmB,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,WAAW;AACX,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAsJD,cAAM,qBAAqB;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IACrD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAA+C;;IAMnE,OAAO,CAAC,iBAAiB;IAazB;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,mBAAmB,GAAG,UAAU,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,qBAAqB,CAAA;KAAE;IA6ClG;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG;QAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC;IAyD3F;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU;IAyBlC;;OAEG;IACH,QAAQ,IAAI,UAAU,GAAG;QAAE,KAAK,EAAE,UAAU,CAAA;KAAE;IAsB9C;;OAEG;YACW,YAAY;IA4B1B;;OAEG;YACW,WAAW;IA4CzB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,KAAK;CAGd;AAGD,eAAO,MAAM,iBAAiB,uBAA8B,CAAC;AAG7D,wBAAgB,MAAM,CAAC,IAAI,EAAE,mBAAmB,GAAG,UAAU,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAEjF;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG;IAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,CAAC,CAEpG;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAEjD;AAED,wBAAgB,QAAQ,IAAI,UAAU,GAAG;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,CAE7D"}
@@ -0,0 +1,456 @@
1
+ /**
2
+ * BackgroundManager - Fire-and-forget 패턴 기반 백그라운드 에이전트 매니저
3
+ * v2.6.0: Concurrency Manager + TaskQueue 도입
4
+ */
5
+ import { CONCURRENCY, DEFAULT_MODELS } from '../lib/constants.js';
6
+ import { warnLog } from '../lib/utils.js';
7
+ import { launchBackgroundAgent } from './AgentExecutor.js';
8
+ // ============================================
9
+ // Error Types (SPEC Error Taxonomy)
10
+ // ============================================
11
+ /** 큐 용량 초과 에러 */
12
+ export class QueueOverflowError extends Error {
13
+ constructor(queueSize, maxSize) {
14
+ super(`Queue overflow: ${queueSize}/${maxSize}. Retry later.`);
15
+ this.name = 'QueueOverflowError';
16
+ }
17
+ }
18
+ /** 개별 태스크 타임아웃 에러 */
19
+ export class TaskTimeoutError extends Error {
20
+ constructor(taskId, timeout) {
21
+ super(`Task "${taskId}" exceeded timeout: ${timeout}ms`);
22
+ this.name = 'TaskTimeoutError';
23
+ }
24
+ }
25
+ /** 전체 파이프라인 타임아웃 에러 */
26
+ export class PipelineTimeoutError extends Error {
27
+ constructor(timeout) {
28
+ super(`Pipeline exceeded timeout: ${timeout}ms`);
29
+ this.name = 'PipelineTimeoutError';
30
+ }
31
+ }
32
+ /** Agent 실행 실패 에러 */
33
+ export class AgentExecutionError extends Error {
34
+ constructor(agentName, reason) {
35
+ super(`Agent "${agentName}" execution failed: ${reason}`);
36
+ this.name = 'AgentExecutionError';
37
+ }
38
+ }
39
+ // ============================================
40
+ // ConcurrencyManager - 동시 실행 제한 관리
41
+ // ============================================
42
+ class ConcurrencyManager {
43
+ runningByModel = new Map();
44
+ runningByProvider = new Map();
45
+ /** 실행 가능 여부 확인 */
46
+ canRun(model, provider) {
47
+ const modelLimit = this.getModelLimit(model);
48
+ const providerLimit = this.getProviderLimit(provider);
49
+ const currentModel = this.runningByModel.get(model) || 0;
50
+ const currentProvider = this.runningByProvider.get(provider) || 0;
51
+ return currentModel < modelLimit && currentProvider < providerLimit;
52
+ }
53
+ /** 실행 시작 (슬롯 획득) */
54
+ acquire(model, provider) {
55
+ const currentModel = this.runningByModel.get(model) || 0;
56
+ const currentProvider = this.runningByProvider.get(provider) || 0;
57
+ this.runningByModel.set(model, currentModel + 1);
58
+ this.runningByProvider.set(provider, currentProvider + 1);
59
+ }
60
+ /** 실행 종료 (슬롯 반환) */
61
+ release(model, provider) {
62
+ const currentModel = this.runningByModel.get(model) || 0;
63
+ const currentProvider = this.runningByProvider.get(provider) || 0;
64
+ if (currentModel > 0)
65
+ this.runningByModel.set(model, currentModel - 1);
66
+ if (currentProvider > 0)
67
+ this.runningByProvider.set(provider, currentProvider - 1);
68
+ }
69
+ /** 모델별 제한 조회 */
70
+ getModelLimit(model) {
71
+ return CONCURRENCY.MODEL_LIMITS[model] ?? CONCURRENCY.MODEL_LIMITS['default'];
72
+ }
73
+ /** 프로바이더별 제한 조회 */
74
+ getProviderLimit(provider) {
75
+ return CONCURRENCY.PROVIDER_LIMITS[provider] ?? CONCURRENCY.PROVIDER_LIMITS['default'];
76
+ }
77
+ /** 현재 상태 조회 */
78
+ getStatus() {
79
+ return {
80
+ byModel: Object.fromEntries(this.runningByModel),
81
+ byProvider: Object.fromEntries(this.runningByProvider)
82
+ };
83
+ }
84
+ }
85
+ // ============================================
86
+ // TaskQueue - Bounded Queue with Backpressure
87
+ // ============================================
88
+ class TaskQueue {
89
+ queue = [];
90
+ maxSize;
91
+ constructor(maxSize = CONCURRENCY.QUEUE_MAX_SIZE) {
92
+ this.maxSize = maxSize;
93
+ }
94
+ /** 큐에 추가 (backpressure 적용) */
95
+ enqueue(task) {
96
+ if (this.queue.length >= this.maxSize) {
97
+ throw new QueueOverflowError(this.queue.length, this.maxSize);
98
+ }
99
+ this.queue.push(task);
100
+ }
101
+ /** 다음 대기 중인 태스크 조회 */
102
+ peek() {
103
+ return this.queue.find(t => t.status === 'pending');
104
+ }
105
+ /** 다음 대기 중인 태스크 제거 및 반환 */
106
+ dequeue() {
107
+ const index = this.queue.findIndex(t => t.status === 'pending');
108
+ if (index === -1)
109
+ return undefined;
110
+ return this.queue[index];
111
+ }
112
+ /** 큐 사이즈 */
113
+ get size() {
114
+ return this.queue.filter(t => t.status === 'pending').length;
115
+ }
116
+ /** 전체 태스크 수 */
117
+ get totalSize() {
118
+ return this.queue.length;
119
+ }
120
+ /** 큐가 비었는지 확인 */
121
+ isEmpty() {
122
+ return this.size === 0;
123
+ }
124
+ /** 큐가 가득 찼는지 확인 */
125
+ isFull() {
126
+ return this.queue.length >= this.maxSize;
127
+ }
128
+ /** 태스크 조회 */
129
+ get(taskId) {
130
+ return this.queue.find(t => t.id === taskId);
131
+ }
132
+ /** 완료된 태스크 정리 (24시간 후) */
133
+ cleanup() {
134
+ const cutoff = Date.now() - 24 * 60 * 60 * 1000;
135
+ const before = this.queue.length;
136
+ this.queue = this.queue.filter(t => {
137
+ if (t.status === 'pending' || t.status === 'running')
138
+ return true;
139
+ return (t.completedAt || t.createdAt) > cutoff;
140
+ });
141
+ return before - this.queue.length;
142
+ }
143
+ /** 통계 */
144
+ getStats() {
145
+ const stats = {
146
+ total: this.queue.length,
147
+ pending: 0,
148
+ running: 0,
149
+ completed: 0,
150
+ failed: 0,
151
+ cancelled: 0,
152
+ queueSize: this.size,
153
+ maxQueueSize: this.maxSize
154
+ };
155
+ for (const task of this.queue) {
156
+ stats[task.status]++;
157
+ }
158
+ return stats;
159
+ }
160
+ /** 모든 태스크 */
161
+ getAll() {
162
+ return [...this.queue];
163
+ }
164
+ }
165
+ // ============================================
166
+ // BackgroundManager - 메인 클래스
167
+ // ============================================
168
+ class BackgroundManagerImpl {
169
+ concurrency = new ConcurrencyManager();
170
+ taskQueue = new TaskQueue();
171
+ tasks = new Map();
172
+ processing = false;
173
+ cleanupTimer = null;
174
+ constructor() {
175
+ this.startCleanupTimer();
176
+ }
177
+ startCleanupTimer() {
178
+ if (this.cleanupTimer)
179
+ return;
180
+ this.cleanupTimer = setInterval(() => {
181
+ const cleaned = this.taskQueue.cleanup();
182
+ if (cleaned > 0) {
183
+ warnLog(`[BackgroundManager] Cleaned up ${cleaned} old tasks`);
184
+ }
185
+ }, 10 * 60 * 1000); // 10분마다
186
+ if (this.cleanupTimer.unref) {
187
+ this.cleanupTimer.unref();
188
+ }
189
+ }
190
+ /**
191
+ * Fire-and-forget 방식으로 백그라운드 에이전트 시작
192
+ * 즉시 handle 반환 (< 100ms)
193
+ */
194
+ launch(args) {
195
+ const taskId = `task-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
196
+ const model = args.model || DEFAULT_MODELS.BACKGROUND;
197
+ const provider = this.extractProvider(model);
198
+ const task = {
199
+ id: taskId,
200
+ args,
201
+ status: 'pending',
202
+ createdAt: Date.now(),
203
+ model,
204
+ provider
205
+ };
206
+ try {
207
+ this.taskQueue.enqueue(task);
208
+ this.tasks.set(taskId, task);
209
+ }
210
+ catch (error) {
211
+ if (error instanceof QueueOverflowError) {
212
+ return {
213
+ content: [{
214
+ type: 'text',
215
+ text: `❌ ${error.message}`
216
+ }],
217
+ taskId,
218
+ isError: true
219
+ };
220
+ }
221
+ throw error;
222
+ }
223
+ // 비동기로 큐 처리 시작 (fire-and-forget)
224
+ this.processQueue().catch(err => {
225
+ warnLog(`[BackgroundManager] Queue processing error: ${err.message}`);
226
+ });
227
+ return {
228
+ content: [{
229
+ type: 'text',
230
+ text: `🚀 Task queued: ${taskId}\nAgent: ${args.agentName || 'unnamed'}\nModel: ${model}\nQueue position: ${this.taskQueue.size}\n\nUse poll("${taskId}") to check status.`
231
+ }],
232
+ taskId
233
+ };
234
+ }
235
+ /**
236
+ * 결과 폴링 (비동기)
237
+ */
238
+ async poll(taskId) {
239
+ const task = this.tasks.get(taskId);
240
+ if (!task) {
241
+ return {
242
+ content: [{ type: 'text', text: `Task "${taskId}" not found` }]
243
+ };
244
+ }
245
+ switch (task.status) {
246
+ case 'pending':
247
+ return {
248
+ content: [{
249
+ type: 'text',
250
+ text: `⏳ Task "${taskId}" is pending\nQueue position: ${this.getQueuePosition(taskId)}`
251
+ }],
252
+ task
253
+ };
254
+ case 'running':
255
+ return {
256
+ content: [{
257
+ type: 'text',
258
+ text: `🔄 Task "${taskId}" is running\nStarted: ${new Date(task.startedAt).toISOString()}`
259
+ }],
260
+ task
261
+ };
262
+ case 'completed':
263
+ return {
264
+ content: [{
265
+ type: 'text',
266
+ text: `✅ Task "${taskId}" completed\nDuration: ${this.formatDuration(task)}\n\nResult:\n${task.result?.result || 'No result'}`
267
+ }],
268
+ task,
269
+ result: task.result
270
+ };
271
+ case 'failed':
272
+ return {
273
+ content: [{
274
+ type: 'text',
275
+ text: `❌ Task "${taskId}" failed\nError: ${task.error || 'Unknown error'}`
276
+ }],
277
+ task
278
+ };
279
+ case 'cancelled':
280
+ return {
281
+ content: [{
282
+ type: 'text',
283
+ text: `🚫 Task "${taskId}" was cancelled`
284
+ }],
285
+ task
286
+ };
287
+ }
288
+ }
289
+ /**
290
+ * 태스크 취소
291
+ */
292
+ cancel(taskId) {
293
+ const task = this.tasks.get(taskId);
294
+ if (!task) {
295
+ return {
296
+ content: [{ type: 'text', text: `Task "${taskId}" not found` }]
297
+ };
298
+ }
299
+ if (task.status !== 'pending' && task.status !== 'running') {
300
+ return {
301
+ content: [{ type: 'text', text: `Task "${taskId}" is already ${task.status}` }]
302
+ };
303
+ }
304
+ if (task.handle) {
305
+ task.handle.cancel();
306
+ }
307
+ task.status = 'cancelled';
308
+ task.completedAt = Date.now();
309
+ return {
310
+ content: [{ type: 'text', text: `Task "${taskId}" cancelled` }]
311
+ };
312
+ }
313
+ /**
314
+ * 통계 조회
315
+ */
316
+ getStats() {
317
+ const stats = this.taskQueue.getStats();
318
+ const concurrencyStatus = this.concurrency.getStatus();
319
+ let text = `## BackgroundManager Stats\n\n`;
320
+ text += `**Queue**: ${stats.queueSize}/${stats.maxQueueSize}\n`;
321
+ text += `**Total tasks**: ${stats.total}\n`;
322
+ text += `- Pending: ${stats.pending}\n`;
323
+ text += `- Running: ${stats.running}\n`;
324
+ text += `- Completed: ${stats.completed}\n`;
325
+ text += `- Failed: ${stats.failed}\n`;
326
+ text += `- Cancelled: ${stats.cancelled}\n\n`;
327
+ text += `**Concurrency**:\n`;
328
+ text += `- By Model: ${JSON.stringify(concurrencyStatus.byModel)}\n`;
329
+ text += `- By Provider: ${JSON.stringify(concurrencyStatus.byProvider)}\n`;
330
+ return {
331
+ content: [{ type: 'text', text }],
332
+ stats
333
+ };
334
+ }
335
+ /**
336
+ * 큐 처리 (내부)
337
+ */
338
+ async processQueue() {
339
+ if (this.processing)
340
+ return;
341
+ this.processing = true;
342
+ try {
343
+ while (!this.taskQueue.isEmpty()) {
344
+ const task = this.taskQueue.peek();
345
+ if (!task)
346
+ break;
347
+ if (!this.concurrency.canRun(task.model, task.provider)) {
348
+ await this.sleep(100);
349
+ continue;
350
+ }
351
+ task.status = 'running';
352
+ task.startedAt = Date.now();
353
+ this.concurrency.acquire(task.model, task.provider);
354
+ // Fire-and-forget 실행
355
+ this.executeTask(task).catch(err => {
356
+ warnLog(`[BackgroundManager] Task ${task.id} error: ${err.message}`);
357
+ });
358
+ }
359
+ }
360
+ finally {
361
+ this.processing = false;
362
+ }
363
+ }
364
+ /**
365
+ * 태스크 실행 (내부)
366
+ */
367
+ async executeTask(task) {
368
+ const timeout = CONCURRENCY.TASK_TIMEOUT;
369
+ const timeoutId = setTimeout(() => {
370
+ if (task.status === 'running') {
371
+ task.status = 'failed';
372
+ task.error = new TaskTimeoutError(task.id, timeout).message;
373
+ task.completedAt = Date.now();
374
+ this.concurrency.release(task.model, task.provider);
375
+ warnLog(`[BackgroundManager] Task ${task.id} timed out`);
376
+ }
377
+ }, timeout);
378
+ try {
379
+ const result = await launchBackgroundAgent(task.args);
380
+ const handle = result.handle;
381
+ if (handle) {
382
+ task.handle = handle;
383
+ const agentResult = await handle.getResult();
384
+ task.result = agentResult;
385
+ task.status = agentResult.success ? 'completed' : 'failed';
386
+ if (!agentResult.success) {
387
+ task.error = agentResult.error;
388
+ }
389
+ }
390
+ else {
391
+ task.status = 'failed';
392
+ task.error = 'No handle returned';
393
+ }
394
+ }
395
+ catch (error) {
396
+ task.status = 'failed';
397
+ task.error = error instanceof Error ? error.message : String(error);
398
+ warnLog(`[BackgroundManager] Task ${task.id} failed: ${task.error}`);
399
+ }
400
+ finally {
401
+ clearTimeout(timeoutId);
402
+ task.completedAt = Date.now();
403
+ this.concurrency.release(task.model, task.provider);
404
+ // 큐에 대기 중인 태스크가 있으면 계속 처리
405
+ if (!this.taskQueue.isEmpty()) {
406
+ this.processQueue().catch(() => { });
407
+ }
408
+ }
409
+ }
410
+ extractProvider(model) {
411
+ if (model.startsWith('claude'))
412
+ return 'claude';
413
+ if (model.startsWith('gpt'))
414
+ return 'gpt';
415
+ if (model.startsWith('gemini'))
416
+ return 'gemini';
417
+ return 'default';
418
+ }
419
+ getQueuePosition(taskId) {
420
+ const all = this.taskQueue.getAll();
421
+ let position = 0;
422
+ for (const task of all) {
423
+ if (task.status === 'pending') {
424
+ position++;
425
+ if (task.id === taskId)
426
+ return position;
427
+ }
428
+ }
429
+ return -1;
430
+ }
431
+ formatDuration(task) {
432
+ if (!task.startedAt || !task.completedAt)
433
+ return 'N/A';
434
+ const ms = task.completedAt - task.startedAt;
435
+ return `${(ms / 1000).toFixed(1)}s`;
436
+ }
437
+ sleep(ms) {
438
+ return new Promise(resolve => setTimeout(resolve, ms));
439
+ }
440
+ }
441
+ // 싱글톤 인스턴스
442
+ export const backgroundManager = new BackgroundManagerImpl();
443
+ // 편의 함수
444
+ export function launch(args) {
445
+ return backgroundManager.launch(args);
446
+ }
447
+ export function poll(taskId) {
448
+ return backgroundManager.poll(taskId);
449
+ }
450
+ export function cancel(taskId) {
451
+ return backgroundManager.cancel(taskId);
452
+ }
453
+ export function getStats() {
454
+ return backgroundManager.getStats();
455
+ }
456
+ //# sourceMappingURL=BackgroundManager.js.map