agentikit 0.0.7 → 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 (98) hide show
  1. package/README.md +215 -76
  2. package/dist/index.d.ts +17 -3
  3. package/dist/index.js +10 -2
  4. package/dist/src/asset-spec.d.ts +14 -0
  5. package/dist/src/asset-spec.js +46 -0
  6. package/dist/src/cli.js +268 -57
  7. package/dist/src/common.d.ts +8 -0
  8. package/dist/src/common.js +46 -0
  9. package/dist/src/config.d.ts +37 -0
  10. package/dist/src/config.js +124 -0
  11. package/dist/src/embedder.d.ts +10 -0
  12. package/dist/src/embedder.js +87 -0
  13. package/dist/src/frontmatter.d.ts +30 -0
  14. package/dist/src/frontmatter.js +86 -0
  15. package/dist/src/indexer.d.ts +20 -2
  16. package/dist/src/indexer.js +212 -80
  17. package/dist/src/init.d.ts +19 -0
  18. package/dist/src/init.js +87 -0
  19. package/dist/src/llm.d.ts +15 -0
  20. package/dist/src/llm.js +91 -0
  21. package/dist/src/markdown.d.ts +18 -0
  22. package/dist/src/markdown.js +77 -0
  23. package/dist/src/metadata.d.ts +11 -2
  24. package/dist/src/metadata.js +161 -29
  25. package/dist/src/registry-install.d.ts +11 -0
  26. package/dist/src/registry-install.js +208 -0
  27. package/dist/src/registry-resolve.d.ts +3 -0
  28. package/dist/src/registry-resolve.js +231 -0
  29. package/dist/src/registry-search.d.ts +5 -0
  30. package/dist/src/registry-search.js +129 -0
  31. package/dist/src/registry-types.d.ts +55 -0
  32. package/dist/src/registry-types.js +1 -0
  33. package/dist/src/ripgrep-install.d.ts +12 -0
  34. package/dist/src/ripgrep-install.js +169 -0
  35. package/dist/src/ripgrep-resolve.d.ts +13 -0
  36. package/dist/src/ripgrep-resolve.js +68 -0
  37. package/dist/src/ripgrep.d.ts +3 -36
  38. package/dist/src/ripgrep.js +2 -262
  39. package/dist/src/similarity.d.ts +1 -2
  40. package/dist/src/similarity.js +11 -0
  41. package/dist/src/stash-add.d.ts +4 -0
  42. package/dist/src/stash-add.js +59 -0
  43. package/dist/src/stash-ref.d.ts +7 -0
  44. package/dist/src/stash-ref.js +33 -0
  45. package/dist/src/stash-registry.d.ts +18 -0
  46. package/dist/src/stash-registry.js +221 -0
  47. package/dist/src/stash-resolve.d.ts +2 -0
  48. package/dist/src/stash-resolve.js +45 -0
  49. package/dist/src/stash-search.d.ts +8 -0
  50. package/dist/src/stash-search.js +484 -0
  51. package/dist/src/stash-show.d.ts +5 -0
  52. package/dist/src/stash-show.js +114 -0
  53. package/dist/src/stash-types.d.ts +217 -0
  54. package/dist/src/stash-types.js +1 -0
  55. package/dist/src/stash.d.ts +10 -63
  56. package/dist/src/stash.js +6 -633
  57. package/dist/src/tool-runner.d.ts +35 -0
  58. package/dist/src/tool-runner.js +100 -0
  59. package/dist/src/walker.d.ts +19 -0
  60. package/dist/src/walker.js +47 -0
  61. package/package.json +8 -14
  62. package/src/asset-spec.ts +69 -0
  63. package/src/cli.ts +282 -46
  64. package/src/common.ts +58 -0
  65. package/src/config.ts +183 -0
  66. package/src/embedder.ts +117 -0
  67. package/src/frontmatter.ts +95 -0
  68. package/src/indexer.ts +244 -84
  69. package/src/init.ts +106 -0
  70. package/src/llm.ts +124 -0
  71. package/src/markdown.ts +106 -0
  72. package/src/metadata.ts +171 -27
  73. package/src/registry-install.ts +245 -0
  74. package/src/registry-resolve.ts +272 -0
  75. package/src/registry-search.ts +145 -0
  76. package/src/registry-types.ts +64 -0
  77. package/src/ripgrep-install.ts +200 -0
  78. package/src/ripgrep-resolve.ts +72 -0
  79. package/src/ripgrep.ts +3 -315
  80. package/src/similarity.ts +13 -1
  81. package/src/stash-add.ts +66 -0
  82. package/src/stash-ref.ts +41 -0
  83. package/src/stash-registry.ts +259 -0
  84. package/src/stash-resolve.ts +47 -0
  85. package/src/stash-search.ts +595 -0
  86. package/src/stash-show.ts +112 -0
  87. package/src/stash-types.ts +221 -0
  88. package/src/stash.ts +31 -760
  89. package/src/tool-runner.ts +129 -0
  90. package/src/walker.ts +53 -0
  91. package/.claude-plugin/plugin.json +0 -21
  92. package/commands/open.md +0 -11
  93. package/commands/run.md +0 -11
  94. package/commands/search.md +0 -11
  95. package/dist/src/plugin.d.ts +0 -2
  96. package/dist/src/plugin.js +0 -55
  97. package/skills/stash/SKILL.md +0 -73
  98. package/src/plugin.ts +0 -56
@@ -0,0 +1,259 @@
1
+ import fs from "node:fs"
2
+ import { resolveStashDir } from "./common"
3
+ import { loadConfig } from "./config"
4
+ import { agentikitIndex } from "./indexer"
5
+ import {
6
+ installRegistryRef,
7
+ removeInstalledRegistryEntry,
8
+ upsertInstalledRegistryEntry,
9
+ } from "./registry-install"
10
+ import { parseRegistryRef } from "./registry-resolve"
11
+ import type { RegistryInstalledEntry } from "./registry-types"
12
+ import type {
13
+ ListResponse,
14
+ RegistryInstallStatus,
15
+ RemoveResponse,
16
+ ReinstallResponse,
17
+ UpdateResponse,
18
+ } from "./stash-types"
19
+
20
+ export async function agentikitList(input?: { stashDir?: string }): Promise<ListResponse> {
21
+ const stashDir = input?.stashDir ?? resolveStashDir()
22
+ const config = loadConfig(stashDir)
23
+ const installed = config.registry?.installed ?? []
24
+
25
+ return {
26
+ stashDir,
27
+ installed: installed.map((entry) => ({
28
+ ...entry,
29
+ status: {
30
+ cacheDirExists: directoryExists(entry.cacheDir),
31
+ stashRootExists: directoryExists(entry.stashRoot),
32
+ },
33
+ })),
34
+ totalInstalled: installed.length,
35
+ }
36
+ }
37
+
38
+ export async function agentikitRemove(input: { target: string; stashDir?: string }): Promise<RemoveResponse> {
39
+ const target = input.target.trim()
40
+ if (!target) throw new Error("Target is required.")
41
+
42
+ const stashDir = input.stashDir ?? resolveStashDir()
43
+ const config = loadConfig(stashDir)
44
+ const installed = config.registry?.installed ?? []
45
+ const entry = resolveInstalledTarget(installed, target)
46
+
47
+ const updatedConfig = removeInstalledRegistryEntry(entry.id, stashDir)
48
+ cleanupDirectoryBestEffort(entry.cacheDir)
49
+ const index = await agentikitIndex({ stashDir })
50
+
51
+ return {
52
+ stashDir,
53
+ target,
54
+ removed: {
55
+ id: entry.id,
56
+ source: entry.source,
57
+ ref: entry.ref,
58
+ cacheDir: entry.cacheDir,
59
+ stashRoot: entry.stashRoot,
60
+ },
61
+ config: {
62
+ additionalStashDirs: updatedConfig.additionalStashDirs,
63
+ installedRegistryCount: updatedConfig.registry?.installed.length ?? 0,
64
+ },
65
+ index: {
66
+ mode: index.mode,
67
+ totalEntries: index.totalEntries,
68
+ directoriesScanned: index.directoriesScanned,
69
+ directoriesSkipped: index.directoriesSkipped,
70
+ },
71
+ }
72
+ }
73
+
74
+ export async function agentikitReinstall(input?: {
75
+ target?: string
76
+ all?: boolean
77
+ stashDir?: string
78
+ }): Promise<ReinstallResponse> {
79
+ const stashDir = input?.stashDir ?? resolveStashDir()
80
+ const target = input?.target?.trim()
81
+ const all = input?.all === true
82
+ const installedEntries = loadConfig(stashDir).registry?.installed ?? []
83
+ const selectedEntries = selectTargets(installedEntries, target, all)
84
+
85
+ const processed: ReinstallResponse["processed"] = []
86
+ for (const entry of selectedEntries) {
87
+ const installed = await installRegistryRef(entry.ref)
88
+ upsertInstalledRegistryEntry(toInstalledEntry(installed), stashDir)
89
+ if (entry.cacheDir !== installed.cacheDir) {
90
+ cleanupDirectoryBestEffort(entry.cacheDir)
91
+ }
92
+
93
+ processed.push({
94
+ id: entry.id,
95
+ source: entry.source,
96
+ ref: entry.ref,
97
+ previousCacheDir: entry.cacheDir,
98
+ installed: toInstallStatus(installed),
99
+ })
100
+ }
101
+
102
+ const index = await agentikitIndex({ stashDir })
103
+ const config = loadConfig(stashDir)
104
+
105
+ return {
106
+ stashDir,
107
+ target,
108
+ all,
109
+ processed,
110
+ config: {
111
+ additionalStashDirs: config.additionalStashDirs,
112
+ installedRegistryCount: config.registry?.installed.length ?? 0,
113
+ },
114
+ index: {
115
+ mode: index.mode,
116
+ totalEntries: index.totalEntries,
117
+ directoriesScanned: index.directoriesScanned,
118
+ directoriesSkipped: index.directoriesSkipped,
119
+ },
120
+ }
121
+ }
122
+
123
+ export async function agentikitUpdate(input?: {
124
+ target?: string
125
+ all?: boolean
126
+ stashDir?: string
127
+ }): Promise<UpdateResponse> {
128
+ const stashDir = input?.stashDir ?? resolveStashDir()
129
+ const target = input?.target?.trim()
130
+ const all = input?.all === true
131
+ const installedEntries = loadConfig(stashDir).registry?.installed ?? []
132
+ const selectedEntries = selectTargets(installedEntries, target, all)
133
+
134
+ const processed: UpdateResponse["processed"] = []
135
+ for (const entry of selectedEntries) {
136
+ const installed = await installRegistryRef(entry.ref)
137
+ upsertInstalledRegistryEntry(toInstalledEntry(installed), stashDir)
138
+ if (entry.cacheDir !== installed.cacheDir) {
139
+ cleanupDirectoryBestEffort(entry.cacheDir)
140
+ }
141
+
142
+ const versionChanged = (entry.resolvedVersion ?? "") !== (installed.resolvedVersion ?? "")
143
+ const revisionChanged = (entry.resolvedRevision ?? "") !== (installed.resolvedRevision ?? "")
144
+
145
+ processed.push({
146
+ id: entry.id,
147
+ source: entry.source,
148
+ ref: entry.ref,
149
+ previous: {
150
+ resolvedVersion: entry.resolvedVersion,
151
+ resolvedRevision: entry.resolvedRevision,
152
+ cacheDir: entry.cacheDir,
153
+ },
154
+ installed: toInstallStatus(installed),
155
+ changed: {
156
+ version: versionChanged,
157
+ revision: revisionChanged,
158
+ any: versionChanged || revisionChanged,
159
+ },
160
+ })
161
+ }
162
+
163
+ const index = await agentikitIndex({ stashDir })
164
+ const config = loadConfig(stashDir)
165
+
166
+ return {
167
+ stashDir,
168
+ target,
169
+ all,
170
+ processed,
171
+ config: {
172
+ additionalStashDirs: config.additionalStashDirs,
173
+ installedRegistryCount: config.registry?.installed.length ?? 0,
174
+ },
175
+ index: {
176
+ mode: index.mode,
177
+ totalEntries: index.totalEntries,
178
+ directoriesScanned: index.directoriesScanned,
179
+ directoriesSkipped: index.directoriesSkipped,
180
+ },
181
+ }
182
+ }
183
+
184
+ function selectTargets(installed: RegistryInstalledEntry[], target: string | undefined, all: boolean): RegistryInstalledEntry[] {
185
+ if (all && target) {
186
+ throw new Error("Specify either <target> or --all, not both.")
187
+ }
188
+ if (all) return installed
189
+ if (!target) {
190
+ throw new Error("Either <target> or --all is required.")
191
+ }
192
+ return [resolveInstalledTarget(installed, target)]
193
+ }
194
+
195
+ function resolveInstalledTarget(installed: RegistryInstalledEntry[], target: string): RegistryInstalledEntry {
196
+ const byId = installed.find((entry) => entry.id === target)
197
+ if (byId) return byId
198
+
199
+ const byRef = installed.find((entry) => entry.ref === target)
200
+ if (byRef) return byRef
201
+
202
+ let parsedId: string | undefined
203
+ try {
204
+ parsedId = parseRegistryRef(target).id
205
+ } catch {
206
+ parsedId = undefined
207
+ }
208
+ if (parsedId) {
209
+ const byParsedId = installed.find((entry) => entry.id === parsedId)
210
+ if (byParsedId) return byParsedId
211
+ }
212
+
213
+ throw new Error(`No installed registry entry matched target: ${target}`)
214
+ }
215
+
216
+ function toInstalledEntry(status: RegistryInstallStatus): RegistryInstalledEntry {
217
+ return {
218
+ id: status.id,
219
+ source: status.source,
220
+ ref: status.ref,
221
+ artifactUrl: status.artifactUrl,
222
+ resolvedVersion: status.resolvedVersion,
223
+ resolvedRevision: status.resolvedRevision,
224
+ stashRoot: status.stashRoot,
225
+ cacheDir: status.cacheDir,
226
+ installedAt: status.installedAt,
227
+ }
228
+ }
229
+
230
+ function toInstallStatus(status: RegistryInstallStatus): RegistryInstallStatus {
231
+ return {
232
+ id: status.id,
233
+ source: status.source,
234
+ ref: status.ref,
235
+ artifactUrl: status.artifactUrl,
236
+ resolvedVersion: status.resolvedVersion,
237
+ resolvedRevision: status.resolvedRevision,
238
+ stashRoot: status.stashRoot,
239
+ cacheDir: status.cacheDir,
240
+ extractedDir: status.extractedDir,
241
+ installedAt: status.installedAt,
242
+ }
243
+ }
244
+
245
+ function cleanupDirectoryBestEffort(target: string): void {
246
+ try {
247
+ fs.rmSync(target, { recursive: true, force: true })
248
+ } catch {
249
+ // Best-effort cleanup only.
250
+ }
251
+ }
252
+
253
+ function directoryExists(target: string): boolean {
254
+ try {
255
+ return fs.statSync(target).isDirectory()
256
+ } catch {
257
+ return false
258
+ }
259
+ }
@@ -0,0 +1,47 @@
1
+ import fs from "node:fs"
2
+ import path from "node:path"
3
+ import { type AgentikitAssetType, hasErrnoCode, isWithin } from "./common"
4
+ import { TYPE_DIRS, isRelevantAssetFile, resolveAssetPathFromName } from "./asset-spec"
5
+
6
+ export function resolveAssetPath(stashDir: string, type: AgentikitAssetType, name: string): string {
7
+ const root = path.join(stashDir, TYPE_DIRS[type])
8
+ const target = resolveAssetPathFromName(type, root, name)
9
+ const resolvedRoot = resolveAndValidateTypeRoot(root, type, name)
10
+ const resolvedTarget = path.resolve(target)
11
+ if (!isWithin(resolvedTarget, resolvedRoot)) {
12
+ throw new Error("Ref resolves outside the stash root.")
13
+ }
14
+ if (!fs.existsSync(resolvedTarget) || !fs.statSync(resolvedTarget).isFile()) {
15
+ throw new Error(`Stash asset not found for ref: ${type}:${name}`)
16
+ }
17
+ const realTarget = fs.realpathSync(resolvedTarget)
18
+ if (!isWithin(realTarget, resolvedRoot)) {
19
+ throw new Error("Ref resolves outside the stash root.")
20
+ }
21
+ if (!isRelevantAssetFile(type, path.basename(resolvedTarget))) {
22
+ if (type === "tool") {
23
+ throw new Error("Tool ref must resolve to a .sh, .ts, .js, .ps1, .cmd, or .bat file.")
24
+ }
25
+ throw new Error(`Stash asset not found for ref: ${type}:${name}`)
26
+ }
27
+ return realTarget
28
+ }
29
+
30
+ function resolveAndValidateTypeRoot(root: string, type: AgentikitAssetType, name: string): string {
31
+ const rootStat = readTypeRootStat(root, type, name)
32
+ if (!rootStat.isDirectory()) {
33
+ throw new Error(`Stash type root is not a directory for ref: ${type}:${name}`)
34
+ }
35
+ return fs.realpathSync(root)
36
+ }
37
+
38
+ function readTypeRootStat(root: string, type: AgentikitAssetType, name: string): fs.Stats {
39
+ try {
40
+ return fs.statSync(root)
41
+ } catch (error: unknown) {
42
+ if (hasErrnoCode(error, "ENOENT")) {
43
+ throw new Error(`Stash type root not found for ref: ${type}:${name}`)
44
+ }
45
+ throw error
46
+ }
47
+ }