@yuaone/core 0.1.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.
- package/LICENSE +663 -0
- package/README.md +15 -0
- package/dist/__tests__/context-manager.test.d.ts +6 -0
- package/dist/__tests__/context-manager.test.d.ts.map +1 -0
- package/dist/__tests__/context-manager.test.js +220 -0
- package/dist/__tests__/context-manager.test.js.map +1 -0
- package/dist/__tests__/governor.test.d.ts +6 -0
- package/dist/__tests__/governor.test.d.ts.map +1 -0
- package/dist/__tests__/governor.test.js +210 -0
- package/dist/__tests__/governor.test.js.map +1 -0
- package/dist/__tests__/model-router.test.d.ts +6 -0
- package/dist/__tests__/model-router.test.d.ts.map +1 -0
- package/dist/__tests__/model-router.test.js +329 -0
- package/dist/__tests__/model-router.test.js.map +1 -0
- package/dist/agent-logger.d.ts +384 -0
- package/dist/agent-logger.d.ts.map +1 -0
- package/dist/agent-logger.js +820 -0
- package/dist/agent-logger.js.map +1 -0
- package/dist/agent-loop.d.ts +163 -0
- package/dist/agent-loop.d.ts.map +1 -0
- package/dist/agent-loop.js +609 -0
- package/dist/agent-loop.js.map +1 -0
- package/dist/agent-modes.d.ts +85 -0
- package/dist/agent-modes.d.ts.map +1 -0
- package/dist/agent-modes.js +418 -0
- package/dist/agent-modes.js.map +1 -0
- package/dist/approval.d.ts +137 -0
- package/dist/approval.d.ts.map +1 -0
- package/dist/approval.js +299 -0
- package/dist/approval.js.map +1 -0
- package/dist/async-completion-queue.d.ts +56 -0
- package/dist/async-completion-queue.d.ts.map +1 -0
- package/dist/async-completion-queue.js +77 -0
- package/dist/async-completion-queue.js.map +1 -0
- package/dist/auto-fix.d.ts +174 -0
- package/dist/auto-fix.d.ts.map +1 -0
- package/dist/auto-fix.js +319 -0
- package/dist/auto-fix.js.map +1 -0
- package/dist/codebase-context.d.ts +396 -0
- package/dist/codebase-context.d.ts.map +1 -0
- package/dist/codebase-context.js +1260 -0
- package/dist/codebase-context.js.map +1 -0
- package/dist/conflict-resolver.d.ts +191 -0
- package/dist/conflict-resolver.d.ts.map +1 -0
- package/dist/conflict-resolver.js +524 -0
- package/dist/conflict-resolver.js.map +1 -0
- package/dist/constants.d.ts +52 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +141 -0
- package/dist/constants.js.map +1 -0
- package/dist/context-budget.d.ts +435 -0
- package/dist/context-budget.d.ts.map +1 -0
- package/dist/context-budget.js +903 -0
- package/dist/context-budget.js.map +1 -0
- package/dist/context-compressor.d.ts +143 -0
- package/dist/context-compressor.d.ts.map +1 -0
- package/dist/context-compressor.js +511 -0
- package/dist/context-compressor.js.map +1 -0
- package/dist/context-manager.d.ts +112 -0
- package/dist/context-manager.d.ts.map +1 -0
- package/dist/context-manager.js +247 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/continuous-reflection.d.ts +267 -0
- package/dist/continuous-reflection.d.ts.map +1 -0
- package/dist/continuous-reflection.js +338 -0
- package/dist/continuous-reflection.js.map +1 -0
- package/dist/cross-file-refactor.d.ts +352 -0
- package/dist/cross-file-refactor.d.ts.map +1 -0
- package/dist/cross-file-refactor.js +1544 -0
- package/dist/cross-file-refactor.js.map +1 -0
- package/dist/dag-orchestrator.d.ts +138 -0
- package/dist/dag-orchestrator.d.ts.map +1 -0
- package/dist/dag-orchestrator.js +379 -0
- package/dist/dag-orchestrator.js.map +1 -0
- package/dist/debate-orchestrator.d.ts +301 -0
- package/dist/debate-orchestrator.d.ts.map +1 -0
- package/dist/debate-orchestrator.js +719 -0
- package/dist/debate-orchestrator.js.map +1 -0
- package/dist/dependency-analyzer.d.ts +113 -0
- package/dist/dependency-analyzer.d.ts.map +1 -0
- package/dist/dependency-analyzer.js +444 -0
- package/dist/dependency-analyzer.js.map +1 -0
- package/dist/design-loop.d.ts +59 -0
- package/dist/design-loop.d.ts.map +1 -0
- package/dist/design-loop.js +344 -0
- package/dist/design-loop.js.map +1 -0
- package/dist/doc-intelligence.d.ts +383 -0
- package/dist/doc-intelligence.d.ts.map +1 -0
- package/dist/doc-intelligence.js +1307 -0
- package/dist/doc-intelligence.js.map +1 -0
- package/dist/dynamic-role-generator.d.ts +76 -0
- package/dist/dynamic-role-generator.d.ts.map +1 -0
- package/dist/dynamic-role-generator.js +194 -0
- package/dist/dynamic-role-generator.js.map +1 -0
- package/dist/errors.d.ts +69 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +102 -0
- package/dist/errors.js.map +1 -0
- package/dist/event-bus.d.ts +159 -0
- package/dist/event-bus.d.ts.map +1 -0
- package/dist/event-bus.js +305 -0
- package/dist/event-bus.js.map +1 -0
- package/dist/execution-engine.d.ts +425 -0
- package/dist/execution-engine.d.ts.map +1 -0
- package/dist/execution-engine.js +1555 -0
- package/dist/execution-engine.js.map +1 -0
- package/dist/git-intelligence.d.ts +306 -0
- package/dist/git-intelligence.d.ts.map +1 -0
- package/dist/git-intelligence.js +1099 -0
- package/dist/git-intelligence.js.map +1 -0
- package/dist/governor.d.ts +77 -0
- package/dist/governor.d.ts.map +1 -0
- package/dist/governor.js +161 -0
- package/dist/governor.js.map +1 -0
- package/dist/hierarchical-planner.d.ts +313 -0
- package/dist/hierarchical-planner.d.ts.map +1 -0
- package/dist/hierarchical-planner.js +981 -0
- package/dist/hierarchical-planner.js.map +1 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +123 -0
- package/dist/index.js.map +1 -0
- package/dist/intent-inference.d.ts +103 -0
- package/dist/intent-inference.d.ts.map +1 -0
- package/dist/intent-inference.js +605 -0
- package/dist/intent-inference.js.map +1 -0
- package/dist/interrupt-manager.d.ts +143 -0
- package/dist/interrupt-manager.d.ts.map +1 -0
- package/dist/interrupt-manager.js +196 -0
- package/dist/interrupt-manager.js.map +1 -0
- package/dist/kernel.d.ts +564 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +1419 -0
- package/dist/kernel.js.map +1 -0
- package/dist/language-support.d.ts +232 -0
- package/dist/language-support.d.ts.map +1 -0
- package/dist/language-support.js +1134 -0
- package/dist/language-support.js.map +1 -0
- package/dist/llm-client.d.ts +82 -0
- package/dist/llm-client.d.ts.map +1 -0
- package/dist/llm-client.js +475 -0
- package/dist/llm-client.js.map +1 -0
- package/dist/mcp-client.d.ts +232 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +718 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/memory-manager.d.ts +200 -0
- package/dist/memory-manager.d.ts.map +1 -0
- package/dist/memory-manager.js +568 -0
- package/dist/memory-manager.js.map +1 -0
- package/dist/memory.d.ts +87 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +341 -0
- package/dist/memory.js.map +1 -0
- package/dist/model-router.d.ts +245 -0
- package/dist/model-router.d.ts.map +1 -0
- package/dist/model-router.js +632 -0
- package/dist/model-router.js.map +1 -0
- package/dist/parallel-executor.d.ts +125 -0
- package/dist/parallel-executor.d.ts.map +1 -0
- package/dist/parallel-executor.js +201 -0
- package/dist/parallel-executor.js.map +1 -0
- package/dist/perf-optimizer.d.ts +212 -0
- package/dist/perf-optimizer.d.ts.map +1 -0
- package/dist/perf-optimizer.js +721 -0
- package/dist/perf-optimizer.js.map +1 -0
- package/dist/persona.d.ts +305 -0
- package/dist/persona.d.ts.map +1 -0
- package/dist/persona.js +887 -0
- package/dist/persona.js.map +1 -0
- package/dist/planner.d.ts +70 -0
- package/dist/planner.d.ts.map +1 -0
- package/dist/planner.js +264 -0
- package/dist/planner.js.map +1 -0
- package/dist/qa-pipeline.d.ts +365 -0
- package/dist/qa-pipeline.d.ts.map +1 -0
- package/dist/qa-pipeline.js +1352 -0
- package/dist/qa-pipeline.js.map +1 -0
- package/dist/reasoning-adapter.d.ts +116 -0
- package/dist/reasoning-adapter.d.ts.map +1 -0
- package/dist/reasoning-adapter.js +187 -0
- package/dist/reasoning-adapter.js.map +1 -0
- package/dist/role-registry.d.ts +55 -0
- package/dist/role-registry.d.ts.map +1 -0
- package/dist/role-registry.js +192 -0
- package/dist/role-registry.js.map +1 -0
- package/dist/sandbox-tiers.d.ts +327 -0
- package/dist/sandbox-tiers.d.ts.map +1 -0
- package/dist/sandbox-tiers.js +928 -0
- package/dist/sandbox-tiers.js.map +1 -0
- package/dist/security-scanner.d.ts +222 -0
- package/dist/security-scanner.d.ts.map +1 -0
- package/dist/security-scanner.js +1129 -0
- package/dist/security-scanner.js.map +1 -0
- package/dist/security.d.ts +93 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +393 -0
- package/dist/security.js.map +1 -0
- package/dist/self-reflection.d.ts +397 -0
- package/dist/self-reflection.d.ts.map +1 -0
- package/dist/self-reflection.js +908 -0
- package/dist/self-reflection.js.map +1 -0
- package/dist/session-persistence.d.ts +191 -0
- package/dist/session-persistence.d.ts.map +1 -0
- package/dist/session-persistence.js +395 -0
- package/dist/session-persistence.js.map +1 -0
- package/dist/speculative-executor.d.ts +210 -0
- package/dist/speculative-executor.d.ts.map +1 -0
- package/dist/speculative-executor.js +618 -0
- package/dist/speculative-executor.js.map +1 -0
- package/dist/state-machine.d.ts +289 -0
- package/dist/state-machine.d.ts.map +1 -0
- package/dist/state-machine.js +695 -0
- package/dist/state-machine.js.map +1 -0
- package/dist/sub-agent.d.ts +177 -0
- package/dist/sub-agent.d.ts.map +1 -0
- package/dist/sub-agent.js +303 -0
- package/dist/sub-agent.js.map +1 -0
- package/dist/system-prompt.d.ts +26 -0
- package/dist/system-prompt.d.ts.map +1 -0
- package/dist/system-prompt.js +84 -0
- package/dist/system-prompt.js.map +1 -0
- package/dist/test-intelligence.d.ts +439 -0
- package/dist/test-intelligence.d.ts.map +1 -0
- package/dist/test-intelligence.js +1165 -0
- package/dist/test-intelligence.js.map +1 -0
- package/dist/types.d.ts +632 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/vector-index.d.ts +314 -0
- package/dist/vector-index.d.ts.map +1 -0
- package/dist/vector-index.js +618 -0
- package/dist/vector-index.js.map +1 -0
- package/package.json +41 -0
package/dist/approval.js
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module approval
|
|
3
|
+
* @description 승인 시스템 — 위험 작업 실행 전 사용자 승인 요청/대기.
|
|
4
|
+
*
|
|
5
|
+
* 플로우:
|
|
6
|
+
* 1. Governor가 위험 작업 감지 (ApprovalRequiredError)
|
|
7
|
+
* 2. ApprovalManager가 승인 요청 이벤트 emit
|
|
8
|
+
* 3. CLI/UI에서 사용자에게 프롬프트 표시
|
|
9
|
+
* 4. 사용자 응답 (approve/reject/always_approve)
|
|
10
|
+
* 5. 결과를 Agent Loop에 반환
|
|
11
|
+
*
|
|
12
|
+
* @see 설계 문서 Section 6.3
|
|
13
|
+
*/
|
|
14
|
+
import { EventEmitter } from "node:events";
|
|
15
|
+
// ─── Constants ───
|
|
16
|
+
/** 항상 승인이 필요한 액션 (기본값) */
|
|
17
|
+
const ALWAYS_REQUIRE_APPROVAL = [
|
|
18
|
+
"DELETE_FILE",
|
|
19
|
+
"GIT_PUSH",
|
|
20
|
+
"CREATE_PR",
|
|
21
|
+
];
|
|
22
|
+
/** 도구별 승인 규칙 */
|
|
23
|
+
const TOOL_APPROVAL_RULES = [
|
|
24
|
+
{
|
|
25
|
+
toolName: "file_write",
|
|
26
|
+
actionType: "OVERWRITE_FILE",
|
|
27
|
+
riskLevel: "medium",
|
|
28
|
+
// 기존 파일 덮어쓰기일 때만 (새 파일 생성은 승인 불필요)
|
|
29
|
+
condition: (args) => args.overwrite === true,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
toolName: "shell_exec",
|
|
33
|
+
actionType: "INSTALL_PACKAGE",
|
|
34
|
+
riskLevel: "medium",
|
|
35
|
+
condition: (args) => {
|
|
36
|
+
const cmd = String(args.command ?? args.cmd ?? "");
|
|
37
|
+
const exec = String(args.executable ?? "");
|
|
38
|
+
const full = `${exec} ${cmd}`.trim();
|
|
39
|
+
return (/\bnpm\s+install\b/.test(full) ||
|
|
40
|
+
/\bpnpm\s+add\b/.test(full) ||
|
|
41
|
+
/\byarn\s+add\b/.test(full) ||
|
|
42
|
+
/\bpip\s+install\b/.test(full));
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
toolName: "shell_exec",
|
|
47
|
+
actionType: "RUN_DANGEROUS_CMD",
|
|
48
|
+
riskLevel: "high",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
toolName: "file_write",
|
|
52
|
+
actionType: "MODIFY_CONFIG",
|
|
53
|
+
riskLevel: "medium",
|
|
54
|
+
condition: (args) => {
|
|
55
|
+
const path = String(args.path ?? args.file ?? "");
|
|
56
|
+
return /(?:tsconfig|package|\.eslintrc|\.prettierrc|webpack|vite)/.test(path);
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
toolName: "file_edit",
|
|
61
|
+
actionType: "MODIFY_CONFIG",
|
|
62
|
+
riskLevel: "medium",
|
|
63
|
+
condition: (args) => {
|
|
64
|
+
const path = String(args.path ?? args.file ?? "");
|
|
65
|
+
return /(?:tsconfig|package|\.eslintrc|\.prettierrc|webpack|vite)/.test(path);
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
toolName: "git_ops",
|
|
70
|
+
actionType: "GIT_PUSH",
|
|
71
|
+
riskLevel: "critical",
|
|
72
|
+
condition: (args) => {
|
|
73
|
+
const op = String(args.operation ?? args.op ?? "");
|
|
74
|
+
return op === "push";
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
// ─── ApprovalManager ───
|
|
79
|
+
/**
|
|
80
|
+
* ApprovalManager — 위험 작업의 승인 프로세스를 관리.
|
|
81
|
+
*
|
|
82
|
+
* 역할:
|
|
83
|
+
* - 도구 호출이 승인 필요한지 판단
|
|
84
|
+
* - 승인 요청 생성 및 핸들러 호출
|
|
85
|
+
* - always_approve 세션 캐시 관리
|
|
86
|
+
* - 승인 타임아웃 처리
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const manager = new ApprovalManager();
|
|
91
|
+
*
|
|
92
|
+
* // CLI에서 핸들러 등록
|
|
93
|
+
* manager.setHandler(async (request) => {
|
|
94
|
+
* const answer = await askUser(`Approve ${request.reason}? [Y/n/a]`);
|
|
95
|
+
* if (answer === 'a') return 'always_approve';
|
|
96
|
+
* return answer === 'n' ? 'reject' : 'approve';
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* // Agent Loop에서 사용
|
|
100
|
+
* if (manager.needsApproval('file_write', args)) {
|
|
101
|
+
* const response = await manager.requestApproval(request);
|
|
102
|
+
* if (response === 'reject') { ... }
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export class ApprovalManager extends EventEmitter {
|
|
107
|
+
/** always_approve로 승인된 도구 (세션 내 유지) */
|
|
108
|
+
alwaysApproved = new Set();
|
|
109
|
+
/** 자동 승인 설정 */
|
|
110
|
+
autoApproveActions;
|
|
111
|
+
/** 항상 승인 필요한 액션 */
|
|
112
|
+
requireApprovalActions;
|
|
113
|
+
/** 승인 핸들러 (CLI/UI가 등록) */
|
|
114
|
+
handler = null;
|
|
115
|
+
/** 기본 타임아웃 (ms) */
|
|
116
|
+
defaultTimeout;
|
|
117
|
+
constructor(config, defaultTimeout = 120_000) {
|
|
118
|
+
super();
|
|
119
|
+
this.autoApproveActions = new Set(config?.autoApprove ?? []);
|
|
120
|
+
this.requireApprovalActions = new Set(config?.requireApproval ?? ALWAYS_REQUIRE_APPROVAL);
|
|
121
|
+
this.defaultTimeout = defaultTimeout;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* 승인 핸들러 등록.
|
|
125
|
+
* CLI에서 readline 기반 프롬프트, UI에서 웹소켓 기반 프롬프트를 구현한다.
|
|
126
|
+
* @param handler 승인 요청을 처리할 함수
|
|
127
|
+
*/
|
|
128
|
+
setHandler(handler) {
|
|
129
|
+
this.handler = handler;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 도구 호출이 승인 필요한지 판단.
|
|
133
|
+
* @param toolName 도구 이름
|
|
134
|
+
* @param args 도구 인자
|
|
135
|
+
* @returns 승인이 필요하면 해당 ApprovalRequest 정보, 불필요하면 null
|
|
136
|
+
*/
|
|
137
|
+
checkApproval(toolName, args) {
|
|
138
|
+
// always_approve된 도구는 스킵
|
|
139
|
+
const toolKey = this.buildToolKey(toolName, args);
|
|
140
|
+
if (this.alwaysApproved.has(toolName) || this.alwaysApproved.has(toolKey)) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
// 승인 규칙 매칭
|
|
144
|
+
for (const rule of TOOL_APPROVAL_RULES) {
|
|
145
|
+
if (rule.toolName !== toolName)
|
|
146
|
+
continue;
|
|
147
|
+
// 조건이 있으면 평가
|
|
148
|
+
if (rule.condition && !rule.condition(args))
|
|
149
|
+
continue;
|
|
150
|
+
// 자동 승인 액션이면 스킵
|
|
151
|
+
if (this.autoApproveActions.has(rule.actionType) &&
|
|
152
|
+
!this.requireApprovalActions.has(rule.actionType)) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
// 승인 필요
|
|
156
|
+
const request = {
|
|
157
|
+
id: crypto.randomUUID(),
|
|
158
|
+
toolName,
|
|
159
|
+
arguments: args,
|
|
160
|
+
riskLevel: rule.riskLevel,
|
|
161
|
+
reason: this.buildReason(rule.actionType, toolName, args),
|
|
162
|
+
diff: this.extractDiff(toolName, args),
|
|
163
|
+
timeout: this.defaultTimeout,
|
|
164
|
+
};
|
|
165
|
+
return request;
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 승인 필요 여부를 간단히 확인하는 편의 메서드.
|
|
171
|
+
* @param toolName 도구 이름
|
|
172
|
+
* @param args 도구 인자
|
|
173
|
+
* @returns 승인이 필요하면 true
|
|
174
|
+
*/
|
|
175
|
+
needsApproval(toolName, args) {
|
|
176
|
+
return this.checkApproval(toolName, args) !== null;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* 승인 요청을 핸들러에 전달하고 응답을 반환.
|
|
180
|
+
* 핸들러가 없으면 기본적으로 reject.
|
|
181
|
+
* @param request 승인 요청
|
|
182
|
+
* @returns 승인 응답
|
|
183
|
+
*/
|
|
184
|
+
async requestApproval(request) {
|
|
185
|
+
this.emit("approval:requested", request);
|
|
186
|
+
if (!this.handler) {
|
|
187
|
+
// 핸들러 미등록 → reject (안전 기본값)
|
|
188
|
+
this.emit("approval:no_handler", request);
|
|
189
|
+
return "reject";
|
|
190
|
+
}
|
|
191
|
+
// 타임아웃 처리 — clear timer after race resolves to prevent leak
|
|
192
|
+
let timer;
|
|
193
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
194
|
+
timer = setTimeout(() => {
|
|
195
|
+
this.emit("approval:timeout", request.id);
|
|
196
|
+
resolve("reject");
|
|
197
|
+
}, request.timeout);
|
|
198
|
+
});
|
|
199
|
+
const response = await Promise.race([
|
|
200
|
+
this.handler(request),
|
|
201
|
+
timeoutPromise,
|
|
202
|
+
]);
|
|
203
|
+
clearTimeout(timer);
|
|
204
|
+
// always_approve 처리
|
|
205
|
+
if (response === "always_approve") {
|
|
206
|
+
this.addAlwaysApprove(request.toolName);
|
|
207
|
+
this.emit("approval:always_approved", request.toolName);
|
|
208
|
+
}
|
|
209
|
+
this.emit("approval:responded", { request, response });
|
|
210
|
+
return response;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* 도구를 always_approve 목록에 추가.
|
|
214
|
+
* 세션 내에서 해당 도구의 모든 호출이 자동 승인된다.
|
|
215
|
+
* @param toolName 도구 이름
|
|
216
|
+
*/
|
|
217
|
+
addAlwaysApprove(toolName) {
|
|
218
|
+
this.alwaysApproved.add(toolName);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* always_approve 목록을 초기화.
|
|
222
|
+
*/
|
|
223
|
+
clearAlwaysApproved() {
|
|
224
|
+
this.alwaysApproved.clear();
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* 현재 always_approve 목록을 반환.
|
|
228
|
+
*/
|
|
229
|
+
getAlwaysApproved() {
|
|
230
|
+
return this.alwaysApproved;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* ToolCall에서 PendingAction을 생성하는 헬퍼.
|
|
234
|
+
* AgentLoop에서 agent:approval_needed 이벤트 emit에 사용.
|
|
235
|
+
*/
|
|
236
|
+
buildPendingAction(toolCall, request) {
|
|
237
|
+
return {
|
|
238
|
+
id: request.id,
|
|
239
|
+
type: this.resolveActionType(request.toolName, request.arguments),
|
|
240
|
+
description: request.reason,
|
|
241
|
+
details: request.arguments,
|
|
242
|
+
risk: request.riskLevel === "critical" ? "high" : request.riskLevel,
|
|
243
|
+
timeout: request.timeout,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
// ─── Private ───
|
|
247
|
+
buildToolKey(toolName, args) {
|
|
248
|
+
const path = String(args.path ?? args.file ?? "");
|
|
249
|
+
return path ? `${toolName}:${path}` : toolName;
|
|
250
|
+
}
|
|
251
|
+
buildReason(actionType, toolName, args) {
|
|
252
|
+
const path = String(args.path ?? args.file ?? "");
|
|
253
|
+
switch (actionType) {
|
|
254
|
+
case "DELETE_FILE":
|
|
255
|
+
return `File deletion: ${path}`;
|
|
256
|
+
case "OVERWRITE_FILE":
|
|
257
|
+
return `File overwrite: ${path}`;
|
|
258
|
+
case "INSTALL_PACKAGE": {
|
|
259
|
+
const cmd = String(args.command ?? args.cmd ?? "");
|
|
260
|
+
return `Package installation: ${cmd}`;
|
|
261
|
+
}
|
|
262
|
+
case "RUN_DANGEROUS_CMD": {
|
|
263
|
+
const cmd = String(args.command ?? args.cmd ?? "");
|
|
264
|
+
return `Dangerous command: ${cmd}`;
|
|
265
|
+
}
|
|
266
|
+
case "MODIFY_CONFIG":
|
|
267
|
+
return `Config file modification: ${path}`;
|
|
268
|
+
case "GIT_PUSH":
|
|
269
|
+
return "Git push to remote";
|
|
270
|
+
case "CREATE_PR":
|
|
271
|
+
return "Pull request creation";
|
|
272
|
+
default:
|
|
273
|
+
return `${toolName} requires approval`;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
extractDiff(toolName, args) {
|
|
277
|
+
if (toolName === "file_write") {
|
|
278
|
+
const content = String(args.content ?? "");
|
|
279
|
+
return content.length > 500 ? content.slice(0, 500) + "\n..." : content;
|
|
280
|
+
}
|
|
281
|
+
if (toolName === "file_edit") {
|
|
282
|
+
const old = String(args.old_string ?? args.old ?? "");
|
|
283
|
+
const newStr = String(args.new_string ?? args.new ?? "");
|
|
284
|
+
return `--- old\n${old}\n+++ new\n${newStr}`;
|
|
285
|
+
}
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
resolveActionType(toolName, args) {
|
|
289
|
+
for (const rule of TOOL_APPROVAL_RULES) {
|
|
290
|
+
if (rule.toolName !== toolName)
|
|
291
|
+
continue;
|
|
292
|
+
if (rule.condition && !rule.condition(args))
|
|
293
|
+
continue;
|
|
294
|
+
return rule.actionType;
|
|
295
|
+
}
|
|
296
|
+
return "RUN_DANGEROUS_CMD";
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.js","sourceRoot":"","sources":["../src/approval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module async-completion-queue
|
|
3
|
+
* @description 비동기 완료 큐 — 병렬 에이전트 완료 이벤트 수집용.
|
|
4
|
+
*
|
|
5
|
+
* 생산자(push)와 소비자(shift)를 비동기로 연결하는 제네릭 큐.
|
|
6
|
+
* 버퍼에 아이템이 있으면 즉시 반환, 없으면 push될 때까지 대기.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* 병렬 에이전트 완료 이벤트를 수집하는 비동기 큐.
|
|
10
|
+
*
|
|
11
|
+
* @typeParam T - 큐에 저장할 아이템 타입
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const queue = new AsyncCompletionQueue<TaskResult>();
|
|
16
|
+
*
|
|
17
|
+
* // Producer
|
|
18
|
+
* queue.push(result);
|
|
19
|
+
*
|
|
20
|
+
* // Consumer (awaits if buffer is empty)
|
|
21
|
+
* const item = await queue.shift();
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class AsyncCompletionQueue<T> {
|
|
25
|
+
private buffer;
|
|
26
|
+
private waiters;
|
|
27
|
+
/**
|
|
28
|
+
* 아이템을 큐에 추가한다.
|
|
29
|
+
* 대기 중인 소비자가 있으면 즉시 전달하고, 없으면 버퍼에 저장한다.
|
|
30
|
+
*
|
|
31
|
+
* @param item - 큐에 추가할 아이템
|
|
32
|
+
*/
|
|
33
|
+
push(item: T): void;
|
|
34
|
+
/**
|
|
35
|
+
* 큐에서 아이템을 하나 꺼낸다.
|
|
36
|
+
* 버퍼에 아이템이 있으면 즉시 반환하고, 없으면 push될 때까지 대기한다.
|
|
37
|
+
*
|
|
38
|
+
* @returns 큐에서 꺼낸 아이템
|
|
39
|
+
*/
|
|
40
|
+
shift(): Promise<T>;
|
|
41
|
+
/**
|
|
42
|
+
* 현재 버퍼에 있는 모든 아이템을 즉시 반환한다 (논블로킹, 동기).
|
|
43
|
+
* 반환 후 버퍼는 비워진다.
|
|
44
|
+
*
|
|
45
|
+
* Note: 의도적으로 동기 메서드입니다. dag-orchestrator의 for...of 루프에서
|
|
46
|
+
* 즉시 반환이 필요하므로 async가 아닌 sync로 유지합니다.
|
|
47
|
+
*
|
|
48
|
+
* @returns 버퍼에 있던 모든 아이템 배열
|
|
49
|
+
*/
|
|
50
|
+
drain(): T[];
|
|
51
|
+
/**
|
|
52
|
+
* 현재 버퍼에 대기 중인 아이템 수.
|
|
53
|
+
*/
|
|
54
|
+
get length(): number;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=async-completion-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-completion-queue.d.ts","sourceRoot":"","sources":["../src/async-completion-queue.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,oBAAoB,CAAC,CAAC;IACjC,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,OAAO,CAAgC;IAE/C;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IASnB;;;;;OAKG;IACG,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC;IAUzB;;;;;;;;OAQG;IACH,KAAK,IAAI,CAAC,EAAE;IAKZ;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module async-completion-queue
|
|
3
|
+
* @description 비동기 완료 큐 — 병렬 에이전트 완료 이벤트 수집용.
|
|
4
|
+
*
|
|
5
|
+
* 생산자(push)와 소비자(shift)를 비동기로 연결하는 제네릭 큐.
|
|
6
|
+
* 버퍼에 아이템이 있으면 즉시 반환, 없으면 push될 때까지 대기.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* 병렬 에이전트 완료 이벤트를 수집하는 비동기 큐.
|
|
10
|
+
*
|
|
11
|
+
* @typeParam T - 큐에 저장할 아이템 타입
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const queue = new AsyncCompletionQueue<TaskResult>();
|
|
16
|
+
*
|
|
17
|
+
* // Producer
|
|
18
|
+
* queue.push(result);
|
|
19
|
+
*
|
|
20
|
+
* // Consumer (awaits if buffer is empty)
|
|
21
|
+
* const item = await queue.shift();
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export class AsyncCompletionQueue {
|
|
25
|
+
buffer = [];
|
|
26
|
+
waiters = [];
|
|
27
|
+
/**
|
|
28
|
+
* 아이템을 큐에 추가한다.
|
|
29
|
+
* 대기 중인 소비자가 있으면 즉시 전달하고, 없으면 버퍼에 저장한다.
|
|
30
|
+
*
|
|
31
|
+
* @param item - 큐에 추가할 아이템
|
|
32
|
+
*/
|
|
33
|
+
push(item) {
|
|
34
|
+
const waiter = this.waiters.shift();
|
|
35
|
+
if (waiter) {
|
|
36
|
+
waiter(item);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.buffer.push(item);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 큐에서 아이템을 하나 꺼낸다.
|
|
44
|
+
* 버퍼에 아이템이 있으면 즉시 반환하고, 없으면 push될 때까지 대기한다.
|
|
45
|
+
*
|
|
46
|
+
* @returns 큐에서 꺼낸 아이템
|
|
47
|
+
*/
|
|
48
|
+
async shift() {
|
|
49
|
+
const item = this.buffer.shift();
|
|
50
|
+
if (item !== undefined) {
|
|
51
|
+
return item;
|
|
52
|
+
}
|
|
53
|
+
return new Promise((resolve) => {
|
|
54
|
+
this.waiters.push(resolve);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 현재 버퍼에 있는 모든 아이템을 즉시 반환한다 (논블로킹, 동기).
|
|
59
|
+
* 반환 후 버퍼는 비워진다.
|
|
60
|
+
*
|
|
61
|
+
* Note: 의도적으로 동기 메서드입니다. dag-orchestrator의 for...of 루프에서
|
|
62
|
+
* 즉시 반환이 필요하므로 async가 아닌 sync로 유지합니다.
|
|
63
|
+
*
|
|
64
|
+
* @returns 버퍼에 있던 모든 아이템 배열
|
|
65
|
+
*/
|
|
66
|
+
drain() {
|
|
67
|
+
const items = this.buffer.splice(0);
|
|
68
|
+
return items;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 현재 버퍼에 대기 중인 아이템 수.
|
|
72
|
+
*/
|
|
73
|
+
get length() {
|
|
74
|
+
return this.buffer.length;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=async-completion-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-completion-queue.js","sourceRoot":"","sources":["../src/async-completion-queue.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,oBAAoB;IACvB,MAAM,GAAQ,EAAE,CAAC;IACjB,OAAO,GAA6B,EAAE,CAAC;IAE/C;;;;;OAKG;IACH,IAAI,CAAC,IAAO;QACV,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACpC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACjC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,EAAE;YAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module auto-fix
|
|
3
|
+
* @description 자동 수정 루프 — 도구 실행 결과를 검증하고, 실패 시 자동 수정 시도.
|
|
4
|
+
*
|
|
5
|
+
* 플로우:
|
|
6
|
+
* 1. 도구 실행 결과 수신
|
|
7
|
+
* 2. 결과 검증 (lint 에러, 빌드 에러, 타입 에러 등)
|
|
8
|
+
* 3. 실패 시 → 에러 메시지를 LLM에 피드백할 프롬프트 생성
|
|
9
|
+
* 4. LLM이 수정 제안 → 도구 재실행
|
|
10
|
+
* 5. 최대 maxRetries 반복 후 포기
|
|
11
|
+
*
|
|
12
|
+
* @see 설계 문서 Section 6.4
|
|
13
|
+
*/
|
|
14
|
+
/** 자동 수정 루프 설정 */
|
|
15
|
+
export interface AutoFixConfig {
|
|
16
|
+
/** 최대 수정 시도 횟수 (기본 3) */
|
|
17
|
+
maxRetries: number;
|
|
18
|
+
/** file_write/edit 후 자동 lint 실행 */
|
|
19
|
+
autoLint: boolean;
|
|
20
|
+
/** 변경 후 자동 테스트 (Phase 1b) */
|
|
21
|
+
autoTest: boolean;
|
|
22
|
+
/** 변경 후 자동 빌드 체크 */
|
|
23
|
+
autoBuild: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** 검증 결과 */
|
|
26
|
+
export interface ValidationResult {
|
|
27
|
+
/** 검증 통과 여부 */
|
|
28
|
+
passed: boolean;
|
|
29
|
+
/** 실패한 검증 항목 */
|
|
30
|
+
failures: ValidationFailure[];
|
|
31
|
+
}
|
|
32
|
+
/** 검증 실패 항목 */
|
|
33
|
+
export interface ValidationFailure {
|
|
34
|
+
/** 검증 종류 */
|
|
35
|
+
type: AutoFixTrigger;
|
|
36
|
+
/** 에러 메시지 */
|
|
37
|
+
message: string;
|
|
38
|
+
/** 관련 파일 경로 */
|
|
39
|
+
file?: string;
|
|
40
|
+
/** 관련 라인 번호 */
|
|
41
|
+
line?: number;
|
|
42
|
+
/** 원본 명령 출력 */
|
|
43
|
+
rawOutput: string;
|
|
44
|
+
}
|
|
45
|
+
/** 자동 수정 트리거 유형 */
|
|
46
|
+
export type AutoFixTrigger = "BUILD_FAIL" | "TEST_FAIL" | "LINT_ERROR" | "RUNTIME_ERROR" | "TYPE_ERROR" | "IMPORT_ERROR";
|
|
47
|
+
/** 수정 시도 기록 */
|
|
48
|
+
export interface FixAttempt {
|
|
49
|
+
/** 시도 번호 (1-based) */
|
|
50
|
+
iteration: number;
|
|
51
|
+
/** 발생한 에러 */
|
|
52
|
+
error: string;
|
|
53
|
+
/** 수정 내용 설명 */
|
|
54
|
+
fix: string;
|
|
55
|
+
/** 수정 성공 여부 */
|
|
56
|
+
success: boolean;
|
|
57
|
+
/** 소요 시간 (ms) */
|
|
58
|
+
durationMs: number;
|
|
59
|
+
}
|
|
60
|
+
/** lint 실행 결과 */
|
|
61
|
+
export interface LintResult {
|
|
62
|
+
/** 성공 여부 */
|
|
63
|
+
passed: boolean;
|
|
64
|
+
/** 에러 수 */
|
|
65
|
+
errorCount: number;
|
|
66
|
+
/** 경고 수 */
|
|
67
|
+
warningCount: number;
|
|
68
|
+
/** 원본 출력 */
|
|
69
|
+
output: string;
|
|
70
|
+
}
|
|
71
|
+
/** 빌드 체크 결과 */
|
|
72
|
+
export interface BuildResult {
|
|
73
|
+
/** 성공 여부 */
|
|
74
|
+
passed: boolean;
|
|
75
|
+
/** 에러 수 */
|
|
76
|
+
errorCount: number;
|
|
77
|
+
/** 원본 출력 */
|
|
78
|
+
output: string;
|
|
79
|
+
}
|
|
80
|
+
/** 기본 자동 수정 설정 */
|
|
81
|
+
export declare const DEFAULT_AUTO_FIX_CONFIG: AutoFixConfig;
|
|
82
|
+
/**
|
|
83
|
+
* AutoFixLoop — 도구 실행 결과를 검증하고 자동 수정 루프를 관리.
|
|
84
|
+
*
|
|
85
|
+
* 이 클래스 자체는 LLM을 호출하지 않는다.
|
|
86
|
+
* 검증 실패 시 LLM에 피드백할 프롬프트를 생성하고,
|
|
87
|
+
* AgentLoop이 해당 프롬프트를 LLM에 전달하여 수정 도구 호출을 받는다.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const autoFix = new AutoFixLoop({ maxRetries: 3, autoLint: true, autoBuild: true, autoTest: false });
|
|
92
|
+
*
|
|
93
|
+
* // 도구 실행 후 검증
|
|
94
|
+
* const validation = await autoFix.validateResult('file_write', result, '/project');
|
|
95
|
+
* if (!validation.passed) {
|
|
96
|
+
* const fixPrompt = autoFix.buildFixPrompt(
|
|
97
|
+
* validation.failures[0].message,
|
|
98
|
+
* 'Writing component file'
|
|
99
|
+
* );
|
|
100
|
+
* // fixPrompt를 LLM에 전달 → 수정 도구 호출 수신
|
|
101
|
+
* }
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export declare class AutoFixLoop {
|
|
105
|
+
private readonly config;
|
|
106
|
+
private readonly attempts;
|
|
107
|
+
constructor(config?: Partial<AutoFixConfig>);
|
|
108
|
+
/**
|
|
109
|
+
* 도구 실행 결과를 검증.
|
|
110
|
+
* file_write/file_edit 후에는 lint/빌드 체크를 자동 실행한다.
|
|
111
|
+
*
|
|
112
|
+
* @param toolName 실행된 도구 이름
|
|
113
|
+
* @param toolOutput 도구 실행 결과 출력
|
|
114
|
+
* @param success 도구 실행 성공 여부
|
|
115
|
+
* @param workDir 프로젝트 루트 경로
|
|
116
|
+
* @returns 검증 결과
|
|
117
|
+
*/
|
|
118
|
+
validateResult(toolName: string, toolOutput: string, success: boolean, workDir: string): Promise<ValidationResult>;
|
|
119
|
+
/**
|
|
120
|
+
* 실패 시 LLM에 피드백할 수정 프롬프트를 생성.
|
|
121
|
+
*
|
|
122
|
+
* @param error 에러 메시지
|
|
123
|
+
* @param context 현재 작업 컨텍스트
|
|
124
|
+
* @returns LLM에 전달할 프롬프트 문자열
|
|
125
|
+
*/
|
|
126
|
+
buildFixPrompt(error: string, context: string): string;
|
|
127
|
+
/**
|
|
128
|
+
* 수정 시도를 기록.
|
|
129
|
+
* @param error 에러 메시지
|
|
130
|
+
* @param fix 수정 내용 설명
|
|
131
|
+
* @param success 수정 성공 여부
|
|
132
|
+
* @param durationMs 소요 시간
|
|
133
|
+
*/
|
|
134
|
+
recordAttempt(error: string, fix: string, success: boolean, durationMs: number): void;
|
|
135
|
+
/**
|
|
136
|
+
* 남은 수정 시도 횟수를 반환.
|
|
137
|
+
*/
|
|
138
|
+
getRemainingRetries(): number;
|
|
139
|
+
/**
|
|
140
|
+
* 수정 시도를 더 할 수 있는지 반환.
|
|
141
|
+
*/
|
|
142
|
+
canRetry(): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* 수정 시도 기록을 반환.
|
|
145
|
+
*/
|
|
146
|
+
getAttempts(): readonly FixAttempt[];
|
|
147
|
+
/**
|
|
148
|
+
* 수정 시도 기록을 초기화 (새 도구 호출 시작 시).
|
|
149
|
+
*/
|
|
150
|
+
resetAttempts(): void;
|
|
151
|
+
/**
|
|
152
|
+
* 현재 설정을 반환.
|
|
153
|
+
*/
|
|
154
|
+
getConfig(): Readonly<AutoFixConfig>;
|
|
155
|
+
/**
|
|
156
|
+
* 프로젝트에서 lint를 실행.
|
|
157
|
+
* 순서: eslint → npx tsc --noEmit (lint 대체)
|
|
158
|
+
* @param workDir 프로젝트 루트 경로
|
|
159
|
+
*/
|
|
160
|
+
runLint(workDir: string): Promise<LintResult>;
|
|
161
|
+
/**
|
|
162
|
+
* 프로젝트에서 빌드 체크 (tsc --noEmit) 를 실행.
|
|
163
|
+
* @param workDir 프로젝트 루트 경로
|
|
164
|
+
*/
|
|
165
|
+
runBuildCheck(workDir: string): Promise<BuildResult>;
|
|
166
|
+
private runTscCheck;
|
|
167
|
+
private classifyError;
|
|
168
|
+
private isBuildTypeError;
|
|
169
|
+
private detectShellErrors;
|
|
170
|
+
private truncateOutput;
|
|
171
|
+
private fileExists;
|
|
172
|
+
private exec;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=auto-fix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-fix.d.ts","sourceRoot":"","sources":["../src/auto-fix.ts"],"names":[],"mappings":"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"}
|