dory-to-dory-watcher 0.1.0 → 0.1.2

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 (50) hide show
  1. package/README.md +83 -8
  2. package/dist/agent.d.ts +5 -1
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +84 -15
  5. package/dist/agent.js.map +1 -1
  6. package/dist/cli.js +106 -4
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +11 -6
  10. package/dist/config.js.map +1 -1
  11. package/dist/doctor.d.ts.map +1 -1
  12. package/dist/doctor.js +13 -24
  13. package/dist/doctor.js.map +1 -1
  14. package/dist/index.d.ts +4 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +4 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/installation.d.ts +19 -0
  19. package/dist/installation.d.ts.map +1 -0
  20. package/dist/installation.js +162 -0
  21. package/dist/installation.js.map +1 -0
  22. package/dist/mcp-registration.d.ts +40 -0
  23. package/dist/mcp-registration.d.ts.map +1 -0
  24. package/dist/mcp-registration.js +573 -0
  25. package/dist/mcp-registration.js.map +1 -0
  26. package/dist/pairing.d.ts +28 -0
  27. package/dist/pairing.d.ts.map +1 -0
  28. package/dist/pairing.js +170 -0
  29. package/dist/pairing.js.map +1 -0
  30. package/dist/process.d.ts +17 -0
  31. package/dist/process.d.ts.map +1 -0
  32. package/dist/process.js +77 -0
  33. package/dist/process.js.map +1 -0
  34. package/dist/run-lock.d.ts +6 -0
  35. package/dist/run-lock.d.ts.map +1 -0
  36. package/dist/run-lock.js +97 -0
  37. package/dist/run-lock.js.map +1 -0
  38. package/dist/service.d.ts +34 -0
  39. package/dist/service.d.ts.map +1 -0
  40. package/dist/service.js +398 -0
  41. package/dist/service.js.map +1 -0
  42. package/dist/setup.d.ts +50 -0
  43. package/dist/setup.d.ts.map +1 -0
  44. package/dist/setup.js +378 -0
  45. package/dist/setup.js.map +1 -0
  46. package/dist/watcher.d.ts +2 -2
  47. package/dist/watcher.d.ts.map +1 -1
  48. package/dist/watcher.js +8 -4
  49. package/dist/watcher.js.map +1 -1
  50. package/package.json +2 -2
package/README.md CHANGED
@@ -19,14 +19,69 @@ Watcher는 Agent를 새로 구현하지 않습니다. 사용자가 이미 로그
19
19
  ## 요구 사항
20
20
 
21
21
  - Node.js 22 이상
22
- - dory-to-dory Core에서 발급한 Agent API key
22
+ - dory-to-dory 계정. `setup`의 device-code pairing이 Agent API key를 안전하게 발급·저장합니다.
23
23
  - 지원되는 Agent CLI 하나 이상
24
24
  - Codex CLI
25
25
  - Claude Code
26
26
  - Gemini CLI
27
27
  - Agent가 실행할 도구를 비대화식 환경에서 사용할 수 있도록 구성된 기존 권한 정책
28
28
 
29
- ## 설치와 실행
29
+ ## 빠른 설치
30
+
31
+ 일반 사용자는 Watcher를 전역 설치한 뒤 대화형 설정을 한 번 실행합니다.
32
+
33
+ ```sh
34
+ npm install --global dory-to-dory-watcher@latest
35
+ dory-watcher setup
36
+ ```
37
+
38
+ `setup`은 다음 작업을 순서대로 수행합니다.
39
+
40
+ 1. 설치된 Codex CLI, Claude Code, Gemini CLI를 찾아 사용할 Agent를 선택합니다.
41
+ 2. Agent가 실행될 workspace를 선택합니다.
42
+ 3. 브라우저에서 dory-to-dory에 로그인하고 짧은 일회용 코드로 이 장치를 승인합니다.
43
+ 4. 발급된 Agent API key를 화면이나 명령행에 노출하지 않고 OS별 사용자 credential 파일에 저장합니다.
44
+ 5. 기존 `dory-to-dory` MCP 설정을 검사하고, 새 등록이면 선택한 Agent의 공식 CLI로 등록합니다.
45
+ 6. 기존 MCP 설정이 있으면 자동으로 덮어쓰지 않습니다. 사용자가 교체에 동의하면 설정 파일을 먼저 백업합니다.
46
+ 7. `doctor` 검사를 수행합니다. 이 과정에서는 item을 claim하거나 처리하지 않습니다.
47
+ 8. macOS와 Linux에서는 사용자가 명시적으로 동의한 경우에만 로그인 백그라운드 서비스를 설치하고 시작합니다.
48
+
49
+ 브라우저가 자동으로 열리지 않으면 화면에 표시된 verification URL을 열고 user code를 입력합니다. `device_code`와 API key 원문은 출력하거나 로그에 기록하지 않습니다.
50
+
51
+ ```sh
52
+ dory-watcher status
53
+ dory-watcher service status
54
+ dory-watcher service logs
55
+ ```
56
+
57
+ `status`는 저장된 비밀이 아닌 설정과 서비스 상태만 표시합니다. 실제 Core 연결은 `doctor`로 확인합니다.
58
+
59
+ ```sh
60
+ dory-watcher doctor
61
+ ```
62
+
63
+ 설정 후 Agent 앱을 재시작하고 다음과 같이 요청해 MCP 연결도 확인합니다.
64
+
65
+ ```text
66
+ dory-to-dory MCP의 d2d_get_connection_status를 실행해서 연결 상태를 확인해줘.
67
+ ```
68
+
69
+ Windows에서는 device pairing, MCP 설정과 터미널의 foreground `dory-watcher run`을 지원합니다. 로그인 백그라운드 서비스 등록은 아직 지원하지 않습니다.
70
+
71
+ ### 고급 setup 옵션
72
+
73
+ ```sh
74
+ dory-watcher setup --agent codex --workspace /absolute/path/to/workspace
75
+ dory-watcher setup --no-browser --no-service
76
+ ```
77
+
78
+ 다른 Core를 사용하는 개발 환경에서만 `--core-url`을 지정합니다.
79
+
80
+ ```sh
81
+ dory-watcher setup --core-url https://core.example.test
82
+ ```
83
+
84
+ ## 수동 설치와 실행
30
85
 
31
86
  개발 중에는 다음과 같이 실행합니다.
32
87
 
@@ -40,12 +95,12 @@ node dist/cli.js run
40
95
  npm 게시 이후에는 전역 설치할 수 있습니다.
41
96
 
42
97
  ```sh
43
- npm install --global dory-to-dory-watcher@0.1.0
98
+ npm install --global dory-to-dory-watcher@latest
44
99
  dory-watcher doctor
45
100
  dory-watcher run
46
101
  ```
47
102
 
48
- 별도의 MCP npm 설치는 필요하지 않습니다. Watcher 호환되는 정확한 MCP 버전을 함께 설치하며, Agent의 MCP 설정은 안정적인 `dory-watcher mcp` 명령을 실행하도록 등록해야 합니다.
103
+ 별도의 MCP npm 설치는 필요하지 않습니다. Watcher 릴리스는 검증된 정확한 MCP 버전을 의존성으로 포함하며, Agent의 MCP 설정은 안정적인 `dory-watcher mcp` 명령을 실행하도록 등록해야 합니다.
49
104
 
50
105
  ```json
51
106
  {
@@ -61,12 +116,13 @@ dory-watcher run
61
116
  }
62
117
  ```
63
118
 
64
- Agent 설정 형식은 제품마다 다르지만 command와 args의 의미는 같습니다. Watcher를 업데이트하면 함께 묶인 MCP도 업데이트되므로 Agent 설정에서 MCP 버전을 다시 입력할 필요가 없습니다. 설치 명령 자체는 Agent 설정을 몰래 변경하지 않으므로 최초 번은 launcher를 해당 Agent에 등록해야 합니다.
119
+ Agent 설정 형식은 제품마다 다르지만 command와 args의 의미는 같습니다. `setup`이 최초 등록을 처리하므로 사용자가 MCP 버전을 직접 입력할 필요는 없습니다. 다만 Watcher와 MCP의 자동 업데이트 릴리스 자동 버전 동기화는 아직 제공하지 않으며, 릴리스의 실제 의존성 버전을 따릅니다.
65
120
 
66
121
  API key를 서비스 설정과 명령행에 반복해서 넣지 않도록 credential 파일 사용을 권장합니다.
67
122
 
68
123
  ```sh
69
124
  mkdir -p ~/.config/dory-to-dory
125
+ chmod 700 ~/.config/dory-to-dory
70
126
  umask 077
71
127
  read -s D2D_WATCHER_KEY
72
128
  printf '%s\n' "$D2D_WATCHER_KEY" > ~/.config/dory-to-dory/agent.key
@@ -132,13 +188,32 @@ export D2D_AGENT_ARGS_JSON='["--headless"]'
132
188
 
133
189
  ## 백그라운드 실행
134
190
 
135
- 정상 동작을 `dory-watcher doctor`와 `dory-watcher once`로 먼저 확인한 OS의 로그인 서비스로 `dory-watcher run`을 등록합니다.
191
+ `dory-watcher setup` 마지막 단계에서 동의하거나 다음 명령을 실행하면 로그인할 터미널 창 없이 사용자 백그라운드 서비스로 시작합니다.
192
+
193
+ ```sh
194
+ dory-watcher service install
195
+ dory-watcher service status
196
+ ```
136
197
 
137
198
  - macOS: 사용자 LaunchAgent
138
199
  - Linux: systemd user service
139
- - Windows: Task Scheduler의 사용자 로그인 트리거
200
+ - Windows: 현재 자동 실행 미지원
201
+
202
+ 서비스는 Agent CLI의 로그인 정보와 MCP 설정을 읽어야 하므로 동일한 OS 사용자 계정에서 실행됩니다. `sudo`로 설치하거나 실행하지 마십시오. 이미 foreground Watcher가 실행 중이면 single-instance lock이 두 번째 실행을 차단하여 중복 Agent 호출 비용을 방지합니다.
203
+
204
+ 설치 시점의 절대경로 `PATH` 항목은 서비스 정의에 보존됩니다. 다만 shell profile에만 선언한 다른 환경 변수나 secret은 복사하지 않습니다. 백그라운드 Agent가 사용하는 도구의 credential은 Agent 설정 또는 OS credential store처럼 비대화식 실행에서도 사용할 수 있는 안전한 위치에 구성하세요.
205
+
206
+ 서비스 관리 명령은 다음과 같습니다.
207
+
208
+ ```sh
209
+ dory-watcher service start
210
+ dory-watcher service stop
211
+ dory-watcher service restart
212
+ dory-watcher service logs
213
+ dory-watcher service uninstall
214
+ ```
140
215
 
141
- 서비스에는 key 대신 `D2D_API_KEY_FILE`과 Agent 종류, workspace를 전달하십시오. Agent CLI로그인 정보와 MCP 설정을 읽을 있도록 반드시 같은 OS 사용자 계정으로 실행해야 합니다.
216
+ 서비스를 중지하면 진행 중인 headless Agent에도 종료 신호를 전달합니다. Coreclaim lease와 fencing token이 중단된 item을 안전하게 다시 처리할 있게 합니다.
142
217
 
143
218
  ## 보안 및 비용
144
219
 
package/dist/agent.d.ts CHANGED
@@ -12,6 +12,10 @@ export interface AgentRunResult {
12
12
  export declare class AgentRunError extends Error {
13
13
  name: string;
14
14
  }
15
+ export declare function windowsTreeKillInvocation(pid: number, force: boolean): {
16
+ command: string;
17
+ args: string[];
18
+ };
15
19
  export declare function buildInvocation(kind: AgentKind, command: string, extraArgs: string[]): AgentInvocation;
16
- export declare function runAgent(config: WatcherConfig): Promise<AgentRunResult>;
20
+ export declare function runAgent(config: WatcherConfig, signal?: AbortSignal): Promise<AgentRunResult>;
17
21
  //# sourceMappingURL=agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D,eAAO,MAAM,WAAW,68BASyD,CAAC;AAElF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,aAAc,SAAQ,KAAK;IAC7B,IAAI,SAAmB;CACjC;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EAAE,GAClB,eAAe,CAuBjB;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CA0C7E"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5D,eAAO,MAAM,WAAW,68BASyD,CAAC;AAElF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,aAAc,SAAQ,KAAK;IAC7B,IAAI,SAAmB;CACjC;AAED,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,GACb;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAKrC;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EAAE,GAClB,eAAe,CAuBjB;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CA8FnG"}
package/dist/agent.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { spawn } from "node:child_process";
2
+ import { commandForSpawn } from "./process.js";
2
3
  export const WAKE_PROMPT = `This is a dory-to-dory background wake-up. Process at most one pending dory-to-dory item.
3
4
 
4
5
  1. Call the dory-to-dory MCP tool d2d_claim_next_item exactly once.
@@ -12,6 +13,12 @@ Do not process ordinary unrelated work and do not include credentials in output.
12
13
  export class AgentRunError extends Error {
13
14
  name = "AgentRunError";
14
15
  }
16
+ export function windowsTreeKillInvocation(pid, force) {
17
+ return {
18
+ command: "taskkill.exe",
19
+ args: ["/pid", String(pid), "/t", ...(force ? ["/f"] : [])],
20
+ };
21
+ }
15
22
  export function buildInvocation(kind, command, extraArgs) {
16
23
  if (kind === "codex") {
17
24
  return {
@@ -30,54 +37,116 @@ export function buildInvocation(kind, command, extraArgs) {
30
37
  if (kind === "gemini") {
31
38
  return {
32
39
  command,
33
- args: ["--output-format", "stream-json", ...extraArgs],
40
+ args: ["--prompt", "", "--output-format", "stream-json", ...extraArgs],
34
41
  promptOnStdin: WAKE_PROMPT,
35
42
  };
36
43
  }
37
44
  return { command, args: extraArgs, promptOnStdin: WAKE_PROMPT };
38
45
  }
39
- export async function runAgent(config) {
46
+ export async function runAgent(config, signal) {
47
+ if (signal?.aborted)
48
+ throw new AgentRunError(`${config.agentKind} Agent run was cancelled`);
40
49
  const invocation = buildInvocation(config.agentKind, config.agentCommand, config.agentArgs);
50
+ const executable = commandForSpawn(invocation.command, invocation.args);
41
51
  const startedAt = Date.now();
42
52
  return await new Promise((resolve, reject) => {
43
- const child = spawn(invocation.command, invocation.args, {
53
+ const childEnvironment = { ...process.env };
54
+ delete childEnvironment.D2D_API_KEY;
55
+ const child = spawn(executable.command, executable.args, {
44
56
  cwd: config.workspace,
45
- env: process.env,
57
+ env: childEnvironment,
46
58
  shell: false,
59
+ detached: process.platform !== "win32",
47
60
  windowsHide: true,
48
61
  stdio: ["pipe", "pipe", "pipe"],
49
62
  });
50
63
  let outputBytes = 0;
51
64
  const outputLimit = 1024 * 1024;
65
+ let settled = false;
66
+ let forceTimer;
67
+ const finish = (operation) => {
68
+ if (settled)
69
+ return;
70
+ settled = true;
71
+ signal?.removeEventListener("abort", abort);
72
+ clearTimeout(timer);
73
+ if (forceTimer)
74
+ clearTimeout(forceTimer);
75
+ operation();
76
+ };
77
+ child.once("error", () => finish(() => reject(new AgentRunError(`Could not start ${config.agentCommand}`))));
78
+ child.stdin.on("error", () => undefined);
79
+ let timedOut = false;
80
+ let cancelled = false;
81
+ const terminate = (killSignal = "SIGTERM") => {
82
+ if (!child.pid || child.exitCode !== null)
83
+ return;
84
+ try {
85
+ if (process.platform === "win32") {
86
+ const invocation = windowsTreeKillInvocation(child.pid, killSignal === "SIGKILL");
87
+ const killer = spawn(invocation.command, invocation.args, {
88
+ shell: false,
89
+ stdio: "ignore",
90
+ windowsHide: true,
91
+ });
92
+ killer.once("error", () => {
93
+ try {
94
+ child.kill(killSignal);
95
+ }
96
+ catch {
97
+ // The process may already have exited.
98
+ }
99
+ });
100
+ }
101
+ else
102
+ process.kill(-child.pid, killSignal);
103
+ }
104
+ catch {
105
+ child.kill(killSignal);
106
+ }
107
+ };
108
+ const terminateWithGrace = () => {
109
+ terminate();
110
+ if (!forceTimer) {
111
+ forceTimer = setTimeout(() => terminate("SIGKILL"), 5_000);
112
+ forceTimer.unref();
113
+ }
114
+ };
52
115
  const consume = (chunk) => {
53
116
  outputBytes += chunk.length;
54
117
  if (outputBytes > outputLimit)
55
- child.kill();
118
+ terminateWithGrace();
56
119
  };
57
120
  child.stdout.on("data", consume);
58
121
  child.stderr.on("data", consume);
59
- child.once("error", () => reject(new AgentRunError(`Could not start ${config.agentCommand}`)));
60
- child.stdin.on("error", () => undefined);
61
- let timedOut = false;
122
+ const abort = () => {
123
+ cancelled = true;
124
+ terminateWithGrace();
125
+ };
126
+ signal?.addEventListener("abort", abort, { once: true });
127
+ if (signal?.aborted)
128
+ abort();
62
129
  const timer = setTimeout(() => {
63
130
  timedOut = true;
64
- child.kill();
131
+ terminateWithGrace();
65
132
  }, config.runTimeoutMs);
66
133
  timer.unref();
67
134
  child.once("close", (code) => {
68
- clearTimeout(timer);
69
135
  const durationMs = Date.now() - startedAt;
70
- if (timedOut) {
71
- reject(new AgentRunError(`${config.agentKind} Agent run timed out`));
136
+ if (cancelled) {
137
+ finish(() => reject(new AgentRunError(`${config.agentKind} Agent run was cancelled`)));
138
+ }
139
+ else if (timedOut) {
140
+ finish(() => reject(new AgentRunError(`${config.agentKind} Agent run timed out`)));
72
141
  }
73
142
  else if (outputBytes > outputLimit) {
74
- reject(new AgentRunError(`${config.agentKind} Agent produced excessive output`));
143
+ finish(() => reject(new AgentRunError(`${config.agentKind} Agent produced excessive output`)));
75
144
  }
76
145
  else if (code !== 0) {
77
- reject(new AgentRunError(`${config.agentKind} Agent exited with code ${code ?? "unknown"}`));
146
+ finish(() => reject(new AgentRunError(`${config.agentKind} Agent exited with code ${code ?? "unknown"}`)));
78
147
  }
79
148
  else {
80
- resolve({ exitCode: 0, durationMs });
149
+ finish(() => resolve({ exitCode: 0, durationMs }));
81
150
  }
82
151
  });
83
152
  child.stdin.end(invocation.promptOnStdin);
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;iFASsD,CAAC;AAalF,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,IAAI,GAAG,eAAe,CAAC;CACjC;AAED,MAAM,UAAU,yBAAyB,CACvC,GAAW,EACX,KAAc;IAEd,OAAO;QACL,OAAO,EAAE,cAAc;QACvB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,IAAe,EACf,OAAe,EACf,SAAmB;IAEnB,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO;YACL,OAAO;YACP,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,uBAAuB,EAAE,GAAG,SAAS,EAAE,GAAG,CAAC;YACnF,aAAa,EAAE,WAAW;SAC3B,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO;YACL,OAAO;YACP,IAAI,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;YACzE,aAAa,EAAE,WAAW;SAC3B,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO;YACL,OAAO;YACP,IAAI,EAAE,CAAC,UAAU,EAAE,EAAE,EAAE,iBAAiB,EAAE,aAAa,EAAE,GAAG,SAAS,CAAC;YACtE,aAAa,EAAE,WAAW;SAC3B,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAqB,EAAE,MAAoB;IACxE,IAAI,MAAM,EAAE,OAAO;QAAE,MAAM,IAAI,aAAa,CAAC,GAAG,MAAM,CAAC,SAAS,0BAA0B,CAAC,CAAC;IAC5F,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5F,MAAM,UAAU,GAAG,eAAe,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,OAAO,MAAM,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3D,MAAM,gBAAgB,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC5C,OAAO,gBAAgB,CAAC,WAAW,CAAC;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE;YACvD,GAAG,EAAE,MAAM,CAAC,SAAS;YACrB,GAAG,EAAE,gBAAgB;YACrB,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;YACtC,WAAW,EAAE,IAAI;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QACH,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;QAChC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,UAAsC,CAAC;QAC3C,MAAM,MAAM,GAAG,CAAC,SAAqB,EAAE,EAAE;YACvC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC5C,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,UAAU;gBAAE,YAAY,CAAC,UAAU,CAAC,CAAC;YACzC,SAAS,EAAE,CAAC;QACd,CAAC,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,mBAAmB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7G,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,SAAS,GAAG,CAAC,aAA6B,SAAS,EAAE,EAAE;YAC3D,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI;gBAAE,OAAO;YAClD,IAAI,CAAC;gBACH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;oBACjC,MAAM,UAAU,GAAG,yBAAyB,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC;oBAClF,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE;wBACxD,KAAK,EAAE,KAAK;wBACZ,KAAK,EAAE,QAAQ;wBACf,WAAW,EAAE,IAAI;qBAClB,CAAC,CAAC;oBACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;wBACxB,IAAI,CAAC;4BACH,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;wBACzB,CAAC;wBAAC,MAAM,CAAC;4BACP,uCAAuC;wBACzC,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;;oBAAM,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAC9C,CAAC;YAAC,MAAM,CAAC;gBACP,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACzB,CAAC;QACH,CAAC,CAAC;QACF,MAAM,kBAAkB,GAAG,GAAG,EAAE;YAC9B,SAAS,EAAE,CAAC;YACZ,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC3D,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;QACH,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE;YAChC,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC;YAC5B,IAAI,WAAW,GAAG,WAAW;gBAAE,kBAAkB,EAAE,CAAC;QACtD,CAAC,CAAC;QACF,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,GAAG,EAAE;YACjB,SAAS,GAAG,IAAI,CAAC;YACjB,kBAAkB,EAAE,CAAC;QACvB,CAAC,CAAC;QACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,MAAM,EAAE,OAAO;YAAE,KAAK,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,QAAQ,GAAG,IAAI,CAAC;YAChB,kBAAkB,EAAE,CAAC;QACvB,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QACxB,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC1C,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,GAAG,MAAM,CAAC,SAAS,0BAA0B,CAAC,CAAC,CAAC,CAAC;YACzF,CAAC;iBAAM,IAAI,QAAQ,EAAE,CAAC;gBACpB,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,GAAG,MAAM,CAAC,SAAS,sBAAsB,CAAC,CAAC,CAAC,CAAC;YACrF,CAAC;iBAAM,IAAI,WAAW,GAAG,WAAW,EAAE,CAAC;gBACrC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,GAAG,MAAM,CAAC,SAAS,kCAAkC,CAAC,CAAC,CAAC,CAAC;YACjG,CAAC;iBAAM,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,GAAG,MAAM,CAAC,SAAS,2BAA2B,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7G,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;YACrD,CAAC;QACH,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/cli.js CHANGED
@@ -1,7 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { serveDoryToDoryMcp } from "dory-to-dory-mcp";
3
+ import { fileURLToPath } from "node:url";
3
4
  import { loadConfig } from "./config.js";
4
5
  import { doctor } from "./doctor.js";
6
+ import { defaultInstallationFile, installationEnvironment, loadInstallation, } from "./installation.js";
7
+ import { installService, restartService, serviceLogs, serviceStatus, startService, stopService, uninstallService, } from "./service.js";
8
+ import { installationStatusLines, parseSetupOptions, runSetup } from "./setup.js";
9
+ import { acquireRunLock, runningWatcherPid } from "./run-lock.js";
5
10
  import { Watcher } from "./watcher.js";
6
11
  const HELP = `dory-watcher <command>
7
12
 
@@ -10,6 +15,9 @@ Commands:
10
15
  once Reconcile and process available items once, then exit
11
16
  mcp Run the bundled dory-to-dory MCP server over stdio
12
17
  doctor Verify the credential, Core connection, workspace, and Agent CLI
18
+ setup Pair this device and configure an Agent, MCP, and optional login service
19
+ status Show saved setup and background-service status (never prints the credential)
20
+ service Manage login background service: install|start|stop|restart|status|logs|uninstall
13
21
  help Show this help
14
22
 
15
23
  Required configuration:
@@ -19,18 +27,98 @@ Agent selection:
19
27
  D2D_AGENT_KIND=codex|claude|gemini|custom (default: codex)
20
28
  D2D_AGENT_COMMAND=<executable> (required only for custom)
21
29
  D2D_AGENT_ARGS_JSON='["arg1","arg2"]' (optional extra CLI arguments)
22
- D2D_AGENT_WORKSPACE=/absolute/path (default: current directory)`;
30
+ D2D_AGENT_WORKSPACE=/absolute/path (default: current directory)
31
+
32
+ Setup options:
33
+ --agent codex|claude|gemini
34
+ --workspace /absolute/path
35
+ --agent-name <display name>
36
+ --core-url https://example.test
37
+ --no-browser
38
+ --no-service`;
39
+ async function resolvedEnvironment() {
40
+ return installationEnvironment(process.env, await loadInstallation());
41
+ }
42
+ function applyMcpEnvironment(env) {
43
+ for (const name of ["D2D_API_KEY", "D2D_API_KEY_FILE", "D2D_CORE_URL"]) {
44
+ if (env[name] !== undefined && process.env[name] === undefined)
45
+ process.env[name] = env[name];
46
+ }
47
+ }
48
+ async function serviceCommand(action, args) {
49
+ if (action === "status") {
50
+ console.log((await serviceStatus()).detail);
51
+ return;
52
+ }
53
+ if (action === "logs") {
54
+ console.log(await serviceLogs());
55
+ return;
56
+ }
57
+ if (action === "start")
58
+ return await startService();
59
+ if (action === "stop")
60
+ return await stopService();
61
+ if (action === "restart")
62
+ return await restartService();
63
+ if (action === "uninstall")
64
+ return await uninstallService();
65
+ if (action === "install") {
66
+ const configFile = process.env.D2D_WATCHER_CONFIG_FILE?.trim() || defaultInstallationFile();
67
+ const installation = await loadInstallation(configFile);
68
+ if (!installation)
69
+ throw new Error("Run `dory-watcher setup` before installing the background service");
70
+ const config = loadConfig(installationEnvironment(process.env, installation));
71
+ for (const line of await doctor(config))
72
+ console.log(line);
73
+ const current = await serviceStatus();
74
+ const activePid = await runningWatcherPid(config.stateFile);
75
+ const startNow = current.running || activePid === undefined;
76
+ await installService({
77
+ installation,
78
+ nodeCommand: process.execPath,
79
+ watcherCli: fileURLToPath(import.meta.url),
80
+ configFile,
81
+ }, args.includes("--replace"), startNow);
82
+ if (startNow)
83
+ console.log("Background service installed and start requested.");
84
+ else {
85
+ console.log(`Background service installed but not started because Watcher PID ${activePid} is already running.`);
86
+ }
87
+ return;
88
+ }
89
+ throw new Error("Usage: dory-watcher service install|start|stop|restart|status|logs|uninstall");
90
+ }
23
91
  async function main() {
24
92
  const command = process.argv[2] ?? "run";
25
93
  if (command === "help" || command === "--help" || command === "-h") {
26
94
  console.log(HELP);
27
95
  return;
28
96
  }
97
+ if (command === "setup") {
98
+ if (process.argv.slice(3).some((arg) => arg === "--help" || arg === "-h")) {
99
+ console.log(HELP);
100
+ return;
101
+ }
102
+ await runSetup(parseSetupOptions(process.argv.slice(3)), {
103
+ watcherCli: fileURLToPath(import.meta.url),
104
+ });
105
+ return;
106
+ }
107
+ if (command === "status") {
108
+ for (const line of await installationStatusLines())
109
+ console.log(line);
110
+ return;
111
+ }
112
+ if (command === "service") {
113
+ await serviceCommand(process.argv[3], process.argv.slice(4));
114
+ return;
115
+ }
29
116
  if (command === "mcp") {
117
+ applyMcpEnvironment(await resolvedEnvironment());
30
118
  await serveDoryToDoryMcp();
31
119
  return;
32
120
  }
33
- const config = loadConfig();
121
+ const config = loadConfig(await resolvedEnvironment());
34
122
  if (command === "doctor") {
35
123
  for (const line of await doctor(config))
36
124
  console.log(line);
@@ -38,7 +126,13 @@ async function main() {
38
126
  }
39
127
  const watcher = new Watcher(config);
40
128
  if (command === "once") {
41
- await watcher.processAvailableWork();
129
+ const release = await acquireRunLock(config.stateFile);
130
+ try {
131
+ await watcher.processAvailableWork();
132
+ }
133
+ finally {
134
+ await release();
135
+ }
42
136
  return;
43
137
  }
44
138
  if (command !== "run")
@@ -47,7 +141,15 @@ async function main() {
47
141
  const stop = () => controller.abort();
48
142
  process.once("SIGINT", stop);
49
143
  process.once("SIGTERM", stop);
50
- await watcher.run(controller.signal);
144
+ const release = await acquireRunLock(config.stateFile);
145
+ try {
146
+ await watcher.run(controller.signal);
147
+ }
148
+ finally {
149
+ process.removeListener("SIGINT", stop);
150
+ process.removeListener("SIGTERM", stop);
151
+ await release();
152
+ }
51
153
  }
52
154
  main().catch((error) => {
53
155
  console.error(`[dory-watcher] ${error instanceof Error ? error.message : String(error)}`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;0EAgB6D,CAAC;AAE3E,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;IACzC,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QACtB,MAAM,kBAAkB,EAAE,CAAC;QAC3B,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3D,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,MAAM,OAAO,CAAC,oBAAoB,EAAE,CAAC;QACrC,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAEtE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9B,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,OAAO,CAAC,KAAK,CAAC,kBAAkB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,GAAG,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,WAAY,SAAQ,KAAK;IAC3B,IAAI,SAAiB;CAC/B;AAqED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,aAAa,CAwD9E"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,GAAG,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,WAAY,SAAQ,KAAK;IAC3B,IAAI,SAAiB;CAC/B;AAuED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,aAAa,CA8D9E"}
package/dist/config.js CHANGED
@@ -1,4 +1,4 @@
1
- import { readFileSync, statSync } from "node:fs";
1
+ import { lstatSync, readFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  export class ConfigError extends Error {
@@ -25,9 +25,10 @@ function credential(env) {
25
25
  if (!filePath)
26
26
  throw new ConfigError("D2D_API_KEY or D2D_API_KEY_FILE is required");
27
27
  try {
28
- const file = statSync(filePath);
29
- if (!file.isFile())
30
- throw new ConfigError("D2D_API_KEY_FILE must point to a regular file");
28
+ const file = lstatSync(filePath);
29
+ if (!file.isFile() || file.isSymbolicLink()) {
30
+ throw new ConfigError("D2D_API_KEY_FILE must point to a regular, non-symbolic-link file");
31
+ }
31
32
  if (file.size > MAX_CREDENTIAL_FILE_BYTES) {
32
33
  throw new ConfigError("D2D_API_KEY_FILE is unexpectedly large");
33
34
  }
@@ -77,8 +78,12 @@ export function loadConfig(env = process.env) {
77
78
  catch {
78
79
  throw new ConfigError("D2D_CORE_URL must be a valid URL");
79
80
  }
80
- if (!new Set(["http:", "https:"]).has(coreUrl.protocol)) {
81
- throw new ConfigError("D2D_CORE_URL must use http or https");
81
+ if (coreUrl.username || coreUrl.password || coreUrl.search || coreUrl.hash) {
82
+ throw new ConfigError("D2D_CORE_URL must not include credentials, a query, or a fragment");
83
+ }
84
+ const loopback = ["localhost", "127.0.0.1", "[::1]"].includes(coreUrl.hostname.toLowerCase());
85
+ if (coreUrl.protocol !== "https:" && !(coreUrl.protocol === "http:" && loopback)) {
86
+ throw new ConfigError("D2D_CORE_URL must use HTTPS; HTTP is allowed only for localhost, 127.0.0.1, or [::1]");
82
87
  }
83
88
  const rawAgentKind = env.D2D_AGENT_KIND?.trim().toLowerCase() || "codex";
84
89
  if (!new Set(["codex", "claude", "gemini", "custom"]).has(rawAgentKind)) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoB1C,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,GAAG,aAAa,CAAC;CAC/B;AAED,MAAM,gBAAgB,GAAG,kCAAkC,CAAC;AAC5D,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAExC,SAAS,eAAe,CACtB,KAAyB,EACzB,QAAgB,EAChB,IAAY;IAEZ,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,WAAW,CAAC,GAAG,IAAI,6BAA6B,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,GAAsB;IACxC,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;IAC9C,IAAI,MAAM,IAAI,QAAQ;QAAE,MAAM,IAAI,WAAW,CAAC,iDAAiD,CAAC,CAAC;IACjG,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,WAAW,CAAC,6CAA6C,CAAC,CAAC;IACpF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,MAAM,IAAI,WAAW,CAAC,+CAA+C,CAAC,CAAC;QAC3F,IAAI,IAAI,CAAC,IAAI,GAAG,yBAAyB,EAAE,CAAC;YAC1C,MAAM,IAAI,WAAW,CAAC,wCAAwC,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,WAAW,CAAC,iEAAiE,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,WAAW,CAAC,2BAA2B,CAAC,CAAC;QAC/D,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW;YAAE,MAAM,KAAK,CAAC;QAC9C,MAAM,IAAI,WAAW,CACnB,oCAAoC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAsB;IAC9C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,sBAAsB,EAAE,YAAY,CAAC,CAAC;IAC7G,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,YAAY,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,sBAAsB,EAAE,YAAY,CAAC,CAAC;AAC9G,CAAC;AAED,SAAS,cAAc,CAAC,KAAyB;IAC/C,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CACnB,mCAAmC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC5F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,gBAAgB,CAAC;IAC5D,IAAI,OAAY,CAAC;IACjB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CAAC,kCAAkC,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,WAAW,CAAC,qCAAqC,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,YAAY,GAAG,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC;IACzE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,WAAW,CAAC,yDAAyD,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,SAAS,GAAG,YAAyB,CAAC;IAC5C,MAAM,cAAc,GAAG,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/D,MAAM,YAAY,GAAG,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,cAAc,CAAC;IACrE,IAAI,CAAC,YAAY;QAAE,MAAM,IAAI,WAAW,CAAC,kDAAkD,CAAC,CAAC;IAE7F,MAAM,mBAAmB,GAAG,eAAe,CACzC,GAAG,CAAC,yBAAyB,EAC7B,CAAC,EACD,2BAA2B,CAC5B,CAAC;IACF,MAAM,mBAAmB,GAAG,eAAe,CACzC,GAAG,CAAC,yBAAyB,EAC7B,EAAE,EACF,2BAA2B,CAC5B,CAAC;IACF,IAAI,mBAAmB,GAAG,mBAAmB,EAAE,CAAC;QAC9C,MAAM,IAAI,WAAW,CAAC,sEAAsE,CAAC,CAAC;IAChG,CAAC;IAED,OAAO;QACL,OAAO;QACP,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC;QACvB,SAAS;QACT,YAAY;QACZ,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,mBAAmB,CAAC;QAClD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACpE,YAAY,EAAE,eAAe,CAAC,GAAG,CAAC,uBAAuB,EAAE,KAAK,EAAE,yBAAyB,CAAC,GAAG,KAAK;QACpG,gBAAgB,EACd,eAAe,CAAC,GAAG,CAAC,2BAA2B,EAAE,EAAE,EAAE,6BAA6B,CAAC,GAAG,KAAK;QAC7F,cAAc,EAAE,mBAAmB,GAAG,KAAK;QAC3C,cAAc,EAAE,mBAAmB,GAAG,KAAK;QAC3C,qBAAqB,EACnB,eAAe,CACb,GAAG,CAAC,iCAAiC,EACrC,GAAG,EACH,mCAAmC,CACpC,GAAG,KAAK;QACX,eAAe,EAAE,eAAe,CAAC,GAAG,CAAC,sBAAsB,EAAE,EAAE,EAAE,wBAAwB,CAAC;QAC1F,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC;KACxE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAyBjD,wBAAsB,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAWrE"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiBjD,wBAAsB,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAWrE"}
package/dist/doctor.js CHANGED
@@ -1,30 +1,19 @@
1
- import { spawn } from "node:child_process";
2
1
  import { stat } from "node:fs/promises";
3
2
  import { CoreClient } from "./core-client.js";
3
+ import { runCommand } from "./process.js";
4
4
  async function commandVersion(command) {
5
- return await new Promise((resolve, reject) => {
6
- const child = spawn(command, ["--version"], {
7
- shell: false,
8
- windowsHide: true,
9
- stdio: ["ignore", "pipe", "pipe"],
10
- });
11
- let output = "";
12
- child.stdout.on("data", (chunk) => {
13
- if (output.length < 2_000)
14
- output += chunk.toString("utf8");
15
- });
16
- child.stderr.on("data", (chunk) => {
17
- if (output.length < 2_000)
18
- output += chunk.toString("utf8");
19
- });
20
- child.once("error", () => reject(new Error(`Could not start ${command}`)));
21
- child.once("close", (code) => {
22
- if (code === 0)
23
- resolve(output.trim().split("\n")[0] || "version not reported");
24
- else
25
- reject(new Error(`${command} --version exited with code ${code ?? "unknown"}`));
26
- });
27
- });
5
+ let result;
6
+ try {
7
+ const childEnvironment = { ...process.env };
8
+ delete childEnvironment.D2D_API_KEY;
9
+ result = await runCommand(command, ["--version"], { env: childEnvironment });
10
+ }
11
+ catch {
12
+ throw new Error(`Could not start ${command}`);
13
+ }
14
+ if (result.exitCode !== 0)
15
+ throw new Error(`${command} --version exited with code ${result.exitCode}`);
16
+ return `${result.stdout}\n${result.stderr}`.trim().split("\n")[0] || "version not reported";
28
17
  }
29
18
  export async function doctor(config) {
30
19
  const workspace = await stat(config.workspace);
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,KAAK,UAAU,cAAc,CAAC,OAAe;IAC3C,OAAO,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE;YAC1C,KAAK,EAAE,KAAK;YACZ,WAAW,EAAE,IAAI;YACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3E,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC3B,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,sBAAsB,CAAC,CAAC;;gBAC3E,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,OAAO,+BAA+B,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;QACvF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAqB;IAChD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACzF,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IACrD,OAAO;QACL,oBAAoB,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG;QAC5C,UAAU,MAAM,CAAC,SAAS,KAAK,OAAO,GAAG;QACzC,cAAc,MAAM,CAAC,SAAS,EAAE;QAChC,uBAAuB,MAAM,CAAC,aAAa,aAAa,MAAM,CAAC,aAAa,sBAAsB,MAAM,CAAC,sBAAsB,EAAE;KAClI,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,KAAK,UAAU,cAAc,CAAC,OAAe;IAC3C,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC5C,OAAO,gBAAgB,CAAC,WAAW,CAAC;QACpC,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,+BAA+B,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvG,OAAO,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,sBAAsB,CAAC;AAC9F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAqB;IAChD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACzF,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IACrD,OAAO;QACL,oBAAoB,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG;QAC5C,UAAU,MAAM,CAAC,SAAS,KAAK,OAAO,GAAG;QACzC,cAAc,MAAM,CAAC,SAAS,EAAE;QAChC,uBAAuB,MAAM,CAAC,aAAa,aAAa,MAAM,CAAC,aAAa,sBAAsB,MAAM,CAAC,sBAAsB,EAAE;KAClI,CAAC;AACJ,CAAC"}