goalbuddy 0.2.13 → 0.2.15
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/README.md
CHANGED
|
@@ -22,7 +22,13 @@ GoalBuddy is a local Codex companion for work that is too broad to trust to a si
|
|
|
22
22
|
npx goalbuddy
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Or install it globally:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm i -g goalbuddy
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Then restart Codex and invoke the installed skill:
|
|
26
32
|
|
|
27
33
|
```text
|
|
28
34
|
$goalbuddy
|
|
@@ -72,10 +78,17 @@ The default agents are installed with the skill:
|
|
|
72
78
|
|
|
73
79
|
## Install And Check Readiness
|
|
74
80
|
|
|
75
|
-
Install
|
|
81
|
+
Install and enable the native Codex plugin:
|
|
76
82
|
|
|
77
83
|
```bash
|
|
78
84
|
npx goalbuddy
|
|
85
|
+
npm i -g goalbuddy
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Use the skill-only fallback if your Codex build does not support plugins:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx goalbuddy install
|
|
79
92
|
npx goalbuddy update
|
|
80
93
|
```
|
|
81
94
|
|
|
@@ -102,10 +115,10 @@ npx goalbuddy doctor
|
|
|
102
115
|
Use a non-default Codex home:
|
|
103
116
|
|
|
104
117
|
```bash
|
|
105
|
-
npx goalbuddy
|
|
118
|
+
npx goalbuddy --codex-home /path/to/.codex
|
|
106
119
|
```
|
|
107
120
|
|
|
108
|
-
`install`, `update`, and `doctor` also support `--json` when an agent or script needs structured output.
|
|
121
|
+
`plugin install`, `install`, `update`, and `doctor` also support `--json` when an agent or script needs structured output.
|
|
109
122
|
|
|
110
123
|
## Run A Goal
|
|
111
124
|
|
|
@@ -36,6 +36,7 @@ const optionsWithValues = new Set([
|
|
|
36
36
|
"--catalog-url",
|
|
37
37
|
"--codex-home",
|
|
38
38
|
"--kind",
|
|
39
|
+
"--source",
|
|
39
40
|
]);
|
|
40
41
|
|
|
41
42
|
const args = process.argv.slice(2);
|
|
@@ -43,7 +44,7 @@ const command = args[0] === "--help" || args[0] === "-h"
|
|
|
43
44
|
? "help"
|
|
44
45
|
: args[0] && !args[0].startsWith("-")
|
|
45
46
|
? args[0]
|
|
46
|
-
: "
|
|
47
|
+
: "default";
|
|
47
48
|
const invokedAs = invokedCommandName();
|
|
48
49
|
|
|
49
50
|
main().catch((error) => {
|
|
@@ -54,6 +55,9 @@ main().catch((error) => {
|
|
|
54
55
|
async function main() {
|
|
55
56
|
maybePrintLegacyNotice();
|
|
56
57
|
switch (command) {
|
|
58
|
+
case "default":
|
|
59
|
+
installPlugin();
|
|
60
|
+
break;
|
|
57
61
|
case "install":
|
|
58
62
|
case "update":
|
|
59
63
|
await installAll();
|
|
@@ -64,6 +68,9 @@ async function main() {
|
|
|
64
68
|
case "doctor":
|
|
65
69
|
doctor();
|
|
66
70
|
break;
|
|
71
|
+
case "plugin":
|
|
72
|
+
plugin();
|
|
73
|
+
break;
|
|
67
74
|
case "extend":
|
|
68
75
|
await extend();
|
|
69
76
|
break;
|
|
@@ -129,6 +136,8 @@ function usage() {
|
|
|
129
136
|
console.log(`Codex ${canonicalProductName}
|
|
130
137
|
|
|
131
138
|
Usage:
|
|
139
|
+
${canonicalCliName} [--codex-home <path>] [--json]
|
|
140
|
+
${canonicalCliName} plugin install [--source <marketplace-source>] [--codex-home <path>] [--json]
|
|
132
141
|
${canonicalCliName} install [--codex-home <path>] [--force] [--json]
|
|
133
142
|
${canonicalCliName} update [--codex-home <path>] [--json]
|
|
134
143
|
${canonicalCliName} agents [--codex-home <path>] [--force]
|
|
@@ -140,7 +149,10 @@ Usage:
|
|
|
140
149
|
${canonicalCliName} extend doctor [<id>] [--codex-home <path>] [--json]
|
|
141
150
|
|
|
142
151
|
Default:
|
|
143
|
-
${canonicalCliName} Installs
|
|
152
|
+
${canonicalCliName} Installs and enables the native Codex plugin.
|
|
153
|
+
|
|
154
|
+
Skill-only fallback:
|
|
155
|
+
${canonicalCliName} install Installs the legacy skill payload and bundled agent definitions.
|
|
144
156
|
|
|
145
157
|
Compatibility:
|
|
146
158
|
${legacyCliName} remains a temporary alias and prints the new npx command for human-facing use.
|
|
@@ -321,6 +333,123 @@ function doctor() {
|
|
|
321
333
|
process.exit(installOk && goalReadyOk ? 0 : 1);
|
|
322
334
|
}
|
|
323
335
|
|
|
336
|
+
function plugin() {
|
|
337
|
+
const subcommand = positional(1) || "";
|
|
338
|
+
switch (subcommand) {
|
|
339
|
+
case "install":
|
|
340
|
+
installPlugin();
|
|
341
|
+
break;
|
|
342
|
+
case "help":
|
|
343
|
+
case "--help":
|
|
344
|
+
case "-h":
|
|
345
|
+
pluginUsage();
|
|
346
|
+
break;
|
|
347
|
+
default:
|
|
348
|
+
console.error(`Unknown plugin command: ${subcommand || "<missing>"}`);
|
|
349
|
+
pluginUsage();
|
|
350
|
+
process.exit(2);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function pluginUsage() {
|
|
355
|
+
console.log(`${canonicalProductName} Plugin
|
|
356
|
+
|
|
357
|
+
Usage:
|
|
358
|
+
${canonicalCliName} plugin install [--source <marketplace-source>] [--codex-home <path>] [--json]
|
|
359
|
+
|
|
360
|
+
Default source:
|
|
361
|
+
tolibear/goalbuddy
|
|
362
|
+
`);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function installPlugin() {
|
|
366
|
+
const source = optionValue("--source") || "tolibear/goalbuddy";
|
|
367
|
+
const pluginSource = join(packageRoot, "plugins", canonicalSkillName);
|
|
368
|
+
const pluginManifestPath = join(pluginSource, ".codex-plugin", "plugin.json");
|
|
369
|
+
if (!existsSync(pluginManifestPath)) {
|
|
370
|
+
throw new Error(`Plugin manifest not found: ${pluginManifestPath}`);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const pluginManifest = JSON.parse(readFileSync(pluginManifestPath, "utf8"));
|
|
374
|
+
const pluginCachePath = pluginCacheRoot(pluginManifest.version);
|
|
375
|
+
const marketplace = runCodex(["plugin", "marketplace", "add", source]);
|
|
376
|
+
if (!marketplace.ok) {
|
|
377
|
+
throw new Error(`Failed to add Codex plugin marketplace: ${firstLine(marketplace.stderr || marketplace.stdout)}`);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
mkdirSync(dirname(pluginCachePath), { recursive: true });
|
|
381
|
+
rmSync(pluginCachePath, { recursive: true, force: true });
|
|
382
|
+
cpSync(pluginSource, pluginCachePath, { recursive: true });
|
|
383
|
+
const configPath = enablePluginConfig();
|
|
384
|
+
|
|
385
|
+
const report = {
|
|
386
|
+
installed: true,
|
|
387
|
+
plugin: `${canonicalSkillName}@${canonicalSkillName}`,
|
|
388
|
+
version: pluginManifest.version,
|
|
389
|
+
codex_home: codexHome(),
|
|
390
|
+
marketplace_source: source,
|
|
391
|
+
cache_path: pluginCachePath,
|
|
392
|
+
config_path: configPath,
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
if (hasFlag("--json")) {
|
|
396
|
+
printJson(report);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
console.log(`Installed ${canonicalProductName} Codex plugin ${pluginManifest.version}`);
|
|
401
|
+
console.log(`Marketplace: ${source}`);
|
|
402
|
+
console.log(`Cache: ${pluginCachePath}`);
|
|
403
|
+
console.log(`Config: ${configPath}`);
|
|
404
|
+
console.log("");
|
|
405
|
+
console.log("Restart Codex, then use:");
|
|
406
|
+
console.log(` $${canonicalSkillName}`);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function pluginCacheRoot(version) {
|
|
410
|
+
return join(codexHome(), "plugins", "cache", canonicalSkillName, canonicalSkillName, version);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function enablePluginConfig() {
|
|
414
|
+
const configPath = join(codexHome(), "config.toml");
|
|
415
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
416
|
+
const header = `[plugins."${canonicalSkillName}@${canonicalSkillName}"]`;
|
|
417
|
+
const existing = existsSync(configPath) ? readFileSync(configPath, "utf8") : "";
|
|
418
|
+
const updated = upsertTomlEnabled(existing, header);
|
|
419
|
+
writeFileSync(configPath, updated);
|
|
420
|
+
return configPath;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function upsertTomlEnabled(text, header) {
|
|
424
|
+
const normalized = text.endsWith("\n") || text.length === 0 ? text : `${text}\n`;
|
|
425
|
+
const lines = normalized.split("\n");
|
|
426
|
+
const start = lines.findIndex((line) => line.trim() === header);
|
|
427
|
+
if (start === -1) {
|
|
428
|
+
const prefix = normalized.trim() ? `${normalized}\n` : "";
|
|
429
|
+
return `${prefix}${header}\nenabled = true\n`;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
let end = lines.length;
|
|
433
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
434
|
+
if (/^\s*\[/.test(lines[index])) {
|
|
435
|
+
end = index;
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
let sawEnabled = false;
|
|
441
|
+
for (let index = start + 1; index < end; index += 1) {
|
|
442
|
+
if (/^\s*enabled\s*=/.test(lines[index])) {
|
|
443
|
+
lines[index] = "enabled = true";
|
|
444
|
+
sawEnabled = true;
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (!sawEnabled) lines.splice(start + 1, 0, "enabled = true");
|
|
449
|
+
|
|
450
|
+
return lines.join("\n").replace(/\n*$/, "\n");
|
|
451
|
+
}
|
|
452
|
+
|
|
324
453
|
function codexGoalRuntimeStatus() {
|
|
325
454
|
const version = runCodex(["--version"]);
|
|
326
455
|
const login = version.ok ? runCodex(["login", "status"]) : { ok: false, stdout: "", stderr: "codex CLI unavailable" };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const cliPath = join(__dirname, "goal-maker.mjs");
|
|
8
|
+
const globalInstall = process.env.npm_config_global === "true"
|
|
9
|
+
|| process.env.npm_config_location === "global";
|
|
10
|
+
|
|
11
|
+
if (!globalInstall || process.env.GOALBUDDY_SKIP_POSTINSTALL) {
|
|
12
|
+
process.exit(0);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const result = spawnSync(process.execPath, [cliPath, "plugin", "install"], {
|
|
16
|
+
encoding: "utf8",
|
|
17
|
+
env: process.env,
|
|
18
|
+
stdio: "inherit",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (result.status === 0) {
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.error("");
|
|
26
|
+
console.error("GoalBuddy installed globally, but Codex plugin setup did not complete.");
|
|
27
|
+
console.error("Run this after Codex is available:");
|
|
28
|
+
console.error(" goalbuddy");
|
|
29
|
+
process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goalbuddy",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.15",
|
|
4
4
|
"description": "Turn open-ended Codex goals into a GoalBuddy Scout/Judge/Worker board with receipts, verification, and optional extensions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,9 +21,10 @@
|
|
|
21
21
|
"goalbuddy/templates"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
|
-
"check": "node --check internal/cli
|
|
24
|
+
"check": "node --check internal/cli/*.mjs goalbuddy/scripts/*.mjs && node --test internal/test/*.test.mjs",
|
|
25
25
|
"test": "node --test internal/test/*.test.mjs",
|
|
26
26
|
"pack:dry-run": "npm pack --dry-run",
|
|
27
|
+
"postinstall": "node internal/cli/postinstall.mjs",
|
|
27
28
|
"publish:check": "node internal/cli/check-publish-version.mjs && npm run pack:dry-run",
|
|
28
29
|
"prepublishOnly": "node internal/cli/check-publish-version.mjs"
|
|
29
30
|
},
|
|
@@ -19,18 +19,24 @@ npx goalbuddy doctor
|
|
|
19
19
|
|
|
20
20
|
## Native Codex Install
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Install and enable GoalBuddy:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
|
|
25
|
+
npx goalbuddy
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Or install the npm package globally:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm i -g goalbuddy
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The marketplace manifest is included for Codex discovery, but current Codex CLI builds only register the marketplace with `codex plugin marketplace add`; the npm CLI also caches and enables the plugin.
|
|
29
35
|
|
|
30
36
|
For local CLI testing before npm publish:
|
|
31
37
|
|
|
32
38
|
```bash
|
|
33
|
-
node internal/cli/goal-maker.mjs
|
|
39
|
+
node internal/cli/goal-maker.mjs --catalog-url extend/catalog.json
|
|
34
40
|
node internal/cli/goal-maker.mjs doctor
|
|
35
41
|
```
|
|
36
42
|
|