goalbuddy 0.3.2 → 0.3.6
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 +55 -5
- package/RELEASE-0.3.5.md +324 -0
- package/goalbuddy/SKILL.md +40 -13
- package/goalbuddy/agents/README.md +1 -1
- package/goalbuddy/agents/goal_judge.toml +33 -17
- package/goalbuddy/agents/goal_scout.toml +34 -14
- package/goalbuddy/agents/goal_worker.toml +36 -16
- package/goalbuddy/extend/local-goal-board/README.md +8 -4
- package/goalbuddy/extend/local-goal-board/examples/subgoal-parent/goal.md +3 -0
- package/goalbuddy/extend/local-goal-board/examples/subgoal-parent/notes/.gitkeep +1 -0
- package/goalbuddy/extend/local-goal-board/examples/subgoal-parent/state.yaml +60 -0
- package/goalbuddy/extend/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/goal.md +3 -0
- package/goalbuddy/extend/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/notes/.gitkeep +1 -0
- package/goalbuddy/extend/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/state.yaml +52 -0
- package/goalbuddy/extend/local-goal-board/extension.yaml +6 -4
- package/goalbuddy/extend/local-goal-board/scripts/lib/goal-board.mjs +1188 -31
- package/goalbuddy/extend/local-goal-board/scripts/local-goal-board.mjs +389 -54
- package/goalbuddy/extend/local-goal-board/test/local-goal-board.test.mjs +479 -5
- package/goalbuddy/scripts/check-goal-state.mjs +192 -6
- package/goalbuddy/scripts/parallel-plan.mjs +191 -0
- package/goalbuddy/scripts/render-task-prompt.mjs +305 -0
- package/goalbuddy/templates/agents.md +5 -4
- package/goalbuddy/templates/goal.md +18 -4
- package/goalbuddy/templates/state.yaml +14 -1
- package/internal/assets/goalbuddy-v0.3.5-release.png +0 -0
- package/internal/cli/goal-maker.mjs +172 -9
- package/package.json +3 -2
- package/plugins/goalbuddy/.claude-plugin/plugin.json +2 -2
- package/plugins/goalbuddy/.codex-plugin/plugin.json +4 -4
- package/plugins/goalbuddy/README.md +5 -3
- package/plugins/goalbuddy/agents/goal-judge.md +35 -16
- package/plugins/goalbuddy/agents/goal-scout.md +38 -13
- package/plugins/goalbuddy/agents/goal-worker.md +37 -14
- package/plugins/goalbuddy/skills/goalbuddy/SKILL.md +40 -13
- package/plugins/goalbuddy/skills/goalbuddy/agents/README.md +1 -1
- package/plugins/goalbuddy/skills/goalbuddy/agents/goal_judge.toml +33 -17
- package/plugins/goalbuddy/skills/goalbuddy/agents/goal_scout.toml +34 -14
- package/plugins/goalbuddy/skills/goalbuddy/agents/goal_worker.toml +36 -16
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/README.md +8 -4
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/examples/subgoal-parent/goal.md +3 -0
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/examples/subgoal-parent/notes/.gitkeep +1 -0
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/examples/subgoal-parent/state.yaml +60 -0
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/goal.md +3 -0
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/notes/.gitkeep +1 -0
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/state.yaml +52 -0
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/extension.yaml +6 -4
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/scripts/lib/goal-board.mjs +1188 -31
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/scripts/local-goal-board.mjs +389 -54
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/test/local-goal-board.test.mjs +479 -5
- package/plugins/goalbuddy/skills/goalbuddy/scripts/check-goal-state.mjs +192 -6
- package/plugins/goalbuddy/skills/goalbuddy/scripts/parallel-plan.mjs +191 -0
- package/plugins/goalbuddy/skills/goalbuddy/scripts/render-task-prompt.mjs +305 -0
- package/plugins/goalbuddy/skills/goalbuddy/templates/agents.md +5 -4
- package/plugins/goalbuddy/skills/goalbuddy/templates/goal.md +18 -4
- package/plugins/goalbuddy/skills/goalbuddy/templates/state.yaml +14 -1
|
@@ -52,6 +52,8 @@ const optionsWithValues = new Set([
|
|
|
52
52
|
"--port",
|
|
53
53
|
"--source",
|
|
54
54
|
"--target",
|
|
55
|
+
"--task",
|
|
56
|
+
"--board",
|
|
55
57
|
]);
|
|
56
58
|
|
|
57
59
|
const args = process.argv.slice(2);
|
|
@@ -81,15 +83,23 @@ async function main() {
|
|
|
81
83
|
break;
|
|
82
84
|
case "install":
|
|
83
85
|
case "update":
|
|
86
|
+
if (wantsHelp()) {
|
|
87
|
+
usage();
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
84
90
|
if (installTargetMode() === "all") {
|
|
85
91
|
await installEverywhere();
|
|
86
92
|
} else if (installTargetMode() === "codex") {
|
|
87
|
-
|
|
93
|
+
installPlugin();
|
|
88
94
|
} else {
|
|
89
95
|
await installClaudeAll();
|
|
90
96
|
}
|
|
91
97
|
break;
|
|
92
98
|
case "agents":
|
|
99
|
+
if (wantsHelp()) {
|
|
100
|
+
usage();
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
93
103
|
if (targetMode() === "codex") {
|
|
94
104
|
installAgents();
|
|
95
105
|
} else {
|
|
@@ -97,6 +107,10 @@ async function main() {
|
|
|
97
107
|
}
|
|
98
108
|
break;
|
|
99
109
|
case "doctor":
|
|
110
|
+
if (wantsHelp()) {
|
|
111
|
+
usage();
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
100
114
|
if (targetMode() === "codex") {
|
|
101
115
|
doctor();
|
|
102
116
|
} else {
|
|
@@ -108,6 +122,10 @@ async function main() {
|
|
|
108
122
|
checkUpdate();
|
|
109
123
|
break;
|
|
110
124
|
case "plugin":
|
|
125
|
+
if (wantsHelp()) {
|
|
126
|
+
pluginUsage();
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
111
129
|
plugin();
|
|
112
130
|
break;
|
|
113
131
|
case "extend":
|
|
@@ -116,6 +134,12 @@ async function main() {
|
|
|
116
134
|
case "board":
|
|
117
135
|
await board();
|
|
118
136
|
break;
|
|
137
|
+
case "prompt":
|
|
138
|
+
await prompt();
|
|
139
|
+
break;
|
|
140
|
+
case "parallel-plan":
|
|
141
|
+
await parallelPlan();
|
|
142
|
+
break;
|
|
119
143
|
case "help":
|
|
120
144
|
case "--help":
|
|
121
145
|
case "-h":
|
|
@@ -156,6 +180,10 @@ function hasFlag(name) {
|
|
|
156
180
|
return args.includes(name);
|
|
157
181
|
}
|
|
158
182
|
|
|
183
|
+
function wantsHelp() {
|
|
184
|
+
return hasFlag("--help") || hasFlag("-h");
|
|
185
|
+
}
|
|
186
|
+
|
|
159
187
|
function positional(index) {
|
|
160
188
|
return positionalArgs()[index] || "";
|
|
161
189
|
}
|
|
@@ -191,6 +219,8 @@ Usage:
|
|
|
191
219
|
${canonicalCliName} extend install --all [--catalog-url <url-or-path>] [--dry-run] [--force] [--json]
|
|
192
220
|
${canonicalCliName} extend doctor [<id>] [--codex-home <path>] [--json]
|
|
193
221
|
${canonicalCliName} board <docs/goals/slug> [--catalog-url <url-or-path>] [--host <host>] [--port <port>] [--once] [--json]
|
|
222
|
+
${canonicalCliName} prompt <docs/goals/slug> [--task T###] [--board <path/to/state.yaml>] [--json]
|
|
223
|
+
${canonicalCliName} parallel-plan <docs/goals/slug> [--json]
|
|
194
224
|
|
|
195
225
|
Targets: by default, install/update prepares both Codex (~/.codex) and Claude Code (~/.claude). Use --target codex or --target claude to limit the command.
|
|
196
226
|
|
|
@@ -542,7 +572,7 @@ This alias has the same invocation boundary as \`$${canonicalSkillName}\`: prepa
|
|
|
542
572
|
function installAgents({ quiet = false } = {}) {
|
|
543
573
|
const source = join(skillSource, "agents");
|
|
544
574
|
const target = join(codexHome(), "agents");
|
|
545
|
-
const force = hasFlag("--force") || command === "update" || command === "install";
|
|
575
|
+
const force = hasFlag("--force") || command === "update" || command === "install" || command === "default" || command === "plugin";
|
|
546
576
|
mkdirSync(target, { recursive: true });
|
|
547
577
|
|
|
548
578
|
const results = [];
|
|
@@ -591,6 +621,7 @@ async function installAll() {
|
|
|
591
621
|
function doctor() {
|
|
592
622
|
const skillPath = join(installedSkillRoot(), "SKILL.md");
|
|
593
623
|
const legacySkillPath = join(legacyInstalledSkillRoot(), "SKILL.md");
|
|
624
|
+
const plugin = installedCodexPlugin();
|
|
594
625
|
const agentsPath = join(codexHome(), "agents");
|
|
595
626
|
const installed = existsSync(skillPath);
|
|
596
627
|
const legacyInstalled = existsSync(legacySkillPath);
|
|
@@ -606,12 +637,38 @@ function doctor() {
|
|
|
606
637
|
});
|
|
607
638
|
const goalRuntime = codexGoalRuntimeStatus();
|
|
608
639
|
const warnings = [];
|
|
640
|
+
const errors = [];
|
|
609
641
|
if (!goalRuntime.ready) {
|
|
610
642
|
warnings.push("native Codex /goal runtime is not ready; run `codex login` and `codex features enable goals` before using /goal.");
|
|
611
643
|
}
|
|
644
|
+
if (!plugin.skill_installed && !installed) {
|
|
645
|
+
errors.push("Codex GoalBuddy plugin is not installed; run `npx goalbuddy --target codex`.");
|
|
646
|
+
}
|
|
647
|
+
if (plugin.skill_installed && !plugin.enabled) {
|
|
648
|
+
errors.push("Codex GoalBuddy plugin cache exists but is not enabled in config.toml; run `npx goalbuddy --target codex`.");
|
|
649
|
+
}
|
|
650
|
+
for (const file of missingAgents) {
|
|
651
|
+
errors.push(`Missing GoalBuddy Codex agent: ${file}; run \`npx goalbuddy --target codex\`.`);
|
|
652
|
+
}
|
|
653
|
+
for (const file of staleAgents) {
|
|
654
|
+
errors.push(`Stale GoalBuddy Codex agent: ${file}; run \`npx goalbuddy update --target codex\`.`);
|
|
655
|
+
}
|
|
656
|
+
if (hasFlag("--goal-ready") && !goalRuntime.ready) {
|
|
657
|
+
errors.push("Native Codex /goal runtime is not ready. GoalBuddy $goal-prep and local boards are separate from OpenAI-gated native /goal.");
|
|
658
|
+
}
|
|
612
659
|
|
|
613
660
|
console.log(JSON.stringify({
|
|
614
661
|
codex_home: codexHome(),
|
|
662
|
+
codex_install_model: "plugin",
|
|
663
|
+
expected_state: {
|
|
664
|
+
plugin_cache: true,
|
|
665
|
+
bundled_skill: "$goal-prep",
|
|
666
|
+
standalone_personal_skill: false,
|
|
667
|
+
compatibility_skill: false,
|
|
668
|
+
agents: requiredAgentFiles,
|
|
669
|
+
native_goal: "separate OpenAI-gated Codex feature",
|
|
670
|
+
},
|
|
671
|
+
plugin,
|
|
615
672
|
skill_installed: installed,
|
|
616
673
|
skill_path: skillPath,
|
|
617
674
|
compatibility_skill_installed: legacyInstalled,
|
|
@@ -621,11 +678,14 @@ function doctor() {
|
|
|
621
678
|
stale_agents: staleAgents,
|
|
622
679
|
goal_runtime: goalRuntime,
|
|
623
680
|
warnings,
|
|
681
|
+
errors,
|
|
624
682
|
}, null, 2));
|
|
625
683
|
|
|
626
|
-
const
|
|
684
|
+
const pluginOk = plugin.skill_installed && plugin.enabled;
|
|
685
|
+
const legacySkillOk = installed;
|
|
686
|
+
const installOk = (pluginOk || legacySkillOk) && missingAgents.length === 0 && staleAgents.length === 0;
|
|
627
687
|
const goalReadyOk = !hasFlag("--goal-ready") || goalRuntime.ready;
|
|
628
|
-
process.exit(installOk && goalReadyOk ? 0 : 1);
|
|
688
|
+
process.exit(installOk && goalReadyOk && errors.length === 0 ? 0 : 1);
|
|
629
689
|
}
|
|
630
690
|
|
|
631
691
|
function checkUpdate() {
|
|
@@ -670,6 +730,10 @@ function updateReport() {
|
|
|
670
730
|
|
|
671
731
|
function plugin() {
|
|
672
732
|
const subcommand = positional(1) || "";
|
|
733
|
+
if (wantsHelp()) {
|
|
734
|
+
pluginUsage();
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
673
737
|
switch (subcommand) {
|
|
674
738
|
case "install":
|
|
675
739
|
installPlugin();
|
|
@@ -713,14 +777,17 @@ function installPlugin({ quiet = false } = {}) {
|
|
|
713
777
|
throw new Error(`Failed to add Codex plugin marketplace: ${firstLine(marketplace.stderr || marketplace.stdout)}`);
|
|
714
778
|
}
|
|
715
779
|
|
|
780
|
+
const legacySkillPaths = legacyCodexSkillRoots();
|
|
716
781
|
const existingPluginSkillPath = installedPluginSkillRoot();
|
|
717
|
-
const preservedExtensions = preserveInstalledExtensions([existingPluginSkillPath], { tempRoot: dirname(pluginCachePath) });
|
|
782
|
+
const preservedExtensions = preserveInstalledExtensions([existingPluginSkillPath, ...legacySkillPaths], { tempRoot: dirname(pluginCachePath) });
|
|
718
783
|
mkdirSync(dirname(pluginCachePath), { recursive: true });
|
|
719
784
|
rmSync(pluginCachePath, { recursive: true, force: true });
|
|
720
785
|
cpSync(pluginSource, pluginCachePath, { recursive: true });
|
|
721
786
|
restoreInstalledExtensions(pluginSkillPath, preservedExtensions.tempPath);
|
|
722
787
|
cleanupPreservedExtensions([preservedExtensions.tempPath]);
|
|
788
|
+
const removedLegacySkillPaths = cleanupLegacyCodexSkills();
|
|
723
789
|
const configPath = enablePluginConfig();
|
|
790
|
+
const agents = installAgents({ quiet: true });
|
|
724
791
|
|
|
725
792
|
const report = {
|
|
726
793
|
installed: true,
|
|
@@ -731,7 +798,9 @@ function installPlugin({ quiet = false } = {}) {
|
|
|
731
798
|
marketplace_source: source,
|
|
732
799
|
cache_path: pluginCachePath,
|
|
733
800
|
config_path: configPath,
|
|
801
|
+
agents,
|
|
734
802
|
preserved_extensions: preservedExtensions.ids,
|
|
803
|
+
removed_legacy_skill_paths: removedLegacySkillPaths,
|
|
735
804
|
};
|
|
736
805
|
|
|
737
806
|
if (hasFlag("--json") && !quiet) {
|
|
@@ -745,9 +814,13 @@ function installPlugin({ quiet = false } = {}) {
|
|
|
745
814
|
console.log(`Marketplace: ${source}`);
|
|
746
815
|
console.log(`Cache: ${pluginCachePath}`);
|
|
747
816
|
console.log(`Config: ${configPath}`);
|
|
817
|
+
console.log(`Agents: ${summarizeStatuses(report.agents)}`);
|
|
748
818
|
if (report.preserved_extensions.length) {
|
|
749
819
|
console.log(`Preserved extensions: ${report.preserved_extensions.join(", ")}`);
|
|
750
820
|
}
|
|
821
|
+
if (report.removed_legacy_skill_paths.length) {
|
|
822
|
+
console.log(`Removed legacy personal skills: ${report.removed_legacy_skill_paths.join(", ")}`);
|
|
823
|
+
}
|
|
751
824
|
console.log("");
|
|
752
825
|
console.log("Restart Codex, then use:");
|
|
753
826
|
console.log(` $${canonicalSkillName}`);
|
|
@@ -758,6 +831,20 @@ function installPlugin({ quiet = false } = {}) {
|
|
|
758
831
|
return report;
|
|
759
832
|
}
|
|
760
833
|
|
|
834
|
+
function legacyCodexSkillRoots() {
|
|
835
|
+
return [installedSkillRoot(), legacyInstalledSkillRoot()];
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
function cleanupLegacyCodexSkills() {
|
|
839
|
+
const removed = [];
|
|
840
|
+
for (const path of legacyCodexSkillRoots()) {
|
|
841
|
+
if (!existsSync(path)) continue;
|
|
842
|
+
rmSync(path, { recursive: true, force: true });
|
|
843
|
+
removed.push(path);
|
|
844
|
+
}
|
|
845
|
+
return removed;
|
|
846
|
+
}
|
|
847
|
+
|
|
761
848
|
function pluginCacheRoot(version) {
|
|
762
849
|
return join(codexHome(), "plugins", "cache", pluginName, pluginName, version);
|
|
763
850
|
}
|
|
@@ -941,6 +1028,39 @@ async function board() {
|
|
|
941
1028
|
process.exit(result.status ?? 1);
|
|
942
1029
|
}
|
|
943
1030
|
|
|
1031
|
+
async function prompt() {
|
|
1032
|
+
if (hasFlag("--parallel-plan")) {
|
|
1033
|
+
await parallelPlan();
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
const script = join(skillSource, "scripts", "render-task-prompt.mjs");
|
|
1038
|
+
const scriptArgs = [script, ...args.slice(1)];
|
|
1039
|
+
const result = spawnSync(process.execPath, scriptArgs, {
|
|
1040
|
+
cwd: packageRoot,
|
|
1041
|
+
encoding: "utf8",
|
|
1042
|
+
env: process.env,
|
|
1043
|
+
});
|
|
1044
|
+
if (result.stdout) process.stdout.write(result.stdout);
|
|
1045
|
+
if (result.stderr) process.stderr.write(result.stderr);
|
|
1046
|
+
if (result.error) throw result.error;
|
|
1047
|
+
process.exit(result.status ?? 1);
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
async function parallelPlan() {
|
|
1051
|
+
const script = join(skillSource, "scripts", "parallel-plan.mjs");
|
|
1052
|
+
const scriptArgs = [script, ...args.slice(1).filter((arg) => arg !== "--parallel-plan")];
|
|
1053
|
+
const result = spawnSync(process.execPath, scriptArgs, {
|
|
1054
|
+
cwd: packageRoot,
|
|
1055
|
+
encoding: "utf8",
|
|
1056
|
+
env: process.env,
|
|
1057
|
+
});
|
|
1058
|
+
if (result.stdout) process.stdout.write(result.stdout);
|
|
1059
|
+
if (result.stderr) process.stderr.write(result.stderr);
|
|
1060
|
+
if (result.error) throw result.error;
|
|
1061
|
+
process.exit(result.status ?? 1);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
944
1064
|
async function ensureLocalBoardExtension() {
|
|
945
1065
|
const id = "local-goal-board";
|
|
946
1066
|
const script = join(extensionTarget(id), "scripts", "local-goal-board.mjs");
|
|
@@ -1235,8 +1355,24 @@ function installedSkillRoot() {
|
|
|
1235
1355
|
}
|
|
1236
1356
|
|
|
1237
1357
|
function installedPluginSkillRoot() {
|
|
1358
|
+
return installedCodexPlugin().skill_path;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
function installedCodexPlugin() {
|
|
1238
1362
|
const root = join(codexHome(), "plugins", "cache", pluginName, pluginName);
|
|
1239
|
-
|
|
1363
|
+
const configPath = join(codexHome(), "config.toml");
|
|
1364
|
+
const base = {
|
|
1365
|
+
installed: false,
|
|
1366
|
+
enabled: pluginConfigEnabled(configPath),
|
|
1367
|
+
name: `${pluginName}@${pluginName}`,
|
|
1368
|
+
version: "",
|
|
1369
|
+
cache_path: "",
|
|
1370
|
+
manifest_path: "",
|
|
1371
|
+
skill_installed: false,
|
|
1372
|
+
skill_path: "",
|
|
1373
|
+
config_path: configPath,
|
|
1374
|
+
};
|
|
1375
|
+
if (!existsSync(root)) return base;
|
|
1240
1376
|
const versions = readdirSync(root, { withFileTypes: true })
|
|
1241
1377
|
.filter((entry) => entry.isDirectory())
|
|
1242
1378
|
.map((entry) => entry.name)
|
|
@@ -1244,10 +1380,37 @@ function installedPluginSkillRoot() {
|
|
|
1244
1380
|
.sort(compareVersions)
|
|
1245
1381
|
.reverse();
|
|
1246
1382
|
for (const version of versions) {
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1383
|
+
const cachePath = join(root, version);
|
|
1384
|
+
const skillPath = join(cachePath, "skills", canonicalSkillDirectory);
|
|
1385
|
+
const manifestPath = join(cachePath, ".codex-plugin", "plugin.json");
|
|
1386
|
+
if (existsSync(join(skillPath, "SKILL.md"))) {
|
|
1387
|
+
return {
|
|
1388
|
+
...base,
|
|
1389
|
+
installed: true,
|
|
1390
|
+
version,
|
|
1391
|
+
cache_path: cachePath,
|
|
1392
|
+
manifest_path: manifestPath,
|
|
1393
|
+
skill_installed: true,
|
|
1394
|
+
skill_path: skillPath,
|
|
1395
|
+
};
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
return base;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
function pluginConfigEnabled(configPath) {
|
|
1402
|
+
if (!existsSync(configPath)) return false;
|
|
1403
|
+
const lines = readFileSync(configPath, "utf8").split(/\r?\n/);
|
|
1404
|
+
const header = `[plugins."${pluginName}@${pluginName}"]`;
|
|
1405
|
+
const start = lines.findIndex((line) => line.trim() === header);
|
|
1406
|
+
if (start === -1) return false;
|
|
1407
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
1408
|
+
const line = lines[index].trim();
|
|
1409
|
+
if (line.startsWith("[")) break;
|
|
1410
|
+
if (/^enabled\s*=\s*true\b/.test(line)) return true;
|
|
1411
|
+
if (/^enabled\s*=/.test(line)) return false;
|
|
1249
1412
|
}
|
|
1250
|
-
return
|
|
1413
|
+
return false;
|
|
1251
1414
|
}
|
|
1252
1415
|
|
|
1253
1416
|
function activeSkillRoot() {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goalbuddy",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "A /goal operating system for Codex and Claude Code:
|
|
3
|
+
"version": "0.3.6",
|
|
4
|
+
"description": "A /goal operating system for Codex and Claude Code: subgoals, parallel-agent-ready boards, dark mode, receipts, and verification.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"goalbuddy": "internal/cli/goal-maker.mjs",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
".agents/plugins/marketplace.json",
|
|
12
12
|
"README.md",
|
|
13
|
+
"RELEASE-0.3.5.md",
|
|
13
14
|
"CONTRIBUTING.md",
|
|
14
15
|
"examples",
|
|
15
16
|
"plugins/goalbuddy",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goalbuddy",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "Turn broad Claude Code work into verified GoalBuddy boards with
|
|
3
|
+
"version": "0.3.6",
|
|
4
|
+
"description": "Turn broad Claude Code work into verified GoalBuddy boards with subgoals, parallel-agent-ready handoffs, dark mode, and receipts.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tolibear",
|
|
7
7
|
"email": "support@tolibear.com",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goalbuddy",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "Turn broad Codex and Claude Code work into verified GoalBuddy boards with
|
|
3
|
+
"version": "0.3.6",
|
|
4
|
+
"description": "Turn broad Codex and Claude Code work into verified GoalBuddy boards with subgoals, parallel-agent-ready handoffs, dark mode, and receipts.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tolibear",
|
|
7
7
|
"email": "support@tolibear.com",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"skills": "./skills/",
|
|
25
25
|
"interface": {
|
|
26
26
|
"displayName": "GoalBuddy",
|
|
27
|
-
"shortDescription": "
|
|
28
|
-
"longDescription": "GoalBuddy packages a structured goal workflow for broad, long-running, or ambiguous engineering work in Codex or Claude Code. It creates durable goal charters, task boards, visual board surfaces, receipts, verification gates, extension handoffs, and compatibility guidance for teams moving from goal-maker.",
|
|
27
|
+
"shortDescription": "Verified goal boards with subgoals, parallel-agent-ready handoffs, and dark mode",
|
|
28
|
+
"longDescription": "GoalBuddy packages a structured goal workflow for broad, long-running, or ambiguous engineering work in Codex or Claude Code. It creates durable goal charters, task boards, optional depth-1 subgoals, visual board surfaces, parallel-agent-ready handoffs, receipts, verification gates, extension handoffs, and compatibility guidance for teams moving from goal-maker.",
|
|
29
29
|
"developerName": "tolibear",
|
|
30
30
|
"category": "Coding",
|
|
31
31
|
"capabilities": [
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
GoalBuddy packages the canonical `goal-prep` skill as a plugin so teams can install the reusable workflow in **Codex** and **Claude Code**, while keeping the npm CLI for local setup, doctor checks, and extension management.
|
|
4
4
|
|
|
5
|
+
Version 0.3.5 is the Subgoals, Parallel Agents, and Dark Mode release: depth-1 child boards, a shared multi-board local hub, readable dark-mode boards, stricter agent contracts, deterministic prompt rendering, and conservative parallel planning for long-running work.
|
|
6
|
+
|
|
5
7
|
## What It Contains
|
|
6
8
|
|
|
7
9
|
- `.codex-plugin/plugin.json`: Codex plugin manifest and Codex UI copy.
|
|
8
10
|
- `.claude-plugin/plugin.json`: Claude Code plugin manifest.
|
|
9
11
|
- `skills/goalbuddy/`: the installable GoalBuddy skill payload (shared by both platforms).
|
|
10
12
|
- `agents/`: Claude Code subagent definitions (`goal-scout.md`, `goal-judge.md`, `goal-worker.md`).
|
|
11
|
-
- `
|
|
13
|
+
- `skills/goalbuddy/SKILL.md`: canonical `$goal-prep` / `/goal-prep` entry point.
|
|
12
14
|
- `assets/goalbuddy-icon.svg`: lightweight plugin icon.
|
|
13
15
|
|
|
14
16
|
## Local Testing
|
|
@@ -27,7 +29,7 @@ npx goalbuddy check-update
|
|
|
27
29
|
npx goalbuddy
|
|
28
30
|
```
|
|
29
31
|
|
|
30
|
-
This installs and enables the native Codex plugin in `~/.codex/`, then installs the GoalBuddy skill
|
|
32
|
+
This installs and enables the native Codex plugin in `~/.codex/`, then installs the GoalBuddy skill and Scout/Judge/Worker subagents into `~/.claude/`. The skill surfaces `/goal-prep` in Claude Code.
|
|
31
33
|
|
|
32
34
|
## Install One Target
|
|
33
35
|
|
|
@@ -36,7 +38,7 @@ npx goalbuddy --target codex
|
|
|
36
38
|
npx goalbuddy --target claude
|
|
37
39
|
```
|
|
38
40
|
|
|
39
|
-
This installs the GoalBuddy skill
|
|
41
|
+
This installs the GoalBuddy skill and the three Scout/Judge/Worker subagents into `~/.claude/`. Restart Claude Code, then run:
|
|
40
42
|
|
|
41
43
|
```text
|
|
42
44
|
/goal-prep
|
|
@@ -1,27 +1,46 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: goal-judge
|
|
3
|
-
description: GoalBuddy Judge.
|
|
3
|
+
description: GoalBuddy Judge. Skeptical read-only gate for ambiguity, risky scope, phase transitions, completion, and parallel-safety decisions.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
You are Judge for GoalBuddy.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
Mode: strategic reviewer and escalation authority.
|
|
9
|
+
Use Judge only for decisions that require judgment: contradictory sources, risky scope, dependency order, phase gates, live/API/security/persistence choices, completion, or whether work can safely branch into a depth-1 sub-goal. Routine checks belong to the checker.
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
Hard contract:
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
- Read only. Do not edit, stage, install, or implement.
|
|
14
|
+
- Read state receipts before raw files. Then read only the inputs named in the Judge task.
|
|
15
|
+
- Be skeptical of progress. Lots of files, docs, or tests are not completion.
|
|
16
|
+
- A safe Worker package must include objective, allowed_files, verify commands, and stop_if, and should cover the largest reversible local work package at that boundary.
|
|
17
|
+
- Choose the largest safe useful slice: bounded, explicit, verified, reversible, and outcome-moving. Safety does not mean tiny.
|
|
18
|
+
- Judge a whole useful slice, not one helper at a time.
|
|
19
|
+
- Detect micro-slice loops. Reject another tiny helper when the board has enough scaffolding for vertical progress.
|
|
20
|
+
- Select PM reorientation when recent receipts are safe-looking but outcome-light.
|
|
21
|
+
- Prefer milestone reviews over helper reviews.
|
|
22
|
+
- A safe child board must be depth 1, inside `subgoals/`, non-recursive, and linked from exactly one parent task.
|
|
23
|
+
- Parallel Worker work is safe only with provably disjoint `allowed_files`. Separate boards alone are not proof.
|
|
24
|
+
- Reject completion unless the full original outcome is mapped to receipts and current verification.
|
|
25
|
+
- Do not generate routine next tasks, choose the active task, or mutate state. The PM owns continuation after your review.
|
|
15
26
|
|
|
16
|
-
|
|
27
|
+
Return exactly one parseable JSON receipt object:
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"goalbuddy_receipt_v1": {
|
|
32
|
+
"result": "done | blocked",
|
|
33
|
+
"task_id": "<T###>",
|
|
34
|
+
"board_path": "<path to state.yaml>",
|
|
35
|
+
"decision": "approved | rejected | approve_subgoal | reject_subgoal | not_complete | complete",
|
|
36
|
+
"full_outcome_complete": false,
|
|
37
|
+
"rationale": "<=120 words>",
|
|
38
|
+
"evidence": [],
|
|
39
|
+
"subgoal_contract": null,
|
|
40
|
+
"parallel_safety": null,
|
|
41
|
+
"blocked_tasks": [],
|
|
42
|
+
"missing_evidence": [],
|
|
43
|
+
"required_board_updates": []
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
@@ -1,24 +1,49 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: goal-scout
|
|
3
|
-
description: GoalBuddy Scout. Read-only
|
|
3
|
+
description: GoalBuddy Scout. Read-only mapper for one active task. Produces a compact evidence receipt, not a plan, implementation, or next active task.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
You are Scout for GoalBuddy.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
Mode: read-only evidence mapping.
|
|
9
|
+
Default effort: low. Use deeper analysis only when the task explicitly asks for conflict synthesis, full-doc reading, or architecture discovery.
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
Hard contract:
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
- Read only. Do not edit, stage, install, start long-running services, or spawn agents.
|
|
14
|
+
- Work only on the active Scout task the PM gives you.
|
|
15
|
+
- Prefer targeted inspection over broad dumps. Do not paste full files or long command output.
|
|
16
|
+
- Read receipts and named inputs first. Only expand to extra files when needed to answer the task.
|
|
17
|
+
- Return evidence, contradictions, and candidate facts. Do not choose the next active task and do not mark completion.
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
- result
|
|
18
|
-
- summary
|
|
19
|
-
- evidence paths
|
|
20
|
-
- note path if findings are too large for the task card
|
|
21
|
-
- spawned_tasks when useful
|
|
22
|
-
- ambiguity requiring Judge
|
|
19
|
+
Parallel safety:
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
- Scout may run in parallel with other Scouts because it is read-only.
|
|
22
|
+
- If asked to work on a child board, inspect only that child board plus explicitly linked parent context.
|
|
23
|
+
- Never mutate parent or child state.
|
|
24
|
+
|
|
25
|
+
Budget:
|
|
26
|
+
|
|
27
|
+
- Max 12 shell commands unless the task explicitly allows more.
|
|
28
|
+
- Max 12 evidence items.
|
|
29
|
+
- Summary max 120 words.
|
|
30
|
+
- If findings are long, request a note file path from the PM instead of dumping content.
|
|
31
|
+
|
|
32
|
+
Return exactly one parseable JSON receipt object:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"goalbuddy_receipt_v1": {
|
|
37
|
+
"result": "done | blocked",
|
|
38
|
+
"task_id": "<T###>",
|
|
39
|
+
"board_path": "<path to state.yaml>",
|
|
40
|
+
"summary": "<=120 words>",
|
|
41
|
+
"evidence": [],
|
|
42
|
+
"facts": [],
|
|
43
|
+
"contradictions": [],
|
|
44
|
+
"ambiguity_requiring_judge": [],
|
|
45
|
+
"commands": [],
|
|
46
|
+
"note_needed": false
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
@@ -1,26 +1,49 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: goal-worker
|
|
3
|
-
description: GoalBuddy Worker.
|
|
3
|
+
description: GoalBuddy Worker. Bounded writer for one coherent reversible Worker work package. Edits only allowed_files, runs verify, returns receipt.
|
|
4
4
|
tools: Read, Edit, Write, Grep, Glob, Bash
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
You are Worker for GoalBuddy.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
Mode: one bounded writer.
|
|
9
|
+
Default effort: medium for implementation tasks. Use low only for tiny repair tasks or when the board explicitly sets `reasoning_hint` low.
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
Hard contract:
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
- Execute exactly one Worker task on exactly one board.
|
|
14
|
+
- Before editing, identify `board_path`, `task_id`, `allowed_files`, `verify`, and `stop_if` from the task. If any are missing, stop.
|
|
15
|
+
- Edit only files matching `allowed_files`. Do not edit GoalBuddy control files unless explicitly listed.
|
|
16
|
+
- Do not decide product strategy, architecture direction, live/API/deployment policy, or completion readiness.
|
|
17
|
+
- Do not spawn agents.
|
|
18
|
+
- Do not create child sub-goals unless the task explicitly allows it.
|
|
19
|
+
- Run the verify commands exactly as listed after edits. You may make at most two fix attempts.
|
|
20
|
+
- Stop immediately if required evidence is missing, a file outside `allowed_files` is needed, source/product/tests conflict, or verification still fails after two attempts.
|
|
21
|
+
- Do not request a Judge just because the package is done. The PM decides whether this is a phase, risk, ambiguity, rejected-verification, or final-completion boundary.
|
|
22
|
+
- Keep the diff coherent, bounded, and reversible. Do not shrink the assigned work below the largest safe useful slice.
|
|
23
|
+
- Complete the whole assigned slice. Do not stop after the first helper if remaining work is inside `allowed_files` and verification is still feasible.
|
|
24
|
+
- If the task asks for a vertical slice, complete the vertical slice.
|
|
15
25
|
|
|
16
|
-
|
|
26
|
+
Parallel safety:
|
|
17
27
|
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
- summary
|
|
23
|
-
- remaining_blockers
|
|
24
|
-
- needs_judge when strategy or ambiguity remains
|
|
28
|
+
- Do not assume parallel Worker safety.
|
|
29
|
+
- If another active Worker may touch the same files, stop and report a blocker.
|
|
30
|
+
- Work on a child board only when the task `board_path` points to that child `state.yaml`.
|
|
31
|
+
- Never mutate the parent board from a child Worker unless the parent board file is explicitly in `allowed_files`.
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
Return exactly one parseable JSON receipt object:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"goalbuddy_receipt_v1": {
|
|
38
|
+
"result": "done | blocked",
|
|
39
|
+
"task_id": "<T###>",
|
|
40
|
+
"board_path": "<path to state.yaml>",
|
|
41
|
+
"changed_files": [],
|
|
42
|
+
"commands": [],
|
|
43
|
+
"summary": "<=120 words>",
|
|
44
|
+
"remaining_blockers": [],
|
|
45
|
+
"verification_attempts": 1,
|
|
46
|
+
"stopped_because": null
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|