@domainlang/cli 0.5.2 → 0.7.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 +16 -16
  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,13 @@
1
+ /**
2
+ * CLI Services Index
3
+ *
4
+ * Exports all CLI-only services for package management.
5
+ * These services contain network operations and should never be used in LSP.
6
+ */
7
+ export * from './types.js';
8
+ export * from './semver.js';
9
+ export * from './git-url-resolver.js';
10
+ export * from './dependency-resolver.js';
11
+ export * from './dependency-analyzer.js';
12
+ export * from './governance-validator.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Semantic Versioning Utilities (CLI-only)
3
+ *
4
+ * Centralized SemVer parsing, comparison, and validation for the dependency system.
5
+ * All version-related logic should use these utilities to ensure consistency.
6
+ *
7
+ * Supported formats:
8
+ * - "1.0.0" or "v1.0.0" (tags)
9
+ * - "1.0.0-alpha.1" (pre-release)
10
+ * - "main", "develop" (branches)
11
+ * - "abc123def" (commit SHAs, 7-40 hex chars)
12
+ */
13
+ import type { SemVer, RefType, ParsedRef } from './types.js';
14
+ /**
15
+ * Parses a version string into SemVer components.
16
+ * Returns undefined if not a valid SemVer.
17
+ *
18
+ * @example
19
+ * parseSemVer("v1.2.3") // { major: 1, minor: 2, patch: 3, original: "v1.2.3" }
20
+ * parseSemVer("1.0.0-alpha") // { major: 1, minor: 0, patch: 0, prerelease: "alpha", ... }
21
+ * parseSemVer("main") // undefined (not SemVer)
22
+ */
23
+ export declare function parseSemVer(version: string): SemVer | undefined;
24
+ /**
25
+ * Detects the type of a git ref based on its format.
26
+ *
27
+ * @example
28
+ * detectRefType("v1.0.0") // 'tag'
29
+ * detectRefType("1.2.3") // 'tag'
30
+ * detectRefType("main") // 'branch'
31
+ * detectRefType("abc123def") // 'commit'
32
+ */
33
+ export declare function detectRefType(ref: string): RefType;
34
+ /**
35
+ * Parses a ref string into a structured ParsedRef with type and optional SemVer.
36
+ */
37
+ export declare function parseRef(ref: string): ParsedRef;
38
+ /**
39
+ * Compares two SemVer versions.
40
+ * Returns: negative if a < b, positive if a > b, zero if equal.
41
+ *
42
+ * @example
43
+ * compareSemVer(parse("1.0.0"), parse("2.0.0")) // negative (a < b)
44
+ * compareSemVer(parse("1.5.0"), parse("1.2.0")) // positive (a > b)
45
+ * compareSemVer(parse("1.0.0-alpha"), parse("1.0.0")) // negative (prerelease < release)
46
+ */
47
+ export declare function compareSemVer(a: SemVer, b: SemVer): number;
48
+ /**
49
+ * Picks the latest from a list of SemVer refs.
50
+ * Returns the ref string (with original 'v' prefix if present).
51
+ *
52
+ * @example
53
+ * pickLatestSemVer(["v1.0.0", "v1.5.0", "v1.2.0"]) // "v1.5.0"
54
+ */
55
+ export declare function pickLatestSemVer(refs: string[]): string | undefined;
56
+ /**
57
+ * Sorts version strings in descending order (newest first).
58
+ * Non-SemVer refs are sorted lexicographically at the end.
59
+ *
60
+ * @example
61
+ * sortVersionsDescending(["v1.0.0", "v2.0.0", "v1.5.0"]) // ["v2.0.0", "v1.5.0", "v1.0.0"]
62
+ */
63
+ export declare function sortVersionsDescending(versions: string[]): string[];
64
+ /**
65
+ * Checks if a version/ref is a pre-release.
66
+ *
67
+ * Pre-release identifiers: alpha, beta, rc, pre, dev, snapshot
68
+ *
69
+ * @example
70
+ * isPreRelease("v1.0.0") // false
71
+ * isPreRelease("v1.0.0-alpha") // true
72
+ * isPreRelease("v1.0.0-rc.1") // true
73
+ */
74
+ export declare function isPreRelease(ref: string): boolean;
75
+ /**
76
+ * Checks if two SemVer versions are compatible (same major version).
77
+ *
78
+ * @example
79
+ * areSameMajor(parse("1.0.0"), parse("1.5.0")) // true
80
+ * areSameMajor(parse("1.0.0"), parse("2.0.0")) // false
81
+ */
82
+ export declare function areSameMajor(a: SemVer, b: SemVer): boolean;
83
+ /**
84
+ * Gets the major version number from a ref string.
85
+ * Returns undefined if not a valid SemVer.
86
+ */
87
+ export declare function getMajorVersion(ref: string): number | undefined;
88
+ /**
89
+ * Filters refs to only stable versions (excludes pre-releases).
90
+ *
91
+ * @example
92
+ * filterStableVersions(["v1.0.0", "v1.1.0-alpha", "v1.2.0"]) // ["v1.0.0", "v1.2.0"]
93
+ */
94
+ export declare function filterStableVersions(refs: string[]): string[];
95
+ /**
96
+ * Filters refs to only SemVer tags (excludes branches and commits).
97
+ */
98
+ export declare function filterSemVerTags(refs: string[]): string[];
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Semantic Versioning Utilities (CLI-only)
3
+ *
4
+ * Centralized SemVer parsing, comparison, and validation for the dependency system.
5
+ * All version-related logic should use these utilities to ensure consistency.
6
+ *
7
+ * Supported formats:
8
+ * - "1.0.0" or "v1.0.0" (tags)
9
+ * - "1.0.0-alpha.1" (pre-release)
10
+ * - "main", "develop" (branches)
11
+ * - "abc123def" (commit SHAs, 7-40 hex chars)
12
+ */
13
+ // ============================================================================
14
+ // Parsing
15
+ // ============================================================================
16
+ /**
17
+ * Parses a version string into SemVer components.
18
+ * Returns undefined if not a valid SemVer.
19
+ *
20
+ * @example
21
+ * parseSemVer("v1.2.3") // { major: 1, minor: 2, patch: 3, original: "v1.2.3" }
22
+ * parseSemVer("1.0.0-alpha") // { major: 1, minor: 0, patch: 0, prerelease: "alpha", ... }
23
+ * parseSemVer("main") // undefined (not SemVer)
24
+ */
25
+ export function parseSemVer(version) {
26
+ // Strip leading 'v' if present
27
+ const normalized = version.startsWith('v') ? version.slice(1) : version;
28
+ // Match semver pattern: major.minor.patch[-prerelease]
29
+ const match = normalized.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
30
+ if (!match)
31
+ return undefined;
32
+ return {
33
+ major: parseInt(match[1], 10),
34
+ minor: parseInt(match[2], 10),
35
+ patch: parseInt(match[3], 10),
36
+ preRelease: match[4],
37
+ original: version,
38
+ };
39
+ }
40
+ /**
41
+ * Detects the type of a git ref based on its format.
42
+ *
43
+ * @example
44
+ * detectRefType("v1.0.0") // 'tag'
45
+ * detectRefType("1.2.3") // 'tag'
46
+ * detectRefType("main") // 'branch'
47
+ * detectRefType("abc123def") // 'commit'
48
+ */
49
+ export function detectRefType(ref) {
50
+ // Commit SHA: 7-40 hex characters
51
+ if (/^[0-9a-f]{7,40}$/i.test(ref)) {
52
+ return 'commit';
53
+ }
54
+ // Tags typically start with 'v' followed by semver
55
+ if (/^v?\d+\.\d+\.\d+/.test(ref)) {
56
+ return 'tag';
57
+ }
58
+ // Everything else is treated as a branch
59
+ return 'branch';
60
+ }
61
+ /**
62
+ * Parses a ref string into a structured ParsedRef with type and optional SemVer.
63
+ */
64
+ export function parseRef(ref) {
65
+ const type = detectRefType(ref);
66
+ const semver = type === 'tag' ? parseSemVer(ref) : undefined;
67
+ return { original: ref, type, semver };
68
+ }
69
+ // ============================================================================
70
+ // Comparison
71
+ // ============================================================================
72
+ /**
73
+ * Compares two SemVer versions.
74
+ * Returns: negative if a < b, positive if a > b, zero if equal.
75
+ *
76
+ * @example
77
+ * compareSemVer(parse("1.0.0"), parse("2.0.0")) // negative (a < b)
78
+ * compareSemVer(parse("1.5.0"), parse("1.2.0")) // positive (a > b)
79
+ * compareSemVer(parse("1.0.0-alpha"), parse("1.0.0")) // negative (prerelease < release)
80
+ */
81
+ export function compareSemVer(a, b) {
82
+ if (a.major !== b.major)
83
+ return a.major - b.major;
84
+ if (a.minor !== b.minor)
85
+ return a.minor - b.minor;
86
+ if (a.patch !== b.patch)
87
+ return a.patch - b.patch;
88
+ // Pre-release versions are lower than release versions
89
+ if (a.preRelease && !b.preRelease)
90
+ return -1;
91
+ if (!a.preRelease && b.preRelease)
92
+ return 1;
93
+ if (a.preRelease && b.preRelease) {
94
+ return a.preRelease.localeCompare(b.preRelease);
95
+ }
96
+ return 0;
97
+ }
98
+ /**
99
+ * Picks the latest from a list of SemVer refs.
100
+ * Returns the ref string (with original 'v' prefix if present).
101
+ *
102
+ * @example
103
+ * pickLatestSemVer(["v1.0.0", "v1.5.0", "v1.2.0"]) // "v1.5.0"
104
+ */
105
+ export function pickLatestSemVer(refs) {
106
+ const parsed = refs
107
+ .map(ref => ({ ref, semver: parseSemVer(ref) }))
108
+ .filter((item) => item.semver !== undefined);
109
+ if (parsed.length === 0)
110
+ return undefined;
111
+ parsed.sort((a, b) => compareSemVer(b.semver, a.semver)); // Descending
112
+ return parsed[0].ref;
113
+ }
114
+ /**
115
+ * Sorts version strings in descending order (newest first).
116
+ * Non-SemVer refs are sorted lexicographically at the end.
117
+ *
118
+ * @example
119
+ * sortVersionsDescending(["v1.0.0", "v2.0.0", "v1.5.0"]) // ["v2.0.0", "v1.5.0", "v1.0.0"]
120
+ */
121
+ export function sortVersionsDescending(versions) {
122
+ return [...versions].sort((a, b) => {
123
+ const semverA = parseSemVer(a);
124
+ const semverB = parseSemVer(b);
125
+ // Both are SemVer - compare semantically
126
+ if (semverA && semverB) {
127
+ return compareSemVer(semverB, semverA); // Descending
128
+ }
129
+ // SemVer comes before non-SemVer
130
+ if (semverA && !semverB)
131
+ return -1;
132
+ if (!semverA && semverB)
133
+ return 1;
134
+ // Both non-SemVer - lexicographic
135
+ return b.localeCompare(a);
136
+ });
137
+ }
138
+ // ============================================================================
139
+ // Validation
140
+ // ============================================================================
141
+ /**
142
+ * Checks if a version/ref is a pre-release.
143
+ *
144
+ * Pre-release identifiers: alpha, beta, rc, pre, dev, snapshot
145
+ *
146
+ * @example
147
+ * isPreRelease("v1.0.0") // false
148
+ * isPreRelease("v1.0.0-alpha") // true
149
+ * isPreRelease("v1.0.0-rc.1") // true
150
+ */
151
+ export function isPreRelease(ref) {
152
+ const semver = parseSemVer(ref);
153
+ if (semver?.preRelease) {
154
+ return true;
155
+ }
156
+ // Also check for common pre-release patterns without proper SemVer
157
+ const clean = ref.replace(/^v/, '');
158
+ return /-(alpha|beta|rc|pre|dev|snapshot)/i.test(clean);
159
+ }
160
+ /**
161
+ * Checks if two SemVer versions are compatible (same major version).
162
+ *
163
+ * @example
164
+ * areSameMajor(parse("1.0.0"), parse("1.5.0")) // true
165
+ * areSameMajor(parse("1.0.0"), parse("2.0.0")) // false
166
+ */
167
+ export function areSameMajor(a, b) {
168
+ return a.major === b.major;
169
+ }
170
+ /**
171
+ * Gets the major version number from a ref string.
172
+ * Returns undefined if not a valid SemVer.
173
+ */
174
+ export function getMajorVersion(ref) {
175
+ return parseSemVer(ref)?.major;
176
+ }
177
+ // ============================================================================
178
+ // Filtering
179
+ // ============================================================================
180
+ /**
181
+ * Filters refs to only stable versions (excludes pre-releases).
182
+ *
183
+ * @example
184
+ * filterStableVersions(["v1.0.0", "v1.1.0-alpha", "v1.2.0"]) // ["v1.0.0", "v1.2.0"]
185
+ */
186
+ export function filterStableVersions(refs) {
187
+ return refs.filter(ref => !isPreRelease(ref));
188
+ }
189
+ /**
190
+ * Filters refs to only SemVer tags (excludes branches and commits).
191
+ */
192
+ export function filterSemVerTags(refs) {
193
+ return refs.filter(ref => detectRefType(ref) === 'tag' && parseSemVer(ref) !== undefined);
194
+ }
195
+ //# sourceMappingURL=semver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semver.js","sourceRoot":"","sources":["../../src/services/semver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Types for CLI-only package management services.
3
+ *
4
+ * These types support git-based dependency resolution and governance
5
+ * that only runs in the CLI context (never in LSP).
6
+ */
7
+ import type { RefType } from '@domainlang/language';
8
+ export type { LockFile, LockedDependency, ModelManifest, DependencySpec, ExtendedDependencySpec, PathAliases, GovernancePolicy, GovernanceMetadata, GovernanceViolation, DependencyTreeNode, ReverseDependency, VersionPolicy, SemVer, RefType, ParsedRef, } from '@domainlang/language';
9
+ /**
10
+ * Parsed git import URL information.
11
+ */
12
+ export interface GitImportInfo {
13
+ /** Original import string */
14
+ original: string;
15
+ /** Detected platform (github, gitlab, bitbucket, generic) */
16
+ platform: 'github' | 'gitlab' | 'bitbucket' | 'generic';
17
+ /** Repository owner/organization */
18
+ owner: string;
19
+ /** Repository name */
20
+ repo: string;
21
+ /** Version/tag/branch/commit */
22
+ version: string;
23
+ /** Full repository URL without version */
24
+ repoUrl: string;
25
+ /** Entry point file (default: index.dlang) */
26
+ entryPoint: string;
27
+ }
28
+ /**
29
+ * Package configuration during dependency resolution.
30
+ */
31
+ export interface ResolvingPackage {
32
+ name?: string;
33
+ version?: string;
34
+ entry?: string;
35
+ dependencies?: Record<string, string>;
36
+ overrides?: Record<string, string>;
37
+ }
38
+ /**
39
+ * Dependency graph for resolution.
40
+ */
41
+ export interface DependencyGraph {
42
+ nodes: Record<string, DependencyGraphNode>;
43
+ root: string;
44
+ }
45
+ /**
46
+ * Node in the dependency graph.
47
+ */
48
+ export interface DependencyGraphNode {
49
+ packageKey: string;
50
+ refConstraint: string;
51
+ constraints?: Set<string>;
52
+ repoUrl?: string;
53
+ dependencies: Record<string, string>;
54
+ dependents: string[];
55
+ resolvedRef?: string;
56
+ refType?: RefType;
57
+ commitHash?: string;
58
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Types for CLI-only package management services.
3
+ *
4
+ * These types support git-based dependency resolution and governance
5
+ * that only runs in the CLI context (never in LSP).
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/services/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@domainlang/cli",
3
3
  "displayName": "DomainLang CLI",
4
4
  "description": "Command-line interface for DomainLang - validate, analyze, and manage Domain-Driven Design models",
5
- "version": "0.5.2",
5
+ "version": "0.7.0",
6
6
  "type": "module",
7
7
  "author": "larsbaunwall",
8
8
  "license": "Apache-2.0",
@@ -38,13 +38,14 @@
38
38
  "src"
39
39
  ],
40
40
  "bin": {
41
- "domain-lang-cli": "./bin/cli.js"
41
+ "dlang": "./bin/cli.js"
42
42
  },
43
43
  "scripts": {
44
44
  "clean": "shx rm -fr *.tsbuildinfo out",
45
45
  "build": "tsc -b tsconfig.json",
46
46
  "build:clean": "npm run clean && npm run build",
47
- "test": "vitest run"
47
+ "test": "vitest run",
48
+ "test:coverage": "vitest run --coverage"
48
49
  },
49
50
  "dependencies": {
50
51
  "@domainlang/language": "0.1.0",
@@ -1,4 +1,5 @@
1
- import { WorkspaceManager, DependencyAnalyzer, GovernanceValidator, loadGovernancePolicy } from '@domainlang/language';
1
+ import { WorkspaceManager } from '@domainlang/language';
2
+ import { DependencyAnalyzer, GovernanceValidator, loadGovernancePolicy, GitUrlResolver, DependencyResolver } from './services/index.js';
2
3
  import path from 'node:path';
3
4
  import fs from 'node:fs/promises';
4
5
  import os from 'node:os';
@@ -25,7 +26,7 @@ export async function listModels(workspaceRoot: string): Promise<void> {
25
26
  await manager.initialize(workspaceRoot);
26
27
  const lock = await manager.getLockFile();
27
28
  if (!lock) {
28
- console.log('No lock file found. Run `domain-lang-cli install` to generate dependencies.');
29
+ console.log('No lock file found. Run `dlang install` to generate dependencies.');
29
30
  return;
30
31
  }
31
32
  console.log('Model dependencies:');
@@ -53,9 +54,7 @@ export async function addModel(workspaceRoot: string, name: string, source: stri
53
54
  }
54
55
 
55
56
  // Add dependency
56
- if (!manifest.dependencies) {
57
- manifest.dependencies = {};
58
- }
57
+ manifest.dependencies ??= {};
59
58
 
60
59
  manifest.dependencies[name] = {
61
60
  source,
@@ -67,7 +66,7 @@ export async function addModel(workspaceRoot: string, name: string, source: stri
67
66
  await fs.writeFile(manifestPath, yamlContent, 'utf-8');
68
67
 
69
68
  console.log(`Added ${name}: ${source}@${version}`);
70
- console.log('Run `domain-lang-cli install` to download dependencies.');
69
+ console.log('Run `dlang install` to download dependencies.');
71
70
  }
72
71
 
73
72
  export async function removeModel(workspaceRoot: string, name: string): Promise<void> {
@@ -88,14 +87,14 @@ export async function removeModel(workspaceRoot: string, name: string): Promise<
88
87
  await fs.writeFile(manifestPath, yamlContent, 'utf-8');
89
88
 
90
89
  console.log(`Removed ${name}`);
91
- console.log('Run `domain-lang-cli install` to update lock file.');
90
+ console.log('Run `dlang install` to update lock file.');
92
91
  } catch (error) {
93
92
  console.error('Failed to remove dependency:', error);
94
93
  }
95
94
  }
96
95
 
97
96
  export async function statusModels(workspaceRoot: string): Promise<void> {
98
- const manager = new WorkspaceManager({ autoResolve: false });
97
+ const manager = new WorkspaceManager();
99
98
  await manager.initialize(workspaceRoot);
100
99
 
101
100
  const manifestPath = await manager.getManifestPath();
@@ -125,17 +124,33 @@ export async function statusModels(workspaceRoot: string): Promise<void> {
125
124
  }
126
125
 
127
126
  if (!lock || Object.keys(lock.dependencies).length === 0) {
128
- console.log('\nRun `domain-lang-cli install` to lock dependencies.');
127
+ console.log('\nRun `dlang install` to lock dependencies.');
129
128
  }
130
129
  }
131
130
 
132
- export async function updateModel(workspaceRoot: string, name?: string): Promise<void> {
133
- console.log(name ? `Updating ${name}...` : 'Updating all dependencies...');
131
+ export async function updateModel(workspaceRoot: string, _name?: string): Promise<void> {
132
+ console.log(_name ? `Updating ${_name}...` : 'Updating all dependencies...');
134
133
 
135
- // For now, just regenerate the lock file
134
+ // Use CLI services to regenerate the lock file
136
135
  const manager = new WorkspaceManager();
137
136
  await manager.initialize(workspaceRoot);
138
- await manager.regenerateLockFile();
137
+
138
+ const manifest = await manager.getManifest();
139
+ if (!manifest?.dependencies) {
140
+ console.log('No dependencies found in model.yaml');
141
+ return;
142
+ }
143
+
144
+ // Resolve dependencies using CLI services
145
+ const cacheDir = path.join(workspaceRoot, '.dlang', 'packages');
146
+ const gitResolver = new GitUrlResolver(cacheDir);
147
+ const resolver = new DependencyResolver(workspaceRoot, gitResolver);
148
+ const lock = await resolver.resolveDependencies();
149
+
150
+ // Write the lock file
151
+ const lockPath = path.join(workspaceRoot, 'model.lock');
152
+ const lockContent = JSON.stringify(lock, null, 2);
153
+ await fs.writeFile(lockPath, lockContent, 'utf-8');
139
154
 
140
155
  console.log('Dependencies updated and lock file regenerated.');
141
156
  }
@@ -143,7 +158,27 @@ export async function updateModel(workspaceRoot: string, name?: string): Promise
143
158
  export async function installModels(workspaceRoot: string): Promise<void> {
144
159
  const manager = new WorkspaceManager();
145
160
  await manager.initialize(workspaceRoot);
146
- const lock = await manager.ensureLockFile();
161
+
162
+ const manifest = await manager.getManifest();
163
+ if (!manifest?.dependencies) {
164
+ console.log('No dependencies found in model.yaml');
165
+ return;
166
+ }
167
+
168
+ // Check if lock file exists
169
+ let lock = await manager.getLockFile();
170
+
171
+ if (!lock) {
172
+ // Generate lock file
173
+ const cacheDir = path.join(workspaceRoot, '.dlang', 'packages');
174
+ const gitResolver = new GitUrlResolver(cacheDir);
175
+ const resolver = new DependencyResolver(workspaceRoot, gitResolver);
176
+ lock = await resolver.resolveDependencies();
177
+
178
+ const lockPath = path.join(workspaceRoot, 'model.lock');
179
+ const lockContent = JSON.stringify(lock, null, 2);
180
+ await fs.writeFile(lockPath, lockContent, 'utf-8');
181
+ }
147
182
 
148
183
  const count = Object.keys(lock.dependencies).length;
149
184
  console.log(`Dependencies installed: ${count} package(s) locked.`);
@@ -161,12 +196,12 @@ export async function cacheClear(): Promise<void> {
161
196
  }
162
197
 
163
198
  export async function showDependencyTree(workspaceRoot: string, options: { commits?: boolean } = {}): Promise<void> {
164
- const manager = new WorkspaceManager({ autoResolve: false });
199
+ const manager = new WorkspaceManager();
165
200
  await manager.initialize(workspaceRoot);
166
201
  const lock = await manager.getLockFile();
167
202
 
168
203
  if (!lock || Object.keys(lock.dependencies).length === 0) {
169
- console.log('No dependencies found. Run `domain-lang-cli install` first.');
204
+ console.log('No dependencies found. Run `dlang install` first.');
170
205
  return;
171
206
  }
172
207
 
@@ -183,12 +218,12 @@ export async function showDependencyTree(workspaceRoot: string, options: { commi
183
218
  }
184
219
 
185
220
  export async function showImpactAnalysis(workspaceRoot: string, packageName: string): Promise<void> {
186
- const manager = new WorkspaceManager({ autoResolve: false });
221
+ const manager = new WorkspaceManager();
187
222
  await manager.initialize(workspaceRoot);
188
223
  const lock = await manager.getLockFile();
189
224
 
190
225
  if (!lock) {
191
- console.log('No lock file found. Run `domain-lang-cli install` first.');
226
+ console.log('No lock file found. Run `dlang install` first.');
192
227
  return;
193
228
  }
194
229
 
@@ -208,12 +243,12 @@ export async function showImpactAnalysis(workspaceRoot: string, packageName: str
208
243
  }
209
244
 
210
245
  export async function validateModel(workspaceRoot: string): Promise<void> {
211
- const manager = new WorkspaceManager({ autoResolve: false });
246
+ const manager = new WorkspaceManager();
212
247
  await manager.initialize(workspaceRoot);
213
248
  const lock = await manager.getLockFile();
214
249
 
215
250
  if (!lock) {
216
- console.log('No lock file found. Run `domain-lang-cli install` first.');
251
+ console.log('No lock file found. Run `dlang install` first.');
217
252
  return;
218
253
  }
219
254
 
@@ -233,12 +268,12 @@ export async function validateModel(workspaceRoot: string): Promise<void> {
233
268
  }
234
269
 
235
270
  export async function auditDependencies(workspaceRoot: string): Promise<void> {
236
- const manager = new WorkspaceManager({ autoResolve: false });
271
+ const manager = new WorkspaceManager();
237
272
  await manager.initialize(workspaceRoot);
238
273
  const lock = await manager.getLockFile();
239
274
 
240
275
  if (!lock) {
241
- console.log('No lock file found. Run `domain-lang-cli install` first.');
276
+ console.log('No lock file found. Run `dlang install` first.');
242
277
  return;
243
278
  }
244
279
 
@@ -250,12 +285,12 @@ export async function auditDependencies(workspaceRoot: string): Promise<void> {
250
285
  }
251
286
 
252
287
  export async function checkCompliance(workspaceRoot: string): Promise<void> {
253
- const manager = new WorkspaceManager({ autoResolve: false });
288
+ const manager = new WorkspaceManager();
254
289
  await manager.initialize(workspaceRoot);
255
290
  const lock = await manager.getLockFile();
256
291
 
257
292
  if (!lock) {
258
- console.log('No lock file found. Run `domain-lang-cli install` first.');
293
+ console.log('No lock file found. Run `dlang install` first.');
259
294
  return;
260
295
  }
261
296
 
package/src/main.ts CHANGED
@@ -71,7 +71,7 @@ export type GenerateOptions = {
71
71
  profile?: boolean;
72
72
  }
73
73
 
74
- export default function(): void {
74
+ export default function setupCli(): void {
75
75
  const program = new Command();
76
76
 
77
77
  program.version(JSON.parse(packageContent).version);