@domainlang/cli 0.5.2 → 0.6.0

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.
Files changed (38) hide show
  1. package/README.md +15 -15
  2. package/out/dependency-commands.d.ts +1 -1
  3. package/out/dependency-commands.js +52 -24
  4. package/out/dependency-commands.js.map +1 -1
  5. package/out/main.d.ts +1 -1
  6. package/out/main.js +1 -1
  7. package/out/main.js.map +1 -1
  8. package/out/services/dependency-analyzer.d.ts +59 -0
  9. package/out/services/dependency-analyzer.js +260 -0
  10. package/out/services/dependency-analyzer.js.map +1 -0
  11. package/out/services/dependency-resolver.d.ts +148 -0
  12. package/out/services/dependency-resolver.js +448 -0
  13. package/out/services/dependency-resolver.js.map +1 -0
  14. package/out/services/git-url-resolver.d.ts +158 -0
  15. package/out/services/git-url-resolver.js +408 -0
  16. package/out/services/git-url-resolver.js.map +1 -0
  17. package/out/services/governance-validator.d.ts +56 -0
  18. package/out/services/governance-validator.js +171 -0
  19. package/out/services/governance-validator.js.map +1 -0
  20. package/out/services/index.d.ts +12 -0
  21. package/out/services/index.js +13 -0
  22. package/out/services/index.js.map +1 -0
  23. package/out/services/semver.d.ts +98 -0
  24. package/out/services/semver.js +195 -0
  25. package/out/services/semver.js.map +1 -0
  26. package/out/services/types.d.ts +58 -0
  27. package/out/services/types.js +8 -0
  28. package/out/services/types.js.map +1 -0
  29. package/package.json +4 -3
  30. package/src/dependency-commands.ts +59 -24
  31. package/src/main.ts +1 -1
  32. package/src/services/dependency-analyzer.ts +329 -0
  33. package/src/services/dependency-resolver.ts +546 -0
  34. package/src/services/git-url-resolver.ts +504 -0
  35. package/src/services/governance-validator.ts +226 -0
  36. package/src/services/index.ts +13 -0
  37. package/src/services/semver.ts +213 -0
  38. package/src/services/types.ts +81 -0
@@ -0,0 +1,448 @@
1
+ /**
2
+ * Dependency Resolution Service (CLI-only)
3
+ *
4
+ * Discovers and resolves transitive dependencies for DomainLang packages.
5
+ * Generates lock files for reproducible builds.
6
+ *
7
+ * Algorithm:
8
+ * 1. Parse root model.yaml
9
+ * 2. Download all direct dependencies
10
+ * 3. Parse each dependency's model.yaml
11
+ * 4. Recursively discover transitive dependencies
12
+ * 5. Resolve version constraints using "Latest Wins" strategy
13
+ * 6. Generate lock file with pinned commit hashes
14
+ *
15
+ * Resolution Strategy ("Latest Wins"):
16
+ * - SemVer tags (same major): Pick highest compatible version
17
+ * - Same branch: No conflict, resolve once
18
+ * - Commit pins: Error (explicit pins are intentional)
19
+ * - Major version mismatch: Error
20
+ * - Tag vs Branch: Error (incompatible intent)
21
+ *
22
+ * This module contains network operations and should ONLY be used in CLI contexts.
23
+ */
24
+ import path from 'node:path';
25
+ import fs from 'node:fs/promises';
26
+ import YAML from 'yaml';
27
+ import { GitUrlParser, GitUrlResolver } from './git-url-resolver.js';
28
+ import { parseSemVer, pickLatestSemVer, detectRefType } from './semver.js';
29
+ export class DependencyResolver {
30
+ constructor(workspaceRoot, gitResolver) {
31
+ /** Override messages for CLI output */
32
+ this.overrideMessages = [];
33
+ /** Resolution messages from "Latest Wins" auto-resolution */
34
+ this.resolutionMessages = [];
35
+ this.workspaceRoot = workspaceRoot;
36
+ // Per PRS-010: Project-local cache at .dlang/packages/
37
+ const cacheDir = path.join(workspaceRoot, '.dlang', 'packages');
38
+ this.gitResolver = gitResolver || new GitUrlResolver(cacheDir);
39
+ }
40
+ /**
41
+ * Resolves all dependencies for a workspace.
42
+ *
43
+ * Process:
44
+ * 1. Load root model.yaml
45
+ * 2. Build dependency graph (discover transitive deps)
46
+ * 3. Resolve version constraints
47
+ * 4. Generate lock file
48
+ * 5. Download all dependencies to cache
49
+ *
50
+ * @returns Generated lock file
51
+ */
52
+ async resolveDependencies() {
53
+ // Load root package config
54
+ const rootConfig = await this.loadPackageConfig(this.workspaceRoot);
55
+ if (!rootConfig.dependencies || Object.keys(rootConfig.dependencies).length === 0) {
56
+ // No dependencies
57
+ return { version: '1', dependencies: {} };
58
+ }
59
+ // Build dependency graph
60
+ const graph = await this.buildDependencyGraph(rootConfig);
61
+ // Apply overrides before conflict detection
62
+ this.applyOverrides(graph, rootConfig.overrides);
63
+ // Detect version conflicts and package-level cycles before resolving
64
+ this.detectVersionConflicts(graph);
65
+ this.detectPackageCycles(graph);
66
+ // Resolve version constraints
67
+ await this.resolveVersions(graph);
68
+ // Generate and return lock file (caller writes to disk)
69
+ return this.generateLockFile(graph);
70
+ }
71
+ /**
72
+ * Applies ref overrides from model.yaml to resolve conflicts explicitly.
73
+ *
74
+ * Overrides take precedence over all other constraints.
75
+ *
76
+ * @example
77
+ * ```yaml
78
+ * overrides:
79
+ * domainlang/core: v2.0.0
80
+ * ```
81
+ */
82
+ applyOverrides(graph, overrides) {
83
+ if (!overrides)
84
+ return;
85
+ for (const [pkg, overrideRef] of Object.entries(overrides)) {
86
+ const node = graph.nodes[pkg];
87
+ if (node) {
88
+ // Override replaces all constraints with a single definitive ref
89
+ node.constraints = new Set([overrideRef]);
90
+ node.refConstraint = overrideRef;
91
+ // Track that this was an override for messaging
92
+ this.overrideMessages.push(`Override applied: ${pkg}@${overrideRef}`);
93
+ }
94
+ }
95
+ }
96
+ /**
97
+ * Returns any override messages from the last dependency resolution.
98
+ */
99
+ getOverrideMessages() {
100
+ return this.overrideMessages;
101
+ }
102
+ /**
103
+ * Builds the complete dependency graph by recursively discovering transitive dependencies.
104
+ */
105
+ async buildDependencyGraph(rootConfig) {
106
+ const graph = {
107
+ nodes: {},
108
+ root: rootConfig.name || 'root',
109
+ };
110
+ // Process root dependencies
111
+ const queue = [];
112
+ for (const [depName, refConstraint] of Object.entries(rootConfig.dependencies || {})) {
113
+ queue.push({
114
+ packageKey: depName,
115
+ refConstraint,
116
+ parent: graph.root
117
+ });
118
+ }
119
+ // BFS to discover all transitive dependencies
120
+ const visited = new Set();
121
+ while (queue.length > 0) {
122
+ const entry = queue.shift();
123
+ if (!entry)
124
+ break;
125
+ const { packageKey, refConstraint, parent } = entry;
126
+ // Skip if already processed
127
+ if (visited.has(packageKey)) {
128
+ // Update dependents list and record constraint
129
+ const existing = graph.nodes[packageKey];
130
+ if (!existing.dependents.includes(parent)) {
131
+ existing.dependents.push(parent);
132
+ }
133
+ if (!existing.constraints)
134
+ existing.constraints = new Set();
135
+ existing.constraints.add(refConstraint);
136
+ continue;
137
+ }
138
+ visited.add(packageKey);
139
+ // Parse package identifier
140
+ const gitInfo = GitUrlParser.parse(packageKey);
141
+ // Download package to get its model.yaml
142
+ const packagePath = await this.gitResolver.resolve(packageKey);
143
+ const packageDir = path.dirname(packagePath);
144
+ // Load package config
145
+ const packageConfig = await this.loadPackageConfig(packageDir);
146
+ // Add to graph
147
+ graph.nodes[packageKey] = {
148
+ packageKey,
149
+ refConstraint,
150
+ constraints: new Set([refConstraint]),
151
+ repoUrl: gitInfo.repoUrl,
152
+ dependencies: packageConfig.dependencies || {},
153
+ dependents: [parent],
154
+ };
155
+ // Queue transitive dependencies
156
+ for (const [transDepName, transRefConstraint] of Object.entries(packageConfig.dependencies || {})) {
157
+ queue.push({
158
+ packageKey: transDepName,
159
+ refConstraint: transRefConstraint,
160
+ parent: packageKey,
161
+ });
162
+ }
163
+ }
164
+ return graph;
165
+ }
166
+ /**
167
+ * Resolves ref constraints to specific commits.
168
+ *
169
+ * Simple algorithm: Use the ref specified in the constraint.
170
+ * Detects refType (tag, branch, or commit) based on format.
171
+ */
172
+ async resolveVersions(graph) {
173
+ for (const [packageKey, node] of Object.entries(graph.nodes)) {
174
+ // Parse package to get repo info
175
+ const gitInfo = GitUrlParser.parse(packageKey);
176
+ // Extract ref from constraint
177
+ const ref = this.extractRefFromConstraint(node.refConstraint);
178
+ // Detect ref type based on format
179
+ const refType = detectRefType(ref);
180
+ // Resolve ref to commit hash
181
+ const commitHash = await this.resolveCommitHash(gitInfo.repoUrl, ref, gitInfo);
182
+ node.resolvedRef = ref;
183
+ node.refType = refType;
184
+ node.commitHash = commitHash;
185
+ }
186
+ }
187
+ /**
188
+ * Extracts a ref from a constraint string.
189
+ *
190
+ * Examples:
191
+ * - "^1.0.0" → "1.0.0" (treated as tag)
192
+ * - "~2.3.0" → "2.3.0" (treated as tag)
193
+ * - "1.5.0" → "1.5.0" (treated as tag)
194
+ * - "main" → "main" (treated as branch)
195
+ * - "abc123def" → "abc123def" (treated as commit)
196
+ * - "owner/repo@1.0.0" → "1.0.0"
197
+ */
198
+ extractRefFromConstraint(constraint) {
199
+ // Remove semver operators (legacy support)
200
+ let ref = constraint.replace(/^[\^~>=<]/, '');
201
+ // Extract ref from full import URL if present
202
+ if (ref.includes('@')) {
203
+ ref = ref.split('@')[1];
204
+ }
205
+ return ref || 'main';
206
+ }
207
+ /**
208
+ * Resolves a version (tag/branch) to a commit hash.
209
+ */
210
+ async resolveCommitHash(_repoUrl, _version, gitInfo) {
211
+ // Use GitUrlResolver to resolve the commit
212
+ const commitHash = await this.gitResolver.resolveCommit(gitInfo);
213
+ return commitHash;
214
+ }
215
+ /**
216
+ * Generates a lock file from the resolved dependency graph.
217
+ */
218
+ generateLockFile(graph) {
219
+ const dependencies = {};
220
+ for (const [packageKey, node] of Object.entries(graph.nodes)) {
221
+ if (!node.resolvedRef || !node.commitHash) {
222
+ throw new Error(`Failed to resolve ref for '${packageKey}'.\n` +
223
+ `Hint: Check that the package exists and the ref is valid.`);
224
+ }
225
+ dependencies[packageKey] = {
226
+ ref: node.resolvedRef,
227
+ refType: node.refType ?? 'commit',
228
+ resolved: node.repoUrl || '',
229
+ commit: node.commitHash,
230
+ // Future: Calculate integrity hash
231
+ };
232
+ }
233
+ return {
234
+ version: '1',
235
+ dependencies,
236
+ };
237
+ }
238
+ /**
239
+ * Loads and parses a package's model.yaml file.
240
+ */
241
+ async loadPackageConfig(packageDir) {
242
+ const yamlPath = path.join(packageDir, 'model.yaml');
243
+ try {
244
+ const yamlContent = await fs.readFile(yamlPath, 'utf-8');
245
+ return this.parseYaml(yamlContent);
246
+ }
247
+ catch {
248
+ // No model.yaml found
249
+ return {};
250
+ }
251
+ }
252
+ /**
253
+ * Parses model.yaml content.
254
+ *
255
+ * Expected structure:
256
+ * model:
257
+ * name: package-name
258
+ * version: 1.0.0
259
+ * entry: index.dlang
260
+ *
261
+ * dependencies:
262
+ * package-name:
263
+ * source: owner/repo
264
+ * ref: v1.0.0
265
+ */
266
+ parseYaml(content) {
267
+ const parsed = YAML.parse(content);
268
+ const config = {};
269
+ if (parsed.model) {
270
+ config.name = parsed.model.name;
271
+ config.version = parsed.model.version;
272
+ config.entry = parsed.model.entry;
273
+ }
274
+ if (parsed.dependencies) {
275
+ config.dependencies = {};
276
+ for (const [, depInfo] of Object.entries(parsed.dependencies)) {
277
+ if (depInfo.source) {
278
+ const refConstraint = depInfo.ref || 'main';
279
+ // Store as "source@ref" for consistency with import resolution
280
+ config.dependencies[depInfo.source] = refConstraint;
281
+ }
282
+ }
283
+ }
284
+ // Parse overrides section for explicit ref control
285
+ if (parsed.overrides) {
286
+ config.overrides = parsed.overrides;
287
+ }
288
+ return config;
289
+ }
290
+ /**
291
+ * Detects ref conflicts and applies "Latest Wins" resolution strategy.
292
+ *
293
+ * Resolution Rules:
294
+ * - SemVer tags (same major): Pick highest version automatically
295
+ * - Same branch refs: No conflict, use single resolution
296
+ * - Commit SHA conflicts: Error (explicit pins are intentional)
297
+ * - Major version mismatch: Error (breaking change)
298
+ * - Tag vs Branch: Error (incompatible intent)
299
+ *
300
+ * Modifies graph nodes in-place to set the resolved constraint.
301
+ * Throws an error only for unresolvable conflicts.
302
+ */
303
+ detectVersionConflicts(graph) {
304
+ const resolutionMessages = [];
305
+ for (const [pkg, node] of Object.entries(graph.nodes)) {
306
+ const constraints = node.constraints ?? new Set([node.refConstraint]);
307
+ if (constraints.size <= 1)
308
+ continue; // No conflict
309
+ const refs = Array.from(constraints);
310
+ const refTypes = refs.map(ref => ({
311
+ ref,
312
+ type: detectRefType(ref),
313
+ semver: parseSemVer(ref),
314
+ }));
315
+ // Check for mixed types (tag vs branch vs commit)
316
+ const types = new Set(refTypes.map(r => r.type));
317
+ // Case 1: All commits - must be exact match
318
+ if (types.size === 1 && types.has('commit')) {
319
+ this.throwConflictError(pkg, refs, node.dependents, 'Explicit commit pins cannot be automatically resolved.\n' +
320
+ 'Add an override in model.yaml:\n\n' +
321
+ ' overrides:\n' +
322
+ ` ${pkg}: ${refs[0]}`);
323
+ }
324
+ // Case 2: Mixed types (tag vs branch or tag vs commit)
325
+ if (types.size > 1) {
326
+ this.throwConflictError(pkg, refs, node.dependents, 'Cannot mix ref types (tags, branches, commits).\n' +
327
+ 'Add an override in model.yaml to specify which to use:\n\n' +
328
+ ' overrides:\n' +
329
+ ` ${pkg}: <ref>`);
330
+ }
331
+ // Case 3: All branches - must be same branch
332
+ if (types.size === 1 && types.has('branch')) {
333
+ const uniqueBranches = new Set(refs);
334
+ if (uniqueBranches.size > 1) {
335
+ this.throwConflictError(pkg, refs, node.dependents, 'Different branch refs cannot be automatically resolved.\n' +
336
+ 'Add an override in model.yaml:\n\n' +
337
+ ' overrides:\n' +
338
+ ` ${pkg}: ${refs[0]}`);
339
+ }
340
+ // Same branch - no conflict, continue
341
+ continue;
342
+ }
343
+ // Case 4: All SemVer tags - apply "Latest Wins"
344
+ const semvers = refTypes
345
+ .filter((r) => r.semver !== undefined)
346
+ .map(r => r.semver);
347
+ if (semvers.length !== refs.length) {
348
+ // Some refs don't parse as SemVer - can't auto-resolve
349
+ this.throwConflictError(pkg, refs, node.dependents, 'Not all refs are valid SemVer tags.\n' +
350
+ 'Add an override in model.yaml:\n\n' +
351
+ ' overrides:\n' +
352
+ ` ${pkg}: <ref>`);
353
+ }
354
+ // Check major version compatibility
355
+ const majors = new Set(semvers.map(s => s.major));
356
+ if (majors.size > 1) {
357
+ const majorList = Array.from(majors).sort().join(' vs ');
358
+ this.throwConflictError(pkg, refs, node.dependents, `Major version mismatch (v${majorList}). This may indicate breaking changes.\n` +
359
+ 'Add an override in model.yaml if you want to force a version:\n\n' +
360
+ ' overrides:\n' +
361
+ ` ${pkg}: ${refs[refs.length - 1]}`);
362
+ }
363
+ // All same major version - pick latest (Latest Wins!)
364
+ const latest = pickLatestSemVer(refs);
365
+ if (latest && latest !== node.refConstraint) {
366
+ // Update the node to use the resolved ref
367
+ node.refConstraint = latest;
368
+ // Log the resolution for user feedback
369
+ const otherRefs = refs.filter(r => r !== latest).join(', ');
370
+ resolutionMessages.push(`Resolved ${pkg}: using ${latest} (satisfies ${otherRefs})`);
371
+ }
372
+ }
373
+ // Store resolution messages for later output
374
+ if (resolutionMessages.length > 0) {
375
+ this.resolutionMessages = resolutionMessages;
376
+ }
377
+ }
378
+ /**
379
+ * Throws a formatted conflict error with actionable hints.
380
+ */
381
+ throwConflictError(pkg, refs, dependents, hint) {
382
+ const depLines = dependents.map((d, i) => ` └─ ${d} requires ${pkg}@${refs[i] || refs[0]}`).join('\n');
383
+ throw new Error(`Dependency ref conflict for '${pkg}'\n` +
384
+ depLines + '\n\n' +
385
+ hint);
386
+ }
387
+ /**
388
+ * Returns any resolution messages from the last dependency resolution.
389
+ * Useful for CLI output to inform users about auto-resolved conflicts.
390
+ */
391
+ getResolutionMessages() {
392
+ return this.resolutionMessages;
393
+ }
394
+ /**
395
+ * Detects package-level cycles in the dependency graph and throws a clear error.
396
+ */
397
+ detectPackageCycles(graph) {
398
+ const GRAY = 1, BLACK = 2;
399
+ const color = {};
400
+ const stack = [];
401
+ const visit = (pkg) => {
402
+ color[pkg] = GRAY;
403
+ stack.push(pkg);
404
+ const deps = Object.keys(graph.nodes[pkg]?.dependencies ?? {});
405
+ for (const dep of deps) {
406
+ if (!graph.nodes[dep])
407
+ continue; // Unknown dep will resolve later
408
+ if (color[dep] === GRAY) {
409
+ // Found a back edge: cycle
410
+ const cycleStart = stack.indexOf(dep);
411
+ const cyclePath = [...stack.slice(cycleStart), dep].join(' → ');
412
+ throw new Error(`Cyclic package dependency detected:\n` +
413
+ ` ${cyclePath}\n\n` +
414
+ `Hint: Extract shared types into a separate package that both can depend on.`);
415
+ }
416
+ if (color[dep] !== BLACK)
417
+ visit(dep);
418
+ }
419
+ stack.pop();
420
+ color[pkg] = BLACK;
421
+ };
422
+ for (const pkg of Object.keys(graph.nodes)) {
423
+ if (!color[pkg])
424
+ visit(pkg);
425
+ }
426
+ }
427
+ /**
428
+ * Loads an existing lock file from disk.
429
+ */
430
+ static async loadLockFile(workspaceRoot) {
431
+ const lockPath = path.join(workspaceRoot, 'model.lock');
432
+ try {
433
+ const content = await fs.readFile(lockPath, 'utf-8');
434
+ return JSON.parse(content);
435
+ }
436
+ catch {
437
+ // No lock file
438
+ return undefined;
439
+ }
440
+ }
441
+ /**
442
+ * Parses a lock file from JSON format.
443
+ */
444
+ static parseLockFile(content) {
445
+ return JSON.parse(content);
446
+ }
447
+ }
448
+ //# sourceMappingURL=dependency-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-resolver.js","sourceRoot":"","sources":["../../src/services/dependency-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Git Repository Resolver Service (CLI-only)
3
+ *
4
+ * Resolves git-based package imports to local cached repositories.
5
+ * Supports simplified GitHub syntax (owner/repo@version) and full URLs.
6
+ *
7
+ * Design: Repository-level imports (not individual files)
8
+ * - Imports load entire package
9
+ * - Package entry point defined in model.yaml
10
+ * - Version pinning at repository level
11
+ *
12
+ * This module contains network operations (git clone, git ls-remote) and
13
+ * should ONLY be used in CLI contexts, never in the LSP.
14
+ */
15
+ import type { GitImportInfo, LockFile } from './types.js';
16
+ /**
17
+ * Parses import URLs into structured git import information.
18
+ *
19
+ * Supported formats:
20
+ * - owner/repo@version (GitHub assumed)
21
+ * - owner/repo (GitHub, defaults to main)
22
+ * - https://github.com/owner/repo@version
23
+ * - https://gitlab.com/owner/repo@version
24
+ * - https://git.example.com/owner/repo@version
25
+ */
26
+ export declare class GitUrlParser {
27
+ /**
28
+ * Determines if an import string is a git repository import.
29
+ */
30
+ static isGitUrl(importStr: string): boolean;
31
+ /**
32
+ * Parses a git import URL into structured components.
33
+ *
34
+ * @param importStr - The import URL string
35
+ * @returns Parsed git import information
36
+ * @throws Error if URL format is invalid
37
+ */
38
+ static parse(importStr: string): GitImportInfo;
39
+ /**
40
+ * Checks if string is GitHub shorthand format.
41
+ */
42
+ private static isGitHubShorthand;
43
+ /**
44
+ * Parses GitHub shorthand (owner/repo or owner/repo@version).
45
+ */
46
+ private static parseGitHubShorthand;
47
+ /**
48
+ * Parses full git URLs (https://...).
49
+ *
50
+ * Supported:
51
+ * - https://github.com/owner/repo@version
52
+ * - https://gitlab.com/owner/repo@version
53
+ * - https://git.example.com/owner/repo@version
54
+ */
55
+ private static parseFullUrl;
56
+ }
57
+ /**
58
+ * Resolves git repository imports to local entry point files.
59
+ *
60
+ * Implements a content-addressable cache:
61
+ * - Cache location: .dlang/packages/ (project-local, per PRS-010)
62
+ * - Cache key: {owner}/{repo}/{commit-hash}
63
+ * - Downloads entire repository on first use
64
+ * - Reads model.yaml to find entry point
65
+ * - Returns path to entry point file
66
+ */
67
+ export declare class GitUrlResolver {
68
+ private cacheDir;
69
+ private lockFile?;
70
+ /**
71
+ * Creates a GitUrlResolver with a project-local cache directory.
72
+ *
73
+ * @param cacheDir - The cache directory path. Per PRS-010, this should be
74
+ * the project's `.dlang/packages/` directory for isolation
75
+ * and reproducibility (like node_modules).
76
+ */
77
+ constructor(cacheDir: string);
78
+ /**
79
+ * Sets the lock file for dependency resolution.
80
+ *
81
+ * When a lock file is set, all package imports will use
82
+ * the locked commit hashes instead of resolving versions.
83
+ * This ensures reproducible builds and handles transitive dependencies.
84
+ *
85
+ * @param lockFile - The parsed lock file from the workspace root
86
+ */
87
+ setLockFile(lockFile: LockFile | undefined): void;
88
+ /**
89
+ * Resolves a git import URL to the package's entry point file path.
90
+ *
91
+ * Process:
92
+ * 1. Parse git URL
93
+ * 2. Check lock file for pinned version (transitive dependency support)
94
+ * 3. Resolve version to commit hash (if not locked)
95
+ * 4. Check cache
96
+ * 5. Download repository if not cached
97
+ * 6. Read model.yaml to find entry point
98
+ * 7. Return path to entry point file
99
+ *
100
+ * @param importUrl - The git import URL
101
+ * @returns Path to the package's entry point file
102
+ */
103
+ resolve(importUrl: string): Promise<string>;
104
+ /**
105
+ * Reads model.yaml to get the package entry point.
106
+ * Falls back to index.dlang if no model.yaml found.
107
+ */
108
+ private getEntryPoint;
109
+ /**
110
+ * Parses model.yaml content to extract entry point.
111
+ *
112
+ * Expected structure:
113
+ * model:
114
+ * entry: index.dlang
115
+ */
116
+ private parseYaml;
117
+ /**
118
+ * Resolves a version (tag/branch) to a commit hash using git ls-remote.
119
+ */
120
+ resolveCommit(gitInfo: GitImportInfo): Promise<string>;
121
+ /**
122
+ * Gets the local cache path for a git repository.
123
+ *
124
+ * Format: .dlang/packages/{owner}/{repo}/{version}/
125
+ *
126
+ * Per PRS-010: Project-local cache structure mirrors the Design Considerations
127
+ * section showing `.dlang/packages/{owner}/{repo}/{version}/` layout.
128
+ */
129
+ getCachePath(gitInfo: GitImportInfo, commitHash: string): string;
130
+ /**
131
+ * Checks if a file or directory exists in the cache.
132
+ */
133
+ private existsInCache;
134
+ /**
135
+ * Downloads a git repository to the cache.
136
+ *
137
+ * Uses shallow clone for efficiency (only downloads the specific commit).
138
+ */
139
+ downloadRepo(gitInfo: GitImportInfo, commitHash: string, cachePath: string): Promise<void>;
140
+ /**
141
+ * Clears the entire cache.
142
+ */
143
+ clearCache(): Promise<void>;
144
+ /**
145
+ * Gets cache statistics (size, number of cached repos, etc.).
146
+ *
147
+ * Cache structure: .dlang/packages/{owner}/{repo}/{version}/
148
+ */
149
+ getCacheStats(): Promise<{
150
+ totalSize: number;
151
+ repoCount: number;
152
+ cacheDir: string;
153
+ }>;
154
+ /**
155
+ * Gets the total size of a directory in bytes.
156
+ */
157
+ private getDirectorySize;
158
+ }