akm-cli 0.0.20 → 0.0.21
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/dist/asset-spec.js +6 -0
- package/dist/metadata.js +2 -6
- package/dist/stash-resolve.js +32 -2
- package/dist/stash-search.js +2 -3
- package/package.json +1 -1
package/dist/asset-spec.js
CHANGED
|
@@ -65,6 +65,12 @@ export function isRelevantAssetFile(assetType, fileName) {
|
|
|
65
65
|
export function deriveCanonicalAssetName(assetType, typeRoot, filePath) {
|
|
66
66
|
return ASSET_SPECS[assetType].toCanonicalName(typeRoot, filePath);
|
|
67
67
|
}
|
|
68
|
+
export function deriveCanonicalAssetNameFromStashRoot(assetType, stashRoot, filePath) {
|
|
69
|
+
const relPath = toPosix(path.relative(stashRoot, filePath));
|
|
70
|
+
const firstSegment = relPath.split("/").filter(Boolean)[0];
|
|
71
|
+
const typeRoot = firstSegment === TYPE_DIRS[assetType] ? path.join(stashRoot, firstSegment) : stashRoot;
|
|
72
|
+
return deriveCanonicalAssetName(assetType, typeRoot, filePath);
|
|
73
|
+
}
|
|
68
74
|
export function resolveAssetPathFromName(assetType, typeRoot, name) {
|
|
69
75
|
return ASSET_SPECS[assetType].toAssetPath(typeRoot, name);
|
|
70
76
|
}
|
package/dist/metadata.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { deriveCanonicalAssetName,
|
|
3
|
+
import { deriveCanonicalAssetName, deriveCanonicalAssetNameFromStashRoot, isRelevantAssetFile } from "./asset-spec";
|
|
4
4
|
import { isAssetType } from "./common";
|
|
5
5
|
import { buildFileContext, buildRenderContext, getRenderer, runMatchers } from "./file-context";
|
|
6
6
|
import { parseFrontmatter, toStringOrUndefined } from "./frontmatter";
|
|
@@ -204,8 +204,6 @@ export function generateMetadata(dirPath, assetType, files, typeRoot = dirPath)
|
|
|
204
204
|
}
|
|
205
205
|
return { entries };
|
|
206
206
|
}
|
|
207
|
-
/** Set of all known type directory names (e.g. "scripts", "skills", "agents") */
|
|
208
|
-
const TYPE_DIR_NAMES = new Set(Object.values(TYPE_DIRS));
|
|
209
207
|
/**
|
|
210
208
|
* Generate metadata for files using the matcher system instead of a fixed asset type.
|
|
211
209
|
*
|
|
@@ -227,11 +225,9 @@ export function generateMetadataFlat(stashRoot, files) {
|
|
|
227
225
|
// If the file lives under a known type directory, use that as the root
|
|
228
226
|
// for canonical naming so names don't include the type prefix.
|
|
229
227
|
// e.g. scripts/deploy.sh → "deploy.sh" not "scripts/deploy.sh"
|
|
230
|
-
const firstAncestor = ctx.ancestorDirs[0];
|
|
231
|
-
const effectiveRoot = firstAncestor && TYPE_DIR_NAMES.has(firstAncestor) ? path.join(stashRoot, firstAncestor) : stashRoot;
|
|
232
228
|
const ext = path.extname(file).toLowerCase();
|
|
233
229
|
const baseName = path.basename(file, ext);
|
|
234
|
-
const canonicalName =
|
|
230
|
+
const canonicalName = deriveCanonicalAssetNameFromStashRoot(assetType, stashRoot, file) ?? baseName;
|
|
235
231
|
const entry = {
|
|
236
232
|
name: canonicalName,
|
|
237
233
|
type: assetType,
|
package/dist/stash-resolve.js
CHANGED
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { isRelevantAssetFile, resolveAssetPathFromName, TYPE_DIRS } from "./asset-spec";
|
|
3
|
+
import { deriveCanonicalAssetNameFromStashRoot, isRelevantAssetFile, resolveAssetPathFromName, TYPE_DIRS, } from "./asset-spec";
|
|
4
4
|
import { hasErrnoCode, isWithin } from "./common";
|
|
5
5
|
import { NotFoundError, UsageError } from "./errors";
|
|
6
|
+
import { runMatchers } from "./file-context";
|
|
7
|
+
import { walkStashFlat } from "./walker";
|
|
6
8
|
/**
|
|
7
9
|
* Resolve an asset path from a stash directory, type, and name.
|
|
8
10
|
*/
|
|
9
11
|
export function resolveAssetPath(stashDir, type, name) {
|
|
10
|
-
|
|
12
|
+
try {
|
|
13
|
+
return resolveInTypeDir(stashDir, TYPE_DIRS[type], type, name);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (!(error instanceof NotFoundError))
|
|
17
|
+
throw error;
|
|
18
|
+
const fallback = resolveByCanonicalName(stashDir, type, name);
|
|
19
|
+
if (fallback)
|
|
20
|
+
return fallback;
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
11
23
|
}
|
|
12
24
|
/**
|
|
13
25
|
* Try to resolve an asset path within a specific type directory.
|
|
@@ -53,3 +65,21 @@ function readTypeRootStat(root, type, name) {
|
|
|
53
65
|
throw error;
|
|
54
66
|
}
|
|
55
67
|
}
|
|
68
|
+
function resolveByCanonicalName(stashDir, type, name) {
|
|
69
|
+
const normalizedName = name.replace(/\\/g, "/");
|
|
70
|
+
for (const ctx of walkStashFlat(stashDir)) {
|
|
71
|
+
const match = runMatchers(ctx);
|
|
72
|
+
if (!match || match.type !== type)
|
|
73
|
+
continue;
|
|
74
|
+
const canonicalName = deriveCanonicalAssetNameFromStashRoot(type, stashDir, ctx.absPath);
|
|
75
|
+
if (canonicalName !== normalizedName)
|
|
76
|
+
continue;
|
|
77
|
+
const realTarget = fs.realpathSync(ctx.absPath);
|
|
78
|
+
const resolvedRoot = fs.realpathSync(stashDir);
|
|
79
|
+
if (!isWithin(realTarget, resolvedRoot)) {
|
|
80
|
+
throw new UsageError("Ref resolves outside the stash root.");
|
|
81
|
+
}
|
|
82
|
+
return realTarget;
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
package/dist/stash-search.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { deriveCanonicalAssetNameFromStashRoot } from "./asset-spec";
|
|
4
4
|
import { loadConfig } from "./config";
|
|
5
5
|
import { closeDatabase, getAllEntries, getEntryById, getEntryCount, getMeta, openDatabase, searchFts, searchVec, } from "./db";
|
|
6
6
|
import { UsageError } from "./errors";
|
|
@@ -303,8 +303,7 @@ function substringSearch(query, searchType, limit, stashDir, sources, config) {
|
|
|
303
303
|
// ── Hit building ────────────────────────────────────────────────────────────
|
|
304
304
|
function buildDbHit(input) {
|
|
305
305
|
const entryStashDir = findSourceForPath(input.path, input.sources)?.path ?? input.defaultStashDir;
|
|
306
|
-
const
|
|
307
|
-
const canonical = deriveCanonicalAssetName(input.entry.type, typeRoot, input.path);
|
|
306
|
+
const canonical = deriveCanonicalAssetNameFromStashRoot(input.entry.type, entryStashDir, input.path);
|
|
308
307
|
// Guard against path traversal when the file is outside the expected type root
|
|
309
308
|
// (e.g. source detection fell back to defaultStashDir for a file from another source)
|
|
310
309
|
const refName = canonical && !canonical.startsWith("../") && !canonical.startsWith("..\\") ? canonical : input.entry.name;
|