akili-specs 2.10.0 → 2.10.1

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/CHANGELOG.md CHANGED
@@ -10,6 +10,11 @@ The format is inspired by Keep a Changelog and the repository follows semantic v
10
10
 
11
11
  - No unreleased changes yet.
12
12
 
13
+ ## [2.10.1] - 2026-07-23
14
+
15
+ ### Changed
16
+
17
+ - **Installer auto-detects installed targets (`bin/akili.js`):** when `--tool` is omitted, `install`, `update`, and `doctor` now scan disk for already-installed targets (`~/.claude`, `~/.config/opencode`, `~/.gemini`) and act on **all** of them instead of silently defaulting to `claude`. A bare `akili update` therefore refreshes every installed tool — fixing the case where new commands (e.g. `akili-quick`, `akili-resume`) landed in Claude Code but never reached OpenCode. An explicit `--tool <name>` still wins; a first-time run with nothing installed still defaults to `claude`. Auto-detected runs print which targets were found, and the update/verify summaries report the resolved tool set and a matching `akili doctor --tool …` hint.
13
18
  ## [2.10.0] - 2026-07-22
14
19
 
15
20
  ### Added
package/bin/akili.js CHANGED
@@ -96,7 +96,9 @@ Commands:
96
96
  help Show this help
97
97
 
98
98
  Options:
99
- --tool <name> Install target: claude, opencode, antigravity, both, or all. Default: claude
99
+ --tool <name> Install target: claude, opencode, antigravity, both, or all.
100
+ When omitted, install/update/doctor auto-detect already-installed
101
+ targets; if none are found they default to claude.
100
102
  --target <path> Target config directory for selected single tool
101
103
  --claude-target Claude config directory. Default: ~/.claude
102
104
  --opencode-target OpenCode config directory. Default: ~/.config/opencode
@@ -178,9 +180,17 @@ function getArgs() {
178
180
  const baseOpencode = values.local ? path.join(process.cwd(), ".config", "opencode") : defaultPaths.opencode;
179
181
  const baseAntigravity = values.local ? path.join(process.cwd(), ".gemini") : defaultPaths.antigravity;
180
182
 
183
+ // Whether the user explicitly passed --tool. When they did not, install/
184
+ // update/doctor auto-detect already-installed targets instead of assuming
185
+ // the "claude" default (see resolveTools).
186
+ const toolExplicit =
187
+ process.argv.includes("--tool") ||
188
+ process.argv.some((a) => a.startsWith("--tool="));
189
+
181
190
  const args = {
182
191
  command,
183
192
  tool: values.tool,
193
+ toolExplicit,
184
194
  force: values.force,
185
195
  dryRun: values["dry-run"],
186
196
  commandsOnly: values["commands-only"],
@@ -230,6 +240,57 @@ function selectedTools(args) {
230
240
  return [args.tool];
231
241
  }
232
242
 
243
+ const ALL_TOOLS = ["claude", "opencode", "antigravity"];
244
+
245
+ // A tool counts as installed when any of its target directories exists and is
246
+ // non-empty. Checking commands / skills / resources covers --commands-only and
247
+ // --skills-only installs too, not just full ones.
248
+ function isToolInstalled(tool, args) {
249
+ const { paths } = getToolRegistryInfo(tool, args);
250
+ const dirs = [...paths.commands, paths.skills, paths.resources];
251
+ return dirs.some((dir) => {
252
+ try {
253
+ return fs.existsSync(dir) && fs.readdirSync(dir).length > 0;
254
+ } catch {
255
+ return false;
256
+ }
257
+ });
258
+ }
259
+
260
+ function detectInstalledTools(args) {
261
+ return ALL_TOOLS.filter((tool) => isToolInstalled(tool, args));
262
+ }
263
+
264
+ // Resolve which tools an install/update/doctor run should act on. An explicit
265
+ // --tool always wins. Otherwise we auto-detect targets already on disk so a bare
266
+ // `akili update` refreshes every installed tool (e.g. claude AND opencode)
267
+ // instead of silently defaulting to claude only. A first-time run with nothing
268
+ // installed falls back to the default (claude). The resolved list and any
269
+ // auto-detection note are stashed on args for the summary output.
270
+ function resolveTools(args) {
271
+ if (args.toolExplicit) {
272
+ args.resolvedTools = selectedTools(args);
273
+ return args.resolvedTools;
274
+ }
275
+ const detected = detectInstalledTools(args);
276
+ const isJustDefault = detected.length === 1 && detected[0] === args.tool;
277
+ if (detected.length > 0 && !isJustDefault) {
278
+ args.autoDetected = detected;
279
+ args.resolvedTools = detected;
280
+ return detected;
281
+ }
282
+ args.resolvedTools = selectedTools(args);
283
+ return args.resolvedTools;
284
+ }
285
+
286
+ // Map a resolved tool list back to a --tool flag value for verify hints.
287
+ function toolFlagFor(tools) {
288
+ if (tools.length === 1) return tools[0];
289
+ const set = new Set(tools);
290
+ if (set.size === 2 && set.has("claude") && set.has("opencode")) return "both";
291
+ return "all";
292
+ }
293
+
233
294
  function shouldInclude(type, args) {
234
295
  if (args.commandsOnly) return type === "commands";
235
296
  if (args.skillsOnly) return type === "skills";
@@ -580,8 +641,9 @@ function runUpdate(args) {
580
641
  } else {
581
642
  console.log(` Package: updated from v${versionBefore} (${installType} install; new version could not be read)`);
582
643
  }
583
- console.log(` Files: reinstalled with --force for ${selectedTools(args).join(", ")} (see Install Summary above)`);
584
- console.log(` Verify: ${colors.cyan}akili doctor --tool ${args.tool}${colors.reset}`);
644
+ const updatedTools = args.resolvedTools || selectedTools(args);
645
+ console.log(` Files: reinstalled with --force for ${updatedTools.join(", ")}${args.autoDetected ? " (auto-detected)" : ""} (see Install Summary above)`);
646
+ console.log(` Verify: ${colors.cyan}akili doctor --tool ${toolFlagFor(updatedTools)}${colors.reset}`);
585
647
  }
586
648
 
587
649
  function summaryCounts(result) {
@@ -589,7 +651,15 @@ function summaryCounts(result) {
589
651
  }
590
652
 
591
653
  function runInstall(args) {
592
- const tools = selectedTools(args);
654
+ const tools = resolveTools(args);
655
+ if (args.autoDetected) {
656
+ console.log(
657
+ `\n${colors.cyan}Auto-detected installed target(s): ${args.autoDetected.join(", ")}${colors.reset}`
658
+ );
659
+ console.log(
660
+ ` Refreshing all detected targets. Pass ${colors.yellow}--tool <name>${colors.reset} to override.`
661
+ );
662
+ }
593
663
  const results = [];
594
664
 
595
665
  for (const tool of tools) {
@@ -626,7 +696,7 @@ function runInstall(args) {
626
696
  if (args.dryRun) {
627
697
  console.log(` - Re-run without ${colors.yellow}--dry-run${colors.reset} to apply the changes above.`);
628
698
  } else {
629
- console.log(` - Verify the installation with ${colors.cyan}akili doctor --tool ${args.tool}${colors.reset}.`);
699
+ console.log(` - Verify the installation with ${colors.cyan}akili doctor --tool ${toolFlagFor(tools)}${colors.reset}.`);
630
700
  }
631
701
  }
632
702
 
@@ -755,7 +825,16 @@ function doctorTool(tool, args) {
755
825
  function runDoctor(args) {
756
826
  const results = [];
757
827
 
758
- for (const tool of selectedTools(args)) {
828
+ const tools = resolveTools(args);
829
+ if (args.autoDetected) {
830
+ console.log(
831
+ `\n${colors.cyan}Auto-detected installed target(s): ${args.autoDetected.join(", ")}${colors.reset}`
832
+ );
833
+ console.log(
834
+ ` Checking all detected targets. Pass ${colors.yellow}--tool <name>${colors.reset} to override.`
835
+ );
836
+ }
837
+ for (const tool of tools) {
759
838
  results.push({ tool, ...doctorTool(tool, args) });
760
839
  }
761
840
 
@@ -875,6 +954,7 @@ async function runInteractiveInit() {
875
954
  const args = {
876
955
  command: "install",
877
956
  tool: tool,
957
+ toolExplicit: true,
878
958
  force: false,
879
959
  dryRun: false,
880
960
  commandsOnly: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akili-specs",
3
- "version": "2.10.0",
3
+ "version": "2.10.1",
4
4
  "description": "Portable AKILI-SPECS methodology commands and skills for AI-assisted development.",
5
5
  "homepage": "https://github.com/JuankCadavid/akili-specs#readme",
6
6
  "repository": {