goalbuddy 0.2.12 → 0.2.14

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.
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "goalbuddy",
3
+ "interface": {
4
+ "displayName": "GoalBuddy"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "goalbuddy",
9
+ "source": {
10
+ "source": "local",
11
+ "path": "./plugins/goalbuddy"
12
+ },
13
+ "policy": {
14
+ "installation": "AVAILABLE",
15
+ "authentication": "ON_INSTALL"
16
+ },
17
+ "category": "Coding"
18
+ }
19
+ ]
20
+ }
package/README.md CHANGED
@@ -1,81 +1,139 @@
1
1
  # GoalBuddy
2
2
 
3
- Turn open-ended Codex work into a living Scout/Judge/Worker board with receipts, verification, and optional extensions.
3
+ <p align="center">
4
+ <a href="https://goalbuddy.dev">
5
+ <img src="internal/assets/goalbuddy-readme-hero.png" alt="GoalBuddy turns vague Codex goals into structured progress with Scout, Judge, Worker, receipts, and verification." width="100%">
6
+ </a>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <strong>Turn open-ended Codex work into one reviewable goal board.</strong>
11
+ </p>
12
+
13
+ <p align="center">
14
+ <a href="https://www.npmjs.com/package/goalbuddy"><img alt="npm" src="https://img.shields.io/npm/v/goalbuddy?style=flat-square&color=684cff"></a>
15
+ <a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-071236?style=flat-square"></a>
16
+ <a href="https://goalbuddy.dev"><img alt="goalbuddy.dev" src="https://img.shields.io/badge/site-goalbuddy.dev-684cff?style=flat-square"></a>
17
+ </p>
18
+
19
+ GoalBuddy is a local Codex companion for work that is too broad to trust to a single prompt. It turns a vague request into a `goal.md` charter, a machine-readable `state.yaml` board, role-tagged Scout/Judge/Worker tasks, compact receipts, and verification before completion.
4
20
 
5
21
  ```bash
6
22
  npx goalbuddy
7
23
  ```
8
24
 
9
- Then invoke the skill inside Codex:
25
+ Then invoke the installed skill inside Codex:
10
26
 
11
27
  ```text
12
28
  $goalbuddy
13
29
  ```
14
30
 
15
- `$goalbuddy` creates a local goal charter and task board, then prints the `/goal` command to run next. It does not start `/goal` automatically.
31
+ `$goalbuddy` prepares the board and prints the `/goal` command to run next. It does not start `/goal` automatically.
16
32
 
17
- Native Codex `/goal` is still an under-development Codex feature. Before relying on the printed command, confirm your local Codex runtime is logged in and has goals enabled:
33
+ For native Codex plugin install instead of the skill-only installer:
18
34
 
19
35
  ```bash
20
- codex login status
21
- codex features enable goals
22
- npx goalbuddy doctor --goal-ready
36
+ npx goalbuddy plugin install
23
37
  ```
24
38
 
25
- ![A simple hand-drawn diagram showing a vague goal becoming a GoalBuddy board with Scout, Judge, Worker, and a receipt.](internal/assets/goal-maker-flow.png)
26
-
27
- ## Why It Exists
39
+ ## Why GoalBuddy Exists
28
40
 
29
- Long Codex goals drift. A broad request like improve this project can turn into unbounded edits, stale verification, and premature completion claims.
41
+ Long Codex goals drift. A request like "improve this project" can turn into unbounded edits, stale verification, and premature completion claims.
30
42
 
31
- GoalBuddy gives Codex an operating loop for that kind of work:
43
+ GoalBuddy gives Codex a durable loop:
32
44
 
33
45
  ```text
34
- vague goal -> discovery -> task board -> one active task -> receipt -> board update -> repeat
46
+ vague goal -> Scout -> Judge -> Worker -> receipt -> verify -> repeat
35
47
  ```
36
48
 
37
- The main Codex thread is the PM. It owns the board, chooses the active task, delegates when useful, records receipts, and only completes after a Judge or PM audit.
49
+ The main `/goal` thread acts as PM. It owns the board, keeps exactly one active task, delegates when useful, records receipts, and only completes after a Judge or PM audit proves the original outcome is done.
38
50
 
39
- ## Core Features
51
+ ## What You Get Locally
52
+
53
+ ```text
54
+ docs/goals/<slug>/
55
+ goal.md
56
+ state.yaml
57
+ notes/
58
+ ```
40
59
 
41
- - **Local board truth**: `goal.md` is the editable charter; `state.yaml` is the machine-readable board; `notes/` holds long receipts.
42
- - **Default role agents**: Scout discovers evidence, Judge resolves risk and completion claims, Worker performs one bounded implementation task.
43
- - **One active task**: keeps autonomous work sequenced and reviewable instead of turning a vague goal into a pile of parallel edits.
44
- - **Task receipts**: every completed, blocked, or escalated task records what changed, what was learned, and what verification ran.
45
- - **Board checker**: validates v2 goal folders and rejects old `gate`, `units`, `artifacts`, and `evidence.jsonl` layouts.
46
- - **Extensions**: optional add-ons are discovered from `extend/catalog.json` without requiring npm updates for every integration.
60
+ - `goal.md` is the editable charter: objective, constraints, tranche, and stop rule.
61
+ - `state.yaml` is the board truth: task status, active task, receipts, and verification.
62
+ - `notes/` holds longer Scout, Judge, or PM findings when a task receipt would be too large.
47
63
 
48
- ## The Model
64
+ ## The Operating Model
49
65
 
50
66
  GoalBuddy uses four primitives:
51
67
 
52
- - **Charter**: `goal.md` states the objective, constraints, current tranche, and stop rule.
53
- - **Board**: `state.yaml` is machine truth for tasks, status, receipts, and verification freshness.
54
- - **Task**: exactly one active task is worked at a time.
55
- - **Receipt**: every completed, blocked, or escalated task leaves compact proof of what happened.
68
+ - **Charter**: states what this goal is trying to accomplish and what must stay true.
69
+ - **Board**: tracks tasks, status, receipts, and verification freshness.
70
+ - **Task**: exactly one active Scout, Judge, Worker, or PM task.
71
+ - **Receipt**: compact proof for every completed, blocked, or escalated task.
56
72
 
57
- Scout, Judge, and Worker are installed by default:
73
+ The default agents are installed with the skill:
58
74
 
59
- - **Scout** maps repo/source/spec evidence and candidate tasks.
60
- - **Judge** resolves ambiguity, scope, risk, and completion claims.
61
- - **Worker** performs one bounded implementation or recovery task.
75
+ - **Scout** maps repo evidence, workflows, constraints, risks, and candidate next tasks.
76
+ - **Judge** resolves ambiguity, scope, risk, task selection, and completion claims.
77
+ - **Worker** performs one bounded implementation or recovery slice with explicit files and checks.
62
78
 
63
- The main `/goal` thread is the PM. Use medium thinking for specific bounded goals, high for open-ended/recovery/audit goals, and reserve xhigh for exceptional high-risk or multi-day final audits.
79
+ ## Install And Check Readiness
64
80
 
65
- ## Goal Folder
81
+ Install or refresh the Codex skill and bundled agents:
66
82
 
67
- For each goal, `$goalbuddy` prepares:
83
+ ```bash
84
+ npx goalbuddy
85
+ npx goalbuddy update
86
+ ```
87
+
88
+ Install and enable the native Codex plugin:
89
+
90
+ ```bash
91
+ npx goalbuddy plugin install
92
+ ```
93
+
94
+ Native Codex `/goal` is still an under-development Codex feature. Before relying on the printed command, confirm your local Codex runtime is logged in and has goals enabled:
95
+
96
+ ```bash
97
+ codex login status
98
+ codex features enable goals
99
+ npx goalbuddy doctor --goal-ready
100
+ ```
101
+
102
+ Repair only the bundled agent definitions:
103
+
104
+ ```bash
105
+ npx goalbuddy agents
106
+ ```
107
+
108
+ Check the local install:
109
+
110
+ ```bash
111
+ npx goalbuddy doctor
112
+ ```
113
+
114
+ Use a non-default Codex home:
115
+
116
+ ```bash
117
+ npx goalbuddy install --codex-home /path/to/.codex
118
+ ```
119
+
120
+ `install`, `update`, and `doctor` also support `--json` when an agent or script needs structured output.
121
+
122
+ ## Run A Goal
123
+
124
+ After `$goalbuddy` creates or repairs the board, start the run with the printed command:
68
125
 
69
126
  ```text
70
- docs/goals/<slug>/
71
- goal.md
72
- state.yaml
73
- notes/
127
+ /goal Follow docs/goals/<slug>/goal.md.
74
128
  ```
75
129
 
76
- Most task results live inline as receipts in `state.yaml`. Use `notes/<task-id>-<slug>.md` only when a Scout, Judge, or PM result is too large for the task card.
130
+ Check board health at any time:
131
+
132
+ ```bash
133
+ node ~/.codex/skills/goalbuddy/scripts/check-goal-state.mjs docs/goals/<slug>/state.yaml
134
+ ```
77
135
 
78
- For a broad prompt like Improve my project,” the first task should usually be Scout, not Worker:
136
+ For a broad prompt like "Improve my project," the first active task should usually be Scout, not Worker:
79
137
 
80
138
  ```yaml
81
139
  tasks:
@@ -104,50 +162,9 @@ tasks:
104
162
  receipt: null
105
163
  ```
106
164
 
107
- ## Commands
108
-
109
- Install or update the Codex skill and bundled agents:
110
-
111
- ```bash
112
- npx goalbuddy
113
- npx goalbuddy update
114
- ```
115
-
116
- `install` and `update` print a compact summary of the skill, agent files, preserved installed extensions, and extension catalog recommendations. Use `--json` when an agent or script needs structured output.
117
-
118
- ### Compatibility Window
119
-
120
- GoalBuddy was previously published as `goal-maker`. During the migration window, `npx goal-maker` remains available as a compatibility alias and prints the new command:
121
-
122
- ```bash
123
- npx goalbuddy
124
- ```
125
-
126
- Machine-readable commands such as `npx goal-maker install --json` keep JSON output clean so existing automation can migrate safely.
127
-
128
- Release automation for future npm publishes is documented in [RELEASE.md](RELEASE.md).
129
-
130
- Repair only the agent definitions:
131
-
132
- ```bash
133
- npx goalbuddy agents
134
- ```
135
-
136
- Check what is installed:
137
-
138
- ```bash
139
- npx goalbuddy doctor
140
- ```
141
-
142
- Strictly check whether the native Codex `/goal` runtime is ready too:
143
-
144
- ```bash
145
- npx goalbuddy doctor --goal-ready
146
- ```
147
-
148
- `doctor` reports missing or stale bundled agents, Codex login status, and whether the `goals` feature is enabled. `update` refreshes the installed skill and bundled agents.
165
+ ## Extensions
149
166
 
150
- Discover optional extensions from the GitHub-hosted catalog:
167
+ The npm package is the stable core. Optional extensions live under `extend/` and are discovered from the GitHub-hosted `extend/catalog.json`, so users do not need a new npm release for every integration.
151
168
 
152
169
  ```bash
153
170
  npx goalbuddy extend
@@ -156,51 +173,44 @@ npx goalbuddy extend install github-pr-workflow --dry-run
156
173
  npx goalbuddy extend install --all --dry-run
157
174
  ```
158
175
 
159
- Use a non-default Codex home:
160
-
161
- ```bash
162
- npx goalbuddy install --codex-home /path/to/.codex
163
- ```
164
-
165
- ## Extensions
166
-
167
- The npm package is the stable core. Extensions live under `extend/` and move through the GitHub-hosted `extend/catalog.json`, so users do not need a new npm release for every optional integration.
176
+ `goalbuddy extend` shows available extensions plus local install state, activation state, credential requirements, safe-by-default status, and missing environment variables.
168
177
 
169
- `goalbuddy extend` reads the catalog and shows available extensions plus operational state such as activation, install/configuration status, approval requirements, safe-by-default status, and missing environment variables. `goalbuddy extend <id>` shows what an extension reads, writes, requires, supports, and a local-use prompt. `goalbuddy extend install <id>` copies a pinned, checksum-verified extension into the local GoalBuddy install. `goalbuddy extend install --all` installs every cataloged extension.
178
+ Current catalog examples include:
170
179
 
171
- Extensions are not board truth. They may publish, report, intake, or add role guidance, but `state.yaml` remains authoritative.
180
+ - `github-pr-workflow`: prepares receipt-aligned commit and PR handoff text.
181
+ - `github-projects`: mirrors GoalBuddy boards into GitHub Projects.
182
+ - `ai-diff-risk-review`: summarizes risk in the current diff.
183
+ - `ci-failure-triage`: maps failing CI back to likely causes and next tasks.
184
+ - `docs-drift-audit`: checks whether docs still match implementation.
185
+ - `codebase-onboarding-map`: creates a concise repo map from files and conventions.
186
+ - `release-readiness`: checks whether a goal is ready to publish.
172
187
 
173
- The first cataloged extension, `github-pr-workflow`, prepares receipt-aligned commit boundaries and GitHub PR handoff text from goal receipts without requiring GitHub credentials or making GitHub authoritative. The catalog also includes GitHub Projects sync plus local-first review, recovery, planning, documentation, audit, and credential-gated handoff extensions such as `github-projects`, `ai-diff-risk-review`, `ci-failure-triage`, `docs-drift-audit`, `test-gap-planner`, `release-readiness`, `dependency-upgrade-planner`, `security-review-brief`, `codebase-onboarding-map`, `slack-standup-digest`, and `linear-ticket-handoff`.
188
+ Extensions can publish, report, intake, or add role guidance. They are not board truth. `state.yaml` remains authoritative.
174
189
 
175
- ## Running A Goal
190
+ ## Compatibility Window
176
191
 
177
- After `$goalbuddy` creates or repairs the board, start `/goal` with the printed command:
192
+ GoalBuddy was previously published as `goal-maker`. During the migration window, `npx goal-maker` remains available as a compatibility alias and prints the new command:
178
193
 
179
- ```text
180
- /goal Follow docs/goals/<slug>/goal.md.
194
+ ```bash
195
+ npx goalbuddy
181
196
  ```
182
197
 
183
- The detailed run instructions live in that goal's `goal.md`, so the kickoff prompt can stay short while the board carries the full stop rule, intake, and PM loop.
184
-
185
- By default, GoalBuddy treats broad goals as requests for continuous work, not plan-only or one-slice exercises. Missing credentials or owner input are blockers for specific tasks, not reasons to stop the goal. A queued or active Worker task blocks `goal.status: done`; finish it, block it with a receipt, or replace it with a smaller safe Worker task before final audit. For continuous execution boards, a final audit must prove the full original outcome is complete, not merely that the latest slice passed.
186
-
187
- Check board health:
198
+ Machine-readable commands such as `npx goal-maker install --json` keep JSON output clean so existing automation can migrate safely.
188
199
 
189
- ```bash
190
- node ~/.codex/skills/goalbuddy/scripts/check-goal-state.mjs docs/goals/<slug>/state.yaml
191
- ```
200
+ Release automation for future npm publishes is documented in [RELEASE.md](RELEASE.md).
192
201
 
193
- ## Example
202
+ ## Examples
194
203
 
195
- See `examples/improve-goal-maker/` for a small completed reliability run, `examples/extend-catalog-workflow/` for a larger run that moves from product framing through implementation and repo cleanup, and `examples/github-pr-workflow-extension/pr-handoff.md` for an extension-generated PR handoff artifact.
204
+ - `examples/improve-goal-maker/`: a small completed reliability run.
205
+ - `examples/extend-catalog-workflow/`: a larger run from product framing through implementation and cleanup.
206
+ - `examples/github-pr-workflow-extension/pr-handoff.md`: an extension-generated PR handoff artifact.
196
207
 
197
- ## Repo Contents
208
+ ## Repo Map
198
209
 
199
- - `goalbuddy/SKILL.md`: the canonical Codex skill
210
+ - `goalbuddy/SKILL.md`: canonical Codex skill
200
211
  - `goalbuddy/agents/`: Scout, Judge, and Worker definitions
201
212
  - `goalbuddy/templates/`: `goal.md`, `state.yaml`, and `note.md`
202
213
  - `goalbuddy/scripts/check-goal-state.mjs`: v2 board checker
203
- - `$goal-maker` compatibility: generated by the installer for existing users
204
214
  - `internal/cli/goal-maker.mjs`: npm installer CLI
205
215
  - `plugins/goalbuddy/`: repo-local Codex plugin package scaffold
206
216
  - `extend/` and `extend/catalog.json`: GitHub-hosted extension surface
@@ -208,9 +218,9 @@ See `examples/improve-goal-maker/` for a small completed reliability run, `examp
208
218
 
209
219
  ## Status
210
220
 
211
- `0.2.x` is the v2 board/receipt model. It intentionally rejects old v1 `gate`, `units`, `artifacts`, and `evidence.jsonl` goal folders instead of auto-migrating them.
221
+ `0.2.x` is the v2 board and receipt model. It intentionally rejects old v1 `gate`, `units`, `artifacts`, and `evidence.jsonl` goal folders instead of auto-migrating them.
212
222
 
213
- Use this to structure autonomous Codex work. Keep relying on repo-specific `AGENTS.md`, tests, and CI for repo facts.
223
+ Use GoalBuddy to structure autonomous Codex work. Keep relying on repo-specific `AGENTS.md`, tests, and CI for repo facts.
214
224
 
215
225
  ## License
216
226
 
@@ -0,0 +1,21 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 190" role="img" aria-labelledby="title desc">
2
+ <title id="title">GoalBuddy logo</title>
3
+ <desc id="desc">GoalBuddy wordmark with lavender cloud mark.</desc>
4
+ <defs>
5
+ <radialGradient id="logoMarkGrad" cx="34%" cy="18%" r="92%">
6
+ <stop offset="0" stop-color="#f8f2ff"/>
7
+ <stop offset="0.46" stop-color="#b6a9ff"/>
8
+ <stop offset="1" stop-color="#5361ff"/>
9
+ </radialGradient>
10
+ <filter id="logoShadow" x="-20%" y="-25%" width="140%" height="160%">
11
+ <feDropShadow dx="0" dy="12" stdDeviation="10" flood-color="#4d48b8" flood-opacity=".24"/>
12
+ </filter>
13
+ </defs>
14
+ <g filter="url(#logoShadow)">
15
+ <path d="M72 141c-30 0-54-24-54-54 0-26 18-48 43-53C65 15 82 0 103 0c18 0 34 10 42 24 12-8 27-13 43-13 36 0 66 26 72 61 22 11 37 33 37 59 0 36-30 66-66 66H93c-8 0-15-2-21-6z" transform="translate(0 4) scale(.82)" fill="url(#logoMarkGrad)"/>
16
+ <ellipse cx="82" cy="81" rx="8" ry="12" fill="#061238"/>
17
+ <ellipse cx="132" cy="81" rx="8" ry="12" fill="#061238"/>
18
+ <path d="M99 101c8 9 18 9 27 0" fill="none" stroke="#061238" stroke-width="7" stroke-linecap="round"/>
19
+ </g>
20
+ <text x="230" y="116" fill="#071236" font-family="Geist, Avenir Next, Arial, sans-serif" font-size="82" font-weight="800" letter-spacing="-1">GoalBuddy</text>
21
+ </svg>
Binary file
@@ -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);
@@ -64,6 +65,9 @@ async function main() {
64
65
  case "doctor":
65
66
  doctor();
66
67
  break;
68
+ case "plugin":
69
+ plugin();
70
+ break;
67
71
  case "extend":
68
72
  await extend();
69
73
  break;
@@ -133,6 +137,7 @@ Usage:
133
137
  ${canonicalCliName} update [--codex-home <path>] [--json]
134
138
  ${canonicalCliName} agents [--codex-home <path>] [--force]
135
139
  ${canonicalCliName} doctor [--codex-home <path>] [--goal-ready]
140
+ ${canonicalCliName} plugin install [--source <marketplace-source>] [--codex-home <path>] [--json]
136
141
  ${canonicalCliName} extend [--catalog-url <url-or-path>] [--kind <kind>] [--json]
137
142
  ${canonicalCliName} extend <id> [--catalog-url <url-or-path>] [--json]
138
143
  ${canonicalCliName} extend install <id> [--catalog-url <url-or-path>] [--dry-run] [--force] [--json]
@@ -321,6 +326,123 @@ function doctor() {
321
326
  process.exit(installOk && goalReadyOk ? 0 : 1);
322
327
  }
323
328
 
329
+ function plugin() {
330
+ const subcommand = positional(1) || "";
331
+ switch (subcommand) {
332
+ case "install":
333
+ installPlugin();
334
+ break;
335
+ case "help":
336
+ case "--help":
337
+ case "-h":
338
+ pluginUsage();
339
+ break;
340
+ default:
341
+ console.error(`Unknown plugin command: ${subcommand || "<missing>"}`);
342
+ pluginUsage();
343
+ process.exit(2);
344
+ }
345
+ }
346
+
347
+ function pluginUsage() {
348
+ console.log(`${canonicalProductName} Plugin
349
+
350
+ Usage:
351
+ ${canonicalCliName} plugin install [--source <marketplace-source>] [--codex-home <path>] [--json]
352
+
353
+ Default source:
354
+ tolibear/goalbuddy
355
+ `);
356
+ }
357
+
358
+ function installPlugin() {
359
+ const source = optionValue("--source") || "tolibear/goalbuddy";
360
+ const pluginSource = join(packageRoot, "plugins", canonicalSkillName);
361
+ const pluginManifestPath = join(pluginSource, ".codex-plugin", "plugin.json");
362
+ if (!existsSync(pluginManifestPath)) {
363
+ throw new Error(`Plugin manifest not found: ${pluginManifestPath}`);
364
+ }
365
+
366
+ const pluginManifest = JSON.parse(readFileSync(pluginManifestPath, "utf8"));
367
+ const pluginCachePath = pluginCacheRoot(pluginManifest.version);
368
+ const marketplace = runCodex(["plugin", "marketplace", "add", source]);
369
+ if (!marketplace.ok) {
370
+ throw new Error(`Failed to add Codex plugin marketplace: ${firstLine(marketplace.stderr || marketplace.stdout)}`);
371
+ }
372
+
373
+ mkdirSync(dirname(pluginCachePath), { recursive: true });
374
+ rmSync(pluginCachePath, { recursive: true, force: true });
375
+ cpSync(pluginSource, pluginCachePath, { recursive: true });
376
+ const configPath = enablePluginConfig();
377
+
378
+ const report = {
379
+ installed: true,
380
+ plugin: `${canonicalSkillName}@${canonicalSkillName}`,
381
+ version: pluginManifest.version,
382
+ codex_home: codexHome(),
383
+ marketplace_source: source,
384
+ cache_path: pluginCachePath,
385
+ config_path: configPath,
386
+ };
387
+
388
+ if (hasFlag("--json")) {
389
+ printJson(report);
390
+ return;
391
+ }
392
+
393
+ console.log(`Installed ${canonicalProductName} Codex plugin ${pluginManifest.version}`);
394
+ console.log(`Marketplace: ${source}`);
395
+ console.log(`Cache: ${pluginCachePath}`);
396
+ console.log(`Config: ${configPath}`);
397
+ console.log("");
398
+ console.log("Restart Codex, then use:");
399
+ console.log(` $${canonicalSkillName}`);
400
+ }
401
+
402
+ function pluginCacheRoot(version) {
403
+ return join(codexHome(), "plugins", "cache", canonicalSkillName, canonicalSkillName, version);
404
+ }
405
+
406
+ function enablePluginConfig() {
407
+ const configPath = join(codexHome(), "config.toml");
408
+ mkdirSync(dirname(configPath), { recursive: true });
409
+ const header = `[plugins."${canonicalSkillName}@${canonicalSkillName}"]`;
410
+ const existing = existsSync(configPath) ? readFileSync(configPath, "utf8") : "";
411
+ const updated = upsertTomlEnabled(existing, header);
412
+ writeFileSync(configPath, updated);
413
+ return configPath;
414
+ }
415
+
416
+ function upsertTomlEnabled(text, header) {
417
+ const normalized = text.endsWith("\n") || text.length === 0 ? text : `${text}\n`;
418
+ const lines = normalized.split("\n");
419
+ const start = lines.findIndex((line) => line.trim() === header);
420
+ if (start === -1) {
421
+ const prefix = normalized.trim() ? `${normalized}\n` : "";
422
+ return `${prefix}${header}\nenabled = true\n`;
423
+ }
424
+
425
+ let end = lines.length;
426
+ for (let index = start + 1; index < lines.length; index += 1) {
427
+ if (/^\s*\[/.test(lines[index])) {
428
+ end = index;
429
+ break;
430
+ }
431
+ }
432
+
433
+ let sawEnabled = false;
434
+ for (let index = start + 1; index < end; index += 1) {
435
+ if (/^\s*enabled\s*=/.test(lines[index])) {
436
+ lines[index] = "enabled = true";
437
+ sawEnabled = true;
438
+ break;
439
+ }
440
+ }
441
+ if (!sawEnabled) lines.splice(start + 1, 0, "enabled = true");
442
+
443
+ return lines.join("\n").replace(/\n*$/, "\n");
444
+ }
445
+
324
446
  function codexGoalRuntimeStatus() {
325
447
  const version = runCodex(["--version"]);
326
448
  const login = version.ok ? runCodex(["login", "status"]) : { ok: false, stdout: "", stderr: "codex CLI unavailable" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goalbuddy",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
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": {
@@ -8,6 +8,7 @@
8
8
  "goal-maker": "internal/cli/goal-maker.mjs"
9
9
  },
10
10
  "files": [
11
+ ".agents/plugins/marketplace.json",
11
12
  "README.md",
12
13
  "CONTRIBUTING.md",
13
14
  "examples",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goalbuddy",
3
- "version": "0.2.10",
3
+ "version": "0.2.14",
4
4
  "description": "Turn broad Codex work into verified GoalBuddy boards with Scout, Judge, Worker, receipts, and optional extensions.",
5
5
  "author": {
6
6
  "name": "tolibear",
@@ -17,6 +17,16 @@ npm run check
17
17
  npx goalbuddy doctor
18
18
  ```
19
19
 
20
+ ## Native Codex Install
21
+
22
+ Install and enable the plugin with the GoalBuddy CLI:
23
+
24
+ ```bash
25
+ npx goalbuddy plugin install
26
+ ```
27
+
28
+ This adds the `tolibear/goalbuddy` marketplace, caches the packaged plugin, and enables `goalbuddy@goalbuddy` for Codex. The npm CLI remains useful for `doctor`, project-local agent setup, and optional GoalBuddy extension management.
29
+
20
30
  For local CLI testing before npm publish:
21
31
 
22
32
  ```bash
@@ -26,4 +36,4 @@ node internal/cli/goal-maker.mjs doctor
26
36
 
27
37
  ## Release Notes
28
38
 
29
- The plugin is prepared for the `tolibear/goalbuddy` repo and `goalbuddy` npm package. Do not publish this plugin until the owner completes the GitHub and npm handoff steps in `docs/goals/goalbuddy-rebrand-plugin/state.yaml`.
39
+ The plugin is prepared for the `tolibear/goalbuddy` repo and `goalbuddy` npm package. Keep `.codex-plugin/plugin.json` aligned with `package.json` before publishing a new package release.