agentikit 0.0.8 → 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.
Files changed (112) hide show
  1. package/README.md +135 -117
  2. package/dist/index.d.ts +13 -3
  3. package/dist/index.js +7 -1
  4. package/dist/src/asset-spec.d.ts +2 -0
  5. package/dist/src/asset-spec.js +22 -3
  6. package/dist/src/asset-type-handler.d.ts +27 -0
  7. package/dist/src/asset-type-handler.js +33 -0
  8. package/dist/src/cli.js +335 -100
  9. package/dist/src/common.d.ts +6 -1
  10. package/dist/src/common.js +18 -4
  11. package/dist/src/config-cli.d.ts +9 -0
  12. package/dist/src/config-cli.js +473 -0
  13. package/dist/src/config.d.ts +25 -6
  14. package/dist/src/config.js +188 -28
  15. package/dist/src/db.d.ts +46 -0
  16. package/dist/src/db.js +299 -0
  17. package/dist/src/embedder.js +12 -7
  18. package/dist/src/github.d.ts +4 -0
  19. package/dist/src/github.js +19 -0
  20. package/dist/src/handlers/agent-handler.d.ts +2 -0
  21. package/dist/src/handlers/agent-handler.js +26 -0
  22. package/dist/src/handlers/command-handler.d.ts +2 -0
  23. package/dist/src/handlers/command-handler.js +23 -0
  24. package/dist/src/handlers/index.d.ts +6 -0
  25. package/dist/src/handlers/index.js +23 -0
  26. package/dist/src/handlers/knowledge-handler.d.ts +2 -0
  27. package/dist/src/handlers/knowledge-handler.js +56 -0
  28. package/dist/src/handlers/markdown-helpers.d.ts +7 -0
  29. package/dist/src/handlers/markdown-helpers.js +15 -0
  30. package/dist/src/handlers/script-handler.d.ts +2 -0
  31. package/dist/src/handlers/script-handler.js +78 -0
  32. package/dist/src/handlers/skill-handler.d.ts +2 -0
  33. package/dist/src/handlers/skill-handler.js +30 -0
  34. package/dist/src/handlers/tool-handler.d.ts +2 -0
  35. package/dist/src/handlers/tool-handler.js +58 -0
  36. package/dist/src/indexer.d.ts +1 -23
  37. package/dist/src/indexer.js +162 -155
  38. package/dist/src/init.d.ts +2 -2
  39. package/dist/src/init.js +21 -9
  40. package/dist/src/llm.js +4 -3
  41. package/dist/src/metadata.d.ts +1 -1
  42. package/dist/src/metadata.js +22 -64
  43. package/dist/src/origin-resolve.d.ts +19 -0
  44. package/dist/src/origin-resolve.js +53 -0
  45. package/dist/src/registry-install.d.ts +11 -0
  46. package/dist/src/registry-install.js +315 -0
  47. package/dist/src/registry-resolve.d.ts +3 -0
  48. package/dist/src/registry-resolve.js +299 -0
  49. package/dist/src/registry-search.d.ts +27 -0
  50. package/dist/src/registry-search.js +263 -0
  51. package/dist/src/registry-types.d.ts +62 -0
  52. package/dist/src/registry-types.js +1 -0
  53. package/dist/src/stash-add.d.ts +4 -0
  54. package/dist/src/stash-add.js +59 -0
  55. package/dist/src/stash-clone.d.ts +22 -0
  56. package/dist/src/stash-clone.js +83 -0
  57. package/dist/src/stash-ref.d.ts +27 -3
  58. package/dist/src/stash-ref.js +63 -24
  59. package/dist/src/stash-registry.d.ts +18 -0
  60. package/dist/src/stash-registry.js +221 -0
  61. package/dist/src/stash-resolve.js +3 -0
  62. package/dist/src/stash-search.d.ts +3 -1
  63. package/dist/src/stash-search.js +357 -138
  64. package/dist/src/stash-show.d.ts +1 -1
  65. package/dist/src/stash-show.js +28 -89
  66. package/dist/src/stash-source.d.ts +24 -0
  67. package/dist/src/stash-source.js +81 -0
  68. package/dist/src/stash-types.d.ts +175 -1
  69. package/dist/src/stash.d.ts +9 -1
  70. package/dist/src/stash.js +5 -0
  71. package/dist/src/tool-runner.d.ts +1 -1
  72. package/dist/src/tool-runner.js +18 -5
  73. package/package.json +7 -2
  74. package/src/asset-spec.ts +20 -4
  75. package/src/asset-type-handler.ts +77 -0
  76. package/src/cli.ts +354 -103
  77. package/src/common.ts +23 -5
  78. package/src/config-cli.ts +499 -0
  79. package/src/config.ts +218 -37
  80. package/src/db.ts +411 -0
  81. package/src/embedder.ts +22 -11
  82. package/src/github.ts +21 -0
  83. package/src/handlers/agent-handler.ts +32 -0
  84. package/src/handlers/command-handler.ts +29 -0
  85. package/src/handlers/index.ts +25 -0
  86. package/src/handlers/knowledge-handler.ts +62 -0
  87. package/src/handlers/markdown-helpers.ts +19 -0
  88. package/src/handlers/script-handler.ts +92 -0
  89. package/src/handlers/skill-handler.ts +37 -0
  90. package/src/handlers/tool-handler.ts +71 -0
  91. package/src/indexer.ts +208 -187
  92. package/src/init.ts +17 -9
  93. package/src/llm.ts +4 -3
  94. package/src/metadata.ts +21 -65
  95. package/src/origin-resolve.ts +67 -0
  96. package/src/registry-install.ts +361 -0
  97. package/src/registry-resolve.ts +341 -0
  98. package/src/registry-search.ts +335 -0
  99. package/src/registry-types.ts +72 -0
  100. package/src/stash-add.ts +63 -0
  101. package/src/stash-clone.ts +127 -0
  102. package/src/stash-ref.ts +84 -26
  103. package/src/stash-registry.ts +259 -0
  104. package/src/stash-resolve.ts +3 -0
  105. package/src/stash-search.ts +425 -155
  106. package/src/stash-show.ts +33 -82
  107. package/src/stash-source.ts +103 -0
  108. package/src/stash-types.ts +186 -1
  109. package/src/stash.ts +23 -0
  110. package/src/tool-runner.ts +18 -5
  111. package/dist/src/similarity.d.ts +0 -34
  112. package/src/similarity.ts +0 -271
@@ -1,27 +1,14 @@
1
1
  import fs from "node:fs";
2
- import path from "node:path";
3
- import { parseFrontmatter, toStringOrUndefined } from "./frontmatter";
4
- import { resolveStashDir } from "./common";
5
- import { parseOpenRef } from "./stash-ref";
2
+ import { parseAssetRef } from "./stash-ref";
3
+ import { resolveSourcesForOrigin } from "./origin-resolve";
6
4
  import { resolveAssetPath } from "./stash-resolve";
7
- import { parseMarkdownToc, extractSection, extractLineRange, extractFrontmatterOnly, formatToc } from "./markdown";
8
- import { buildToolInfo } from "./tool-runner";
9
- import { loadConfig } from "./config";
10
- export function agentikitShow(input) {
11
- const parsed = parseOpenRef(input.ref);
12
- const stashDir = resolveStashDir();
13
- const config = loadConfig(stashDir);
14
- const allStashDirs = [
15
- stashDir,
16
- ...config.additionalStashDirs.filter((d) => {
17
- try {
18
- return fs.statSync(d).isDirectory();
19
- }
20
- catch {
21
- return false;
22
- }
23
- }),
24
- ];
5
+ import { getHandler } from "./asset-type-handler";
6
+ import { resolveStashSources, findSourceForPath } from "./stash-source";
7
+ export async function agentikitShow(input) {
8
+ const parsed = parseAssetRef(input.ref);
9
+ const allSources = resolveStashSources();
10
+ const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
11
+ const allStashDirs = searchSources.map((s) => s.path);
25
12
  let assetPath;
26
13
  let lastError;
27
14
  for (const dir of allStashDirs) {
@@ -33,75 +20,27 @@ export function agentikitShow(input) {
33
20
  lastError = err instanceof Error ? err : new Error(String(err));
34
21
  }
35
22
  }
23
+ if (!assetPath && parsed.origin && searchSources.length === 0) {
24
+ const installCmd = `akm add ${parsed.origin}`;
25
+ throw new Error(`Stash asset not found for ref: ${parsed.type}:${parsed.name}. ` +
26
+ `Kit "${parsed.origin}" is not installed. Run: ${installCmd}`);
27
+ }
36
28
  if (!assetPath) {
37
29
  throw lastError ?? new Error(`Stash asset not found for ref: ${parsed.type}:${parsed.name}`);
38
30
  }
39
31
  const content = fs.readFileSync(assetPath, "utf8");
40
- switch (parsed.type) {
41
- case "skill":
42
- return {
43
- type: "skill",
44
- name: parsed.name,
45
- path: assetPath,
46
- content,
47
- };
48
- case "command": {
49
- const parsedMd = parseFrontmatter(content);
50
- return {
51
- type: "command",
52
- name: parsed.name,
53
- path: assetPath,
54
- description: toStringOrUndefined(parsedMd.data.description),
55
- template: parsedMd.content,
56
- };
57
- }
58
- case "agent": {
59
- const parsedMd = parseFrontmatter(content);
60
- return {
61
- type: "agent",
62
- name: parsed.name,
63
- path: assetPath,
64
- description: toStringOrUndefined(parsedMd.data.description),
65
- prompt: parsedMd.content,
66
- toolPolicy: parsedMd.data.tools,
67
- modelHint: parsedMd.data.model,
68
- };
69
- }
70
- case "tool": {
71
- const assetStashDir = allStashDirs.find((d) => path.resolve(assetPath).startsWith(path.resolve(d) + path.sep)) ?? stashDir;
72
- const toolInfo = buildToolInfo(assetStashDir, assetPath);
73
- return {
74
- type: "tool",
75
- name: parsed.name,
76
- path: assetPath,
77
- runCmd: toolInfo.runCmd,
78
- kind: toolInfo.kind,
79
- };
80
- }
81
- case "knowledge": {
82
- const v = input.view ?? { mode: "full" };
83
- switch (v.mode) {
84
- case "toc": {
85
- const toc = parseMarkdownToc(content);
86
- return { type: "knowledge", name: parsed.name, path: assetPath, content: formatToc(toc) };
87
- }
88
- case "frontmatter": {
89
- const fm = extractFrontmatterOnly(content);
90
- return { type: "knowledge", name: parsed.name, path: assetPath, content: fm ?? "(no frontmatter)" };
91
- }
92
- case "section": {
93
- const section = extractSection(content, v.heading);
94
- if (!section)
95
- throw new Error(`Section "${v.heading}" not found in ${parsed.name}`);
96
- return { type: "knowledge", name: parsed.name, path: assetPath, content: section.content };
97
- }
98
- case "lines": {
99
- return { type: "knowledge", name: parsed.name, path: assetPath, content: extractLineRange(content, v.start, v.end) };
100
- }
101
- default: {
102
- return { type: "knowledge", name: parsed.name, path: assetPath, content };
103
- }
104
- }
105
- }
106
- }
32
+ const source = findSourceForPath(assetPath, allSources);
33
+ const handler = getHandler(parsed.type);
34
+ const response = handler.buildShowResponse({
35
+ name: parsed.name,
36
+ path: assetPath,
37
+ content,
38
+ view: input.view,
39
+ stashDirs: allStashDirs,
40
+ });
41
+ return {
42
+ ...response,
43
+ registryId: source?.registryId,
44
+ editable: source?.writable ?? false,
45
+ };
107
46
  }
@@ -0,0 +1,24 @@
1
+ export type StashSourceKind = "working" | "mounted" | "installed";
2
+ export interface StashSource {
3
+ kind: StashSourceKind;
4
+ path: string;
5
+ /** For installed sources, the registry entry id */
6
+ registryId?: string;
7
+ /** Whether this source is writable (only working stash) */
8
+ writable: boolean;
9
+ }
10
+ /**
11
+ * Build the ordered list of stash sources:
12
+ * 1. Working stash (writable)
13
+ * 2. Mounted stash dirs (read-only, user-configured)
14
+ * 3. Installed stash dirs (read-only, derived from registry.installed)
15
+ */
16
+ export declare function resolveStashSources(overrideStashDir?: string): StashSource[];
17
+ /**
18
+ * Convenience: returns just the directory paths, preserving priority order.
19
+ */
20
+ export declare function resolveAllStashDirs(overrideStashDir?: string): string[];
21
+ /**
22
+ * Find which source a file path belongs to.
23
+ */
24
+ export declare function findSourceForPath(filePath: string, sources: StashSource[]): StashSource | undefined;
@@ -0,0 +1,81 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { resolveStashDir } from "./common";
4
+ import { loadConfig } from "./config";
5
+ // ── Resolution ──────────────────────────────────────────────────────────────
6
+ /**
7
+ * Build the ordered list of stash sources:
8
+ * 1. Working stash (writable)
9
+ * 2. Mounted stash dirs (read-only, user-configured)
10
+ * 3. Installed stash dirs (read-only, derived from registry.installed)
11
+ */
12
+ export function resolveStashSources(overrideStashDir) {
13
+ const stashDir = overrideStashDir ?? resolveStashDir();
14
+ const config = loadConfig();
15
+ const sources = [
16
+ { kind: "working", path: stashDir, writable: true },
17
+ ];
18
+ for (const dir of config.mountedStashDirs) {
19
+ if (isSuspiciousStashRoot(dir)) {
20
+ console.warn(`Warning: stash root "${dir}" appears to be a system directory. This may be unintentional.`);
21
+ }
22
+ if (isValidDirectory(dir)) {
23
+ sources.push({ kind: "mounted", path: dir, writable: false });
24
+ }
25
+ }
26
+ for (const entry of config.registry?.installed ?? []) {
27
+ if (isSuspiciousStashRoot(entry.stashRoot)) {
28
+ console.warn(`Warning: stash root "${entry.stashRoot}" appears to be a system directory. This may be unintentional.`);
29
+ }
30
+ if (isValidDirectory(entry.stashRoot)) {
31
+ sources.push({
32
+ kind: "installed",
33
+ path: entry.stashRoot,
34
+ registryId: entry.id,
35
+ writable: false,
36
+ });
37
+ }
38
+ }
39
+ return sources;
40
+ }
41
+ /**
42
+ * Convenience: returns just the directory paths, preserving priority order.
43
+ */
44
+ export function resolveAllStashDirs(overrideStashDir) {
45
+ return resolveStashSources(overrideStashDir).map((s) => s.path);
46
+ }
47
+ /**
48
+ * Find which source a file path belongs to.
49
+ */
50
+ export function findSourceForPath(filePath, sources) {
51
+ const resolved = path.resolve(filePath);
52
+ for (const source of sources) {
53
+ if (resolved.startsWith(path.resolve(source.path) + path.sep))
54
+ return source;
55
+ }
56
+ return undefined;
57
+ }
58
+ // ── Validation ──────────────────────────────────────────────────────────────
59
+ const SUSPICIOUS_ROOTS = new Set(['/', '/etc', '/bin', '/sbin', '/usr', '/var', '/tmp', '/dev', '/proc', '/sys']);
60
+ function isSuspiciousStashRoot(dir) {
61
+ const resolved = path.resolve(dir);
62
+ const normalized = process.platform === 'win32' ? resolved.toLowerCase() : resolved;
63
+ if (SUSPICIOUS_ROOTS.has(normalized))
64
+ return true;
65
+ if (process.platform === 'win32') {
66
+ // Check for Windows system directories
67
+ const winDir = (process.env.SystemRoot || 'C:\\Windows').toLowerCase();
68
+ if (normalized === winDir || normalized.startsWith(winDir + path.sep))
69
+ return true;
70
+ }
71
+ return false;
72
+ }
73
+ // ── Helpers ─────────────────────────────────────────────────────────────────
74
+ function isValidDirectory(dir) {
75
+ try {
76
+ return fs.statSync(dir).isDirectory();
77
+ }
78
+ catch {
79
+ return false;
80
+ }
81
+ }
@@ -1,22 +1,58 @@
1
1
  import type { AgentikitAssetType } from "./common";
2
+ import type { RegistrySource } from "./registry-types";
2
3
  import type { ToolKind } from "./tool-runner";
3
4
  export type AgentikitSearchType = AgentikitAssetType | "any";
4
- export interface SearchHit {
5
+ export type SearchUsageMode = "none" | "both" | "item" | "guide";
6
+ export type SearchSource = "local" | "registry" | "both";
7
+ export interface LocalSearchHit {
8
+ hitSource: "local";
5
9
  type: AgentikitAssetType;
6
10
  name: string;
7
11
  path: string;
8
12
  openRef: string;
13
+ /** For installed sources, the registry id */
14
+ registryId?: string;
15
+ /** Whether this asset is editable (only true for working stash) */
16
+ editable?: boolean;
9
17
  description?: string;
10
18
  tags?: string[];
11
19
  score?: number;
12
20
  whyMatched?: string[];
13
21
  runCmd?: string;
14
22
  kind?: ToolKind;
23
+ usage?: string[];
15
24
  }
25
+ export interface RegistrySearchResultHit {
26
+ hitSource: "registry";
27
+ type: "registry";
28
+ name: string;
29
+ path?: string;
30
+ openRef?: string;
31
+ id: string;
32
+ registrySource: RegistrySource;
33
+ ref: string;
34
+ description?: string;
35
+ tags?: string[];
36
+ homepage?: string;
37
+ score?: number;
38
+ whyMatched?: string[];
39
+ runCmd?: string;
40
+ kind?: ToolKind;
41
+ usage?: string[];
42
+ metadata?: Record<string, string>;
43
+ installRef: string;
44
+ installCmd: string;
45
+ /** Whether this entry was manually reviewed and approved */
46
+ curated?: boolean;
47
+ }
48
+ export type SearchHit = LocalSearchHit | RegistrySearchResultHit;
16
49
  export interface SearchResponse {
17
50
  stashDir: string;
51
+ source: SearchSource;
18
52
  hits: SearchHit[];
53
+ usageGuide?: Partial<Record<AgentikitAssetType, string[]>>;
19
54
  tip?: string;
55
+ warnings?: string[];
20
56
  /** Timing counters in milliseconds */
21
57
  timing?: {
22
58
  totalMs: number;
@@ -24,6 +60,140 @@ export interface SearchResponse {
24
60
  embedMs?: number;
25
61
  };
26
62
  }
63
+ export interface AddResponse {
64
+ stashDir: string;
65
+ ref: string;
66
+ installed: {
67
+ id: string;
68
+ source: RegistrySource;
69
+ ref: string;
70
+ artifactUrl: string;
71
+ resolvedVersion?: string;
72
+ resolvedRevision?: string;
73
+ stashRoot: string;
74
+ cacheDir: string;
75
+ extractedDir: string;
76
+ installedAt: string;
77
+ };
78
+ config: {
79
+ mountedStashDirs: string[];
80
+ installedRegistryCount: number;
81
+ };
82
+ index: {
83
+ mode: "full" | "incremental";
84
+ totalEntries: number;
85
+ directoriesScanned: number;
86
+ directoriesSkipped: number;
87
+ };
88
+ }
89
+ export interface RegistryInstallStatus {
90
+ id: string;
91
+ source: RegistrySource;
92
+ ref: string;
93
+ artifactUrl: string;
94
+ resolvedVersion?: string;
95
+ resolvedRevision?: string;
96
+ stashRoot: string;
97
+ cacheDir: string;
98
+ extractedDir: string;
99
+ installedAt: string;
100
+ }
101
+ export interface RegistryListEntry {
102
+ id: string;
103
+ source: RegistrySource;
104
+ ref: string;
105
+ artifactUrl: string;
106
+ resolvedVersion?: string;
107
+ resolvedRevision?: string;
108
+ stashRoot: string;
109
+ cacheDir: string;
110
+ installedAt: string;
111
+ status: {
112
+ cacheDirExists: boolean;
113
+ stashRootExists: boolean;
114
+ };
115
+ }
116
+ export interface ListResponse {
117
+ stashDir: string;
118
+ installed: RegistryListEntry[];
119
+ totalInstalled: number;
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
+ mountedStashDirs: string[];
133
+ installedRegistryCount: number;
134
+ };
135
+ index: {
136
+ mode: "full" | "incremental";
137
+ totalEntries: number;
138
+ directoriesScanned: number;
139
+ directoriesSkipped: number;
140
+ };
141
+ }
142
+ export interface ReinstallResultItem {
143
+ id: string;
144
+ source: RegistrySource;
145
+ ref: string;
146
+ previousCacheDir: string;
147
+ installed: RegistryInstallStatus;
148
+ }
149
+ export interface ReinstallResponse {
150
+ stashDir: string;
151
+ target?: string;
152
+ all: boolean;
153
+ processed: ReinstallResultItem[];
154
+ config: {
155
+ mountedStashDirs: string[];
156
+ installedRegistryCount: number;
157
+ };
158
+ index: {
159
+ mode: "full" | "incremental";
160
+ totalEntries: number;
161
+ directoriesScanned: number;
162
+ directoriesSkipped: number;
163
+ };
164
+ }
165
+ export interface UpdateResultItem {
166
+ id: string;
167
+ source: RegistrySource;
168
+ ref: string;
169
+ previous: {
170
+ resolvedVersion?: string;
171
+ resolvedRevision?: string;
172
+ cacheDir: string;
173
+ };
174
+ installed: RegistryInstallStatus;
175
+ changed: {
176
+ version: boolean;
177
+ revision: boolean;
178
+ any: boolean;
179
+ };
180
+ }
181
+ export interface UpdateResponse {
182
+ stashDir: string;
183
+ target?: string;
184
+ all: boolean;
185
+ processed: UpdateResultItem[];
186
+ config: {
187
+ mountedStashDirs: string[];
188
+ installedRegistryCount: number;
189
+ };
190
+ index: {
191
+ mode: "full" | "incremental";
192
+ totalEntries: number;
193
+ directoriesScanned: number;
194
+ directoriesSkipped: number;
195
+ };
196
+ }
27
197
  export interface ShowResponse {
28
198
  type: AgentikitAssetType;
29
199
  name: string;
@@ -36,6 +206,10 @@ export interface ShowResponse {
36
206
  modelHint?: unknown;
37
207
  runCmd?: string;
38
208
  kind?: ToolKind;
209
+ /** For installed sources, the registry id */
210
+ registryId?: string;
211
+ /** Whether this asset is editable (only true for working stash) */
212
+ editable?: boolean;
39
213
  }
40
214
  export type KnowledgeView = {
41
215
  mode: "full";
@@ -3,6 +3,14 @@ export { resolveStashDir } from "./common";
3
3
  export { agentikitInit } from "./init";
4
4
  export type { InitResponse } from "./init";
5
5
  export type { ToolKind } from "./tool-runner";
6
+ export type { AssetTypeHandler, ShowInput } from "./asset-type-handler";
7
+ export { registerAssetType, getHandler, getAllHandlers, getRegisteredTypeNames } from "./asset-type-handler";
6
8
  export { agentikitSearch } from "./stash-search";
7
9
  export { agentikitShow } from "./stash-show";
8
- export type { AgentikitSearchType, SearchHit, SearchResponse, ShowResponse, KnowledgeView, } from "./stash-types";
10
+ export { agentikitAdd } from "./stash-add";
11
+ export { agentikitClone } from "./stash-clone";
12
+ export { agentikitList, agentikitRemove, agentikitReinstall, agentikitUpdate } from "./stash-registry";
13
+ export { resolveStashSources, resolveAllStashDirs, findSourceForPath } from "./stash-source";
14
+ export type { StashSource, StashSourceKind } from "./stash-source";
15
+ export type { AddResponse, AgentikitSearchType, LocalSearchHit, RegistrySearchResultHit, SearchSource, SearchUsageMode, SearchHit, SearchResponse, ShowResponse, KnowledgeView, ListResponse, RemoveResponse, ReinstallResponse, UpdateResponse, RegistryListEntry, RegistryInstallStatus, ReinstallResultItem, UpdateResultItem, } from "./stash-types";
16
+ export type { CloneOptions, CloneResponse } from "./stash-clone";
package/dist/src/stash.js CHANGED
@@ -1,4 +1,9 @@
1
1
  export { resolveStashDir } from "./common";
2
2
  export { agentikitInit } from "./init";
3
+ export { registerAssetType, getHandler, getAllHandlers, getRegisteredTypeNames } from "./asset-type-handler";
3
4
  export { agentikitSearch } from "./stash-search";
4
5
  export { agentikitShow } from "./stash-show";
6
+ export { agentikitAdd } from "./stash-add";
7
+ export { agentikitClone } from "./stash-clone";
8
+ export { agentikitList, agentikitRemove, agentikitReinstall, agentikitUpdate } from "./stash-registry";
9
+ export { resolveStashSources, resolveAllStashDirs, findSourceForPath } from "./stash-source";
@@ -22,7 +22,7 @@ export interface ToolInfo {
22
22
  *
23
23
  * For `.ts` / `.js` files, looks up the nearest `package.json` so that
24
24
  * `bun install` can be run in the correct working directory when the
25
- * `AGENTIKIT_BUN_INSTALL` env flag is set.
25
+ * `AKM_BUN_INSTALL` env flag is set.
26
26
  */
27
27
  export declare function buildToolInfo(stashDir: string, filePath: string): ToolInfo;
28
28
  /**
@@ -13,7 +13,7 @@ import { IS_WINDOWS, isWithin } from "./common";
13
13
  *
14
14
  * For `.ts` / `.js` files, looks up the nearest `package.json` so that
15
15
  * `bun install` can be run in the correct working directory when the
16
- * `AGENTIKIT_BUN_INSTALL` env flag is set.
16
+ * `AKM_BUN_INSTALL` env flag is set.
17
17
  */
18
18
  export function buildToolInfo(stashDir, filePath) {
19
19
  const ext = path.extname(filePath).toLowerCase();
@@ -41,8 +41,17 @@ export function buildToolInfo(stashDir, filePath) {
41
41
  if (ext !== ".ts" && ext !== ".js") {
42
42
  throw new Error(`Unsupported tool extension: ${ext}`);
43
43
  }
44
- const toolsRoot = path.resolve(path.join(stashDir, "tools"));
45
- const pkgDir = findNearestPackageDir(path.dirname(filePath), toolsRoot);
44
+ // Determine the type root by checking which subdirectory contains the file
45
+ const resolvedFile = path.resolve(filePath);
46
+ let typeRoot = path.resolve(path.join(stashDir, "tools"));
47
+ for (const subdir of ["tools", "scripts"]) {
48
+ const candidate = path.resolve(path.join(stashDir, subdir));
49
+ if (resolvedFile.startsWith(candidate + path.sep)) {
50
+ typeRoot = candidate;
51
+ break;
52
+ }
53
+ }
54
+ const pkgDir = findNearestPackageDir(path.dirname(filePath), typeRoot);
46
55
  if (!pkgDir) {
47
56
  return {
48
57
  runCmd: `bun ${shellQuote(filePath)}`,
@@ -50,7 +59,7 @@ export function buildToolInfo(stashDir, filePath) {
50
59
  execute: { command: "bun", args: [filePath] },
51
60
  };
52
61
  }
53
- const installFlag = process.env.AGENTIKIT_BUN_INSTALL;
62
+ const installFlag = process.env.AKM_BUN_INSTALL;
54
63
  const shouldInstall = installFlag === "1" || installFlag === "true" || installFlag === "yes";
55
64
  const quotedPkgDir = shellQuote(pkgDir);
56
65
  const quotedFilePath = shellQuote(filePath);
@@ -73,7 +82,11 @@ export function shellQuote(input) {
73
82
  throw new Error("Unsupported control characters in stash path.");
74
83
  }
75
84
  if (IS_WINDOWS) {
76
- return `"${input.replace(/"/g, '""')}"`;
85
+ const escaped = input
86
+ .replace(/%/g, "%%")
87
+ .replace(/([\\^|&<>])/g, "^$1")
88
+ .replace(/"/g, '""');
89
+ return `"${escaped}"`;
77
90
  }
78
91
  const escaped = input
79
92
  .replace(/\\/g, "\\\\")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentikit",
3
- "version": "0.0.8",
3
+ "version": "0.0.12",
4
4
  "type": "module",
5
5
  "description": "CLI tool to search, open, and run extension assets from an agentikit stash directory.",
6
6
  "keywords": [
@@ -49,10 +49,15 @@
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^24.0.0",
52
+ "bun-types": "^1.3.10",
52
53
  "typescript": "^5.9.3"
53
54
  },
54
55
  "optionalDependencies": {
55
- "@xenova/transformers": "^2.17.0"
56
+ "@xenova/transformers": "^2.17.0",
57
+ "sqlite-vec": "^0.1.7-alpha.2"
58
+ },
59
+ "engines": {
60
+ "bun": ">=1.0.0"
56
61
  },
57
62
  "dependencies": {
58
63
  "citty": "^0.2.1"
package/src/asset-spec.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import path from "node:path"
2
2
  import type { AgentikitAssetType } from "./common"
3
+ import { toPosix } from "./common"
4
+ import { tryGetHandler } from "./asset-type-handler"
3
5
 
4
6
  export const SCRIPT_EXTENSIONS = new Set([".sh", ".ts", ".js", ".ps1", ".cmd", ".bat"])
5
7
 
@@ -16,6 +18,12 @@ const markdownSpec: Omit<AssetSpec, "stashDir"> = {
16
18
  toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
17
19
  }
18
20
 
21
+ /** Extended set of script extensions for the script asset type */
22
+ export const SCRIPT_EXTENSIONS_BROAD = new Set([
23
+ ...SCRIPT_EXTENSIONS,
24
+ ".py", ".rb", ".go", ".pl", ".php", ".lua", ".r", ".swift", ".kt", ".kts",
25
+ ])
26
+
19
27
  export const ASSET_SPECS: Record<AgentikitAssetType, AssetSpec> = {
20
28
  tool: {
21
29
  stashDir: "tools",
@@ -36,6 +44,12 @@ export const ASSET_SPECS: Record<AgentikitAssetType, AssetSpec> = {
36
44
  command: { stashDir: "commands", ...markdownSpec },
37
45
  agent: { stashDir: "agents", ...markdownSpec },
38
46
  knowledge: { stashDir: "knowledge", ...markdownSpec },
47
+ script: {
48
+ stashDir: "scripts",
49
+ isRelevantFile: (fileName) => SCRIPT_EXTENSIONS_BROAD.has(path.extname(fileName).toLowerCase()),
50
+ toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
51
+ toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
52
+ },
39
53
  }
40
54
 
41
55
  export const ASSET_TYPES = Object.keys(ASSET_SPECS) as AgentikitAssetType[]
@@ -49,6 +63,8 @@ export const TYPE_DIRS: Record<AgentikitAssetType, string> = ASSET_TYPES.reduce(
49
63
  )
50
64
 
51
65
  export function isRelevantAssetFile(assetType: AgentikitAssetType, fileName: string): boolean {
66
+ const handler = tryGetHandler(assetType)
67
+ if (handler) return handler.isRelevantFile(fileName)
52
68
  return ASSET_SPECS[assetType].isRelevantFile(fileName)
53
69
  }
54
70
 
@@ -57,13 +73,13 @@ export function deriveCanonicalAssetName(
57
73
  typeRoot: string,
58
74
  filePath: string,
59
75
  ): string | undefined {
76
+ const handler = tryGetHandler(assetType)
77
+ if (handler) return handler.toCanonicalName(typeRoot, filePath)
60
78
  return ASSET_SPECS[assetType].toCanonicalName(typeRoot, filePath)
61
79
  }
62
80
 
63
81
  export function resolveAssetPathFromName(assetType: AgentikitAssetType, typeRoot: string, name: string): string {
82
+ const handler = tryGetHandler(assetType)
83
+ if (handler) return handler.toAssetPath(typeRoot, name)
64
84
  return ASSET_SPECS[assetType].toAssetPath(typeRoot, name)
65
85
  }
66
-
67
- function toPosix(input: string): string {
68
- return input.replace(/\\/g, "/")
69
- }