@kenkaiiii/gg-editor 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,7 +1,11 @@
1
1
  #!/usr/bin/env node
2
+ import { mkdirSync, writeFileSync } from "node:fs";
3
+ import { dirname } from "node:path";
2
4
  import chalk from "chalk";
3
5
  import { getDefaultModel } from "@kenkaiiii/ggcoder/models";
4
6
  import { AuthStorage, NotLoggedInError, runLogin, runLogout, runStatus, } from "./core/auth/index.js";
7
+ import { isOnboarded, onboardedMarkerPath, runDoctor } from "./core/doctor.js";
8
+ import { renderDoctorReport } from "./core/doctor-render.js";
5
9
  import { discoverSkills } from "./core/skills-loader.js";
6
10
  import { discoverStyles } from "./core/styles-loader.js";
7
11
  import { SKILLS } from "./skills.js";
@@ -34,16 +38,31 @@ function printHelp() {
34
38
  process.stdout.write(`ggeditor — video editor agent for DaVinci Resolve and Premiere Pro
35
39
 
36
40
  USAGE
37
- ggeditor Launch the editor (auto-detects open NLE)
38
- ggeditor continue Resume the most recent session
39
- ggeditor login Authenticate
40
- ggeditor logout Clear credentials
41
- ggeditor auth Show stored credentials
41
+ ggeditor Launch the editor (auto-detects open NLE)
42
+ ggeditor continue Resume the most recent session
43
+ ggeditor login Authenticate
44
+ ggeditor logout Clear credentials
45
+ ggeditor auth Show stored credentials
46
+ ggeditor doctor Check ffmpeg, host detection, API keys, etc.
42
47
 
43
48
  Auth lives in ~/.gg/auth.json — the SAME file ggcoder uses, so logging into
44
49
  either CLI works for both.
45
50
  `);
46
51
  }
52
+ /**
53
+ * Mark the current home as onboarded so we don't re-run the doctor on
54
+ * subsequent launches. Called after a first-run doctor pass succeeds.
55
+ */
56
+ function markOnboarded() {
57
+ const path = onboardedMarkerPath();
58
+ try {
59
+ mkdirSync(dirname(path), { recursive: true });
60
+ writeFileSync(path, new Date().toISOString() + "\n", "utf8");
61
+ }
62
+ catch {
63
+ // Non-fatal — we'll just re-run onboarding next time.
64
+ }
65
+ }
47
66
  async function pickProvider(auth) {
48
67
  for (const p of PROVIDER_ORDER) {
49
68
  if (await auth.hasCredentials(p))
@@ -70,6 +89,11 @@ async function main() {
70
89
  await runStatus();
71
90
  return;
72
91
  }
92
+ if (sub === "doctor") {
93
+ const report = runDoctor();
94
+ process.stdout.write(renderDoctorReport(report));
95
+ return;
96
+ }
73
97
  const isContinue = sub === "continue";
74
98
  if (sub && !isContinue) {
75
99
  fail(`unknown command: ${sub}\nrun: ggeditor --help`);
@@ -78,6 +102,13 @@ async function main() {
78
102
  if (!process.stdin.isTTY) {
79
103
  fail("ggeditor requires an interactive terminal");
80
104
  }
105
+ // First-run onboarding — only when neither the marker nor auth.json
106
+ // exist. Re-runnable any time via `ggeditor doctor`.
107
+ if (!isOnboarded()) {
108
+ const report = runDoctor();
109
+ process.stdout.write(renderDoctorReport(report, { onboarding: true }));
110
+ markOnboarded();
111
+ }
81
112
  const auth = new AuthStorage();
82
113
  await auth.load();
83
114
  const provider = await pickProvider(auth);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { DoctorReport } from "./doctor.js";
2
+ /**
3
+ * Produce the full doctor output. Used by both the explicit
4
+ * `ggeditor doctor` command and the first-run onboarding flow.
5
+ */
6
+ export declare function renderDoctorReport(report: DoctorReport, opts?: {
7
+ onboarding?: boolean;
8
+ }): string;
9
+ //# sourceMappingURL=doctor-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-render.d.ts","sourceRoot":"","sources":["../../src/core/doctor-render.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,aAAa,CAAC;AAoC7D;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,MAAM,CA2DR"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Pretty-printer for DoctorReport. Lives next to the doctor logic so
3
+ * the chalk dependency stays scoped to user-facing CLI output.
4
+ */
5
+ import chalk from "chalk";
6
+ const SEVERITY_LABEL = {
7
+ block: "BLOCK",
8
+ required: "REQUIRED",
9
+ optional: "OPTIONAL",
10
+ info: "INFO",
11
+ };
12
+ function statusGlyph(c) {
13
+ if (c.status === "ok")
14
+ return chalk.green("✓");
15
+ if (c.status === "warn")
16
+ return chalk.yellow("!");
17
+ // missing — color by severity
18
+ if (c.severity === "required" || c.severity === "block")
19
+ return chalk.red("✗");
20
+ if (c.severity === "optional")
21
+ return chalk.yellow("○");
22
+ return chalk.dim("·");
23
+ }
24
+ /** Render a single check as a 3-4 line block. */
25
+ function renderCheck(c) {
26
+ const lines = [];
27
+ const badge = chalk.dim(`[${SEVERITY_LABEL[c.severity]}]`);
28
+ const header = `${statusGlyph(c)} ${chalk.bold(c.label)} ${badge} ${chalk.dim(c.detail)}`;
29
+ lines.push(header);
30
+ lines.push(chalk.dim(" Unlocks: ") + c.unlocks);
31
+ if (c.fix) {
32
+ const fixed = c.fix
33
+ .split("\n")
34
+ .map((l) => " " + chalk.cyan(l))
35
+ .join("\n");
36
+ lines.push(chalk.dim(" Fix:"));
37
+ lines.push(fixed);
38
+ }
39
+ return lines.join("\n");
40
+ }
41
+ /**
42
+ * Produce the full doctor output. Used by both the explicit
43
+ * `ggeditor doctor` command and the first-run onboarding flow.
44
+ */
45
+ export function renderDoctorReport(report, opts = {}) {
46
+ const out = [];
47
+ if (opts.onboarding) {
48
+ out.push("");
49
+ out.push(chalk.bold("Welcome to gg-editor."));
50
+ out.push("Quick environment check before we go. This runs once; re-run any time with `ggeditor doctor`.");
51
+ out.push("");
52
+ }
53
+ else {
54
+ out.push("");
55
+ out.push(chalk.bold("gg-editor — environment doctor"));
56
+ out.push("");
57
+ }
58
+ // Group: required > optional > info
59
+ const groups = [
60
+ { title: chalk.bold("Required"), severities: ["block", "required"] },
61
+ { title: chalk.bold("Recommended (optional)"), severities: ["optional"] },
62
+ { title: chalk.dim("Informational"), severities: ["info"] },
63
+ ];
64
+ for (const group of groups) {
65
+ const items = report.checks.filter((c) => group.severities.includes(c.severity));
66
+ if (items.length === 0)
67
+ continue;
68
+ out.push(group.title);
69
+ out.push("");
70
+ for (const c of items)
71
+ out.push(renderCheck(c));
72
+ out.push("");
73
+ }
74
+ // Summary line
75
+ const missingRequired = report.checks.filter((c) => c.severity === "required" && c.status !== "ok");
76
+ const missingOptional = report.checks.filter((c) => c.severity === "optional" && c.status !== "ok");
77
+ if (report.ready) {
78
+ out.push(chalk.green("✓ Ready to launch.") + chalk.dim(" Run `ggeditor` to start."));
79
+ }
80
+ else {
81
+ out.push(chalk.yellow("! ") +
82
+ chalk.bold(`${missingRequired.length} required item${missingRequired.length === 1 ? "" : "s"} missing.`) +
83
+ " You can still launch ggeditor, but most tools will error until they're installed.");
84
+ }
85
+ if (missingOptional.length > 0) {
86
+ out.push(chalk.dim(` ${missingOptional.length} optional item${missingOptional.length === 1 ? "" : "s"} would unlock more features (see above).`));
87
+ }
88
+ out.push("");
89
+ return out.join("\n");
90
+ }
91
+ //# sourceMappingURL=doctor-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-render.js","sourceRoot":"","sources":["../../src/core/doctor-render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * First-run doctor — environment probes + actionable install hints.
3
+ *
4
+ * The CLI runs onboarding on first launch (no `~/.gg/auth.json` and no
5
+ * `~/.gg/onboarded-ggeditor` marker). The same checks are exposed via
6
+ * `ggeditor doctor` so users can re-run it any time.
7
+ *
8
+ * Design rules:
9
+ * - Probes only. We never auto-install anything — surprise sudo
10
+ * prompts are worse than a missing dep.
11
+ * - Each check carries `severity`:
12
+ * block — nothing meaningful works without it (none currently;
13
+ * the agent can run with zero deps)
14
+ * required — most tools need it (ffmpeg / ffprobe)
15
+ * optional — unlocks a feature group (openai-key, resolve,
16
+ * premiere, whisper-cpp, whisperx)
17
+ * info — purely informational (auth status)
18
+ * - Each check tells the user EXACTLY what to do to fix it, including
19
+ * the platform-appropriate install command.
20
+ * - Pure module — no I/O writes, no side effects beyond `spawnSync` /
21
+ * `existsSync` probes.
22
+ */
23
+ export type CheckSeverity = "block" | "required" | "optional" | "info";
24
+ export type CheckStatus = "ok" | "missing" | "warn";
25
+ export interface DoctorCheck {
26
+ /** Stable id (also the check key). */
27
+ id: string;
28
+ /** ≤30 char display label. */
29
+ label: string;
30
+ status: CheckStatus;
31
+ severity: CheckSeverity;
32
+ /** One-line current state ("v6.1.1 found", "not on PATH", …). */
33
+ detail: string;
34
+ /**
35
+ * What this check unlocks for the user. Always present, even when
36
+ * status=ok — gives the user the mental model.
37
+ */
38
+ unlocks: string;
39
+ /**
40
+ * Fix instruction. Multi-line ok. Empty when status=ok.
41
+ * Platform-appropriate (macOS / linux / win32).
42
+ */
43
+ fix?: string;
44
+ }
45
+ export interface DoctorReport {
46
+ checks: DoctorCheck[];
47
+ /** True when no `severity=required` check is missing. */
48
+ ready: boolean;
49
+ /** Where the marker file was/should be written. */
50
+ markerPath: string;
51
+ /** Whether onboarding has been completed before. */
52
+ onboarded: boolean;
53
+ }
54
+ export declare function onboardedMarkerPath(home?: string): string;
55
+ export declare function isOnboarded(home?: string): boolean;
56
+ /**
57
+ * Run every check. Synchronous and quick — only spawns short-lived
58
+ * `--version` style probes.
59
+ */
60
+ export declare function runDoctor(home?: string): DoctorReport;
61
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/core/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAEvE,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,aAAa,CAAC;IACxB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;CACpB;AAID,wBAAgB,mBAAmB,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAEpE;AAED,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAkB,GAAG,OAAO,CAM7D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAAkB,GAAG,YAAY,CAqBhE"}
@@ -0,0 +1,332 @@
1
+ /**
2
+ * First-run doctor — environment probes + actionable install hints.
3
+ *
4
+ * The CLI runs onboarding on first launch (no `~/.gg/auth.json` and no
5
+ * `~/.gg/onboarded-ggeditor` marker). The same checks are exposed via
6
+ * `ggeditor doctor` so users can re-run it any time.
7
+ *
8
+ * Design rules:
9
+ * - Probes only. We never auto-install anything — surprise sudo
10
+ * prompts are worse than a missing dep.
11
+ * - Each check carries `severity`:
12
+ * block — nothing meaningful works without it (none currently;
13
+ * the agent can run with zero deps)
14
+ * required — most tools need it (ffmpeg / ffprobe)
15
+ * optional — unlocks a feature group (openai-key, resolve,
16
+ * premiere, whisper-cpp, whisperx)
17
+ * info — purely informational (auth status)
18
+ * - Each check tells the user EXACTLY what to do to fix it, including
19
+ * the platform-appropriate install command.
20
+ * - Pure module — no I/O writes, no side effects beyond `spawnSync` /
21
+ * `existsSync` probes.
22
+ */
23
+ import { existsSync, statSync } from "node:fs";
24
+ import { homedir, platform } from "node:os";
25
+ import { join } from "node:path";
26
+ import { spawnSync } from "node:child_process";
27
+ import { detectHost } from "./hosts/detect.js";
28
+ import { checkFfmpeg, checkFfprobe } from "./media/ffmpeg.js";
29
+ const ONBOARDED_MARKER = "onboarded-ggeditor";
30
+ export function onboardedMarkerPath(home = homedir()) {
31
+ return join(home, ".gg", ONBOARDED_MARKER);
32
+ }
33
+ export function isOnboarded(home = homedir()) {
34
+ try {
35
+ return statSync(onboardedMarkerPath(home)).isFile();
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
41
+ /**
42
+ * Run every check. Synchronous and quick — only spawns short-lived
43
+ * `--version` style probes.
44
+ */
45
+ export function runDoctor(home = homedir()) {
46
+ const checks = [
47
+ checkFfmpegProbe(),
48
+ checkFfprobeProbe(),
49
+ checkOpenAIKey(),
50
+ checkAnthropicKey(),
51
+ checkPython(),
52
+ checkResolve(),
53
+ checkPremiere(),
54
+ checkWhisperCpp(),
55
+ checkWhisperX(),
56
+ checkAuthFile(home),
57
+ ];
58
+ const ready = checks.every((c) => c.severity !== "required" || c.status === "ok");
59
+ return {
60
+ checks,
61
+ ready,
62
+ markerPath: onboardedMarkerPath(home),
63
+ onboarded: isOnboarded(home),
64
+ };
65
+ }
66
+ // ── Individual probes ──────────────────────────────────────
67
+ function checkFfmpegProbe() {
68
+ const ok = checkFfmpeg();
69
+ return {
70
+ id: "ffmpeg",
71
+ label: "ffmpeg",
72
+ status: ok ? "ok" : "missing",
73
+ severity: "required",
74
+ detail: ok ? versionLine("ffmpeg") : "not on PATH",
75
+ unlocks: "Most tools (transcoding, captions, color grading, silence/filler cuts, transitions, " +
76
+ "audio mixing, GIF/thumbnail generation). ~70% of the toolkit.",
77
+ fix: ok ? undefined : ffmpegInstallHint(),
78
+ };
79
+ }
80
+ function checkFfprobeProbe() {
81
+ const ok = checkFfprobe();
82
+ return {
83
+ id: "ffprobe",
84
+ label: "ffprobe",
85
+ status: ok ? "ok" : "missing",
86
+ severity: "required",
87
+ detail: ok ? versionLine("ffprobe") : "not on PATH",
88
+ unlocks: "probe_media (fps / duration / codec detection — runs on every input file).",
89
+ fix: ok ? undefined : ffmpegInstallHint(),
90
+ };
91
+ }
92
+ function checkOpenAIKey() {
93
+ const present = !!process.env.OPENAI_API_KEY;
94
+ return {
95
+ id: "openai-key",
96
+ label: "OPENAI_API_KEY",
97
+ status: present ? "ok" : "missing",
98
+ severity: "optional",
99
+ detail: present ? "set in environment" : "not set",
100
+ unlocks: "Vision tools: analyze_hook (retention scoring), score_shot, color_match, " +
101
+ "grade_skin_tones, match_clip_color, and the OpenAI transcription backend.",
102
+ fix: present
103
+ ? undefined
104
+ : "Get a key at https://platform.openai.com/api-keys, then:\n" +
105
+ " export OPENAI_API_KEY=sk-...\n" +
106
+ " # add to ~/.zshrc / ~/.bashrc to persist",
107
+ };
108
+ }
109
+ function checkAnthropicKey() {
110
+ // Anthropic auth normally goes through OAuth (~/.gg/auth.json). The env
111
+ // var only matters for users who prefer raw API keys. We mark it as
112
+ // info — auth status is what really matters.
113
+ const present = !!process.env.ANTHROPIC_API_KEY;
114
+ return {
115
+ id: "anthropic-key",
116
+ label: "ANTHROPIC_API_KEY",
117
+ status: present ? "ok" : "missing",
118
+ severity: "info",
119
+ detail: present
120
+ ? "set in environment (overrides OAuth token if present)"
121
+ : "not set (OAuth is the recommended path)",
122
+ unlocks: "Direct Anthropic API auth without OAuth. Most users should `ggeditor login` instead.",
123
+ fix: undefined,
124
+ };
125
+ }
126
+ function checkPython() {
127
+ const candidates = platform() === "win32" ? ["py", "python", "python3"] : ["python3", "python"];
128
+ for (const cmd of candidates) {
129
+ const r = spawnSync(cmd, cmd === "py" ? ["-3", "--version"] : ["--version"], {
130
+ encoding: "utf8",
131
+ });
132
+ if (r.status === 0) {
133
+ const out = (r.stdout || r.stderr).trim();
134
+ return {
135
+ id: "python",
136
+ label: "Python 3",
137
+ status: "ok",
138
+ severity: "optional",
139
+ detail: `${cmd}: ${out}`,
140
+ unlocks: "DaVinci Resolve scripting bridge (host integration). Without Python, file-only " +
141
+ "mode still works.",
142
+ };
143
+ }
144
+ }
145
+ return {
146
+ id: "python",
147
+ label: "Python 3",
148
+ status: "missing",
149
+ severity: "optional",
150
+ detail: "no python3 / python / py interpreter found",
151
+ unlocks: "DaVinci Resolve scripting bridge (host integration). File-only mode works without it.",
152
+ fix: platform() === "darwin"
153
+ ? "brew install python@3.12 # or use python.org installer"
154
+ : platform() === "linux"
155
+ ? "sudo apt install python3 # debian/ubuntu — your distro's package manager otherwise"
156
+ : "winget install Python.Python.3 # or python.org installer",
157
+ };
158
+ }
159
+ function checkResolve() {
160
+ const detected = detectHost();
161
+ if (detected.name === "resolve") {
162
+ return {
163
+ id: "resolve",
164
+ label: "DaVinci Resolve",
165
+ status: "ok",
166
+ severity: "optional",
167
+ detail: "running",
168
+ unlocks: "Live timeline editing on Resolve: cut, marker, append, color grade, smart reframe, render.",
169
+ };
170
+ }
171
+ // Resolve isn't running — but is it INSTALLED? Check the canonical
172
+ // install path so the message is precise.
173
+ const installed = isResolveInstalled();
174
+ return {
175
+ id: "resolve",
176
+ label: "DaVinci Resolve",
177
+ status: "missing",
178
+ severity: "optional",
179
+ detail: installed ? "installed but not running" : "not installed",
180
+ unlocks: "Live timeline editing on Resolve. Open Resolve before launching ggeditor (or " +
181
+ "mid-session — the agent re-detects every 2s).",
182
+ fix: installed
183
+ ? "Open DaVinci Resolve, then re-run ggeditor (or just keep going — ggeditor will pick " +
184
+ "it up automatically within a few seconds)."
185
+ : "Install the free version from https://www.blackmagicdesign.com/products/davinciresolve",
186
+ };
187
+ }
188
+ function checkPremiere() {
189
+ const detected = detectHost();
190
+ if (detected.name === "premiere") {
191
+ return {
192
+ id: "premiere",
193
+ label: "Adobe Premiere Pro",
194
+ status: "ok",
195
+ severity: "optional",
196
+ detail: "running",
197
+ unlocks: "Live timeline editing on Premiere via the gg-editor UXP panel (insert / cut / marker " +
198
+ "/ render). Requires the panel installed (`ggeditor-premiere-panel install`).",
199
+ };
200
+ }
201
+ // Premiere is paid; we don't try to detect installation. Just note it.
202
+ return {
203
+ id: "premiere",
204
+ label: "Adobe Premiere Pro",
205
+ status: "missing",
206
+ severity: "optional",
207
+ detail: "not running",
208
+ unlocks: "Live timeline editing on Premiere. Open Premiere + install the gg-editor panel.",
209
+ fix: "Open Premiere Pro, then install the panel:\n npx @kenkaiiii/gg-editor-premiere-panel install",
210
+ };
211
+ }
212
+ function checkWhisperCpp() {
213
+ for (const cmd of ["whisper-cli", "whisper", "main"]) {
214
+ const r = spawnSync(cmd, ["--help"], { encoding: "utf8" });
215
+ if (r.status === 0 && (r.stdout + r.stderr).toLowerCase().includes("whisper")) {
216
+ return {
217
+ id: "whisper-cpp",
218
+ label: "whisper.cpp",
219
+ status: "ok",
220
+ severity: "optional",
221
+ detail: `${cmd} on PATH`,
222
+ unlocks: "Local transcription (free, fast, private). Without it, transcribe falls back to " +
223
+ "the OpenAI API (requires OPENAI_API_KEY).",
224
+ };
225
+ }
226
+ }
227
+ return {
228
+ id: "whisper-cpp",
229
+ label: "whisper.cpp",
230
+ status: "missing",
231
+ severity: "optional",
232
+ detail: "not on PATH",
233
+ unlocks: "Local transcription. Without it, transcribe uses the OpenAI API (requires OPENAI_API_KEY).",
234
+ fix: platform() === "darwin"
235
+ ? "brew install whisper-cpp # then download a model from https://huggingface.co/ggerganov/whisper.cpp"
236
+ : "Build from source: https://github.com/ggml-org/whisper.cpp",
237
+ };
238
+ }
239
+ function checkWhisperX() {
240
+ const r = spawnSync("whisperx", ["--help"], { encoding: "utf8" });
241
+ const ok = r.status === 0;
242
+ const hfToken = !!process.env.HF_TOKEN;
243
+ if (ok && hfToken) {
244
+ return {
245
+ id: "whisperx",
246
+ label: "whisperx + HF_TOKEN",
247
+ status: "ok",
248
+ severity: "optional",
249
+ detail: "whisperx on PATH, HF_TOKEN set",
250
+ unlocks: "Speaker diarization (transcribe with diarize=true). Required for read_transcript with " +
251
+ "speaker filters.",
252
+ };
253
+ }
254
+ if (ok && !hfToken) {
255
+ return {
256
+ id: "whisperx",
257
+ label: "whisperx + HF_TOKEN",
258
+ status: "warn",
259
+ severity: "optional",
260
+ detail: "whisperx on PATH but HF_TOKEN not set",
261
+ unlocks: "Speaker diarization (transcribe with diarize=true).",
262
+ fix: "Get a token at https://huggingface.co/settings/tokens (free), then:\n" +
263
+ " export HF_TOKEN=hf_...\n" +
264
+ "Also accept the pyannote model terms: https://huggingface.co/pyannote/speaker-diarization-3.1",
265
+ };
266
+ }
267
+ return {
268
+ id: "whisperx",
269
+ label: "whisperx + HF_TOKEN",
270
+ status: "missing",
271
+ severity: "optional",
272
+ detail: "whisperx not on PATH",
273
+ unlocks: "Speaker diarization (transcribe with diarize=true).",
274
+ fix: "pip install whisperx\n" +
275
+ "export HF_TOKEN=hf_... # https://huggingface.co/settings/tokens\n" +
276
+ "Then accept https://huggingface.co/pyannote/speaker-diarization-3.1 model terms.",
277
+ };
278
+ }
279
+ function checkAuthFile(home) {
280
+ const path = join(home, ".gg", "auth.json");
281
+ const exists = (() => {
282
+ try {
283
+ return statSync(path).isFile();
284
+ }
285
+ catch {
286
+ return false;
287
+ }
288
+ })();
289
+ return {
290
+ id: "auth",
291
+ label: "Auth (~/.gg/auth.json)",
292
+ status: exists ? "ok" : "missing",
293
+ severity: "required",
294
+ detail: exists ? `present at ${path}` : "not configured",
295
+ unlocks: "The agent itself. Without auth, ggeditor can't talk to a model provider.",
296
+ fix: exists
297
+ ? undefined
298
+ : "Run `ggeditor login` and pick a provider (Anthropic OAuth recommended; OpenAI / GLM / " +
299
+ "Moonshot also supported). Auth is shared with ggcoder via ~/.gg/auth.json — log in once.",
300
+ };
301
+ }
302
+ // ── Helpers ────────────────────────────────────────────────
303
+ function versionLine(cmd) {
304
+ const r = spawnSync(cmd, ["-version"], { encoding: "utf8" });
305
+ if (r.status !== 0)
306
+ return "found";
307
+ const first = (r.stdout.split(/\r?\n/)[0] || "").trim();
308
+ return first || "found";
309
+ }
310
+ function ffmpegInstallHint() {
311
+ switch (platform()) {
312
+ case "darwin":
313
+ return "brew install ffmpeg";
314
+ case "linux":
315
+ return "sudo apt install ffmpeg # debian/ubuntu — your distro's package manager otherwise";
316
+ case "win32":
317
+ return "winget install ffmpeg # or scoop install ffmpeg";
318
+ default:
319
+ return "Install ffmpeg from https://ffmpeg.org/download.html";
320
+ }
321
+ }
322
+ function isResolveInstalled() {
323
+ if (platform() === "darwin") {
324
+ return existsSync("/Applications/DaVinci Resolve/DaVinci Resolve.app");
325
+ }
326
+ if (platform() === "win32") {
327
+ return existsSync("C:\\Program Files\\Blackmagic Design\\DaVinci Resolve\\Resolve.exe");
328
+ }
329
+ // Linux: Resolve installs into /opt/resolve by default.
330
+ return existsSync("/opt/resolve/bin/resolve");
331
+ }
332
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/core/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=doctor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.test.d.ts","sourceRoot":"","sources":["../../src/core/doctor.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,143 @@
1
+ import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { describe, expect, it } from "vitest";
5
+ import { isOnboarded, onboardedMarkerPath, runDoctor } from "./doctor.js";
6
+ /**
7
+ * The doctor module is mostly env probes; we don't try to mock spawn.
8
+ * What we DO test is:
9
+ * - Every check is present and well-formed.
10
+ * - severity / status semantics are consistent.
11
+ * - The marker file plumbing works against a synthetic home dir.
12
+ * - `ready` reflects required-check status correctly.
13
+ */
14
+ describe("runDoctor", () => {
15
+ it("returns a check for every documented id", () => {
16
+ const r = runDoctor();
17
+ const ids = r.checks.map((c) => c.id).sort();
18
+ expect(ids).toEqual([
19
+ "anthropic-key",
20
+ "auth",
21
+ "ffmpeg",
22
+ "ffprobe",
23
+ "openai-key",
24
+ "premiere",
25
+ "python",
26
+ "resolve",
27
+ "whisper-cpp",
28
+ "whisperx",
29
+ ].sort());
30
+ });
31
+ it("every check has label / detail / unlocks populated", () => {
32
+ const r = runDoctor();
33
+ for (const c of r.checks) {
34
+ expect(c.label.length).toBeGreaterThan(0);
35
+ expect(c.label.length).toBeLessThanOrEqual(40);
36
+ expect(c.detail.length).toBeGreaterThan(0);
37
+ expect(c.unlocks.length).toBeGreaterThan(0);
38
+ }
39
+ });
40
+ it("only checks with status='missing' or 'warn' carry a fix message", () => {
41
+ const r = runDoctor();
42
+ for (const c of r.checks) {
43
+ if (c.status === "ok") {
44
+ expect(c.fix).toBeUndefined();
45
+ }
46
+ }
47
+ });
48
+ it("ready === true only when every required check is ok", () => {
49
+ const r = runDoctor();
50
+ const requiredOk = r.checks
51
+ .filter((c) => c.severity === "required")
52
+ .every((c) => c.status === "ok");
53
+ expect(r.ready).toBe(requiredOk);
54
+ });
55
+ it("returns a markerPath inside the user's home", () => {
56
+ const r = runDoctor();
57
+ expect(r.markerPath).toContain(".gg");
58
+ expect(r.markerPath).toContain("onboarded-ggeditor");
59
+ });
60
+ });
61
+ describe("isOnboarded / onboardedMarkerPath", () => {
62
+ it("returns false when the marker is absent", () => {
63
+ const home = mkdtempSync(join(tmpdir(), "gg-doctor-"));
64
+ expect(isOnboarded(home)).toBe(false);
65
+ });
66
+ it("returns true once the marker file exists", () => {
67
+ const home = mkdtempSync(join(tmpdir(), "gg-doctor-"));
68
+ const path = onboardedMarkerPath(home);
69
+ mkdirSync(join(home, ".gg"), { recursive: true });
70
+ writeFileSync(path, "2026-04-30T00:00:00.000Z\n", "utf8");
71
+ expect(isOnboarded(home)).toBe(true);
72
+ });
73
+ it("returns false when the marker path exists but isn't a regular file", () => {
74
+ const home = mkdtempSync(join(tmpdir(), "gg-doctor-"));
75
+ // Create a directory at the marker path instead of a file.
76
+ mkdirSync(onboardedMarkerPath(home), { recursive: true });
77
+ expect(isOnboarded(home)).toBe(false);
78
+ });
79
+ it("auth check sees a present auth.json under the synthetic home", () => {
80
+ const home = mkdtempSync(join(tmpdir(), "gg-doctor-"));
81
+ mkdirSync(join(home, ".gg"), { recursive: true });
82
+ writeFileSync(join(home, ".gg", "auth.json"), "{}", "utf8");
83
+ const r = runDoctor(home);
84
+ const auth = r.checks.find((c) => c.id === "auth");
85
+ expect(auth.status).toBe("ok");
86
+ expect(auth.detail).toContain("auth.json");
87
+ });
88
+ it("auth check reports missing on a fresh home", () => {
89
+ const home = mkdtempSync(join(tmpdir(), "gg-doctor-"));
90
+ const r = runDoctor(home);
91
+ const auth = r.checks.find((c) => c.id === "auth");
92
+ expect(auth.status).toBe("missing");
93
+ expect(auth.fix).toContain("ggeditor login");
94
+ });
95
+ });
96
+ describe("doctor severity / status invariants", () => {
97
+ it("OPENAI_API_KEY status follows the env var", () => {
98
+ const prev = process.env.OPENAI_API_KEY;
99
+ delete process.env.OPENAI_API_KEY;
100
+ try {
101
+ const r = runDoctor();
102
+ const k = r.checks.find((c) => c.id === "openai-key");
103
+ expect(k.status).toBe("missing");
104
+ expect(k.severity).toBe("optional");
105
+ expect(k.fix).toContain("OPENAI_API_KEY");
106
+ }
107
+ finally {
108
+ if (prev !== undefined)
109
+ process.env.OPENAI_API_KEY = prev;
110
+ }
111
+ process.env.OPENAI_API_KEY = "test-fake-key";
112
+ try {
113
+ const r = runDoctor();
114
+ const k = r.checks.find((c) => c.id === "openai-key");
115
+ expect(k.status).toBe("ok");
116
+ expect(k.fix).toBeUndefined();
117
+ }
118
+ finally {
119
+ if (prev === undefined)
120
+ delete process.env.OPENAI_API_KEY;
121
+ else
122
+ process.env.OPENAI_API_KEY = prev;
123
+ }
124
+ });
125
+ it("ANTHROPIC_API_KEY check is informational (never blocks)", () => {
126
+ const r = runDoctor();
127
+ const k = r.checks.find((c) => c.id === "anthropic-key");
128
+ expect(k.severity).toBe("info");
129
+ });
130
+ it("ffmpeg / ffprobe checks are required", () => {
131
+ const r = runDoctor();
132
+ const ff = r.checks.find((c) => c.id === "ffmpeg");
133
+ const fp = r.checks.find((c) => c.id === "ffprobe");
134
+ expect(ff.severity).toBe("required");
135
+ expect(fp.severity).toBe("required");
136
+ });
137
+ it("host probes (resolve/premiere) are optional", () => {
138
+ const r = runDoctor();
139
+ expect(r.checks.find((c) => c.id === "resolve").severity).toBe("optional");
140
+ expect(r.checks.find((c) => c.id === "premiere").severity).toBe("optional");
141
+ });
142
+ });
143
+ //# sourceMappingURL=doctor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.test.js","sourceRoot":"","sources":["../../src/core/doctor.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1E;;;;;;;GAOG;AAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7C,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CACjB;YACE,eAAe;YACf,MAAM;YACN,QAAQ;YACR,SAAS;YACT,YAAY;YACZ,UAAU;YACV,QAAQ;YACR,SAAS;YACT,aAAa;YACb,UAAU;SACX,CAAC,IAAI,EAAE,CACT,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;gBACtB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM;aACxB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC;aACxC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACvC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,aAAa,CAAC,IAAI,EAAE,4BAA4B,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;QACvD,2DAA2D;QAC3D,SAAS,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;QACvD,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC5D,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QACxC,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,YAAY,CAAE,CAAC;YACvD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACjC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACpC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC5C,CAAC;gBAAS,CAAC;YACT,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC;QAC5D,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,eAAe,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,YAAY,CAAE,CAAC;YACvD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5B,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;QAChC,CAAC;gBAAS,CAAC;YACT,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;;gBACrD,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC;QACzC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAE,CAAC;QAC1D,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAE,CAAC;QACpD,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAE,CAAC;QACrD,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5E,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -6,6 +6,9 @@ export { createLazyHost } from "./core/hosts/lazy.js";
6
6
  export type { LazyHost, LazyHostOptions } from "./core/hosts/lazy.js";
7
7
  export { checkFfmpeg, checkFfprobe, probeMedia, runFfmpeg } from "./core/media/ffmpeg.js";
8
8
  export type { FfmpegResult, MediaProbe } from "./core/media/ffmpeg.js";
9
+ export { isOnboarded, onboardedMarkerPath, runDoctor } from "./core/doctor.js";
10
+ export type { CheckSeverity, CheckStatus, DoctorCheck, DoctorReport } from "./core/doctor.js";
11
+ export { renderDoctorReport } from "./core/doctor-render.js";
9
12
  export { buildEditorSystemPrompt, buildEditorStaticBody, buildEditorHostBlock, spliceHostBlock, } from "./system-prompt.js";
10
13
  export type { StaticPromptOptions } from "./system-prompt.js";
11
14
  export { AuthStorage, AUTH_FILE, NotLoggedInError, generatePKCE, loginAnthropic, loginOpenAI, refreshAnthropicToken, refreshOpenAIToken, runLogin, runLogout, runStatus, } from "./core/auth/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGjE,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGvE,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGjE,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGvE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -5,6 +5,9 @@ export { createHost, detectHost, HostUnreachableError, HostUnsupportedError, Non
5
5
  export { createLazyHost } from "./core/hosts/lazy.js";
6
6
  // Media
7
7
  export { checkFfmpeg, checkFfprobe, probeMedia, runFfmpeg } from "./core/media/ffmpeg.js";
8
+ // Doctor / first-run onboarding
9
+ export { isOnboarded, onboardedMarkerPath, runDoctor } from "./core/doctor.js";
10
+ export { renderDoctorReport } from "./core/doctor-render.js";
8
11
  // System prompt
9
12
  export { buildEditorSystemPrompt, buildEditorStaticBody, buildEditorHostBlock, spliceHostBlock, } from "./system-prompt.js";
10
13
  // Auth (shared with ggcoder via ~/.gg/auth.json)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,QAAQ;AACR,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG1F,gBAAgB;AAChB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,iDAAiD;AACjD,OAAO,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,QAAQ;AACR,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG1F,gCAAgC;AAChC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,gBAAgB;AAChB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,iDAAiD;AACjD,OAAO,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC"}
@@ -4,9 +4,9 @@ declare const TranscribeParams: z.ZodObject<{
4
4
  input: z.ZodString;
5
5
  output: z.ZodString;
6
6
  backend: z.ZodOptional<z.ZodEnum<{
7
+ whisperx: "whisperx";
7
8
  local: "local";
8
9
  api: "api";
9
- whisperx: "whisperx";
10
10
  auto: "auto";
11
11
  }>>;
12
12
  modelPath: z.ZodOptional<z.ZodString>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenkaiiii/gg-editor",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "CLI video editor agent. Drives DaVinci Resolve and Premiere Pro via API + hotkeys + GUI fallback.",
6
6
  "license": "MIT",
@@ -28,8 +28,8 @@
28
28
  "ws": "^8.18.0",
29
29
  "zod": "^4.3.6",
30
30
  "@kenkaiiii/gg-agent": "4.3.84",
31
- "@kenkaiiii/ggcoder": "4.3.84",
32
- "@kenkaiiii/gg-ai": "4.3.84"
31
+ "@kenkaiiii/gg-ai": "4.3.84",
32
+ "@kenkaiiii/ggcoder": "4.3.84"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/node": "^25.6.0",