agentikit 0.0.13 → 0.0.15
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/LICENSE +385 -0
- package/README.md +187 -110
- package/dist/{src/asset-spec.js → asset-spec.js} +11 -2
- package/dist/{src/asset-type-handler.js → asset-type-handler.js} +4 -3
- package/dist/cli.js +709 -0
- package/dist/common.js +192 -0
- package/dist/{src/config-cli.js → config-cli.js} +36 -30
- package/dist/{src/config.js → config.js} +95 -25
- package/dist/{src/db.js → db.js} +123 -51
- package/dist/{src/embedder.js → embedder.js} +57 -2
- package/dist/errors.js +28 -0
- package/dist/file-context.js +188 -0
- package/dist/{src/frontmatter.js → frontmatter.js} +1 -1
- package/dist/{src/github.js → github.js} +1 -3
- package/dist/handlers/agent-handler.js +19 -0
- package/dist/handlers/command-handler.js +20 -0
- package/dist/handlers/handler-bridge.js +51 -0
- package/dist/handlers/index.js +19 -0
- package/dist/handlers/knowledge-handler.js +32 -0
- package/dist/handlers/script-handler.js +42 -0
- package/dist/{src/handlers → handlers}/skill-handler.js +5 -6
- package/dist/{src/handlers → handlers}/tool-handler.js +8 -24
- package/dist/{src/indexer.js → indexer.js} +50 -26
- package/dist/init.js +43 -0
- package/dist/{src/llm.js → llm.js} +6 -11
- package/dist/lockfile.js +60 -0
- package/dist/matchers.js +163 -0
- package/dist/{src/metadata.js → metadata.js} +36 -16
- package/dist/{src/origin-resolve.js → origin-resolve.js} +10 -9
- package/dist/paths.js +83 -0
- package/dist/{src/registry-install.js → registry-install.js} +151 -19
- package/dist/{src/registry-resolve.js → registry-resolve.js} +190 -26
- package/dist/{src/registry-search.js → registry-search.js} +13 -21
- package/dist/renderers.js +286 -0
- package/dist/{src/ripgrep-install.js → ripgrep-install.js} +8 -27
- package/dist/{src/ripgrep-resolve.js → ripgrep-resolve.js} +21 -11
- package/dist/ripgrep.js +2 -0
- package/dist/self-update.js +226 -0
- package/dist/{src/stash-add.js → stash-add.js} +14 -4
- package/dist/stash-clone.js +115 -0
- package/dist/{src/stash-ref.js → stash-ref.js} +10 -9
- package/dist/{src/stash-registry.js → stash-registry.js} +21 -46
- package/dist/{src/stash-resolve.js → stash-resolve.js} +10 -9
- package/dist/{src/stash-search.js → stash-search.js} +89 -74
- package/dist/stash-show.js +74 -0
- package/dist/stash-source.js +127 -0
- package/dist/submit.js +557 -0
- package/dist/{src/tool-runner.js → tool-runner.js} +1 -5
- package/dist/{src/walker.js → walker.js} +38 -0
- package/dist/warn.js +20 -0
- package/package.json +13 -18
- package/dist/index.d.ts +0 -28
- package/dist/index.js +0 -15
- package/dist/src/asset-spec.d.ts +0 -16
- package/dist/src/asset-type-handler.d.ts +0 -27
- package/dist/src/cli.d.ts +0 -2
- package/dist/src/cli.js +0 -399
- package/dist/src/common.d.ts +0 -13
- package/dist/src/common.js +0 -60
- package/dist/src/config-cli.d.ts +0 -9
- package/dist/src/config.d.ts +0 -50
- package/dist/src/db.d.ts +0 -46
- package/dist/src/embedder.d.ts +0 -10
- package/dist/src/frontmatter.d.ts +0 -30
- package/dist/src/github.d.ts +0 -4
- package/dist/src/handlers/agent-handler.d.ts +0 -2
- package/dist/src/handlers/agent-handler.js +0 -26
- package/dist/src/handlers/command-handler.d.ts +0 -2
- package/dist/src/handlers/command-handler.js +0 -23
- package/dist/src/handlers/index.d.ts +0 -6
- package/dist/src/handlers/index.js +0 -23
- package/dist/src/handlers/knowledge-handler.d.ts +0 -2
- package/dist/src/handlers/knowledge-handler.js +0 -56
- package/dist/src/handlers/markdown-helpers.d.ts +0 -7
- package/dist/src/handlers/script-handler.d.ts +0 -2
- package/dist/src/handlers/script-handler.js +0 -78
- package/dist/src/handlers/skill-handler.d.ts +0 -2
- package/dist/src/handlers/tool-handler.d.ts +0 -2
- package/dist/src/indexer.d.ts +0 -22
- package/dist/src/init.d.ts +0 -19
- package/dist/src/init.js +0 -99
- package/dist/src/llm.d.ts +0 -15
- package/dist/src/markdown.d.ts +0 -18
- package/dist/src/metadata.d.ts +0 -41
- package/dist/src/origin-resolve.d.ts +0 -19
- package/dist/src/registry-install.d.ts +0 -11
- package/dist/src/registry-resolve.d.ts +0 -3
- package/dist/src/registry-search.d.ts +0 -27
- package/dist/src/registry-types.d.ts +0 -62
- package/dist/src/ripgrep-install.d.ts +0 -12
- package/dist/src/ripgrep-resolve.d.ts +0 -13
- package/dist/src/ripgrep.d.ts +0 -3
- package/dist/src/ripgrep.js +0 -2
- package/dist/src/stash-add.d.ts +0 -4
- package/dist/src/stash-clone.d.ts +0 -22
- package/dist/src/stash-clone.js +0 -83
- package/dist/src/stash-ref.d.ts +0 -31
- package/dist/src/stash-registry.d.ts +0 -18
- package/dist/src/stash-resolve.d.ts +0 -2
- package/dist/src/stash-search.d.ts +0 -8
- package/dist/src/stash-show.d.ts +0 -5
- package/dist/src/stash-show.js +0 -46
- package/dist/src/stash-source.d.ts +0 -24
- package/dist/src/stash-source.js +0 -81
- package/dist/src/stash-types.d.ts +0 -227
- package/dist/src/stash.d.ts +0 -16
- package/dist/src/stash.js +0 -9
- package/dist/src/tool-runner.d.ts +0 -35
- package/dist/src/walker.d.ts +0 -19
- package/src/asset-spec.ts +0 -85
- package/src/asset-type-handler.ts +0 -77
- package/src/cli.ts +0 -427
- package/src/common.ts +0 -76
- package/src/config-cli.ts +0 -499
- package/src/config.ts +0 -305
- package/src/db.ts +0 -411
- package/src/embedder.ts +0 -128
- package/src/frontmatter.ts +0 -95
- package/src/github.ts +0 -21
- package/src/handlers/agent-handler.ts +0 -32
- package/src/handlers/command-handler.ts +0 -29
- package/src/handlers/index.ts +0 -25
- package/src/handlers/knowledge-handler.ts +0 -62
- package/src/handlers/markdown-helpers.ts +0 -19
- package/src/handlers/script-handler.ts +0 -92
- package/src/handlers/skill-handler.ts +0 -37
- package/src/handlers/tool-handler.ts +0 -71
- package/src/indexer.ts +0 -392
- package/src/init.ts +0 -114
- package/src/llm.ts +0 -125
- package/src/markdown.ts +0 -106
- package/src/metadata.ts +0 -333
- package/src/origin-resolve.ts +0 -67
- package/src/registry-install.ts +0 -361
- package/src/registry-resolve.ts +0 -341
- package/src/registry-search.ts +0 -335
- package/src/registry-types.ts +0 -72
- package/src/ripgrep-install.ts +0 -200
- package/src/ripgrep-resolve.ts +0 -72
- package/src/ripgrep.ts +0 -3
- package/src/stash-add.ts +0 -63
- package/src/stash-clone.ts +0 -127
- package/src/stash-ref.ts +0 -99
- package/src/stash-registry.ts +0 -259
- package/src/stash-resolve.ts +0 -50
- package/src/stash-search.ts +0 -613
- package/src/stash-show.ts +0 -55
- package/src/stash-source.ts +0 -103
- package/src/stash-types.ts +0 -231
- package/src/stash.ts +0 -39
- package/src/tool-runner.ts +0 -142
- package/src/walker.ts +0 -53
- /package/dist/{src/handlers → handlers}/markdown-helpers.js +0 -0
- /package/dist/{src/markdown.js → markdown.js} +0 -0
- /package/dist/{src/registry-types.js → registry-types.js} +0 -0
- /package/dist/{src/stash-types.js → stash-types.js} +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { TYPE_DIRS } from "./asset-spec";
|
|
4
|
+
import { isRemoteOrigin, resolveSourcesForOrigin } from "./origin-resolve";
|
|
5
|
+
import { installRegistryRef } from "./registry-install";
|
|
6
|
+
import { makeAssetRef, parseAssetRef } from "./stash-ref";
|
|
7
|
+
import { resolveAssetPath } from "./stash-resolve";
|
|
8
|
+
import { findSourceForPath, getPrimarySource, resolveStashSources } from "./stash-source";
|
|
9
|
+
export async function agentikitClone(options) {
|
|
10
|
+
const parsed = parseAssetRef(options.sourceRef);
|
|
11
|
+
// When --dest is provided, the working stash is optional
|
|
12
|
+
let allSources;
|
|
13
|
+
try {
|
|
14
|
+
allSources = resolveStashSources();
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
if (options.dest) {
|
|
18
|
+
allSources = [];
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
throw err;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const primarySource = getPrimarySource(allSources);
|
|
25
|
+
const destRoot = options.dest ? path.resolve(options.dest) : primarySource?.path;
|
|
26
|
+
if (!destRoot) {
|
|
27
|
+
throw new Error("No working stash configured and no --dest provided. Run `akm init` or pass --dest.");
|
|
28
|
+
}
|
|
29
|
+
let searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
|
|
30
|
+
// Remote fetch fallback: if no local source matched and origin looks remote, fetch it
|
|
31
|
+
let remoteFetched;
|
|
32
|
+
if (searchSources.length === 0 && parsed.origin && isRemoteOrigin(parsed.origin, allSources)) {
|
|
33
|
+
const installResult = await installRegistryRef(parsed.origin);
|
|
34
|
+
const syntheticSource = {
|
|
35
|
+
path: installResult.stashRoot,
|
|
36
|
+
registryId: installResult.id,
|
|
37
|
+
};
|
|
38
|
+
searchSources = [syntheticSource];
|
|
39
|
+
allSources = [...allSources, syntheticSource];
|
|
40
|
+
remoteFetched = {
|
|
41
|
+
origin: parsed.origin,
|
|
42
|
+
stashRoot: installResult.stashRoot,
|
|
43
|
+
cacheDir: installResult.cacheDir,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
let sourcePath;
|
|
47
|
+
let lastError;
|
|
48
|
+
for (const source of searchSources) {
|
|
49
|
+
try {
|
|
50
|
+
sourcePath = resolveAssetPath(source.path, parsed.type, parsed.name);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!sourcePath) {
|
|
58
|
+
const context = remoteFetched ? ` (remote package fetched but asset not found inside it)` : "";
|
|
59
|
+
throw lastError ?? new Error(`Source asset not found for ref: ${options.sourceRef}${context}`);
|
|
60
|
+
}
|
|
61
|
+
const sourceSource = findSourceForPath(sourcePath, allSources);
|
|
62
|
+
const destName = options.newName ?? parsed.name;
|
|
63
|
+
const typeDir = TYPE_DIRS[parsed.type];
|
|
64
|
+
const destLabel = options.dest ? "at destination" : "in working stash";
|
|
65
|
+
// Guard against self-clone
|
|
66
|
+
if (parsed.type === "skill") {
|
|
67
|
+
const sourceSkillDir = path.resolve(path.dirname(sourcePath));
|
|
68
|
+
const destSkillDir = path.resolve(path.join(destRoot, typeDir, destName));
|
|
69
|
+
if (sourceSkillDir === destSkillDir) {
|
|
70
|
+
throw new Error(`Source and destination are the same path. Use --name to provide a new name for the clone.`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const resolvedSource = path.resolve(sourcePath);
|
|
75
|
+
const resolvedDest = path.resolve(path.join(destRoot, typeDir, destName));
|
|
76
|
+
if (resolvedSource === resolvedDest) {
|
|
77
|
+
throw new Error(`Source and destination are the same path. Use --name to provide a new name for the clone.`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
let destPath;
|
|
81
|
+
if (parsed.type === "skill") {
|
|
82
|
+
const sourceSkillDir = path.dirname(sourcePath);
|
|
83
|
+
const destSkillDir = path.join(destRoot, typeDir, destName);
|
|
84
|
+
const overwritten = fs.existsSync(destSkillDir);
|
|
85
|
+
if (overwritten && !options.force) {
|
|
86
|
+
throw new Error(`Asset already exists ${destLabel}: ${destSkillDir}. Use --force to overwrite.`);
|
|
87
|
+
}
|
|
88
|
+
if (overwritten) {
|
|
89
|
+
fs.rmSync(destSkillDir, { recursive: true, force: true });
|
|
90
|
+
}
|
|
91
|
+
fs.cpSync(sourceSkillDir, destSkillDir, { recursive: true });
|
|
92
|
+
destPath = path.join(destSkillDir, "SKILL.md");
|
|
93
|
+
const ref = makeAssetRef(parsed.type, destName, "local");
|
|
94
|
+
return {
|
|
95
|
+
source: { path: sourcePath, registryId: sourceSource?.registryId },
|
|
96
|
+
destination: { path: destPath, ref },
|
|
97
|
+
overwritten,
|
|
98
|
+
...(remoteFetched ? { remoteFetched } : {}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
destPath = path.join(destRoot, typeDir, destName);
|
|
102
|
+
const overwritten = fs.existsSync(destPath);
|
|
103
|
+
if (overwritten && !options.force) {
|
|
104
|
+
throw new Error(`Asset already exists ${destLabel}: ${destPath}. Use --force to overwrite.`);
|
|
105
|
+
}
|
|
106
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
107
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
108
|
+
const ref = makeAssetRef(parsed.type, destName, "local");
|
|
109
|
+
return {
|
|
110
|
+
source: { path: sourcePath, registryId: sourceSource?.registryId },
|
|
111
|
+
destination: { path: destPath, ref },
|
|
112
|
+
overwritten,
|
|
113
|
+
...(remoteFetched ? { remoteFetched } : {}),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { isAssetType } from "./common";
|
|
3
|
+
import { UsageError } from "./errors";
|
|
3
4
|
// ── Construction ────────────────────────────────────────────────────────────
|
|
4
5
|
/**
|
|
5
6
|
* Build a ref string from components.
|
|
@@ -29,7 +30,7 @@ export function makeAssetRef(type, name, origin) {
|
|
|
29
30
|
export function parseAssetRef(ref) {
|
|
30
31
|
const trimmed = ref.trim();
|
|
31
32
|
if (!trimmed)
|
|
32
|
-
throw new
|
|
33
|
+
throw new UsageError("Empty ref.");
|
|
33
34
|
let origin;
|
|
34
35
|
let body = trimmed;
|
|
35
36
|
const boundary = trimmed.indexOf("//");
|
|
@@ -37,16 +38,16 @@ export function parseAssetRef(ref) {
|
|
|
37
38
|
origin = trimmed.slice(0, boundary);
|
|
38
39
|
body = trimmed.slice(boundary + 2);
|
|
39
40
|
if (!origin)
|
|
40
|
-
throw new
|
|
41
|
+
throw new UsageError("Empty origin in ref.");
|
|
41
42
|
}
|
|
42
43
|
const colon = body.indexOf(":");
|
|
43
44
|
if (colon <= 0) {
|
|
44
|
-
throw new
|
|
45
|
+
throw new UsageError(`Invalid ref "${trimmed}". Expected [origin//]type:name`);
|
|
45
46
|
}
|
|
46
47
|
const rawType = body.slice(0, colon);
|
|
47
48
|
const rawName = body.slice(colon + 1);
|
|
48
49
|
if (!isAssetType(rawType)) {
|
|
49
|
-
throw new
|
|
50
|
+
throw new UsageError(`Invalid asset type: "${rawType}".`);
|
|
50
51
|
}
|
|
51
52
|
validateName(rawName);
|
|
52
53
|
const name = normalizeName(rawName);
|
|
@@ -55,16 +56,16 @@ export function parseAssetRef(ref) {
|
|
|
55
56
|
// ── Validation ──────────────────────────────────────────────────────────────
|
|
56
57
|
function validateName(name) {
|
|
57
58
|
if (!name)
|
|
58
|
-
throw new
|
|
59
|
+
throw new UsageError("Empty asset name.");
|
|
59
60
|
if (name.includes("\0"))
|
|
60
|
-
throw new
|
|
61
|
+
throw new UsageError("Null byte in asset name.");
|
|
61
62
|
if (/^[A-Za-z]:/.test(name))
|
|
62
|
-
throw new
|
|
63
|
+
throw new UsageError("Windows drive path in asset name.");
|
|
63
64
|
const normalized = path.posix.normalize(name.replace(/\\/g, "/"));
|
|
64
65
|
if (path.posix.isAbsolute(normalized))
|
|
65
|
-
throw new
|
|
66
|
+
throw new UsageError("Absolute path in asset name.");
|
|
66
67
|
if (normalized === ".." || normalized.startsWith("../")) {
|
|
67
|
-
throw new
|
|
68
|
+
throw new UsageError("Path traversal in asset name.");
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
function normalizeName(name) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { resolveStashDir } from "./common";
|
|
3
3
|
import { loadConfig } from "./config";
|
|
4
|
+
import { NotFoundError, UsageError } from "./errors";
|
|
4
5
|
import { agentikitIndex } from "./indexer";
|
|
5
|
-
import {
|
|
6
|
+
import { removeLockEntry, upsertLockEntry } from "./lockfile";
|
|
7
|
+
import { installRegistryRef, removeInstalledRegistryEntry, upsertInstalledRegistryEntry } from "./registry-install";
|
|
6
8
|
import { parseRegistryRef } from "./registry-resolve";
|
|
7
9
|
export async function agentikitList(input) {
|
|
8
10
|
const stashDir = input?.stashDir ?? resolveStashDir();
|
|
@@ -23,12 +25,13 @@ export async function agentikitList(input) {
|
|
|
23
25
|
export async function agentikitRemove(input) {
|
|
24
26
|
const target = input.target.trim();
|
|
25
27
|
if (!target)
|
|
26
|
-
throw new
|
|
28
|
+
throw new UsageError("Target is required.");
|
|
27
29
|
const stashDir = input.stashDir ?? resolveStashDir();
|
|
28
30
|
const config = loadConfig();
|
|
29
31
|
const installed = config.registry?.installed ?? [];
|
|
30
32
|
const entry = resolveInstalledTarget(installed, target);
|
|
31
33
|
const updatedConfig = removeInstalledRegistryEntry(entry.id);
|
|
34
|
+
removeLockEntry(entry.id);
|
|
32
35
|
cleanupDirectoryBestEffort(entry.cacheDir);
|
|
33
36
|
const index = await agentikitIndex({ stashDir });
|
|
34
37
|
return {
|
|
@@ -42,7 +45,7 @@ export async function agentikitRemove(input) {
|
|
|
42
45
|
stashRoot: entry.stashRoot,
|
|
43
46
|
},
|
|
44
47
|
config: {
|
|
45
|
-
|
|
48
|
+
searchPaths: updatedConfig.searchPaths,
|
|
46
49
|
installedRegistryCount: updatedConfig.registry?.installed.length ?? 0,
|
|
47
50
|
},
|
|
48
51
|
index: {
|
|
@@ -53,56 +56,28 @@ export async function agentikitRemove(input) {
|
|
|
53
56
|
},
|
|
54
57
|
};
|
|
55
58
|
}
|
|
56
|
-
export async function
|
|
59
|
+
export async function agentikitUpdate(input) {
|
|
57
60
|
const stashDir = input?.stashDir ?? resolveStashDir();
|
|
58
61
|
const target = input?.target?.trim();
|
|
59
62
|
const all = input?.all === true;
|
|
63
|
+
const force = input?.force === true;
|
|
60
64
|
const installedEntries = loadConfig().registry?.installed ?? [];
|
|
61
65
|
const selectedEntries = selectTargets(installedEntries, target, all);
|
|
62
66
|
const processed = [];
|
|
63
67
|
for (const entry of selectedEntries) {
|
|
64
|
-
|
|
65
|
-
upsertInstalledRegistryEntry(toInstalledEntry(installed));
|
|
66
|
-
if (entry.cacheDir !== installed.cacheDir) {
|
|
68
|
+
if (force) {
|
|
67
69
|
cleanupDirectoryBestEffort(entry.cacheDir);
|
|
68
70
|
}
|
|
69
|
-
processed.push({
|
|
70
|
-
id: entry.id,
|
|
71
|
-
source: entry.source,
|
|
72
|
-
ref: entry.ref,
|
|
73
|
-
previousCacheDir: entry.cacheDir,
|
|
74
|
-
installed: toInstallStatus(installed),
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
const index = await agentikitIndex({ stashDir });
|
|
78
|
-
const config = loadConfig();
|
|
79
|
-
return {
|
|
80
|
-
stashDir,
|
|
81
|
-
target,
|
|
82
|
-
all,
|
|
83
|
-
processed,
|
|
84
|
-
config: {
|
|
85
|
-
mountedStashDirs: config.mountedStashDirs,
|
|
86
|
-
installedRegistryCount: config.registry?.installed.length ?? 0,
|
|
87
|
-
},
|
|
88
|
-
index: {
|
|
89
|
-
mode: index.mode,
|
|
90
|
-
totalEntries: index.totalEntries,
|
|
91
|
-
directoriesScanned: index.directoriesScanned,
|
|
92
|
-
directoriesSkipped: index.directoriesSkipped,
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
export async function agentikitUpdate(input) {
|
|
97
|
-
const stashDir = input?.stashDir ?? resolveStashDir();
|
|
98
|
-
const target = input?.target?.trim();
|
|
99
|
-
const all = input?.all === true;
|
|
100
|
-
const installedEntries = loadConfig().registry?.installed ?? [];
|
|
101
|
-
const selectedEntries = selectTargets(installedEntries, target, all);
|
|
102
|
-
const processed = [];
|
|
103
|
-
for (const entry of selectedEntries) {
|
|
104
71
|
const installed = await installRegistryRef(entry.ref);
|
|
105
72
|
upsertInstalledRegistryEntry(toInstalledEntry(installed));
|
|
73
|
+
upsertLockEntry({
|
|
74
|
+
id: installed.id,
|
|
75
|
+
source: installed.source,
|
|
76
|
+
ref: installed.ref,
|
|
77
|
+
resolvedVersion: installed.resolvedVersion,
|
|
78
|
+
resolvedRevision: installed.resolvedRevision,
|
|
79
|
+
integrity: installed.integrity ?? (installed.source === "local" ? "local" : undefined),
|
|
80
|
+
});
|
|
106
81
|
if (entry.cacheDir !== installed.cacheDir) {
|
|
107
82
|
cleanupDirectoryBestEffort(entry.cacheDir);
|
|
108
83
|
}
|
|
@@ -133,7 +108,7 @@ export async function agentikitUpdate(input) {
|
|
|
133
108
|
all,
|
|
134
109
|
processed,
|
|
135
110
|
config: {
|
|
136
|
-
|
|
111
|
+
searchPaths: config.searchPaths,
|
|
137
112
|
installedRegistryCount: config.registry?.installed.length ?? 0,
|
|
138
113
|
},
|
|
139
114
|
index: {
|
|
@@ -146,12 +121,12 @@ export async function agentikitUpdate(input) {
|
|
|
146
121
|
}
|
|
147
122
|
function selectTargets(installed, target, all) {
|
|
148
123
|
if (all && target) {
|
|
149
|
-
throw new
|
|
124
|
+
throw new UsageError("Specify either <target> or --all, not both.");
|
|
150
125
|
}
|
|
151
126
|
if (all)
|
|
152
127
|
return installed;
|
|
153
128
|
if (!target) {
|
|
154
|
-
throw new
|
|
129
|
+
throw new UsageError("Either <target> or --all is required.");
|
|
155
130
|
}
|
|
156
131
|
return [resolveInstalledTarget(installed, target)];
|
|
157
132
|
}
|
|
@@ -174,7 +149,7 @@ function resolveInstalledTarget(installed, target) {
|
|
|
174
149
|
if (byParsedId)
|
|
175
150
|
return byParsedId;
|
|
176
151
|
}
|
|
177
|
-
throw new
|
|
152
|
+
throw new NotFoundError(`No installed registry entry matched target: ${target}`);
|
|
178
153
|
}
|
|
179
154
|
function toInstalledEntry(status) {
|
|
180
155
|
return {
|
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { isRelevantAssetFile, resolveAssetPathFromName, TYPE_DIRS } from "./asset-spec";
|
|
3
4
|
import { hasErrnoCode, isWithin } from "./common";
|
|
4
|
-
import {
|
|
5
|
+
import { NotFoundError, UsageError } from "./errors";
|
|
5
6
|
export function resolveAssetPath(stashDir, type, name) {
|
|
6
7
|
const root = path.join(stashDir, TYPE_DIRS[type]);
|
|
7
8
|
const target = resolveAssetPathFromName(type, root, name);
|
|
8
9
|
const resolvedRoot = resolveAndValidateTypeRoot(root, type, name);
|
|
9
10
|
const resolvedTarget = path.resolve(target);
|
|
10
11
|
if (!isWithin(resolvedTarget, resolvedRoot)) {
|
|
11
|
-
throw new
|
|
12
|
+
throw new UsageError("Ref resolves outside the stash root.");
|
|
12
13
|
}
|
|
13
14
|
if (!fs.existsSync(resolvedTarget) || !fs.statSync(resolvedTarget).isFile()) {
|
|
14
|
-
throw new
|
|
15
|
+
throw new NotFoundError(`Stash asset not found for ref: ${type}:${name}`);
|
|
15
16
|
}
|
|
16
17
|
const realTarget = fs.realpathSync(resolvedTarget);
|
|
17
18
|
if (!isWithin(realTarget, resolvedRoot)) {
|
|
18
|
-
throw new
|
|
19
|
+
throw new UsageError("Ref resolves outside the stash root.");
|
|
19
20
|
}
|
|
20
21
|
if (!isRelevantAssetFile(type, path.basename(resolvedTarget))) {
|
|
21
22
|
if (type === "tool") {
|
|
22
|
-
throw new
|
|
23
|
+
throw new NotFoundError("Tool ref must resolve to a .sh, .ts, .js, .ps1, .cmd, or .bat file.");
|
|
23
24
|
}
|
|
24
25
|
if (type === "script") {
|
|
25
|
-
throw new
|
|
26
|
+
throw new NotFoundError("Script ref must resolve to a file with a supported script extension. Refer to the Agentikit documentation for the complete list of supported script extensions.");
|
|
26
27
|
}
|
|
27
|
-
throw new
|
|
28
|
+
throw new NotFoundError(`Stash asset not found for ref: ${type}:${name}`);
|
|
28
29
|
}
|
|
29
30
|
return realTarget;
|
|
30
31
|
}
|
|
31
32
|
function resolveAndValidateTypeRoot(root, type, name) {
|
|
32
33
|
const rootStat = readTypeRootStat(root, type, name);
|
|
33
34
|
if (!rootStat.isDirectory()) {
|
|
34
|
-
throw new
|
|
35
|
+
throw new NotFoundError(`Stash type root is not a directory for ref: ${type}:${name}`);
|
|
35
36
|
}
|
|
36
37
|
return fs.realpathSync(root);
|
|
37
38
|
}
|
|
@@ -41,7 +42,7 @@ function readTypeRootStat(root, type, name) {
|
|
|
41
42
|
}
|
|
42
43
|
catch (error) {
|
|
43
44
|
if (hasErrnoCode(error, "ENOENT")) {
|
|
44
|
-
throw new
|
|
45
|
+
throw new NotFoundError(`Stash type root not found for ref: ${type}:${name}`);
|
|
45
46
|
}
|
|
46
47
|
throw error;
|
|
47
48
|
}
|