@revturbine/cli 0.9.1 → 0.10.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 +1 -0
- package/dist/cli.js +55 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -63,6 +63,7 @@ Commands that read a config name the version explicitly — there is no default:
|
|
|
63
63
|
|
|
64
64
|
| Command | What it does |
|
|
65
65
|
|---|---|
|
|
66
|
+
| `init` (alias `create`) | Scaffold RevTurbine into this app: detect the package manager and stack, install the SDK, pin the CLI exactly, drop a starter Playbook, and install the Agent Skills. In a directory with no `package.json` it offers to start a new project (`--yes` to skip the prompt); `--dir`, `--dry-run`, `--no-skills`, `--json`. Runs the invoked CLI even inside a repo that pins a different one — setup establishes the pin, so it never delegates. |
|
|
66
67
|
| `signup` | Create an account headlessly: email + password, then an emailed one-time code to verify, then a token is stored. |
|
|
67
68
|
| `login` / `logout` | Device-flow auth; tokens stored at `~/.revturbine/credentials.json` (mode 0600). |
|
|
68
69
|
| `whoami` | The resolved instance, tenant, credentials source, and whether the stored token works. |
|
package/dist/cli.js
CHANGED
|
@@ -6566,10 +6566,21 @@ async function resolveActiveDraft(baseUrl, headers, fetchImpl = fetch) {
|
|
|
6566
6566
|
// src/lib/delegate.ts
|
|
6567
6567
|
var DELEGATION_ENV = "REVTURBINE_DELEGATED";
|
|
6568
6568
|
var NO_LOCAL_FLAG = "--no-local";
|
|
6569
|
+
var SETUP_COMMANDS = ["init", "create"];
|
|
6570
|
+
function commandFromArgv(argv) {
|
|
6571
|
+
for (const arg of argv.slice(2)) {
|
|
6572
|
+
if (!arg.startsWith("-")) return arg;
|
|
6573
|
+
}
|
|
6574
|
+
return null;
|
|
6575
|
+
}
|
|
6569
6576
|
function planDelegation(params) {
|
|
6570
6577
|
if (params.env[DELEGATION_ENV]) {
|
|
6571
6578
|
return { delegate: false, reason: "already delegated" };
|
|
6572
6579
|
}
|
|
6580
|
+
const command = commandFromArgv(params.argv);
|
|
6581
|
+
if (command && SETUP_COMMANDS.includes(command)) {
|
|
6582
|
+
return { delegate: false, reason: `${command} establishes the repo pin \u2014 never delegated` };
|
|
6583
|
+
}
|
|
6573
6584
|
if (params.argv.includes(NO_LOCAL_FLAG)) {
|
|
6574
6585
|
return { delegate: false, reason: `${NO_LOCAL_FLAG} requested` };
|
|
6575
6586
|
}
|
|
@@ -6639,6 +6650,13 @@ function detectStack(signals) {
|
|
|
6639
6650
|
}
|
|
6640
6651
|
var SDK_PACKAGE = "@revturbine/sdk";
|
|
6641
6652
|
var CLI_PACKAGE = "@revturbine/cli";
|
|
6653
|
+
function projectNameFromDir(dirName) {
|
|
6654
|
+
const slug = dirName.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[-_.]+|[-_.]+$/g, "");
|
|
6655
|
+
return slug || "my-app";
|
|
6656
|
+
}
|
|
6657
|
+
function newProjectManifest(dirName) {
|
|
6658
|
+
return { name: projectNameFromDir(dirName), version: "0.1.0", private: true, type: "module" };
|
|
6659
|
+
}
|
|
6642
6660
|
function planInstall(params) {
|
|
6643
6661
|
const deps = params.dependencies ?? {};
|
|
6644
6662
|
const devDeps = params.devDependencies ?? {};
|
|
@@ -7060,6 +7078,22 @@ async function confirmOrExit(promptText, yes) {
|
|
|
7060
7078
|
process.exit(0);
|
|
7061
7079
|
}
|
|
7062
7080
|
}
|
|
7081
|
+
async function confirmNewProject(dir, yes) {
|
|
7082
|
+
if (yes) return;
|
|
7083
|
+
if (!process.stdin.isTTY) {
|
|
7084
|
+
fail(
|
|
7085
|
+
EXIT.USAGE,
|
|
7086
|
+
`No package.json in ${dir}. Re-run with --yes to start a new project here, or --dir <path> to target an existing one.`
|
|
7087
|
+
);
|
|
7088
|
+
}
|
|
7089
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
7090
|
+
const answer = (await rl.question(`No package.json in ${dir}. Start a new project here? [Y/n] `)).trim().toLowerCase();
|
|
7091
|
+
rl.close();
|
|
7092
|
+
if (answer === "n" || answer === "no") {
|
|
7093
|
+
diag("Aborted \u2014 no project created.");
|
|
7094
|
+
process.exit(0);
|
|
7095
|
+
}
|
|
7096
|
+
}
|
|
7063
7097
|
function table(rows) {
|
|
7064
7098
|
if (rows.length === 0) return " (none)";
|
|
7065
7099
|
const widths = rows[0].map((_, col) => Math.max(...rows.map((r) => (r[col] ?? "").length)));
|
|
@@ -7185,20 +7219,30 @@ function runInstall(manager, args, cwd) {
|
|
|
7185
7219
|
child.on("close", (code) => resolve(code ?? 1));
|
|
7186
7220
|
});
|
|
7187
7221
|
}
|
|
7188
|
-
program.command("init").alias("create").description("Scaffold RevTurbine into this app: detect the stack, install the SDK, pin the CLI, drop a starter Playbook, and install the Agent Skills.").option("-d, --dir <path>", "Target directory (defaults to the current directory)").option("--dry-run", "Report what would be installed without running the package manager").option("--no-skills", "Do not install the RevTurbine Agent Skills").option("--json", "Emit the scaffold plan as JSON").action(async (opts) => {
|
|
7222
|
+
program.command("init").alias("create").description("Scaffold RevTurbine into this app: detect the stack, install the SDK, pin the CLI, drop a starter Playbook, and install the Agent Skills. Offers to start a new project when the directory has no package.json.").option("-d, --dir <path>", "Target directory (defaults to the current directory)").option("-y, --yes", "Skip prompts \u2014 create a new project non-interactively when the directory has none").option("--dry-run", "Report what would be installed without running the package manager").option("--no-skills", "Do not install the RevTurbine Agent Skills").option("--json", "Emit the scaffold plan as JSON").action(async (opts) => {
|
|
7189
7223
|
const dir = path2.resolve(opts.dir ?? process.cwd());
|
|
7190
7224
|
const manifestPath = path2.join(dir, "package.json");
|
|
7191
|
-
if (!existsSync2(manifestPath)) {
|
|
7192
|
-
fail(EXIT.USAGE, `No package.json in ${dir} \u2014 run init inside a JavaScript project (or pass --dir).`);
|
|
7193
|
-
}
|
|
7194
7225
|
let manifest;
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7226
|
+
let createdProject = false;
|
|
7227
|
+
if (existsSync2(manifestPath)) {
|
|
7228
|
+
try {
|
|
7229
|
+
manifest = JSON.parse(readFileSync2(manifestPath, "utf8"));
|
|
7230
|
+
} catch (err) {
|
|
7231
|
+
fail(EXIT.VALIDATION, `invalid JSON in ${manifestPath}: ${err.message}`);
|
|
7232
|
+
}
|
|
7233
|
+
} else {
|
|
7234
|
+
manifest = newProjectManifest(path2.basename(dir));
|
|
7235
|
+
createdProject = true;
|
|
7236
|
+
if (!opts.dryRun) {
|
|
7237
|
+
await confirmNewProject(dir, opts.yes === true);
|
|
7238
|
+
mkdirSync2(dir, { recursive: true });
|
|
7239
|
+
writeFileSync2(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
7240
|
+
`, "utf8");
|
|
7241
|
+
diag(`\u2713 Created a new project (package.json \u2014 ${manifest.name})`);
|
|
7242
|
+
}
|
|
7199
7243
|
}
|
|
7200
7244
|
const manager = detectPackageManager({
|
|
7201
|
-
files: readdirSync(dir),
|
|
7245
|
+
files: existsSync2(dir) ? readdirSync(dir) : [],
|
|
7202
7246
|
packageManagerField: manifest.packageManager,
|
|
7203
7247
|
userAgent: process.env["npm_config_user_agent"]
|
|
7204
7248
|
});
|
|
@@ -7219,6 +7263,7 @@ program.command("init").alias("create").description("Scaffold RevTurbine into th
|
|
|
7219
7263
|
emit(
|
|
7220
7264
|
{
|
|
7221
7265
|
dir,
|
|
7266
|
+
project: createdProject ? "created" : "existing",
|
|
7222
7267
|
manager: manager.name,
|
|
7223
7268
|
stack,
|
|
7224
7269
|
install: plan.install,
|
|
@@ -7230,6 +7275,7 @@ program.command("init").alias("create").description("Scaffold RevTurbine into th
|
|
|
7230
7275
|
);
|
|
7231
7276
|
}
|
|
7232
7277
|
if (opts.dryRun) {
|
|
7278
|
+
if (createdProject) diag(`would create: package.json (new project \u2014 ${manifest.name})`);
|
|
7233
7279
|
for (const step of plan.install) {
|
|
7234
7280
|
diag(`would run: ${manager.name} ${installArgs(manager.name, step).join(" ")}`);
|
|
7235
7281
|
}
|
package/package.json
CHANGED