adde-acp 0.1.3

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 (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +88 -0
  3. package/README.md +88 -0
  4. package/dist/backend/acp/client.d.ts +149 -0
  5. package/dist/backend/acp/client.js +538 -0
  6. package/dist/backend/acp/client.js.map +1 -0
  7. package/dist/backend/acp/index.d.ts +8 -0
  8. package/dist/backend/acp/index.js +7 -0
  9. package/dist/backend/acp/index.js.map +1 -0
  10. package/dist/backend/acp/lifecycle.d.ts +15 -0
  11. package/dist/backend/acp/lifecycle.js +56 -0
  12. package/dist/backend/acp/lifecycle.js.map +1 -0
  13. package/dist/backend/acp/perm-diff.d.ts +37 -0
  14. package/dist/backend/acp/perm-diff.js +58 -0
  15. package/dist/backend/acp/perm-diff.js.map +1 -0
  16. package/dist/backend/acp/spawn.d.ts +20 -0
  17. package/dist/backend/acp/spawn.js +70 -0
  18. package/dist/backend/acp/spawn.js.map +1 -0
  19. package/dist/cli/adde.d.ts +2 -0
  20. package/dist/cli/adde.js +11 -0
  21. package/dist/cli/adde.js.map +1 -0
  22. package/dist/cli/alias.d.ts +45 -0
  23. package/dist/cli/alias.js +94 -0
  24. package/dist/cli/alias.js.map +1 -0
  25. package/dist/cli/completion.d.ts +4 -0
  26. package/dist/cli/completion.js +209 -0
  27. package/dist/cli/completion.js.map +1 -0
  28. package/dist/cli/init.d.ts +3 -0
  29. package/dist/cli/init.js +114 -0
  30. package/dist/cli/init.js.map +1 -0
  31. package/dist/cli/lane.d.ts +20 -0
  32. package/dist/cli/lane.js +350 -0
  33. package/dist/cli/lane.js.map +1 -0
  34. package/dist/cli/ops.d.ts +5 -0
  35. package/dist/cli/ops.js +230 -0
  36. package/dist/cli/ops.js.map +1 -0
  37. package/dist/cli/prompt.d.ts +15 -0
  38. package/dist/cli/prompt.js +41 -0
  39. package/dist/cli/prompt.js.map +1 -0
  40. package/dist/cli/run.d.ts +5 -0
  41. package/dist/cli/run.js +216 -0
  42. package/dist/cli/run.js.map +1 -0
  43. package/dist/cli/spec.d.ts +48 -0
  44. package/dist/cli/spec.js +98 -0
  45. package/dist/cli/spec.js.map +1 -0
  46. package/dist/core/diagnostics.d.ts +73 -0
  47. package/dist/core/diagnostics.js +333 -0
  48. package/dist/core/diagnostics.js.map +1 -0
  49. package/dist/core/index.d.ts +11 -0
  50. package/dist/core/index.js +9 -0
  51. package/dist/core/index.js.map +1 -0
  52. package/dist/core/injector.d.ts +27 -0
  53. package/dist/core/injector.js +297 -0
  54. package/dist/core/injector.js.map +1 -0
  55. package/dist/core/lane-config.d.ts +80 -0
  56. package/dist/core/lane-config.js +303 -0
  57. package/dist/core/lane-config.js.map +1 -0
  58. package/dist/core/launchd.d.ts +81 -0
  59. package/dist/core/launchd.js +216 -0
  60. package/dist/core/launchd.js.map +1 -0
  61. package/dist/core/messages.d.ts +31 -0
  62. package/dist/core/messages.js +71 -0
  63. package/dist/core/messages.js.map +1 -0
  64. package/dist/core/queue.d.ts +74 -0
  65. package/dist/core/queue.js +227 -0
  66. package/dist/core/queue.js.map +1 -0
  67. package/dist/core/runtime-state.d.ts +52 -0
  68. package/dist/core/runtime-state.js +90 -0
  69. package/dist/core/runtime-state.js.map +1 -0
  70. package/dist/core/session-ledger.d.ts +25 -0
  71. package/dist/core/session-ledger.js +89 -0
  72. package/dist/core/session-ledger.js.map +1 -0
  73. package/dist/core/supervisor.d.ts +41 -0
  74. package/dist/core/supervisor.js +315 -0
  75. package/dist/core/supervisor.js.map +1 -0
  76. package/dist/core/transcript.d.ts +22 -0
  77. package/dist/core/transcript.js +93 -0
  78. package/dist/core/transcript.js.map +1 -0
  79. package/dist/core/update-check.d.ts +25 -0
  80. package/dist/core/update-check.js +142 -0
  81. package/dist/core/update-check.js.map +1 -0
  82. package/dist/core/version.d.ts +7 -0
  83. package/dist/core/version.js +32 -0
  84. package/dist/core/version.js.map +1 -0
  85. package/dist/gate/gate.d.ts +41 -0
  86. package/dist/gate/gate.js +28 -0
  87. package/dist/gate/gate.js.map +1 -0
  88. package/dist/gate/index.d.ts +6 -0
  89. package/dist/gate/index.js +6 -0
  90. package/dist/gate/index.js.map +1 -0
  91. package/dist/shared/conf.d.ts +54 -0
  92. package/dist/shared/conf.js +85 -0
  93. package/dist/shared/conf.js.map +1 -0
  94. package/dist/shared/deny-match.d.ts +19 -0
  95. package/dist/shared/deny-match.js +122 -0
  96. package/dist/shared/deny-match.js.map +1 -0
  97. package/dist/shared/envelope.d.ts +37 -0
  98. package/dist/shared/envelope.js +91 -0
  99. package/dist/shared/envelope.js.map +1 -0
  100. package/dist/shared/errors.d.ts +8 -0
  101. package/dist/shared/errors.js +23 -0
  102. package/dist/shared/errors.js.map +1 -0
  103. package/dist/shared/fs-atomic.d.ts +17 -0
  104. package/dist/shared/fs-atomic.js +31 -0
  105. package/dist/shared/fs-atomic.js.map +1 -0
  106. package/dist/shared/i18n.d.ts +23 -0
  107. package/dist/shared/i18n.js +53 -0
  108. package/dist/shared/i18n.js.map +1 -0
  109. package/dist/shared/locales/en.d.ts +393 -0
  110. package/dist/shared/locales/en.js +447 -0
  111. package/dist/shared/locales/en.js.map +1 -0
  112. package/dist/shared/locales/ko.d.ts +389 -0
  113. package/dist/shared/locales/ko.js +443 -0
  114. package/dist/shared/locales/ko.js.map +1 -0
  115. package/dist/shared/mask.d.ts +6 -0
  116. package/dist/shared/mask.js +28 -0
  117. package/dist/shared/mask.js.map +1 -0
  118. package/dist/shared/notify.d.ts +15 -0
  119. package/dist/shared/notify.js +20 -0
  120. package/dist/shared/notify.js.map +1 -0
  121. package/dist/shared/paths.d.ts +42 -0
  122. package/dist/shared/paths.js +83 -0
  123. package/dist/shared/paths.js.map +1 -0
  124. package/dist/src-adapters/index.d.ts +8 -0
  125. package/dist/src-adapters/index.js +6 -0
  126. package/dist/src-adapters/index.js.map +1 -0
  127. package/dist/src-adapters/markdown.d.ts +80 -0
  128. package/dist/src-adapters/markdown.js +794 -0
  129. package/dist/src-adapters/markdown.js.map +1 -0
  130. package/dist/src-adapters/source.d.ts +33 -0
  131. package/dist/src-adapters/source.js +3 -0
  132. package/dist/src-adapters/source.js.map +1 -0
  133. package/dist/src-adapters/telegram.d.ts +48 -0
  134. package/dist/src-adapters/telegram.js +412 -0
  135. package/dist/src-adapters/telegram.js.map +1 -0
  136. package/package.json +62 -0
@@ -0,0 +1,230 @@
1
+ /**
2
+ * `adde status|doctor|logs` — 운영 가시성 명령의 CLI 표면.
3
+ * core/diagnostics 의 읽기 전용 로직을 호출하고 표/JSON/텍스트로 표면화한다.
4
+ */
5
+ import { collectStatus, collectAllStatus, runDoctor, readLogs } from "../core/diagnostics.js";
6
+ import { checkForUpdate, formatUpdateNotice } from "../core/update-check.js";
7
+ import { errMsg } from "../shared/errors.js";
8
+ import { USAGE } from "../core/messages.js";
9
+ import { t } from "../shared/i18n.js";
10
+ import { readLedger, formatWhen } from "../core/session-ledger.js";
11
+ import { lanePaths, defaultBase } from "../shared/paths.js";
12
+ import { readFile } from "node:fs/promises";
13
+ /** ms → 사람용 경과시간(예: 1h2m, 3m4s, 12s). */
14
+ function formatUptime(ms) {
15
+ if (ms === null)
16
+ return "-";
17
+ const s = Math.floor(ms / 1000);
18
+ if (s < 60)
19
+ return `${s}s`;
20
+ const m = Math.floor(s / 60);
21
+ if (m < 60)
22
+ return `${m}m${s % 60}s`;
23
+ const h = Math.floor(m / 60);
24
+ return `${h}h${m % 60}m`;
25
+ }
26
+ /** ISO 시각 → 현재 기준 경과(예: 12s, 3m4s). null 이면 "-". */
27
+ function formatAge(iso) {
28
+ if (iso === null)
29
+ return "-";
30
+ const ms = Date.now() - Date.parse(iso);
31
+ return formatUptime(Number.isFinite(ms) ? Math.max(0, ms) : null);
32
+ }
33
+ function statusTable(rows) {
34
+ if (rows.length === 0)
35
+ return t("ops.status.noLanesConf");
36
+ const header = ["LANE", "STATUS", "PID", "UPTIME", "SEEN", "SOURCE"];
37
+ const body = rows.map((r) => [
38
+ r.lane,
39
+ r.status,
40
+ r.pid === null ? "-" : String(r.pid),
41
+ formatUptime(r.uptimeMs),
42
+ formatAge(r.lastSeenAt),
43
+ r.source ?? "-",
44
+ ]);
45
+ const widths = header.map((h, i) => Math.max(h.length, ...body.map((row) => (row[i] ?? "").length)));
46
+ const fmt = (cols) => cols.map((c, i) => c.padEnd(widths[i] ?? 0)).join(" ");
47
+ return [fmt(header), ...body.map(fmt)].join("\n");
48
+ }
49
+ /**
50
+ * 집계 status 표 — PROJECT 컬럼을 앞에 둔다(다중 프로젝트 뷰).
51
+ * 단일 프로젝트 표(statusTable)와 분리 — 기존 `status <proj>` 출력은 불변.
52
+ */
53
+ function statusTableAggregate(rows, all) {
54
+ if (rows.length === 0) {
55
+ return all ? t("ops.status.noLanesRegistered") : t("ops.status.noRunning");
56
+ }
57
+ const header = ["PROJECT", "LANE", "STATUS", "PID", "UPTIME", "SEEN", "SOURCE"];
58
+ const body = rows.map((r) => [
59
+ r.proj,
60
+ r.lane,
61
+ r.status,
62
+ r.pid === null ? "-" : String(r.pid),
63
+ formatUptime(r.uptimeMs),
64
+ formatAge(r.lastSeenAt),
65
+ r.source ?? "-",
66
+ ]);
67
+ const widths = header.map((h, i) => Math.max(h.length, ...body.map((row) => (row[i] ?? "").length)));
68
+ const fmt = (cols) => cols.map((c, i) => c.padEnd(widths[i] ?? 0)).join(" ");
69
+ return [fmt(header), ...body.map(fmt)].join("\n");
70
+ }
71
+ /**
72
+ * 새 npm 버전이 있으면 안내 한 줄을 stdout 에 덧붙인다(보조 — 조회 실패는 무시).
73
+ * 네트워크 조회는 대화형(TTY)에서만 허용해 파이프·스크립트에는 지연·잡음을 주지 않는다.
74
+ */
75
+ async function printUpdateNoticeIfAny() {
76
+ try {
77
+ const notice = await checkForUpdate({ allowNetwork: process.stdout.isTTY === true });
78
+ if (notice)
79
+ process.stdout.write("\n" + formatUpdateNotice(notice) + "\n");
80
+ }
81
+ catch {
82
+ // 보조 기능 — 조회 실패는 흡수.
83
+ }
84
+ }
85
+ export async function runStatus(rest) {
86
+ const json = rest.includes("--json");
87
+ const all = rest.includes("--all");
88
+ const proj = rest.find((a) => !a.startsWith("--"));
89
+ // 인자 없음 → 전 프로젝트 집계(CCTG parity). 기본은 실행 중(정지 제외), --all 은 정지 포함 전체.
90
+ if (!proj) {
91
+ const allRows = await collectAllStatus();
92
+ const rows = all ? allRows : allRows.filter((r) => r.status !== "stopped");
93
+ if (json) {
94
+ process.stdout.write(JSON.stringify(rows, null, 2) + "\n");
95
+ }
96
+ else {
97
+ process.stdout.write(statusTableAggregate(rows, all) + "\n");
98
+ const dead = rows.filter((r) => r.status === "dead");
99
+ if (dead.length > 0) {
100
+ process.stdout.write("\n" +
101
+ t("ops.status.deadWarnAggregate", {
102
+ lanes: dead.map((r) => `${r.proj}/${r.lane}`).join(", "),
103
+ }) +
104
+ "\n");
105
+ }
106
+ const stale = rows.filter((r) => r.status === "stale");
107
+ if (stale.length > 0) {
108
+ process.stdout.write("\n" +
109
+ t("ops.status.staleWarnAggregate", {
110
+ lanes: stale.map((r) => `${r.proj}/${r.lane}`).join(", "),
111
+ }) +
112
+ "\n");
113
+ }
114
+ await printUpdateNoticeIfAny();
115
+ }
116
+ return rows.some((r) => r.status === "dead" || r.status === "stale") ? 1 : 0;
117
+ }
118
+ const rows = await collectStatus(proj);
119
+ if (json) {
120
+ process.stdout.write(JSON.stringify(rows, null, 2) + "\n");
121
+ }
122
+ else {
123
+ process.stdout.write(statusTable(rows) + "\n");
124
+ const dead = rows.filter((r) => r.status === "dead");
125
+ if (dead.length > 0) {
126
+ process.stdout.write("\n" +
127
+ t("ops.status.deadWarnSingle", { lanes: dead.map((r) => r.lane).join(", "), proj }) +
128
+ "\n");
129
+ }
130
+ const stale = rows.filter((r) => r.status === "stale");
131
+ if (stale.length > 0) {
132
+ process.stdout.write("\n" +
133
+ t("ops.status.staleWarnSingle", { lanes: stale.map((r) => r.lane).join(", "), proj }) +
134
+ "\n");
135
+ }
136
+ await printUpdateNoticeIfAny();
137
+ }
138
+ // 비정상(dead 크래시·stale 행) 잔존을 종료 코드로 신호 — 모니터링 친화.
139
+ return rows.some((r) => r.status === "dead" || r.status === "stale") ? 1 : 0;
140
+ }
141
+ function checkSymbol(level) {
142
+ return level === "PASS" ? "✔" : level === "WARN" ? "▲" : "✘";
143
+ }
144
+ export async function runDoctorCli(rest) {
145
+ const proj = rest.find((a) => !a.startsWith("--"));
146
+ const checks = await runDoctor(proj);
147
+ for (const c of checks) {
148
+ process.stdout.write(`${checkSymbol(c.level)} [${c.level}] ${c.name}: ${c.detail}\n`);
149
+ if (c.hint)
150
+ process.stdout.write(t("ops.doctor.hint", { hint: c.hint }) + "\n");
151
+ }
152
+ const fails = checks.filter((c) => c.level === "FAIL").length;
153
+ const warns = checks.filter((c) => c.level === "WARN").length;
154
+ process.stdout.write("\n" +
155
+ t("ops.doctor.summary", { pass: checks.length - fails - warns, warn: warns, fail: fails }) +
156
+ "\n");
157
+ await printUpdateNoticeIfAny();
158
+ return fails > 0 ? 1 : 0;
159
+ }
160
+ /** `adde sessions <proj> <lane>` — 세션 장부 목록(read-only). 재개는 채널 명령으로 수행. */
161
+ export async function runSessions(rest) {
162
+ const [proj, lane] = rest;
163
+ if (!proj || !lane) {
164
+ process.stderr.write(USAGE.sessions + "\n");
165
+ return 1;
166
+ }
167
+ let paths;
168
+ try {
169
+ paths = lanePaths(defaultBase(), proj, lane);
170
+ }
171
+ catch (err) {
172
+ process.stderr.write(errMsg(err) + "\n");
173
+ return 1;
174
+ }
175
+ const entries = await readLedger(paths);
176
+ if (entries.length === 0) {
177
+ process.stdout.write(t("injector.control.sessionsEmpty") + "\n");
178
+ return 0;
179
+ }
180
+ let current = null;
181
+ try {
182
+ current = (await readFile(paths.sessionIdFile, "utf8")).trim() || null;
183
+ }
184
+ catch {
185
+ // 세션 파일 부재 — 현재 표시 생략
186
+ }
187
+ const lines = entries.map((e, i) => {
188
+ const label = e.label ?? t("injector.control.sessionsNoLabel");
189
+ const mark = e.id === current ? " ◀" : "";
190
+ return (t("injector.control.sessionsItem", {
191
+ n: i + 1,
192
+ label,
193
+ last: formatWhen(e.lastActivityAt),
194
+ id: e.id,
195
+ }) + mark);
196
+ });
197
+ process.stdout.write(`${t("injector.control.sessionsHeader")}\n${lines.join("\n")}\n\n${t("injector.control.sessionsHint")}\n`);
198
+ return 0;
199
+ }
200
+ export async function runLogs(rest) {
201
+ const engine = rest.includes("--engine");
202
+ const positional = rest.filter((a) => !a.startsWith("--"));
203
+ const [proj, lane, nRaw] = positional;
204
+ if (!proj || !lane) {
205
+ process.stderr.write(USAGE.logs + "\n");
206
+ return 1;
207
+ }
208
+ const n = nRaw !== undefined && /^\d+$/.test(nRaw) ? Number(nRaw) : 50;
209
+ let result;
210
+ try {
211
+ result = await readLogs(proj, lane, n, { engine });
212
+ }
213
+ catch (err) {
214
+ // proj/lane 검증 실패(경로 탈출 차단 등) — 친절한 메시지 후 비정상 종료코드.
215
+ process.stderr.write(errMsg(err) + "\n");
216
+ return 1;
217
+ }
218
+ if (!result.exists) {
219
+ const what = engine ? t("ops.logs.whatEngine") : t("ops.logs.whatTranscript");
220
+ process.stdout.write(t("ops.logs.notFound", { what, path: result.path, proj }) + "\n");
221
+ return 0;
222
+ }
223
+ if (result.lines.length === 0) {
224
+ process.stdout.write(t("ops.logs.empty", { path: result.path }) + "\n");
225
+ return 0;
226
+ }
227
+ process.stdout.write(result.lines.join("\n") + "\n");
228
+ return 0;
229
+ }
230
+ //# sourceMappingURL=ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops.js","sourceRoot":"","sources":["../../src/cli/ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** 한 줄 질의 함수 — (질문, 기본값) → 응답. */
2
+ export type Ask = (question: string, def?: string) => Promise<string>;
3
+ export interface Prompter {
4
+ ask: Ask;
5
+ /** 가려진 입력(에코 억제) — 봇 토큰 등 시크릿 수집용. 기본값 없음. */
6
+ askSecret: (question: string) => Promise<string>;
7
+ close: () => void;
8
+ }
9
+ /** 주입 가능한 입출력(테스트용). 미지정 시 process.stdin/stdout. */
10
+ export interface PrompterDeps {
11
+ input?: NodeJS.ReadableStream;
12
+ output?: NodeJS.WritableStream;
13
+ }
14
+ /** process.stdin/stdout 에 붙는 대화형 프롬프터를 만든다(TTY 에서 사용). */
15
+ export declare function createPrompter(deps?: PrompterDeps): Prompter;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * 대화형 프롬프트 — readline 기반 질의(ask)와 가려진 입력(askSecret).
3
+ * askSecret 은 출력 스트림을 일시 뮤트해 봇 토큰 등 시크릿이 화면에 에코되지 않게 한다
4
+ * (시크릿 비노출 원칙 — transcript·화면 평문 노출 금지).
5
+ */
6
+ import * as readline from "node:readline/promises";
7
+ import { Writable } from "node:stream";
8
+ /** process.stdin/stdout 에 붙는 대화형 프롬프터를 만든다(TTY 에서 사용). */
9
+ export function createPrompter(deps = {}) {
10
+ const input = deps.input ?? process.stdin;
11
+ const sink = deps.output ?? process.stdout;
12
+ let muted = false;
13
+ // 뮤트 가능 출력 — askSecret 동안 readline 의 키 에코를 삼킨다.
14
+ const out = new Writable({
15
+ write(chunk, _enc, cb) {
16
+ if (!muted)
17
+ sink.write(chunk);
18
+ cb();
19
+ },
20
+ });
21
+ const rl = readline.createInterface({ input, output: out, terminal: true });
22
+ const ask = async (question, def) => {
23
+ const a = (await rl.question(`${question}${def ? ` [${def}]` : ""}: `)).trim();
24
+ return a || (def ?? "");
25
+ };
26
+ const askSecret = async (question) => {
27
+ // 프롬프트는 뮤트 전에 출력하고, 입력 구간만 뮤트해 에코를 억제.
28
+ sink.write(`${question}: `);
29
+ muted = true;
30
+ try {
31
+ const a = await rl.question("");
32
+ return a.trim();
33
+ }
34
+ finally {
35
+ muted = false;
36
+ sink.write("\n");
37
+ }
38
+ };
39
+ return { ask, askSecret, close: () => rl.close() };
40
+ }
41
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAkBvC,0DAA0D;AAC1D,MAAM,UAAU,cAAc,CAAC,OAAqB,EAAE;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAC3C,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,gDAAgD;IAChD,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC;QACvB,KAAK,CAAC,KAAa,EAAE,IAAI,EAAE,EAAE;YAC3B,IAAI,CAAC,KAAK;gBAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC9B,EAAE,EAAE,CAAC;QACP,CAAC;KACF,CAAC,CAAC;IACH,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5E,MAAM,GAAG,GAAQ,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/E,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,KAAK,EAAE,QAAgB,EAAmB,EAAE;QAC5D,uCAAuC;QACvC,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;QAC5B,KAAK,GAAG,IAAI,CAAC;QACb,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAChC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAClB,CAAC;gBAAS,CAAC;YACT,KAAK,GAAG,KAAK,CAAC;YACd,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;AACrD,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * CLI 진입 로직. adde / add 양쪽 진입점이 공유한다.
3
+ * @returns 프로세스 종료 코드.
4
+ */
5
+ export declare function run(argv: readonly string[]): Promise<number>;
@@ -0,0 +1,216 @@
1
+ import { readVersion } from "../core/version.js";
2
+ import { errMsg } from "../shared/errors.js";
3
+ import { COMMANDS, buildUsage, USAGE, cmdError } from "../core/messages.js";
4
+ import { formatException } from "../shared/notify.js";
5
+ import { t } from "../shared/i18n.js";
6
+ import { findCommand, suggestCommands } from "./spec.js";
7
+ import { completionScript, SUPPORTED_SHELLS } from "./completion.js";
8
+ /** -h/--help 플래그가 인자에 있는지. */
9
+ function wantsHelp(argv) {
10
+ return argv.includes("--help") || argv.includes("-h");
11
+ }
12
+ /**
13
+ * 포그라운드 데몬 워커 로직 — `adde __daemon <proj>` 가 호출한다.
14
+ * supervisorUp 후 SIGTERM/SIGINT graceful shutdown 까지 포그라운드 상주.
15
+ * launchd KeepAlive 재기동 시에도 이 경로로 진입한다.
16
+ */
17
+ async function runDaemonForeground(proj) {
18
+ const { supervisorUp, supervisorDown } = await import("../core/supervisor.js");
19
+ const result = await supervisorUp(proj);
20
+ process.stdout.write(`${result.message}\n`);
21
+ // 기동 실패 레인은 원인 + 조치(doctor/logs)를 인라인 표면화.
22
+ const errorLanes = result.lanes.filter((l) => l.status === "error");
23
+ for (const l of errorLanes) {
24
+ process.stderr.write(formatException({
25
+ situation: t("run.laneStartFailed.situation", {
26
+ lane: l.lane,
27
+ error: l.error ?? t("run.unknownCause"),
28
+ }),
29
+ action: t("run.laneStartFailed.action", { proj, lane: l.lane }),
30
+ }) + "\n");
31
+ }
32
+ const running = result.lanes.filter((l) => l.status === "running");
33
+ if (running.length === 0) {
34
+ // 레인 conf 자체가 없으면 생성 단계를 안내한다.
35
+ if (result.lanes.length === 0) {
36
+ process.stderr.write(formatException({
37
+ situation: t("run.noLanes.situation", { proj }),
38
+ action: t("run.noLanes.action", { proj }),
39
+ }) + "\n");
40
+ }
41
+ // 기동된 레인이 없으면 상주할 이유가 없다 — 오류 레인이 있으면 1.
42
+ return errorLanes.length > 0 ? 1 : 0;
43
+ }
44
+ // 종료 신호 시 graceful shutdown — supervisorDown 으로 엔진 child·소스를 정리한 뒤 종료.
45
+ // await 완료 후에만 exit(typescript 규칙: 비동기 작업이 끝나기 전에 process.exit 금지).
46
+ let shuttingDown = false;
47
+ const shutdown = (sig) => {
48
+ if (shuttingDown)
49
+ return;
50
+ shuttingDown = true;
51
+ process.stderr.write(`\n${t("run.signalShutdown", { sig })}\n`);
52
+ void supervisorDown(proj)
53
+ .then((r) => {
54
+ process.stdout.write(`${r.message}\n`);
55
+ process.exit(0);
56
+ })
57
+ .catch((err) => {
58
+ process.stderr.write(formatException({
59
+ situation: t("run.shutdownError.situation", {
60
+ error: errMsg(err),
61
+ }),
62
+ action: t("run.shutdownError.action"),
63
+ }) + "\n");
64
+ process.exit(1);
65
+ });
66
+ };
67
+ process.once("SIGINT", () => shutdown("SIGINT"));
68
+ process.once("SIGTERM", () => shutdown("SIGTERM"));
69
+ // 레인 기동 성공 → 소스 루프가 이벤트 루프를 유지하는 동안 포그라운드 상주.
70
+ // 종료(SIGTERM/SIGINT) 까지 resolve 하지 않아 진입점의 process.exit 를 막는다.
71
+ await new Promise(() => { });
72
+ return 0; // 도달하지 않음
73
+ }
74
+ /**
75
+ * CLI 진입 로직. adde / add 양쪽 진입점이 공유한다.
76
+ * @returns 프로세스 종료 코드.
77
+ */
78
+ export async function run(argv) {
79
+ const [first, second] = argv;
80
+ if (first === "--version" || first === "-v") {
81
+ process.stdout.write(`${COMMANDS.primary} ${readVersion()}\n`);
82
+ return 0;
83
+ }
84
+ // 서브커맨드별 도움말 — `adde <cmd> --help`. lane 은 runLane 가 자체 처리(하위 명령 도움말).
85
+ if (first !== undefined && first !== "lane" && wantsHelp(argv.slice(1))) {
86
+ const spec = findCommand(first);
87
+ if (spec?.usageKey && !spec.hidden) {
88
+ process.stdout.write(t(spec.usageKey) + "\n");
89
+ return 0;
90
+ }
91
+ }
92
+ if (first === "completion") {
93
+ const shell = second;
94
+ if (!shell) {
95
+ process.stderr.write(USAGE.completion + "\n");
96
+ return 1;
97
+ }
98
+ const script = completionScript(shell);
99
+ if (script === null) {
100
+ process.stderr.write(cmdError("completion", t("completion.unknownShell", { shell, supported: SUPPORTED_SHELLS.join("|") })) + "\n");
101
+ return 1;
102
+ }
103
+ process.stdout.write(script);
104
+ return 0;
105
+ }
106
+ if (first === "init") {
107
+ const { runInit } = await import("./init.js");
108
+ return runInit(argv.slice(1));
109
+ }
110
+ if (first === "alias") {
111
+ const { runAlias } = await import("./init.js");
112
+ return runAlias(argv.slice(1));
113
+ }
114
+ if (first === "lane") {
115
+ const { runLane } = await import("./lane.js");
116
+ return runLane(argv.slice(1));
117
+ }
118
+ if (first === "status") {
119
+ const { runStatus } = await import("./ops.js");
120
+ return runStatus(argv.slice(1));
121
+ }
122
+ if (first === "doctor") {
123
+ const { runDoctorCli } = await import("./ops.js");
124
+ return runDoctorCli(argv.slice(1));
125
+ }
126
+ if (first === "logs") {
127
+ const { runLogs } = await import("./ops.js");
128
+ return runLogs(argv.slice(1));
129
+ }
130
+ if (first === "sessions") {
131
+ const { runSessions } = await import("./ops.js");
132
+ return runSessions(argv.slice(1));
133
+ }
134
+ // 내부 서브커맨드 — launchd 가 데몬 워커로 기동하는 포그라운드 상주 진입점.
135
+ // 도움말 미노출(최소 표면). 사용자가 직접 부르지 않는 내부 명령.
136
+ if (first === "__daemon") {
137
+ const proj = second;
138
+ if (!proj) {
139
+ process.stderr.write(t("usage.daemon") + "\n");
140
+ return 1;
141
+ }
142
+ try {
143
+ return await runDaemonForeground(proj);
144
+ }
145
+ catch (err) {
146
+ process.stderr.write(cmdError("__daemon", errMsg(err)) + "\n");
147
+ return 1;
148
+ }
149
+ }
150
+ if (first === "up") {
151
+ const proj = second;
152
+ if (!proj) {
153
+ process.stderr.write(USAGE.up + "\n");
154
+ return 1;
155
+ }
156
+ try {
157
+ const { loadDaemon } = await import("../core/launchd.js");
158
+ await loadDaemon(proj);
159
+ process.stdout.write(t("run.upDone", { proj }) + "\n");
160
+ process.stdout.write(t("run.statusHint", { proj }) + "\n");
161
+ return 0;
162
+ }
163
+ catch (err) {
164
+ process.stderr.write(cmdError("up", errMsg(err)) + "\n");
165
+ return 1;
166
+ }
167
+ }
168
+ if (first === "down") {
169
+ const proj = second;
170
+ if (!proj) {
171
+ process.stderr.write(USAGE.down + "\n");
172
+ return 1;
173
+ }
174
+ try {
175
+ const { unloadDaemon } = await import("../core/launchd.js");
176
+ await unloadDaemon(proj);
177
+ process.stdout.write(t("run.downDone", { proj }) + "\n");
178
+ return 0;
179
+ }
180
+ catch (err) {
181
+ process.stderr.write(cmdError("down", errMsg(err)) + "\n");
182
+ return 1;
183
+ }
184
+ }
185
+ if (first === "restart") {
186
+ const proj = second;
187
+ if (!proj) {
188
+ process.stderr.write(USAGE.restart + "\n");
189
+ return 1;
190
+ }
191
+ try {
192
+ const { unloadDaemon, loadDaemon } = await import("../core/launchd.js");
193
+ // down 완료 await 후 up — 부분 실패 시 up 오류 표면화.
194
+ await unloadDaemon(proj);
195
+ await loadDaemon(proj);
196
+ process.stdout.write(t("run.restartDone", { proj }) + "\n");
197
+ process.stdout.write(t("run.statusHint", { proj }) + "\n");
198
+ return 0;
199
+ }
200
+ catch (err) {
201
+ process.stderr.write(cmdError("restart", errMsg(err)) + "\n");
202
+ return 1;
203
+ }
204
+ }
205
+ // 인자 없음·명시적 도움말 → 사용법(정상 종료).
206
+ if (first === undefined || first === "-h" || first === "--help" || first === "help") {
207
+ process.stdout.write(`${buildUsage()}\n`);
208
+ return 0;
209
+ }
210
+ // 미지원 명령 → stderr 로 오류(+오타 추정 힌트) + 사용법, 비정상 종료(스크립트 오류 은폐 방지).
211
+ const suggestions = suggestCommands(first);
212
+ const hint = suggestions.length > 0 ? " " + t("cli.didYouMean", { cmds: suggestions.join(", ") }) : "";
213
+ process.stderr.write(`${t("cli.unknownCmd", { cmd: first })}${hint}\n\n${buildUsage()}\n`);
214
+ return 1;
215
+ }
216
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * CLI 명령·플래그 스펙(SSOT) — 셸 자동완성·서브커맨드 도움말·미지원 명령 힌트가 공유한다.
3
+ * 명령/플래그를 한 곳에서 선언해 자동완성·힌트가 함께 갱신되도록(확장성): 새 명령·플래그는
4
+ * 여기에 추가하면 completion·help·"did you mean" 힌트에 자동 반영된다. 문구 본문(설명)은
5
+ * i18n 카탈로그가 소유하고, 본 스펙은 이름·인자 형태·플래그 목록(구조)만 담는다.
6
+ */
7
+ /** 위치 인자 종류 — 자동완성 동적 후보(proj/lane 이름 스캔)를 결정한다. */
8
+ export type ArgKind = "proj" | "lane";
9
+ /** 최상위 명령 스펙. usageKey 는 `adde <cmd> --help` 및 인자 누락 시 출력할 i18n usage 키. */
10
+ export interface CommandSpec {
11
+ /** 명령 이름(디스패치·자동완성 후보). */
12
+ name: string;
13
+ /** 위치 인자 형태 힌트(예: `<proj>`, `[<proj>]`). */
14
+ args: string;
15
+ /** 이 명령이 받는 옵션 플래그(자동완성·힌트용). */
16
+ flags: readonly string[];
17
+ /** 위치 인자 종류(순서대로) — 자동완성이 해당 위치에서 proj/lane 이름을 완성한다. */
18
+ positional?: readonly ArgKind[];
19
+ /** zsh 자동완성에서 명령 옆에 표시할 짧은 설명(영문). */
20
+ desc?: string;
21
+ /** i18n usage 키(있으면 `--help`·인자누락 시 출력). */
22
+ usageKey?: string;
23
+ /** 하위 명령 이름(예: lane 의 add/ls/show/rm). */
24
+ subs?: readonly string[];
25
+ /** 도움말·자동완성 노출 제외(내부 명령). */
26
+ hidden?: boolean;
27
+ }
28
+ /** 값이 열거형인 플래그 — 자동완성이 플래그 뒤에서 이 값들을 완성한다. */
29
+ export declare const FLAG_VALUES: Record<string, readonly string[]>;
30
+ /** 디렉터리 경로를 받는 플래그 — 자동완성이 뒤에서 디렉터리를 완성한다. */
31
+ export declare const DIR_FLAGS: readonly ["--cwd", "--root"];
32
+ /** 전역 옵션(모든 명령 위치에서 완성 후보). */
33
+ export declare const GLOBAL_FLAGS: readonly ["-h", "--help", "-v", "--version"];
34
+ /** `lane add` 옵션 플래그(SSOT — lane.ts ADD_VALUE_KEYS 의 표면형 `--key`). */
35
+ export declare const LANE_ADD_FLAGS: readonly ["--source", "--engine", "--backend", "--channel", "--perm-tier", "--acp-version", "--cwd", "--allowlist", "--denylist", "--hard-deny", "--safe-defaults", "--lang", "--chat-id", "--allow-from", "--file-mode", "--token-stdin", "--root", "--inbox", "--approvals", "--outbox", "--force", "--interactive", "--no-interactive"];
36
+ /** lane 하위 명령(정식 이름 — list/remove 별칭은 자동완성 미노출, 디스패치만 허용). */
37
+ export declare const LANE_SUBS: readonly ["add", "ls", "show", "rm", "help"];
38
+ /** 최상위 명령 SSOT. hidden 명령은 도움말·자동완성에서 제외. */
39
+ export declare const COMMAND_SPECS: readonly CommandSpec[];
40
+ /** 도움말·자동완성에 노출할 명령(hidden 제외). */
41
+ export declare function visibleCommands(): CommandSpec[];
42
+ /** 이름으로 명령 스펙 조회(디스패치 힌트·help 라우팅). */
43
+ export declare function findCommand(name: string): CommandSpec | undefined;
44
+ /**
45
+ * 오타 추정 — 후보 중 대상과 편집거리가 가장 가까운 이름들(임계 이하)을 반환.
46
+ * 미지원 명령 힌트("did you mean")용. 완전 일치는 호출 전 이미 걸러진 상태를 가정.
47
+ */
48
+ export declare function suggestCommands(input: string, max?: number): string[];