agentikit 0.0.7 → 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.
Files changed (80) hide show
  1. package/README.md +113 -77
  2. package/dist/index.d.ts +13 -3
  3. package/dist/index.js +7 -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 +154 -52
  7. package/dist/src/common.d.ts +8 -0
  8. package/dist/src/common.js +46 -0
  9. package/dist/src/config.d.ts +31 -0
  10. package/dist/src/config.js +74 -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 +10 -2
  24. package/dist/src/metadata.js +146 -30
  25. package/dist/src/ripgrep-install.d.ts +12 -0
  26. package/dist/src/ripgrep-install.js +169 -0
  27. package/dist/src/ripgrep-resolve.d.ts +13 -0
  28. package/dist/src/ripgrep-resolve.js +68 -0
  29. package/dist/src/ripgrep.d.ts +3 -36
  30. package/dist/src/ripgrep.js +2 -262
  31. package/dist/src/similarity.d.ts +1 -2
  32. package/dist/src/similarity.js +11 -0
  33. package/dist/src/stash-ref.d.ts +7 -0
  34. package/dist/src/stash-ref.js +33 -0
  35. package/dist/src/stash-resolve.d.ts +2 -0
  36. package/dist/src/stash-resolve.js +45 -0
  37. package/dist/src/stash-search.d.ts +6 -0
  38. package/dist/src/stash-search.js +269 -0
  39. package/dist/src/stash-show.d.ts +5 -0
  40. package/dist/src/stash-show.js +107 -0
  41. package/dist/src/stash-types.d.ts +53 -0
  42. package/dist/src/stash-types.js +1 -0
  43. package/dist/src/stash.d.ts +8 -63
  44. package/dist/src/stash.js +4 -633
  45. package/dist/src/tool-runner.d.ts +35 -0
  46. package/dist/src/tool-runner.js +100 -0
  47. package/dist/src/walker.d.ts +19 -0
  48. package/dist/src/walker.js +47 -0
  49. package/package.json +8 -14
  50. package/src/asset-spec.ts +69 -0
  51. package/src/cli.ts +164 -48
  52. package/src/common.ts +58 -0
  53. package/src/config.ts +124 -0
  54. package/src/embedder.ts +117 -0
  55. package/src/frontmatter.ts +95 -0
  56. package/src/indexer.ts +244 -84
  57. package/src/init.ts +106 -0
  58. package/src/llm.ts +124 -0
  59. package/src/markdown.ts +106 -0
  60. package/src/metadata.ts +157 -29
  61. package/src/ripgrep-install.ts +200 -0
  62. package/src/ripgrep-resolve.ts +72 -0
  63. package/src/ripgrep.ts +3 -315
  64. package/src/similarity.ts +13 -1
  65. package/src/stash-ref.ts +41 -0
  66. package/src/stash-resolve.ts +47 -0
  67. package/src/stash-search.ts +343 -0
  68. package/src/stash-show.ts +104 -0
  69. package/src/stash-types.ts +46 -0
  70. package/src/stash.ts +16 -760
  71. package/src/tool-runner.ts +129 -0
  72. package/src/walker.ts +53 -0
  73. package/.claude-plugin/plugin.json +0 -21
  74. package/commands/open.md +0 -11
  75. package/commands/run.md +0 -11
  76. package/commands/search.md +0 -11
  77. package/dist/src/plugin.d.ts +0 -2
  78. package/dist/src/plugin.js +0 -55
  79. package/skills/stash/SKILL.md +0 -73
  80. package/src/plugin.ts +0 -56
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Tool execution utilities.
3
+ *
4
+ * Handles building run commands and executing tool scripts for all supported
5
+ * kinds (bash, bun, powershell, cmd).
6
+ */
7
+
8
+ import fs from "node:fs"
9
+ import path from "node:path"
10
+ import { IS_WINDOWS, isWithin } from "./common"
11
+
12
+ // ── Types ───────────────────────────────────────────────────────────────────
13
+
14
+ /** The supported tool execution kinds. */
15
+ export type ToolKind = "bash" | "bun" | "powershell" | "cmd"
16
+
17
+ export interface ToolExecution {
18
+ command: string
19
+ args: string[]
20
+ cwd?: string
21
+ }
22
+
23
+ export interface ToolInfo {
24
+ runCmd: string
25
+ kind: ToolKind
26
+ install?: ToolExecution
27
+ execute: ToolExecution
28
+ }
29
+
30
+ // ── Public API ──────────────────────────────────────────────────────────────
31
+
32
+ /**
33
+ * Build execution metadata for a tool file based on its extension.
34
+ *
35
+ * For `.ts` / `.js` files, looks up the nearest `package.json` so that
36
+ * `bun install` can be run in the correct working directory when the
37
+ * `AGENTIKIT_BUN_INSTALL` env flag is set.
38
+ */
39
+ export function buildToolInfo(stashDir: string, filePath: string): ToolInfo {
40
+ const ext = path.extname(filePath).toLowerCase()
41
+
42
+ if (ext === ".sh") {
43
+ return {
44
+ runCmd: `bash ${shellQuote(filePath)}`,
45
+ kind: "bash",
46
+ execute: { command: "bash", args: [filePath] },
47
+ }
48
+ }
49
+
50
+ if (ext === ".ps1") {
51
+ return {
52
+ runCmd: `powershell -ExecutionPolicy Bypass -File ${shellQuote(filePath)}`,
53
+ kind: "powershell",
54
+ execute: { command: "powershell", args: ["-ExecutionPolicy", "Bypass", "-File", filePath] },
55
+ }
56
+ }
57
+
58
+ if (ext === ".cmd" || ext === ".bat") {
59
+ return {
60
+ runCmd: `cmd /c ${shellQuote(filePath)}`,
61
+ kind: "cmd",
62
+ execute: { command: "cmd", args: ["/c", filePath] },
63
+ }
64
+ }
65
+
66
+ if (ext !== ".ts" && ext !== ".js") {
67
+ throw new Error(`Unsupported tool extension: ${ext}`)
68
+ }
69
+
70
+ const toolsRoot = path.resolve(path.join(stashDir, "tools"))
71
+ const pkgDir = findNearestPackageDir(path.dirname(filePath), toolsRoot)
72
+ if (!pkgDir) {
73
+ return {
74
+ runCmd: `bun ${shellQuote(filePath)}`,
75
+ kind: "bun",
76
+ execute: { command: "bun", args: [filePath] },
77
+ }
78
+ }
79
+ const installFlag = process.env.AGENTIKIT_BUN_INSTALL
80
+ const shouldInstall = installFlag === "1" || installFlag === "true" || installFlag === "yes"
81
+
82
+ const quotedPkgDir = shellQuote(pkgDir)
83
+ const quotedFilePath = shellQuote(filePath)
84
+ const cdCmd = IS_WINDOWS ? `cd /d ${quotedPkgDir}` : `cd ${quotedPkgDir}`
85
+ const chain = IS_WINDOWS ? " & " : " && "
86
+ return {
87
+ runCmd: shouldInstall
88
+ ? `${cdCmd}${chain}bun install${chain}bun ${quotedFilePath}`
89
+ : `${cdCmd}${chain}bun ${quotedFilePath}`,
90
+ kind: "bun",
91
+ install: shouldInstall ? { command: "bun", args: ["install"], cwd: pkgDir } : undefined,
92
+ execute: { command: "bun", args: [filePath], cwd: pkgDir },
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Shell-quote a path for inclusion in a human-readable `runCmd` string.
98
+ */
99
+ export function shellQuote(input: string): string {
100
+ if (/[\r\n\t\0]/.test(input)) {
101
+ throw new Error("Unsupported control characters in stash path.")
102
+ }
103
+ if (IS_WINDOWS) {
104
+ return `"${input.replace(/"/g, '""')}"`
105
+ }
106
+ const escaped = input
107
+ .replace(/\\/g, "\\\\")
108
+ .replace(/"/g, '\\"')
109
+ .replace(/\$/g, "\\$")
110
+ .replace(/`/g, "\\`")
111
+ return `"${escaped}"`
112
+ }
113
+
114
+ /**
115
+ * Walk up from `startDir` toward `toolsRoot` looking for the nearest `package.json`.
116
+ */
117
+ export function findNearestPackageDir(startDir: string, toolsRoot: string): string | undefined {
118
+ let current = path.resolve(startDir)
119
+ const root = path.resolve(toolsRoot)
120
+ while (isWithin(current, root)) {
121
+ if (fs.existsSync(path.join(current, "package.json"))) {
122
+ return current
123
+ }
124
+ if (current === root) return undefined
125
+ current = path.dirname(current)
126
+ }
127
+ return undefined
128
+ }
129
+
package/src/walker.ts ADDED
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Shared filesystem walker for agentikit stash directories.
3
+ *
4
+ * Provides a single implementation used by both the search fallback
5
+ * (stash.ts) and the indexer (indexer.ts) to walk type-specific asset
6
+ * directories and group files by parent directory.
7
+ */
8
+
9
+ import fs from "node:fs"
10
+ import path from "node:path"
11
+ import { type AgentikitAssetType } from "./common"
12
+ import { isRelevantAssetFile } from "./asset-spec"
13
+
14
+ export interface DirectoryGroup {
15
+ dirPath: string
16
+ files: string[]
17
+ }
18
+
19
+ /**
20
+ * Walk a type root directory and return files grouped by their parent directory.
21
+ *
22
+ * Only files relevant to the given `assetType` are included (e.g. `.md` for
23
+ * commands, script extensions for tools, `SKILL.md` for skills).
24
+ */
25
+ export function walkStash(typeRoot: string, assetType: AgentikitAssetType): DirectoryGroup[] {
26
+ if (!fs.existsSync(typeRoot)) return []
27
+
28
+ const groups = new Map<string, string[]>()
29
+
30
+ const stack = [typeRoot]
31
+ while (stack.length > 0) {
32
+ const current = stack.pop()
33
+ if (!current) continue
34
+ const entries = fs.readdirSync(current, { withFileTypes: true })
35
+ for (const entry of entries) {
36
+ if (entry.name === ".stash.json") continue
37
+ const fullPath = path.join(current, entry.name)
38
+ if (entry.isDirectory()) {
39
+ stack.push(fullPath)
40
+ } else if (entry.isFile() && isRelevantAssetFile(assetType, entry.name)) {
41
+ const parentDir = path.dirname(fullPath)
42
+ const existing = groups.get(parentDir)
43
+ if (existing) {
44
+ existing.push(fullPath)
45
+ } else {
46
+ groups.set(parentDir, [fullPath])
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ return Array.from(groups, ([dirPath, files]) => ({ dirPath, files }))
53
+ }
@@ -1,21 +0,0 @@
1
- {
2
- "name": "agentikit",
3
- "description": "Search, open, and run extension assets from an Agentikit stash directory. Provides tools, skills, commands, and agents management for AI coding assistants.",
4
- "version": "0.0.1",
5
- "author": {
6
- "name": "itlackey",
7
- "url": "https://github.com/itlackey"
8
- },
9
- "homepage": "https://github.com/itlackey/agentikit#readme",
10
- "repository": "https://github.com/itlackey/agentikit",
11
- "license": "CC-BY-4.0",
12
- "keywords": [
13
- "agentikit",
14
- "stash",
15
- "tools",
16
- "skills",
17
- "commands",
18
- "agents",
19
- "plugin"
20
- ]
21
- }
package/commands/open.md DELETED
@@ -1,11 +0,0 @@
1
- ---
2
- description: Open an Agentikit stash asset by its openRef
3
- ---
4
-
5
- Open an Agentikit stash asset using the CLI. Run:
6
-
7
- ```bash
8
- agentikit open $ARGUMENTS
9
- ```
10
-
11
- Parse the JSON output and present the asset content to the user based on its type (skill content, command template, agent prompt, or tool info).
package/commands/run.md DELETED
@@ -1,11 +0,0 @@
1
- ---
2
- description: Run an Agentikit stash tool by its openRef
3
- ---
4
-
5
- Run an Agentikit stash tool using the CLI. Run:
6
-
7
- ```bash
8
- agentikit run $ARGUMENTS
9
- ```
10
-
11
- Parse the JSON output and present the tool's output and exit code to the user.
@@ -1,11 +0,0 @@
1
- ---
2
- description: Search the Agentikit stash for tools, skills, commands, and agents using semantic search
3
- ---
4
-
5
- Search the Agentikit stash using the CLI. If a search index exists, results are ranked by semantic relevance. Run `agentikit index` first to enable semantic search.
6
-
7
- ```bash
8
- agentikit search $ARGUMENTS
9
- ```
10
-
11
- Parse the JSON output and present the results to the user in a readable format. Include the `openRef` for each hit so the user can open or run assets. Results may include `description`, `tags`, and `score` fields when semantic search is active.
@@ -1,2 +0,0 @@
1
- import { type Plugin } from "@opencode-ai/plugin";
2
- export declare const plugin: Plugin;
@@ -1,55 +0,0 @@
1
- import { tool } from "@opencode-ai/plugin";
2
- import { agentikitOpen, agentikitRun, agentikitSearch } from "./stash";
3
- import { agentikitIndex } from "./indexer";
4
- function tryJson(fn, action) {
5
- try {
6
- return JSON.stringify(fn());
7
- }
8
- catch (error) {
9
- const message = error instanceof Error ? error.message : String(error);
10
- return JSON.stringify({ ok: false, error: `Failed to ${action}: ${message}` });
11
- }
12
- }
13
- export const plugin = async () => ({
14
- tool: {
15
- agentikit_search: tool({
16
- description: "Search the Agentikit stash for tools, skills, commands, and agents.",
17
- args: {
18
- query: tool.schema.string().describe("Case-insensitive substring search."),
19
- type: tool.schema
20
- .enum(["tool", "skill", "command", "agent", "any"])
21
- .optional()
22
- .describe("Optional type filter. Defaults to 'any'."),
23
- limit: tool.schema.number().optional().describe("Maximum number of hits to return. Defaults to 20."),
24
- },
25
- async execute({ query, type, limit }) {
26
- return tryJson(() => agentikitSearch({ query, type, limit }), "search Agentikit stash");
27
- },
28
- }),
29
- agentikit_open: tool({
30
- description: "Open a stash asset from an openRef returned by agentikit_search.",
31
- args: {
32
- ref: tool.schema.string().describe("Open reference returned by agentikit_search."),
33
- },
34
- async execute({ ref }) {
35
- return tryJson(() => agentikitOpen({ ref }), "open stash asset");
36
- },
37
- }),
38
- agentikit_run: tool({
39
- description: "Run a tool from the Agentikit stash by its openRef. Only tool refs are supported.",
40
- args: {
41
- ref: tool.schema.string().describe("Open reference of a tool returned by agentikit_search."),
42
- },
43
- async execute({ ref }) {
44
- return tryJson(() => agentikitRun({ ref }), "run stash tool");
45
- },
46
- }),
47
- agentikit_index: tool({
48
- description: "Build or rebuild the Agentikit search index. Scans stash directories, generates missing .stash.json metadata, and builds a semantic search index.",
49
- args: {},
50
- async execute() {
51
- return tryJson(() => agentikitIndex(), "build Agentikit index");
52
- },
53
- }),
54
- },
55
- });
@@ -1,73 +0,0 @@
1
- ---
2
- name: stash
3
- description: Search, open, and run extension assets from an Agentikit stash directory. Use when the user wants to find tools, skills, commands, or agents in their stash, view asset contents, or execute stash tools.
4
- ---
5
-
6
- # Agentikit Stash
7
-
8
- You have access to the `agentikit` CLI to manage extension assets from a stash directory.
9
-
10
- The stash directory is configured via the `AGENTIKIT_STASH_DIR` environment variable and contains:
11
-
12
- - **tools/** — executable scripts (.sh, .ts, .js, .ps1, .cmd, .bat)
13
- - **skills/** — skill directories containing SKILL.md
14
- - **commands/** — markdown template files
15
- - **agents/** — markdown agent definition files
16
-
17
- ## Commands
18
-
19
- ### Build the search index
20
-
21
- Scan stash directories, auto-generate missing `.stash.json` metadata, and build a semantic search index.
22
-
23
- ```bash
24
- agentikit index
25
- ```
26
-
27
- Run this after adding new extensions to enable semantic search ranking.
28
-
29
- ### Search the stash
30
-
31
- Find assets using a two-stage search pipeline: ripgrep pre-filters `.stash.json` metadata files for fast candidate discovery, then TF-IDF ranks results by semantic relevance. Falls back to name substring matching when no index exists.
32
-
33
- ```bash
34
- agentikit search [query] [--type tool|skill|command|agent|any] [--limit N]
35
- ```
36
-
37
- ### Open an asset
38
-
39
- Retrieve the full content/payload of an asset using its `openRef` from search results.
40
-
41
- ```bash
42
- agentikit open <openRef>
43
- ```
44
-
45
- Returns type-specific payloads:
46
- - **skill** → full SKILL.md content
47
- - **command** → markdown template + description
48
- - **agent** → prompt + description, toolPolicy, modelHint
49
- - **tool** → execution command and kind
50
-
51
- ### Run a tool
52
-
53
- Execute a tool asset by its `openRef`. Only tool refs are supported.
54
-
55
- ```bash
56
- agentikit run <openRef>
57
- ```
58
-
59
- Returns the tool's stdout/stderr output and exit code.
60
-
61
- ## Dependencies
62
-
63
- `agentikit init` will auto-install [ripgrep](https://github.com/BurntSushi/ripgrep) to `stash/bin/` if not already on PATH. Ripgrep is used for fast candidate filtering during search.
64
-
65
- ## Workflow
66
-
67
- 1. Initialize: `agentikit init` (creates stash dirs, installs ripgrep)
68
- 2. Build the index: `agentikit index`
69
- 3. Search for assets: `agentikit search "deploy" --type tool`
70
- 4. Inspect a result: `agentikit open <openRef>`
71
- 5. Run a tool: `agentikit run <openRef>`
72
-
73
- All output is JSON for easy parsing.
package/src/plugin.ts DELETED
@@ -1,56 +0,0 @@
1
- import { type Plugin, tool } from "@opencode-ai/plugin"
2
- import { agentikitOpen, agentikitRun, agentikitSearch } from "./stash"
3
- import { agentikitIndex } from "./indexer"
4
-
5
- function tryJson(fn: () => unknown, action: string): string {
6
- try {
7
- return JSON.stringify(fn())
8
- } catch (error: unknown) {
9
- const message = error instanceof Error ? error.message : String(error)
10
- return JSON.stringify({ ok: false, error: `Failed to ${action}: ${message}` })
11
- }
12
- }
13
-
14
- export const plugin: Plugin = async () => ({
15
- tool: {
16
- agentikit_search: tool({
17
- description: "Search the Agentikit stash for tools, skills, commands, and agents.",
18
- args: {
19
- query: tool.schema.string().describe("Case-insensitive substring search."),
20
- type: tool.schema
21
- .enum(["tool", "skill", "command", "agent", "any"])
22
- .optional()
23
- .describe("Optional type filter. Defaults to 'any'."),
24
- limit: tool.schema.number().optional().describe("Maximum number of hits to return. Defaults to 20."),
25
- },
26
- async execute({ query, type, limit }) {
27
- return tryJson(() => agentikitSearch({ query, type, limit }), "search Agentikit stash")
28
- },
29
- }),
30
- agentikit_open: tool({
31
- description: "Open a stash asset from an openRef returned by agentikit_search.",
32
- args: {
33
- ref: tool.schema.string().describe("Open reference returned by agentikit_search."),
34
- },
35
- async execute({ ref }) {
36
- return tryJson(() => agentikitOpen({ ref }), "open stash asset")
37
- },
38
- }),
39
- agentikit_run: tool({
40
- description: "Run a tool from the Agentikit stash by its openRef. Only tool refs are supported.",
41
- args: {
42
- ref: tool.schema.string().describe("Open reference of a tool returned by agentikit_search."),
43
- },
44
- async execute({ ref }) {
45
- return tryJson(() => agentikitRun({ ref }), "run stash tool")
46
- },
47
- }),
48
- agentikit_index: tool({
49
- description: "Build or rebuild the Agentikit search index. Scans stash directories, generates missing .stash.json metadata, and builds a semantic search index.",
50
- args: {},
51
- async execute() {
52
- return tryJson(() => agentikitIndex(), "build Agentikit index")
53
- },
54
- }),
55
- },
56
- })