@aspects-ai/workspace-cli 0.1.6 → 0.1.8
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/dist/index.js +67 -26
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -436,6 +436,9 @@ import chalk5 from "chalk";
|
|
|
436
436
|
import { Command as Command5 } from "commander";
|
|
437
437
|
import fs5 from "fs-extra";
|
|
438
438
|
import path5 from "path";
|
|
439
|
+
function generateId() {
|
|
440
|
+
return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString();
|
|
441
|
+
}
|
|
439
442
|
function parseManifestOption(manifestStr) {
|
|
440
443
|
try {
|
|
441
444
|
return JSON.parse(manifestStr);
|
|
@@ -446,7 +449,8 @@ function parseManifestOption(manifestStr) {
|
|
|
446
449
|
function validateAndFixManifest(manifest, toolName, frameName) {
|
|
447
450
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
448
451
|
const validatedManifest = {
|
|
449
|
-
id:
|
|
452
|
+
id: frameName,
|
|
453
|
+
// Always match the directory name
|
|
450
454
|
projectId: manifest.projectId || "default-project",
|
|
451
455
|
title: manifest.title || frameName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" "),
|
|
452
456
|
description: manifest.description || `Frame for ${toolName}`,
|
|
@@ -459,17 +463,20 @@ function validateAndFixManifest(manifest, toolName, frameName) {
|
|
|
459
463
|
}
|
|
460
464
|
return validatedManifest;
|
|
461
465
|
}
|
|
462
|
-
async function getNextFrameName(framesDir,
|
|
463
|
-
|
|
464
|
-
|
|
466
|
+
async function getNextFrameName(framesDir, customName) {
|
|
467
|
+
let frameName;
|
|
468
|
+
if (customName) {
|
|
469
|
+
const truncatedName = customName.slice(0, 20);
|
|
470
|
+
const uniqueId = generateId();
|
|
471
|
+
frameName = `${truncatedName}-${uniqueId}`;
|
|
472
|
+
} else {
|
|
473
|
+
frameName = generateId();
|
|
465
474
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
counter++;
|
|
470
|
-
nextName = `${baseName}-${counter}`;
|
|
475
|
+
while (await fs5.pathExists(path5.join(framesDir, frameName))) {
|
|
476
|
+
const uniqueId = generateId();
|
|
477
|
+
frameName = customName ? `${customName.slice(0, 20)}-${uniqueId}` : uniqueId;
|
|
471
478
|
}
|
|
472
|
-
return
|
|
479
|
+
return frameName;
|
|
473
480
|
}
|
|
474
481
|
async function fetchExampleFrame(toolName, targetPath) {
|
|
475
482
|
const library = await getLibrary(toolName);
|
|
@@ -490,8 +497,8 @@ function createCreateFrameCommand() {
|
|
|
490
497
|
const workspaceRoot = await ensureWorkspaceRoot();
|
|
491
498
|
const framesDir = path5.join(workspaceRoot, "frames");
|
|
492
499
|
await fs5.ensureDir(framesDir);
|
|
493
|
-
const
|
|
494
|
-
const frameName = await getNextFrameName(framesDir,
|
|
500
|
+
const customName = options.name && options.name !== "new-frame" ? options.name : void 0;
|
|
501
|
+
const frameName = await getNextFrameName(framesDir, customName);
|
|
495
502
|
const frameDir = path5.join(framesDir, frameName);
|
|
496
503
|
logger.info(`Creating frame: ${chalk5.cyan(frameName)} for ${chalk5.cyan(toolName)}`);
|
|
497
504
|
await fetchExampleFrame(toolName, frameDir);
|
|
@@ -518,29 +525,30 @@ function createCreateFrameCommand() {
|
|
|
518
525
|
import { Command as Command6 } from "commander";
|
|
519
526
|
import path6 from "path";
|
|
520
527
|
import fs6 from "fs-extra";
|
|
528
|
+
import { execa as execa2 } from "execa";
|
|
529
|
+
import os2 from "os";
|
|
521
530
|
import chalk6 from "chalk";
|
|
522
|
-
|
|
523
|
-
var
|
|
524
|
-
var
|
|
531
|
+
var NOODLE_BASE_REPO = "https://github.com/aspects-ai/noodle-templates";
|
|
532
|
+
var NOODLE_BASE_BRANCH = "main";
|
|
533
|
+
var EDITING_FILE_PATH = "noodle-base/EDITING.md";
|
|
525
534
|
function createUpdateTemplateCommand() {
|
|
526
535
|
return new Command6("update-template").description("Update EDITING.md file from noodle-base template").action(async () => {
|
|
527
536
|
try {
|
|
528
537
|
const workspaceRoot = await ensureWorkspaceRoot();
|
|
529
|
-
const noodleBasePath = path6.resolve(__dirname2, "../../../noodle-base");
|
|
530
|
-
const sourceFile = path6.join(noodleBasePath, "EDITING.md");
|
|
531
538
|
const targetFile = path6.join(workspaceRoot, "EDITING.md");
|
|
532
|
-
|
|
533
|
-
throw new Error(
|
|
534
|
-
`Template file not found at: ${sourceFile}
|
|
535
|
-
Make sure noodle-base is available in the monorepo.`
|
|
536
|
-
);
|
|
537
|
-
}
|
|
539
|
+
const token = getToken();
|
|
538
540
|
const targetExists = await fs6.pathExists(targetFile);
|
|
539
541
|
if (targetExists) {
|
|
540
542
|
logger.info("Existing EDITING.md found, it will be overwritten.");
|
|
541
543
|
}
|
|
542
|
-
logger.info(
|
|
543
|
-
await
|
|
544
|
+
logger.info("Fetching EDITING.md from noodle-base...");
|
|
545
|
+
const content = await fetchFileFromGit({
|
|
546
|
+
repository: NOODLE_BASE_REPO,
|
|
547
|
+
filePath: EDITING_FILE_PATH,
|
|
548
|
+
branch: NOODLE_BASE_BRANCH,
|
|
549
|
+
token
|
|
550
|
+
});
|
|
551
|
+
await fs6.writeFile(targetFile, content, "utf-8");
|
|
544
552
|
logger.success(
|
|
545
553
|
`Successfully ${targetExists ? "updated" : "copied"} EDITING.md to workspace`
|
|
546
554
|
);
|
|
@@ -553,11 +561,44 @@ Make sure noodle-base is available in the monorepo.`
|
|
|
553
561
|
}
|
|
554
562
|
});
|
|
555
563
|
}
|
|
564
|
+
async function fetchFileFromGit(options) {
|
|
565
|
+
const tempDir = await fs6.mkdtemp(path6.join(os2.tmpdir(), "workspace-cli-"));
|
|
566
|
+
try {
|
|
567
|
+
const repoUrl = options.repository.replace(
|
|
568
|
+
"https://github.com/",
|
|
569
|
+
`https://${options.token}@github.com/`
|
|
570
|
+
);
|
|
571
|
+
await execa2("git", ["init"], { cwd: tempDir });
|
|
572
|
+
await execa2("git", ["remote", "add", "origin", repoUrl], { cwd: tempDir });
|
|
573
|
+
await execa2("git", ["config", "core.sparseCheckout", "true"], { cwd: tempDir });
|
|
574
|
+
const sparseFile = path6.join(tempDir, ".git", "info", "sparse-checkout");
|
|
575
|
+
await fs6.writeFile(sparseFile, `${options.filePath}
|
|
576
|
+
`);
|
|
577
|
+
await execa2("git", ["pull", "origin", options.branch, "--depth=1"], {
|
|
578
|
+
cwd: tempDir,
|
|
579
|
+
stderr: "pipe"
|
|
580
|
+
});
|
|
581
|
+
const sourceFile = path6.join(tempDir, options.filePath);
|
|
582
|
+
if (!await fs6.pathExists(sourceFile)) {
|
|
583
|
+
throw new Error(`File '${options.filePath}' not found in repository`);
|
|
584
|
+
}
|
|
585
|
+
return await fs6.readFile(sourceFile, "utf-8");
|
|
586
|
+
} catch (error) {
|
|
587
|
+
if (error.stderr && error.stderr.includes("Authentication failed")) {
|
|
588
|
+
throw new Error(
|
|
589
|
+
"Git authentication failed. Please check your WORKSPACE_CLI_TOKEN.\nThe token must have access to the repository."
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
throw new Error(`Failed to fetch file from git: ${error.message}`);
|
|
593
|
+
} finally {
|
|
594
|
+
await fs6.remove(tempDir);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
556
597
|
|
|
557
598
|
// package.json
|
|
558
599
|
var package_default = {
|
|
559
600
|
name: "@aspects-ai/workspace-cli",
|
|
560
|
-
version: "0.1.
|
|
601
|
+
version: "0.1.7",
|
|
561
602
|
private: false,
|
|
562
603
|
description: "Lightweight CLI for installing libraries into workspaces",
|
|
563
604
|
type: "module",
|