goalbuddy 0.2.16 → 0.2.18

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
@@ -172,9 +172,10 @@ npx goalbuddy extend
172
172
  npx goalbuddy extend github-pr-workflow
173
173
  npx goalbuddy extend install github-pr-workflow --dry-run
174
174
  npx goalbuddy extend install --all --dry-run
175
+ npx goalbuddy extend install --all
175
176
  ```
176
177
 
177
- `goalbuddy extend` shows available extensions plus local install state, activation state, credential requirements, safe-by-default status, and missing environment variables.
178
+ `goalbuddy extend` shows available extensions and detail commands. `goalbuddy extend <id>` shows local install state, activation state, credential requirements, safe-by-default status, and missing environment variables.
178
179
 
179
180
  Current catalog examples include:
180
181
 
@@ -1,6 +1,6 @@
1
1
  interface:
2
- display_name: "GoalBuddy"
3
- short_description: "Diagnose intent before making reliable goal boards."
2
+ display_name: "Goal Prep"
3
+ short_description: "Prepare GoalBuddy boards before running /goal."
4
4
  default_prompt: "Use goal-prep to run diagnostic intake on my rough or detailed goal. If the goal is vague or improvement-oriented, ask one guided question at a time, surface likely blind spots, and do not create files until intent, proof, scope, and board handling are clear or explicitly defaulted. If it is clear or already planned, prepare or repair goal.md, state.yaml, and notes/, then print the /goal Follow command instead of starting /goal automatically."
5
5
  policy:
6
6
  allow_implicit_invocation: true
@@ -406,6 +406,10 @@ function installPlugin() {
406
406
  console.log("");
407
407
  console.log("Restart Codex, then use:");
408
408
  console.log(` $${canonicalSkillName}`);
409
+ console.log("");
410
+ console.log("Optional extensions:");
411
+ console.log(` npx ${canonicalCliName} extend`);
412
+ console.log(` npx ${canonicalCliName} extend install --all`);
409
413
  }
410
414
 
411
415
  function pluginCacheRoot(version) {
@@ -568,17 +572,9 @@ async function extendCatalog() {
568
572
  for (const extension of extensions) {
569
573
  console.log(extension.name || extension.id);
570
574
  if (extension.summary) console.log(` ${extension.summary}`);
571
- console.log(` id: ${extension.id}`);
572
- console.log(` kind: ${extension.kind} | activation: ${extension.activation || "unspecified"}`);
573
- console.log(` state: ${extension.state.installed ? "installed" : "available"} | configured: ${extension.state.configured ? "yes" : "no"}`);
574
- console.log(` safe by default: ${extension.safe_by_default ? "yes" : "no"} | requires approval: ${extension.requires_approval ? "yes" : "no"}`);
575
- if (extension.state.missing_env.length) {
576
- console.log(` missing env: ${extension.state.missing_env.join(", ")}`);
577
- }
575
+ console.log(` Details: npx ${canonicalCliName} extend ${extension.id}`);
578
576
  console.log("");
579
577
  }
580
- console.log("View details:");
581
- console.log(` npx ${canonicalCliName} extend ${extensions[0].id}`);
582
578
  console.log("Install all:");
583
579
  console.log(` npx ${canonicalCliName} extend install --all`);
584
580
  }
@@ -799,12 +795,34 @@ function installedSkillRoot() {
799
795
  return join(codexHome(), "skills", canonicalSkillDirectory);
800
796
  }
801
797
 
798
+ function installedPluginSkillRoot() {
799
+ const root = join(codexHome(), "plugins", "cache", pluginName, pluginName);
800
+ if (!existsSync(root)) return "";
801
+ const versions = readdirSync(root, { withFileTypes: true })
802
+ .filter((entry) => entry.isDirectory())
803
+ .map((entry) => entry.name)
804
+ .sort(compareVersions)
805
+ .reverse();
806
+ for (const version of versions) {
807
+ const skillPath = join(root, version, "skills", canonicalSkillDirectory);
808
+ if (existsSync(join(skillPath, "SKILL.md"))) return skillPath;
809
+ }
810
+ return "";
811
+ }
812
+
813
+ function activeSkillRoot() {
814
+ if (existsSync(join(installedSkillRoot(), "SKILL.md"))) return installedSkillRoot();
815
+ const pluginSkillRoot = installedPluginSkillRoot();
816
+ if (pluginSkillRoot) return pluginSkillRoot;
817
+ return installedSkillRoot();
818
+ }
819
+
802
820
  function legacyInstalledSkillRoot() {
803
821
  return join(codexHome(), "skills", legacySkillName);
804
822
  }
805
823
 
806
824
  function extendRoot() {
807
- return join(installedSkillRoot(), "extend");
825
+ return join(activeSkillRoot(), "extend");
808
826
  }
809
827
 
810
828
  function extensionTarget(id) {
@@ -1105,9 +1123,20 @@ function summarizeStatuses(items) {
1105
1123
  }
1106
1124
 
1107
1125
  function assertSkillInstalledForExtensionInstall() {
1108
- if (!existsSync(join(installedSkillRoot(), "SKILL.md"))) {
1109
- throw new Error(`${canonicalProductName} skill is not installed at ${installedSkillRoot()}. Run: npx ${canonicalCliName}`);
1126
+ if (!existsSync(join(activeSkillRoot(), "SKILL.md"))) {
1127
+ throw new Error(`${canonicalProductName} skill is not installed. Run: npx ${canonicalCliName}`);
1128
+ }
1129
+ }
1130
+
1131
+ function compareVersions(left, right) {
1132
+ const leftParts = left.split(".").map((part) => Number.parseInt(part, 10) || 0);
1133
+ const rightParts = right.split(".").map((part) => Number.parseInt(part, 10) || 0);
1134
+ const length = Math.max(leftParts.length, rightParts.length);
1135
+ for (let index = 0; index < length; index += 1) {
1136
+ const diff = (leftParts[index] || 0) - (rightParts[index] || 0);
1137
+ if (diff !== 0) return diff;
1110
1138
  }
1139
+ return left.localeCompare(right);
1111
1140
  }
1112
1141
 
1113
1142
  function installedExtensions() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goalbuddy",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
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": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goalbuddy",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
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",
@@ -1,6 +1,6 @@
1
1
  interface:
2
- display_name: "GoalBuddy"
3
- short_description: "Diagnose intent before making reliable goal boards."
2
+ display_name: "Goal Prep"
3
+ short_description: "Prepare GoalBuddy boards before running /goal."
4
4
  default_prompt: "Use goal-prep to run diagnostic intake on my rough or detailed goal. If the goal is vague or improvement-oriented, ask one guided question at a time, surface likely blind spots, and do not create files until intent, proof, scope, and board handling are clear or explicitly defaulted. If it is clear or already planned, prepare or repair goal.md, state.yaml, and notes/, then print the /goal Follow command instead of starting /goal automatically."
5
5
  policy:
6
6
  allow_implicit_invocation: true