@aspects-ai/workspace-cli 0.1.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.
package/README.md ADDED
@@ -0,0 +1,268 @@
1
+ # @aspects-ai/workspace-cli
2
+
3
+ Lightweight CLI for installing libraries into workspaces. Designed to be AI-friendly and CI/CD compatible.
4
+
5
+ ## Features
6
+
7
+ - Simple, non-interactive commands
8
+ - Git-based library installation via sparse checkout
9
+ - Environment variable authentication only (no prompts)
10
+ - Automatic dependency management
11
+ - Tracks installed libraries in `workspace.config.json`
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install -g @aspects-ai/workspace-cli
17
+ ```
18
+
19
+ Or use with npx:
20
+
21
+ ```bash
22
+ npx @aspects-ai/workspace-cli <command>
23
+ ```
24
+
25
+ ## Prerequisites
26
+
27
+ - Node.js >= 18.0.0
28
+ - Git installed and available in PATH
29
+ - GitHub personal access token (for private repositories)
30
+
31
+ ## Authentication
32
+
33
+ Set the `WORKSPACE_CLI_TOKEN` environment variable with your GitHub personal access token:
34
+
35
+ ```bash
36
+ export WORKSPACE_CLI_TOKEN=ghp_xxxxxxxxxxxx
37
+ ```
38
+
39
+ The token needs read access to the repositories containing the libraries.
40
+
41
+ ## Commands
42
+
43
+ ### `init`
44
+
45
+ Initialize workspace configuration. Creates `workspace.config.json` in the current workspace.
46
+
47
+ ```bash
48
+ workspace-cli init
49
+ ```
50
+
51
+ ### `list`
52
+
53
+ List all available libraries in the registry.
54
+
55
+ ```bash
56
+ workspace-cli list
57
+ ```
58
+
59
+ Example output:
60
+ ```
61
+ Available libraries:
62
+
63
+ animate-core @0.1.3
64
+ Core animation components for Noodle videos
65
+
66
+ Total: 1 library
67
+ ```
68
+
69
+ ### `add <library>`
70
+
71
+ Install a library into the workspace.
72
+
73
+ ```bash
74
+ WORKSPACE_CLI_TOKEN=ghp_xxx workspace-cli add animate-core
75
+ ```
76
+
77
+ Options:
78
+ - `-f, --force` - Force reinstall if already installed
79
+
80
+ The command will:
81
+ 1. Fetch the library from the git repository
82
+ 2. Install it to `./core/<library-name>/`
83
+ 3. Update `workspace.config.json`
84
+ 4. Add dependencies to `package.json`
85
+
86
+ ## Usage Examples
87
+
88
+ ### Basic Workflow
89
+
90
+ ```bash
91
+ # Navigate to your workspace
92
+ cd my-workspace
93
+
94
+ # Initialize workspace config
95
+ workspace-cli init
96
+
97
+ # View available libraries
98
+ workspace-cli list
99
+
100
+ # Install a library (requires token)
101
+ export WORKSPACE_CLI_TOKEN=ghp_xxxxxxxxxxxx
102
+ workspace-cli add animate-core
103
+
104
+ # Install dependencies
105
+ npm install
106
+ ```
107
+
108
+ ### CI/CD Usage
109
+
110
+ ```yaml
111
+ # .github/workflows/setup.yml
112
+ name: Setup Workspace
113
+
114
+ on: [push]
115
+
116
+ jobs:
117
+ setup:
118
+ runs-on: ubuntu-latest
119
+ steps:
120
+ - uses: actions/checkout@v3
121
+
122
+ - name: Setup Node.js
123
+ uses: actions/setup-node@v3
124
+ with:
125
+ node-version: '18'
126
+
127
+ - name: Install libraries
128
+ env:
129
+ WORKSPACE_CLI_TOKEN: ${{ secrets.GITHUB_TOKEN }}
130
+ run: |
131
+ npx @aspects-ai/workspace-cli add animate-core
132
+
133
+ - name: Install dependencies
134
+ run: npm install
135
+ ```
136
+
137
+ ### AI Agent Usage
138
+
139
+ The CLI is designed to be used by AI agents without any interactive prompts:
140
+
141
+ ```bash
142
+ # All commands fail fast with clear error messages
143
+ # No confirmation prompts
144
+ # Machine-readable output
145
+
146
+ WORKSPACE_CLI_TOKEN=$TOKEN workspace-cli add animate-core
147
+ ```
148
+
149
+ ## Configuration
150
+
151
+ ### workspace.config.json
152
+
153
+ The CLI creates and manages `workspace.config.json` in your workspace:
154
+
155
+ ```json
156
+ {
157
+ "version": "1.0",
158
+ "coreDir": "./core",
159
+ "libraries": {
160
+ "animate-core": {
161
+ "version": "0.1.3",
162
+ "installedAt": "2025-10-15T12:34:56Z",
163
+ "commit": "097cf62abc123"
164
+ }
165
+ }
166
+ }
167
+ ```
168
+
169
+ ### Library Registry
170
+
171
+ Libraries are defined in `src/registry/libraries.json`:
172
+
173
+ ```json
174
+ {
175
+ "libraries": {
176
+ "animate-core": {
177
+ "name": "@aspects-ai/noodle-animate-core",
178
+ "description": "Core animation components for Noodle videos",
179
+ "version": "0.1.3",
180
+ "repository": {
181
+ "url": "https://github.com/aspects-ai/noodle-templates.git",
182
+ "directory": "noodle-animate-core/src",
183
+ "branch": "main"
184
+ },
185
+ "installPath": "animate-core",
186
+ "dependencies": {
187
+ "react": "19.1.0",
188
+ "remotion": "4.0.356"
189
+ }
190
+ }
191
+ }
192
+ }
193
+ ```
194
+
195
+ ## How It Works
196
+
197
+ 1. **Git Sparse Checkout**: The CLI uses git sparse checkout to efficiently fetch only the required directory from the repository
198
+ 2. **Local Installation**: Files are copied to `./core/<library-name>/` in your workspace
199
+ 3. **Dependency Management**: Required dependencies are automatically added to your `package.json`
200
+ 4. **Version Tracking**: The exact git commit hash is stored for reproducibility
201
+
202
+ ## Error Handling
203
+
204
+ All errors are reported to stderr with clear, actionable messages:
205
+
206
+ ```bash
207
+ # Missing token
208
+ Error: WORKSPACE_CLI_TOKEN environment variable is required
209
+
210
+ # Not in workspace
211
+ Error: Not a workspace directory. Could not find package.json.
212
+
213
+ # Library not found
214
+ Error: Library 'invalid-name' not found in registry.
215
+ Available libraries: animate-core
216
+
217
+ # Already installed
218
+ Error: Library 'animate-core' is already installed at version 0.1.3.
219
+ Use --force to reinstall.
220
+ ```
221
+
222
+ ## Development
223
+
224
+ ```bash
225
+ # Install dependencies
226
+ npm install
227
+
228
+ # Build
229
+ npm run build
230
+
231
+ # Type check
232
+ npm run typecheck
233
+
234
+ # Development mode (watch)
235
+ npm run dev
236
+ ```
237
+
238
+ ## Adding New Libraries
239
+
240
+ To add a new library to the registry:
241
+
242
+ 1. Add the library definition to `src/registry/libraries.json`
243
+ 2. Ensure the library source is available in a git repository
244
+ 3. Test installation with `workspace-cli add <library-name>`
245
+
246
+ Example:
247
+ ```json
248
+ {
249
+ "my-library": {
250
+ "name": "@aspects-ai/my-library",
251
+ "description": "Description of the library",
252
+ "version": "1.0.0",
253
+ "repository": {
254
+ "url": "https://github.com/org/repo.git",
255
+ "directory": "path/to/library/src",
256
+ "branch": "main"
257
+ },
258
+ "installPath": "my-library",
259
+ "dependencies": {
260
+ "react": "^18.0.0"
261
+ }
262
+ }
263
+ }
264
+ ```
265
+
266
+ ## License
267
+
268
+ ISC
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,373 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command as Command4 } from "commander";
5
+
6
+ // src/commands/init.ts
7
+ import { Command } from "commander";
8
+
9
+ // src/utils/fs.ts
10
+ import fs from "fs-extra";
11
+ import path from "path";
12
+ import { fileURLToPath } from "url";
13
+ var __filename = fileURLToPath(import.meta.url);
14
+ var __dirname = path.dirname(__filename);
15
+ async function findWorkspaceRoot(startDir = process.cwd()) {
16
+ let currentDir = startDir;
17
+ while (currentDir !== path.parse(currentDir).root) {
18
+ const packageJsonPath = path.join(currentDir, "package.json");
19
+ if (await fs.pathExists(packageJsonPath)) {
20
+ return currentDir;
21
+ }
22
+ currentDir = path.dirname(currentDir);
23
+ }
24
+ return null;
25
+ }
26
+ async function ensureWorkspaceRoot() {
27
+ const workspaceRoot = await findWorkspaceRoot();
28
+ if (!workspaceRoot) {
29
+ throw new Error(
30
+ "Not a workspace directory. Could not find package.json.\nRun this command from within a workspace directory."
31
+ );
32
+ }
33
+ return workspaceRoot;
34
+ }
35
+ function getRegistryPath() {
36
+ const prodPath = path.resolve(__dirname, "registry/libraries.json");
37
+ if (fs.existsSync(prodPath)) {
38
+ return prodPath;
39
+ }
40
+ return path.resolve(__dirname, "../registry/libraries.json");
41
+ }
42
+ async function readJsonFile(filePath) {
43
+ try {
44
+ return await fs.readJson(filePath);
45
+ } catch (error) {
46
+ throw new Error(`Failed to read ${filePath}: ${error}`);
47
+ }
48
+ }
49
+ async function writeJsonFile(filePath, data) {
50
+ try {
51
+ await fs.writeJson(filePath, data, { spaces: 2 });
52
+ } catch (error) {
53
+ throw new Error(`Failed to write ${filePath}: ${error}`);
54
+ }
55
+ }
56
+
57
+ // src/core/config.ts
58
+ import { z } from "zod";
59
+ import path2 from "path";
60
+ import fs2 from "fs-extra";
61
+ var LibraryInstallSchema = z.object({
62
+ version: z.string(),
63
+ installedAt: z.string(),
64
+ commit: z.string()
65
+ });
66
+ var WorkspaceConfigSchema = z.object({
67
+ version: z.string(),
68
+ coreDir: z.string(),
69
+ libraries: z.record(LibraryInstallSchema)
70
+ });
71
+ var CONFIG_FILE_NAME = "workspace.config.json";
72
+ async function loadWorkspaceConfig(workspaceRoot) {
73
+ const configPath = path2.join(workspaceRoot, CONFIG_FILE_NAME);
74
+ if (!await fs2.pathExists(configPath)) {
75
+ return null;
76
+ }
77
+ const data = await readJsonFile(configPath);
78
+ return WorkspaceConfigSchema.parse(data);
79
+ }
80
+ async function saveWorkspaceConfig(workspaceRoot, config) {
81
+ const configPath = path2.join(workspaceRoot, CONFIG_FILE_NAME);
82
+ await writeJsonFile(configPath, config);
83
+ }
84
+ async function createDefaultConfig(workspaceRoot) {
85
+ const config = {
86
+ version: "1.0",
87
+ coreDir: "./core",
88
+ libraries: {}
89
+ };
90
+ await saveWorkspaceConfig(workspaceRoot, config);
91
+ return config;
92
+ }
93
+ async function getOrCreateConfig(workspaceRoot) {
94
+ const existing = await loadWorkspaceConfig(workspaceRoot);
95
+ if (existing) {
96
+ return existing;
97
+ }
98
+ return createDefaultConfig(workspaceRoot);
99
+ }
100
+ async function addLibraryToConfig(workspaceRoot, libraryName, version, commit) {
101
+ const config = await getOrCreateConfig(workspaceRoot);
102
+ config.libraries[libraryName] = {
103
+ version,
104
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
105
+ commit
106
+ };
107
+ await saveWorkspaceConfig(workspaceRoot, config);
108
+ }
109
+ async function isLibraryInstalled(workspaceRoot, libraryName) {
110
+ const config = await loadWorkspaceConfig(workspaceRoot);
111
+ return config ? libraryName in config.libraries : false;
112
+ }
113
+ function getConfigPath(workspaceRoot) {
114
+ return path2.join(workspaceRoot, CONFIG_FILE_NAME);
115
+ }
116
+
117
+ // src/utils/logger.ts
118
+ import chalk from "chalk";
119
+ var logger = {
120
+ info(message) {
121
+ console.log(chalk.blue("[INFO]"), message);
122
+ },
123
+ success(message) {
124
+ console.log(chalk.green("[SUCCESS]"), message);
125
+ },
126
+ error(message) {
127
+ console.error(chalk.red("[ERROR]"), message);
128
+ },
129
+ warn(message) {
130
+ console.warn(chalk.yellow("[WARN]"), message);
131
+ },
132
+ log(message) {
133
+ console.log(message);
134
+ }
135
+ };
136
+
137
+ // src/commands/init.ts
138
+ function createInitCommand() {
139
+ return new Command("init").description("Initialize workspace configuration").action(async () => {
140
+ try {
141
+ const workspaceRoot = await ensureWorkspaceRoot();
142
+ const existing = await loadWorkspaceConfig(workspaceRoot);
143
+ if (existing) {
144
+ logger.warn("workspace.config.json already exists");
145
+ logger.info(`Config file: ${getConfigPath(workspaceRoot)}`);
146
+ return;
147
+ }
148
+ await createDefaultConfig(workspaceRoot);
149
+ logger.success("Created workspace.config.json");
150
+ logger.log("\nNext steps:");
151
+ logger.log(" workspace-cli list # View available libraries");
152
+ logger.log(" workspace-cli add <library> # Install a library");
153
+ } catch (error) {
154
+ logger.error(error.message);
155
+ process.exit(1);
156
+ }
157
+ });
158
+ }
159
+
160
+ // src/commands/list.ts
161
+ import { Command as Command2 } from "commander";
162
+
163
+ // src/core/registry.ts
164
+ import { z as z2 } from "zod";
165
+ var RepositorySchema = z2.object({
166
+ url: z2.string(),
167
+ directory: z2.string(),
168
+ branch: z2.string()
169
+ });
170
+ var LibrarySchema = z2.object({
171
+ name: z2.string(),
172
+ description: z2.string(),
173
+ version: z2.string(),
174
+ repository: RepositorySchema,
175
+ installPath: z2.string(),
176
+ dependencies: z2.record(z2.string())
177
+ });
178
+ var RegistrySchema = z2.object({
179
+ libraries: z2.record(LibrarySchema)
180
+ });
181
+ var cachedRegistry = null;
182
+ async function loadRegistry() {
183
+ if (cachedRegistry) {
184
+ return cachedRegistry;
185
+ }
186
+ const registryPath = getRegistryPath();
187
+ const data = await readJsonFile(registryPath);
188
+ cachedRegistry = RegistrySchema.parse(data);
189
+ return cachedRegistry;
190
+ }
191
+ async function getLibrary(libraryName) {
192
+ const registry = await loadRegistry();
193
+ const library = registry.libraries[libraryName];
194
+ if (!library) {
195
+ throw new Error(
196
+ `Library '${libraryName}' not found in registry.
197
+ Available libraries: ${Object.keys(registry.libraries).join(", ")}`
198
+ );
199
+ }
200
+ return library;
201
+ }
202
+ async function listLibraries() {
203
+ const registry = await loadRegistry();
204
+ return Object.entries(registry.libraries).map(([name, library]) => ({
205
+ name,
206
+ library
207
+ }));
208
+ }
209
+
210
+ // src/commands/list.ts
211
+ import chalk2 from "chalk";
212
+ function createListCommand() {
213
+ return new Command2("list").description("List available libraries").action(async () => {
214
+ try {
215
+ const libraries = await listLibraries();
216
+ logger.log(chalk2.bold("\nAvailable libraries:\n"));
217
+ for (const { name, library } of libraries) {
218
+ logger.log(chalk2.cyan(` ${name}`) + chalk2.gray(` @${library.version}`));
219
+ logger.log(` ${library.description}`);
220
+ logger.log("");
221
+ }
222
+ logger.log(`Total: ${libraries.length} ${libraries.length === 1 ? "library" : "libraries"}
223
+ `);
224
+ } catch (error) {
225
+ logger.error(error.message);
226
+ process.exit(1);
227
+ }
228
+ });
229
+ }
230
+
231
+ // src/commands/add.ts
232
+ import { Command as Command3 } from "commander";
233
+
234
+ // src/core/installer.ts
235
+ import path4 from "path";
236
+ import fs4 from "fs-extra";
237
+
238
+ // src/core/git-fetcher.ts
239
+ import { execa } from "execa";
240
+ import fs3 from "fs-extra";
241
+ import path3 from "path";
242
+ import os from "os";
243
+ async function fetchDirectory(options) {
244
+ const tempDir = await fs3.mkdtemp(path3.join(os.tmpdir(), "workspace-cli-"));
245
+ try {
246
+ const repoUrl = options.repository.replace(
247
+ "https://github.com/",
248
+ `https://${options.token}@github.com/`
249
+ );
250
+ await execa("git", ["init"], { cwd: tempDir });
251
+ await execa("git", ["remote", "add", "origin", repoUrl], { cwd: tempDir });
252
+ await execa("git", ["config", "core.sparseCheckout", "true"], { cwd: tempDir });
253
+ const sparseFile = path3.join(tempDir, ".git", "info", "sparse-checkout");
254
+ await fs3.writeFile(sparseFile, `${options.directory}/*
255
+ `);
256
+ await execa("git", ["pull", "origin", options.branch, "--depth=1"], {
257
+ cwd: tempDir,
258
+ stderr: "pipe"
259
+ });
260
+ const { stdout: commit } = await execa("git", ["rev-parse", "HEAD"], { cwd: tempDir });
261
+ const sourceDir = path3.join(tempDir, options.directory);
262
+ if (!await fs3.pathExists(sourceDir)) {
263
+ throw new Error(`Directory '${options.directory}' not found in repository`);
264
+ }
265
+ await fs3.ensureDir(options.targetPath);
266
+ await fs3.copy(sourceDir, options.targetPath, {
267
+ overwrite: true,
268
+ errorOnExist: false
269
+ });
270
+ return commit.trim();
271
+ } catch (error) {
272
+ if (error.stderr && error.stderr.includes("Authentication failed")) {
273
+ throw new Error(
274
+ "Git authentication failed. Please check your WORKSPACE_CLI_TOKEN.\nThe token must have access to the repository."
275
+ );
276
+ }
277
+ throw new Error(`Failed to fetch library from git: ${error.message}`);
278
+ } finally {
279
+ await fs3.remove(tempDir);
280
+ }
281
+ }
282
+ function getToken() {
283
+ const token = process.env.WORKSPACE_CLI_TOKEN;
284
+ if (!token) {
285
+ throw new Error(
286
+ "WORKSPACE_CLI_TOKEN environment variable is required.\nPlease set it with your GitHub personal access token:\n export WORKSPACE_CLI_TOKEN=ghp_xxxxxxxxxxxx\n\nThe token needs read access to the repository."
287
+ );
288
+ }
289
+ return token;
290
+ }
291
+
292
+ // src/core/installer.ts
293
+ async function installLibrary(workspaceRoot, libraryName, options = {}) {
294
+ if (!options.force && await isLibraryInstalled(workspaceRoot, libraryName)) {
295
+ const config2 = await loadWorkspaceConfig(workspaceRoot);
296
+ const existingVersion = config2?.libraries[libraryName]?.version;
297
+ throw new Error(
298
+ `Library '${libraryName}' is already installed at version ${existingVersion}.
299
+ Use --force to reinstall.`
300
+ );
301
+ }
302
+ logger.info(`Fetching ${libraryName} metadata...`);
303
+ const library = await getLibrary(libraryName);
304
+ const token = getToken();
305
+ const config = await loadWorkspaceConfig(workspaceRoot);
306
+ const coreDir = config?.coreDir || "./core";
307
+ const targetPath = path4.join(workspaceRoot, coreDir, library.installPath);
308
+ logger.info(`Fetching ${libraryName}@${library.version} from git...`);
309
+ const commit = await fetchDirectory({
310
+ repository: library.repository.url,
311
+ directory: library.repository.directory,
312
+ branch: library.repository.branch,
313
+ token,
314
+ targetPath
315
+ });
316
+ logger.info(`Installed to ${path4.relative(workspaceRoot, targetPath)}`);
317
+ logger.info(`Updating workspace.config.json...`);
318
+ await addLibraryToConfig(workspaceRoot, libraryName, library.version, commit);
319
+ await updatePackageDependencies(workspaceRoot, library.dependencies);
320
+ logger.success(
321
+ `Installed ${libraryName}@${library.version} (commit: ${commit.substring(0, 7)})`
322
+ );
323
+ }
324
+ async function updatePackageDependencies(workspaceRoot, dependencies) {
325
+ const packageJsonPath = path4.join(workspaceRoot, "package.json");
326
+ if (!await fs4.pathExists(packageJsonPath)) {
327
+ logger.warn("No package.json found, skipping dependency updates");
328
+ return;
329
+ }
330
+ logger.info("Adding dependencies to package.json...");
331
+ const packageJson = await fs4.readJson(packageJsonPath);
332
+ packageJson.dependencies = packageJson.dependencies || {};
333
+ let addedCount = 0;
334
+ for (const [dep, version] of Object.entries(dependencies)) {
335
+ if (!packageJson.dependencies[dep]) {
336
+ packageJson.dependencies[dep] = version;
337
+ addedCount++;
338
+ }
339
+ }
340
+ if (addedCount > 0) {
341
+ await fs4.writeJson(packageJsonPath, packageJson, { spaces: 2 });
342
+ logger.info(`Added ${addedCount} ${addedCount === 1 ? "dependency" : "dependencies"}`);
343
+ } else {
344
+ logger.info("All dependencies already present");
345
+ }
346
+ }
347
+
348
+ // src/commands/add.ts
349
+ import chalk3 from "chalk";
350
+ function createAddCommand() {
351
+ return new Command3("add").description("Add a library to the workspace").argument("<library>", "Name of the library to add").option("-f, --force", "Force reinstall if already installed").action(async (libraryName, options) => {
352
+ try {
353
+ const workspaceRoot = await ensureWorkspaceRoot();
354
+ await getOrCreateConfig(workspaceRoot);
355
+ await installLibrary(workspaceRoot, libraryName, { force: options.force });
356
+ logger.log("\n" + chalk3.bold("Next steps:"));
357
+ logger.log(` ${chalk3.gray("Import components:")} import { ... } from '@/core/${libraryName.replace("animate-", "")}'`);
358
+ logger.log(` ${chalk3.gray("Install dependencies:")} npm install`);
359
+ logger.log("");
360
+ } catch (error) {
361
+ logger.error(error.message);
362
+ process.exit(1);
363
+ }
364
+ });
365
+ }
366
+
367
+ // src/index.ts
368
+ var program = new Command4();
369
+ program.name("workspace-cli").description("Lightweight CLI for installing libraries into workspaces").version("0.1.0");
370
+ program.addCommand(createInitCommand());
371
+ program.addCommand(createListCommand());
372
+ program.addCommand(createAddCommand());
373
+ program.parse(process.argv);
@@ -0,0 +1,31 @@
1
+ {
2
+ "libraries": {
3
+ "animate-core": {
4
+ "name": "@aspects-ai/noodle-animate-core",
5
+ "description": "Core animation components for Noodle videos",
6
+ "version": "0.1.3",
7
+ "repository": {
8
+ "url": "https://github.com/aspects-ai/noodle-templates.git",
9
+ "directory": "noodle-animate-core/src",
10
+ "branch": "main"
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
+ }
29
+ }
30
+ }
31
+ }
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@aspects-ai/workspace-cli",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "Lightweight CLI for installing libraries into workspaces",
6
+ "type": "module",
7
+ "bin": {
8
+ "workspace-cli": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsup src/index.ts --format esm --dts --clean && npm run copy:registry",
12
+ "copy:registry": "mkdir -p dist/registry && cp src/registry/libraries.json dist/registry/",
13
+ "dev": "tsup src/index.ts --format esm --watch",
14
+ "typecheck": "tsc --noEmit"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "src/registry"
19
+ ],
20
+ "dependencies": {
21
+ "commander": "^12.0.0",
22
+ "chalk": "^5.3.0",
23
+ "execa": "^8.0.0",
24
+ "fs-extra": "^11.2.0",
25
+ "zod": "^3.22.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^20",
29
+ "@types/fs-extra": "^11.0.0",
30
+ "tsup": "^8.0.0",
31
+ "typescript": "^5"
32
+ },
33
+ "engines": {
34
+ "node": ">=18.0.0"
35
+ }
36
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "libraries": {
3
+ "animate-core": {
4
+ "name": "@aspects-ai/noodle-animate-core",
5
+ "description": "Core animation components for Noodle videos",
6
+ "version": "0.1.3",
7
+ "repository": {
8
+ "url": "https://github.com/aspects-ai/noodle-templates.git",
9
+ "directory": "noodle-animate-core/src",
10
+ "branch": "main"
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
+ }
29
+ }
30
+ }
31
+ }