@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.
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AA4BzC,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,QAAQ,GAAG,MAAM,CAAC;IAExB,aAAa;IACb,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChF,OAAO;YACL,GAAG,EAAE,MAAM;YACX,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,IAAI,OAA2B,CAAC;IAChC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QACtC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,WAAW;IACX,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAClE,IAAI,KAAK,EAAE,CAAC;YACV,OAAO;gBACL,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,MAAM;gBACvD,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;gBACf,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACpC,OAAO;gBACP,QAAQ;aACT,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC5C,CAAC;IAED,uBAAuB;IACvB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,OAAO;YACL,GAAG,EAAE,sBAAsB,KAAK,IAAI,IAAI,MAAM;YAC9C,KAAK;YACL,IAAI;YACJ,OAAO;YACP,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAoB;IAC9C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IAED,+CAA+C;IAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG;SACzB,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;IAEnC,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAoB;IACnD,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAErC,iCAAiC;IACjC,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvD,MAAM,GAAG,GAAc,SAAS,EAAE,CAAC;IAEnC,IAAI,CAAC;QACH,uBAAuB;QACvB,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;QAEvB,4BAA4B;QAC5B,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;QAC/B,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,kBAAkB;IAClB,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;IAEnC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,GAAW;IAC7D,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAExB,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3C,OAAO,GAAG,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB,EAAE,MAAc,MAAM;IACrE,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC"}
@@ -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"}
@@ -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":"AAAA,OAAO,GAAyB,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,iCAAiC;AACjC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;AAExD,sBAAsB;AACtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC;IAC1B,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,IAAI;CACd,CAAC,CAAC;AAEH,eAAe;AACf,IAAI,YAAgC,CAAC;AACrC,IAAI,UAA8B,CAAC;AAEnC;;GAEG;AACH,KAAK,UAAU,eAAe;IAC5B,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QACxE,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC;IAC/C,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa;IAC1B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC,CAAC;QAC7E,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC;IAC7C,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAYD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAe;IAClD,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAE/B,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,MAAM,GAAsB,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAgB,EAAE,EAAE,CAAC,CAAC;QACnF,IAAI,EAAE,GAAG,CAAC,YAAY,IAAI,GAAG;QAC7B,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,0BAA0B;KACnD,CAAC,CAAC,CAAC;IAEJ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAa;IAC9C,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE7B,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,MAAM,GAAsB,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAgB,EAAE,EAAE,CAAC,CAAC;QACnF,IAAI,EAAE,GAAG,CAAC,YAAY,IAAI,GAAG;QAC7B,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,0BAA0B;KACnD,CAAC,CAAC,CAAC;IAEJ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAyB;IAC9D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC"}
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
+ }