@openscaffold/cli 0.1.3 → 0.1.5

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 CHANGED
@@ -4,7 +4,7 @@ import { execFileSync, spawn } from "node:child_process";
4
4
  import { chmodSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, readlinkSync, rmSync, statSync, writeFileSync } from "node:fs";
5
5
  import { homedir, hostname } from "node:os";
6
6
  import { dirname, join, resolve } from "node:path";
7
- import { briefingFacts, briefingStatus, browserCommand, collectDiff, gitInfo, hasOpenScaffoldPlugin, hookBase, HOSTED, installedHooks, loadedEntry, loginResultLine, MCP_NAME, mcpText, nameFromDomain, callerSession, commandLine, rememberedCache, DEFAULT_REVIEW_TITLE, parseReviewArgs, parseSetupArgs, planSummary, pluginServes, preCommitOutput, REVIEW_HELP, REVIEW_WAIT, reviewTitle, selectFiles, SETUP_EXTENSIONS, setupPrompt, setupResultLine, skillFile, statusReport, stopOutput, switchAllowed, switchedTo, transcriptActivity, whichCustomerError, windowsCommandLine, withHooks, withoutHooks, } from "./install.js";
7
+ import { briefingFacts, briefingStatus, browserCommand, collectDiff, gitInfo, hasOpenScaffoldPlugin, hookBase, HOSTED, installedHooks, loadedEntry, loginResultLine, MCP_NAME, mcpText, nameFromDomain, callerSession, commandLine, gitTracks, rememberedCache, DEFAULT_REVIEW_TITLE, parseReviewArgs, parseSetupArgs, planSummary, pluginServes, preCommitOutput, REVIEW_HELP, REVIEW_WAIT, reviewTitle, selectFiles, SETUP_EXTENSIONS, setupPrompt, setupResultLine, skillFile, statusReport, stopOutput, switchAllowed, switchedTo, transcriptActivity, whichCustomerError, windowsCommandLine, withHooks, withoutHooks, } from "./install.js";
8
8
  const CONFIG = join(homedir(), ".config", "openscaffold");
9
9
  const CREDENTIALS = join(CONFIG, "credentials.json");
10
10
  const CACHE = join(CONFIG, "cache");
@@ -443,7 +443,7 @@ async function useDeployment() {
443
443
  * get_review (which holds up to 50 s per call) and prints the verdict. Nothing to paste, nothing to poll.
444
444
  */
445
445
  async function review() {
446
- const args = parseReviewArgs(process.argv.slice(3), existsSync);
446
+ const args = parseReviewArgs(process.argv.slice(3), (p) => existsSync(p) || gitTracks(p, (a) => execFileSync("git", a, { stdio: "ignore" })));
447
447
  if ("help" in args)
448
448
  return console.log(REVIEW_HELP);
449
449
  if ("error" in args)
package/dist/install.js CHANGED
@@ -446,7 +446,7 @@ export function parseReviewArgs(args, exists = () => true) {
446
446
  return { error: `Unknown option ${flag}. ${REVIEW_USAGE}` };
447
447
  else if (/^req_\w+$/.test(args[i]) && !exists(args[i]))
448
448
  out.reqs.push(args[i]); // `--req req_1 req_2`
449
- // ponytail: a deleted file named alone reads as the title; then the whole change is reviewed, which still includes it.
449
+ // `exists` also knows paths git tracks (a deleted file), so a listed deletion is a file, not the title.
450
450
  else if (!out.title && !exists(args[i]))
451
451
  out.title = args[i];
452
452
  else
@@ -454,8 +454,28 @@ export function parseReviewArgs(args, exists = () => true) {
454
454
  }
455
455
  return { ...out, title: out.title.trim() || DEFAULT_REVIEW_TITLE, reqs: [...new Set(out.reqs)] };
456
456
  }
457
- /** A CLI command line to copy and run: `npx -y @openscaffold/cli@latest <args>`, quoting what a shell would split. */
458
- export const commandLine = (args) => ["npx -y @openscaffold/cli@latest", ...args.map((a) => (/^[\w./:@=,-]+$/.test(a) ? a : JSON.stringify(a)))].join(" ");
457
+ /**
458
+ * A CLI command line to copy and run: `npx -y @openscaffold/cli@latest <args>`, each argument single-quoted when a shell
459
+ * would split or expand it ($, backticks, spaces), so the copy keeps the exact text: PowerShell's form on Windows.
460
+ */
461
+ export const commandLine = (args, platform = process.platform) => ["npx -y @openscaffold/cli@latest", ...args.map((a) => /^[\w./:@=,-]+$/.test(a) ? a
462
+ // PowerShell: single quotes are literal and a quote is doubled; elsewhere POSIX's '\'' escape.
463
+ : platform === "win32" ? `'${a.replace(/'/g, "''")}'` : `'${a.replace(/'/g, `'\\''`)}'`)].join(" ");
464
+ /**
465
+ * Whether git tracks a path given relative to the current folder: in the index, or in HEAD (a staged deletion).
466
+ * `HEAD:./p` resolves against the current folder, not the repository root. `git` runs git and throws on failure.
467
+ */
468
+ export function gitTracks(path, git) {
469
+ return [["ls-files", "--error-unmatch", "--", path], ["cat-file", "-e", `HEAD:./${path.replace(/^\.\//, "")}`]].some((a) => {
470
+ try {
471
+ git(a);
472
+ return true;
473
+ }
474
+ catch {
475
+ return false;
476
+ }
477
+ });
478
+ }
459
479
  /** `review` with no --deployment and none cached for this session or folder: the same command with each cached customer's id. */
460
480
  export function whichCustomerError(args, known) {
461
481
  const head = "Which customer? This session has no OpenScaffold deployment cached here.";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openscaffold/cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Connect Claude Code to your OpenScaffold workspace: each session loads the right customer deployment.",
5
5
  "type": "module",
6
6
  "bin": {