agentikit 0.0.9 → 0.0.12
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 +129 -214
- package/dist/index.d.ts +8 -2
- package/dist/index.js +4 -1
- package/dist/src/asset-spec.d.ts +2 -0
- package/dist/src/asset-spec.js +22 -3
- package/dist/src/asset-type-handler.d.ts +27 -0
- package/dist/src/asset-type-handler.js +33 -0
- package/dist/src/cli.js +201 -75
- package/dist/src/common.d.ts +6 -1
- package/dist/src/common.js +18 -4
- package/dist/src/config-cli.d.ts +9 -0
- package/dist/src/config-cli.js +473 -0
- package/dist/src/config.d.ts +19 -6
- package/dist/src/config.js +139 -29
- package/dist/src/db.d.ts +46 -0
- package/dist/src/db.js +299 -0
- package/dist/src/embedder.js +12 -7
- package/dist/src/github.d.ts +4 -0
- package/dist/src/github.js +19 -0
- package/dist/src/handlers/agent-handler.d.ts +2 -0
- package/dist/src/handlers/agent-handler.js +26 -0
- package/dist/src/handlers/command-handler.d.ts +2 -0
- package/dist/src/handlers/command-handler.js +23 -0
- package/dist/src/handlers/index.d.ts +6 -0
- package/dist/src/handlers/index.js +23 -0
- package/dist/src/handlers/knowledge-handler.d.ts +2 -0
- package/dist/src/handlers/knowledge-handler.js +56 -0
- package/dist/src/handlers/markdown-helpers.d.ts +7 -0
- package/dist/src/handlers/markdown-helpers.js +15 -0
- package/dist/src/handlers/script-handler.d.ts +2 -0
- package/dist/src/handlers/script-handler.js +78 -0
- package/dist/src/handlers/skill-handler.d.ts +2 -0
- package/dist/src/handlers/skill-handler.js +30 -0
- package/dist/src/handlers/tool-handler.d.ts +2 -0
- package/dist/src/handlers/tool-handler.js +58 -0
- package/dist/src/indexer.d.ts +1 -23
- package/dist/src/indexer.js +162 -155
- package/dist/src/init.d.ts +2 -2
- package/dist/src/init.js +21 -9
- package/dist/src/llm.js +4 -3
- package/dist/src/metadata.d.ts +0 -1
- package/dist/src/metadata.js +6 -64
- package/dist/src/origin-resolve.d.ts +19 -0
- package/dist/src/origin-resolve.js +53 -0
- package/dist/src/registry-install.d.ts +2 -2
- package/dist/src/registry-install.js +142 -35
- package/dist/src/registry-resolve.js +90 -22
- package/dist/src/registry-search.d.ts +22 -0
- package/dist/src/registry-search.js +231 -97
- package/dist/src/registry-types.d.ts +9 -2
- package/dist/src/stash-add.js +4 -4
- package/dist/src/stash-clone.d.ts +22 -0
- package/dist/src/stash-clone.js +83 -0
- package/dist/src/stash-ref.d.ts +27 -3
- package/dist/src/stash-ref.js +63 -24
- package/dist/src/stash-registry.js +12 -12
- package/dist/src/stash-resolve.js +3 -0
- package/dist/src/stash-search.js +168 -164
- package/dist/src/stash-show.d.ts +1 -1
- package/dist/src/stash-show.js +28 -96
- package/dist/src/stash-source.d.ts +24 -0
- package/dist/src/stash-source.js +81 -0
- package/dist/src/stash-types.d.ts +14 -4
- package/dist/src/stash.d.ts +6 -0
- package/dist/src/stash.js +3 -0
- package/dist/src/tool-runner.d.ts +1 -1
- package/dist/src/tool-runner.js +18 -5
- package/package.json +7 -2
- package/src/asset-spec.ts +20 -4
- package/src/asset-type-handler.ts +77 -0
- package/src/cli.ts +213 -82
- package/src/common.ts +23 -5
- package/src/config-cli.ts +499 -0
- package/src/config.ts +160 -38
- package/src/db.ts +411 -0
- package/src/embedder.ts +22 -11
- package/src/github.ts +21 -0
- package/src/handlers/agent-handler.ts +32 -0
- package/src/handlers/command-handler.ts +29 -0
- package/src/handlers/index.ts +25 -0
- package/src/handlers/knowledge-handler.ts +62 -0
- package/src/handlers/markdown-helpers.ts +19 -0
- package/src/handlers/script-handler.ts +92 -0
- package/src/handlers/skill-handler.ts +37 -0
- package/src/handlers/tool-handler.ts +71 -0
- package/src/indexer.ts +208 -187
- package/src/init.ts +17 -9
- package/src/llm.ts +4 -3
- package/src/metadata.ts +5 -65
- package/src/origin-resolve.ts +67 -0
- package/src/registry-install.ts +158 -42
- package/src/registry-resolve.ts +92 -23
- package/src/registry-search.ts +288 -98
- package/src/registry-types.ts +10 -2
- package/src/stash-add.ts +14 -17
- package/src/stash-clone.ts +127 -0
- package/src/stash-ref.ts +84 -26
- package/src/stash-registry.ts +12 -12
- package/src/stash-resolve.ts +3 -0
- package/src/stash-search.ts +202 -184
- package/src/stash-show.ts +33 -90
- package/src/stash-source.ts +103 -0
- package/src/stash-types.ts +14 -4
- package/src/stash.ts +8 -0
- package/src/tool-runner.ts +18 -5
- package/dist/src/similarity.d.ts +0 -34
- package/src/similarity.ts +0 -271
package/src/cli.ts
CHANGED
|
@@ -13,14 +13,25 @@ import {
|
|
|
13
13
|
import type { SearchSource, SearchUsageMode } from "./stash-types"
|
|
14
14
|
import { agentikitInit } from "./init"
|
|
15
15
|
import { agentikitIndex } from "./indexer"
|
|
16
|
-
import {
|
|
17
|
-
|
|
16
|
+
import { agentikitClone } from "./stash-clone"
|
|
17
|
+
|
|
18
|
+
import { resolveStashSources } from "./stash-source"
|
|
19
|
+
import { loadConfig, saveConfig } from "./config"
|
|
20
|
+
import {
|
|
21
|
+
getConfigValue,
|
|
22
|
+
listConfig,
|
|
23
|
+
listProviders,
|
|
24
|
+
parseConfigValue,
|
|
25
|
+
setConfigValue,
|
|
26
|
+
unsetConfigValue,
|
|
27
|
+
useProvider,
|
|
28
|
+
} from "./config-cli"
|
|
18
29
|
|
|
19
30
|
const initCommand = defineCommand({
|
|
20
|
-
meta: { name: "init", description: "Initialize
|
|
21
|
-
run() {
|
|
22
|
-
|
|
23
|
-
const result = agentikitInit()
|
|
31
|
+
meta: { name: "init", description: "Initialize Agent-i-Kit's working stash directory and set AKM_STASH_DIR" },
|
|
32
|
+
async run() {
|
|
33
|
+
await runWithJsonErrors(async () => {
|
|
34
|
+
const result = await agentikitInit()
|
|
24
35
|
console.log(JSON.stringify(result, null, 2))
|
|
25
36
|
})
|
|
26
37
|
},
|
|
@@ -43,14 +54,14 @@ const searchCommand = defineCommand({
|
|
|
43
54
|
meta: { name: "search", description: "Search the stash" },
|
|
44
55
|
args: {
|
|
45
56
|
query: { type: "positional", description: "Search query", required: false, default: "" },
|
|
46
|
-
type: { type: "string", description: "Asset type filter (tool|skill|command|agent|knowledge|any)" },
|
|
57
|
+
type: { type: "string", description: "Asset type filter (tool|skill|command|agent|knowledge|script|any)" },
|
|
47
58
|
limit: { type: "string", description: "Maximum number of results" },
|
|
48
59
|
usage: { type: "string", description: "Usage metadata mode (none|both|item|guide)", default: "both" },
|
|
49
60
|
source: { type: "string", description: "Search source (local|registry|both)", default: "local" },
|
|
50
61
|
},
|
|
51
62
|
async run({ args }) {
|
|
52
63
|
await runWithJsonErrors(async () => {
|
|
53
|
-
const type = args.type as "tool" | "skill" | "command" | "agent" | "knowledge" | "any" | undefined
|
|
64
|
+
const type = args.type as "tool" | "skill" | "command" | "agent" | "knowledge" | "script" | "any" | undefined
|
|
54
65
|
const limit = args.limit ? parseInt(args.limit, 10) : undefined
|
|
55
66
|
const usage = parseSearchUsageMode(args.usage)
|
|
56
67
|
const source = parseSearchSource(args.source)
|
|
@@ -60,9 +71,13 @@ const searchCommand = defineCommand({
|
|
|
60
71
|
})
|
|
61
72
|
|
|
62
73
|
const addCommand = defineCommand({
|
|
63
|
-
meta: { name: "add", description: "Install a registry package into the stash" },
|
|
74
|
+
meta: { name: "add", description: "Install a registry package or local git directory into the stash" },
|
|
64
75
|
args: {
|
|
65
|
-
ref: {
|
|
76
|
+
ref: {
|
|
77
|
+
type: "positional",
|
|
78
|
+
description: "Registry ref (npm package, owner/repo, github URL, or local git directory)",
|
|
79
|
+
required: true,
|
|
80
|
+
},
|
|
66
81
|
},
|
|
67
82
|
async run({ args }) {
|
|
68
83
|
await runWithJsonErrors(async () => {
|
|
@@ -127,8 +142,8 @@ const showCommand = defineCommand({
|
|
|
127
142
|
start: { type: "string", description: "Start line (for --view lines)" },
|
|
128
143
|
end: { type: "string", description: "End line (for --view lines)" },
|
|
129
144
|
},
|
|
130
|
-
run({ args }) {
|
|
131
|
-
|
|
145
|
+
async run({ args }) {
|
|
146
|
+
await runWithJsonErrors(async () => {
|
|
132
147
|
let view: KnowledgeView | undefined
|
|
133
148
|
if (args.view) {
|
|
134
149
|
switch (args.view) {
|
|
@@ -151,20 +166,111 @@ const showCommand = defineCommand({
|
|
|
151
166
|
throw new Error(`Unknown view mode: ${args.view}. Expected one of: full|toc|frontmatter|section|lines`)
|
|
152
167
|
}
|
|
153
168
|
}
|
|
154
|
-
console.log(JSON.stringify(agentikitShow({ ref: args.ref, view }), null, 2))
|
|
169
|
+
console.log(JSON.stringify(await agentikitShow({ ref: args.ref, view }), null, 2))
|
|
155
170
|
})
|
|
156
171
|
},
|
|
157
172
|
})
|
|
158
173
|
|
|
159
174
|
const configCommand = defineCommand({
|
|
160
|
-
meta: { name: "config", description: "Show
|
|
175
|
+
meta: { name: "config", description: "Show configuration, get/set keys, and manage embedding/LLM providers" },
|
|
161
176
|
args: {
|
|
162
|
-
|
|
177
|
+
list: { type: "boolean", description: "List current configuration with effective defaults", default: false },
|
|
178
|
+
get: { type: "string", description: "Get a configuration value by key" },
|
|
179
|
+
unset: { type: "string", description: "Unset an optional configuration key or whole embedding/llm section" },
|
|
180
|
+
set: { type: "string", description: "Back-compat alias for updating a key (key=value format)" },
|
|
181
|
+
},
|
|
182
|
+
subCommands: {
|
|
183
|
+
list: defineCommand({
|
|
184
|
+
meta: { name: "list", description: "List current configuration with effective embedding/LLM settings" },
|
|
185
|
+
run() {
|
|
186
|
+
return runWithJsonErrors(() => {
|
|
187
|
+
console.log(JSON.stringify(listConfig(loadConfig()), null, 2))
|
|
188
|
+
})
|
|
189
|
+
},
|
|
190
|
+
}),
|
|
191
|
+
get: defineCommand({
|
|
192
|
+
meta: { name: "get", description: "Get a configuration value by key" },
|
|
193
|
+
args: {
|
|
194
|
+
key: { type: "positional", required: true, description: "Config key (for example: embedding.provider)" },
|
|
195
|
+
},
|
|
196
|
+
run({ args }) {
|
|
197
|
+
return runWithJsonErrors(() => {
|
|
198
|
+
console.log(JSON.stringify(getConfigValue(loadConfig(), args.key), null, 2))
|
|
199
|
+
})
|
|
200
|
+
},
|
|
201
|
+
}),
|
|
202
|
+
set: defineCommand({
|
|
203
|
+
meta: { name: "set", description: "Set a configuration value by key" },
|
|
204
|
+
args: {
|
|
205
|
+
key: { type: "positional", required: true, description: "Config key (for example: llm.temperature)" },
|
|
206
|
+
value: { type: "positional", required: true, description: "Config value" },
|
|
207
|
+
},
|
|
208
|
+
run({ args }) {
|
|
209
|
+
return runWithJsonErrors(() => {
|
|
210
|
+
const updated = setConfigValue(loadConfig(), args.key, args.value)
|
|
211
|
+
saveConfig(updated)
|
|
212
|
+
console.log(JSON.stringify(listConfig(updated), null, 2))
|
|
213
|
+
})
|
|
214
|
+
},
|
|
215
|
+
}),
|
|
216
|
+
unset: defineCommand({
|
|
217
|
+
meta: { name: "unset", description: "Unset an optional configuration key or whole embedding/llm section" },
|
|
218
|
+
args: {
|
|
219
|
+
key: { type: "positional", required: true, description: "Config key to unset" },
|
|
220
|
+
},
|
|
221
|
+
run({ args }) {
|
|
222
|
+
return runWithJsonErrors(() => {
|
|
223
|
+
const updated = unsetConfigValue(loadConfig(), args.key)
|
|
224
|
+
saveConfig(updated)
|
|
225
|
+
console.log(JSON.stringify(listConfig(updated), null, 2))
|
|
226
|
+
})
|
|
227
|
+
},
|
|
228
|
+
}),
|
|
229
|
+
providers: defineCommand({
|
|
230
|
+
meta: { name: "providers", description: "List available embedding or LLM providers" },
|
|
231
|
+
args: {
|
|
232
|
+
scope: { type: "positional", required: true, description: "Provider scope: embedding or llm" },
|
|
233
|
+
},
|
|
234
|
+
run({ args }) {
|
|
235
|
+
return runWithJsonErrors(() => {
|
|
236
|
+
const scope = parseProviderScope(args.scope)
|
|
237
|
+
console.log(JSON.stringify(listProviders(scope, loadConfig()), null, 2))
|
|
238
|
+
})
|
|
239
|
+
},
|
|
240
|
+
}),
|
|
241
|
+
use: defineCommand({
|
|
242
|
+
meta: { name: "use", description: "Switch the default embedding or LLM provider" },
|
|
243
|
+
args: {
|
|
244
|
+
scope: { type: "positional", required: true, description: "Provider scope: embedding or llm" },
|
|
245
|
+
provider: { type: "positional", required: true, description: "Provider name" },
|
|
246
|
+
},
|
|
247
|
+
run({ args }) {
|
|
248
|
+
return runWithJsonErrors(() => {
|
|
249
|
+
const scope = parseProviderScope(args.scope)
|
|
250
|
+
const updated = useProvider(loadConfig(), scope, args.provider)
|
|
251
|
+
saveConfig(updated)
|
|
252
|
+
console.log(JSON.stringify(listConfig(updated), null, 2))
|
|
253
|
+
})
|
|
254
|
+
},
|
|
255
|
+
}),
|
|
163
256
|
},
|
|
164
257
|
run({ args }) {
|
|
165
258
|
return runWithJsonErrors(() => {
|
|
166
|
-
|
|
167
|
-
|
|
259
|
+
if (hasConfigSubcommand(args)) return
|
|
260
|
+
if (args.list) {
|
|
261
|
+
console.log(JSON.stringify(listConfig(loadConfig()), null, 2))
|
|
262
|
+
return
|
|
263
|
+
}
|
|
264
|
+
if (args.get) {
|
|
265
|
+
console.log(JSON.stringify(getConfigValue(loadConfig(), args.get), null, 2))
|
|
266
|
+
return
|
|
267
|
+
}
|
|
268
|
+
if (args.unset) {
|
|
269
|
+
const updated = unsetConfigValue(loadConfig(), args.unset)
|
|
270
|
+
saveConfig(updated)
|
|
271
|
+
console.log(JSON.stringify(listConfig(updated), null, 2))
|
|
272
|
+
return
|
|
273
|
+
}
|
|
168
274
|
if (args.set) {
|
|
169
275
|
const eqIndex = args.set.indexOf("=")
|
|
170
276
|
if (eqIndex === -1) {
|
|
@@ -173,20 +279,50 @@ const configCommand = defineCommand({
|
|
|
173
279
|
const key = args.set.slice(0, eqIndex)
|
|
174
280
|
const value = args.set.slice(eqIndex + 1)
|
|
175
281
|
const partial = parseConfigValue(key, value)
|
|
176
|
-
const config =
|
|
177
|
-
|
|
282
|
+
const config = { ...loadConfig(), ...partial }
|
|
283
|
+
saveConfig(config)
|
|
284
|
+
console.log(JSON.stringify(listConfig(config), null, 2))
|
|
178
285
|
} else {
|
|
179
|
-
|
|
180
|
-
console.log(JSON.stringify(config, null, 2))
|
|
286
|
+
console.log(JSON.stringify(listConfig(loadConfig()), null, 2))
|
|
181
287
|
}
|
|
182
288
|
})
|
|
183
289
|
},
|
|
184
290
|
})
|
|
185
291
|
|
|
292
|
+
const cloneCommand = defineCommand({
|
|
293
|
+
meta: { name: "clone", description: "Clone an asset from any stash source into the working stash" },
|
|
294
|
+
args: {
|
|
295
|
+
ref: { type: "positional", description: "Asset ref (e.g. @installed:pkg/tool:script.sh)", required: true },
|
|
296
|
+
name: { type: "string", description: "New name for the cloned asset" },
|
|
297
|
+
force: { type: "boolean", description: "Overwrite if asset already exists in working stash", default: false },
|
|
298
|
+
},
|
|
299
|
+
async run({ args }) {
|
|
300
|
+
await runWithJsonErrors(async () => {
|
|
301
|
+
const result = await agentikitClone({
|
|
302
|
+
sourceRef: args.ref,
|
|
303
|
+
newName: args.name,
|
|
304
|
+
force: args.force,
|
|
305
|
+
})
|
|
306
|
+
console.log(JSON.stringify(result, null, 2))
|
|
307
|
+
})
|
|
308
|
+
},
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
const sourcesCommand = defineCommand({
|
|
313
|
+
meta: { name: "sources", description: "List all stash sources with their kind, path, and status" },
|
|
314
|
+
run() {
|
|
315
|
+
return runWithJsonErrors(() => {
|
|
316
|
+
const sources = resolveStashSources()
|
|
317
|
+
console.log(JSON.stringify({ sources }, null, 2))
|
|
318
|
+
})
|
|
319
|
+
},
|
|
320
|
+
})
|
|
321
|
+
|
|
186
322
|
const main = defineCommand({
|
|
187
323
|
meta: {
|
|
188
324
|
name: "akm",
|
|
189
|
-
description: "CLI tool to search, open, and
|
|
325
|
+
description: "CLI tool to search, open, and manage assets from Agent-i-Kit stash.",
|
|
190
326
|
},
|
|
191
327
|
subCommands: {
|
|
192
328
|
init: initCommand,
|
|
@@ -198,14 +334,20 @@ const main = defineCommand({
|
|
|
198
334
|
reinstall: reinstallCommand,
|
|
199
335
|
search: searchCommand,
|
|
200
336
|
show: showCommand,
|
|
337
|
+
clone: cloneCommand,
|
|
338
|
+
sources: sourcesCommand,
|
|
201
339
|
config: configCommand,
|
|
202
340
|
},
|
|
203
341
|
})
|
|
204
342
|
|
|
205
|
-
runMain(main)
|
|
206
|
-
|
|
207
343
|
const SEARCH_USAGE_MODES: SearchUsageMode[] = ["none", "both", "item", "guide"]
|
|
208
344
|
const SEARCH_SOURCES: SearchSource[] = ["local", "registry", "both"]
|
|
345
|
+
const CONFIG_SUBCOMMAND_SET = new Set(["list", "get", "set", "unset", "providers", "use"])
|
|
346
|
+
|
|
347
|
+
// Note: citty reads process.argv directly, so we must normalize it in-place.
|
|
348
|
+
// This is done once at startup before runMain.
|
|
349
|
+
normalizeConfigArgv(process.argv)
|
|
350
|
+
runMain(main)
|
|
209
351
|
|
|
210
352
|
function parseSearchUsageMode(value: string): SearchUsageMode {
|
|
211
353
|
if ((SEARCH_USAGE_MODES as string[]).includes(value)) return value as SearchUsageMode
|
|
@@ -217,63 +359,6 @@ function parseSearchSource(value: string): SearchSource {
|
|
|
217
359
|
throw new Error(`Invalid value for --source: ${value}. Expected one of: ${SEARCH_SOURCES.join("|")}`)
|
|
218
360
|
}
|
|
219
361
|
|
|
220
|
-
function parseConnectionValue(
|
|
221
|
-
key: string,
|
|
222
|
-
value: string,
|
|
223
|
-
exampleEndpoint: string,
|
|
224
|
-
exampleModel: string,
|
|
225
|
-
): { endpoint: string; model: string; apiKey?: string } | undefined {
|
|
226
|
-
if (value === "null" || value === "") return undefined
|
|
227
|
-
let parsed: unknown
|
|
228
|
-
try {
|
|
229
|
-
parsed = JSON.parse(value)
|
|
230
|
-
} catch {
|
|
231
|
-
throw new Error(
|
|
232
|
-
`Invalid value for ${key}: expected JSON object with endpoint and model`
|
|
233
|
-
+ ` (e.g. '{"endpoint":"${exampleEndpoint}","model":"${exampleModel}"}')`,
|
|
234
|
-
)
|
|
235
|
-
}
|
|
236
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
237
|
-
throw new Error(`Invalid value for ${key}: expected a JSON object`)
|
|
238
|
-
}
|
|
239
|
-
const obj = parsed as Record<string, unknown>
|
|
240
|
-
if (typeof obj.endpoint !== "string" || !obj.endpoint || typeof obj.model !== "string" || !obj.model) {
|
|
241
|
-
throw new Error(`Invalid value for ${key}: "endpoint" and "model" are required string fields`)
|
|
242
|
-
}
|
|
243
|
-
const result: { endpoint: string; model: string; apiKey?: string } = {
|
|
244
|
-
endpoint: obj.endpoint,
|
|
245
|
-
model: obj.model,
|
|
246
|
-
}
|
|
247
|
-
if (typeof obj.apiKey === "string" && obj.apiKey) {
|
|
248
|
-
result.apiKey = obj.apiKey
|
|
249
|
-
}
|
|
250
|
-
return result
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function parseConfigValue(key: string, value: string): Partial<AgentikitConfig> {
|
|
254
|
-
switch (key) {
|
|
255
|
-
case "semanticSearch":
|
|
256
|
-
if (value !== "true" && value !== "false") {
|
|
257
|
-
throw new Error(`Invalid value for semanticSearch: expected "true" or "false"`)
|
|
258
|
-
}
|
|
259
|
-
return { semanticSearch: value === "true" }
|
|
260
|
-
case "additionalStashDirs":
|
|
261
|
-
try {
|
|
262
|
-
const parsed = JSON.parse(value)
|
|
263
|
-
if (!Array.isArray(parsed)) throw new Error("expected JSON array")
|
|
264
|
-
return { additionalStashDirs: parsed.filter((d: unknown): d is string => typeof d === "string") }
|
|
265
|
-
} catch {
|
|
266
|
-
throw new Error(`Invalid value for additionalStashDirs: expected JSON array (e.g. '["/path/a","/path/b"]')`)
|
|
267
|
-
}
|
|
268
|
-
case "embedding":
|
|
269
|
-
return { embedding: parseConnectionValue("embedding", value, "http://localhost:11434/v1/embeddings", "nomic-embed-text") }
|
|
270
|
-
case "llm":
|
|
271
|
-
return { llm: parseConnectionValue("llm", value, "http://localhost:11434/v1/chat/completions", "llama3.2") }
|
|
272
|
-
default:
|
|
273
|
-
throw new Error(`Unknown config key: ${key}`)
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
362
|
async function runWithJsonErrors(fn: (() => void) | (() => Promise<void>)): Promise<void> {
|
|
278
363
|
try {
|
|
279
364
|
await fn()
|
|
@@ -286,11 +371,57 @@ async function runWithJsonErrors(fn: (() => void) | (() => Promise<void>)): Prom
|
|
|
286
371
|
}
|
|
287
372
|
|
|
288
373
|
function buildHint(message: string): string | undefined {
|
|
289
|
-
if (message.includes("
|
|
374
|
+
if (message.includes("AKM_STASH_DIR")) return "Run `akm init` or set AKM_STASH_DIR to a valid directory."
|
|
290
375
|
if (message.includes("Either <target> or --all is required")) return "Use `akm update --all` or pass a target like `akm update npm:@scope/pkg`."
|
|
291
376
|
if (message.includes("Specify either <target> or --all")) return "Use only one: a positional target or `--all`."
|
|
292
377
|
if (message.includes("No installed registry entry matched target")) return "Run `akm list` to view installed ids/refs, then retry with one of those values."
|
|
293
378
|
if (message.includes("Invalid value for --source")) return "Pick one of: local, registry, both."
|
|
294
379
|
if (message.includes("Invalid value for --usage")) return "Pick one of: none, both, item, guide."
|
|
380
|
+
if (message.includes("expected JSON object with endpoint and model")) {
|
|
381
|
+
return "Quote JSON values in your shell, for example: akm config set embedding '{\"endpoint\":\"http://localhost:11434/v1/embeddings\",\"model\":\"nomic-embed-text\"}'."
|
|
382
|
+
}
|
|
295
383
|
return undefined
|
|
296
384
|
}
|
|
385
|
+
|
|
386
|
+
function parseProviderScope(value: string): "embedding" | "llm" {
|
|
387
|
+
if (value === "embedding" || value === "llm") return value
|
|
388
|
+
throw new Error(`Invalid provider scope: ${value}. Expected one of: embedding|llm`)
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function hasConfigSubcommand(args: Record<string, unknown>): boolean {
|
|
392
|
+
const command = Array.isArray(args._) ? args._[0] : undefined
|
|
393
|
+
return typeof command === "string" && CONFIG_SUBCOMMAND_SET.has(command)
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Mutate argv before citty parses it so git-style config forms like
|
|
398
|
+
* `akm config llm.maxTokens 512` and `akm config --get llm.maxTokens`
|
|
399
|
+
* are normalized into the existing config subcommands.
|
|
400
|
+
*/
|
|
401
|
+
function normalizeConfigArgv(argv: string[]): void {
|
|
402
|
+
const [, , command, argAfterCommand, argAfterKey, ...rest] = argv
|
|
403
|
+
if (command !== "config") return
|
|
404
|
+
if (!argAfterCommand) return
|
|
405
|
+
if (argAfterCommand === "--list") {
|
|
406
|
+
argv.splice(3, argv.length - 3, "list")
|
|
407
|
+
return
|
|
408
|
+
}
|
|
409
|
+
if (argAfterCommand === "--get" && argAfterKey) {
|
|
410
|
+
argv.splice(3, argv.length - 3, "get", argAfterKey, ...rest)
|
|
411
|
+
return
|
|
412
|
+
}
|
|
413
|
+
if (argAfterCommand === "--unset" && argAfterKey) {
|
|
414
|
+
argv.splice(3, argv.length - 3, "unset", argAfterKey, ...rest)
|
|
415
|
+
return
|
|
416
|
+
}
|
|
417
|
+
if (argAfterCommand.startsWith("-")) return
|
|
418
|
+
if (CONFIG_SUBCOMMAND_SET.has(argAfterCommand)) return
|
|
419
|
+
|
|
420
|
+
// A single arg after `config` behaves like `git config <key>` and reads the value.
|
|
421
|
+
if (argAfterKey === undefined) {
|
|
422
|
+
argv.splice(3, argv.length - 3, "get", argAfterCommand)
|
|
423
|
+
return
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
argv.splice(3, argv.length - 3, "set", argAfterCommand, argAfterKey, ...rest)
|
|
427
|
+
}
|
package/src/common.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { TYPE_DIRS } from "./asset-spec"
|
|
|
4
4
|
|
|
5
5
|
// ── Types ───────────────────────────────────────────────────────────────────
|
|
6
6
|
|
|
7
|
-
export type AgentikitAssetType = "tool" | "skill" | "command" | "agent" | "knowledge"
|
|
7
|
+
export type AgentikitAssetType = "tool" | "skill" | "command" | "agent" | "knowledge" | "script"
|
|
8
8
|
|
|
9
9
|
// ── Constants ───────────────────────────────────────────────────────────────
|
|
10
10
|
|
|
@@ -20,19 +20,19 @@ export function isAssetType(type: string): type is AgentikitAssetType {
|
|
|
20
20
|
// ── Utilities ───────────────────────────────────────────────────────────────
|
|
21
21
|
|
|
22
22
|
export function resolveStashDir(): string {
|
|
23
|
-
const raw = process.env.
|
|
23
|
+
const raw = process.env.AKM_STASH_DIR?.trim()
|
|
24
24
|
if (!raw) {
|
|
25
|
-
throw new Error("
|
|
25
|
+
throw new Error("AKM_STASH_DIR is not set. Set it to your Agentikit stash path.")
|
|
26
26
|
}
|
|
27
27
|
const stashDir = path.resolve(raw)
|
|
28
28
|
let stat: fs.Stats
|
|
29
29
|
try {
|
|
30
30
|
stat = fs.statSync(stashDir)
|
|
31
31
|
} catch {
|
|
32
|
-
throw new Error(`Unable to read
|
|
32
|
+
throw new Error(`Unable to read AKM_STASH_DIR at "${stashDir}".`)
|
|
33
33
|
}
|
|
34
34
|
if (!stat.isDirectory()) {
|
|
35
|
-
throw new Error(`
|
|
35
|
+
throw new Error(`AKM_STASH_DIR must point to a directory: "${stashDir}".`)
|
|
36
36
|
}
|
|
37
37
|
return stashDir
|
|
38
38
|
}
|
|
@@ -56,3 +56,21 @@ export function isWithin(candidate: string, root: string): boolean {
|
|
|
56
56
|
function normalizeFsPathForComparison(value: string): string {
|
|
57
57
|
return process.platform === "win32" ? value.toLowerCase() : value
|
|
58
58
|
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Fetch with an AbortController timeout.
|
|
62
|
+
* Defaults to 30 seconds if no timeout is specified.
|
|
63
|
+
*/
|
|
64
|
+
export async function fetchWithTimeout(
|
|
65
|
+
url: string,
|
|
66
|
+
opts?: RequestInit,
|
|
67
|
+
timeoutMs = 30_000,
|
|
68
|
+
): Promise<Response> {
|
|
69
|
+
const controller = new AbortController()
|
|
70
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs)
|
|
71
|
+
try {
|
|
72
|
+
return await fetch(url, { ...opts, signal: controller.signal })
|
|
73
|
+
} finally {
|
|
74
|
+
clearTimeout(timer)
|
|
75
|
+
}
|
|
76
|
+
}
|