@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 +36 -5
- package/dist/cli.js.map +1 -1
- package/dist/core/doctor-render.d.ts +9 -0
- package/dist/core/doctor-render.d.ts.map +1 -0
- package/dist/core/doctor-render.js +91 -0
- package/dist/core/doctor-render.js.map +1 -0
- package/dist/core/doctor.d.ts +61 -0
- package/dist/core/doctor.d.ts.map +1 -0
- package/dist/core/doctor.js +332 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/doctor.test.d.ts +2 -0
- package/dist/core/doctor.test.d.ts.map +1 -0
- package/dist/core/doctor.test.js +143 -0
- package/dist/core/doctor.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/tools/transcribe.d.ts +1 -1
- package/package.json +3 -3
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
|
|
38
|
-
ggeditor continue
|
|
39
|
-
ggeditor login
|
|
40
|
-
ggeditor logout
|
|
41
|
-
ggeditor auth
|
|
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":";AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,SAAS,EACT,SAAS,GAEV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,mFAAmF;AACnF,MAAM,cAAc,GAA4B;IAC9C,WAAW;IACX,QAAQ;IACR,KAAK;IACL,UAAU;IACV,QAAQ;IACR,SAAS;IACT,UAAU;IACV,YAAY;CACb,CAAC;AAEF,SAAS,gBAAgB,CAAC,GAAuB;IAC/C,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,OAAQ,cAA2B,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAA6B,CAAC,CAAC,CAAC,SAAS,CAAC;AACjG,CAAC;AAED,SAAS,IAAI,CAAC,GAAW;IACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC
|
|
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 @@
|
|
|
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":"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"}
|
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";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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.
|
|
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/
|
|
32
|
-
"@kenkaiiii/
|
|
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",
|