@ccdd/project 2.0.1

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 (163) hide show
  1. package/README.md +25 -0
  2. package/dist/monitor-ui/assets/GraphView-CYMJ1Nb7.css +1 -0
  3. package/dist/monitor-ui/assets/GraphView-UjtW4QRC.js +27 -0
  4. package/dist/monitor-ui/assets/ValidationView-CC1FvqUl.js +1 -0
  5. package/dist/monitor-ui/assets/ValidationView-DWl4b8Ug.css +1 -0
  6. package/dist/monitor-ui/assets/_plugin-vue_export-helper-BDNMzG2s.js +1 -0
  7. package/dist/monitor-ui/assets/elk-api-yRi2AOS6.js +1 -0
  8. package/dist/monitor-ui/assets/elk.bundled-CtLobQTy.js +24 -0
  9. package/dist/monitor-ui/assets/graph-layout-worker-CgfWoa9t.js +22 -0
  10. package/dist/monitor-ui/assets/index-CUzg-dht.css +1 -0
  11. package/dist/monitor-ui/assets/index-Cpm0fC0p.js +8 -0
  12. package/dist/monitor-ui/index.html +15 -0
  13. package/dist/scripts/prepare-demo.d.ts +26 -0
  14. package/dist/scripts/prepare-demo.js +121 -0
  15. package/dist/scripts/prepare-demo.js.map +1 -0
  16. package/dist/src/artifacts/groups.d.ts +9 -0
  17. package/dist/src/artifacts/groups.js +77 -0
  18. package/dist/src/artifacts/groups.js.map +1 -0
  19. package/dist/src/artifacts/human.d.ts +38 -0
  20. package/dist/src/artifacts/human.js +156 -0
  21. package/dist/src/artifacts/human.js.map +1 -0
  22. package/dist/src/artifacts/index.d.ts +149 -0
  23. package/dist/src/artifacts/index.js +354 -0
  24. package/dist/src/artifacts/index.js.map +1 -0
  25. package/dist/src/artifacts/instruction.d.ts +23 -0
  26. package/dist/src/artifacts/instruction.js +94 -0
  27. package/dist/src/artifacts/instruction.js.map +1 -0
  28. package/dist/src/artifacts/mcp-server.d.ts +6 -0
  29. package/dist/src/artifacts/mcp-server.js +96 -0
  30. package/dist/src/artifacts/mcp-server.js.map +1 -0
  31. package/dist/src/artifacts/tool-check.d.ts +40 -0
  32. package/dist/src/artifacts/tool-check.js +113 -0
  33. package/dist/src/artifacts/tool-check.js.map +1 -0
  34. package/dist/src/artifacts/types.d.ts +43 -0
  35. package/dist/src/artifacts/types.js +97 -0
  36. package/dist/src/artifacts/types.js.map +1 -0
  37. package/dist/src/broker/config.d.ts +11 -0
  38. package/dist/src/broker/config.js +141 -0
  39. package/dist/src/broker/config.js.map +1 -0
  40. package/dist/src/broker/graph.d.ts +69 -0
  41. package/dist/src/broker/graph.js +94 -0
  42. package/dist/src/broker/graph.js.map +1 -0
  43. package/dist/src/broker/index.d.ts +170 -0
  44. package/dist/src/broker/index.js +931 -0
  45. package/dist/src/broker/index.js.map +1 -0
  46. package/dist/src/cli.d.ts +24 -0
  47. package/dist/src/cli.js +340 -0
  48. package/dist/src/cli.js.map +1 -0
  49. package/dist/src/contracts.d.ts +116 -0
  50. package/dist/src/contracts.js +2 -0
  51. package/dist/src/contracts.js.map +1 -0
  52. package/dist/src/definitions.d.ts +53 -0
  53. package/dist/src/definitions.js +2 -0
  54. package/dist/src/definitions.js.map +1 -0
  55. package/dist/src/doctor/index.d.ts +41 -0
  56. package/dist/src/doctor/index.js +189 -0
  57. package/dist/src/doctor/index.js.map +1 -0
  58. package/dist/src/executors/auth.d.ts +16 -0
  59. package/dist/src/executors/auth.js +150 -0
  60. package/dist/src/executors/auth.js.map +1 -0
  61. package/dist/src/executors/errors.d.ts +6 -0
  62. package/dist/src/executors/errors.js +10 -0
  63. package/dist/src/executors/errors.js.map +1 -0
  64. package/dist/src/executors/index.d.ts +20 -0
  65. package/dist/src/executors/index.js +262 -0
  66. package/dist/src/executors/index.js.map +1 -0
  67. package/dist/src/executors/pi.d.ts +32 -0
  68. package/dist/src/executors/pi.js +190 -0
  69. package/dist/src/executors/pi.js.map +1 -0
  70. package/dist/src/executors/process.d.ts +22 -0
  71. package/dist/src/executors/process.js +70 -0
  72. package/dist/src/executors/process.js.map +1 -0
  73. package/dist/src/local.d.ts +13 -0
  74. package/dist/src/local.js +20 -0
  75. package/dist/src/local.js.map +1 -0
  76. package/dist/src/monitor/actions.d.ts +12 -0
  77. package/dist/src/monitor/actions.js +74 -0
  78. package/dist/src/monitor/actions.js.map +1 -0
  79. package/dist/src/monitor/server.d.ts +8 -0
  80. package/dist/src/monitor/server.js +493 -0
  81. package/dist/src/monitor/server.js.map +1 -0
  82. package/dist/src/monitor/store.d.ts +22 -0
  83. package/dist/src/monitor/store.js +517 -0
  84. package/dist/src/monitor/store.js.map +1 -0
  85. package/dist/src/monitor/types.d.ts +143 -0
  86. package/dist/src/monitor/types.js +2 -0
  87. package/dist/src/monitor/types.js.map +1 -0
  88. package/dist/src/monitor/ui/api.d.ts +11 -0
  89. package/dist/src/monitor/ui/api.js +29 -0
  90. package/dist/src/monitor/ui/api.js.map +1 -0
  91. package/dist/src/monitor/ui/critic-presentation.d.ts +11 -0
  92. package/dist/src/monitor/ui/critic-presentation.js +60 -0
  93. package/dist/src/monitor/ui/critic-presentation.js.map +1 -0
  94. package/dist/src/monitor/ui/format.d.ts +9 -0
  95. package/dist/src/monitor/ui/format.js +22 -0
  96. package/dist/src/monitor/ui/format.js.map +1 -0
  97. package/dist/src/monitor/ui/graph-layout.d.ts +43 -0
  98. package/dist/src/monitor/ui/graph-layout.js +191 -0
  99. package/dist/src/monitor/ui/graph-layout.js.map +1 -0
  100. package/dist/src/monitor/ui/tool-content.d.ts +13 -0
  101. package/dist/src/monitor/ui/tool-content.js +22 -0
  102. package/dist/src/monitor/ui/tool-content.js.map +1 -0
  103. package/dist/src/monitor/ui/tool-input.d.ts +23 -0
  104. package/dist/src/monitor/ui/tool-input.js +112 -0
  105. package/dist/src/monitor/ui/tool-input.js.map +1 -0
  106. package/dist/src/project/cli.d.ts +9 -0
  107. package/dist/src/project/cli.js +306 -0
  108. package/dist/src/project/cli.js.map +1 -0
  109. package/dist/src/project/graph.d.ts +4 -0
  110. package/dist/src/project/graph.js +26 -0
  111. package/dist/src/project/graph.js.map +1 -0
  112. package/dist/src/project/identity.d.ts +5 -0
  113. package/dist/src/project/identity.js +87 -0
  114. package/dist/src/project/identity.js.map +1 -0
  115. package/dist/src/project/index.d.ts +19 -0
  116. package/dist/src/project/index.js +26 -0
  117. package/dist/src/project/index.js.map +1 -0
  118. package/dist/src/project/query.d.ts +9 -0
  119. package/dist/src/project/query.js +136 -0
  120. package/dist/src/project/query.js.map +1 -0
  121. package/dist/src/project/store.d.ts +15 -0
  122. package/dist/src/project/store.js +47 -0
  123. package/dist/src/project/store.js.map +1 -0
  124. package/dist/src/project/types.d.ts +106 -0
  125. package/dist/src/project/types.js +2 -0
  126. package/dist/src/project/types.js.map +1 -0
  127. package/dist/src/requester/index.d.ts +16 -0
  128. package/dist/src/requester/index.js +96 -0
  129. package/dist/src/requester/index.js.map +1 -0
  130. package/dist/src/runtime-paths.d.ts +1 -0
  131. package/dist/src/runtime-paths.js +4 -0
  132. package/dist/src/runtime-paths.js.map +1 -0
  133. package/dist/src/sdk.d.ts +9 -0
  134. package/dist/src/sdk.js +3 -0
  135. package/dist/src/sdk.js.map +1 -0
  136. package/dist/src/tools/contracts.d.ts +108 -0
  137. package/dist/src/tools/contracts.js +2 -0
  138. package/dist/src/tools/contracts.js.map +1 -0
  139. package/dist/src/tools/host.d.ts +7 -0
  140. package/dist/src/tools/host.js +98 -0
  141. package/dist/src/tools/host.js.map +1 -0
  142. package/dist/src/tools/paths.d.ts +2 -0
  143. package/dist/src/tools/paths.js +18 -0
  144. package/dist/src/tools/paths.js.map +1 -0
  145. package/dist/src/tools/runner.d.ts +54 -0
  146. package/dist/src/tools/runner.js +194 -0
  147. package/dist/src/tools/runner.js.map +1 -0
  148. package/dist/src/tools/runtime-host.d.ts +1 -0
  149. package/dist/src/tools/runtime-host.js +116 -0
  150. package/dist/src/tools/runtime-host.js.map +1 -0
  151. package/dist/src/tools/schema.d.ts +6 -0
  152. package/dist/src/tools/schema.js +106 -0
  153. package/dist/src/tools/schema.js.map +1 -0
  154. package/dist/src/worker-client.d.ts +27 -0
  155. package/dist/src/worker-client.js +96 -0
  156. package/dist/src/worker-client.js.map +1 -0
  157. package/dist/src/worker.d.ts +1 -0
  158. package/dist/src/worker.js +50 -0
  159. package/dist/src/worker.js.map +1 -0
  160. package/dist/src/workspaces/index.d.ts +33 -0
  161. package/dist/src/workspaces/index.js +394 -0
  162. package/dist/src/workspaces/index.js.map +1 -0
  163. package/package.json +26 -0
@@ -0,0 +1,53 @@
1
+ /** The definition package has no dependency on persistence or review execution. */
2
+ export interface AgentProfile {
3
+ kind: 'agent';
4
+ provider: string;
5
+ model: string;
6
+ reasoning: string;
7
+ timeoutMs?: number;
8
+ }
9
+ export interface HumanProfile {
10
+ kind: 'human';
11
+ }
12
+ export interface RuntimeProfile {
13
+ kind: 'runtime';
14
+ command: string;
15
+ args: string[];
16
+ timeoutMs?: number;
17
+ }
18
+ export type CriticProfile = AgentProfile | HumanProfile | RuntimeProfile;
19
+ export interface ReviewPayload {
20
+ instruction: string;
21
+ [key: string]: unknown;
22
+ }
23
+ export interface CriticDefinition {
24
+ id: string;
25
+ title: string;
26
+ target: string;
27
+ deps: string[];
28
+ profile: CriticProfile;
29
+ payload: ReviewPayload;
30
+ }
31
+ export type StaleStrategy = {
32
+ kind: 'file-hash';
33
+ paths?: string[];
34
+ } | {
35
+ kind: 'always';
36
+ };
37
+ export interface ArtifactDefinition {
38
+ type: string;
39
+ path: string;
40
+ basis?: boolean;
41
+ stale?: StaleStrategy;
42
+ }
43
+ export interface ArtifactGroupDefinition {
44
+ kind: 'group';
45
+ members: string[];
46
+ basis?: boolean;
47
+ stale?: StaleStrategy;
48
+ }
49
+ export type ArtifactEntryDefinition = ArtifactDefinition | ArtifactGroupDefinition;
50
+ export interface ArtifactGroupReference {
51
+ id: string;
52
+ members: string[];
53
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import type { ExecutorRegistry, ExecutionEvent, WorkspaceMode } from '../contracts.js';
2
+ export type DiagnosticScope = {
3
+ kind: 'graph';
4
+ } | {
5
+ kind: 'critic';
6
+ criticId: string;
7
+ };
8
+ export interface DiagnosticCheck {
9
+ id: string;
10
+ status: 'PASS' | 'FAIL' | 'SKIP';
11
+ kind?: string;
12
+ provider?: string;
13
+ model?: string;
14
+ reasoning?: string;
15
+ criticIds?: string[];
16
+ message: string;
17
+ remedy?: string;
18
+ details?: Record<string, unknown>;
19
+ }
20
+ export interface DiagnosticReport {
21
+ ok: boolean;
22
+ status: 'READY' | 'NOT_READY';
23
+ repoId: string;
24
+ mode: WorkspaceMode;
25
+ snapshotHash?: string;
26
+ scope: DiagnosticScope;
27
+ checkedAt: string;
28
+ checks: DiagnosticCheck[];
29
+ }
30
+ export interface DiagnoseProjectOptions {
31
+ repoPath: string;
32
+ repoId?: string;
33
+ mode?: WorkspaceMode;
34
+ stateDir?: string;
35
+ criticId?: string;
36
+ executors: Pick<ExecutorRegistry, 'probe' | 'validateWorkspace'>;
37
+ signal?: AbortSignal;
38
+ onEvent?: (event: ExecutionEvent) => void | Promise<void>;
39
+ }
40
+ /** Ephemeral diagnostics: no broker, review history, verdict, test or notification. */
41
+ export declare function diagnoseProject({ repoPath, repoId, mode, stateDir, criticId, executors, signal, onEvent }: DiagnoseProjectOptions): Promise<DiagnosticReport>;
@@ -0,0 +1,189 @@
1
+ import { mkdtemp, realpath } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join, resolve } from 'node:path';
4
+ import { prepareReviewRequests } from '../requester/index.js';
5
+ import { prepareWorkspace, removeOwnedWorkspaceTree } from '../workspaces/index.js';
6
+ import { createArtifactViewer, createArtifactTools } from '../artifacts/index.js';
7
+ import { createHumanArtifactTools } from '../artifacts/human.js';
8
+ import { createReviewTools } from '../tools/runner.js';
9
+ import { errorCode, errorMessage } from '../executors/errors.js';
10
+ const canonical = (value) => Array.isArray(value) ? value.map(canonical) : value && typeof value === 'object' ? Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, entry]) => [key, canonical(entry)])) : value;
11
+ const scopeFor = (criticId) => criticId === undefined ? { kind: 'graph' } : { kind: 'critic', criticId };
12
+ const bounded = (value) => String(value).slice(0, 2_000);
13
+ const remedyFor = (value) => value && typeof value === 'object' && 'remedy' in value && typeof value.remedy === 'string' ? value.remedy : undefined;
14
+ async function inspectViewers(request, worktreePath, signal, runDir) {
15
+ if (request.configManifest) {
16
+ // Runtime has its own path/startup contract and requires no Agent/Human tools.
17
+ if (request.profile.kind === 'runtime')
18
+ return { toolNames: [], toolsExecuted: false, artifactPathsVerified: true };
19
+ const registry = await createReviewTools({ worktreePath, artifacts: request.artifacts, artifactGroups: request.artifactGroups, artifactTypes: request.artifactTypes, configManifest: request.configManifest, criticId: request.criticId, audience: request.profile.kind, signal, runDir });
20
+ try {
21
+ const checks = await registry.preflight();
22
+ const failed = checks.filter(check => !check.ok);
23
+ if (failed.length)
24
+ throw new Error(failed.map(check => `${check.toolName}: ${check.message}`).join('; '));
25
+ return { toolNames: registry.tools.map(tool => tool.name), checks, toolsExecuted: false, programsLaunched: false };
26
+ }
27
+ finally {
28
+ await registry.close();
29
+ }
30
+ }
31
+ if (request.profile.kind === 'human') {
32
+ const registry = await createHumanArtifactTools({ worktreePath, artifacts: request.artifacts, artifactTypes: request.artifactTypes, signal });
33
+ const checks = await registry.preflight();
34
+ const failed = checks.filter(check => !check.ok);
35
+ if (failed.length)
36
+ throw new Error(failed.map(check => `${check.toolName}: ${check.message}`).join('; '));
37
+ return { toolNames: registry.tools.map(tool => tool.name), checks, programsLaunched: false };
38
+ }
39
+ const viewer = await createArtifactViewer({ worktreePath, artifacts: request.artifacts, artifactTypes: request.artifactTypes, signal });
40
+ const registry = createArtifactTools(viewer, { audience: request.profile.kind === 'runtime' ? 'viewer' : 'agent' });
41
+ const hasTool = (name) => registry.tools.some(tool => tool.name === name);
42
+ let inspectedFiles = 0;
43
+ const inspectFile = async (artifactId, path) => {
44
+ if (!hasTool(`read_${artifactId}`))
45
+ return;
46
+ if (++inspectedFiles > 10_000)
47
+ throw new Error('Artifact viewer readiness check exceeds 10000 files; narrow the Critic artifact scope.');
48
+ await registry.call(`read_${artifactId}`, { ...(path ? { path } : {}), startLine: 1, lineCount: 80 });
49
+ };
50
+ const inspectDirectory = async (artifactId, path = '') => {
51
+ let offset = 0;
52
+ do {
53
+ const listing = hasTool(`list_${artifactId}`)
54
+ ? await registry.call(`list_${artifactId}`, { path, offset })
55
+ : await viewer.list({ artifactId, path, offset });
56
+ for (const entry of listing.entries) {
57
+ if (entry.kind === 'directory')
58
+ await inspectDirectory(artifactId, entry.path);
59
+ else if (entry.kind === 'file')
60
+ await inspectFile(artifactId, entry.path);
61
+ else
62
+ throw new Error(`Unsupported artifact entry: ${entry.path}`);
63
+ }
64
+ offset = listing.nextOffset;
65
+ } while (offset !== null);
66
+ };
67
+ for (const artifact of viewer.listArtifacts()) {
68
+ if (artifact.directory)
69
+ await inspectDirectory(artifact.id);
70
+ else
71
+ await inspectFile(artifact.id);
72
+ }
73
+ return { toolNames: registry.tools.map(tool => tool.name), inspectedFiles, readLimitLinesPerFile: 80, readLimitBytesPerFile: 65_536 };
74
+ }
75
+ /** Ephemeral diagnostics: no broker, review history, verdict, test or notification. */
76
+ export async function diagnoseProject({ repoPath, repoId = 'demo', mode = 'copy', stateDir, criticId, executors, signal, onEvent = () => { } }) {
77
+ const report = { ok: false, status: 'NOT_READY', repoId, mode, scope: scopeFor(criticId), checkedAt: new Date().toISOString(), checks: [] };
78
+ const add = async (check) => { report.checks.push(check); await onEvent({ type: 'doctor.check', check }); };
79
+ let scratch, workspace;
80
+ try {
81
+ if (signal?.aborted)
82
+ throw Object.assign(new Error('진단이 취소되었습니다.'), { code: 'ABORTED' });
83
+ try {
84
+ await executors.validateWorkspace?.(repoPath);
85
+ }
86
+ catch (error) {
87
+ await add({ id: 'workspace-preflight', status: 'FAIL', kind: 'workspace', message: errorCode(error) ? bounded(errorMessage(error)) : '진단 입력의 사전 조건을 확인하지 못했습니다.', remedy: remedyFor(error) ?? '인증 파일과 실행 상태의 경로가 리뷰 workspace 밖에 있는지 확인하세요.', details: { code: errorCode(error) ?? 'WORKSPACE_PREFLIGHT_FAILED' } });
88
+ return report;
89
+ }
90
+ scratch = await realpath(await mkdtemp(join(tmpdir(), 'ccdd-doctor-')));
91
+ try {
92
+ workspace = await prepareWorkspace({ repoPath, stateDir: stateDir ?? join(scratch, 'state'), mode, signal });
93
+ report.snapshotHash = workspace.descriptor.hash;
94
+ await add({ id: 'workspace-input', status: 'PASS', kind: 'workspace', message: mode === 'copy' ? '현재 repo 전체의 불변 복사본을 진단 입력으로 준비했습니다.' : '현재 workspace 전체의 변경 감시를 시작했습니다.', details: { mode, snapshotHash: report.snapshotHash } });
95
+ }
96
+ catch (error) {
97
+ await add({ id: 'workspace-input', status: 'FAIL', kind: 'workspace', message: bounded(errorMessage(error)), remedy: '현재 repo의 읽기 권한과 repo 밖의 CCDD 저장 경로를 확인하세요. 복사 도중에는 입력을 변경하지 마세요.', details: { code: signal?.aborted ? 'ABORTED' : errorCode(error) ?? 'WORKSPACE_UNAVAILABLE' } });
98
+ return report;
99
+ }
100
+ const worktreePath = workspace.descriptor.path;
101
+ let requests;
102
+ try {
103
+ requests = await prepareReviewRequests({ repoPath: worktreePath, repoId, snapshotHash: workspace.descriptor.hash, criticId });
104
+ await workspace.assertUnchanged();
105
+ await add({ id: 'workspace-config', status: 'PASS', kind: 'workspace', criticIds: requests.map(x => x.criticId), message: '현재 workspace의 설정과 Artifact 정의를 확인했습니다.' });
106
+ }
107
+ catch (error) {
108
+ await add({ id: 'workspace-config', status: 'FAIL', kind: 'workspace', message: bounded(errorMessage(error)), remedy: '현재 ccdd.config.ts 또는 legacy ccdd.config.json, Artifact 경로와 Critic 식별자를 확인하세요.', details: { code: errorCode(error) ?? 'WORKSPACE_CONFIG_INVALID' } });
109
+ return report;
110
+ }
111
+ const readyViewers = new Set();
112
+ for (const request of requests) {
113
+ if (workspace.signal.aborted)
114
+ break;
115
+ try {
116
+ const details = await inspectViewers(request, worktreePath, workspace.signal, resolve(scratch, `tools-${request.criticId}`));
117
+ readyViewers.add(request.criticId);
118
+ await add({ id: `artifacts:${request.criticId}`, status: 'PASS', kind: 'artifacts', criticIds: [request.criticId], message: request.configManifest ? '등록된 Artifact 도구의 명세와 실행 준비를 확인했습니다. 실제 도구 실행은 tools check --execute로 별도 확인할 수 있습니다.' : request.profile.kind === 'human' ? 'Human Artifact 도구의 등록과 실행 준비를 확인했습니다. 프로그램은 실행하지 않았습니다.' : '스냅샷의 Artifact Viewer 목록·읽기 진입점을 확인했습니다.', details });
119
+ }
120
+ catch (error) {
121
+ await add({ id: `artifacts:${request.criticId}`, status: 'FAIL', kind: 'artifacts', criticIds: [request.criticId], message: bounded(errorMessage(error)), remedy: 'Artifact 경로·유형·내용과 읽기 권한을 확인하세요.', details: { code: 'ARTIFACT_VIEWER_UNAVAILABLE' } });
122
+ }
123
+ }
124
+ const groups = new Map();
125
+ for (const request of requests) {
126
+ // Provider probes are profile-wide; runtime path readiness is per Critic
127
+ // because identical commands can have different declared artifact scopes.
128
+ const key = request.profile.kind === 'runtime' ? `runtime:${request.criticId}` : JSON.stringify(canonical(request.profile));
129
+ const group = groups.get(key) ?? [];
130
+ group.push(request);
131
+ groups.set(key, group);
132
+ }
133
+ let index = 0;
134
+ for (const group of groups.values()) {
135
+ index++;
136
+ const request = group.find(x => readyViewers.has(x.criticId)) ?? group[0];
137
+ const base = { id: `executor:${index}`, kind: request.profile.kind, ...(request.profile.kind === 'agent' ? { provider: request.profile.provider, model: request.profile.model, reasoning: request.profile.reasoning } : {}), criticIds: group.map(x => x.criticId) };
138
+ if (workspace.signal.aborted) {
139
+ await add({ ...base, status: 'FAIL', message: '진단이 취소되었습니다.', remedy: '필요하면 doctor를 다시 실행하세요.', details: { code: 'ABORTED' } });
140
+ continue;
141
+ }
142
+ if (!readyViewers.has(request.criticId)) {
143
+ await add({ ...base, status: 'SKIP', message: 'Artifact Viewer 준비 실패로 실행기 실사용 진단을 수행하지 않았습니다.' });
144
+ continue;
145
+ }
146
+ try {
147
+ if (typeof executors?.probe !== 'function')
148
+ throw Object.assign(new Error('실행기에 실사용 진단 기능이 없습니다.'), { code: 'PROBE_UNSUPPORTED', remedy: 'probe를 제공하는 실행기를 등록하세요.' });
149
+ const result = await executors.probe(request, { worktreePath, workspacePath: worktreePath, runDir: resolve(scratch, `probe-${index}`), signal: workspace.signal, onEvent });
150
+ if (result?.ok !== true)
151
+ throw Object.assign(new Error(result?.message ?? '실행기 준비 상태를 확인하지 못했습니다.'), { code: 'PROBE_FAILED', remedy: result?.remedy });
152
+ await add({ ...base, status: 'PASS', message: result.message, details: result.details });
153
+ }
154
+ catch (error) {
155
+ // Unknown adapter failures get a safe generic diagnostic, not raw output.
156
+ await add({ ...base, status: 'FAIL', message: errorCode(error) ? bounded(errorMessage(error)) : '실행기의 실사용 진단을 완료하지 못했습니다.', remedy: remedyFor(error) ?? 'Provider 설정·연결과 실행 환경을 확인한 뒤 다시 진단하세요.', details: { code: errorCode(error) ?? 'PROBE_FAILED' } });
157
+ }
158
+ }
159
+ await workspace.assertUnchanged();
160
+ }
161
+ catch (error) {
162
+ const code = errorCode(error) ?? (signal?.aborted ? 'ABORTED' : 'DIAGNOSTIC_FAILED');
163
+ const changed = ['WORKSPACE_CHANGED', 'WORKSPACE_CACHE_TAMPERED'].includes(code);
164
+ await add({ id: changed ? 'workspace-unchanged' : 'diagnostic', status: 'FAIL', kind: 'workspace', message: changed ? '진단 도중 리뷰 입력이 변경되었습니다.' : code === 'ABORTED' ? '진단이 취소되었습니다.' : '진단을 완료하지 못했습니다.', remedy: changed ? '진단 입력을 변경하지 않은 상태에서 doctor를 다시 실행하세요.' : '로컬 실행 환경과 권한을 확인한 뒤 다시 진단하세요.', details: { code } });
165
+ }
166
+ finally {
167
+ if (workspace) {
168
+ try {
169
+ await workspace.close();
170
+ }
171
+ catch (error) {
172
+ await add({ id: 'workspace-cleanup', status: 'FAIL', message: '진단용 workspace 감시를 정리하지 못했습니다.', remedy: 'CCDD 저장 경로의 권한을 확인하세요.', details: { code: errorCode(error) ?? 'CLEANUP_FAILED' } });
173
+ }
174
+ }
175
+ if (scratch) {
176
+ try {
177
+ await removeOwnedWorkspaceTree(scratch);
178
+ }
179
+ catch {
180
+ await add({ id: 'temporary-cleanup', status: 'FAIL', message: '진단 임시 파일을 정리하지 못했습니다.', remedy: '임시 디렉터리의 쓰기 권한을 확인하세요.', details: { code: 'CLEANUP_FAILED' } });
181
+ }
182
+ }
183
+ report.ok = report.checks.length > 0 && report.checks.every(check => check.status === 'PASS');
184
+ report.status = report.ok ? 'READY' : 'NOT_READY';
185
+ report.checkedAt = new Date().toISOString();
186
+ }
187
+ return report;
188
+ }
189
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/doctor/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { CredentialStore } from '@earendil-works/pi-ai';
2
+ /** Paths only: credentials are resolved in the worker and never stored in review state. */
3
+ export interface PiOptions {
4
+ authFile?: string;
5
+ codexAuthFile?: string;
6
+ }
7
+ export declare class PiAuthError extends Error {
8
+ readonly code: string;
9
+ readonly remedy: string;
10
+ constructor(code: string, message: string, remedy: string);
11
+ }
12
+ export declare function validatePiOptions(options?: PiOptions): void;
13
+ /** Call before snapshot creation as well as at execution: credentials must never be copied as review input. */
14
+ export declare function assertPiAuthFilesOutsideWorkspace(options: PiOptions, workspacePath: string): Promise<void>;
15
+ /** Explicit credential adapters are read-only; even an expired token never enters Pi's refresh path. */
16
+ export declare function createPiCredentialStore(options: PiOptions, workspacePath: string): Promise<CredentialStore>;
@@ -0,0 +1,150 @@
1
+ import { readFile, realpath, stat } from 'node:fs/promises';
2
+ import { basename, dirname, isAbsolute, join, relative, sep } from 'node:path';
3
+ export class PiAuthError extends Error {
4
+ code;
5
+ remedy;
6
+ constructor(code, message, remedy) {
7
+ super(message);
8
+ this.name = 'PiAuthError';
9
+ this.code = code;
10
+ this.remedy = remedy;
11
+ }
12
+ }
13
+ const unavailable = () => new PiAuthError('AUTHENTICATION_UNAVAILABLE', '명시한 인증 파일을 읽을 수 없습니다.', '인증 파일 경로와 읽기 권한을 확인하세요. 인증 파일은 리뷰 workspace 밖에 두세요.');
14
+ const invalid = () => new PiAuthError('AUTHENTICATION_INVALID', '명시한 인증 파일의 형식이 올바르지 않습니다.', 'Pi provider별 api_key 또는 oauth 형식의 인증 파일을 지정하세요.');
15
+ const expired = () => new PiAuthError('AUTHENTICATION_EXPIRED', '인증 토큰이 만료되었거나 곧 만료됩니다.', '해당 로그인 도구로 인증을 갱신한 뒤 다시 실행하세요. CCDD는 인증 파일과 공유 Codex 토큰을 갱신하지 않습니다.');
16
+ const readonly = () => new PiAuthError('AUTHENTICATION_READ_ONLY', 'CCDD 인증 파일 연결은 읽기 전용입니다.', '해당 로그인 도구로 인증을 갱신한 뒤 다시 실행하세요.');
17
+ const inWorkspace = () => new PiAuthError('AUTHENTICATION_IN_WORKSPACE', '인증 파일을 리뷰 workspace 안에 둘 수 없습니다.', '인증 파일을 원본 repo와 복사된 workspace 밖에 두고 경로를 다시 지정하세요.');
18
+ function object(value) { return !!value && typeof value === 'object' && !Array.isArray(value); }
19
+ export function validatePiOptions(options = {}) {
20
+ for (const value of [options.authFile, options.codexAuthFile]) {
21
+ if (value !== undefined && (typeof value !== 'string' || !value.trim() || value.length > 4_096 || value.includes('\0') || !isAbsolute(value))) {
22
+ throw new PiAuthError('AUTHENTICATION_PATH_INVALID', '인증 파일은 절대경로로 지정해야 합니다.', '--pi-auth-file 또는 --codex-auth-file에 workspace 밖 인증 파일의 절대경로를 지정하세요.');
23
+ }
24
+ }
25
+ }
26
+ function isWithin(root, candidate) {
27
+ const sub = relative(root, candidate);
28
+ return sub === '' || (!isAbsolute(sub) && sub !== '..' && !sub.startsWith(`..${sep}`));
29
+ }
30
+ async function canonicalPath(path) {
31
+ let ancestor = path;
32
+ const missing = [];
33
+ for (;;) {
34
+ try {
35
+ return join(await realpath(ancestor), ...missing);
36
+ }
37
+ catch (error) {
38
+ if (!error || typeof error !== 'object' || !('code' in error) || error.code !== 'ENOENT' || dirname(ancestor) === ancestor)
39
+ throw unavailable();
40
+ missing.unshift(basename(ancestor));
41
+ ancestor = dirname(ancestor);
42
+ }
43
+ }
44
+ }
45
+ /** Call before snapshot creation as well as at execution: credentials must never be copied as review input. */
46
+ export async function assertPiAuthFilesOutsideWorkspace(options, workspacePath) {
47
+ validatePiOptions(options);
48
+ if (!options.authFile && !options.codexAuthFile)
49
+ return;
50
+ const root = await canonicalPath(workspacePath);
51
+ for (const path of [options.authFile, options.codexAuthFile]) {
52
+ if (path && isWithin(root, await canonicalPath(path)))
53
+ throw inWorkspace();
54
+ }
55
+ }
56
+ function credential(value) {
57
+ if (!object(value))
58
+ throw invalid();
59
+ if (value.type === 'api_key') {
60
+ if (value.key !== undefined && (typeof value.key !== 'string' || !value.key))
61
+ throw invalid();
62
+ if (value.env !== undefined && (!object(value.env) || Object.values(value.env).some(item => typeof item !== 'string')))
63
+ throw invalid();
64
+ if (value.key === undefined && value.env === undefined)
65
+ throw invalid();
66
+ return { type: 'api_key', ...(value.key === undefined ? {} : { key: value.key }), ...(value.env === undefined ? {} : { env: value.env }) };
67
+ }
68
+ if (value.type === 'oauth') {
69
+ if (typeof value.access !== 'string' || !value.access || typeof value.refresh !== 'string' || !value.refresh || typeof value.expires !== 'number' || !Number.isFinite(value.expires))
70
+ throw invalid();
71
+ if (value.expires <= Date.now() + 300_000)
72
+ throw expired();
73
+ return { ...value, type: 'oauth', access: value.access, refresh: value.refresh, expires: value.expires };
74
+ }
75
+ throw invalid();
76
+ }
77
+ /** Explicit credential adapters are read-only; even an expired token never enters Pi's refresh path. */
78
+ export async function createPiCredentialStore(options, workspacePath) {
79
+ validatePiOptions(options);
80
+ const root = await realpath(workspacePath);
81
+ async function load(path, signal) {
82
+ signal?.throwIfAborted();
83
+ try {
84
+ const target = await realpath(path);
85
+ if (isWithin(root, target))
86
+ throw inWorkspace();
87
+ const info = await stat(target);
88
+ if (!info.isFile() || info.size > 1_048_576)
89
+ throw invalid();
90
+ const data = JSON.parse(await readFile(target, { encoding: 'utf8', signal }));
91
+ if (!object(data))
92
+ throw invalid();
93
+ return data;
94
+ }
95
+ catch (error) {
96
+ if (error instanceof PiAuthError)
97
+ throw error;
98
+ signal?.throwIfAborted();
99
+ throw unavailable();
100
+ }
101
+ }
102
+ async function codex(signal) {
103
+ if (!options.codexAuthFile)
104
+ return undefined;
105
+ const data = await load(options.codexAuthFile, signal);
106
+ if (!object(data.tokens) || typeof data.tokens.access_token !== 'string' || !data.tokens.access_token)
107
+ throw invalid();
108
+ let claims;
109
+ try {
110
+ claims = JSON.parse(Buffer.from(data.tokens.access_token.split('.')[1] ?? '', 'base64url').toString('utf8'));
111
+ }
112
+ catch {
113
+ throw invalid();
114
+ }
115
+ if (!object(claims) || typeof claims.exp !== 'number' || !Number.isFinite(claims.exp))
116
+ throw invalid();
117
+ const expires = claims.exp * 1_000;
118
+ if (expires <= Date.now() + 300_000)
119
+ throw expired();
120
+ // Pi receives only access, never the shared refresh token. Refresh is rejected by this store.
121
+ return { type: 'oauth', access: data.tokens.access_token, refresh: '', expires };
122
+ }
123
+ return {
124
+ async read(providerId, operation = {}) {
125
+ operation.signal?.throwIfAborted();
126
+ const values = options.authFile ? await load(options.authFile, operation.signal) : {};
127
+ const found = Object.hasOwn(values, providerId) ? values[providerId] : undefined;
128
+ if (providerId === 'openai-codex' && options.codexAuthFile) {
129
+ if (found !== undefined)
130
+ throw new PiAuthError('AUTHENTICATION_CONFLICT', 'OpenAI Codex 인증 파일이 두 곳에 지정되어 있습니다.', 'openai-codex에는 Pi 인증 또는 읽기 전용 Codex 인증 중 하나만 지정하세요.');
131
+ return codex(operation.signal);
132
+ }
133
+ return found === undefined ? undefined : credential(found);
134
+ },
135
+ async list(operation = {}) {
136
+ const values = options.authFile ? await load(options.authFile, operation.signal) : {};
137
+ const result = [];
138
+ for (const [providerId, entry] of Object.entries(values)) {
139
+ if (object(entry) && (entry.type === 'api_key' || entry.type === 'oauth'))
140
+ result.push({ providerId, type: entry.type });
141
+ }
142
+ if (options.codexAuthFile && !result.some(item => item.providerId === 'openai-codex'))
143
+ result.push({ providerId: 'openai-codex', type: 'oauth' });
144
+ return result;
145
+ },
146
+ async modify() { throw readonly(); },
147
+ async delete() { throw readonly(); },
148
+ };
149
+ }
150
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/executors/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function diagnosticError(code: string, message: string, remedy: string): Error & {
2
+ code: string;
3
+ remedy: string;
4
+ };
5
+ export declare function errorMessage(value: unknown): string;
6
+ export declare function errorCode(value: unknown): string | undefined;
@@ -0,0 +1,10 @@
1
+ export function diagnosticError(code, message, remedy) {
2
+ return Object.assign(new Error(message), { code, remedy });
3
+ }
4
+ export function errorMessage(value) { return value instanceof Error ? value.message : String(value); }
5
+ export function errorCode(value) {
6
+ if (value && typeof value === 'object' && 'code' in value && typeof value.code === 'string')
7
+ return value.code;
8
+ return undefined;
9
+ }
10
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/executors/errors.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,OAAe,EAAE,MAAc;IAC3E,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AAC7D,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,KAAc,IAAY,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvH,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC;IAC/G,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { PiOptions, StreamFn } from './pi.js';
2
+ import type { AlarmMethod, ReviewEnvelope, ReviewRequest, ReviewResult, ExecutionContext, ExecutorReadiness, ProbeResult } from '../contracts.js';
3
+ import type { SpawnImplementation } from './process.js';
4
+ export declare function validateResult(value: unknown): ReviewResult;
5
+ /** Three executor strategies. The broker alone persists workflow state. */
6
+ export interface ExecutorOptions {
7
+ piOptions?: PiOptions;
8
+ streamFn?: StreamFn;
9
+ alarmMethods?: (AlarmMethod | AlarmMethod['notify'])[];
10
+ spawnImpl?: SpawnImplementation;
11
+ }
12
+ export declare function createExecutorRegistry({ piOptions, streamFn, alarmMethods, spawnImpl }?: ExecutorOptions): {
13
+ validateWorkspace(repoPath: string): Promise<void>;
14
+ canExecute(request: Pick<ReviewEnvelope, 'profile'>): Promise<ExecutorReadiness>;
15
+ probe(request: ReviewEnvelope, { worktreePath, workspacePath, runDir, signal, onEvent }: ExecutionContext): Promise<ProbeResult>;
16
+ notifyHuman(request: ReviewRequest): Promise<{
17
+ alarmMethods: string[];
18
+ }>;
19
+ execute(request: ReviewEnvelope, { worktreePath, workspacePath, runDir, signal, onEvent }: ExecutionContext): Promise<ReviewResult>;
20
+ };