@aspects-ai/workspace-cli 0.1.0 → 0.1.2
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/README.md +29 -16
- package/dist/index.js +80 -15
- package/dist/registry/libraries.json +4 -20
- package/package.json +2 -2
- package/src/registry/libraries.json +4 -20
package/README.md
CHANGED
|
@@ -83,6 +83,21 @@ The command will:
|
|
|
83
83
|
3. Update `workspace.config.json`
|
|
84
84
|
4. Add dependencies to `package.json`
|
|
85
85
|
|
|
86
|
+
### `update <library>`
|
|
87
|
+
|
|
88
|
+
Update an installed library to the latest version from the repository.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
WORKSPACE_CLI_TOKEN=ghp_xxx workspace-cli update animate-core
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
This command will:
|
|
95
|
+
1. Check the currently installed version
|
|
96
|
+
2. Fetch the latest version from the git repository
|
|
97
|
+
3. Overwrite the existing files
|
|
98
|
+
4. Update `workspace.config.json` with the new version and commit hash
|
|
99
|
+
5. Update dependencies in `package.json` if they changed
|
|
100
|
+
|
|
86
101
|
## Usage Examples
|
|
87
102
|
|
|
88
103
|
### Basic Workflow
|
|
@@ -176,28 +191,27 @@ Libraries are defined in `src/registry/libraries.json`:
|
|
|
176
191
|
"animate-core": {
|
|
177
192
|
"name": "@aspects-ai/noodle-animate-core",
|
|
178
193
|
"description": "Core animation components for Noodle videos",
|
|
179
|
-
"version": "0.1.3",
|
|
180
194
|
"repository": {
|
|
181
195
|
"url": "https://github.com/aspects-ai/noodle-templates.git",
|
|
182
196
|
"directory": "noodle-animate-core/src",
|
|
183
|
-
"branch": "main"
|
|
197
|
+
"branch": "main",
|
|
198
|
+
"packageJsonPath": "noodle-animate-core/package.json"
|
|
184
199
|
},
|
|
185
|
-
"installPath": "animate-core"
|
|
186
|
-
"dependencies": {
|
|
187
|
-
"react": "19.1.0",
|
|
188
|
-
"remotion": "4.0.356"
|
|
189
|
-
}
|
|
200
|
+
"installPath": "animate-core"
|
|
190
201
|
}
|
|
191
202
|
}
|
|
192
203
|
}
|
|
193
204
|
```
|
|
194
205
|
|
|
206
|
+
**Automatic Detection**: The CLI automatically reads both the `version` and `dependencies` from the library's `package.json` in the git repository. You don't need to hardcode these values in the registry - they're always fetched from the source of truth.
|
|
207
|
+
|
|
195
208
|
## How It Works
|
|
196
209
|
|
|
197
210
|
1. **Git Sparse Checkout**: The CLI uses git sparse checkout to efficiently fetch only the required directory from the repository
|
|
198
|
-
2. **
|
|
199
|
-
3. **
|
|
200
|
-
4. **
|
|
211
|
+
2. **Automatic Metadata Detection**: Both version and dependencies are read from the library's `package.json` in the repository, so they're always up-to-date
|
|
212
|
+
3. **Local Installation**: Files are copied to `./core/<library-name>/` in your workspace
|
|
213
|
+
4. **Dependency Management**: Required dependencies are automatically added to your `package.json`
|
|
214
|
+
5. **Version Tracking**: The exact git commit hash and detected version are stored for reproducibility
|
|
201
215
|
|
|
202
216
|
## Error Handling
|
|
203
217
|
|
|
@@ -249,20 +263,19 @@ Example:
|
|
|
249
263
|
"my-library": {
|
|
250
264
|
"name": "@aspects-ai/my-library",
|
|
251
265
|
"description": "Description of the library",
|
|
252
|
-
"version": "1.0.0",
|
|
253
266
|
"repository": {
|
|
254
267
|
"url": "https://github.com/org/repo.git",
|
|
255
268
|
"directory": "path/to/library/src",
|
|
256
|
-
"branch": "main"
|
|
269
|
+
"branch": "main",
|
|
270
|
+
"packageJsonPath": "path/to/library/package.json"
|
|
257
271
|
},
|
|
258
|
-
"installPath": "my-library"
|
|
259
|
-
"dependencies": {
|
|
260
|
-
"react": "^18.0.0"
|
|
261
|
-
}
|
|
272
|
+
"installPath": "my-library"
|
|
262
273
|
}
|
|
263
274
|
}
|
|
264
275
|
```
|
|
265
276
|
|
|
277
|
+
**Note**: Both `version` and `dependencies` fields are optional. If you provide `packageJsonPath`, the CLI will automatically read these from the library's `package.json` in the repository. This keeps the registry minimal and ensures values are always current.
|
|
278
|
+
|
|
266
279
|
## License
|
|
267
280
|
|
|
268
281
|
ISC
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command5 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -165,15 +165,19 @@ import { z as z2 } from "zod";
|
|
|
165
165
|
var RepositorySchema = z2.object({
|
|
166
166
|
url: z2.string(),
|
|
167
167
|
directory: z2.string(),
|
|
168
|
-
branch: z2.string()
|
|
168
|
+
branch: z2.string(),
|
|
169
|
+
packageJsonPath: z2.string().optional()
|
|
170
|
+
// Path to package.json in repo (e.g., "noodle-animate-core/package.json")
|
|
169
171
|
});
|
|
170
172
|
var LibrarySchema = z2.object({
|
|
171
173
|
name: z2.string(),
|
|
172
174
|
description: z2.string(),
|
|
173
|
-
version: z2.string(),
|
|
175
|
+
version: z2.string().optional(),
|
|
176
|
+
// Optional - if not provided, will be read from package.json in repo
|
|
174
177
|
repository: RepositorySchema,
|
|
175
178
|
installPath: z2.string(),
|
|
176
|
-
dependencies: z2.record(z2.string())
|
|
179
|
+
dependencies: z2.record(z2.string()).optional()
|
|
180
|
+
// Optional - if not provided, will be read from package.json in repo
|
|
177
181
|
});
|
|
178
182
|
var RegistrySchema = z2.object({
|
|
179
183
|
libraries: z2.record(LibrarySchema)
|
|
@@ -215,7 +219,8 @@ function createListCommand() {
|
|
|
215
219
|
const libraries = await listLibraries();
|
|
216
220
|
logger.log(chalk2.bold("\nAvailable libraries:\n"));
|
|
217
221
|
for (const { name, library } of libraries) {
|
|
218
|
-
|
|
222
|
+
const versionStr = library.version ? ` @${library.version}` : " @latest";
|
|
223
|
+
logger.log(chalk2.cyan(` ${name}`) + chalk2.gray(versionStr));
|
|
219
224
|
logger.log(` ${library.description}`);
|
|
220
225
|
logger.log("");
|
|
221
226
|
}
|
|
@@ -251,8 +256,13 @@ async function fetchDirectory(options) {
|
|
|
251
256
|
await execa("git", ["remote", "add", "origin", repoUrl], { cwd: tempDir });
|
|
252
257
|
await execa("git", ["config", "core.sparseCheckout", "true"], { cwd: tempDir });
|
|
253
258
|
const sparseFile = path3.join(tempDir, ".git", "info", "sparse-checkout");
|
|
254
|
-
|
|
255
|
-
|
|
259
|
+
let sparsePaths = `${options.directory}/*
|
|
260
|
+
`;
|
|
261
|
+
if (options.packageJsonPath) {
|
|
262
|
+
sparsePaths += `${options.packageJsonPath}
|
|
263
|
+
`;
|
|
264
|
+
}
|
|
265
|
+
await fs3.writeFile(sparseFile, sparsePaths);
|
|
256
266
|
await execa("git", ["pull", "origin", options.branch, "--depth=1"], {
|
|
257
267
|
cwd: tempDir,
|
|
258
268
|
stderr: "pipe"
|
|
@@ -267,7 +277,26 @@ async function fetchDirectory(options) {
|
|
|
267
277
|
overwrite: true,
|
|
268
278
|
errorOnExist: false
|
|
269
279
|
});
|
|
270
|
-
|
|
280
|
+
let version = null;
|
|
281
|
+
let dependencies = {};
|
|
282
|
+
if (options.packageJsonPath) {
|
|
283
|
+
const packageJsonFullPath = path3.join(tempDir, options.packageJsonPath);
|
|
284
|
+
if (await fs3.pathExists(packageJsonFullPath)) {
|
|
285
|
+
try {
|
|
286
|
+
const packageJson = await fs3.readJson(packageJsonFullPath);
|
|
287
|
+
version = packageJson.version || null;
|
|
288
|
+
dependencies = packageJson.dependencies || {};
|
|
289
|
+
} catch (error) {
|
|
290
|
+
version = null;
|
|
291
|
+
dependencies = {};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
commit: commit.trim(),
|
|
297
|
+
version,
|
|
298
|
+
dependencies
|
|
299
|
+
};
|
|
271
300
|
} catch (error) {
|
|
272
301
|
if (error.stderr && error.stderr.includes("Authentication failed")) {
|
|
273
302
|
throw new Error(
|
|
@@ -305,20 +334,24 @@ Use --force to reinstall.`
|
|
|
305
334
|
const config = await loadWorkspaceConfig(workspaceRoot);
|
|
306
335
|
const coreDir = config?.coreDir || "./core";
|
|
307
336
|
const targetPath = path4.join(workspaceRoot, coreDir, library.installPath);
|
|
308
|
-
|
|
309
|
-
|
|
337
|
+
const versionDisplay = library.version || "latest";
|
|
338
|
+
logger.info(`Fetching ${libraryName}@${versionDisplay} from git...`);
|
|
339
|
+
const result = await fetchDirectory({
|
|
310
340
|
repository: library.repository.url,
|
|
311
341
|
directory: library.repository.directory,
|
|
312
342
|
branch: library.repository.branch,
|
|
313
343
|
token,
|
|
314
|
-
targetPath
|
|
344
|
+
targetPath,
|
|
345
|
+
packageJsonPath: library.repository.packageJsonPath
|
|
315
346
|
});
|
|
347
|
+
const actualVersion = result.version || library.version || "unknown";
|
|
348
|
+
const actualDependencies = Object.keys(result.dependencies).length > 0 ? result.dependencies : library.dependencies || {};
|
|
316
349
|
logger.info(`Installed to ${path4.relative(workspaceRoot, targetPath)}`);
|
|
317
350
|
logger.info(`Updating workspace.config.json...`);
|
|
318
|
-
await addLibraryToConfig(workspaceRoot, libraryName,
|
|
319
|
-
await updatePackageDependencies(workspaceRoot,
|
|
351
|
+
await addLibraryToConfig(workspaceRoot, libraryName, actualVersion, result.commit);
|
|
352
|
+
await updatePackageDependencies(workspaceRoot, actualDependencies);
|
|
320
353
|
logger.success(
|
|
321
|
-
`Installed ${libraryName}@${
|
|
354
|
+
`Installed ${libraryName}@${actualVersion} (commit: ${result.commit.substring(0, 7)})`
|
|
322
355
|
);
|
|
323
356
|
}
|
|
324
357
|
async function updatePackageDependencies(workspaceRoot, dependencies) {
|
|
@@ -364,10 +397,42 @@ function createAddCommand() {
|
|
|
364
397
|
});
|
|
365
398
|
}
|
|
366
399
|
|
|
400
|
+
// src/commands/update.ts
|
|
401
|
+
import { Command as Command4 } from "commander";
|
|
402
|
+
import chalk4 from "chalk";
|
|
403
|
+
function createUpdateCommand() {
|
|
404
|
+
return new Command4("update").description("Update an installed library to the latest version").argument("<library>", "Name of the library to update").action(async (libraryName) => {
|
|
405
|
+
try {
|
|
406
|
+
const workspaceRoot = await ensureWorkspaceRoot();
|
|
407
|
+
await getOrCreateConfig(workspaceRoot);
|
|
408
|
+
if (!await isLibraryInstalled(workspaceRoot, libraryName)) {
|
|
409
|
+
throw new Error(
|
|
410
|
+
`Library '${libraryName}' is not installed.
|
|
411
|
+
Use 'workspace-cli add ${libraryName}' to install it first.`
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
const config = await loadWorkspaceConfig(workspaceRoot);
|
|
415
|
+
const currentVersion = config?.libraries[libraryName]?.version || "unknown";
|
|
416
|
+
const currentCommit = config?.libraries[libraryName]?.commit || "unknown";
|
|
417
|
+
logger.info(`Current version: ${currentVersion} (commit: ${currentCommit.substring(0, 7)})`);
|
|
418
|
+
logger.info(`Updating ${libraryName}...`);
|
|
419
|
+
await installLibrary(workspaceRoot, libraryName, { force: true });
|
|
420
|
+
logger.log("\n" + chalk4.bold("Next steps:"));
|
|
421
|
+
logger.log(` ${chalk4.gray("Review changes:")} git diff ./core/${libraryName.replace("animate-", "")}`);
|
|
422
|
+
logger.log(` ${chalk4.gray("Install updated dependencies:")} npm install`);
|
|
423
|
+
logger.log("");
|
|
424
|
+
} catch (error) {
|
|
425
|
+
logger.error(error.message);
|
|
426
|
+
process.exit(1);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
367
431
|
// src/index.ts
|
|
368
|
-
var program = new
|
|
432
|
+
var program = new Command5();
|
|
369
433
|
program.name("workspace-cli").description("Lightweight CLI for installing libraries into workspaces").version("0.1.0");
|
|
370
434
|
program.addCommand(createInitCommand());
|
|
371
435
|
program.addCommand(createListCommand());
|
|
372
436
|
program.addCommand(createAddCommand());
|
|
437
|
+
program.addCommand(createUpdateCommand());
|
|
373
438
|
program.parse(process.argv);
|
|
@@ -3,29 +3,13 @@
|
|
|
3
3
|
"animate-core": {
|
|
4
4
|
"name": "@aspects-ai/noodle-animate-core",
|
|
5
5
|
"description": "Core animation components for Noodle videos",
|
|
6
|
-
"version": "0.1.3",
|
|
7
6
|
"repository": {
|
|
8
7
|
"url": "https://github.com/aspects-ai/noodle-templates.git",
|
|
9
8
|
"directory": "noodle-animate-core/src",
|
|
10
|
-
"branch": "main"
|
|
9
|
+
"branch": "main",
|
|
10
|
+
"packageJsonPath": "noodle-animate-core/package.json"
|
|
11
11
|
},
|
|
12
|
-
"installPath": "animate-core"
|
|
13
|
-
"dependencies": {
|
|
14
|
-
"react": "19.1.0",
|
|
15
|
-
"react-dom": "19.1.0",
|
|
16
|
-
"remotion": "4.0.356",
|
|
17
|
-
"react-rnd": "^10.5.2",
|
|
18
|
-
"class-variance-authority": "^0.7.1",
|
|
19
|
-
"clsx": "^2.1.1",
|
|
20
|
-
"cmdk": "^1.1.1",
|
|
21
|
-
"date-fns": "^4.1.0",
|
|
22
|
-
"embla-carousel-react": "^8.6.0",
|
|
23
|
-
"input-otp": "^1.4.2",
|
|
24
|
-
"lucide-react": "^0.542.0",
|
|
25
|
-
"tailwind-merge": "^3.3.1",
|
|
26
|
-
"tailwindcss-animate": "^1.0.7",
|
|
27
|
-
"vaul": "^1.1.2"
|
|
28
|
-
}
|
|
12
|
+
"installPath": "animate-core"
|
|
29
13
|
}
|
|
30
14
|
}
|
|
31
|
-
}
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aspects-ai/workspace-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Lightweight CLI for installing libraries into workspaces",
|
|
6
6
|
"type": "module",
|
|
@@ -33,4 +33,4 @@
|
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=18.0.0"
|
|
35
35
|
}
|
|
36
|
-
}
|
|
36
|
+
}
|
|
@@ -3,29 +3,13 @@
|
|
|
3
3
|
"animate-core": {
|
|
4
4
|
"name": "@aspects-ai/noodle-animate-core",
|
|
5
5
|
"description": "Core animation components for Noodle videos",
|
|
6
|
-
"version": "0.1.3",
|
|
7
6
|
"repository": {
|
|
8
7
|
"url": "https://github.com/aspects-ai/noodle-templates.git",
|
|
9
8
|
"directory": "noodle-animate-core/src",
|
|
10
|
-
"branch": "main"
|
|
9
|
+
"branch": "main",
|
|
10
|
+
"packageJsonPath": "noodle-animate-core/package.json"
|
|
11
11
|
},
|
|
12
|
-
"installPath": "animate-core"
|
|
13
|
-
"dependencies": {
|
|
14
|
-
"react": "19.1.0",
|
|
15
|
-
"react-dom": "19.1.0",
|
|
16
|
-
"remotion": "4.0.356",
|
|
17
|
-
"react-rnd": "^10.5.2",
|
|
18
|
-
"class-variance-authority": "^0.7.1",
|
|
19
|
-
"clsx": "^2.1.1",
|
|
20
|
-
"cmdk": "^1.1.1",
|
|
21
|
-
"date-fns": "^4.1.0",
|
|
22
|
-
"embla-carousel-react": "^8.6.0",
|
|
23
|
-
"input-otp": "^1.4.2",
|
|
24
|
-
"lucide-react": "^0.542.0",
|
|
25
|
-
"tailwind-merge": "^3.3.1",
|
|
26
|
-
"tailwindcss-animate": "^1.0.7",
|
|
27
|
-
"vaul": "^1.1.2"
|
|
28
|
-
}
|
|
12
|
+
"installPath": "animate-core"
|
|
29
13
|
}
|
|
30
14
|
}
|
|
31
|
-
}
|
|
15
|
+
}
|