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 +5 -0
- package/bin/akili.js +86 -6
- package/package.json +1 -1
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.
|
|
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
|
-
|
|
584
|
-
console.log(`
|
|
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 =
|
|
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 ${
|
|
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
|
-
|
|
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