agentikit 0.0.13 → 0.0.15
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/LICENSE +385 -0
- package/README.md +187 -110
- package/dist/{src/asset-spec.js → asset-spec.js} +11 -2
- package/dist/{src/asset-type-handler.js → asset-type-handler.js} +4 -3
- package/dist/cli.js +709 -0
- package/dist/common.js +192 -0
- package/dist/{src/config-cli.js → config-cli.js} +36 -30
- package/dist/{src/config.js → config.js} +95 -25
- package/dist/{src/db.js → db.js} +123 -51
- package/dist/{src/embedder.js → embedder.js} +57 -2
- package/dist/errors.js +28 -0
- package/dist/file-context.js +188 -0
- package/dist/{src/frontmatter.js → frontmatter.js} +1 -1
- package/dist/{src/github.js → github.js} +1 -3
- package/dist/handlers/agent-handler.js +19 -0
- package/dist/handlers/command-handler.js +20 -0
- package/dist/handlers/handler-bridge.js +51 -0
- package/dist/handlers/index.js +19 -0
- package/dist/handlers/knowledge-handler.js +32 -0
- package/dist/handlers/script-handler.js +42 -0
- package/dist/{src/handlers → handlers}/skill-handler.js +5 -6
- package/dist/{src/handlers → handlers}/tool-handler.js +8 -24
- package/dist/{src/indexer.js → indexer.js} +50 -26
- package/dist/init.js +43 -0
- package/dist/{src/llm.js → llm.js} +6 -11
- package/dist/lockfile.js +60 -0
- package/dist/matchers.js +163 -0
- package/dist/{src/metadata.js → metadata.js} +36 -16
- package/dist/{src/origin-resolve.js → origin-resolve.js} +10 -9
- package/dist/paths.js +83 -0
- package/dist/{src/registry-install.js → registry-install.js} +151 -19
- package/dist/{src/registry-resolve.js → registry-resolve.js} +190 -26
- package/dist/{src/registry-search.js → registry-search.js} +13 -21
- package/dist/renderers.js +286 -0
- package/dist/{src/ripgrep-install.js → ripgrep-install.js} +8 -27
- package/dist/{src/ripgrep-resolve.js → ripgrep-resolve.js} +21 -11
- package/dist/ripgrep.js +2 -0
- package/dist/self-update.js +226 -0
- package/dist/{src/stash-add.js → stash-add.js} +14 -4
- package/dist/stash-clone.js +115 -0
- package/dist/{src/stash-ref.js → stash-ref.js} +10 -9
- package/dist/{src/stash-registry.js → stash-registry.js} +21 -46
- package/dist/{src/stash-resolve.js → stash-resolve.js} +10 -9
- package/dist/{src/stash-search.js → stash-search.js} +89 -74
- package/dist/stash-show.js +74 -0
- package/dist/stash-source.js +127 -0
- package/dist/submit.js +557 -0
- package/dist/{src/tool-runner.js → tool-runner.js} +1 -5
- package/dist/{src/walker.js → walker.js} +38 -0
- package/dist/warn.js +20 -0
- package/package.json +13 -18
- package/dist/index.d.ts +0 -28
- package/dist/index.js +0 -15
- package/dist/src/asset-spec.d.ts +0 -16
- package/dist/src/asset-type-handler.d.ts +0 -27
- package/dist/src/cli.d.ts +0 -2
- package/dist/src/cli.js +0 -399
- package/dist/src/common.d.ts +0 -13
- package/dist/src/common.js +0 -60
- package/dist/src/config-cli.d.ts +0 -9
- package/dist/src/config.d.ts +0 -50
- package/dist/src/db.d.ts +0 -46
- package/dist/src/embedder.d.ts +0 -10
- package/dist/src/frontmatter.d.ts +0 -30
- package/dist/src/github.d.ts +0 -4
- package/dist/src/handlers/agent-handler.d.ts +0 -2
- package/dist/src/handlers/agent-handler.js +0 -26
- package/dist/src/handlers/command-handler.d.ts +0 -2
- package/dist/src/handlers/command-handler.js +0 -23
- package/dist/src/handlers/index.d.ts +0 -6
- package/dist/src/handlers/index.js +0 -23
- package/dist/src/handlers/knowledge-handler.d.ts +0 -2
- package/dist/src/handlers/knowledge-handler.js +0 -56
- package/dist/src/handlers/markdown-helpers.d.ts +0 -7
- package/dist/src/handlers/script-handler.d.ts +0 -2
- package/dist/src/handlers/script-handler.js +0 -78
- package/dist/src/handlers/skill-handler.d.ts +0 -2
- package/dist/src/handlers/tool-handler.d.ts +0 -2
- package/dist/src/indexer.d.ts +0 -22
- package/dist/src/init.d.ts +0 -19
- package/dist/src/init.js +0 -99
- package/dist/src/llm.d.ts +0 -15
- package/dist/src/markdown.d.ts +0 -18
- package/dist/src/metadata.d.ts +0 -41
- package/dist/src/origin-resolve.d.ts +0 -19
- package/dist/src/registry-install.d.ts +0 -11
- package/dist/src/registry-resolve.d.ts +0 -3
- package/dist/src/registry-search.d.ts +0 -27
- package/dist/src/registry-types.d.ts +0 -62
- package/dist/src/ripgrep-install.d.ts +0 -12
- package/dist/src/ripgrep-resolve.d.ts +0 -13
- package/dist/src/ripgrep.d.ts +0 -3
- package/dist/src/ripgrep.js +0 -2
- package/dist/src/stash-add.d.ts +0 -4
- package/dist/src/stash-clone.d.ts +0 -22
- package/dist/src/stash-clone.js +0 -83
- package/dist/src/stash-ref.d.ts +0 -31
- package/dist/src/stash-registry.d.ts +0 -18
- package/dist/src/stash-resolve.d.ts +0 -2
- package/dist/src/stash-search.d.ts +0 -8
- package/dist/src/stash-show.d.ts +0 -5
- package/dist/src/stash-show.js +0 -46
- package/dist/src/stash-source.d.ts +0 -24
- package/dist/src/stash-source.js +0 -81
- package/dist/src/stash-types.d.ts +0 -227
- package/dist/src/stash.d.ts +0 -16
- package/dist/src/stash.js +0 -9
- package/dist/src/tool-runner.d.ts +0 -35
- package/dist/src/walker.d.ts +0 -19
- package/src/asset-spec.ts +0 -85
- package/src/asset-type-handler.ts +0 -77
- package/src/cli.ts +0 -427
- package/src/common.ts +0 -76
- package/src/config-cli.ts +0 -499
- package/src/config.ts +0 -305
- package/src/db.ts +0 -411
- package/src/embedder.ts +0 -128
- package/src/frontmatter.ts +0 -95
- package/src/github.ts +0 -21
- package/src/handlers/agent-handler.ts +0 -32
- package/src/handlers/command-handler.ts +0 -29
- package/src/handlers/index.ts +0 -25
- package/src/handlers/knowledge-handler.ts +0 -62
- package/src/handlers/markdown-helpers.ts +0 -19
- package/src/handlers/script-handler.ts +0 -92
- package/src/handlers/skill-handler.ts +0 -37
- package/src/handlers/tool-handler.ts +0 -71
- package/src/indexer.ts +0 -392
- package/src/init.ts +0 -114
- package/src/llm.ts +0 -125
- package/src/markdown.ts +0 -106
- package/src/metadata.ts +0 -333
- package/src/origin-resolve.ts +0 -67
- package/src/registry-install.ts +0 -361
- package/src/registry-resolve.ts +0 -341
- package/src/registry-search.ts +0 -335
- package/src/registry-types.ts +0 -72
- package/src/ripgrep-install.ts +0 -200
- package/src/ripgrep-resolve.ts +0 -72
- package/src/ripgrep.ts +0 -3
- package/src/stash-add.ts +0 -63
- package/src/stash-clone.ts +0 -127
- package/src/stash-ref.ts +0 -99
- package/src/stash-registry.ts +0 -259
- package/src/stash-resolve.ts +0 -50
- package/src/stash-search.ts +0 -613
- package/src/stash-show.ts +0 -55
- package/src/stash-source.ts +0 -103
- package/src/stash-types.ts +0 -231
- package/src/stash.ts +0 -39
- package/src/tool-runner.ts +0 -142
- package/src/walker.ts +0 -53
- /package/dist/{src/handlers → handlers}/markdown-helpers.js +0 -0
- /package/dist/{src/markdown.js → markdown.js} +0 -0
- /package/dist/{src/registry-types.js → registry-types.js} +0 -0
- /package/dist/{src/stash-types.js → stash-types.js} +0 -0
package/dist/matchers.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in asset matchers for the agentikit file classification system.
|
|
3
|
+
*
|
|
4
|
+
* Four matchers are registered at module load time, each at a different
|
|
5
|
+
* specificity level. Extension and content determine type; directories are
|
|
6
|
+
* optional specificity boosts, not requirements.
|
|
7
|
+
*
|
|
8
|
+
* - `extensionMatcher` (3) -- classifies any file by extension alone.
|
|
9
|
+
* Ensures every known file type is discoverable regardless of directory.
|
|
10
|
+
* - `directoryMatcher` (10) -- boosts specificity when the first ancestor
|
|
11
|
+
* directory matches a known type name (e.g. `scripts/`, `agents/`).
|
|
12
|
+
* - `parentDirHintMatcher` (15) -- boosts specificity based on the
|
|
13
|
+
* immediate parent directory name.
|
|
14
|
+
* - `smartMdMatcher` (20 / 18 / 8 / 5) -- inspects markdown frontmatter
|
|
15
|
+
* and body content for agent/command signals; falls back to "knowledge"
|
|
16
|
+
* at specificity 5 when no signals are found. Command signals (`agent`
|
|
17
|
+
* frontmatter, `$ARGUMENTS`/`$1`-`$3` placeholders) return 18.
|
|
18
|
+
*/
|
|
19
|
+
import { SCRIPT_EXTENSIONS_BROAD } from "./asset-spec";
|
|
20
|
+
import { registerMatcher } from "./file-context";
|
|
21
|
+
// ── extensionMatcher (specificity: 3) ────────────────────────────────────────
|
|
22
|
+
/**
|
|
23
|
+
* Base-level matcher that classifies files purely by extension.
|
|
24
|
+
*
|
|
25
|
+
* This is the foundation of the classification system: every file with a
|
|
26
|
+
* known extension gets a type, regardless of what directory it lives in.
|
|
27
|
+
* Higher-specificity matchers (directory, content) can override this.
|
|
28
|
+
*
|
|
29
|
+
* .md files are NOT handled here -- smartMdMatcher provides richer
|
|
30
|
+
* classification for markdown via frontmatter inspection.
|
|
31
|
+
*/
|
|
32
|
+
export function extensionMatcher(ctx) {
|
|
33
|
+
// SKILL.md is a skill regardless of location
|
|
34
|
+
if (ctx.fileName === "SKILL.md") {
|
|
35
|
+
return { type: "skill", specificity: 3, renderer: "skill-md" };
|
|
36
|
+
}
|
|
37
|
+
// Known script extensions (excluding .md, handled by smartMdMatcher)
|
|
38
|
+
if (SCRIPT_EXTENSIONS_BROAD.has(ctx.ext)) {
|
|
39
|
+
return { type: "script", specificity: 3, renderer: "script-source" };
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
// ── directoryMatcher (specificity: 10) ──────────────────────────────────────
|
|
44
|
+
/**
|
|
45
|
+
* Directory-based matcher that boosts specificity when the first ancestor
|
|
46
|
+
* directory segment from the stash root matches a known type name.
|
|
47
|
+
*
|
|
48
|
+
* Accepts ALL known script extensions in both `tools/` and `scripts/`
|
|
49
|
+
* directories -- the distinction is purely organizational.
|
|
50
|
+
*/
|
|
51
|
+
export function directoryMatcher(ctx) {
|
|
52
|
+
const topDir = ctx.ancestorDirs[0];
|
|
53
|
+
if (!topDir)
|
|
54
|
+
return null;
|
|
55
|
+
const ext = ctx.ext;
|
|
56
|
+
if ((topDir === "tools" || topDir === "scripts") && SCRIPT_EXTENSIONS_BROAD.has(ext)) {
|
|
57
|
+
return { type: "script", specificity: 10, renderer: "script-source" };
|
|
58
|
+
}
|
|
59
|
+
if (topDir === "skills" && ctx.fileName === "SKILL.md") {
|
|
60
|
+
return { type: "skill", specificity: 10, renderer: "skill-md" };
|
|
61
|
+
}
|
|
62
|
+
if (topDir === "commands" && ext === ".md") {
|
|
63
|
+
return { type: "command", specificity: 10, renderer: "command-md" };
|
|
64
|
+
}
|
|
65
|
+
if (topDir === "agents" && ext === ".md") {
|
|
66
|
+
return { type: "agent", specificity: 10, renderer: "agent-md" };
|
|
67
|
+
}
|
|
68
|
+
if (topDir === "knowledge" && ext === ".md") {
|
|
69
|
+
return { type: "knowledge", specificity: 10, renderer: "knowledge-md" };
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
// ── parentDirHintMatcher (specificity: 15) ──────────────────────────────────
|
|
74
|
+
/**
|
|
75
|
+
* Uses the immediate parent directory name as a hint. More specific than
|
|
76
|
+
* the ancestor-based directory matcher because the file might be nested
|
|
77
|
+
* several levels deep, yet its immediate parent can still carry strong
|
|
78
|
+
* naming conventions (e.g. `my-project/agents/planning.md`).
|
|
79
|
+
*
|
|
80
|
+
* Accepts ALL known script extensions in both `tools/` and `scripts/`.
|
|
81
|
+
*/
|
|
82
|
+
export function parentDirHintMatcher(ctx) {
|
|
83
|
+
const { parentDir, ext, fileName } = ctx;
|
|
84
|
+
if ((parentDir === "tools" || parentDir === "scripts") && SCRIPT_EXTENSIONS_BROAD.has(ext)) {
|
|
85
|
+
return { type: "script", specificity: 15, renderer: "script-source" };
|
|
86
|
+
}
|
|
87
|
+
if (parentDir === "skills" && fileName === "SKILL.md") {
|
|
88
|
+
return { type: "skill", specificity: 15, renderer: "skill-md" };
|
|
89
|
+
}
|
|
90
|
+
if (parentDir === "agents" && ext === ".md") {
|
|
91
|
+
return { type: "agent", specificity: 15, renderer: "agent-md" };
|
|
92
|
+
}
|
|
93
|
+
if (parentDir === "commands" && ext === ".md") {
|
|
94
|
+
return { type: "command", specificity: 15, renderer: "command-md" };
|
|
95
|
+
}
|
|
96
|
+
if (parentDir === "knowledge" && ext === ".md") {
|
|
97
|
+
return { type: "knowledge", specificity: 15, renderer: "knowledge-md" };
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
// ── smartMdMatcher (specificity: 20 / 18 / 8 / 5) ──────────────────────────
|
|
102
|
+
/** Pattern that matches OpenCode command placeholders in markdown body. */
|
|
103
|
+
const COMMAND_PLACEHOLDER_RE = /\$ARGUMENTS|\$[123]\b/;
|
|
104
|
+
/**
|
|
105
|
+
* Content-based matcher for `.md` files. Inspects frontmatter keys and body
|
|
106
|
+
* content to classify markdown as agent, command, or knowledge.
|
|
107
|
+
*
|
|
108
|
+
* Specificity levels:
|
|
109
|
+
* 20 -- agent-exclusive signals (`tools`, `toolPolicy`)
|
|
110
|
+
* 18 -- command content signals (`agent` frontmatter, `$ARGUMENTS`/`$1`-`$3`)
|
|
111
|
+
* 8 -- weak agent signal (`model` alone)
|
|
112
|
+
* 5 -- knowledge fallback (any unclassified `.md`)
|
|
113
|
+
*
|
|
114
|
+
* Command signals at 18 override directory hints (10/15) because the content
|
|
115
|
+
* unambiguously identifies a command template. Agent-exclusive signals at 20
|
|
116
|
+
* still win over command signals when both are present.
|
|
117
|
+
*/
|
|
118
|
+
export function smartMdMatcher(ctx) {
|
|
119
|
+
if (ctx.ext !== ".md")
|
|
120
|
+
return null;
|
|
121
|
+
const fm = ctx.frontmatter();
|
|
122
|
+
if (fm) {
|
|
123
|
+
// Agent-exclusive indicators: toolPolicy or tools
|
|
124
|
+
// These return high specificity (20) to override everything else.
|
|
125
|
+
if ("toolPolicy" in fm || "tools" in fm) {
|
|
126
|
+
return { type: "agent", specificity: 20, renderer: "agent-md" };
|
|
127
|
+
}
|
|
128
|
+
// Command signal: `agent` frontmatter key names a dispatch target.
|
|
129
|
+
// This is an OpenCode convention specific to commands.
|
|
130
|
+
if ("agent" in fm) {
|
|
131
|
+
return { type: "command", specificity: 18, renderer: "command-md" };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Command signal: body contains $ARGUMENTS or $1/$2/$3 placeholders.
|
|
135
|
+
// These are definitively command template patterns (OpenCode convention).
|
|
136
|
+
const body = ctx.content();
|
|
137
|
+
if (COMMAND_PLACEHOLDER_RE.test(body)) {
|
|
138
|
+
return { type: "command", specificity: 18, renderer: "command-md" };
|
|
139
|
+
}
|
|
140
|
+
if (fm) {
|
|
141
|
+
// model alone is a weaker agent signal (specificity 8) -- it can appear
|
|
142
|
+
// on commands too (OpenCode convention). Directory hints (10/15) win
|
|
143
|
+
// when the file lives in commands/, but model still classifies an .md
|
|
144
|
+
// as agent when no directory hint is present.
|
|
145
|
+
if ("model" in fm) {
|
|
146
|
+
return { type: "agent", specificity: 8, renderer: "agent-md" };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Weak fallback: any .md file is assumed to be knowledge
|
|
150
|
+
return { type: "knowledge", specificity: 5, renderer: "knowledge-md" };
|
|
151
|
+
}
|
|
152
|
+
// ── Registration ────────────────────────────────────────────────────────────
|
|
153
|
+
/** All built-in matchers in registration order (later wins ties). */
|
|
154
|
+
const builtinMatchers = [extensionMatcher, directoryMatcher, parentDirHintMatcher, smartMdMatcher];
|
|
155
|
+
/**
|
|
156
|
+
* Register all built-in matchers with the file-context registry.
|
|
157
|
+
* Called once from the CLI entry point (or ensureBuiltinsRegistered).
|
|
158
|
+
*/
|
|
159
|
+
export function registerBuiltinMatchers() {
|
|
160
|
+
for (const matcher of builtinMatchers) {
|
|
161
|
+
registerMatcher(matcher);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { deriveCanonicalAssetName, isRelevantAssetFile } from "./asset-spec";
|
|
4
|
+
import { tryGetHandler } from "./asset-type-handler";
|
|
3
5
|
import { isAssetType } from "./common";
|
|
4
|
-
import { isRelevantAssetFile, deriveCanonicalAssetName } from "./asset-spec";
|
|
5
6
|
import { parseFrontmatter, toStringOrUndefined } from "./frontmatter";
|
|
6
|
-
import {
|
|
7
|
+
import { warn } from "./warn";
|
|
7
8
|
// ── Load / Write ────────────────────────────────────────────────────────────
|
|
8
9
|
const STASH_FILENAME = ".stash.json";
|
|
9
10
|
export function stashFilePath(dirPath) {
|
|
@@ -20,8 +21,15 @@ export function loadStashFile(dirPath) {
|
|
|
20
21
|
const entries = [];
|
|
21
22
|
for (const e of raw.entries) {
|
|
22
23
|
const validated = validateStashEntry(e);
|
|
23
|
-
if (validated)
|
|
24
|
+
if (validated) {
|
|
24
25
|
entries.push(validated);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
const name = typeof e === "object" && e !== null && typeof e.name === "string"
|
|
29
|
+
? e.name
|
|
30
|
+
: "(unknown)";
|
|
31
|
+
warn(`Warning: Skipping invalid entry "${name}" in ${filePath}`);
|
|
32
|
+
}
|
|
25
33
|
}
|
|
26
34
|
return entries.length > 0 ? { entries } : null;
|
|
27
35
|
}
|
|
@@ -31,7 +39,20 @@ export function loadStashFile(dirPath) {
|
|
|
31
39
|
}
|
|
32
40
|
export function writeStashFile(dirPath, stash) {
|
|
33
41
|
const filePath = stashFilePath(dirPath);
|
|
34
|
-
|
|
42
|
+
const tmpPath = filePath + `.tmp.${process.pid}`;
|
|
43
|
+
try {
|
|
44
|
+
fs.writeFileSync(tmpPath, JSON.stringify(stash, null, 2) + "\n", "utf8");
|
|
45
|
+
fs.renameSync(tmpPath, filePath);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
try {
|
|
49
|
+
fs.unlinkSync(tmpPath);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
/* ignore cleanup failure */
|
|
53
|
+
}
|
|
54
|
+
throw err;
|
|
55
|
+
}
|
|
35
56
|
}
|
|
36
57
|
export function validateStashEntry(entry) {
|
|
37
58
|
if (typeof entry !== "object" || entry === null)
|
|
@@ -74,7 +95,8 @@ export function validateStashEntry(entry) {
|
|
|
74
95
|
result.quality = e.quality;
|
|
75
96
|
if (typeof e.confidence === "number" && Number.isFinite(e.confidence))
|
|
76
97
|
result.confidence = Math.max(0, Math.min(1, e.confidence));
|
|
77
|
-
if (typeof e.source === "string" &&
|
|
98
|
+
if (typeof e.source === "string" &&
|
|
99
|
+
["package", "frontmatter", "comments", "filename", "manual", "llm"].includes(e.source)) {
|
|
78
100
|
result.source = e.source;
|
|
79
101
|
}
|
|
80
102
|
if (Array.isArray(e.aliases)) {
|
|
@@ -87,9 +109,7 @@ export function validateStashEntry(entry) {
|
|
|
87
109
|
if (typeof h !== "object" || h === null)
|
|
88
110
|
return false;
|
|
89
111
|
const rec = h;
|
|
90
|
-
return typeof rec.level === "number"
|
|
91
|
-
&& typeof rec.text === "string"
|
|
92
|
-
&& typeof rec.line === "number";
|
|
112
|
+
return typeof rec.level === "number" && typeof rec.text === "string" && typeof rec.line === "number";
|
|
93
113
|
});
|
|
94
114
|
if (validated.length > 0)
|
|
95
115
|
result.toc = validated;
|
|
@@ -123,9 +143,7 @@ export function generateMetadata(dirPath, assetType, files, typeRoot = dirPath)
|
|
|
123
143
|
// Skip non-relevant files
|
|
124
144
|
if (!isRelevantAssetFile(assetType, fileName))
|
|
125
145
|
continue;
|
|
126
|
-
const canonicalName = assetType === "skill"
|
|
127
|
-
? deriveCanonicalAssetName(assetType, typeRoot, file) ?? baseName
|
|
128
|
-
: baseName;
|
|
146
|
+
const canonicalName = assetType === "skill" ? (deriveCanonicalAssetName(assetType, typeRoot, file) ?? baseName) : baseName;
|
|
129
147
|
const entry = {
|
|
130
148
|
name: canonicalName,
|
|
131
149
|
type: assetType,
|
|
@@ -134,7 +152,7 @@ export function generateMetadata(dirPath, assetType, files, typeRoot = dirPath)
|
|
|
134
152
|
confidence: 0.55,
|
|
135
153
|
source: "filename",
|
|
136
154
|
};
|
|
137
|
-
// Priority 1:
|
|
155
|
+
// Priority 1: Package.json metadata
|
|
138
156
|
if (pkgMeta) {
|
|
139
157
|
if (pkgMeta.description && !entry.description) {
|
|
140
158
|
entry.description = pkgMeta.description;
|
|
@@ -144,7 +162,7 @@ export function generateMetadata(dirPath, assetType, files, typeRoot = dirPath)
|
|
|
144
162
|
if (pkgMeta.keywords && pkgMeta.keywords.length > 0)
|
|
145
163
|
entry.tags = normalizeTerms(pkgMeta.keywords);
|
|
146
164
|
}
|
|
147
|
-
// Priority 2: Frontmatter (for .md files
|
|
165
|
+
// Priority 2: Frontmatter (for .md files -- overrides package.json description)
|
|
148
166
|
if (ext === ".md") {
|
|
149
167
|
const fm = extractFrontmatterDescription(file);
|
|
150
168
|
if (fm) {
|
|
@@ -153,7 +171,7 @@ export function generateMetadata(dirPath, assetType, files, typeRoot = dirPath)
|
|
|
153
171
|
entry.confidence = 0.9;
|
|
154
172
|
}
|
|
155
173
|
}
|
|
156
|
-
// Type-specific metadata extraction (e.g. TOC for knowledge, comments for tools/scripts)
|
|
174
|
+
// Priority 3: Type-specific metadata extraction (e.g. TOC for knowledge, comments for tools/scripts)
|
|
157
175
|
const handler = tryGetHandler(assetType);
|
|
158
176
|
if (handler?.extractTypeMetadata) {
|
|
159
177
|
handler.extractTypeMetadata(entry, file, ext);
|
|
@@ -215,7 +233,10 @@ export function extractDescriptionFromComments(filePath) {
|
|
|
215
233
|
const line = lines[i];
|
|
216
234
|
if (i > blockStart && /\*\//.test(line))
|
|
217
235
|
break;
|
|
218
|
-
const cleaned = line
|
|
236
|
+
const cleaned = line
|
|
237
|
+
.replace(/^\s*\/?\*\*?\s?/, "")
|
|
238
|
+
.replace(/\*\/\s*$/, "")
|
|
239
|
+
.trim();
|
|
219
240
|
if (cleaned)
|
|
220
241
|
desc.push(cleaned);
|
|
221
242
|
}
|
|
@@ -233,7 +254,6 @@ export function extractDescriptionFromComments(filePath) {
|
|
|
233
254
|
hashLines.push(line.replace(/^#+\s*/, "").trim());
|
|
234
255
|
}
|
|
235
256
|
else if (line === "") {
|
|
236
|
-
continue;
|
|
237
257
|
}
|
|
238
258
|
else {
|
|
239
259
|
break;
|
|
@@ -5,21 +5,22 @@ import { parseRegistryRef } from "./registry-resolve";
|
|
|
5
5
|
* sources, return the subset of sources to search.
|
|
6
6
|
*
|
|
7
7
|
* Resolution order:
|
|
8
|
-
* 1. undefined → all sources
|
|
9
|
-
* 2. "local" →
|
|
10
|
-
* 3. exact match →
|
|
8
|
+
* 1. undefined → all sources
|
|
9
|
+
* 2. "local" → primary stash only (first entry)
|
|
10
|
+
* 3. exact match → source whose registryId matches verbatim
|
|
11
11
|
* 4. parsed match → parse origin as a registry ref, match by parsed ID
|
|
12
|
-
* 5. path match →
|
|
12
|
+
* 5. path match → source whose resolved path matches the origin
|
|
13
13
|
* 6. empty → indicates a remote/uninstalled origin (caller decides)
|
|
14
14
|
*/
|
|
15
15
|
export function resolveSourcesForOrigin(origin, allSources) {
|
|
16
16
|
if (!origin)
|
|
17
17
|
return allSources;
|
|
18
|
+
// "local" means the primary stash (first entry)
|
|
18
19
|
if (origin === "local") {
|
|
19
|
-
return allSources.
|
|
20
|
+
return allSources.length > 0 ? [allSources[0]] : [];
|
|
20
21
|
}
|
|
21
22
|
// Exact registryId match (e.g. origin is "npm:@scope/pkg")
|
|
22
|
-
const byExactId = allSources.filter((s) => s.
|
|
23
|
+
const byExactId = allSources.filter((s) => s.registryId !== undefined && s.registryId === origin);
|
|
23
24
|
if (byExactId.length > 0)
|
|
24
25
|
return byExactId;
|
|
25
26
|
// Parse origin as a registry ref and match by parsed ID.
|
|
@@ -27,16 +28,16 @@ export function resolveSourcesForOrigin(origin, allSources) {
|
|
|
27
28
|
// "@scope/pkg" matches "npm:@scope/pkg".
|
|
28
29
|
try {
|
|
29
30
|
const parsed = parseRegistryRef(origin);
|
|
30
|
-
const byParsedId = allSources.filter((s) => s.
|
|
31
|
+
const byParsedId = allSources.filter((s) => s.registryId !== undefined && s.registryId === parsed.id);
|
|
31
32
|
if (byParsedId.length > 0)
|
|
32
33
|
return byParsedId;
|
|
33
34
|
}
|
|
34
35
|
catch {
|
|
35
36
|
// Not a valid registry ref — continue to path matching
|
|
36
37
|
}
|
|
37
|
-
//
|
|
38
|
+
// Match by resolved path (any source, including installed)
|
|
38
39
|
const resolvedOrigin = path.resolve(origin);
|
|
39
|
-
const byPath = allSources.filter((s) =>
|
|
40
|
+
const byPath = allSources.filter((s) => path.resolve(s.path) === resolvedOrigin);
|
|
40
41
|
if (byPath.length > 0)
|
|
41
42
|
return byPath;
|
|
42
43
|
// No match — origin may be remote/uninstalled
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized path resolution for all agentikit directories.
|
|
3
|
+
*
|
|
4
|
+
* Provides platform-aware paths for config, cache, and stash directories,
|
|
5
|
+
* following XDG Base Directory conventions on Unix and standard locations
|
|
6
|
+
* on Windows.
|
|
7
|
+
*/
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { ConfigError } from "./errors";
|
|
10
|
+
const IS_WINDOWS = process.platform === "win32";
|
|
11
|
+
// ── Config directory ─────────────────────────────────────────────────────────
|
|
12
|
+
export function getConfigDir(env = process.env, platform = process.platform) {
|
|
13
|
+
if (platform === "win32") {
|
|
14
|
+
const appData = env.APPDATA?.trim();
|
|
15
|
+
if (appData)
|
|
16
|
+
return path.join(appData, "agentikit");
|
|
17
|
+
const userProfile = env.USERPROFILE?.trim();
|
|
18
|
+
if (!userProfile) {
|
|
19
|
+
throw new ConfigError("Unable to determine config directory. Set APPDATA or USERPROFILE.");
|
|
20
|
+
}
|
|
21
|
+
return path.join(userProfile, "AppData", "Roaming", "agentikit");
|
|
22
|
+
}
|
|
23
|
+
const xdgConfigHome = env.XDG_CONFIG_HOME?.trim();
|
|
24
|
+
if (xdgConfigHome)
|
|
25
|
+
return path.join(xdgConfigHome, "agentikit");
|
|
26
|
+
const home = env.HOME?.trim();
|
|
27
|
+
if (!home) {
|
|
28
|
+
throw new ConfigError("Unable to determine config directory. Set XDG_CONFIG_HOME or HOME.");
|
|
29
|
+
}
|
|
30
|
+
return path.join(home, ".config", "agentikit");
|
|
31
|
+
}
|
|
32
|
+
export function getConfigPath() {
|
|
33
|
+
return path.join(getConfigDir(), "config.json");
|
|
34
|
+
}
|
|
35
|
+
// ── Cache directory ──────────────────────────────────────────────────────────
|
|
36
|
+
export function getCacheDir() {
|
|
37
|
+
if (IS_WINDOWS) {
|
|
38
|
+
const localAppData = process.env.LOCALAPPDATA?.trim();
|
|
39
|
+
if (localAppData)
|
|
40
|
+
return path.join(localAppData, "agentikit");
|
|
41
|
+
const userProfile = process.env.USERPROFILE?.trim();
|
|
42
|
+
if (userProfile)
|
|
43
|
+
return path.join(userProfile, "AppData", "Local", "agentikit");
|
|
44
|
+
const appData = process.env.APPDATA?.trim();
|
|
45
|
+
if (!appData) {
|
|
46
|
+
throw new ConfigError("Unable to determine cache directory. Set LOCALAPPDATA, USERPROFILE, or APPDATA.");
|
|
47
|
+
}
|
|
48
|
+
return path.join(appData, "..", "Local", "agentikit");
|
|
49
|
+
}
|
|
50
|
+
const xdgCacheHome = process.env.XDG_CACHE_HOME?.trim();
|
|
51
|
+
if (xdgCacheHome)
|
|
52
|
+
return path.join(xdgCacheHome, "agentikit");
|
|
53
|
+
const home = process.env.HOME?.trim();
|
|
54
|
+
if (!home)
|
|
55
|
+
return path.join("/tmp", "agentikit-cache");
|
|
56
|
+
return path.join(home, ".cache", "agentikit");
|
|
57
|
+
}
|
|
58
|
+
export function getDbPath() {
|
|
59
|
+
return path.join(getCacheDir(), "index.db");
|
|
60
|
+
}
|
|
61
|
+
export function getRegistryCacheDir() {
|
|
62
|
+
return path.join(getCacheDir(), "registry");
|
|
63
|
+
}
|
|
64
|
+
export function getRegistryIndexCacheDir() {
|
|
65
|
+
return path.join(getCacheDir(), "registry-index");
|
|
66
|
+
}
|
|
67
|
+
export function getBinDir() {
|
|
68
|
+
return path.join(getCacheDir(), "bin");
|
|
69
|
+
}
|
|
70
|
+
// ── Default stash directory ──────────────────────────────────────────────────
|
|
71
|
+
export function getDefaultStashDir() {
|
|
72
|
+
if (IS_WINDOWS) {
|
|
73
|
+
const userProfile = process.env.USERPROFILE?.trim();
|
|
74
|
+
if (userProfile)
|
|
75
|
+
return path.join(userProfile, "Documents", "agentikit");
|
|
76
|
+
return path.join("C:\\", "agentikit");
|
|
77
|
+
}
|
|
78
|
+
const home = process.env.HOME?.trim();
|
|
79
|
+
if (!home) {
|
|
80
|
+
throw new ConfigError("Unable to determine default stash directory. Set HOME.");
|
|
81
|
+
}
|
|
82
|
+
return path.join(home, "agentikit");
|
|
83
|
+
}
|