skilld 1.7.3 → 1.7.4
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/_chunks/agent.mjs +693 -599
- package/dist/_chunks/agent.mjs.map +1 -1
- package/dist/_chunks/assemble.mjs +3 -3
- package/dist/_chunks/author.mjs +51 -121
- package/dist/_chunks/author.mjs.map +1 -1
- package/dist/_chunks/cache.mjs +315 -9
- package/dist/_chunks/cache.mjs.map +1 -1
- package/dist/_chunks/cache2.mjs +2 -2
- package/dist/_chunks/cli-helpers.mjs +3 -3
- package/dist/_chunks/core.mjs +7 -4
- package/dist/_chunks/detect.mjs +1 -1
- package/dist/_chunks/embedding-cache2.mjs +2 -2
- package/dist/_chunks/index.d.mts +305 -112
- package/dist/_chunks/index.d.mts.map +1 -1
- package/dist/_chunks/index2.d.mts +267 -32
- package/dist/_chunks/index2.d.mts.map +1 -1
- package/dist/_chunks/index3.d.mts +32 -577
- package/dist/_chunks/index3.d.mts.map +1 -1
- package/dist/_chunks/index4.d.mts +553 -0
- package/dist/_chunks/index4.d.mts.map +1 -0
- package/dist/_chunks/install.mjs +48 -88
- package/dist/_chunks/install.mjs.map +1 -1
- package/dist/_chunks/list.mjs +1 -1
- package/dist/_chunks/lockfile.mjs +29 -6
- package/dist/_chunks/lockfile.mjs.map +1 -1
- package/dist/_chunks/monorepo.mjs +71 -0
- package/dist/_chunks/monorepo.mjs.map +1 -0
- package/dist/_chunks/{shared.mjs → package-registry.mjs} +2 -40
- package/dist/_chunks/package-registry.mjs.map +1 -0
- package/dist/_chunks/paths.mjs +49 -0
- package/dist/_chunks/paths.mjs.map +1 -0
- package/dist/_chunks/pool2.mjs +1 -1
- package/dist/_chunks/prepare.mjs +1 -1
- package/dist/_chunks/prepare2.mjs +5 -5
- package/dist/_chunks/prepare2.mjs.map +1 -1
- package/dist/_chunks/prompts.mjs +366 -18
- package/dist/_chunks/prompts.mjs.map +1 -1
- package/dist/_chunks/search-helpers.mjs +5 -6
- package/dist/_chunks/search-helpers.mjs.map +1 -1
- package/dist/_chunks/search-interactive.mjs +1 -1
- package/dist/_chunks/search.mjs +1 -2
- package/dist/_chunks/search.mjs.map +1 -1
- package/dist/_chunks/semver.mjs +13 -0
- package/dist/_chunks/semver.mjs.map +1 -0
- package/dist/_chunks/skill-installer.mjs +2 -0
- package/dist/_chunks/skill-installer2.mjs +155 -0
- package/dist/_chunks/skill-installer2.mjs.map +1 -0
- package/dist/_chunks/skills.mjs +10 -9
- package/dist/_chunks/skills.mjs.map +1 -1
- package/dist/_chunks/sources.mjs +549 -372
- package/dist/_chunks/sources.mjs.map +1 -1
- package/dist/_chunks/sync-pipeline.mjs +952 -0
- package/dist/_chunks/sync-pipeline.mjs.map +1 -0
- package/dist/_chunks/sync-registry.mjs +19 -13
- package/dist/_chunks/sync-registry.mjs.map +1 -1
- package/dist/_chunks/sync.mjs +797 -886
- package/dist/_chunks/sync.mjs.map +1 -1
- package/dist/_chunks/sync2.mjs +4 -2
- package/dist/_chunks/types.d.mts +65 -77
- package/dist/_chunks/types.d.mts.map +1 -1
- package/dist/_chunks/types2.d.mts +88 -0
- package/dist/_chunks/types2.d.mts.map +1 -0
- package/dist/_chunks/uninstall.mjs +7 -8
- package/dist/_chunks/uninstall.mjs.map +1 -1
- package/dist/_chunks/upload.mjs +2 -2
- package/dist/_chunks/validate.mjs +1 -1
- package/dist/_chunks/version.mjs +3 -13
- package/dist/_chunks/version.mjs.map +1 -1
- package/dist/_chunks/wizard.mjs +2 -2
- package/dist/agent/index.d.mts +2 -346
- package/dist/agent/index.mjs +2 -3
- package/dist/cache/index.d.mts +2 -2
- package/dist/cache/index.mjs +4 -3
- package/dist/cli.mjs +12 -13
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +5 -4
- package/dist/index.mjs +4 -3
- package/dist/prepare.mjs +2 -2
- package/dist/prepare.mjs.map +1 -1
- package/dist/retriv/index.d.mts +2 -2
- package/dist/retriv/worker.d.mts +1 -1
- package/dist/sources/index.d.mts +3 -2
- package/dist/sources/index.mjs +3 -3
- package/dist/types.d.mts +3 -3
- package/package.json +2 -2
- package/dist/_chunks/config.mjs +0 -122
- package/dist/_chunks/config.mjs.map +0 -1
- package/dist/_chunks/prefix.mjs +0 -108
- package/dist/_chunks/prefix.mjs.map +0 -1
- package/dist/_chunks/shared.mjs.map +0 -1
- package/dist/_chunks/skill.mjs +0 -329
- package/dist/_chunks/skill.mjs.map +0 -1
- package/dist/_chunks/sync-shared.mjs +0 -2
- package/dist/_chunks/sync-shared2.mjs +0 -1020
- package/dist/_chunks/sync-shared2.mjs.map +0 -1
- package/dist/agent/index.d.mts.map +0 -1
package/dist/_chunks/types.d.mts
CHANGED
|
@@ -1,88 +1,76 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Doc resolver types
|
|
3
|
+
*/
|
|
4
|
+
interface NpmPackageInfo {
|
|
2
5
|
name: string;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
version?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
homepage?: string;
|
|
9
|
+
repository?: string | {
|
|
10
|
+
type: string;
|
|
11
|
+
url: string;
|
|
12
|
+
directory?: string;
|
|
13
|
+
};
|
|
14
|
+
readme?: string;
|
|
15
|
+
dependencies?: Record<string, string>;
|
|
16
|
+
devDependencies?: Record<string, string>;
|
|
17
|
+
peerDependencies?: Record<string, string>;
|
|
6
18
|
}
|
|
7
|
-
interface
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
19
|
+
interface ResolvedPackage {
|
|
20
|
+
name: string;
|
|
21
|
+
version?: string;
|
|
22
|
+
/** ISO date string when this version was released */
|
|
23
|
+
releasedAt?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
/** Production dependencies with version specifiers */
|
|
26
|
+
dependencies?: Record<string, string>;
|
|
27
|
+
/** npm dist-tags with version and release date */
|
|
28
|
+
distTags?: Record<string, {
|
|
29
|
+
version: string;
|
|
30
|
+
releasedAt?: string;
|
|
31
|
+
}>;
|
|
32
|
+
docsUrl?: string;
|
|
33
|
+
llmsUrl?: string;
|
|
34
|
+
readmeUrl?: string;
|
|
35
|
+
repoUrl?: string;
|
|
36
|
+
/** Git docs folder - versioned docs from repo */
|
|
37
|
+
gitDocsUrl?: string;
|
|
38
|
+
/** Git tag/ref used for gitDocsUrl */
|
|
39
|
+
gitRef?: string;
|
|
40
|
+
/** True when gitRef is a branch fallback (no version tag found) */
|
|
41
|
+
gitDocsFallback?: boolean;
|
|
42
|
+
/** URL pattern to crawl for docs */
|
|
43
|
+
crawlUrl?: string;
|
|
11
44
|
}
|
|
12
|
-
interface
|
|
13
|
-
|
|
14
|
-
|
|
45
|
+
interface LocalDependency {
|
|
46
|
+
name: string;
|
|
47
|
+
version: string;
|
|
15
48
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
total: number;
|
|
49
|
+
interface LlmsContent {
|
|
50
|
+
raw: string;
|
|
51
|
+
/** Markdown links extracted from llms.txt */
|
|
52
|
+
links: LlmsLink[];
|
|
21
53
|
}
|
|
22
|
-
interface
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
chunking?: ChunkingOptions;
|
|
26
|
-
/** Progress callback forwarded from retriv */
|
|
27
|
-
onProgress?: (progress: IndexProgress) => void;
|
|
54
|
+
interface LlmsLink {
|
|
55
|
+
title: string;
|
|
56
|
+
url: string;
|
|
28
57
|
}
|
|
29
|
-
interface
|
|
30
|
-
|
|
58
|
+
interface FetchedDoc {
|
|
59
|
+
url: string;
|
|
60
|
+
title: string;
|
|
31
61
|
content: string;
|
|
32
|
-
score: number;
|
|
33
|
-
metadata: Record<string, any>;
|
|
34
|
-
highlights: string[];
|
|
35
|
-
/** Line range from chunk [start, end] */
|
|
36
|
-
lineRange?: [number, number];
|
|
37
|
-
entities?: ChunkEntity[];
|
|
38
|
-
scope?: ChunkEntity[];
|
|
39
62
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
$gt: number;
|
|
46
|
-
} | {
|
|
47
|
-
$gte: number;
|
|
48
|
-
} | {
|
|
49
|
-
$lt: number;
|
|
50
|
-
} | {
|
|
51
|
-
$lte: number;
|
|
52
|
-
} | {
|
|
53
|
-
$in: (string | number)[];
|
|
54
|
-
} | {
|
|
55
|
-
$prefix: string;
|
|
56
|
-
} | {
|
|
57
|
-
$exists: boolean;
|
|
58
|
-
};
|
|
59
|
-
type FilterValue = string | number | boolean | FilterOperator;
|
|
60
|
-
type SearchFilter = Record<string, FilterValue>;
|
|
61
|
-
interface SearchOptions {
|
|
62
|
-
/** Max results */
|
|
63
|
-
limit?: number;
|
|
64
|
-
/** Filter by metadata fields */
|
|
65
|
-
filter?: SearchFilter;
|
|
63
|
+
interface ResolveAttempt {
|
|
64
|
+
source: 'npm' | 'crates' | 'github-docs' | 'github-meta' | 'github-search' | 'llms.txt' | 'readme';
|
|
65
|
+
url?: string;
|
|
66
|
+
status: 'success' | 'not-found' | 'error';
|
|
67
|
+
message?: string;
|
|
66
68
|
}
|
|
67
|
-
interface
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
/** Start line number */
|
|
73
|
-
lineStart: number;
|
|
74
|
-
/** End line number */
|
|
75
|
-
lineEnd: number;
|
|
76
|
-
/** Snippet content (5 lines around best match) */
|
|
77
|
-
content: string;
|
|
78
|
-
/** Relevance score */
|
|
79
|
-
score: number;
|
|
80
|
-
/** Matched query terms, ordered by BM25 score */
|
|
81
|
-
highlights: string[];
|
|
82
|
-
/** Entities defined in this chunk */
|
|
83
|
-
entities?: ChunkEntity[];
|
|
84
|
-
/** Containing scope chain */
|
|
85
|
-
scope?: ChunkEntity[];
|
|
69
|
+
interface ResolveResult {
|
|
70
|
+
package: ResolvedPackage | null;
|
|
71
|
+
attempts: ResolveAttempt[];
|
|
72
|
+
/** npm registry version, available even when doc resolution fails */
|
|
73
|
+
registryVersion?: string;
|
|
86
74
|
}
|
|
87
|
-
export {
|
|
75
|
+
export { NpmPackageInfo as a, ResolvedPackage as c, LocalDependency as i, LlmsContent as n, ResolveAttempt as o, LlmsLink as r, ResolveResult as s, FetchedDoc as t };
|
|
88
76
|
//# sourceMappingURL=types.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/sources/types.ts"],"mappings":"AAIA;;;AAAA,UAAiB,cAAA;EACf,IAAA;EACA,OAAA;EACA,WAAA;EACA,QAAA;EACA,UAAA;IACE,IAAA;IACA,GAAA;IACA,SAAA;EAAA;EAEF,MAAA;EACA,YAAA,GAAe,MAAA;EACf,eAAA,GAAkB,MAAA;EAClB,gBAAA,GAAmB,MAAA;AAAA;AAAA,UAGJ,eAAA;EACf,IAAA;EACA,OAAA;EALA;EAOA,UAAA;EACA,WAAA;EARyB;EAUzB,YAAA,GAAe,MAAA;EAPe;EAS9B,QAAA,GAAW,MAAA;IAAiB,OAAA;IAAiB,UAAA;EAAA;EAC7C,OAAA;EACA,OAAA;EACA,SAAA;EACA,OAAA;EAJA;EAMA,UAAA;EAN4B;EAQ5B,MAAA;EAPA;EASA,eAAA;EAPA;EASA,QAAA;AAAA;AAAA,UAGe,eAAA;EACf,IAAA;EACA,OAAA;AAAA;AAAA,UAGe,WAAA;EACf,GAAA;EAN8B;EAQ9B,KAAA,EAAO,QAAA;AAAA;AAAA,UAGQ,QAAA;EACf,KAAA;EACA,GAAA;AAAA;AAAA,UAGe,UAAA;EACf,GAAA;EACA,KAAA;EACA,OAAA;AAAA;AAAA,UAGe,cAAA;EACf,MAAA;EACA,GAAA;EACA,MAAA;EACA,OAAA;AAAA;AAAA,UAGe,aAAA;EACf,OAAA,EAAS,eAAA;EACT,QAAA,EAAU,cAAA;EAfe;EAiBzB,eAAA;AAAA"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
interface ChunkEntity {
|
|
2
|
+
name: string;
|
|
3
|
+
type: string;
|
|
4
|
+
signature?: string;
|
|
5
|
+
isPartial?: boolean;
|
|
6
|
+
}
|
|
7
|
+
interface Document {
|
|
8
|
+
id: string;
|
|
9
|
+
content: string;
|
|
10
|
+
metadata?: Record<string, any>;
|
|
11
|
+
}
|
|
12
|
+
interface ChunkingOptions {
|
|
13
|
+
chunkSize?: number;
|
|
14
|
+
chunkOverlap?: number;
|
|
15
|
+
}
|
|
16
|
+
type IndexPhase = 'chunking' | 'embedding' | 'storing';
|
|
17
|
+
interface IndexProgress {
|
|
18
|
+
phase: IndexPhase;
|
|
19
|
+
current: number;
|
|
20
|
+
total: number;
|
|
21
|
+
}
|
|
22
|
+
interface IndexConfig {
|
|
23
|
+
dbPath: string;
|
|
24
|
+
model?: string;
|
|
25
|
+
chunking?: ChunkingOptions;
|
|
26
|
+
/** Progress callback forwarded from retriv */
|
|
27
|
+
onProgress?: (progress: IndexProgress) => void;
|
|
28
|
+
}
|
|
29
|
+
interface SearchResult {
|
|
30
|
+
id: string;
|
|
31
|
+
content: string;
|
|
32
|
+
score: number;
|
|
33
|
+
metadata: Record<string, any>;
|
|
34
|
+
highlights: string[];
|
|
35
|
+
/** Line range from chunk [start, end] */
|
|
36
|
+
lineRange?: [number, number];
|
|
37
|
+
entities?: ChunkEntity[];
|
|
38
|
+
scope?: ChunkEntity[];
|
|
39
|
+
}
|
|
40
|
+
type FilterOperator = {
|
|
41
|
+
$eq: string | number | boolean;
|
|
42
|
+
} | {
|
|
43
|
+
$ne: string | number | boolean;
|
|
44
|
+
} | {
|
|
45
|
+
$gt: number;
|
|
46
|
+
} | {
|
|
47
|
+
$gte: number;
|
|
48
|
+
} | {
|
|
49
|
+
$lt: number;
|
|
50
|
+
} | {
|
|
51
|
+
$lte: number;
|
|
52
|
+
} | {
|
|
53
|
+
$in: (string | number)[];
|
|
54
|
+
} | {
|
|
55
|
+
$prefix: string;
|
|
56
|
+
} | {
|
|
57
|
+
$exists: boolean;
|
|
58
|
+
};
|
|
59
|
+
type FilterValue = string | number | boolean | FilterOperator;
|
|
60
|
+
type SearchFilter = Record<string, FilterValue>;
|
|
61
|
+
interface SearchOptions {
|
|
62
|
+
/** Max results */
|
|
63
|
+
limit?: number;
|
|
64
|
+
/** Filter by metadata fields */
|
|
65
|
+
filter?: SearchFilter;
|
|
66
|
+
}
|
|
67
|
+
interface SearchSnippet {
|
|
68
|
+
/** Package name and version */
|
|
69
|
+
package: string;
|
|
70
|
+
/** Source file path */
|
|
71
|
+
source: string;
|
|
72
|
+
/** Start line number */
|
|
73
|
+
lineStart: number;
|
|
74
|
+
/** End line number */
|
|
75
|
+
lineEnd: number;
|
|
76
|
+
/** Snippet content (5 lines around best match) */
|
|
77
|
+
content: string;
|
|
78
|
+
/** Relevance score */
|
|
79
|
+
score: number;
|
|
80
|
+
/** Matched query terms, ordered by BM25 score */
|
|
81
|
+
highlights: string[];
|
|
82
|
+
/** Entities defined in this chunk */
|
|
83
|
+
entities?: ChunkEntity[];
|
|
84
|
+
/** Containing scope chain */
|
|
85
|
+
scope?: ChunkEntity[];
|
|
86
|
+
}
|
|
87
|
+
export { IndexProgress as a, SearchResult as c, IndexPhase as i, SearchSnippet as l, Document as n, SearchFilter as o, IndexConfig as r, SearchOptions as s, ChunkEntity as t };
|
|
88
|
+
//# sourceMappingURL=types2.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types2.d.mts","names":[],"sources":["../../src/retriv/types.ts"],"mappings":"UAAiB,WAAA;EACf,IAAA;EACA,IAAA;EACA,SAAA;EACA,SAAA;AAAA;AAAA,UAGe,QAAA;EACf,EAAA;EACA,OAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,UAGI,eAAA;EACf,SAAA;EACA,YAAA;AAAA;AAAA,KAGU,UAAA;AAAA,UAEK,aAAA;EACf,KAAA,EAAO,UAAA;EACP,OAAA;EACA,KAAA;AAAA;AAAA,UAGe,WAAA;EACf,MAAA;EACA,KAAA;EACA,QAAA,GAAW,eAAA;EAXD;EAaV,UAAA,IAAc,QAAA,EAAU,aAAA;AAAA;AAAA,UAGT,YAAA;EACf,EAAA;EACA,OAAA;EACA,KAAA;EACA,QAAA,EAAU,MAAA;EACV,UAAA;EAlBA;EAoBA,SAAA;EACA,QAAA,GAAW,WAAA;EACX,KAAA,GAAQ,WAAA;AAAA;AAAA,KAGE,cAAA;EACJ,GAAA;AAAA;EACA,GAAA;AAAA;EACA,GAAA;AAAA;EACA,IAAA;AAAA;EACA,GAAA;AAAA;EACA,IAAA;AAAA;EACA,GAAA;AAAA;EACA,OAAA;AAAA;EACA,OAAA;AAAA;AAAA,KAEI,WAAA,+BAA0C,cAAA;AAAA,KAC1C,YAAA,GAAe,MAAA,SAAe,WAAA;AAAA,UAEzB,aAAA;EAzBf;EA2BA,KAAA;EAzBA;EA2BA,MAAA,GAAS,YAAA;AAAA;AAAA,UAGM,aAAA;EA1Bf;EA4BA,OAAA;EA3BW;EA6BX,MAAA;EA5BQ;EA8BR,SAAA;EA9BmB;EAgCnB,OAAA;EA7BwB;EA+BxB,OAAA;EA/BwB;EAiCxB,KAAA;EA/BM;EAiCN,UAAA;EA/BM;EAiCN,QAAA,GAAW,WAAA;EA/BL;EAiCN,KAAA,GAAQ,WAAA;AAAA"}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import {
|
|
3
|
-
import "./
|
|
4
|
-
import { r as mapInsert, t as SHARED_SKILLS_DIR } from "./shared.mjs";
|
|
1
|
+
import { c as SHARED_SKILLS_DIR, t as CACHE_DIR } from "./paths.mjs";
|
|
2
|
+
import { I as unregisterProject, j as getRegisteredProjects } from "./cache.mjs";
|
|
3
|
+
import { X as mapInsert } from "./sources.mjs";
|
|
5
4
|
import { a as targets } from "./detect.mjs";
|
|
6
|
-
import
|
|
5
|
+
import "./agent.mjs";
|
|
7
6
|
import { p as isInteractive, x as sharedArgs } from "./cli-helpers.mjs";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
7
|
+
import { c as readLock } from "./lockfile.mjs";
|
|
8
|
+
import { n as SKILLD_MARKER_START, t as SKILLD_MARKER_END } from "./skill-installer2.mjs";
|
|
10
9
|
import "./sync.mjs";
|
|
11
|
-
import { join } from "pathe";
|
|
12
10
|
import { existsSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { join } from "pathe";
|
|
13
12
|
import * as p from "@clack/prompts";
|
|
14
13
|
import { defineCommand } from "citty";
|
|
15
14
|
function removeAgentInstructions(agent, projectPath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uninstall.mjs","names":["agents"],"sources":["../../src/commands/uninstall.ts"],"sourcesContent":["import type { AgentType } from '../agent/index.ts'\nimport { existsSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join } from 'pathe'\nimport { agents } from '../agent/index.ts'\nimport { CACHE_DIR } from '../cache/index.ts'\nimport { isInteractive, sharedArgs } from '../cli-helpers.ts'\nimport { getRegisteredProjects, unregisterProject } from '../core/config.ts'\nimport { readLock } from '../core/lockfile.ts'\nimport { mapInsert, SHARED_SKILLS_DIR } from '../core/shared.ts'\nimport { SKILLD_MARKER_END, SKILLD_MARKER_START } from './sync.ts'\n\n/**\n * Remove the skilld marker block from an agent's instruction file.\n * For .mdc files (dedicated skilld files), delete the entire file.\n * Also cleans up legacy .cursorrules markers for backwards compat.\n */\nfunction removeAgentInstructions(agent: AgentType, projectPath: string): boolean {\n const agentConfig = agents[agent]\n if (!agentConfig.instructionFile)\n return false\n\n let removed = false\n\n // Handle current instruction file\n const filePath = join(projectPath, agentConfig.instructionFile)\n if (agentConfig.instructionFile.endsWith('.mdc')) {\n // MDC files are dedicated skilld files - just delete\n if (existsSync(filePath)) {\n rmSync(filePath)\n removed = true\n }\n // Also clean up legacy .cursorrules markers (cursor-specific)\n if (agent === 'cursor')\n removed = removeMarkerBlock(join(projectPath, '.cursorrules')) || removed\n }\n else if (existsSync(filePath)) {\n removed = removeMarkerBlock(filePath)\n }\n\n return removed\n}\n\nfunction removeMarkerBlock(filePath: string): boolean {\n if (!existsSync(filePath))\n return false\n\n const content = readFileSync(filePath, 'utf-8')\n const startIdx = content.indexOf(SKILLD_MARKER_START)\n if (startIdx === -1)\n return false\n\n const endIdx = content.indexOf(SKILLD_MARKER_END, startIdx)\n if (endIdx === -1)\n return false\n\n // Remove marker block plus surrounding blank lines\n const before = content.slice(0, startIdx).replace(/\\n+$/, '')\n const after = content.slice(endIdx + SKILLD_MARKER_END.length).replace(/^\\n+/, '')\n const updated = before + (before && after ? '\\n' : '') + after\n\n if (updated.trim() === '') {\n rmSync(filePath)\n }\n else {\n writeFileSync(filePath, updated.endsWith('\\n') ? updated : `${updated}\\n`)\n }\n return true\n}\n\nexport interface UninstallOptions {\n scope?: 'project' | 'all'\n agent?: AgentType\n yes: boolean\n}\n\n/**\n * Uninstall skilld skills by scope:\n * - project: Remove project skills (cwd)\n * - all: All registered projects + global skills + cache\n */\nexport async function uninstallCommand(opts: UninstallOptions): Promise<void> {\n let scope = opts.scope\n const registeredProjects = getRegisteredProjects()\n\n // Prompt for scope if not provided\n if (!scope) {\n if (!isInteractive()) {\n scope = 'project'\n }\n else {\n const allHint = registeredProjects.length > 0\n ? `${registeredProjects.length} projects + global + cache`\n : 'global skills + cache'\n\n const selected = await p.select({\n message: 'What do you want to uninstall?',\n options: [\n { label: 'This project', value: 'project', hint: 'current project only' },\n { label: 'Everything', value: 'all', hint: allHint },\n ],\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Cancelled')\n return\n }\n scope = selected as 'project' | 'all'\n }\n }\n\n interface RemoveItem { label: string, path: string, version?: string }\n const toRemove: RemoveItem[] = []\n const seenPaths = new Set<string>()\n const projectsToUnregister: string[] = []\n const agentFilter = opts.agent ? [opts.agent] : undefined\n\n const addToRemove = (label: string, path: string, version?: string) => {\n if (seenPaths.has(path))\n return\n seenPaths.add(path)\n toRemove.push({ label, path, version })\n }\n\n // Helper to add skills from a lockfile\n const addSkillsFromLock = (skillsDir: string, label: string): string[] => {\n const trackedNames: string[] = []\n const lock = readLock(skillsDir)\n\n if (lock?.skills) {\n for (const [skillName, info] of Object.entries(lock.skills)) {\n trackedNames.push(skillName)\n const skillDir = join(skillsDir, skillName)\n if (existsSync(skillDir)) {\n const version = info.version ? `${info.version.split('.').slice(0, 2).join('.')}.x` : undefined\n addToRemove(`${label}: ${skillName}`, skillDir, version)\n }\n }\n\n // Also add the lockfile itself\n const lockPath = join(skillsDir, 'skilld-lock.yaml')\n if (existsSync(lockPath)) {\n addToRemove(`${label}: skilld-lock.yaml`, lockPath)\n }\n }\n\n return trackedNames\n }\n\n // Helper to find untracked skills in a directory\n const findUntrackedSkills = (skillsDir: string, trackedNames: string[]): string[] => {\n if (!existsSync(skillsDir))\n return []\n const tracked = new Set(trackedNames)\n return readdirSync(skillsDir)\n .filter(f => !f.startsWith('.') && f !== 'skilld-lock.yaml' && !tracked.has(f))\n }\n\n // Track untracked skills per directory (dedupe by path)\n const untrackedByDir = new Map<string, { label: string, skills: string[] }>()\n const processedDirs = new Set<string>()\n\n // Helper to process a skills directory (with deduping)\n const processSkillsDir = (skillsDir: string, label: string) => {\n if (processedDirs.has(skillsDir))\n return\n processedDirs.add(skillsDir)\n\n const tracked = addSkillsFromLock(skillsDir, label)\n const untracked = findUntrackedSkills(skillsDir, tracked)\n if (untracked.length > 0) {\n untrackedByDir.set(skillsDir, { label, skills: untracked })\n }\n }\n\n // Project skills\n if (scope === 'project') {\n // Shared dir\n const sharedDir = join(process.cwd(), SHARED_SKILLS_DIR)\n if (existsSync(sharedDir))\n processSkillsDir(sharedDir, 'project (.skills)')\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n processSkillsDir(join(process.cwd(), agent.skillsDir), 'project')\n }\n projectsToUnregister.push(process.cwd())\n }\n\n // All registered projects + global\n if (scope === 'all') {\n const projectPaths = registeredProjects.length > 0 ? registeredProjects : [process.cwd()]\n\n // Show which projects will be affected\n if (registeredProjects.length > 0) {\n p.log.info('Projects to uninstall from:')\n for (const proj of projectPaths) {\n p.log.message(` ${proj}`)\n }\n }\n\n // Project skills from lockfiles\n for (const projectPath of projectPaths) {\n if (!existsSync(projectPath))\n continue\n\n const shortPath = projectPath.replace(process.env.HOME || '', '~')\n\n // Shared dir\n const sharedDir = join(projectPath, SHARED_SKILLS_DIR)\n if (existsSync(sharedDir))\n processSkillsDir(sharedDir, `${shortPath} (.skills)`)\n\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n processSkillsDir(join(projectPath, agent.skillsDir), shortPath)\n }\n\n projectsToUnregister.push(projectPath)\n }\n\n // Global skills from lockfiles\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n if (!agent.globalSkillsDir)\n continue\n processSkillsDir(agent.globalSkillsDir, 'user')\n }\n\n // Cache directory\n if (existsSync(CACHE_DIR)) {\n addToRemove('~/.skilld cache', CACHE_DIR)\n }\n }\n\n // Warn about untracked skills that will remain (grouped by label, deduped)\n if (untrackedByDir.size > 0) {\n const groupedUntracked = new Map<string, Set<string>>()\n for (const [_dir, { label, skills }] of untrackedByDir) {\n const set = mapInsert(groupedUntracked, label, () => new Set())\n for (const s of skills) set.add(s)\n }\n\n const totalUntracked = [...groupedUntracked.values()].reduce((sum, s) => sum + s.size, 0)\n p.log.warn(`${totalUntracked} untracked skill(s) will remain (not managed by skilld):`)\n for (const [label, skills] of groupedUntracked) {\n p.log.message(` ${label}: ${[...skills].join(', ')}`)\n }\n }\n\n if (toRemove.length === 0) {\n p.log.info('Nothing to uninstall')\n return\n }\n\n // Group by prefix for display\n const groups = new Map<string, Array<{ name: string, version?: string }>>()\n for (const item of toRemove) {\n const [prefix, name] = item.label.includes(': ')\n ? item.label.split(': ', 2)\n : ['other', item.label]\n mapInsert(groups, prefix!, () => []).push({ name: name!, version: item.version })\n }\n\n const formatGroup = (items: Array<{ name: string, version?: string }>) =>\n items.map(i => i.version ? `${i.name}@${i.version}` : i.name).join(', ')\n\n p.log.info(`Will remove ${toRemove.length} items:`)\n for (const [prefix, items] of groups) {\n p.log.message(` ${prefix}: ${formatGroup(items)}`)\n }\n\n if (!opts.yes && isInteractive()) {\n const confirmed = await p.confirm({\n message: 'Proceed with uninstall?',\n })\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('Cancelled')\n return\n }\n }\n\n // Remove all items\n for (const item of toRemove) {\n rmSync(item.path, { recursive: true, force: true })\n }\n\n // Show grouped removal summary\n for (const [prefix, items] of groups) {\n p.log.success(`Removed ${prefix}: ${formatGroup(items)}`)\n }\n\n // Remove skilld instructions from agent instruction files\n const agentTypes = agentFilter || (Object.keys(agents) as AgentType[])\n for (const proj of projectsToUnregister) {\n for (const agent of agentTypes) {\n if (removeAgentInstructions(agent, proj)) {\n const file = agents[agent].instructionFile!\n p.log.success(`Cleaned ${file}`)\n }\n }\n }\n\n // Unregister projects from config (skip if cache dir was removed — config is gone)\n if (scope !== 'all') {\n for (const proj of projectsToUnregister) {\n unregisterProject(proj)\n }\n }\n\n p.outro('skilld uninstalled')\n}\n\nexport const uninstallCommandDef = defineCommand({\n meta: { name: 'uninstall', description: 'Remove skilld data' },\n args: {\n ...sharedArgs,\n },\n async run({ args }) {\n p.intro(`\\x1B[1m\\x1B[35mskilld\\x1B[0m uninstall`)\n return uninstallCommand({\n scope: args.global ? 'all' : undefined,\n agent: args.agent as AgentType | undefined,\n yes: args.yes,\n })\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uninstall.mjs","names":["agents"],"sources":["../../src/commands/uninstall.ts"],"sourcesContent":["import type { AgentType } from '../agent/index.ts'\nimport { existsSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join } from 'pathe'\nimport { agents } from '../agent/index.ts'\nimport { CACHE_DIR } from '../cache/index.ts'\nimport { isInteractive, sharedArgs } from '../cli-helpers.ts'\nimport { getRegisteredProjects, unregisterProject } from '../core/config.ts'\nimport { readLock } from '../core/lockfile.ts'\nimport { mapInsert } from '../core/map.ts'\nimport { SHARED_SKILLS_DIR } from '../core/paths.ts'\nimport { SKILLD_MARKER_END, SKILLD_MARKER_START } from './sync.ts'\n\n/**\n * Remove the skilld marker block from an agent's instruction file.\n * For .mdc files (dedicated skilld files), delete the entire file.\n * Also cleans up legacy .cursorrules markers for backwards compat.\n */\nfunction removeAgentInstructions(agent: AgentType, projectPath: string): boolean {\n const agentConfig = agents[agent]\n if (!agentConfig.instructionFile)\n return false\n\n let removed = false\n\n // Handle current instruction file\n const filePath = join(projectPath, agentConfig.instructionFile)\n if (agentConfig.instructionFile.endsWith('.mdc')) {\n // MDC files are dedicated skilld files - just delete\n if (existsSync(filePath)) {\n rmSync(filePath)\n removed = true\n }\n // Also clean up legacy .cursorrules markers (cursor-specific)\n if (agent === 'cursor')\n removed = removeMarkerBlock(join(projectPath, '.cursorrules')) || removed\n }\n else if (existsSync(filePath)) {\n removed = removeMarkerBlock(filePath)\n }\n\n return removed\n}\n\nfunction removeMarkerBlock(filePath: string): boolean {\n if (!existsSync(filePath))\n return false\n\n const content = readFileSync(filePath, 'utf-8')\n const startIdx = content.indexOf(SKILLD_MARKER_START)\n if (startIdx === -1)\n return false\n\n const endIdx = content.indexOf(SKILLD_MARKER_END, startIdx)\n if (endIdx === -1)\n return false\n\n // Remove marker block plus surrounding blank lines\n const before = content.slice(0, startIdx).replace(/\\n+$/, '')\n const after = content.slice(endIdx + SKILLD_MARKER_END.length).replace(/^\\n+/, '')\n const updated = before + (before && after ? '\\n' : '') + after\n\n if (updated.trim() === '') {\n rmSync(filePath)\n }\n else {\n writeFileSync(filePath, updated.endsWith('\\n') ? updated : `${updated}\\n`)\n }\n return true\n}\n\nexport interface UninstallOptions {\n scope?: 'project' | 'all'\n agent?: AgentType\n yes: boolean\n}\n\n/**\n * Uninstall skilld skills by scope:\n * - project: Remove project skills (cwd)\n * - all: All registered projects + global skills + cache\n */\nexport async function uninstallCommand(opts: UninstallOptions): Promise<void> {\n let scope = opts.scope\n const registeredProjects = getRegisteredProjects()\n\n // Prompt for scope if not provided\n if (!scope) {\n if (!isInteractive()) {\n scope = 'project'\n }\n else {\n const allHint = registeredProjects.length > 0\n ? `${registeredProjects.length} projects + global + cache`\n : 'global skills + cache'\n\n const selected = await p.select({\n message: 'What do you want to uninstall?',\n options: [\n { label: 'This project', value: 'project', hint: 'current project only' },\n { label: 'Everything', value: 'all', hint: allHint },\n ],\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Cancelled')\n return\n }\n scope = selected as 'project' | 'all'\n }\n }\n\n interface RemoveItem { label: string, path: string, version?: string }\n const toRemove: RemoveItem[] = []\n const seenPaths = new Set<string>()\n const projectsToUnregister: string[] = []\n const agentFilter = opts.agent ? [opts.agent] : undefined\n\n const addToRemove = (label: string, path: string, version?: string) => {\n if (seenPaths.has(path))\n return\n seenPaths.add(path)\n toRemove.push({ label, path, version })\n }\n\n // Helper to add skills from a lockfile\n const addSkillsFromLock = (skillsDir: string, label: string): string[] => {\n const trackedNames: string[] = []\n const lock = readLock(skillsDir)\n\n if (lock?.skills) {\n for (const [skillName, info] of Object.entries(lock.skills)) {\n trackedNames.push(skillName)\n const skillDir = join(skillsDir, skillName)\n if (existsSync(skillDir)) {\n const version = info.version ? `${info.version.split('.').slice(0, 2).join('.')}.x` : undefined\n addToRemove(`${label}: ${skillName}`, skillDir, version)\n }\n }\n\n // Also add the lockfile itself\n const lockPath = join(skillsDir, 'skilld-lock.yaml')\n if (existsSync(lockPath)) {\n addToRemove(`${label}: skilld-lock.yaml`, lockPath)\n }\n }\n\n return trackedNames\n }\n\n // Helper to find untracked skills in a directory\n const findUntrackedSkills = (skillsDir: string, trackedNames: string[]): string[] => {\n if (!existsSync(skillsDir))\n return []\n const tracked = new Set(trackedNames)\n return readdirSync(skillsDir)\n .filter(f => !f.startsWith('.') && f !== 'skilld-lock.yaml' && !tracked.has(f))\n }\n\n // Track untracked skills per directory (dedupe by path)\n const untrackedByDir = new Map<string, { label: string, skills: string[] }>()\n const processedDirs = new Set<string>()\n\n // Helper to process a skills directory (with deduping)\n const processSkillsDir = (skillsDir: string, label: string) => {\n if (processedDirs.has(skillsDir))\n return\n processedDirs.add(skillsDir)\n\n const tracked = addSkillsFromLock(skillsDir, label)\n const untracked = findUntrackedSkills(skillsDir, tracked)\n if (untracked.length > 0) {\n untrackedByDir.set(skillsDir, { label, skills: untracked })\n }\n }\n\n // Project skills\n if (scope === 'project') {\n // Shared dir\n const sharedDir = join(process.cwd(), SHARED_SKILLS_DIR)\n if (existsSync(sharedDir))\n processSkillsDir(sharedDir, 'project (.skills)')\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n processSkillsDir(join(process.cwd(), agent.skillsDir), 'project')\n }\n projectsToUnregister.push(process.cwd())\n }\n\n // All registered projects + global\n if (scope === 'all') {\n const projectPaths = registeredProjects.length > 0 ? registeredProjects : [process.cwd()]\n\n // Show which projects will be affected\n if (registeredProjects.length > 0) {\n p.log.info('Projects to uninstall from:')\n for (const proj of projectPaths) {\n p.log.message(` ${proj}`)\n }\n }\n\n // Project skills from lockfiles\n for (const projectPath of projectPaths) {\n if (!existsSync(projectPath))\n continue\n\n const shortPath = projectPath.replace(process.env.HOME || '', '~')\n\n // Shared dir\n const sharedDir = join(projectPath, SHARED_SKILLS_DIR)\n if (existsSync(sharedDir))\n processSkillsDir(sharedDir, `${shortPath} (.skills)`)\n\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n processSkillsDir(join(projectPath, agent.skillsDir), shortPath)\n }\n\n projectsToUnregister.push(projectPath)\n }\n\n // Global skills from lockfiles\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n if (!agent.globalSkillsDir)\n continue\n processSkillsDir(agent.globalSkillsDir, 'user')\n }\n\n // Cache directory\n if (existsSync(CACHE_DIR)) {\n addToRemove('~/.skilld cache', CACHE_DIR)\n }\n }\n\n // Warn about untracked skills that will remain (grouped by label, deduped)\n if (untrackedByDir.size > 0) {\n const groupedUntracked = new Map<string, Set<string>>()\n for (const [_dir, { label, skills }] of untrackedByDir) {\n const set = mapInsert(groupedUntracked, label, () => new Set())\n for (const s of skills) set.add(s)\n }\n\n const totalUntracked = [...groupedUntracked.values()].reduce((sum, s) => sum + s.size, 0)\n p.log.warn(`${totalUntracked} untracked skill(s) will remain (not managed by skilld):`)\n for (const [label, skills] of groupedUntracked) {\n p.log.message(` ${label}: ${[...skills].join(', ')}`)\n }\n }\n\n if (toRemove.length === 0) {\n p.log.info('Nothing to uninstall')\n return\n }\n\n // Group by prefix for display\n const groups = new Map<string, Array<{ name: string, version?: string }>>()\n for (const item of toRemove) {\n const [prefix, name] = item.label.includes(': ')\n ? item.label.split(': ', 2)\n : ['other', item.label]\n mapInsert(groups, prefix!, () => []).push({ name: name!, version: item.version })\n }\n\n const formatGroup = (items: Array<{ name: string, version?: string }>) =>\n items.map(i => i.version ? `${i.name}@${i.version}` : i.name).join(', ')\n\n p.log.info(`Will remove ${toRemove.length} items:`)\n for (const [prefix, items] of groups) {\n p.log.message(` ${prefix}: ${formatGroup(items)}`)\n }\n\n if (!opts.yes && isInteractive()) {\n const confirmed = await p.confirm({\n message: 'Proceed with uninstall?',\n })\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('Cancelled')\n return\n }\n }\n\n // Remove all items\n for (const item of toRemove) {\n rmSync(item.path, { recursive: true, force: true })\n }\n\n // Show grouped removal summary\n for (const [prefix, items] of groups) {\n p.log.success(`Removed ${prefix}: ${formatGroup(items)}`)\n }\n\n // Remove skilld instructions from agent instruction files\n const agentTypes = agentFilter || (Object.keys(agents) as AgentType[])\n for (const proj of projectsToUnregister) {\n for (const agent of agentTypes) {\n if (removeAgentInstructions(agent, proj)) {\n const file = agents[agent].instructionFile!\n p.log.success(`Cleaned ${file}`)\n }\n }\n }\n\n // Unregister projects from config (skip if cache dir was removed — config is gone)\n if (scope !== 'all') {\n for (const proj of projectsToUnregister) {\n unregisterProject(proj)\n }\n }\n\n p.outro('skilld uninstalled')\n}\n\nexport const uninstallCommandDef = defineCommand({\n meta: { name: 'uninstall', description: 'Remove skilld data' },\n args: {\n ...sharedArgs,\n },\n async run({ args }) {\n p.intro(`\\x1B[1m\\x1B[35mskilld\\x1B[0m uninstall`)\n return uninstallCommand({\n scope: args.global ? 'all' : undefined,\n agent: args.agent as AgentType | undefined,\n yes: args.yes,\n })\n },\n})\n"],"mappings":"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"}
|
package/dist/_chunks/upload.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { i as parseFrontmatter } from "./markdown.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { c as readLock } from "./lockfile.mjs";
|
|
3
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
4
|
import { homedir } from "node:os";
|
|
4
5
|
import { join } from "pathe";
|
|
5
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
6
6
|
import { ofetch } from "ofetch";
|
|
7
7
|
import { multiselect } from "@clack/prompts";
|
|
8
8
|
import { defineCommand } from "citty";
|
package/dist/_chunks/version.mjs
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
const CACHE_DIR = join(homedir(), ".skilld");
|
|
4
|
-
const REFERENCES_DIR = join(CACHE_DIR, "references");
|
|
5
|
-
const REPOS_DIR = join(CACHE_DIR, "repos");
|
|
6
|
-
function getRepoCacheDir(owner, repo) {
|
|
7
|
-
if (owner.includes("..") || repo.includes("..") || owner.includes("/") || repo.includes("/")) throw new Error(`Invalid repo path: ${owner}/${repo}`);
|
|
8
|
-
return join(REPOS_DIR, owner, repo);
|
|
9
|
-
}
|
|
10
|
-
function getPackageDbPath(name, version) {
|
|
11
|
-
return join(REFERENCES_DIR, `${name}@${version}`, "search.db");
|
|
12
|
-
}
|
|
1
|
+
import { o as REFERENCES_DIR } from "./paths.mjs";
|
|
2
|
+
import { resolve } from "pathe";
|
|
13
3
|
const VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\/)?[a-z0-9][-a-z0-9._]*$/;
|
|
14
4
|
const VALID_VERSION = /^[a-z0-9][-\w.+]*$/i;
|
|
15
5
|
function getVersionKey(version) {
|
|
@@ -25,6 +15,6 @@ function getCacheDir(name, version) {
|
|
|
25
15
|
if (!dir.startsWith(REFERENCES_DIR)) throw new Error(`Path traversal detected: ${dir}`);
|
|
26
16
|
return dir;
|
|
27
17
|
}
|
|
28
|
-
export {
|
|
18
|
+
export { getCacheKey as n, getVersionKey as r, getCacheDir as t };
|
|
29
19
|
|
|
30
20
|
//# sourceMappingURL=version.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.mjs","names":[],"sources":["../../src/cache/
|
|
1
|
+
{"version":3,"file":"version.mjs","names":[],"sources":["../../src/cache/version.ts"],"sourcesContent":["/**\n * Version utilities\n */\n\nimport { resolve } from 'pathe'\nimport { REFERENCES_DIR } from '../core/paths.ts'\n\n/** Validate npm package name (scoped or unscoped) */\nconst VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\\/)?[a-z0-9][-a-z0-9._]*$/\n\n/** Validate version string (semver-ish, no path separators) */\nconst VALID_VERSION = /^[a-z0-9][-\\w.+]*$/i\n\n/**\n * Get exact version key for cache keying\n */\nexport function getVersionKey(version: string): string {\n return version\n}\n\n/**\n * Get cache key for a package: name@version\n */\nexport function getCacheKey(name: string, version: string): string {\n return `${name}@${getVersionKey(version)}`\n}\n\n/**\n * Get path to cached package references.\n * Validates name/version to prevent path traversal.\n */\nexport function getCacheDir(name: string, version: string): string {\n if (!VALID_PKG_NAME.test(name))\n throw new Error(`Invalid package name: ${name}`)\n if (!VALID_VERSION.test(version))\n throw new Error(`Invalid version: ${version}`)\n\n const dir = resolve(REFERENCES_DIR, getCacheKey(name, version))\n if (!dir.startsWith(REFERENCES_DIR))\n throw new Error(`Path traversal detected: ${dir}`)\n return dir\n}\n"],"mappings":";;;AAQA,MAAM,gBAAA;AAGN,SAAM,cAAgB,SAAA;;;AAKtB,SAAgB,YAAA,MAAc,SAAyB;CACrD,OAAO,GAAA,KAAA,GAAA,cAAA,QAAA;;;;CAMT,IAAA,CAAA,cAAgB,KAAY,QAAc,EAAA,MAAyB,IAAA,MAAA,oBAAA,UAAA;CACjE,MAAA,MAAU,QAAQ,gBAAc,YAAQ,MAAA,QAAA,CAAA"}
|
package/dist/_chunks/wizard.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { L as updateConfig, k as defaultFeatures } from "./cache.mjs";
|
|
2
2
|
import { a as targets } from "./detect.mjs";
|
|
3
|
-
import { c as
|
|
3
|
+
import { a as getModelName, c as getOAuthProviderList, l as loginOAuthProvider, r as getAvailableModels } from "./agent.mjs";
|
|
4
4
|
import { g as pickModel, n as NO_MODELS_MESSAGE, p as isInteractive, r as OAUTH_NOTE } from "./cli-helpers.mjs";
|
|
5
5
|
import { execSync } from "node:child_process";
|
|
6
6
|
import * as p from "@clack/prompts";
|