agentikit 0.0.3 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -77
- package/dist/index.d.ts +15 -3
- package/dist/index.js +8 -2
- package/dist/src/asset-spec.d.ts +14 -0
- package/dist/src/asset-spec.js +46 -0
- package/dist/src/cli.js +154 -52
- package/dist/src/common.d.ts +8 -0
- package/dist/src/common.js +46 -0
- package/dist/src/config.d.ts +31 -0
- package/dist/src/config.js +74 -0
- package/dist/src/embedder.d.ts +10 -0
- package/dist/src/embedder.js +87 -0
- package/dist/src/frontmatter.d.ts +30 -0
- package/dist/src/frontmatter.js +86 -0
- package/dist/src/indexer.d.ts +20 -2
- package/dist/src/indexer.js +212 -80
- package/dist/src/init.d.ts +19 -0
- package/dist/src/init.js +87 -0
- package/dist/src/llm.d.ts +15 -0
- package/dist/src/llm.js +91 -0
- package/dist/src/markdown.d.ts +18 -0
- package/dist/src/markdown.js +77 -0
- package/dist/src/metadata.d.ts +10 -2
- package/dist/src/metadata.js +146 -30
- package/dist/src/ripgrep-install.d.ts +12 -0
- package/dist/src/ripgrep-install.js +169 -0
- package/dist/src/ripgrep-resolve.d.ts +13 -0
- package/dist/src/ripgrep-resolve.js +68 -0
- package/dist/src/ripgrep.d.ts +3 -0
- package/dist/src/ripgrep.js +2 -0
- package/dist/src/similarity.d.ts +1 -2
- package/dist/src/similarity.js +35 -9
- package/dist/src/stash-ref.d.ts +7 -0
- package/dist/src/stash-ref.js +33 -0
- package/dist/src/stash-resolve.d.ts +2 -0
- package/dist/src/stash-resolve.js +45 -0
- package/dist/src/stash-search.d.ts +6 -0
- package/dist/src/stash-search.js +269 -0
- package/dist/src/stash-show.d.ts +5 -0
- package/dist/src/stash-show.js +107 -0
- package/dist/src/stash-types.d.ts +53 -0
- package/dist/src/stash-types.js +1 -0
- package/dist/src/stash.d.ts +8 -58
- package/dist/src/stash.js +4 -580
- package/dist/src/tool-runner.d.ts +35 -0
- package/dist/src/tool-runner.js +100 -0
- package/dist/src/walker.d.ts +19 -0
- package/dist/src/walker.js +47 -0
- package/package.json +8 -14
- package/src/asset-spec.ts +69 -0
- package/src/cli.ts +164 -48
- package/src/common.ts +58 -0
- package/src/config.ts +124 -0
- package/src/embedder.ts +117 -0
- package/src/frontmatter.ts +95 -0
- package/src/indexer.ts +244 -84
- package/src/init.ts +106 -0
- package/src/llm.ts +124 -0
- package/src/markdown.ts +106 -0
- package/src/metadata.ts +157 -29
- package/src/ripgrep-install.ts +200 -0
- package/src/ripgrep-resolve.ts +72 -0
- package/src/ripgrep.ts +3 -0
- package/src/similarity.ts +33 -9
- package/src/stash-ref.ts +41 -0
- package/src/stash-resolve.ts +47 -0
- package/src/stash-search.ts +343 -0
- package/src/stash-show.ts +104 -0
- package/src/stash-types.ts +46 -0
- package/src/stash.ts +16 -695
- package/src/tool-runner.ts +129 -0
- package/src/walker.ts +53 -0
- package/.claude-plugin/plugin.json +0 -21
- package/commands/open.md +0 -11
- package/commands/run.md +0 -11
- package/commands/search.md +0 -11
- package/dist/src/plugin.d.ts +0 -2
- package/dist/src/plugin.js +0 -55
- package/skills/stash/SKILL.md +0 -68
- package/src/plugin.ts +0 -56
package/README.md
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
# agentikit
|
|
2
2
|
|
|
3
|
-
Agentikit is a stash
|
|
3
|
+
Agentikit is a CLI tool and library for managing a stash of extension assets for AI coding assistants. It lets you **search** and **show** tools, skills, commands, and agents from a stash directory.
|
|
4
|
+
|
|
5
|
+
The CLI is called **akm** (Agentikit Manager).
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
7
9
|
### npm / bun
|
|
8
10
|
|
|
9
11
|
```sh
|
|
10
|
-
npm install
|
|
12
|
+
npm install -g agentikit
|
|
11
13
|
# or
|
|
12
|
-
bun add
|
|
14
|
+
bun add -g agentikit
|
|
13
15
|
```
|
|
14
16
|
|
|
15
17
|
### Standalone binary
|
|
@@ -17,131 +19,165 @@ bun add @itlackey/agentikit
|
|
|
17
19
|
Use the install scripts for a copy/paste install:
|
|
18
20
|
|
|
19
21
|
```sh
|
|
20
|
-
# macOS / Linux
|
|
22
|
+
# macOS / Linux
|
|
23
|
+
curl -fsSL https://raw.githubusercontent.com/itlackey/agentikit/main/install.sh | bash
|
|
24
|
+
# pin a release tag)
|
|
21
25
|
curl -fsSL https://raw.githubusercontent.com/itlackey/agentikit/main/install.sh | bash -s -- v1.2.3
|
|
22
|
-
```
|
|
23
26
|
|
|
24
|
-
```sh
|
|
25
27
|
# PowerShell (Windows)
|
|
26
|
-
irm https://raw.githubusercontent.com/itlackey/agentikit/main/install.ps1 -OutFile install.ps1; ./install.ps1
|
|
28
|
+
irm https://raw.githubusercontent.com/itlackey/agentikit/main/install.ps1 -OutFile install.ps1; ./install.ps1
|
|
27
29
|
```
|
|
28
30
|
|
|
29
31
|
The shell installer verifies the downloaded binary against release `checksums.txt` before installing it.
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
## Stash model
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
Set a stash path via `AGENTIKIT_STASH_DIR`, or run `akm init` to create one automatically.
|
|
34
36
|
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
"plugin": ["@itlackey/agentikit"]
|
|
38
|
-
}
|
|
37
|
+
```sh
|
|
38
|
+
export AGENTIKIT_STASH_DIR=/abs/path/to/your-stash
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Expected stash layout:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
$AGENTIKIT_STASH_DIR/
|
|
45
|
+
├── tools/ # recursive files (.sh, .ts, .js, .ps1, .cmd, .bat)
|
|
46
|
+
├── skills/ # skill directories containing SKILL.md
|
|
47
|
+
├── commands/ # markdown files
|
|
48
|
+
├── agents/ # markdown files
|
|
49
|
+
└── knowledge/ # markdown files
|
|
50
|
+
```
|
|
42
51
|
|
|
43
|
-
|
|
52
|
+
## CLI usage
|
|
44
53
|
|
|
45
54
|
```sh
|
|
46
|
-
|
|
55
|
+
akm init # Initialize stash directory and set AGENTIKIT_STASH_DIR
|
|
56
|
+
akm index [--full] # Build search index (incremental by default)
|
|
57
|
+
akm search [query] # Search the stash
|
|
58
|
+
akm show <type:name> # Read a stash asset by ref
|
|
47
59
|
```
|
|
48
60
|
|
|
49
|
-
|
|
61
|
+
### search
|
|
50
62
|
|
|
51
|
-
|
|
63
|
+
Search the stash for extension assets.
|
|
52
64
|
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
```sh
|
|
66
|
+
akm search "deploy" --type tool --limit 10
|
|
67
|
+
```
|
|
55
68
|
|
|
56
|
-
|
|
69
|
+
- `query`: case-insensitive substring over stable names (relative paths)
|
|
70
|
+
- `--type`: `tool | skill | command | agent | knowledge | any` (default: `any`)
|
|
71
|
+
- `--limit`: defaults to `20`
|
|
72
|
+
|
|
73
|
+
Returns typed hits with `openRef`, score/explainability details (`score`, `whyMatched`), and, for tools, execution-ready `runCmd`.
|
|
57
74
|
|
|
58
|
-
|
|
75
|
+
### show
|
|
76
|
+
|
|
77
|
+
Show a hit using `openRef` from search results.
|
|
59
78
|
|
|
60
79
|
```sh
|
|
61
|
-
|
|
80
|
+
akm show skill:code-review
|
|
81
|
+
akm show knowledge:guide.md --view toc
|
|
82
|
+
akm show knowledge:guide.md --view section --heading "Getting Started"
|
|
83
|
+
akm show knowledge:guide.md --view lines --start 10 --end 30
|
|
62
84
|
```
|
|
63
85
|
|
|
64
|
-
|
|
86
|
+
Returns full payload by type:
|
|
65
87
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
88
|
+
- `skill` — full `SKILL.md` content
|
|
89
|
+
- `command` — full markdown body as `template` (+ best-effort `description`)
|
|
90
|
+
- `agent` — full markdown body as `prompt` (+ best-effort `description`, `toolPolicy`, `modelHint`)
|
|
91
|
+
- `tool` — `runCmd`/`kind` (the agent uses the host's shell to execute `runCmd`)
|
|
92
|
+
- `knowledge` — content with optional view modes (`full`, `toc`, `frontmatter`, `section`, `lines`)
|
|
93
|
+
|
|
94
|
+
## Library API
|
|
95
|
+
|
|
96
|
+
Agentikit also exports its core functions for use as a library:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { agentikitSearch, agentikitShow, agentikitInit, agentikitIndex } from "agentikit"
|
|
72
100
|
```
|
|
73
101
|
|
|
74
|
-
|
|
102
|
+
- `agentikitSearch({ query, type?, limit? })` — search the stash
|
|
103
|
+
- `agentikitShow({ ref, view? })` — show a stash asset
|
|
104
|
+
- `agentikitInit()` — initialize stash directory
|
|
105
|
+
- `agentikitIndex()` — build/rebuild search index
|
|
75
106
|
|
|
76
|
-
|
|
107
|
+
## Configuration
|
|
77
108
|
|
|
78
|
-
|
|
79
|
-
- `agentikit_open({ ref })`
|
|
80
|
-
- `agentikit_run({ ref })`
|
|
109
|
+
Agentikit stores configuration in `config.json` inside the stash directory.
|
|
81
110
|
|
|
82
|
-
|
|
111
|
+
```sh
|
|
112
|
+
akm config # Show current config
|
|
113
|
+
akm config --set key=value # Update a config key
|
|
114
|
+
```
|
|
83
115
|
|
|
84
|
-
|
|
116
|
+
### Embedding connection
|
|
85
117
|
|
|
86
|
-
|
|
87
|
-
- `type`: `tool | skill | command | agent | any` (default: `any`)
|
|
88
|
-
- `limit`: defaults to `20`
|
|
118
|
+
By default, agentikit uses the local `@xenova/transformers` library for embeddings. You can configure an OpenAI-compatible embedding endpoint instead:
|
|
89
119
|
|
|
90
|
-
|
|
120
|
+
```sh
|
|
121
|
+
akm config --set 'embedding={"endpoint":"http://localhost:11434/v1/embeddings","model":"nomic-embed-text"}'
|
|
122
|
+
```
|
|
91
123
|
|
|
92
|
-
|
|
124
|
+
To clear the custom embedding config and revert to local embeddings:
|
|
93
125
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
- `.ts`/`.js`:
|
|
98
|
-
- find nearest `package.json` from script dir upward to stash `tools/` root
|
|
99
|
-
- if found: `cd "<pkgDir>" && bun "<absolute-file>"`
|
|
100
|
-
- else: `bun "<absolute-file>"`
|
|
101
|
-
- optional: set `AGENTIKIT_BUN_INSTALL=true` to include `bun install` before running
|
|
126
|
+
```sh
|
|
127
|
+
akm config --set 'embedding=null'
|
|
128
|
+
```
|
|
102
129
|
|
|
103
|
-
###
|
|
130
|
+
### LLM connection
|
|
104
131
|
|
|
105
|
-
|
|
132
|
+
When configured, agentikit uses an OpenAI-compatible LLM to generate richer metadata (descriptions, intents, tags) during indexing:
|
|
106
133
|
|
|
107
|
-
|
|
134
|
+
```sh
|
|
135
|
+
akm config --set 'llm={"endpoint":"http://localhost:11434/v1/chat/completions","model":"llama3.2"}'
|
|
136
|
+
```
|
|
108
137
|
|
|
109
|
-
|
|
110
|
-
- `command` → full markdown body as `template` (+ best-effort `description`)
|
|
111
|
-
- `agent` → full markdown body as `prompt` (+ best-effort `description`, `toolPolicy`, `modelHint`)
|
|
112
|
-
- `tool` → `runCmd`/`kind`
|
|
138
|
+
To clear:
|
|
113
139
|
|
|
114
|
-
|
|
140
|
+
```sh
|
|
141
|
+
akm config --set 'llm=null'
|
|
142
|
+
```
|
|
115
143
|
|
|
116
|
-
|
|
144
|
+
### Using a local Ollama instance
|
|
117
145
|
|
|
118
|
-
-
|
|
146
|
+
[Ollama](https://ollama.com) provides local models with an OpenAI-compatible API. After installing Ollama and pulling your models:
|
|
119
147
|
|
|
120
|
-
|
|
148
|
+
```sh
|
|
149
|
+
# Pull models
|
|
150
|
+
ollama pull nomic-embed-text
|
|
151
|
+
ollama pull llama3.2
|
|
121
152
|
|
|
122
|
-
|
|
153
|
+
# Configure agentikit to use Ollama for both embeddings and metadata generation
|
|
154
|
+
akm config --set 'embedding={"endpoint":"http://localhost:11434/v1/embeddings","model":"nomic-embed-text"}'
|
|
155
|
+
akm config --set 'llm={"endpoint":"http://localhost:11434/v1/chat/completions","model":"llama3.2"}'
|
|
123
156
|
|
|
124
|
-
|
|
125
|
-
|
|
157
|
+
# Rebuild the index — embeddings use Ollama, metadata is LLM-enhanced
|
|
158
|
+
akm index --full
|
|
159
|
+
```
|
|
126
160
|
|
|
127
|
-
|
|
161
|
+
Both `embedding` and `llm` accept an optional `apiKey` field for authenticated endpoints:
|
|
128
162
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"endpoint": "https://api.openai.com/v1/embeddings",
|
|
166
|
+
"model": "text-embedding-3-small",
|
|
167
|
+
"apiKey": "sk-..."
|
|
168
|
+
}
|
|
169
|
+
```
|
|
132
170
|
|
|
133
|
-
|
|
171
|
+
### Config reference
|
|
134
172
|
|
|
135
|
-
|
|
136
|
-
|
|
173
|
+
| Key | Type | Default | Description |
|
|
174
|
+
|-----|------|---------|-------------|
|
|
175
|
+
| `semanticSearch` | `boolean` | `true` | Enable semantic search ranking |
|
|
176
|
+
| `additionalStashDirs` | `string[]` | `[]` | Extra stash directories to search |
|
|
177
|
+
| `embedding` | `object` | not set | OpenAI-compatible embedding endpoint (`endpoint`, `model`, `apiKey?`) |
|
|
178
|
+
| `llm` | `object` | not set | OpenAI-compatible LLM endpoint (`endpoint`, `model`, `apiKey?`) |
|
|
137
179
|
|
|
138
180
|
## Notes
|
|
139
181
|
|
|
140
|
-
- Agentikit does not write to `.opencode/` or `.claude/`.
|
|
141
182
|
- Agentikit does not install or copy kit files.
|
|
142
183
|
- Missing or unreadable stash paths return friendly errors.
|
|
143
|
-
|
|
144
|
-
## Docs
|
|
145
|
-
|
|
146
|
-
- **OpenCode**: [Plugins](https://opencode.ai/docs/plugins/) · [Commands](https://opencode.ai/docs/commands/) · [Agents](https://opencode.ai/docs/agents/) · [Agent Skills](https://opencode.ai/docs/skills/) · [Custom tools](https://opencode.ai/docs/custom-tools/) · [Config](https://opencode.ai/docs/config/)
|
|
147
|
-
- **Claude Code**: [Plugins](https://code.claude.com/docs/en/plugins) · [Skills](https://code.claude.com/docs/en/skills) · [Plugins reference](https://code.claude.com/docs/en/plugins-reference)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export type {
|
|
1
|
+
export { agentikitSearch, agentikitShow } from "./src/stash";
|
|
2
|
+
export { agentikitInit } from "./src/init";
|
|
3
|
+
export type { InitResponse } from "./src/init";
|
|
4
|
+
export type { AgentikitAssetType, AgentikitSearchType, SearchHit, SearchResponse, ShowResponse, KnowledgeView, } from "./src/stash";
|
|
5
|
+
export type { ToolKind } from "./src/tool-runner";
|
|
4
6
|
export { agentikitIndex } from "./src/indexer";
|
|
5
7
|
export type { IndexResponse } from "./src/indexer";
|
|
6
8
|
export type { StashEntry, StashFile, StashIntent } from "./src/metadata";
|
|
9
|
+
export { resolveRg, isRgAvailable, ensureRg } from "./src/ripgrep";
|
|
10
|
+
export type { EnsureRgResult } from "./src/ripgrep";
|
|
11
|
+
export { parseMarkdownToc, extractSection, extractLineRange, extractFrontmatterOnly, formatToc } from "./src/markdown";
|
|
12
|
+
export type { TocHeading, KnowledgeToc } from "./src/markdown";
|
|
13
|
+
export { parseFrontmatter } from "./src/frontmatter";
|
|
14
|
+
export { loadConfig, saveConfig, updateConfig } from "./src/config";
|
|
15
|
+
export type { AgentikitConfig, EmbeddingConnectionConfig, LlmConnectionConfig } from "./src/config";
|
|
16
|
+
export { enhanceMetadata, isLlmAvailable } from "./src/llm";
|
|
17
|
+
export { embed, cosineSimilarity, isEmbeddingAvailable } from "./src/embedder";
|
|
18
|
+
export type { EmbeddingVector } from "./src/embedder";
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { agentikitSearch, agentikitShow } from "./src/stash";
|
|
2
|
+
export { agentikitInit } from "./src/init";
|
|
3
3
|
export { agentikitIndex } from "./src/indexer";
|
|
4
|
+
export { resolveRg, isRgAvailable, ensureRg } from "./src/ripgrep";
|
|
5
|
+
export { parseMarkdownToc, extractSection, extractLineRange, extractFrontmatterOnly, formatToc } from "./src/markdown";
|
|
6
|
+
export { parseFrontmatter } from "./src/frontmatter";
|
|
7
|
+
export { loadConfig, saveConfig, updateConfig } from "./src/config";
|
|
8
|
+
export { enhanceMetadata, isLlmAvailable } from "./src/llm";
|
|
9
|
+
export { embed, cosineSimilarity, isEmbeddingAvailable } from "./src/embedder";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AgentikitAssetType } from "./common";
|
|
2
|
+
export declare const SCRIPT_EXTENSIONS: Set<string>;
|
|
3
|
+
export interface AssetSpec {
|
|
4
|
+
stashDir: string;
|
|
5
|
+
isRelevantFile: (fileName: string) => boolean;
|
|
6
|
+
toCanonicalName: (typeRoot: string, filePath: string) => string | undefined;
|
|
7
|
+
toAssetPath: (typeRoot: string, name: string) => string;
|
|
8
|
+
}
|
|
9
|
+
export declare const ASSET_SPECS: Record<AgentikitAssetType, AssetSpec>;
|
|
10
|
+
export declare const ASSET_TYPES: AgentikitAssetType[];
|
|
11
|
+
export declare const TYPE_DIRS: Record<AgentikitAssetType, string>;
|
|
12
|
+
export declare function isRelevantAssetFile(assetType: AgentikitAssetType, fileName: string): boolean;
|
|
13
|
+
export declare function deriveCanonicalAssetName(assetType: AgentikitAssetType, typeRoot: string, filePath: string): string | undefined;
|
|
14
|
+
export declare function resolveAssetPathFromName(assetType: AgentikitAssetType, typeRoot: string, name: string): string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
export const SCRIPT_EXTENSIONS = new Set([".sh", ".ts", ".js", ".ps1", ".cmd", ".bat"]);
|
|
3
|
+
const markdownSpec = {
|
|
4
|
+
isRelevantFile: (fileName) => path.extname(fileName).toLowerCase() === ".md",
|
|
5
|
+
toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
|
|
6
|
+
toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
|
|
7
|
+
};
|
|
8
|
+
export const ASSET_SPECS = {
|
|
9
|
+
tool: {
|
|
10
|
+
stashDir: "tools",
|
|
11
|
+
isRelevantFile: (fileName) => SCRIPT_EXTENSIONS.has(path.extname(fileName).toLowerCase()),
|
|
12
|
+
toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
|
|
13
|
+
toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
|
|
14
|
+
},
|
|
15
|
+
skill: {
|
|
16
|
+
stashDir: "skills",
|
|
17
|
+
isRelevantFile: (fileName) => fileName === "SKILL.md",
|
|
18
|
+
toCanonicalName: (typeRoot, filePath) => {
|
|
19
|
+
const relDir = toPosix(path.dirname(path.relative(typeRoot, filePath)));
|
|
20
|
+
if (!relDir || relDir === ".")
|
|
21
|
+
return undefined;
|
|
22
|
+
return relDir;
|
|
23
|
+
},
|
|
24
|
+
toAssetPath: (typeRoot, name) => path.join(typeRoot, name, "SKILL.md"),
|
|
25
|
+
},
|
|
26
|
+
command: { stashDir: "commands", ...markdownSpec },
|
|
27
|
+
agent: { stashDir: "agents", ...markdownSpec },
|
|
28
|
+
knowledge: { stashDir: "knowledge", ...markdownSpec },
|
|
29
|
+
};
|
|
30
|
+
export const ASSET_TYPES = Object.keys(ASSET_SPECS);
|
|
31
|
+
export const TYPE_DIRS = ASSET_TYPES.reduce((acc, type) => {
|
|
32
|
+
acc[type] = ASSET_SPECS[type].stashDir;
|
|
33
|
+
return acc;
|
|
34
|
+
}, {});
|
|
35
|
+
export function isRelevantAssetFile(assetType, fileName) {
|
|
36
|
+
return ASSET_SPECS[assetType].isRelevantFile(fileName);
|
|
37
|
+
}
|
|
38
|
+
export function deriveCanonicalAssetName(assetType, typeRoot, filePath) {
|
|
39
|
+
return ASSET_SPECS[assetType].toCanonicalName(typeRoot, filePath);
|
|
40
|
+
}
|
|
41
|
+
export function resolveAssetPathFromName(assetType, typeRoot, name) {
|
|
42
|
+
return ASSET_SPECS[assetType].toAssetPath(typeRoot, name);
|
|
43
|
+
}
|
|
44
|
+
function toPosix(input) {
|
|
45
|
+
return input.replace(/\\/g, "/");
|
|
46
|
+
}
|
package/dist/src/cli.js
CHANGED
|
@@ -1,62 +1,164 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { defineCommand, runMain } from "citty";
|
|
3
|
+
import { agentikitSearch, agentikitShow } from "./stash";
|
|
4
|
+
import { agentikitInit } from "./init";
|
|
3
5
|
import { agentikitIndex } from "./indexer";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
function usage() {
|
|
11
|
-
console.error("Usage: agentikit <init|search|open|run> [options]");
|
|
12
|
-
console.error("");
|
|
13
|
-
console.error("Commands:");
|
|
14
|
-
console.error(" init Initialize agentikit stash directory and set AGENTIKIT_STASH_DIR");
|
|
15
|
-
console.error(" index Build search index with metadata generation");
|
|
16
|
-
console.error(" search [query] Search the stash (--type tool|skill|command|agent|any) (--limit N)");
|
|
17
|
-
console.error(" open <type:name> Open a stash asset by ref");
|
|
18
|
-
console.error(" run <type:name> Run a tool by ref");
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
21
|
-
switch (command) {
|
|
22
|
-
case "init": {
|
|
6
|
+
import { loadConfig, updateConfig } from "./config";
|
|
7
|
+
import { resolveStashDir } from "./common";
|
|
8
|
+
const initCommand = defineCommand({
|
|
9
|
+
meta: { name: "init", description: "Initialize agentikit stash directory and set AGENTIKIT_STASH_DIR" },
|
|
10
|
+
run() {
|
|
23
11
|
const result = agentikitInit();
|
|
24
12
|
console.log(JSON.stringify(result, null, 2));
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
const indexCommand = defineCommand({
|
|
16
|
+
meta: { name: "index", description: "Build search index (incremental by default; --full forces full reindex)" },
|
|
17
|
+
args: {
|
|
18
|
+
full: { type: "boolean", description: "Force full reindex", default: false },
|
|
19
|
+
},
|
|
20
|
+
async run({ args }) {
|
|
21
|
+
const result = await agentikitIndex({ full: args.full });
|
|
29
22
|
console.log(JSON.stringify(result, null, 2));
|
|
30
|
-
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
const searchCommand = defineCommand({
|
|
26
|
+
meta: { name: "search", description: "Search the stash" },
|
|
27
|
+
args: {
|
|
28
|
+
query: { type: "positional", description: "Search query", required: false, default: "" },
|
|
29
|
+
type: { type: "string", description: "Asset type filter (tool|skill|command|agent|knowledge|any)" },
|
|
30
|
+
limit: { type: "string", description: "Maximum number of results" },
|
|
31
|
+
},
|
|
32
|
+
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));
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
const showCommand = defineCommand({
|
|
39
|
+
meta: { name: "show", description: "Show a stash asset by ref (e.g. agent:bunjs-typescript-coder.md)" },
|
|
40
|
+
args: {
|
|
41
|
+
ref: { type: "positional", description: "Asset ref (type:name)", required: true },
|
|
42
|
+
view: { type: "string", description: "Knowledge view mode (full|toc|frontmatter|section|lines)" },
|
|
43
|
+
heading: { type: "string", description: "Section heading (for --view section)" },
|
|
44
|
+
start: { type: "string", description: "Start line (for --view lines)" },
|
|
45
|
+
end: { type: "string", description: "End line (for --view lines)" },
|
|
46
|
+
},
|
|
47
|
+
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);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
console.log(JSON.stringify(agentikitShow({ ref: args.ref, view }), null, 2));
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
const configCommand = defineCommand({
|
|
75
|
+
meta: { name: "config", description: "Show or update configuration" },
|
|
76
|
+
args: {
|
|
77
|
+
set: { type: "string", description: "Update a config key (key=value format)" },
|
|
78
|
+
},
|
|
79
|
+
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);
|
|
86
|
+
}
|
|
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
|
+
}
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
const main = defineCommand({
|
|
100
|
+
meta: {
|
|
101
|
+
name: "akm",
|
|
102
|
+
description: "CLI tool to search, open, and run extension assets from an agentikit stash directory.",
|
|
103
|
+
},
|
|
104
|
+
subCommands: {
|
|
105
|
+
init: initCommand,
|
|
106
|
+
index: indexCommand,
|
|
107
|
+
search: searchCommand,
|
|
108
|
+
show: showCommand,
|
|
109
|
+
config: configCommand,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
runMain(main);
|
|
113
|
+
function parseConnectionValue(key, value, exampleEndpoint, exampleModel) {
|
|
114
|
+
if (value === "null" || value === "")
|
|
115
|
+
return undefined;
|
|
116
|
+
let parsed;
|
|
117
|
+
try {
|
|
118
|
+
parsed = JSON.parse(value);
|
|
31
119
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const limitStr = flag("--limit");
|
|
36
|
-
const limit = limitStr ? parseInt(limitStr, 10) : undefined;
|
|
37
|
-
console.log(JSON.stringify(agentikitSearch({ query, type, limit }), null, 2));
|
|
38
|
-
break;
|
|
120
|
+
catch {
|
|
121
|
+
throw new Error(`Invalid value for ${key}: expected JSON object with endpoint and model`
|
|
122
|
+
+ ` (e.g. '{"endpoint":"${exampleEndpoint}","model":"${exampleModel}"}')`);
|
|
39
123
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (!ref) {
|
|
43
|
-
console.error("Error: missing ref argument\n");
|
|
44
|
-
usage();
|
|
45
|
-
}
|
|
46
|
-
console.log(JSON.stringify(agentikitOpen({ ref }), null, 2));
|
|
47
|
-
break;
|
|
124
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
125
|
+
throw new Error(`Invalid value for ${key}: expected a JSON object`);
|
|
48
126
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
127
|
+
const obj = parsed;
|
|
128
|
+
if (typeof obj.endpoint !== "string" || !obj.endpoint || typeof obj.model !== "string" || !obj.model) {
|
|
129
|
+
throw new Error(`Invalid value for ${key}: "endpoint" and "model" are required string fields`);
|
|
130
|
+
}
|
|
131
|
+
const result = {
|
|
132
|
+
endpoint: obj.endpoint,
|
|
133
|
+
model: obj.model,
|
|
134
|
+
};
|
|
135
|
+
if (typeof obj.apiKey === "string" && obj.apiKey) {
|
|
136
|
+
result.apiKey = obj.apiKey;
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
function parseConfigValue(key, value) {
|
|
141
|
+
switch (key) {
|
|
142
|
+
case "semanticSearch":
|
|
143
|
+
if (value !== "true" && value !== "false") {
|
|
144
|
+
throw new Error(`Invalid value for semanticSearch: expected "true" or "false"`);
|
|
145
|
+
}
|
|
146
|
+
return { semanticSearch: value === "true" };
|
|
147
|
+
case "additionalStashDirs":
|
|
148
|
+
try {
|
|
149
|
+
const parsed = JSON.parse(value);
|
|
150
|
+
if (!Array.isArray(parsed))
|
|
151
|
+
throw new Error("expected JSON array");
|
|
152
|
+
return { additionalStashDirs: parsed.filter((d) => typeof d === "string") };
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
throw new Error(`Invalid value for additionalStashDirs: expected JSON array (e.g. '["/path/a","/path/b"]')`);
|
|
156
|
+
}
|
|
157
|
+
case "embedding":
|
|
158
|
+
return { embedding: parseConnectionValue("embedding", value, "http://localhost:11434/v1/embeddings", "nomic-embed-text") };
|
|
159
|
+
case "llm":
|
|
160
|
+
return { llm: parseConnectionValue("llm", value, "http://localhost:11434/v1/chat/completions", "llama3.2") };
|
|
161
|
+
default:
|
|
162
|
+
throw new Error(`Unknown config key: ${key}`);
|
|
59
163
|
}
|
|
60
|
-
default:
|
|
61
|
-
usage();
|
|
62
164
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type AgentikitAssetType = "tool" | "skill" | "command" | "agent" | "knowledge";
|
|
2
|
+
export declare const IS_WINDOWS: boolean;
|
|
3
|
+
export { SCRIPT_EXTENSIONS, TYPE_DIRS } from "./asset-spec";
|
|
4
|
+
export declare function isAssetType(type: string): type is AgentikitAssetType;
|
|
5
|
+
export declare function resolveStashDir(): string;
|
|
6
|
+
export declare function toPosix(input: string): string;
|
|
7
|
+
export declare function hasErrnoCode(error: unknown, code: string): boolean;
|
|
8
|
+
export declare function isWithin(candidate: string, root: string): boolean;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { TYPE_DIRS } from "./asset-spec";
|
|
4
|
+
// ── Constants ───────────────────────────────────────────────────────────────
|
|
5
|
+
export const IS_WINDOWS = process.platform === "win32";
|
|
6
|
+
export { SCRIPT_EXTENSIONS, TYPE_DIRS } from "./asset-spec";
|
|
7
|
+
// ── Validators ──────────────────────────────────────────────────────────────
|
|
8
|
+
export function isAssetType(type) {
|
|
9
|
+
return type in TYPE_DIRS;
|
|
10
|
+
}
|
|
11
|
+
// ── Utilities ───────────────────────────────────────────────────────────────
|
|
12
|
+
export function resolveStashDir() {
|
|
13
|
+
const raw = process.env.AGENTIKIT_STASH_DIR?.trim();
|
|
14
|
+
if (!raw) {
|
|
15
|
+
throw new Error("AGENTIKIT_STASH_DIR is not set. Set it to your Agentikit stash path.");
|
|
16
|
+
}
|
|
17
|
+
const stashDir = path.resolve(raw);
|
|
18
|
+
let stat;
|
|
19
|
+
try {
|
|
20
|
+
stat = fs.statSync(stashDir);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw new Error(`Unable to read AGENTIKIT_STASH_DIR at "${stashDir}".`);
|
|
24
|
+
}
|
|
25
|
+
if (!stat.isDirectory()) {
|
|
26
|
+
throw new Error(`AGENTIKIT_STASH_DIR must point to a directory: "${stashDir}".`);
|
|
27
|
+
}
|
|
28
|
+
return stashDir;
|
|
29
|
+
}
|
|
30
|
+
export function toPosix(input) {
|
|
31
|
+
return input.replace(/\\/g, "/");
|
|
32
|
+
}
|
|
33
|
+
export function hasErrnoCode(error, code) {
|
|
34
|
+
if (typeof error !== "object" || error === null || !("code" in error))
|
|
35
|
+
return false;
|
|
36
|
+
return error.code === code;
|
|
37
|
+
}
|
|
38
|
+
export function isWithin(candidate, root) {
|
|
39
|
+
const normalizedRoot = normalizeFsPathForComparison(path.resolve(root));
|
|
40
|
+
const normalizedCandidate = normalizeFsPathForComparison(path.resolve(candidate));
|
|
41
|
+
const rel = path.relative(normalizedRoot, normalizedCandidate);
|
|
42
|
+
return rel === "" || (!rel.startsWith("..") && !path.isAbsolute(rel));
|
|
43
|
+
}
|
|
44
|
+
function normalizeFsPathForComparison(value) {
|
|
45
|
+
return process.platform === "win32" ? value.toLowerCase() : value;
|
|
46
|
+
}
|