gooseworks 0.4.2 → 0.4.4

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 (84) hide show
  1. package/README.md +42 -11
  2. package/dist/commands/doctor.d.ts +29 -5
  3. package/dist/commands/doctor.d.ts.map +1 -1
  4. package/dist/commands/doctor.js +107 -63
  5. package/dist/commands/doctor.js.map +1 -1
  6. package/dist/commands/fetch.d.ts +1 -0
  7. package/dist/commands/fetch.d.ts.map +1 -1
  8. package/dist/commands/fetch.js +64 -29
  9. package/dist/commands/fetch.js.map +1 -1
  10. package/dist/commands/install.d.ts.map +1 -1
  11. package/dist/commands/install.js +37 -4
  12. package/dist/commands/install.js.map +1 -1
  13. package/dist/commands/login.d.ts.map +1 -1
  14. package/dist/commands/login.js +8 -3
  15. package/dist/commands/login.js.map +1 -1
  16. package/dist/commands/skills.d.ts +34 -0
  17. package/dist/commands/skills.d.ts.map +1 -0
  18. package/dist/commands/skills.js +109 -0
  19. package/dist/commands/skills.js.map +1 -0
  20. package/dist/commands/update.d.ts.map +1 -1
  21. package/dist/commands/update.js +17 -6
  22. package/dist/commands/update.js.map +1 -1
  23. package/dist/commands/video-local.d.ts +9 -0
  24. package/dist/commands/video-local.d.ts.map +1 -0
  25. package/dist/commands/video-local.js +83 -0
  26. package/dist/commands/video-local.js.map +1 -0
  27. package/dist/commands/video-save.d.ts +3 -0
  28. package/dist/commands/video-save.d.ts.map +1 -0
  29. package/dist/commands/video-save.js +83 -0
  30. package/dist/commands/video-save.js.map +1 -0
  31. package/dist/index.js +7 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/lib/video-local-captions.d.ts +83 -0
  34. package/dist/lib/video-local-captions.d.ts.map +1 -0
  35. package/dist/lib/video-local-captions.js +261 -0
  36. package/dist/lib/video-local-captions.js.map +1 -0
  37. package/dist/lib/video-local-runtime.d.ts +8 -0
  38. package/dist/lib/video-local-runtime.d.ts.map +1 -0
  39. package/dist/lib/video-local-runtime.js +201 -0
  40. package/dist/lib/video-local-runtime.js.map +1 -0
  41. package/dist/lib/video-save-mcp.d.ts +9 -0
  42. package/dist/lib/video-save-mcp.d.ts.map +1 -0
  43. package/dist/lib/video-save-mcp.js +162 -0
  44. package/dist/lib/video-save-mcp.js.map +1 -0
  45. package/dist/lib/video-save.d.ts +77 -0
  46. package/dist/lib/video-save.d.ts.map +1 -0
  47. package/dist/lib/video-save.js +440 -0
  48. package/dist/lib/video-save.js.map +1 -0
  49. package/dist/skills/custom-video-skill.d.ts +3 -0
  50. package/dist/skills/custom-video-skill.d.ts.map +1 -0
  51. package/dist/skills/custom-video-skill.js +6 -0
  52. package/dist/skills/custom-video-skill.js.map +1 -0
  53. package/dist/skills/installer.d.ts +12 -6
  54. package/dist/skills/installer.d.ts.map +1 -1
  55. package/dist/skills/installer.js +41 -15
  56. package/dist/skills/installer.js.map +1 -1
  57. package/dist/skills/master-skill.d.ts +22 -19
  58. package/dist/skills/master-skill.d.ts.map +1 -1
  59. package/dist/skills/master-skill.js +1472 -551
  60. package/dist/skills/master-skill.js.map +1 -1
  61. package/dist/skills/package-freshness.d.ts +16 -0
  62. package/dist/skills/package-freshness.d.ts.map +1 -0
  63. package/dist/skills/package-freshness.js +36 -0
  64. package/dist/skills/package-freshness.js.map +1 -0
  65. package/dist/skills/releases.d.ts +12 -0
  66. package/dist/skills/releases.d.ts.map +1 -0
  67. package/dist/skills/releases.js +152 -0
  68. package/dist/skills/releases.js.map +1 -0
  69. package/dist/skills/routes.d.ts.map +1 -1
  70. package/dist/skills/routes.js +7 -1
  71. package/dist/skills/routes.js.map +1 -1
  72. package/dist/utils/browser-preflight.d.ts +29 -0
  73. package/dist/utils/browser-preflight.d.ts.map +1 -0
  74. package/dist/utils/browser-preflight.js +338 -0
  75. package/dist/utils/browser-preflight.js.map +1 -0
  76. package/package.json +2 -2
  77. package/skills/goose-ads/SKILL.md +124 -16
  78. package/skills/goose-product-photos/SKILL.md +55 -3
  79. package/skills/goose-video/SKILL.md +322 -253
  80. package/skills/goose-video-local/SKILL.md +1199 -234
  81. package/skills/gooseworks/SKILL.md +199 -13
  82. package/skills/make-custom-video/SKILL.md +490 -0
  83. package/skills/manifest.json +12 -0
  84. package/skills/routes.json +8 -1
package/README.md CHANGED
@@ -152,12 +152,20 @@ Credits: 847 available (500 subscription + 347 purchased)
152
152
 
153
153
  ### `update`
154
154
 
155
- Re-fetch the latest skill without re-authenticating.
155
+ Refresh the entry instructions bundled in your installed CLI without re-authenticating.
156
+ The command checks the published release first and refuses to reinstall a known older CLI
157
+ bundle. Edited or untracked entry files and standalone recipe packages are preserved.
156
158
 
157
159
  ```bash
160
+ npx gooseworks skills status
158
161
  npx gooseworks update
159
162
  ```
160
163
 
164
+ Use `gooseworks skills status --json` for release, bundle and actual-file hashes. Upgrade an
165
+ outdated CLI with `npm install -g gooseworks@latest` before updating its entries. Review and
166
+ back up local edits before explicitly using `gooseworks update --overwrite-modified`.
167
+ An unavailable release check means freshness is unknown, not current.
168
+
161
169
  ## How It Works
162
170
 
163
171
  1. **Install** — authenticates you and installs a master skill file into your coding agent
@@ -184,7 +192,7 @@ For focused creative work you can also use:
184
192
 
185
193
  - `/goose-ads` for static ads, ad research, and ad performance.
186
194
  - `/goose-product-photos` for studio, lifestyle, marketplace, social, and on-model product photography.
187
- - `/goose-video` to order a video ad in chat (renders on the GooseWorks server).
195
+ - `/goose-video` to pick a video format and make the ad on this machine (Claude Code, Codex or Cursor).
188
196
  - `/goose-video-local` to render a video project you started in the app, on this machine.
189
197
  - `goose-graphics` for social graphics, carousels, slides, and branded visual content.
190
198
  - `animate-image` to turn an approved still into a short motion creative.
@@ -214,7 +222,7 @@ npx gooseworks call scrapecreators /v1/facebook/adLibrary/search/ads \
214
222
 
215
223
  We'd rather you know exactly what this CLI does before you run it:
216
224
 
217
- - **Skill scripts are open source and fetched at runtime.** `gooseworks fetch <slug>` (and the skills that call it) download skill content and Python scripts from the GooseWorks catalog on demand, save them under `/tmp/gooseworks-scripts/`, and run them on your machine. Every skill and its scripts live in the public, open-source [goose-skills repo](https://github.com/gooseworks-ai/goose-skills/tree/main/skills) — the catalog is synced from there — so the code is the same maintained, auditable source you can read on GitHub. They're served from the catalog (kept current) rather than pinned to the installed CLI version, so you always get the latest version of a skill.
225
+ - **Skill scripts are open source and fetched at runtime.** `gooseworks fetch <slug>` (and the skills that call it) download skill content and Python scripts from the GooseWorks catalog on demand, save them under `/tmp/gooseworks-scripts/`, and run them on your machine. Every skill and its scripts live in the public, open-source [goose-skills repo](https://github.com/gooseworks-ai/goose-skills/tree/main/skills) — the catalog is synced from there — so the code is the same maintained, auditable source you can read on GitHub. They are served from the connected catalog rather than the installed CLI version. Saved copies retain the version/hash returned when fetched; compare them again for new work.
218
226
  - **The MCP server is opt-in.** It's only registered when you pass `--mcp` (or `--all`). When you do, the CLI adds a `gooseworks` entry to `~/.claude.json` (Claude Code) or `~/.codex/config.toml` (Codex) that includes your bearer token in an `Authorization` header — this is how every HTTP MCP server authenticates. Skip `--mcp` if you don't want the server registered as a live tool provider; shared onboarding and ads creation require it.
219
227
  - **Credentials are stored locally.** Your API key lives in `~/.gooseworks/credentials.json`, written with `0600` permissions in a `0700` directory. `gooseworks logout` deletes it.
220
228
  - **`gooseworks env` exposes your key.** `eval $(gooseworks env)` exports `GOOSEWORKS_API_KEY` into your shell environment, where any process you run can read it. Most commands (e.g. `gooseworks call`) load credentials on their own — only use `env` when a script genuinely needs the environment variable.
@@ -246,8 +254,8 @@ creative fatigue, CAC & lead quality, competitor ad intelligence, ad angles & ho
246
254
  `gooseworks` parent router also hands ad requests to it. Claude auto-loads whichever skill
247
255
  matches the task; the two are domain-scoped and never merged.
248
256
 
249
- > Renamed from `ads-remix`. Older installs get the stale `ads-remix` skill cleaned up
250
- > automatically on the next `install`.
257
+ > Renamed from `ads-remix`. Install and update preserve legacy directories. If an
258
+ > older `ads-remix` entry remains, review and back it up before removing it yourself.
251
259
 
252
260
  ```bash
253
261
  gooseworks install --claude --mcp
@@ -267,14 +275,37 @@ Generation is billed to your GooseWorks credits **server-side**: `submit_remix_b
267
275
  the estimated cost up front and bills only the images that complete. There's no separate
268
276
  ad-credit balance. Use `estimate_remix_batch` (cost preview) and `gooseworks credits` (balance).
269
277
 
278
+ ### Original videos and the shared harness
279
+
280
+ The installed `make-custom-video` entry connects GooseWorks projects, authenticated
281
+ script and ingredient approvals, budgets, media storage and delivery to the shared
282
+ `video-production-harness` catalog skill. It contains no production playbook or
283
+ assembly code. CLI, direct MCP and Growth fetch the same production package through
284
+ the GooseWorks catalog; direct MCP clients do not need a local CLI.
285
+
286
+ Production instructions are maintained in Goose Studio's existing control-plane
287
+ harness. Tested Studio changes publish a generated package to `goose-skills`.
288
+ Each run saves its fetched package in its durable workspace. Project metadata keeps
289
+ only the version, hash and package location; resuming uses the saved package instead
290
+ of changing instructions during production. An unavailable package blocks
291
+ generation. New runs use the currently published catalog version.
292
+
270
293
  ### Keeping skills up to date
271
294
 
272
- - **Entry skills** (`gooseworks`, `goose-ads`) are vendored in the CLI. They're (re)installed
273
- on `install`/`update`, and **refreshed on `login`** — but only when their content actually
274
- changed (a content-hash stamp skips unchanged ones, so re-running is cheap). Bump the CLI
275
- (`npx gooseworks@latest …`) to get new entry-skill content.
276
- - **Recipe skills** (e.g. ad-analytics like `meta-ads-analyzer`) are **fetched live** from
277
- goose-skills each time they're used, so they're always current — nothing to update.
295
+ - **Entry skills** are bundled in the CLI. `skills status` compares their actual installed bytes,
296
+ bundled bytes and the integrity-verified published npm package. Install/update/login warn
297
+ about an outdated CLI, different instructions, modified files or an unavailable release check.
298
+ They preserve edited or untracked files by default. A development build ahead of the release
299
+ is reported as unreleased; it is not silently downgraded.
300
+ - **Saved recipe packages** use the connected catalog's `version` / `contentHash` and dependency
301
+ hashes. `gooseworks fetch <slug> --saved-package <json-file>` compares a saved fetch response
302
+ and returns the current package without replacing the file. Canonical MCP `catalog_fetch`
303
+ supports optional saved hashes when advertised; other hosts compare the returned hashes
304
+ themselves. The server cannot inspect a client's files, and reported hashes do not certify
305
+ later manual edits. Missing hashes mean unknown.
306
+ - **Hosted snapshots** use the existing Skills Update action. Approved runs keep their recorded
307
+ package. Fetch into a new directory for new work; do not replace a running project's harness.
308
+ Updating skill content does not refresh a host's cached MCP tool schemas.
278
309
 
279
310
  ## File Layout
280
311
 
@@ -1,10 +1,34 @@
1
1
  import { Command } from 'commander';
2
+ export interface DoctorCheck {
3
+ id: 'login' | 'mcp' | 'node' | 'ffmpeg' | 'ffprobe' | 'chromium';
4
+ label: string;
5
+ ok: boolean;
6
+ /** What to run when the check fails. */
7
+ fix: string;
8
+ /** What was actually found, for the human and for `--json`. */
9
+ detail?: string;
10
+ /** Browser diagnostics identify the package actually probed. */
11
+ code?: string;
12
+ rendererScript?: string;
13
+ modulePath?: string;
14
+ version?: string;
15
+ executablePath?: string;
16
+ }
2
17
  /**
3
- * `gooseworks doctor` — verify the local prerequisites for making VIDEO ads
4
- * (the goose-video-local skill renders locally: Playwright records the mockup, ffmpeg
5
- * stitches/mixes). Also checks auth + that the GooseWorks MCP server is wired,
6
- * since the skill reads/writes the project over MCP. Exits non-zero if anything
7
- * is missing so the agent's Phase-0 preflight can relay the fix and stop.
18
+ * The checks behind `gooseworks doctor`, reusable by `install` and by anything
19
+ * that wants common machine checks. An explicit renderer script verifies that
20
+ * renderer's Playwright, not a package belonging to the calling project.
21
+ * No download or ad render. Browser startup uses normal runtime temp files.
8
22
  */
23
+ export declare function runDoctorChecks(opts?: {
24
+ includeAuth?: boolean;
25
+ includeBrowser?: boolean;
26
+ rendererScript?: string;
27
+ }): DoctorCheck[];
28
+ /**
29
+ * General setup is not certification for an unfetched renderer. The selected
30
+ * renderer must pass its own free launch check before paid ingredients.
31
+ */
32
+ export declare function createDoctorCommand(): Command;
9
33
  export declare const doctorCommand: Command;
10
34
  //# sourceMappingURL=doctor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmCpC;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,SAiDtB,CAAC"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2CpC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,WAAW,EAAE,CAsCtI;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAuC7C;AAED,eAAO,MAAM,aAAa,SAAwB,CAAC"}
@@ -34,85 +34,129 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.doctorCommand = void 0;
37
+ exports.runDoctorChecks = runDoctorChecks;
38
+ exports.createDoctorCommand = createDoctorCommand;
37
39
  const commander_1 = require("commander");
38
40
  const child_process_1 = require("child_process");
39
41
  const credentials_1 = require("../auth/credentials");
40
42
  const logger = __importStar(require("../utils/logger"));
41
- /** True if `bin` resolves on PATH (cross-platform). */
42
- function onPath(bin) {
43
- const probe = process.platform === 'win32' ? 'where' : 'which';
43
+ const browser_preflight_1 = require("../utils/browser-preflight");
44
+ /** Run a binary and capture its output; never throws. */
45
+ function run(bin, args) {
44
46
  try {
45
- return (0, child_process_1.spawnSync)(probe, [bin], { stdio: 'ignore' }).status === 0;
47
+ const r = (0, child_process_1.spawnSync)(bin, args, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
48
+ return { status: r.status, out: `${r.stdout ?? ''}${r.stderr ?? ''}` };
46
49
  }
47
50
  catch {
48
- return false;
51
+ return { status: null, out: '' };
49
52
  }
50
53
  }
51
- /** Playwright is usable either as a global bin or via `npx playwright`. */
52
- function hasPlaywright() {
53
- if (onPath('playwright'))
54
- return true;
55
- try {
56
- return ((0, child_process_1.spawnSync)('npx', ['--no-install', 'playwright', '--version'], {
57
- stdio: 'ignore',
58
- }).status === 0);
59
- }
60
- catch {
61
- return false;
62
- }
54
+ /** True if `bin` resolves on PATH (cross-platform). */
55
+ function onPath(bin) {
56
+ const probe = process.platform === 'win32' ? 'where' : 'which';
57
+ return run(probe, [bin]).status === 0;
58
+ }
59
+ /**
60
+ * Local video renders burn subtitles with libass and encode with libx264. An
61
+ * ffmpeg without either passes a bare `which ffmpeg` and then fails mid-render,
62
+ * so check the build, not the path.
63
+ */
64
+ function ffmpegBuild() {
65
+ if (!onPath('ffmpeg'))
66
+ return { ok: false, detail: 'ffmpeg is not on PATH' };
67
+ const encoders = run('ffmpeg', ['-hide_banner', '-encoders']).out;
68
+ const filters = run('ffmpeg', ['-hide_banner', '-filters']).out;
69
+ const hasX264 = /\blibx264\b/.test(encoders);
70
+ const hasAss = /\bass\b/.test(filters);
71
+ if (hasX264 && hasAss)
72
+ return { ok: true, detail: 'libx264 + libass present' };
73
+ const missing = [!hasX264 && 'libx264 encoder', !hasAss && 'libass `ass` filter'].filter(Boolean).join(' and ');
74
+ return { ok: false, detail: `ffmpeg is installed but lacks ${missing}` };
75
+ }
76
+ function nodeVersion() {
77
+ const major = Number(process.versions.node.split('.')[0]);
78
+ return { ok: major >= 18, detail: `node ${process.versions.node}` };
63
79
  }
64
80
  /**
65
- * `gooseworks doctor` — verify the local prerequisites for making VIDEO ads
66
- * (the goose-video-local skill renders locally: Playwright records the mockup, ffmpeg
67
- * stitches/mixes). Also checks auth + that the GooseWorks MCP server is wired,
68
- * since the skill reads/writes the project over MCP. Exits non-zero if anything
69
- * is missing so the agent's Phase-0 preflight can relay the fix and stop.
81
+ * The checks behind `gooseworks doctor`, reusable by `install` and by anything
82
+ * that wants common machine checks. An explicit renderer script verifies that
83
+ * renderer's Playwright, not a package belonging to the calling project.
84
+ * No download or ad render. Browser startup uses normal runtime temp files.
70
85
  */
71
- exports.doctorCommand = new commander_1.Command('doctor')
72
- .description('Check local prerequisites for video ad rendering (ffmpeg, Playwright) + auth/MCP')
73
- .action(() => {
74
- const creds = (0, credentials_1.getCredentials)();
75
- const checks = [
76
- { label: 'Logged in', ok: !!creds, fix: 'gooseworks login' },
77
- {
86
+ function runDoctorChecks(opts = {}) {
87
+ if (opts.includeBrowser === false && opts.rendererScript !== undefined) {
88
+ throw new Error('--renderer-script cannot be combined with --no-browser');
89
+ }
90
+ const checks = [];
91
+ if (opts.includeAuth !== false) {
92
+ const creds = (0, credentials_1.getCredentials)();
93
+ checks.push({ id: 'login', label: 'Logged in', ok: !!creds, fix: 'gooseworks login' }, {
94
+ id: 'mcp',
78
95
  label: 'GooseWorks MCP configured',
79
96
  ok: !!creds?.mcp_server_url,
80
97
  fix: 'gooseworks install --claude --mcp (then restart Claude Code)',
81
- },
82
- {
83
- label: 'ffmpeg on PATH',
84
- ok: onPath('ffmpeg'),
85
- fix: 'brew install ffmpeg (macOS) / apt-get install ffmpeg (Linux)',
86
- },
87
- {
88
- label: 'ffprobe on PATH',
89
- ok: onPath('ffprobe'),
90
- fix: 'bundled with ffmpeg — install ffmpeg',
91
- },
92
- {
93
- label: 'Playwright (Chromium renderer)',
94
- ok: hasPlaywright(),
95
- fix: 'npx playwright install chromium',
96
- },
97
- ];
98
- logger.info('GooseWorks doctor — prerequisites for local video ad rendering\n');
99
- let allOk = true;
100
- for (const c of checks) {
101
- if (c.ok) {
102
- logger.success(c.label);
98
+ });
99
+ }
100
+ const node = nodeVersion();
101
+ const ffmpeg = ffmpegBuild();
102
+ checks.push({ id: 'node', label: 'Node.js 18 or newer', ok: node.ok, detail: node.detail, fix: 'install Node 18+ (https://nodejs.org) or `nvm install 22`' }, {
103
+ id: 'ffmpeg',
104
+ label: 'ffmpeg with libx264 + libass',
105
+ ok: ffmpeg.ok,
106
+ detail: ffmpeg.detail,
107
+ fix: 'brew install ffmpeg (macOS) / apt-get install ffmpeg (Linux)',
108
+ }, { id: 'ffprobe', label: 'ffprobe on PATH', ok: onPath('ffprobe'), fix: 'bundled with ffmpeg — install ffmpeg' });
109
+ if (opts.includeBrowser !== false) {
110
+ checks.push({
111
+ id: 'chromium',
112
+ label: opts.rendererScript !== undefined ? 'Selected renderer Chromium launch' : 'General Playwright Chromium launch',
113
+ ...(0, browser_preflight_1.checkBrowserPreflight)({ rendererScript: opts.rendererScript }),
114
+ });
115
+ }
116
+ return checks;
117
+ }
118
+ /**
119
+ * General setup is not certification for an unfetched renderer. The selected
120
+ * renderer must pass its own free launch check before paid ingredients.
121
+ */
122
+ function createDoctorCommand() {
123
+ return new commander_1.Command('doctor')
124
+ .description('Check local prerequisites for video ad rendering (ffmpeg, Playwright Chromium, Node) + auth/MCP')
125
+ .option('--json', 'Print the checks as JSON (for an agent to parse)')
126
+ .option('--renderer-script <path>', 'Launch Chromium through the selected Node renderer’s Playwright installation')
127
+ .option('--no-browser', 'Check common prerequisites only (for non-browser formats or before fetching a renderer)')
128
+ .action((opts, command) => {
129
+ if (opts.browser === false && opts.rendererScript !== undefined) {
130
+ command.error('--renderer-script cannot be combined with --no-browser');
131
+ }
132
+ const checks = runDoctorChecks({ includeBrowser: opts.browser, rendererScript: opts.rendererScript });
133
+ const allOk = checks.every((c) => c.ok);
134
+ if (opts.json) {
135
+ console.log(JSON.stringify({ ok: allOk, checks }, null, 2));
136
+ if (!allOk)
137
+ process.exitCode = 1;
138
+ return;
139
+ }
140
+ logger.info('GooseWorks doctor — prerequisites for local video ad rendering\n');
141
+ for (const c of checks) {
142
+ if (c.ok) {
143
+ logger.success(c.detail ? `${c.label} (${c.detail})` : c.label);
144
+ }
145
+ else {
146
+ logger.error(`${c.label} → fix: ${c.fix}${c.detail ? ` [${c.detail}]` : ''}`);
147
+ }
148
+ }
149
+ logger.info('');
150
+ if (allOk) {
151
+ logger.success(opts.rendererScript !== undefined
152
+ ? 'Common prerequisites and the selected renderer’s default Chromium launch passed.'
153
+ : 'Common setup checks passed. After fetching a browser renderer, check it with --renderer-script before paid work.');
103
154
  }
104
155
  else {
105
- logger.error(`${c.label} → fix: ${c.fix}`);
106
- allOk = false;
156
+ logger.warn('Some prerequisites are missing. Fix the items above, then re-run the same doctor check before paid work.');
157
+ process.exitCode = 1;
107
158
  }
108
- }
109
- logger.info('');
110
- if (allOk) {
111
- logger.success('All set — you can render video ads locally (goose-video-local).');
112
- }
113
- else {
114
- logger.warn('Some prerequisites are missing. Fix the items above, then re-run: gooseworks doctor');
115
- process.exitCode = 1;
116
- }
117
- });
159
+ });
160
+ }
161
+ exports.doctorCommand = createDoctorCommand();
118
162
  //# sourceMappingURL=doctor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAAoC;AACpC,iDAA0C;AAC1C,qDAAqD;AACrD,wDAA0C;AAE1C,uDAAuD;AACvD,SAAS,MAAM,CAAC,GAAW;IACzB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/D,IAAI,CAAC;QACH,OAAO,IAAA,yBAAS,EAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,SAAS,aAAa;IACpB,IAAI,MAAM,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,CAAC;QACH,OAAO,CACL,IAAA,yBAAS,EAAC,KAAK,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE;YAC5D,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAC,MAAM,KAAK,CAAC,CAChB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAQD;;;;;;GAMG;AACU,QAAA,aAAa,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CACV,kFAAkF,CACnF;KACA,MAAM,CAAC,GAAG,EAAE;IACX,MAAM,KAAK,GAAG,IAAA,4BAAc,GAAE,CAAC;IAC/B,MAAM,MAAM,GAAY;QACtB,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE;QAC5D;YACE,KAAK,EAAE,2BAA2B;YAClC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,cAAc;YAC3B,GAAG,EAAE,+DAA+D;SACrE;QACD;YACE,KAAK,EAAE,gBAAgB;YACvB,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC;YACpB,GAAG,EAAE,8DAA8D;SACpE;QACD;YACE,KAAK,EAAE,iBAAiB;YACxB,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC;YACrB,GAAG,EAAE,sCAAsC;SAC5C;QACD;YACE,KAAK,EAAE,gCAAgC;YACvC,EAAE,EAAE,aAAa,EAAE;YACnB,GAAG,EAAE,iCAAiC;SACvC;KACF,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAChF,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;YACT,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YAC7C,KAAK,GAAG,KAAK,CAAC;QAChB,CAAC;IACH,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC;IACpF,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CACT,qFAAqF,CACtF,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
1
  import { Command } from 'commander';
2
+ export declare function createFetchCommand(): Command;
2
3
  export declare const fetchCommand: Command;
3
4
  //# sourceMappingURL=fetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/commands/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0BpC,eAAO,MAAM,YAAY,SAgCrB,CAAC"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/commands/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCpC,wBAAgB,kBAAkB,IAAI,OAAO,CAqD5C;AAED,eAAO,MAAM,YAAY,SAAuB,CAAC"}
@@ -34,39 +34,74 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.fetchCommand = void 0;
37
+ exports.createFetchCommand = createFetchCommand;
37
38
  const commander_1 = require("commander");
38
39
  const credentials_1 = require("../auth/credentials");
39
40
  const http_1 = require("../utils/http");
40
41
  const logger = __importStar(require("../utils/logger"));
41
- exports.fetchCommand = new commander_1.Command('fetch')
42
- .description('Fetch a GooseWorks skill (content + scripts + dependencies) by slug')
43
- .argument('<slug>', 'Skill slug (e.g. "reddit-scraper")')
44
- .action(async (slug) => {
45
- const creds = (0, credentials_1.getCredentials)();
46
- if (!creds) {
47
- logger.error('Not logged in. Run "gooseworks login" first.');
48
- process.exit(1);
49
- }
50
- const spin = logger.spinner(`Fetching skill ${slug}...`);
51
- try {
52
- const response = await (0, http_1.requestJson)({
53
- apiBase: creds.api_base,
54
- apiKey: creds.api_key,
55
- method: 'GET',
56
- path: `/api/skills/catalog/${encodeURIComponent(slug)}`,
57
- });
58
- spin.stop();
59
- if (response.status === 'error' || !response.data) {
60
- logger.error('Failed to fetch skill');
42
+ const fs = __importStar(require("node:fs"));
43
+ const package_freshness_1 = require("../skills/package-freshness");
44
+ function createFetchCommand() {
45
+ return new commander_1.Command('fetch')
46
+ .description('Fetch a GooseWorks skill (content + scripts + dependencies) by slug')
47
+ .argument('<slug>', 'Skill slug (e.g. "reddit-scraper")')
48
+ .option('--saved-package <file>', 'Compare a previously saved fetch JSON with the current connected catalog; do not replace it')
49
+ .action(async (slug, options) => {
50
+ const creds = (0, credentials_1.getCredentials)();
51
+ if (!creds) {
52
+ logger.error('Not logged in. Run "gooseworks login" first.');
61
53
  process.exit(1);
62
54
  }
63
- console.log(JSON.stringify(response.data, null, 2));
64
- }
65
- catch (err) {
66
- spin.stop();
67
- const message = err instanceof Error ? err.message : 'Fetch failed';
68
- logger.error(message);
69
- process.exit(1);
70
- }
71
- });
55
+ const spin = logger.spinner(`Fetching skill ${slug}...`);
56
+ try {
57
+ let saved;
58
+ if (options.savedPackage) {
59
+ const fd = fs.openSync(options.savedPackage, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK);
60
+ try {
61
+ if (!fs.fstatSync(fd).isFile())
62
+ throw new Error('Saved package must be a regular JSON file');
63
+ const buffer = Buffer.alloc(16 * 1024 * 1024 + 1);
64
+ let size = 0, count = 0;
65
+ do {
66
+ count = fs.readSync(fd, buffer, size, buffer.length - size, null);
67
+ size += count;
68
+ } while (count && size < buffer.length);
69
+ if (size === buffer.length)
70
+ throw new Error('Saved package exceeds 16 MiB');
71
+ const parsed = JSON.parse(buffer.subarray(0, size).toString('utf8'));
72
+ if (!parsed || typeof parsed !== 'object' || parsed.slug !== slug)
73
+ throw new Error('Saved package slug does not match the requested skill');
74
+ const value = parsed;
75
+ if (value.contentHash != null && typeof value.contentHash !== 'string')
76
+ throw new Error('Invalid saved content hash');
77
+ if (value.dependencySkills != null && (!Array.isArray(value.dependencySkills) || value.dependencySkills.length > 100 || value.dependencySkills.some((dep) => !dep || typeof dep.slug !== 'string' || (dep.contentHash != null && typeof dep.contentHash !== 'string'))))
78
+ throw new Error('Invalid saved dependency hashes');
79
+ saved = value;
80
+ }
81
+ finally {
82
+ fs.closeSync(fd);
83
+ }
84
+ }
85
+ const response = await (0, http_1.requestJson)({
86
+ apiBase: creds.api_base,
87
+ apiKey: creds.api_key,
88
+ method: 'GET',
89
+ path: `/api/skills/catalog/${encodeURIComponent(slug)}`,
90
+ });
91
+ spin.stop();
92
+ if (response.status === 'error' || !response.data) {
93
+ logger.error('Failed to fetch skill');
94
+ process.exit(1);
95
+ }
96
+ console.log(JSON.stringify({ ...response.data, freshness: (0, package_freshness_1.compareSavedPackage)(response.data, saved) }, null, 2));
97
+ }
98
+ catch (err) {
99
+ spin.stop();
100
+ const message = err instanceof Error ? err.message : 'Fetch failed';
101
+ logger.error(message);
102
+ process.exit(1);
103
+ }
104
+ });
105
+ }
106
+ exports.fetchCommand = createFetchCommand();
72
107
  //# sourceMappingURL=fetch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/commands/fetch.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAAoC;AACpC,qDAAqD;AACrD,wCAA4C;AAC5C,wDAA0C;AAuB7B,QAAA,YAAY,GAAG,IAAI,mBAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,qEAAqE,CAAC;KAClF,QAAQ,CAAC,QAAQ,EAAE,oCAAoC,CAAC;KACxD,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7B,MAAM,KAAK,GAAG,IAAA,4BAAc,GAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,IAAI,KAAK,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAA,kBAAW,EAAuB;YACvD,OAAO,EAAE,KAAK,CAAC,QAAQ;YACvB,MAAM,EAAE,KAAK,CAAC,OAAO;YACrB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,uBAAuB,kBAAkB,CAAC,IAAI,CAAC,EAAE;SACxD,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,EAAE,CAAC;QAEZ,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YAClD,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;QACpE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/commands/fetch.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,gDAqDC;AAvFD,yCAAoC;AACpC,qDAAqD;AACrD,wCAA4C;AAC5C,wDAA0C;AAC1C,4CAA8B;AAC9B,mEAA6F;AA6B7F,SAAgB,kBAAkB;IAClC,OAAO,IAAI,mBAAO,CAAC,OAAO,CAAC;SACxB,WAAW,CAAC,qEAAqE,CAAC;SAClF,QAAQ,CAAC,QAAQ,EAAE,oCAAoC,CAAC;SACxD,MAAM,CAAC,wBAAwB,EAAE,6FAA6F,CAAC;SAC/H,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAkC,EAAE,EAAE;QACjE,MAAM,KAAK,GAAG,IAAA,4BAAc,GAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,IAAI,KAAK,CAAC,CAAC;QACzD,IAAI,CAAC;YACH,IAAI,KAAuC,CAAC;YAC5C,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;gBAC9F,IAAI,CAAC;oBACH,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;wBAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;oBAC7F,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;oBAClD,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;oBACxB,GAAG,CAAC;wBAAC,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;wBAAC,IAAI,IAAI,KAAK,CAAC;oBAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE;oBAC/H,IAAI,IAAI,KAAK,MAAM,CAAC,MAAM;wBAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;oBAC5E,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC9E,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAK,MAA+B,CAAC,IAAI,KAAK,IAAI;wBAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;oBACtK,MAAM,KAAK,GAAG,MAA8B,CAAC;oBAC7C,IAAI,KAAK,CAAC,WAAW,IAAI,IAAI,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ;wBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;oBACtH,IAAI,KAAK,CAAC,gBAAgB,IAAI,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC;wBAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;oBAC5T,KAAK,GAAG,KAAK,CAAC;gBAChB,CAAC;wBAAS,CAAC;oBAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBAAC,CAAC;YACjC,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,IAAA,kBAAW,EAAuB;gBACvD,OAAO,EAAE,KAAK,CAAC,QAAQ;gBACvB,MAAM,EAAE,KAAK,CAAC,OAAO;gBACrB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,uBAAuB,kBAAkB,CAAC,IAAI,CAAC,EAAE;aACxD,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,EAAE,CAAC;YAEZ,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAClD,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAA,uCAAmB,EAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACnH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;YACpE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AAEL,CAAC;AAEY,QAAA,YAAY,GAAG,kBAAkB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC,wBAAgB,oBAAoB,IAAI,OAAO,CA6J9C;AAED,eAAO,MAAM,cAAc,SAAyB,CAAC"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC,wBAAgB,oBAAoB,IAAI,OAAO,CAyK9C;AAED,eAAO,MAAM,cAAc,SAAyB,CAAC"}
@@ -47,6 +47,8 @@ const logger = __importStar(require("../utils/logger"));
47
47
  const master_skill_1 = require("../skills/master-skill");
48
48
  const config_1 = require("../config");
49
49
  const version_1 = require("../version");
50
+ const doctor_1 = require("./doctor");
51
+ const skills_1 = require("./skills");
50
52
  function createInstallCommand() {
51
53
  return new commander_1.Command('install')
52
54
  .description(`Install GooseWorks data tools into your coding agent
@@ -58,6 +60,7 @@ Examples:
58
60
  .option('--codex', 'Configure for Codex')
59
61
  .option('--cursor', 'Configure for Cursor')
60
62
  .option('--all', 'Configure for all detected agents (implies --mcp)')
63
+ .option('--overwrite-modified', 'Replace edited or untracked managed skill files after you back them up')
61
64
  .option('--mcp', 'Also register the GooseWorks MCP server')
62
65
  .option('--with <skill-slug>', 'Also install a standalone GooseWorks skill (repeatable)', collectSkillSlug, [])
63
66
  .option('--api-base <url>', 'API base URL', config_1.API_BASE)
@@ -75,17 +78,27 @@ Examples:
75
78
  logger.step(1, 3, 'Authenticating...');
76
79
  const creds = await (0, login_1.ensureLoggedIn)(opts.apiBase, opts.ref);
77
80
  logger.success(`Logged in as ${creds.email}`);
78
- // Step 2: Install entry skills (clean old skills first)
81
+ // Step 2: Refresh bundled entries; preserve standalone and edited copies.
82
+ const freshness = await (0, skills_1.readEntryFreshnessReport)();
83
+ await (0, skills_1.reportEntrySkillFreshness)(freshness);
84
+ if (freshness.cli === 'outdated') {
85
+ logger.error('Entry refresh refused: upgrade this CLI before installing its bundled instructions. No skill files were changed.');
86
+ process.exit(1);
87
+ return;
88
+ }
79
89
  logger.step(2, 3, 'Installing GooseWorks skills...');
80
- (0, installer_1.removeAllSkills)();
81
- for (const r of (0, installer_1.installManagedEntrySkills)((0, master_skill_1.getEntrySkills)(), { force: true })) {
82
- logger.success(`Installed ${r.name} skill to ~/.agents/skills/${r.name}/`);
90
+ for (const r of (0, installer_1.installManagedEntrySkills)((0, master_skill_1.getEntrySkills)(), { overwriteModified: opts.overwriteModified })) {
91
+ if (r.action === 'preserved')
92
+ logger.warn(`Preserved edited or untracked ${r.name}; review/back up before --overwrite-modified.`);
93
+ else
94
+ logger.success(`${r.action === 'installed' ? 'Installed' : 'Kept'} ${r.name} skill at ~/.agents/skills/${r.name}/`);
83
95
  }
84
96
  for (const slug of opts.with || []) {
85
97
  try {
86
98
  logger.info(`Installing standalone skill ${slug}...`);
87
99
  let lastReported = 0;
88
100
  await (0, installer_1.installStandaloneSkill)(slug, {
101
+ overwriteModified: opts.overwriteModified,
89
102
  onProgress: ({ downloaded, total }) => {
90
103
  const step = Math.max(1, Math.min(5, Math.ceil(total / 10)));
91
104
  if (downloaded === total || downloaded - lastReported >= step) {
@@ -182,6 +195,8 @@ Examples:
182
195
  logger.success('Cursor configured');
183
196
  }
184
197
  }
198
+ // General setup only; selected renderers are checked after they are fetched.
199
+ reportLocalVideoToolchain();
185
200
  const agentNames = targetAgents.map((a) => a === 'claude' ? 'Claude Code' : a === 'codex' ? 'Codex' : 'Cursor').join(' and ');
186
201
  logger.done(`Setup complete! Open ${agentNames} and ask for the work you want done.`);
187
202
  console.log('');
@@ -217,6 +232,24 @@ function resolveTargetAgents(opts) {
217
232
  targets.push('cursor');
218
233
  return targets;
219
234
  }
235
+ function reportLocalVideoToolchain() {
236
+ let missing;
237
+ try {
238
+ missing = (0, doctor_1.runDoctorChecks)({ includeAuth: false }).filter((c) => !c.ok);
239
+ }
240
+ catch {
241
+ return; // a broken probe must never fail the install
242
+ }
243
+ if (missing.length === 0) {
244
+ logger.success('Local video toolchain ready for general setup (ffmpeg, ffprobe, Playwright Chromium, Node). Check the selected renderer with `gooseworks doctor --renderer-script <path>` before paid work.');
245
+ return;
246
+ }
247
+ logger.info('Video ads are made on this machine and need these tools. To make them here, install:');
248
+ for (const c of missing) {
249
+ logger.warn(` ${c.label} → ${c.fix}`);
250
+ }
251
+ logger.info('Then run `gooseworks doctor` for general setup; check the selected browser renderer with `--renderer-script <path>` before paid work.');
252
+ }
220
253
  function collectSkillSlug(value, previous) {
221
254
  return [...previous, value];
222
255
  }