@agpm/core 0.0.1
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/config.d.ts +32 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/discovery.d.ts +48 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +197 -0
- package/dist/discovery.js.map +1 -0
- package/dist/git.d.ts +53 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +130 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/validate.d.ts +21 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +74 -0
- package/dist/validate.js.map +1 -0
- package/package.json +25 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface TargetConfig {
|
|
2
|
+
}
|
|
3
|
+
export interface AgpmConfig {
|
|
4
|
+
$schema?: string;
|
|
5
|
+
targets: Record<string, TargetConfig>;
|
|
6
|
+
sources: string[];
|
|
7
|
+
artifacts: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface LockedArtifact {
|
|
10
|
+
sha: string;
|
|
11
|
+
integrity: string;
|
|
12
|
+
path: string;
|
|
13
|
+
metadata: {
|
|
14
|
+
name: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface AgpmLock {
|
|
20
|
+
$schema?: string;
|
|
21
|
+
version: number;
|
|
22
|
+
artifacts: Record<string, LockedArtifact>;
|
|
23
|
+
}
|
|
24
|
+
export declare const CONFIG_SCHEMA_URL = "https://agpm.dev/schemas/agpm.json";
|
|
25
|
+
export declare const LOCK_SCHEMA_URL = "https://agpm.dev/schemas/agpm-lock.json";
|
|
26
|
+
export declare const DEFAULT_CONFIG: AgpmConfig;
|
|
27
|
+
export declare const DEFAULT_LOCK: AgpmLock;
|
|
28
|
+
export declare function loadConfig(dir: string): Promise<AgpmConfig>;
|
|
29
|
+
export declare function saveConfig(dir: string, config: AgpmConfig): Promise<void>;
|
|
30
|
+
export declare function loadLock(dir: string): Promise<AgpmLock>;
|
|
31
|
+
export declare function saveLock(dir: string, lock: AgpmLock): Promise<void>;
|
|
32
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;CAE5B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC3C;AAMD,eAAO,MAAM,iBAAiB,uCAAuC,CAAC;AACtE,eAAO,MAAM,eAAe,4CAA4C,CAAC;AAMzE,eAAO,MAAM,cAAc,EAAE,UAK5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,QAI1B,CAAC;AASF,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAqBjE;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/E;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqB7D;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAMzE"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { validateConfig, validateLock, formatValidationErrors } from "./validate.js";
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Schema URLs
|
|
6
|
+
// ============================================================================
|
|
7
|
+
export const CONFIG_SCHEMA_URL = "https://agpm.dev/schemas/agpm.json";
|
|
8
|
+
export const LOCK_SCHEMA_URL = "https://agpm.dev/schemas/agpm-lock.json";
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Defaults
|
|
11
|
+
// ============================================================================
|
|
12
|
+
export const DEFAULT_CONFIG = {
|
|
13
|
+
$schema: CONFIG_SCHEMA_URL,
|
|
14
|
+
targets: {},
|
|
15
|
+
sources: [],
|
|
16
|
+
artifacts: [],
|
|
17
|
+
};
|
|
18
|
+
export const DEFAULT_LOCK = {
|
|
19
|
+
$schema: LOCK_SCHEMA_URL,
|
|
20
|
+
version: 1,
|
|
21
|
+
artifacts: {},
|
|
22
|
+
};
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// File I/O
|
|
25
|
+
// ============================================================================
|
|
26
|
+
const CONFIG_FILE = "agpm.json";
|
|
27
|
+
const LOCK_FILE = "agpm-lock.json";
|
|
28
|
+
export async function loadConfig(dir) {
|
|
29
|
+
const path = join(dir, CONFIG_FILE);
|
|
30
|
+
try {
|
|
31
|
+
const content = await readFile(path, "utf-8");
|
|
32
|
+
const config = JSON.parse(content);
|
|
33
|
+
// Validate against schema
|
|
34
|
+
const result = await validateConfig(config);
|
|
35
|
+
if (!result.valid) {
|
|
36
|
+
throw new Error(`Invalid ${CONFIG_FILE}:\n${formatValidationErrors(result.errors)}`);
|
|
37
|
+
}
|
|
38
|
+
return config;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (error.code === "ENOENT") {
|
|
42
|
+
return { ...DEFAULT_CONFIG };
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function saveConfig(dir, config) {
|
|
48
|
+
const path = join(dir, CONFIG_FILE);
|
|
49
|
+
// Ensure $schema is always included
|
|
50
|
+
const configWithSchema = { $schema: CONFIG_SCHEMA_URL, ...config };
|
|
51
|
+
const content = JSON.stringify(configWithSchema, null, 2) + "\n";
|
|
52
|
+
await writeFile(path, content, "utf-8");
|
|
53
|
+
}
|
|
54
|
+
export async function loadLock(dir) {
|
|
55
|
+
const path = join(dir, LOCK_FILE);
|
|
56
|
+
try {
|
|
57
|
+
const content = await readFile(path, "utf-8");
|
|
58
|
+
const lock = JSON.parse(content);
|
|
59
|
+
// Validate against schema
|
|
60
|
+
const result = await validateLock(lock);
|
|
61
|
+
if (!result.valid) {
|
|
62
|
+
throw new Error(`Invalid ${LOCK_FILE}:\n${formatValidationErrors(result.errors)}`);
|
|
63
|
+
}
|
|
64
|
+
return lock;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (error.code === "ENOENT") {
|
|
68
|
+
return { ...DEFAULT_LOCK };
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export async function saveLock(dir, lock) {
|
|
74
|
+
const path = join(dir, LOCK_FILE);
|
|
75
|
+
// Ensure $schema is always included
|
|
76
|
+
const lockWithSchema = { $schema: LOCK_SCHEMA_URL, ...lock };
|
|
77
|
+
const content = JSON.stringify(lockWithSchema, null, 2) + "\n";
|
|
78
|
+
await writeFile(path, content, "utf-8");
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export interface DiscoveredArtifact {
|
|
2
|
+
/** Artifact name */
|
|
3
|
+
name: string;
|
|
4
|
+
/** Description */
|
|
5
|
+
description?: string;
|
|
6
|
+
/** Artifact type */
|
|
7
|
+
type: "skill" | "command" | "hook";
|
|
8
|
+
/** Path relative to repo root */
|
|
9
|
+
path: string;
|
|
10
|
+
/** Full absolute path */
|
|
11
|
+
absolutePath: string;
|
|
12
|
+
/** Source format that was detected */
|
|
13
|
+
format: "claude-marketplace" | "simple";
|
|
14
|
+
/** Additional metadata */
|
|
15
|
+
metadata?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
export interface ClaudePluginManifest {
|
|
18
|
+
name: string;
|
|
19
|
+
owner?: {
|
|
20
|
+
name: string;
|
|
21
|
+
email?: string;
|
|
22
|
+
};
|
|
23
|
+
metadata?: {
|
|
24
|
+
description?: string;
|
|
25
|
+
version?: string;
|
|
26
|
+
};
|
|
27
|
+
plugins: Array<{
|
|
28
|
+
name: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
source?: string;
|
|
31
|
+
skills?: string[];
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export interface SkillMetadata {
|
|
35
|
+
name: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
export type RepoFormat = "claude-marketplace" | "simple" | "unknown";
|
|
40
|
+
/**
|
|
41
|
+
* Detect the format of a repository.
|
|
42
|
+
*/
|
|
43
|
+
export declare function detectFormat(repoPath: string): Promise<RepoFormat>;
|
|
44
|
+
/**
|
|
45
|
+
* Discover all artifacts in a repository.
|
|
46
|
+
*/
|
|
47
|
+
export declare function discoverArtifacts(repoPath: string, subpath?: string): Promise<DiscoveredArtifact[]>;
|
|
48
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,kBAAkB;IACjC,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACnC,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,MAAM,EAAE,oBAAoB,GAAG,QAAQ,CAAC;IACxC,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,UAAU,GAAG,oBAAoB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAMrE;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAoBxE;AAMD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAa/B"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { readFile, readdir, stat } from "node:fs/promises";
|
|
2
|
+
import { join, relative, basename } from "node:path";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Format Detection
|
|
6
|
+
// ============================================================================
|
|
7
|
+
/**
|
|
8
|
+
* Detect the format of a repository.
|
|
9
|
+
*/
|
|
10
|
+
export async function detectFormat(repoPath) {
|
|
11
|
+
// Check for Claude marketplace format (.claude-plugin/marketplace.json)
|
|
12
|
+
try {
|
|
13
|
+
await stat(join(repoPath, ".claude-plugin", "marketplace.json"));
|
|
14
|
+
return "claude-marketplace";
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// Not claude-marketplace format
|
|
18
|
+
}
|
|
19
|
+
// Check for simple format (skills/ directory)
|
|
20
|
+
try {
|
|
21
|
+
const skillsStat = await stat(join(repoPath, "skills"));
|
|
22
|
+
if (skillsStat.isDirectory()) {
|
|
23
|
+
return "simple";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// No skills directory
|
|
28
|
+
}
|
|
29
|
+
return "unknown";
|
|
30
|
+
}
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Discovery
|
|
33
|
+
// ============================================================================
|
|
34
|
+
/**
|
|
35
|
+
* Discover all artifacts in a repository.
|
|
36
|
+
*/
|
|
37
|
+
export async function discoverArtifacts(repoPath, subpath) {
|
|
38
|
+
const searchPath = subpath ? join(repoPath, subpath) : repoPath;
|
|
39
|
+
const format = await detectFormat(searchPath);
|
|
40
|
+
switch (format) {
|
|
41
|
+
case "claude-marketplace":
|
|
42
|
+
return discoverClaudeMarketplace(searchPath);
|
|
43
|
+
case "simple":
|
|
44
|
+
return discoverSimpleFormat(searchPath);
|
|
45
|
+
default:
|
|
46
|
+
// Try simple format from the root anyway
|
|
47
|
+
return discoverSimpleFormat(searchPath);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Discover artifacts from Claude plugin manifest.
|
|
52
|
+
*
|
|
53
|
+
* Claude marketplace format:
|
|
54
|
+
* - .claude-marketplace/marketplace.json contains plugins array
|
|
55
|
+
* - Each plugin has `source` pointing to a directory
|
|
56
|
+
* - That directory contains a `skills/` subdirectory with skill folders
|
|
57
|
+
* - Each skill folder has SKILL.md
|
|
58
|
+
*
|
|
59
|
+
* Some repos (like Anthropic's) also include explicit `skills` arrays
|
|
60
|
+
* as a convenience, which we support as a fallback.
|
|
61
|
+
*/
|
|
62
|
+
async function discoverClaudeMarketplace(repoPath) {
|
|
63
|
+
const manifestPath = join(repoPath, ".claude-plugin", "marketplace.json");
|
|
64
|
+
const artifacts = [];
|
|
65
|
+
const seenPaths = new Set();
|
|
66
|
+
const content = await readFile(manifestPath, "utf-8");
|
|
67
|
+
const manifest = JSON.parse(content);
|
|
68
|
+
for (const plugin of manifest.plugins) {
|
|
69
|
+
// Primary method: source points to plugin directory with skills/ inside
|
|
70
|
+
if (plugin.source) {
|
|
71
|
+
const sourcePath = plugin.source.replace(/^\.\//, "");
|
|
72
|
+
const pluginDir = sourcePath ? join(repoPath, sourcePath) : repoPath;
|
|
73
|
+
const skillsDir = join(pluginDir, "skills");
|
|
74
|
+
try {
|
|
75
|
+
const entries = await readdir(skillsDir, { withFileTypes: true });
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
78
|
+
continue;
|
|
79
|
+
const skillPath = join(skillsDir, entry.name);
|
|
80
|
+
const relativePath = relative(repoPath, skillPath);
|
|
81
|
+
// Skip duplicates (multiple plugins may point to same skills dir)
|
|
82
|
+
if (seenPaths.has(relativePath))
|
|
83
|
+
continue;
|
|
84
|
+
seenPaths.add(relativePath);
|
|
85
|
+
const metadata = await parseSkillMd(skillPath);
|
|
86
|
+
artifacts.push({
|
|
87
|
+
name: metadata?.name ?? entry.name,
|
|
88
|
+
description: metadata?.description ?? plugin.description,
|
|
89
|
+
type: "skill",
|
|
90
|
+
path: relativePath,
|
|
91
|
+
absolutePath: skillPath,
|
|
92
|
+
format: "claude-marketplace",
|
|
93
|
+
metadata: metadata,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// skills/ directory doesn't exist in plugin source dir
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Fallback: explicit skills array (convenience format used by some repos)
|
|
102
|
+
if (plugin.skills && plugin.skills.length > 0) {
|
|
103
|
+
for (const skillPath of plugin.skills) {
|
|
104
|
+
const normalizedPath = skillPath.replace(/^\.\//, "");
|
|
105
|
+
// Skip duplicates
|
|
106
|
+
if (seenPaths.has(normalizedPath))
|
|
107
|
+
continue;
|
|
108
|
+
seenPaths.add(normalizedPath);
|
|
109
|
+
const absolutePath = join(repoPath, normalizedPath);
|
|
110
|
+
const metadata = await parseSkillMd(absolutePath);
|
|
111
|
+
artifacts.push({
|
|
112
|
+
name: metadata?.name ?? basename(normalizedPath),
|
|
113
|
+
description: metadata?.description ?? plugin.description,
|
|
114
|
+
type: "skill",
|
|
115
|
+
path: normalizedPath,
|
|
116
|
+
absolutePath,
|
|
117
|
+
format: "claude-marketplace",
|
|
118
|
+
metadata: metadata,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return artifacts;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Discover artifacts from simple format (skills/ directory).
|
|
127
|
+
*/
|
|
128
|
+
async function discoverSimpleFormat(repoPath) {
|
|
129
|
+
const skillsDir = join(repoPath, "skills");
|
|
130
|
+
const artifacts = [];
|
|
131
|
+
try {
|
|
132
|
+
const entries = await readdir(skillsDir, { withFileTypes: true });
|
|
133
|
+
for (const entry of entries) {
|
|
134
|
+
if (!entry.isDirectory())
|
|
135
|
+
continue;
|
|
136
|
+
if (entry.name.startsWith("."))
|
|
137
|
+
continue;
|
|
138
|
+
const skillPath = join(skillsDir, entry.name);
|
|
139
|
+
const metadata = await parseSkillMd(skillPath);
|
|
140
|
+
// Also try metadata.json
|
|
141
|
+
let jsonMetadata = null;
|
|
142
|
+
try {
|
|
143
|
+
const metadataContent = await readFile(join(skillPath, "metadata.json"), "utf-8");
|
|
144
|
+
jsonMetadata = JSON.parse(metadataContent);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// No metadata.json
|
|
148
|
+
}
|
|
149
|
+
const name = metadata?.name ?? jsonMetadata?.name ?? entry.name;
|
|
150
|
+
const description = metadata?.description ??
|
|
151
|
+
jsonMetadata?.abstract ??
|
|
152
|
+
jsonMetadata?.description;
|
|
153
|
+
artifacts.push({
|
|
154
|
+
name,
|
|
155
|
+
description,
|
|
156
|
+
type: "skill",
|
|
157
|
+
path: relative(repoPath, skillPath),
|
|
158
|
+
absolutePath: skillPath,
|
|
159
|
+
format: "simple",
|
|
160
|
+
metadata: { ...jsonMetadata, ...metadata },
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// skills/ directory doesn't exist or can't be read
|
|
166
|
+
}
|
|
167
|
+
return artifacts;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Parse SKILL.md or AGENTS.md YAML frontmatter.
|
|
171
|
+
*/
|
|
172
|
+
async function parseSkillMd(dirPath) {
|
|
173
|
+
for (const filename of ["SKILL.md", "AGENTS.md"]) {
|
|
174
|
+
try {
|
|
175
|
+
const content = await readFile(join(dirPath, filename), "utf-8");
|
|
176
|
+
// Extract YAML frontmatter
|
|
177
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
178
|
+
if (match) {
|
|
179
|
+
const yaml = parseYaml(match[1]);
|
|
180
|
+
return {
|
|
181
|
+
name: yaml.name ?? basename(dirPath),
|
|
182
|
+
description: yaml.description,
|
|
183
|
+
...yaml,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
// No frontmatter, use directory name
|
|
187
|
+
return {
|
|
188
|
+
name: basename(dirPath),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// File doesn't exist
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface ParsedSource {
|
|
2
|
+
/** Full git URL for cloning */
|
|
3
|
+
url: string;
|
|
4
|
+
/** GitHub owner (if GitHub) */
|
|
5
|
+
owner?: string;
|
|
6
|
+
/** Repository name */
|
|
7
|
+
repo?: string;
|
|
8
|
+
/** Git ref (branch, tag, SHA) */
|
|
9
|
+
ref?: string;
|
|
10
|
+
/** Subpath within repo (after #) */
|
|
11
|
+
subpath?: string;
|
|
12
|
+
/** Original source string */
|
|
13
|
+
original: string;
|
|
14
|
+
}
|
|
15
|
+
export interface RepoInfo {
|
|
16
|
+
/** Path to the cloned repo */
|
|
17
|
+
path: string;
|
|
18
|
+
/** Current HEAD SHA */
|
|
19
|
+
sha: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse a source string into its components.
|
|
23
|
+
*
|
|
24
|
+
* Supported formats:
|
|
25
|
+
* - owner/repo
|
|
26
|
+
* - owner/repo#subpath
|
|
27
|
+
* - https://github.com/owner/repo
|
|
28
|
+
* - https://github.com/owner/repo#subpath
|
|
29
|
+
* - ./local/path
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseSource(source: string): ParsedSource;
|
|
32
|
+
/**
|
|
33
|
+
* Get the global agpm directory path.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getAgpmDir(): string;
|
|
36
|
+
/**
|
|
37
|
+
* Get the path where a repo should be stored.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getRepoPath(source: ParsedSource): string;
|
|
40
|
+
/**
|
|
41
|
+
* Clone or fetch a repository.
|
|
42
|
+
* Returns the path to the repo and the current HEAD SHA.
|
|
43
|
+
*/
|
|
44
|
+
export declare function ensureRepo(source: ParsedSource): Promise<RepoInfo>;
|
|
45
|
+
/**
|
|
46
|
+
* Checkout a specific ref (branch, tag, or SHA) in a repo.
|
|
47
|
+
*/
|
|
48
|
+
export declare function checkoutRef(repoPath: string, ref: string): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* Resolve a ref to a full SHA.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveRef(repoPath: string, ref?: string): Promise<string>;
|
|
53
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,+BAA+B;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;CACb;AAMD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAiDxD;AAMD;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAcxD;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0BxE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMhF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAIxF"}
|
package/dist/git.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { simpleGit } from "simple-git";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { mkdir } from "node:fs/promises";
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Source Parsing
|
|
7
|
+
// ============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* Parse a source string into its components.
|
|
10
|
+
*
|
|
11
|
+
* Supported formats:
|
|
12
|
+
* - owner/repo
|
|
13
|
+
* - owner/repo#subpath
|
|
14
|
+
* - https://github.com/owner/repo
|
|
15
|
+
* - https://github.com/owner/repo#subpath
|
|
16
|
+
* - ./local/path
|
|
17
|
+
*/
|
|
18
|
+
export function parseSource(source) {
|
|
19
|
+
const original = source;
|
|
20
|
+
// Local path
|
|
21
|
+
if (source.startsWith("./") || source.startsWith("/") || source.startsWith("~")) {
|
|
22
|
+
return {
|
|
23
|
+
url: source,
|
|
24
|
+
original,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// Split on # for subpath
|
|
28
|
+
let subpath;
|
|
29
|
+
const hashIndex = source.indexOf("#");
|
|
30
|
+
if (hashIndex !== -1) {
|
|
31
|
+
subpath = source.slice(hashIndex + 1);
|
|
32
|
+
source = source.slice(0, hashIndex);
|
|
33
|
+
}
|
|
34
|
+
// Full URL
|
|
35
|
+
if (source.startsWith("https://") || source.startsWith("git@")) {
|
|
36
|
+
const match = source.match(/github\.com[/:]([\w.-]+)\/([\w.-]+)/);
|
|
37
|
+
if (match) {
|
|
38
|
+
return {
|
|
39
|
+
url: source.endsWith(".git") ? source : `${source}.git`,
|
|
40
|
+
owner: match[1],
|
|
41
|
+
repo: match[2].replace(/\.git$/, ""),
|
|
42
|
+
subpath,
|
|
43
|
+
original,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return { url: source, subpath, original };
|
|
47
|
+
}
|
|
48
|
+
// owner/repo shorthand
|
|
49
|
+
const parts = source.split("/");
|
|
50
|
+
if (parts.length >= 2) {
|
|
51
|
+
const owner = parts[0];
|
|
52
|
+
const repo = parts[1];
|
|
53
|
+
return {
|
|
54
|
+
url: `https://github.com/${owner}/${repo}.git`,
|
|
55
|
+
owner,
|
|
56
|
+
repo,
|
|
57
|
+
subpath,
|
|
58
|
+
original,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Invalid source format: ${original}`);
|
|
62
|
+
}
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// Repository Management
|
|
65
|
+
// ============================================================================
|
|
66
|
+
/**
|
|
67
|
+
* Get the global agpm directory path.
|
|
68
|
+
*/
|
|
69
|
+
export function getAgpmDir() {
|
|
70
|
+
return join(homedir(), ".agpm");
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the path where a repo should be stored.
|
|
74
|
+
*/
|
|
75
|
+
export function getRepoPath(source) {
|
|
76
|
+
const apmDir = getAgpmDir();
|
|
77
|
+
if (source.owner && source.repo) {
|
|
78
|
+
return join(apmDir, "repos", "github.com", source.owner, source.repo);
|
|
79
|
+
}
|
|
80
|
+
// For non-GitHub URLs, use a sanitized version
|
|
81
|
+
const sanitized = source.url
|
|
82
|
+
.replace(/^https?:\/\//, "")
|
|
83
|
+
.replace(/\.git$/, "")
|
|
84
|
+
.replace(/[^a-zA-Z0-9.-]/g, "_");
|
|
85
|
+
return join(apmDir, "repos", sanitized);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Clone or fetch a repository.
|
|
89
|
+
* Returns the path to the repo and the current HEAD SHA.
|
|
90
|
+
*/
|
|
91
|
+
export async function ensureRepo(source) {
|
|
92
|
+
const repoPath = getRepoPath(source);
|
|
93
|
+
// Ensure parent directory exists
|
|
94
|
+
await mkdir(join(repoPath, ".."), { recursive: true });
|
|
95
|
+
const git = simpleGit();
|
|
96
|
+
try {
|
|
97
|
+
// Check if repo exists
|
|
98
|
+
const repoGit = simpleGit(repoPath);
|
|
99
|
+
await repoGit.status();
|
|
100
|
+
// Repo exists, fetch latest
|
|
101
|
+
await repoGit.fetch(["--all"]);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Repo doesn't exist, clone it
|
|
105
|
+
await git.clone(source.url, repoPath);
|
|
106
|
+
}
|
|
107
|
+
// Get current SHA
|
|
108
|
+
const repoGit = simpleGit(repoPath);
|
|
109
|
+
const log = await repoGit.log({ maxCount: 1 });
|
|
110
|
+
const sha = log.latest?.hash ?? "";
|
|
111
|
+
return { path: repoPath, sha };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Checkout a specific ref (branch, tag, or SHA) in a repo.
|
|
115
|
+
*/
|
|
116
|
+
export async function checkoutRef(repoPath, ref) {
|
|
117
|
+
const git = simpleGit(repoPath);
|
|
118
|
+
await git.checkout(ref);
|
|
119
|
+
const log = await git.log({ maxCount: 1 });
|
|
120
|
+
return log.latest?.hash ?? "";
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Resolve a ref to a full SHA.
|
|
124
|
+
*/
|
|
125
|
+
export async function resolveRef(repoPath, ref = "HEAD") {
|
|
126
|
+
const git = simpleGit(repoPath);
|
|
127
|
+
const result = await git.revparse([ref]);
|
|
128
|
+
return result.trim();
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { type AgpmConfig, type AgpmLock, type TargetConfig, type LockedArtifact, DEFAULT_CONFIG, DEFAULT_LOCK, CONFIG_SCHEMA_URL, LOCK_SCHEMA_URL, loadConfig, saveConfig, loadLock, saveLock, } from "./config.js";
|
|
2
|
+
export { type ValidationError, type ValidationResult, validateConfig, validateLock, formatValidationErrors, } from "./validate.js";
|
|
3
|
+
export { type ParsedSource, type RepoInfo, parseSource, getAgpmDir, getRepoPath, ensureRepo, checkoutRef, resolveRef, } from "./git.js";
|
|
4
|
+
export { type DiscoveredArtifact, type ClaudePluginManifest, type SkillMetadata, type RepoFormat, detectFormat, discoverArtifacts, } from "./discovery.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,GACT,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,cAAc,EACd,YAAY,EACZ,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,GACX,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,YAAY,EACZ,iBAAiB,GAClB,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Config types and I/O
|
|
2
|
+
export { DEFAULT_CONFIG, DEFAULT_LOCK, CONFIG_SCHEMA_URL, LOCK_SCHEMA_URL, loadConfig, saveConfig, loadLock, saveLock, } from "./config.js";
|
|
3
|
+
// Validation
|
|
4
|
+
export { validateConfig, validateLock, formatValidationErrors, } from "./validate.js";
|
|
5
|
+
// Git operations
|
|
6
|
+
export { parseSource, getAgpmDir, getRepoPath, ensureRepo, checkoutRef, resolveRef, } from "./git.js";
|
|
7
|
+
// Discovery
|
|
8
|
+
export { detectFormat, discoverArtifacts, } from "./discovery.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAKL,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,GACT,MAAM,aAAa,CAAC;AAErB,aAAa;AACb,OAAO,EAGL,cAAc,EACd,YAAY,EACZ,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,iBAAiB;AACjB,OAAO,EAGL,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,GACX,MAAM,UAAU,CAAC;AAElB,YAAY;AACZ,OAAO,EAKL,YAAY,EACZ,iBAAiB,GAClB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ValidationError {
|
|
2
|
+
path: string;
|
|
3
|
+
message: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ValidationResult {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
errors: ValidationError[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Validate an APM config against the schema.
|
|
11
|
+
*/
|
|
12
|
+
export declare function validateConfig(config: unknown): Promise<ValidationResult>;
|
|
13
|
+
/**
|
|
14
|
+
* Validate an APM lock file against the schema.
|
|
15
|
+
*/
|
|
16
|
+
export declare function validateLock(lock: unknown): Promise<ValidationResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Format validation errors for display.
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatValidationErrors(errors: ValidationError[]): string;
|
|
21
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAyCA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAe/E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAe3E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,CAExE"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import Ajv from "ajv";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
// Get the schemas directory path
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const SCHEMAS_DIR = join(__dirname, "../../../schemas");
|
|
8
|
+
// Create Ajv instance
|
|
9
|
+
const ajv = new Ajv.default({
|
|
10
|
+
allErrors: true,
|
|
11
|
+
verbose: true,
|
|
12
|
+
});
|
|
13
|
+
// Schema cache
|
|
14
|
+
let configSchema;
|
|
15
|
+
let lockSchema;
|
|
16
|
+
/**
|
|
17
|
+
* Load and cache the config schema.
|
|
18
|
+
*/
|
|
19
|
+
async function getConfigSchema() {
|
|
20
|
+
if (!configSchema) {
|
|
21
|
+
const content = await readFile(join(SCHEMAS_DIR, "agpm.json"), "utf-8");
|
|
22
|
+
configSchema = JSON.parse(content);
|
|
23
|
+
}
|
|
24
|
+
return configSchema;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Load and cache the lock schema.
|
|
28
|
+
*/
|
|
29
|
+
async function getLockSchema() {
|
|
30
|
+
if (!lockSchema) {
|
|
31
|
+
const content = await readFile(join(SCHEMAS_DIR, "agpm-lock.json"), "utf-8");
|
|
32
|
+
lockSchema = JSON.parse(content);
|
|
33
|
+
}
|
|
34
|
+
return lockSchema;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Validate an APM config against the schema.
|
|
38
|
+
*/
|
|
39
|
+
export async function validateConfig(config) {
|
|
40
|
+
const schema = await getConfigSchema();
|
|
41
|
+
const validate = ajv.compile(schema);
|
|
42
|
+
const valid = validate(config);
|
|
43
|
+
if (valid) {
|
|
44
|
+
return { valid: true, errors: [] };
|
|
45
|
+
}
|
|
46
|
+
const errors = (validate.errors || []).map((err) => ({
|
|
47
|
+
path: err.instancePath || "/",
|
|
48
|
+
message: err.message || "Unknown validation error",
|
|
49
|
+
}));
|
|
50
|
+
return { valid: false, errors };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Validate an APM lock file against the schema.
|
|
54
|
+
*/
|
|
55
|
+
export async function validateLock(lock) {
|
|
56
|
+
const schema = await getLockSchema();
|
|
57
|
+
const validate = ajv.compile(schema);
|
|
58
|
+
const valid = validate(lock);
|
|
59
|
+
if (valid) {
|
|
60
|
+
return { valid: true, errors: [] };
|
|
61
|
+
}
|
|
62
|
+
const errors = (validate.errors || []).map((err) => ({
|
|
63
|
+
path: err.instancePath || "/",
|
|
64
|
+
message: err.message || "Unknown validation error",
|
|
65
|
+
}));
|
|
66
|
+
return { valid: false, errors };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Format validation errors for display.
|
|
70
|
+
*/
|
|
71
|
+
export function formatValidationErrors(errors) {
|
|
72
|
+
return errors.map((e) => ` ${e.path}: ${e.message}`).join("\n");
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agpm/core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"files": ["dist"],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"typecheck": "tsc --noEmit"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"ajv": "^8.17.1",
|
|
18
|
+
"fast-glob": "^3.3.3",
|
|
19
|
+
"simple-git": "^3.27.0",
|
|
20
|
+
"yaml": "^2.7.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"typescript": "^5.7.0"
|
|
24
|
+
}
|
|
25
|
+
}
|