@archon-research/uikit-cli 0.3.0-rohit-improve-cli.2 → 0.3.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,168 @@
1
+ import path from 'node:path';
2
+ /**
3
+ * Package and workspace discovery for monorepos
4
+ */
5
+ export class PackageDiscovery {
6
+ fs;
7
+ constructor(fs) {
8
+ this.fs = fs;
9
+ }
10
+ /**
11
+ * Find consumer workspace root by walking up looking for package.json with workspaces
12
+ */
13
+ findConsumerRoot(startDir) {
14
+ let current = startDir;
15
+ while (true) {
16
+ const pkgPath = path.join(current, 'package.json');
17
+ if (this.fs.exists(pkgPath)) {
18
+ try {
19
+ const pkg = this.fs.readJson(pkgPath);
20
+ if (pkg.workspaces) {
21
+ return current;
22
+ }
23
+ }
24
+ catch {
25
+ // Continue searching if parse fails
26
+ }
27
+ }
28
+ const parent = path.dirname(current);
29
+ if (parent === current) {
30
+ throw new Error(`Could not find consumer workspace root (no package.json with workspaces field)\n` +
31
+ `Searched from: ${startDir}\n` +
32
+ `Suggestion: Run from inside a workspace-based monorepo`);
33
+ }
34
+ current = parent;
35
+ }
36
+ }
37
+ /**
38
+ * Find uikit root by walking up looking for valid uikit monorepo structure
39
+ */
40
+ findUIKitRoot(startDir) {
41
+ let current = startDir;
42
+ while (true) {
43
+ if (this.isValidUIKitRoot(current)) {
44
+ return current;
45
+ }
46
+ const parent = path.dirname(current);
47
+ if (parent === current) {
48
+ return null;
49
+ }
50
+ current = parent;
51
+ }
52
+ }
53
+ /**
54
+ * Find uikit root from consumer by looking for sibling "uikit" directory
55
+ */
56
+ findUIKitRootFromConsumer(consumerRoot) {
57
+ const candidateNames = ['uikit'];
58
+ let current = consumerRoot;
59
+ while (true) {
60
+ for (const candidateName of candidateNames) {
61
+ const candidate = path.join(current, candidateName);
62
+ if (this.isValidUIKitRoot(candidate)) {
63
+ return candidate;
64
+ }
65
+ }
66
+ const parent = path.dirname(current);
67
+ if (parent === current) {
68
+ return null;
69
+ }
70
+ current = parent;
71
+ }
72
+ }
73
+ /**
74
+ * Check if directory is a valid uikit root (has design-system package)
75
+ */
76
+ isValidUIKitRoot(rootDir) {
77
+ if (!this.fs.exists(rootDir)) {
78
+ return false;
79
+ }
80
+ try {
81
+ const workspaces = this.loadWorkspaces(rootDir);
82
+ return workspaces.some((ws) => ws.name === '@archon-research/design-system');
83
+ }
84
+ catch {
85
+ return false;
86
+ }
87
+ }
88
+ /**
89
+ * Load all workspaces from a monorepo root
90
+ */
91
+ loadWorkspaces(rootDir) {
92
+ const patterns = this.getWorkspacePatterns(rootDir);
93
+ const workspaces = [];
94
+ if (process.env.UIKIT_DEBUG) {
95
+ console.log('[DEBUG loadWorkspaces] rootDir:', rootDir, 'patterns:', patterns);
96
+ }
97
+ for (const pattern of patterns) {
98
+ const resolved = this.resolveWorkspacePattern(rootDir, pattern);
99
+ if (process.env.UIKIT_DEBUG) {
100
+ console.log('[DEBUG loadWorkspaces] pattern:', pattern, 'resolved to:', resolved);
101
+ }
102
+ for (const dir of resolved) {
103
+ const pkgPath = path.join(dir, 'package.json');
104
+ if (!this.fs.exists(pkgPath)) {
105
+ if (process.env.UIKIT_DEBUG) {
106
+ console.log('[DEBUG loadWorkspaces] Skipping (no package.json):', dir);
107
+ }
108
+ continue;
109
+ }
110
+ try {
111
+ const pkg = this.fs.readJson(pkgPath);
112
+ workspaces.push({
113
+ name: pkg.name ?? null,
114
+ location: path.relative(rootDir, dir),
115
+ path: dir,
116
+ dependencies: pkg.dependencies ?? {},
117
+ });
118
+ }
119
+ catch {
120
+ // Skip invalid package.json
121
+ }
122
+ }
123
+ }
124
+ return workspaces.filter((ws) => Boolean(ws.name));
125
+ }
126
+ getWorkspacePatterns(rootDir) {
127
+ const pkgPath = path.join(rootDir, 'package.json');
128
+ if (!this.fs.exists(pkgPath)) {
129
+ return [];
130
+ }
131
+ try {
132
+ const pkg = this.fs.readJson(pkgPath);
133
+ if (Array.isArray(pkg.workspaces)) {
134
+ return pkg.workspaces;
135
+ }
136
+ if (pkg.workspaces && Array.isArray(pkg.workspaces.packages)) {
137
+ return pkg.workspaces.packages;
138
+ }
139
+ }
140
+ catch {
141
+ // Return empty if parse fails
142
+ }
143
+ return [];
144
+ }
145
+ resolveWorkspacePattern(rootDir, pattern) {
146
+ // Handle simple glob patterns like "packages/*"
147
+ if (pattern.includes('*')) {
148
+ // Only support "dir/*" pattern for now
149
+ if (pattern.endsWith('/*')) {
150
+ const baseDir = pattern.slice(0, -2);
151
+ const basePath = path.join(rootDir, baseDir);
152
+ if (!this.fs.exists(basePath) || !this.fs.isDirectory(basePath)) {
153
+ return [];
154
+ }
155
+ const entries = this.fs.readDir(basePath);
156
+ return entries
157
+ .filter((entry) => !entry.startsWith('.') && entry !== 'node_modules')
158
+ .map((entry) => path.join(basePath, entry))
159
+ .filter((p) => this.fs.isDirectory(p));
160
+ }
161
+ // Unsupported pattern
162
+ return [];
163
+ }
164
+ // Static pattern, return as-is if it's a directory
165
+ const fullPath = path.join(rootDir, pattern);
166
+ return this.fs.isDirectory(fullPath) ? [fullPath] : [];
167
+ }
168
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shell argument escaping utility
3
+ */
4
+ export function shellEscape(arg) {
5
+ if (/^[a-zA-Z0-9_\-./:=]+$/.test(arg)) {
6
+ return arg;
7
+ }
8
+ return `'${arg.replace(/'/g, "'\\''")}'`;
9
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "@archon-research/uikit-cli",
3
- "version": "0.3.0-rohit-improve-cli.2",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "CLI for managing local uikit package linking in consumer workspaces",
6
6
  "scripts": {
7
- "build": "tsc -p tsconfig.json",
7
+ "build": "tsgo -b && npm run wrapper",
8
+ "wrapper": "./scripts/create-wrapper.sh",
8
9
  "clean": "rm -rf dist",
9
10
  "type:check": "tsgo -p tsconfig.json --noEmit",
10
11
  "prepare": "npm run build"
11
12
  },
12
13
  "bin": {
13
- "uikit-cli": "./dist/cli.js"
14
+ "uikit-cli": "./dist/cli.sh"
14
15
  },
15
16
  "publishConfig": {
16
17
  "access": "public"