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
@@ -7,8 +7,17 @@ import { TfIdfAdapter, type ScoredEntry } from "./similarity"
7
7
  import { buildToolInfo } from "./tool-runner"
8
8
  import { walkStash } from "./walker"
9
9
  import { makeOpenRef } from "./stash-ref"
10
- import type { AgentikitSearchType, SearchHit, SearchResponse } from "./stash-types"
10
+ import type {
11
+ AgentikitSearchType,
12
+ LocalSearchHit,
13
+ RegistrySearchResultHit,
14
+ SearchHit,
15
+ SearchResponse,
16
+ SearchSource,
17
+ SearchUsageMode,
18
+ } from "./stash-types"
11
19
  import { loadConfig } from "./config"
20
+ import { searchRegistry } from "./registry-search"
12
21
 
13
22
  type IndexedAsset = {
14
23
  type: AgentikitAssetType
@@ -18,18 +27,121 @@ type IndexedAsset = {
18
27
 
19
28
  const DEFAULT_LIMIT = 20
20
29
 
30
+ const DEFAULT_USAGE_GUIDE_BY_TYPE: Record<AgentikitAssetType, string[]> = {
31
+ tool: [
32
+ "Use the hit's runCmd for execution so runtime and working directory stay correct.",
33
+ "Use `akm show <openRef>` to inspect the tool before running it.",
34
+ ],
35
+ skill: [
36
+ "Read and apply the skill instructions as written, then adapt examples to your current repo state and task.",
37
+ "Use `akm show <openRef>` to read the full SKILL.md for required steps and constraints.",
38
+ ],
39
+ command: [
40
+ "Read the .md file, fill placeholders, and run it in the current repo context.",
41
+ "Use `akm show <openRef>` to retrieve the command template body.",
42
+ ],
43
+ agent: [
44
+ "Read the .md file and dispatch and agent using the content of the file. Use modelHint/toolPolicy when present to run the agent with compatible settings.",
45
+ "Use with `akm show <openRef>` to get the full prompt payload.",
46
+ ],
47
+ knowledge: [
48
+ "Use `akm show <openRef>` to read the document; start with `--view toc` for large files.",
49
+ "Use `--view section` or `--view lines` to load only the part you need.",
50
+ ],
51
+ }
52
+
21
53
  export async function agentikitSearch(input: {
22
54
  query: string
23
55
  type?: AgentikitSearchType
24
56
  limit?: number
57
+ usage?: SearchUsageMode
58
+ source?: SearchSource
25
59
  }): Promise<SearchResponse> {
26
60
  const t0 = Date.now()
27
- const query = input.query.trim().toLowerCase()
61
+ const query = input.query.trim()
62
+ const normalizedQuery = query.toLowerCase()
28
63
  const searchType = input.type ?? "any"
29
64
  const limit = normalizeLimit(input.limit)
65
+ const usageMode = parseSearchUsageMode(input.usage)
66
+ const source = parseSearchSource(input.source)
30
67
  const stashDir = resolveStashDir()
31
- const config = loadConfig(stashDir)
68
+ const localResult = source === "registry"
69
+ ? undefined
70
+ : await searchLocal({
71
+ query: normalizedQuery,
72
+ searchType,
73
+ limit,
74
+ usageMode,
75
+ stashDir,
76
+ })
77
+
78
+ const registryResult = source === "local"
79
+ ? undefined
80
+ : await searchRegistry(query, { limit })
81
+
82
+ if (source === "local") {
83
+ return {
84
+ stashDir,
85
+ source,
86
+ hits: localResult?.hits ?? [],
87
+ usageGuide: localResult?.usageGuide,
88
+ tip: localResult?.tip,
89
+ timing: { totalMs: Date.now() - t0, rankMs: localResult?.rankMs, embedMs: localResult?.embedMs },
90
+ }
91
+ }
92
+
93
+ const registryHits = (registryResult?.hits ?? []).map((hit): RegistrySearchResultHit => {
94
+ const installRef = hit.source === "npm" ? `npm:${hit.ref}` : `github:${hit.ref}`
95
+ return {
96
+ hitSource: "registry",
97
+ type: "registry",
98
+ name: hit.title,
99
+ id: hit.id,
100
+ registrySource: hit.source,
101
+ ref: hit.ref,
102
+ description: hit.description,
103
+ homepage: hit.homepage,
104
+ score: hit.score,
105
+ metadata: hit.metadata,
106
+ installRef,
107
+ installCmd: `akm add ${installRef}`,
108
+ }
109
+ })
110
+
111
+ if (source === "registry") {
112
+ const hits = registryHits.slice(0, limit)
113
+ return {
114
+ stashDir,
115
+ source,
116
+ hits,
117
+ tip: hits.length === 0 ? "No matching registry entries were found." : undefined,
118
+ warnings: registryResult?.warnings.length ? registryResult.warnings : undefined,
119
+ timing: { totalMs: Date.now() - t0 },
120
+ }
121
+ }
122
+
123
+ const mergedHits = mergeSearchHits(localResult?.hits ?? [], registryHits, limit)
32
124
 
125
+ return {
126
+ stashDir,
127
+ source,
128
+ hits: mergedHits,
129
+ usageGuide: localResult?.usageGuide,
130
+ tip: mergedHits.length === 0 ? "No matching stash assets or registry entries were found." : undefined,
131
+ warnings: registryResult?.warnings.length ? registryResult.warnings : undefined,
132
+ timing: { totalMs: Date.now() - t0 },
133
+ }
134
+ }
135
+
136
+ async function searchLocal(input: {
137
+ query: string
138
+ searchType: AgentikitSearchType
139
+ limit: number
140
+ usageMode: SearchUsageMode
141
+ stashDir: string
142
+ }): Promise<{ hits: LocalSearchHit[]; usageGuide?: Partial<Record<AgentikitAssetType, string[]>>; tip?: string; embedMs?: number; rankMs?: number }> {
143
+ const { query, searchType, limit, usageMode, stashDir } = input
144
+ const config = loadConfig(stashDir)
33
145
  const allStashDirs = [
34
146
  stashDir,
35
147
  ...config.additionalStashDirs.filter((d) => {
@@ -37,28 +149,26 @@ export async function agentikitSearch(input: {
37
149
  }),
38
150
  ]
39
151
 
40
- // Try indexed search (single unified pipeline: embedding + TF-IDF as weighted features)
41
152
  const index = loadSearchIndex()
42
153
  if (index && index.entries && index.entries.length > 0 && index.stashDir === stashDir) {
43
- const { hits, embedMs, rankMs } = await searchIndex(index, query, searchType, limit, stashDir, allStashDirs, config)
154
+ const { hits, usageGuide, embedMs, rankMs } = await searchIndex(index, query, searchType, limit, stashDir, allStashDirs, config, usageMode)
44
155
  return {
45
- stashDir,
46
156
  hits,
157
+ usageGuide,
47
158
  tip: hits.length === 0 ? "No matching stash assets were found. Try running 'akm index' to rebuild." : undefined,
48
- timing: { totalMs: Date.now() - t0, rankMs, embedMs },
159
+ embedMs,
160
+ rankMs,
49
161
  }
50
162
  }
51
163
 
52
- // No index: fall back to filesystem walk + substring match across all stash dirs
53
164
  const hits = allStashDirs
54
165
  .flatMap((dir) => substringSearch(query, searchType, limit, dir))
55
166
  .slice(0, limit)
56
-
167
+ const usageGuide = shouldIncludeUsageGuide(usageMode) ? buildUsageGuide(hits.map((hit) => hit.type), searchType) : undefined
57
168
  return {
58
- stashDir,
59
169
  hits,
170
+ usageGuide,
60
171
  tip: hits.length === 0 ? "No matching stash assets were found. Try running 'akm index' to rebuild." : undefined,
61
- timing: { totalMs: Date.now() - t0 },
62
172
  }
63
173
  }
64
174
 
@@ -72,20 +182,42 @@ async function searchIndex(
72
182
  stashDir: string,
73
183
  allStashDirs: string[],
74
184
  config: import("./config").AgentikitConfig,
75
- ): Promise<{ hits: SearchHit[]; embedMs?: number; rankMs?: number }> {
185
+ usageMode: SearchUsageMode,
186
+ ): Promise<{ hits: LocalSearchHit[]; usageGuide?: Partial<Record<AgentikitAssetType, string[]>>; embedMs?: number; rankMs?: number }> {
76
187
  // Filter candidates by type
77
188
  let candidates = index.entries
78
189
  if (searchType !== "any") {
79
190
  candidates = candidates.filter((ie) => ie.entry.type === searchType)
80
191
  }
81
192
 
82
- if (candidates.length === 0) return { hits: [] }
193
+ if (candidates.length === 0) {
194
+ return {
195
+ hits: [],
196
+ usageGuide: shouldIncludeUsageGuide(usageMode) ? buildUsageGuide([], searchType) : undefined,
197
+ }
198
+ }
83
199
 
84
200
  // Empty query: return all entries (no scoring needed)
85
201
  if (!query) {
86
- return { hits: candidates.slice(0, limit).map((ie) =>
87
- buildIndexedHit({ entry: ie.entry, path: ie.path, score: 1, query, rankingMode: "tfidf", defaultStashDir: stashDir, allStashDirs }),
88
- ) }
202
+ const selectedCandidates = candidates.slice(0, limit)
203
+ const hits = selectedCandidates.map((ie) =>
204
+ buildIndexedHit({
205
+ entry: ie.entry,
206
+ path: ie.path,
207
+ score: 1,
208
+ query,
209
+ rankingMode: "tfidf",
210
+ defaultStashDir: stashDir,
211
+ allStashDirs,
212
+ includeItemUsage: shouldIncludeItemUsage(usageMode),
213
+ }),
214
+ )
215
+ return {
216
+ hits,
217
+ usageGuide: shouldIncludeUsageGuide(usageMode)
218
+ ? buildUsageGuideFromEntries(selectedCandidates.map((candidate) => candidate.entry), searchType)
219
+ : undefined,
220
+ }
89
221
  }
90
222
 
91
223
  // Score each candidate using available signals
@@ -115,7 +247,8 @@ async function searchIndex(
115
247
  scored.sort((a, b) => b.score - a.score)
116
248
  const rankMs = Date.now() - tRank0
117
249
 
118
- return { embedMs, rankMs, hits: scored.slice(0, limit).map(({ ie, score, rankingMode }) =>
250
+ const selected = scored.slice(0, limit)
251
+ const hits = selected.map(({ ie, score, rankingMode }) =>
119
252
  buildIndexedHit({
120
253
  entry: ie.entry,
121
254
  path: ie.path,
@@ -124,8 +257,18 @@ async function searchIndex(
124
257
  rankingMode,
125
258
  defaultStashDir: stashDir,
126
259
  allStashDirs,
260
+ includeItemUsage: shouldIncludeItemUsage(usageMode),
127
261
  }),
128
- ) }
262
+ )
263
+
264
+ return {
265
+ embedMs,
266
+ rankMs,
267
+ hits,
268
+ usageGuide: shouldIncludeUsageGuide(usageMode)
269
+ ? buildUsageGuideFromEntries(selected.map((item) => item.ie.entry), searchType)
270
+ : undefined,
271
+ }
129
272
  }
130
273
 
131
274
  // ── Embedding scorer ────────────────────────────────────────────────────────
@@ -189,13 +332,13 @@ function substringSearch(
189
332
  searchType: AgentikitSearchType,
190
333
  limit: number,
191
334
  stashDir: string,
192
- ): SearchHit[] {
335
+ ): LocalSearchHit[] {
193
336
  const assets = indexAssets(stashDir, searchType)
194
337
  return assets
195
338
  .filter((asset) => asset.name.toLowerCase().includes(query))
196
339
  .sort(compareAssets)
197
340
  .slice(0, limit)
198
- .map((asset): SearchHit => assetToSearchHit(asset, stashDir))
341
+ .map((asset) => assetToSearchHit(asset, stashDir))
199
342
  }
200
343
 
201
344
  // ── Hit building ────────────────────────────────────────────────────────────
@@ -216,7 +359,8 @@ function buildIndexedHit(input: {
216
359
  rankingMode: "semantic" | "tfidf"
217
360
  defaultStashDir: string
218
361
  allStashDirs: string[]
219
- }): SearchHit {
362
+ includeItemUsage: boolean
363
+ }): LocalSearchHit {
220
364
  const entryStashDir = findStashDirForPath(input.path, input.allStashDirs) ?? input.defaultStashDir
221
365
  const typeRoot = path.join(entryStashDir, TYPE_DIRS[input.entry.type])
222
366
  const openRefName = deriveCanonicalAssetName(input.entry.type, typeRoot, input.path)
@@ -228,7 +372,8 @@ function buildIndexedHit(input: {
228
372
 
229
373
  const whyMatched = buildWhyMatched(input.entry, input.query, input.rankingMode, qualityBoost, confidenceBoost)
230
374
 
231
- const hit: SearchHit = {
375
+ const hit: LocalSearchHit = {
376
+ hitSource: "local",
232
377
  type: input.entry.type,
233
378
  name: input.entry.name,
234
379
  path: input.path,
@@ -239,6 +384,10 @@ function buildIndexedHit(input: {
239
384
  whyMatched,
240
385
  }
241
386
 
387
+ if (input.includeItemUsage && input.entry.usage && input.entry.usage.length > 0) {
388
+ hit.usage = input.entry.usage
389
+ }
390
+
242
391
  if (input.entry.type === "tool") {
243
392
  try {
244
393
  const toolInfo = buildToolInfo(entryStashDir, input.path)
@@ -288,9 +437,10 @@ function toScoredEntries(entries: IndexedEntry[]): ScoredEntry[] {
288
437
  }))
289
438
  }
290
439
 
291
- function assetToSearchHit(asset: IndexedAsset, stashDir: string): SearchHit {
440
+ function assetToSearchHit(asset: IndexedAsset, stashDir: string): LocalSearchHit {
292
441
  if (asset.type !== "tool") {
293
442
  return {
443
+ hitSource: "local",
294
444
  type: asset.type,
295
445
  name: asset.name,
296
446
  path: asset.path,
@@ -299,6 +449,7 @@ function assetToSearchHit(asset: IndexedAsset, stashDir: string): SearchHit {
299
449
  }
300
450
  const toolInfo = buildToolInfo(stashDir, asset.path)
301
451
  return {
452
+ hitSource: "local",
302
453
  type: "tool",
303
454
  name: asset.name,
304
455
  path: asset.path,
@@ -315,6 +466,107 @@ function normalizeLimit(limit?: number): number {
315
466
  return Math.min(Math.floor(limit), 200)
316
467
  }
317
468
 
469
+ function parseSearchUsageMode(mode: SearchUsageMode | undefined): SearchUsageMode {
470
+ if (mode === "none" || mode === "both" || mode === "item" || mode === "guide") {
471
+ return mode
472
+ }
473
+ if (typeof mode === "undefined") return "both"
474
+ throw new Error(`Invalid usage mode: ${String(mode)}. Expected one of: none|both|item|guide`)
475
+ }
476
+
477
+ function parseSearchSource(source: SearchSource | undefined): SearchSource {
478
+ if (source === "local" || source === "registry" || source === "both") return source
479
+ if (typeof source === "undefined") return "local"
480
+ throw new Error(`Invalid search source: ${String(source)}. Expected one of: local|registry|both`)
481
+ }
482
+
483
+ function mergeSearchHits(localHits: LocalSearchHit[], registryHits: RegistrySearchResultHit[], limit: number): SearchHit[] {
484
+ const merged: SearchHit[] = []
485
+ let localIndex = 0
486
+ let registryIndex = 0
487
+
488
+ while (merged.length < limit && (localIndex < localHits.length || registryIndex < registryHits.length)) {
489
+ if (localIndex < localHits.length) {
490
+ merged.push(localHits[localIndex])
491
+ localIndex += 1
492
+ if (merged.length >= limit) break
493
+ }
494
+ if (registryIndex < registryHits.length) {
495
+ merged.push(registryHits[registryIndex])
496
+ registryIndex += 1
497
+ }
498
+ }
499
+
500
+ return merged
501
+ }
502
+
503
+ function shouldIncludeUsageGuide(mode: SearchUsageMode): boolean {
504
+ return mode === "both" || mode === "guide"
505
+ }
506
+
507
+ function shouldIncludeItemUsage(mode: SearchUsageMode): boolean {
508
+ return mode === "both" || mode === "item"
509
+ }
510
+
511
+ function buildUsageGuideFromEntries(
512
+ entries: IndexedEntry["entry"][],
513
+ searchType: AgentikitSearchType,
514
+ ): Partial<Record<AgentikitAssetType, string[]>> | undefined {
515
+ const types = entries.map((entry) => entry.type)
516
+ const fallbackGuide = buildUsageGuide(types, searchType)
517
+ const metadataByType = new Map<AgentikitAssetType, string[]>()
518
+
519
+ for (const entry of entries) {
520
+ if (!entry.usage || entry.usage.length === 0) continue
521
+ const current = metadataByType.get(entry.type) ?? []
522
+ for (const item of entry.usage) {
523
+ const trimmed = item.trim()
524
+ if (trimmed && !current.includes(trimmed)) current.push(trimmed)
525
+ }
526
+ if (current.length > 0) metadataByType.set(entry.type, current)
527
+ }
528
+
529
+ if (!fallbackGuide && metadataByType.size === 0) return undefined
530
+
531
+ const result: Partial<Record<AgentikitAssetType, string[]>> = {}
532
+ for (const assetType of resolveGuideTypes(types, searchType)) {
533
+ const lines: string[] = []
534
+ const metadataLines = metadataByType.get(assetType)
535
+ if (metadataLines && metadataLines.length > 0) {
536
+ lines.push(...metadataLines)
537
+ }
538
+ const fallbackLines = fallbackGuide?.[assetType]
539
+ if (fallbackLines && fallbackLines.length > 0) {
540
+ for (const line of fallbackLines) {
541
+ if (!lines.includes(line)) lines.push(line)
542
+ }
543
+ }
544
+ if (lines.length > 0) result[assetType] = lines
545
+ }
546
+
547
+ return Object.keys(result).length > 0 ? result : undefined
548
+ }
549
+
550
+ function buildUsageGuide(
551
+ hitTypes: AgentikitAssetType[],
552
+ searchType: AgentikitSearchType,
553
+ ): Partial<Record<AgentikitAssetType, string[]>> | undefined {
554
+ const result: Partial<Record<AgentikitAssetType, string[]>> = {}
555
+ for (const assetType of resolveGuideTypes(hitTypes, searchType)) {
556
+ result[assetType] = usageGuideByType(assetType)
557
+ }
558
+ return Object.keys(result).length > 0 ? result : undefined
559
+ }
560
+
561
+ function resolveGuideTypes(hitTypes: AgentikitAssetType[], searchType: AgentikitSearchType): AgentikitAssetType[] {
562
+ if (searchType !== "any") return [searchType]
563
+ return Array.from(new Set(hitTypes))
564
+ }
565
+
566
+ function usageGuideByType(type: AgentikitAssetType): string[] {
567
+ return DEFAULT_USAGE_GUIDE_BY_TYPE[type]
568
+ }
569
+
318
570
  function fileToAsset(assetType: AgentikitAssetType, root: string, file: string): IndexedAsset | undefined {
319
571
  const name = deriveCanonicalAssetName(assetType, root, file)
320
572
  if (!name) return undefined
package/src/stash-show.ts CHANGED
@@ -60,7 +60,8 @@ export function agentikitShow(input: { ref: string; view?: KnowledgeView }): Sho
60
60
  name: parsed.name,
61
61
  path: assetPath,
62
62
  description: toStringOrUndefined(parsedMd.data.description),
63
- prompt: parsedMd.content,
63
+ prompt: "Dispatching prompt must include the agent's full prompt content verbatim; summaries are non-compliant. \n\n"
64
+ + parsedMd.content,
64
65
  toolPolicy: parsedMd.data.tools,
65
66
  modelHint: parsedMd.data.model,
66
67
  }
@@ -89,7 +90,14 @@ export function agentikitShow(input: { ref: string; view?: KnowledgeView }): Sho
89
90
  }
90
91
  case "section": {
91
92
  const section = extractSection(content, v.heading)
92
- if (!section) throw new Error(`Section "${v.heading}" not found in ${parsed.name}`)
93
+ if (!section) {
94
+ return {
95
+ type: "knowledge",
96
+ name: parsed.name,
97
+ path: assetPath,
98
+ content: `Section "${v.heading}" not found in ${parsed.name}. Try --view toc to discover available headings.`,
99
+ }
100
+ }
93
101
  return { type: "knowledge", name: parsed.name, path: assetPath, content: section.content }
94
102
  }
95
103
  case "lines": {
@@ -1,9 +1,13 @@
1
1
  import type { AgentikitAssetType } from "./common"
2
+ import type { RegistrySource } from "./registry-types"
2
3
  import type { ToolKind } from "./tool-runner"
3
4
 
4
5
  export type AgentikitSearchType = AgentikitAssetType | "any"
6
+ export type SearchUsageMode = "none" | "both" | "item" | "guide"
7
+ export type SearchSource = "local" | "registry" | "both"
5
8
 
6
- export interface SearchHit {
9
+ export interface LocalSearchHit {
10
+ hitSource: "local"
7
11
  type: AgentikitAssetType
8
12
  name: string
9
13
  path: string
@@ -14,16 +18,187 @@ export interface SearchHit {
14
18
  whyMatched?: string[]
15
19
  runCmd?: string
16
20
  kind?: ToolKind
21
+ usage?: string[]
17
22
  }
18
23
 
24
+ export interface RegistrySearchResultHit {
25
+ hitSource: "registry"
26
+ type: "registry"
27
+ name: string
28
+ path?: string
29
+ openRef?: string
30
+ id: string
31
+ registrySource: RegistrySource
32
+ ref: string
33
+ description?: string
34
+ tags?: string[]
35
+ homepage?: string
36
+ score?: number
37
+ whyMatched?: string[]
38
+ runCmd?: string
39
+ kind?: ToolKind
40
+ usage?: string[]
41
+ metadata?: Record<string, string>
42
+ installRef: string
43
+ installCmd: string
44
+ }
45
+
46
+ export type SearchHit = LocalSearchHit | RegistrySearchResultHit
47
+
19
48
  export interface SearchResponse {
20
49
  stashDir: string
50
+ source: SearchSource
21
51
  hits: SearchHit[]
52
+ usageGuide?: Partial<Record<AgentikitAssetType, string[]>>
22
53
  tip?: string
54
+ warnings?: string[]
23
55
  /** Timing counters in milliseconds */
24
56
  timing?: { totalMs: number; rankMs?: number; embedMs?: number }
25
57
  }
26
58
 
59
+ export interface AddResponse {
60
+ stashDir: string
61
+ ref: string
62
+ installed: {
63
+ id: string
64
+ source: RegistrySource
65
+ ref: string
66
+ artifactUrl: string
67
+ resolvedVersion?: string
68
+ resolvedRevision?: string
69
+ stashRoot: string
70
+ cacheDir: string
71
+ extractedDir: string
72
+ installedAt: string
73
+ }
74
+ config: {
75
+ additionalStashDirs: string[]
76
+ installedRegistryCount: number
77
+ }
78
+ index: {
79
+ mode: "full" | "incremental"
80
+ totalEntries: number
81
+ directoriesScanned: number
82
+ directoriesSkipped: number
83
+ }
84
+ }
85
+
86
+ export interface RegistryInstallStatus {
87
+ id: string
88
+ source: RegistrySource
89
+ ref: string
90
+ artifactUrl: string
91
+ resolvedVersion?: string
92
+ resolvedRevision?: string
93
+ stashRoot: string
94
+ cacheDir: string
95
+ extractedDir: string
96
+ installedAt: string
97
+ }
98
+
99
+ export interface RegistryListEntry {
100
+ id: string
101
+ source: RegistrySource
102
+ ref: string
103
+ artifactUrl: string
104
+ resolvedVersion?: string
105
+ resolvedRevision?: string
106
+ stashRoot: string
107
+ cacheDir: string
108
+ installedAt: string
109
+ status: {
110
+ cacheDirExists: boolean
111
+ stashRootExists: boolean
112
+ }
113
+ }
114
+
115
+ export interface ListResponse {
116
+ stashDir: string
117
+ installed: RegistryListEntry[]
118
+ totalInstalled: number
119
+ }
120
+
121
+ export interface RemoveResponse {
122
+ stashDir: string
123
+ target: string
124
+ removed: {
125
+ id: string
126
+ source: RegistrySource
127
+ ref: string
128
+ cacheDir: string
129
+ stashRoot: string
130
+ }
131
+ config: {
132
+ additionalStashDirs: string[]
133
+ installedRegistryCount: number
134
+ }
135
+ index: {
136
+ mode: "full" | "incremental"
137
+ totalEntries: number
138
+ directoriesScanned: number
139
+ directoriesSkipped: number
140
+ }
141
+ }
142
+
143
+ export interface ReinstallResultItem {
144
+ id: string
145
+ source: RegistrySource
146
+ ref: string
147
+ previousCacheDir: string
148
+ installed: RegistryInstallStatus
149
+ }
150
+
151
+ export interface ReinstallResponse {
152
+ stashDir: string
153
+ target?: string
154
+ all: boolean
155
+ processed: ReinstallResultItem[]
156
+ config: {
157
+ additionalStashDirs: string[]
158
+ installedRegistryCount: number
159
+ }
160
+ index: {
161
+ mode: "full" | "incremental"
162
+ totalEntries: number
163
+ directoriesScanned: number
164
+ directoriesSkipped: number
165
+ }
166
+ }
167
+
168
+ export interface UpdateResultItem {
169
+ id: string
170
+ source: RegistrySource
171
+ ref: string
172
+ previous: {
173
+ resolvedVersion?: string
174
+ resolvedRevision?: string
175
+ cacheDir: string
176
+ }
177
+ installed: RegistryInstallStatus
178
+ changed: {
179
+ version: boolean
180
+ revision: boolean
181
+ any: boolean
182
+ }
183
+ }
184
+
185
+ export interface UpdateResponse {
186
+ stashDir: string
187
+ target?: string
188
+ all: boolean
189
+ processed: UpdateResultItem[]
190
+ config: {
191
+ additionalStashDirs: string[]
192
+ installedRegistryCount: number
193
+ }
194
+ index: {
195
+ mode: "full" | "incremental"
196
+ totalEntries: number
197
+ directoriesScanned: number
198
+ directoriesSkipped: number
199
+ }
200
+ }
201
+
27
202
  export interface ShowResponse {
28
203
  type: AgentikitAssetType
29
204
  name: string
package/src/stash.ts CHANGED
@@ -6,11 +6,26 @@ export type { ToolKind } from "./tool-runner"
6
6
 
7
7
  export { agentikitSearch } from "./stash-search"
8
8
  export { agentikitShow } from "./stash-show"
9
+ export { agentikitAdd } from "./stash-add"
10
+ export { agentikitList, agentikitRemove, agentikitReinstall, agentikitUpdate } from "./stash-registry"
9
11
 
10
12
  export type {
13
+ AddResponse,
11
14
  AgentikitSearchType,
15
+ LocalSearchHit,
16
+ RegistrySearchResultHit,
17
+ SearchSource,
18
+ SearchUsageMode,
12
19
  SearchHit,
13
20
  SearchResponse,
14
21
  ShowResponse,
15
22
  KnowledgeView,
23
+ ListResponse,
24
+ RemoveResponse,
25
+ ReinstallResponse,
26
+ UpdateResponse,
27
+ RegistryListEntry,
28
+ RegistryInstallStatus,
29
+ ReinstallResultItem,
30
+ UpdateResultItem,
16
31
  } from "./stash-types"