agentikit 0.0.8 → 0.0.9

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.
Files changed (40) hide show
  1. package/README.md +110 -7
  2. package/dist/index.d.ts +7 -3
  3. package/dist/index.js +4 -1
  4. package/dist/src/cli.js +156 -47
  5. package/dist/src/config.d.ts +6 -0
  6. package/dist/src/config.js +50 -0
  7. package/dist/src/metadata.d.ts +1 -0
  8. package/dist/src/metadata.js +16 -0
  9. package/dist/src/registry-install.d.ts +11 -0
  10. package/dist/src/registry-install.js +208 -0
  11. package/dist/src/registry-resolve.d.ts +3 -0
  12. package/dist/src/registry-resolve.js +231 -0
  13. package/dist/src/registry-search.d.ts +5 -0
  14. package/dist/src/registry-search.js +129 -0
  15. package/dist/src/registry-types.d.ts +55 -0
  16. package/dist/src/registry-types.js +1 -0
  17. package/dist/src/stash-add.d.ts +4 -0
  18. package/dist/src/stash-add.js +59 -0
  19. package/dist/src/stash-registry.d.ts +18 -0
  20. package/dist/src/stash-registry.js +221 -0
  21. package/dist/src/stash-search.d.ts +3 -1
  22. package/dist/src/stash-search.js +236 -21
  23. package/dist/src/stash-show.js +10 -3
  24. package/dist/src/stash-types.d.ts +165 -1
  25. package/dist/src/stash.d.ts +3 -1
  26. package/dist/src/stash.js +2 -0
  27. package/package.json +1 -1
  28. package/src/cli.ts +166 -46
  29. package/src/config.ts +59 -0
  30. package/src/metadata.ts +16 -0
  31. package/src/registry-install.ts +245 -0
  32. package/src/registry-resolve.ts +272 -0
  33. package/src/registry-search.ts +145 -0
  34. package/src/registry-types.ts +64 -0
  35. package/src/stash-add.ts +66 -0
  36. package/src/stash-registry.ts +259 -0
  37. package/src/stash-search.ts +275 -23
  38. package/src/stash-show.ts +10 -2
  39. package/src/stash-types.ts +176 -1
  40. package/src/stash.ts +15 -0
package/README.md CHANGED
@@ -54,23 +54,109 @@ $AGENTIKIT_STASH_DIR/
54
54
  ```sh
55
55
  akm init # Initialize stash directory and set AGENTIKIT_STASH_DIR
56
56
  akm index [--full] # Build search index (incremental by default)
57
- akm search [query] # Search the stash
57
+ akm add <ref> # Install a registry kit by npm/GitHub ref
58
+ akm list # List installed registry kits from config.registry.installed
59
+ akm remove <target> # Remove installed kit by id/ref (or parsed ref id)
60
+ akm update [target] [--all] # Fresh install from current ref(s), report changed revision/version
61
+ akm reinstall [target] [--all] # Reinstall from stored refs
62
+ akm search [query] # Search local stash and/or registry
58
63
  akm show <type:name> # Read a stash asset by ref
59
64
  ```
60
65
 
66
+ ### add
67
+
68
+ Install a registry reference and make it searchable immediately.
69
+
70
+ ```sh
71
+ akm add @scope/kit
72
+ akm add npm:@scope/kit@latest
73
+ akm add owner/repo
74
+ akm add github:owner/repo#v1.2.3
75
+ ```
76
+
77
+ - Uses registry resolution + install helpers (`npm` and `github` refs)
78
+ - Updates `config.json` registry install records and syncs `additionalStashDirs`
79
+ - If an existing install with the same id is replaced, old cache directories are cleaned up (best effort)
80
+ - Triggers an incremental index build
81
+ - Returns JSON with install details and index stats
82
+
83
+ ### list
84
+
85
+ Show installed entries from `config.registry.installed`.
86
+
87
+ - Source of truth is config, not cache directory discovery
88
+ - Each entry includes status flags:
89
+ - `status.cacheDirExists`
90
+ - `status.stashRootExists`
91
+
92
+ ### remove
93
+
94
+ Remove a single installed entry and reindex incrementally.
95
+
96
+ ```sh
97
+ akm remove npm:@scope/kit
98
+ akm remove github:owner/repo
99
+ akm remove owner/repo
100
+ ```
101
+
102
+ - Target resolution order: exact `id`, exact stored `ref`, then parsed ref `id`
103
+ - Removes entry via config helper (also syncs `additionalStashDirs`)
104
+ - Deletes prior `cacheDir` best effort
105
+ - Runs one incremental reindex
106
+
107
+ ### reinstall
108
+
109
+ Reinstall one entry or all entries from stored refs.
110
+
111
+ ```sh
112
+ akm reinstall npm:@scope/kit
113
+ akm reinstall --all
114
+ ```
115
+
116
+ - Uses the same registry install flow as `akm add`
117
+ - Upserts config entries + `additionalStashDirs`
118
+ - Cleans up replaced cache directories best effort
119
+ - Runs one incremental reindex after all installs
120
+
121
+ ### update
122
+
123
+ Update one entry or all entries by doing a fresh resolve/install from each current ref.
124
+
125
+ ```sh
126
+ akm update npm:@scope/kit
127
+ akm update --all
128
+ ```
129
+
130
+ - Same target selection rules as `reinstall`
131
+ - Floating refs (for example `@latest` or default branch) resolve to newest available artifact
132
+ - Reports per-entry change flags for version/revision (`changed.version`, `changed.revision`, `changed.any`)
133
+ - Runs one incremental reindex after all installs
134
+
61
135
  ### search
62
136
 
63
- Search the stash for extension assets.
137
+ Search local stash assets, registry entries, or both.
64
138
 
65
139
  ```sh
66
- akm search "deploy" --type tool --limit 10
140
+ akm search "deploy" --type tool --limit 10 --usage both
141
+ akm search "lint" --source registry
142
+ akm search "docker" --source both
67
143
  ```
68
144
 
69
145
  - `query`: case-insensitive substring over stable names (relative paths)
70
146
  - `--type`: `tool | skill | command | agent | knowledge | any` (default: `any`)
71
147
  - `--limit`: defaults to `20`
148
+ - `--usage`: `none | both | item | guide` (default: `both`)
149
+ - `--source`: `local | registry | both` (default: `local`)
150
+
151
+ By default (`--source local`), results are the existing stash hits with `openRef`, score/explainability details (`score`, `whyMatched`), and, for tools, execution-ready `runCmd`.
152
+
153
+ When registry results are included (`--source registry|both`), each registry hit includes explicit install guidance:
154
+
155
+ - `installRef` (normalized ref for install)
156
+ - `installCmd` (ready-to-run command, e.g. `akm add npm:@scope/kit`)
72
157
 
73
- Returns typed hits with `openRef`, score/explainability details (`score`, `whyMatched`), and, for tools, execution-ready `runCmd`.
158
+ - `usageGuide` is included by default (`--usage both`) and explains how to use each hit type.
159
+ - Per-hit `usage` is optional metadata from `.stash.json` and is included when present.
74
160
 
75
161
  ### show
76
162
 
@@ -96,10 +182,25 @@ Returns full payload by type:
96
182
  Agentikit also exports its core functions for use as a library:
97
183
 
98
184
  ```ts
99
- import { agentikitSearch, agentikitShow, agentikitInit, agentikitIndex } from "agentikit"
185
+ import {
186
+ agentikitAdd,
187
+ agentikitList,
188
+ agentikitRemove,
189
+ agentikitReinstall,
190
+ agentikitUpdate,
191
+ agentikitSearch,
192
+ agentikitShow,
193
+ agentikitInit,
194
+ agentikitIndex,
195
+ } from "agentikit"
100
196
  ```
101
197
 
102
- - `agentikitSearch({ query, type?, limit? })` — search the stash
198
+ - `agentikitAdd({ ref })` — install a registry reference and index it
199
+ - `agentikitList()` — list installed registry entries and filesystem status flags
200
+ - `agentikitRemove({ target })` — remove one installed entry and reindex incrementally
201
+ - `agentikitReinstall({ target? , all? })` — reinstall one/all installed entries
202
+ - `agentikitUpdate({ target? , all? })` — fresh resolve/install one/all installed entries with change reporting
203
+ - `agentikitSearch({ query, type?, limit?, usage?, source? })` — search local stash and/or registry
103
204
  - `agentikitShow({ ref, view? })` — show a stash asset
104
205
  - `agentikitInit()` — initialize stash directory
105
206
  - `agentikitIndex()` — build/rebuild search index
@@ -179,5 +280,7 @@ Both `embedding` and `llm` accept an optional `apiKey` field for authenticated e
179
280
 
180
281
  ## Notes
181
282
 
182
- - Agentikit does not install or copy kit files.
283
+ - `akm add` installs registry kits into the local cache and adds discovered stash roots to `additionalStashDirs`.
284
+ - Registry lifecycle commands (`list`, `remove`, `reinstall`, `update`) use `config.registry.installed` as the source of truth.
285
+ - When commands fail, CLI errors are returned as structured JSON with `error` and `hint` fields.
183
286
  - Missing or unreadable stash paths return friendly errors.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { agentikitSearch, agentikitShow } from "./src/stash";
1
+ export { agentikitAdd, agentikitList, agentikitRemove, agentikitReinstall, agentikitSearch, agentikitShow, agentikitUpdate, } from "./src/stash";
2
2
  export { agentikitInit } from "./src/init";
3
3
  export type { InitResponse } from "./src/init";
4
- export type { AgentikitAssetType, AgentikitSearchType, SearchHit, SearchResponse, ShowResponse, KnowledgeView, } from "./src/stash";
4
+ export type { AgentikitAssetType, AgentikitSearchType, AddResponse, LocalSearchHit, RegistrySearchResultHit, SearchSource, SearchHit, SearchResponse, ShowResponse, KnowledgeView, ListResponse, RemoveResponse, ReinstallResponse, UpdateResponse, RegistryListEntry, RegistryInstallStatus, ReinstallResultItem, UpdateResultItem, } from "./src/stash";
5
5
  export type { ToolKind } from "./src/tool-runner";
6
6
  export { agentikitIndex } from "./src/indexer";
7
7
  export type { IndexResponse } from "./src/indexer";
@@ -12,7 +12,11 @@ export { parseMarkdownToc, extractSection, extractLineRange, extractFrontmatterO
12
12
  export type { TocHeading, KnowledgeToc } from "./src/markdown";
13
13
  export { parseFrontmatter } from "./src/frontmatter";
14
14
  export { loadConfig, saveConfig, updateConfig } from "./src/config";
15
- export type { AgentikitConfig, EmbeddingConnectionConfig, LlmConnectionConfig } from "./src/config";
15
+ export type { AgentikitConfig, EmbeddingConnectionConfig, LlmConnectionConfig, RegistryConfig } from "./src/config";
16
+ export { parseRegistryRef, resolveRegistryArtifact } from "./src/registry-resolve";
17
+ export { searchRegistry } from "./src/registry-search";
18
+ export { installRegistryRef, upsertInstalledRegistryEntry, removeInstalledRegistryEntry, getRegistryCacheRootDir, detectStashRoot, } from "./src/registry-install";
19
+ export type { RegistrySource, ParsedRegistryRef, ParsedNpmRef, ParsedGithubRef, ResolvedRegistryArtifact, RegistryInstalledEntry, RegistryInstallResult, RegistrySearchHit, RegistrySearchResponse, } from "./src/registry-types";
16
20
  export { enhanceMetadata, isLlmAvailable } from "./src/llm";
17
21
  export { embed, cosineSimilarity, isEmbeddingAvailable } from "./src/embedder";
18
22
  export type { EmbeddingVector } from "./src/embedder";
package/dist/index.js CHANGED
@@ -1,9 +1,12 @@
1
- export { agentikitSearch, agentikitShow } from "./src/stash";
1
+ export { agentikitAdd, agentikitList, agentikitRemove, agentikitReinstall, agentikitSearch, agentikitShow, agentikitUpdate, } from "./src/stash";
2
2
  export { agentikitInit } from "./src/init";
3
3
  export { agentikitIndex } from "./src/indexer";
4
4
  export { resolveRg, isRgAvailable, ensureRg } from "./src/ripgrep";
5
5
  export { parseMarkdownToc, extractSection, extractLineRange, extractFrontmatterOnly, formatToc } from "./src/markdown";
6
6
  export { parseFrontmatter } from "./src/frontmatter";
7
7
  export { loadConfig, saveConfig, updateConfig } from "./src/config";
8
+ export { parseRegistryRef, resolveRegistryArtifact } from "./src/registry-resolve";
9
+ export { searchRegistry } from "./src/registry-search";
10
+ export { installRegistryRef, upsertInstalledRegistryEntry, removeInstalledRegistryEntry, getRegistryCacheRootDir, detectStashRoot, } from "./src/registry-install";
8
11
  export { enhanceMetadata, isLlmAvailable } from "./src/llm";
9
12
  export { embed, cosineSimilarity, isEmbeddingAvailable } from "./src/embedder";
package/dist/src/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { defineCommand, runMain } from "citty";
3
- import { agentikitSearch, agentikitShow } from "./stash";
3
+ import { agentikitAdd, agentikitList, agentikitReinstall, agentikitRemove, agentikitSearch, agentikitShow, agentikitUpdate, } from "./stash";
4
4
  import { agentikitInit } from "./init";
5
5
  import { agentikitIndex } from "./indexer";
6
6
  import { loadConfig, updateConfig } from "./config";
@@ -8,8 +8,10 @@ import { resolveStashDir } from "./common";
8
8
  const initCommand = defineCommand({
9
9
  meta: { name: "init", description: "Initialize agentikit stash directory and set AGENTIKIT_STASH_DIR" },
10
10
  run() {
11
- const result = agentikitInit();
12
- console.log(JSON.stringify(result, null, 2));
11
+ return runWithJsonErrors(() => {
12
+ const result = agentikitInit();
13
+ console.log(JSON.stringify(result, null, 2));
14
+ });
13
15
  },
14
16
  });
15
17
  const indexCommand = defineCommand({
@@ -18,8 +20,10 @@ const indexCommand = defineCommand({
18
20
  full: { type: "boolean", description: "Force full reindex", default: false },
19
21
  },
20
22
  async run({ args }) {
21
- const result = await agentikitIndex({ full: args.full });
22
- console.log(JSON.stringify(result, null, 2));
23
+ await runWithJsonErrors(async () => {
24
+ const result = await agentikitIndex({ full: args.full });
25
+ console.log(JSON.stringify(result, null, 2));
26
+ });
23
27
  },
24
28
  });
25
29
  const searchCommand = defineCommand({
@@ -28,11 +32,71 @@ const searchCommand = defineCommand({
28
32
  query: { type: "positional", description: "Search query", required: false, default: "" },
29
33
  type: { type: "string", description: "Asset type filter (tool|skill|command|agent|knowledge|any)" },
30
34
  limit: { type: "string", description: "Maximum number of results" },
35
+ usage: { type: "string", description: "Usage metadata mode (none|both|item|guide)", default: "both" },
36
+ source: { type: "string", description: "Search source (local|registry|both)", default: "local" },
31
37
  },
32
38
  async run({ args }) {
33
- const type = args.type;
34
- const limit = args.limit ? parseInt(args.limit, 10) : undefined;
35
- console.log(JSON.stringify(await agentikitSearch({ query: args.query, type, limit }), null, 2));
39
+ await runWithJsonErrors(async () => {
40
+ const type = args.type;
41
+ const limit = args.limit ? parseInt(args.limit, 10) : undefined;
42
+ const usage = parseSearchUsageMode(args.usage);
43
+ const source = parseSearchSource(args.source);
44
+ console.log(JSON.stringify(await agentikitSearch({ query: args.query, type, limit, usage, source }), null, 2));
45
+ });
46
+ },
47
+ });
48
+ const addCommand = defineCommand({
49
+ meta: { name: "add", description: "Install a registry package into the stash" },
50
+ args: {
51
+ ref: { type: "positional", description: "Registry ref (npm package, owner/repo, or github URL)", required: true },
52
+ },
53
+ async run({ args }) {
54
+ await runWithJsonErrors(async () => {
55
+ console.log(JSON.stringify(await agentikitAdd({ ref: args.ref }), null, 2));
56
+ });
57
+ },
58
+ });
59
+ const listCommand = defineCommand({
60
+ meta: { name: "list", description: "List installed registry packages from config" },
61
+ async run() {
62
+ await runWithJsonErrors(async () => {
63
+ console.log(JSON.stringify(await agentikitList(), null, 2));
64
+ });
65
+ },
66
+ });
67
+ const removeCommand = defineCommand({
68
+ meta: { name: "remove", description: "Remove an installed registry package by id or ref" },
69
+ args: {
70
+ target: { type: "positional", description: "Installed target (id or ref)", required: true },
71
+ },
72
+ async run({ args }) {
73
+ await runWithJsonErrors(async () => {
74
+ console.log(JSON.stringify(await agentikitRemove({ target: args.target }), null, 2));
75
+ });
76
+ },
77
+ });
78
+ const updateCommand = defineCommand({
79
+ meta: { name: "update", description: "Update one or all installed registry packages" },
80
+ args: {
81
+ target: { type: "positional", description: "Installed target (id or ref)", required: false },
82
+ all: { type: "boolean", description: "Update all installed entries", default: false },
83
+ },
84
+ async run({ args }) {
85
+ await runWithJsonErrors(async () => {
86
+ console.log(JSON.stringify(await agentikitUpdate({ target: args.target, all: args.all }), null, 2));
87
+ });
88
+ },
89
+ });
90
+ const reinstallCommand = defineCommand({
91
+ meta: { name: "reinstall", description: "Reinstall one or all installed registry packages" },
92
+ args: {
93
+ target: { type: "positional", description: "Installed target (id or ref)", required: false },
94
+ all: { type: "boolean", description: "Reinstall all installed entries", default: false },
95
+ },
96
+ async run({ args }) {
97
+ await runWithJsonErrors(async () => {
98
+ console.log(JSON.stringify(await agentikitReinstall({ target: args.target, all: args.all }), null, 2));
99
+ });
36
100
  },
37
101
  });
38
102
  const showCommand = defineCommand({
@@ -45,30 +109,31 @@ const showCommand = defineCommand({
45
109
  end: { type: "string", description: "End line (for --view lines)" },
46
110
  },
47
111
  run({ args }) {
48
- let view;
49
- if (args.view) {
50
- switch (args.view) {
51
- case "section":
52
- view = { mode: "section", heading: args.heading ?? "" };
53
- break;
54
- case "lines":
55
- view = {
56
- mode: "lines",
57
- start: Number(args.start ?? "1"),
58
- end: args.end ? parseInt(args.end, 10) : Number.MAX_SAFE_INTEGER,
59
- };
60
- break;
61
- case "toc":
62
- case "frontmatter":
63
- case "full":
64
- view = { mode: args.view };
65
- break;
66
- default:
67
- console.error(`Unknown view mode: ${args.view}`);
68
- process.exit(1);
112
+ return runWithJsonErrors(() => {
113
+ let view;
114
+ if (args.view) {
115
+ switch (args.view) {
116
+ case "section":
117
+ view = { mode: "section", heading: args.heading ?? "" };
118
+ break;
119
+ case "lines":
120
+ view = {
121
+ mode: "lines",
122
+ start: Number(args.start ?? "1"),
123
+ end: args.end ? parseInt(args.end, 10) : Number.MAX_SAFE_INTEGER,
124
+ };
125
+ break;
126
+ case "toc":
127
+ case "frontmatter":
128
+ case "full":
129
+ view = { mode: args.view };
130
+ break;
131
+ default:
132
+ throw new Error(`Unknown view mode: ${args.view}. Expected one of: full|toc|frontmatter|section|lines`);
133
+ }
69
134
  }
70
- }
71
- console.log(JSON.stringify(agentikitShow({ ref: args.ref, view }), null, 2));
135
+ console.log(JSON.stringify(agentikitShow({ ref: args.ref, view }), null, 2));
136
+ });
72
137
  },
73
138
  });
74
139
  const configCommand = defineCommand({
@@ -77,23 +142,24 @@ const configCommand = defineCommand({
77
142
  set: { type: "string", description: "Update a config key (key=value format)" },
78
143
  },
79
144
  run({ args }) {
80
- const stashDir = resolveStashDir();
81
- if (args.set) {
82
- const eqIndex = args.set.indexOf("=");
83
- if (eqIndex === -1) {
84
- console.error("Error: --set expects key=value format");
85
- process.exit(1);
145
+ return runWithJsonErrors(() => {
146
+ const stashDir = resolveStashDir();
147
+ if (args.set) {
148
+ const eqIndex = args.set.indexOf("=");
149
+ if (eqIndex === -1) {
150
+ throw new Error("--set expects key=value format");
151
+ }
152
+ const key = args.set.slice(0, eqIndex);
153
+ const value = args.set.slice(eqIndex + 1);
154
+ const partial = parseConfigValue(key, value);
155
+ const config = updateConfig(partial, stashDir);
156
+ console.log(JSON.stringify(config, null, 2));
157
+ }
158
+ else {
159
+ const config = loadConfig(stashDir);
160
+ console.log(JSON.stringify(config, null, 2));
86
161
  }
87
- const key = args.set.slice(0, eqIndex);
88
- const value = args.set.slice(eqIndex + 1);
89
- const partial = parseConfigValue(key, value);
90
- const config = updateConfig(partial, stashDir);
91
- console.log(JSON.stringify(config, null, 2));
92
- }
93
- else {
94
- const config = loadConfig(stashDir);
95
- console.log(JSON.stringify(config, null, 2));
96
- }
162
+ });
97
163
  },
98
164
  });
99
165
  const main = defineCommand({
@@ -104,12 +170,29 @@ const main = defineCommand({
104
170
  subCommands: {
105
171
  init: initCommand,
106
172
  index: indexCommand,
173
+ add: addCommand,
174
+ list: listCommand,
175
+ remove: removeCommand,
176
+ update: updateCommand,
177
+ reinstall: reinstallCommand,
107
178
  search: searchCommand,
108
179
  show: showCommand,
109
180
  config: configCommand,
110
181
  },
111
182
  });
112
183
  runMain(main);
184
+ const SEARCH_USAGE_MODES = ["none", "both", "item", "guide"];
185
+ const SEARCH_SOURCES = ["local", "registry", "both"];
186
+ function parseSearchUsageMode(value) {
187
+ if (SEARCH_USAGE_MODES.includes(value))
188
+ return value;
189
+ throw new Error(`Invalid value for --usage: ${value}. Expected one of: ${SEARCH_USAGE_MODES.join("|")}`);
190
+ }
191
+ function parseSearchSource(value) {
192
+ if (SEARCH_SOURCES.includes(value))
193
+ return value;
194
+ throw new Error(`Invalid value for --source: ${value}. Expected one of: ${SEARCH_SOURCES.join("|")}`);
195
+ }
113
196
  function parseConnectionValue(key, value, exampleEndpoint, exampleModel) {
114
197
  if (value === "null" || value === "")
115
198
  return undefined;
@@ -162,3 +245,29 @@ function parseConfigValue(key, value) {
162
245
  throw new Error(`Unknown config key: ${key}`);
163
246
  }
164
247
  }
248
+ async function runWithJsonErrors(fn) {
249
+ try {
250
+ await fn();
251
+ }
252
+ catch (error) {
253
+ const message = error instanceof Error ? error.message : String(error);
254
+ const hint = buildHint(message);
255
+ console.error(JSON.stringify({ ok: false, error: message, hint }, null, 2));
256
+ process.exit(1);
257
+ }
258
+ }
259
+ function buildHint(message) {
260
+ if (message.includes("AGENTIKIT_STASH_DIR"))
261
+ return "Run `akm init` or set AGENTIKIT_STASH_DIR to a valid directory.";
262
+ if (message.includes("Either <target> or --all is required"))
263
+ return "Use `akm update --all` or pass a target like `akm update npm:@scope/pkg`.";
264
+ if (message.includes("Specify either <target> or --all"))
265
+ return "Use only one: a positional target or `--all`.";
266
+ if (message.includes("No installed registry entry matched target"))
267
+ return "Run `akm list` to view installed ids/refs, then retry with one of those values.";
268
+ if (message.includes("Invalid value for --source"))
269
+ return "Pick one of: local, registry, both.";
270
+ if (message.includes("Invalid value for --usage"))
271
+ return "Pick one of: none, both, item, guide.";
272
+ return undefined;
273
+ }
@@ -1,3 +1,4 @@
1
+ import type { RegistryInstalledEntry } from "./registry-types";
1
2
  export interface EmbeddingConnectionConfig {
2
3
  /** OpenAI-compatible embeddings endpoint (e.g. "http://localhost:11434/v1/embeddings") */
3
4
  endpoint: string;
@@ -23,6 +24,11 @@ export interface AgentikitConfig {
23
24
  embedding?: EmbeddingConnectionConfig;
24
25
  /** OpenAI-compatible LLM endpoint config for metadata generation. If not set, uses heuristic generation */
25
26
  llm?: LlmConnectionConfig;
27
+ /** Installed registry sources and local cache metadata */
28
+ registry?: RegistryConfig;
29
+ }
30
+ export interface RegistryConfig {
31
+ installed: RegistryInstalledEntry[];
26
32
  }
27
33
  export declare const DEFAULT_CONFIG: AgentikitConfig;
28
34
  export declare function getConfigPath(stashDir: string): string;
@@ -53,6 +53,9 @@ function pickKnownKeys(raw) {
53
53
  const llm = parseConnectionConfig(raw.llm);
54
54
  if (llm)
55
55
  config.llm = llm;
56
+ const registry = parseRegistryConfig(raw.registry);
57
+ if (registry)
58
+ config.registry = registry;
56
59
  return config;
57
60
  }
58
61
  function parseConnectionConfig(value) {
@@ -72,3 +75,50 @@ function parseConnectionConfig(value) {
72
75
  }
73
76
  return result;
74
77
  }
78
+ function parseRegistryConfig(value) {
79
+ if (typeof value !== "object" || value === null || Array.isArray(value))
80
+ return undefined;
81
+ const obj = value;
82
+ if (!Array.isArray(obj.installed))
83
+ return undefined;
84
+ const installed = obj.installed
85
+ .map((entry) => parseRegistryInstalledEntry(entry))
86
+ .filter((entry) => entry !== undefined);
87
+ return { installed };
88
+ }
89
+ function parseRegistryInstalledEntry(value) {
90
+ if (typeof value !== "object" || value === null || Array.isArray(value))
91
+ return undefined;
92
+ const obj = value;
93
+ const id = asNonEmptyString(obj.id);
94
+ const source = asRegistrySource(obj.source);
95
+ const ref = asNonEmptyString(obj.ref);
96
+ const artifactUrl = asNonEmptyString(obj.artifactUrl);
97
+ const stashRoot = asNonEmptyString(obj.stashRoot);
98
+ const cacheDir = asNonEmptyString(obj.cacheDir);
99
+ const installedAt = asNonEmptyString(obj.installedAt);
100
+ if (!id || !source || !ref || !artifactUrl || !stashRoot || !cacheDir || !installedAt)
101
+ return undefined;
102
+ const entry = {
103
+ id,
104
+ source,
105
+ ref,
106
+ artifactUrl,
107
+ stashRoot,
108
+ cacheDir,
109
+ installedAt,
110
+ };
111
+ const resolvedVersion = asNonEmptyString(obj.resolvedVersion);
112
+ if (resolvedVersion)
113
+ entry.resolvedVersion = resolvedVersion;
114
+ const resolvedRevision = asNonEmptyString(obj.resolvedRevision);
115
+ if (resolvedRevision)
116
+ entry.resolvedRevision = resolvedRevision;
117
+ return entry;
118
+ }
119
+ function asNonEmptyString(value) {
120
+ return typeof value === "string" && value ? value : undefined;
121
+ }
122
+ function asRegistrySource(value) {
123
+ return value === "npm" || value === "github" ? value : undefined;
124
+ }
@@ -20,6 +20,7 @@ export interface StashEntry {
20
20
  source?: "package" | "frontmatter" | "comments" | "filename" | "manual" | "llm";
21
21
  aliases?: string[];
22
22
  toc?: TocHeading[];
23
+ usage?: string[];
23
24
  }
24
25
  export interface StashFile {
25
26
  entries: StashEntry[];
@@ -94,8 +94,24 @@ export function validateStashEntry(entry) {
94
94
  if (validated.length > 0)
95
95
  result.toc = validated;
96
96
  }
97
+ const usage = normalizeNonEmptyStringList(e.usage);
98
+ if (usage)
99
+ result.usage = usage;
97
100
  return result;
98
101
  }
102
+ function normalizeNonEmptyStringList(value) {
103
+ if (typeof value === "string") {
104
+ const trimmed = value.trim();
105
+ return trimmed ? [trimmed] : undefined;
106
+ }
107
+ if (!Array.isArray(value))
108
+ return undefined;
109
+ const filtered = value
110
+ .filter((item) => typeof item === "string")
111
+ .map((item) => item.trim())
112
+ .filter((item) => item.length > 0);
113
+ return filtered.length > 0 ? filtered : undefined;
114
+ }
99
115
  // ── Metadata Generation ─────────────────────────────────────────────────────
100
116
  export function generateMetadata(dirPath, assetType, files, typeRoot = dirPath) {
101
117
  const entries = [];
@@ -0,0 +1,11 @@
1
+ import { type AgentikitConfig } from "./config";
2
+ import type { RegistryInstallResult, RegistryInstalledEntry } from "./registry-types";
3
+ export interface InstallRegistryRefOptions {
4
+ cacheRootDir?: string;
5
+ now?: Date;
6
+ }
7
+ export declare function installRegistryRef(ref: string, options?: InstallRegistryRefOptions): Promise<RegistryInstallResult>;
8
+ export declare function upsertInstalledRegistryEntry(entry: RegistryInstalledEntry, stashDir?: string): AgentikitConfig;
9
+ export declare function removeInstalledRegistryEntry(id: string, stashDir?: string): AgentikitConfig;
10
+ export declare function getRegistryCacheRootDir(): string;
11
+ export declare function detectStashRoot(extractedDir: string): string;