@delfini/cli 0.1.2 → 0.2.1

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/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  main
3
- } from "./chunk-IDYMVTTU.js";
4
- import "./chunk-MUW24ZC4.js";
3
+ } from "./chunk-K5X5TSUR.js";
4
+ import "./chunk-LJKEHO6F.js";
5
5
  export {
6
6
  main
7
7
  };
package/dist/index.cjs CHANGED
@@ -33,10 +33,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
  ));
34
34
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
35
 
36
- // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.9_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js
36
+ // ../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.15_tsx@4.22.4_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js
37
37
  var getImportMetaUrl, importMetaUrl;
38
38
  var init_cjs_shims = __esm({
39
- "../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.9_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js"() {
39
+ "../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.15_tsx@4.22.4_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js"() {
40
40
  "use strict";
41
41
  getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
42
42
  importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
@@ -7402,9 +7402,74 @@ async function runInstall(targetPath, options) {
7402
7402
  const resolvedTarget = (0, import_node_path3.resolve)(process.cwd(), targetPath);
7403
7403
  const repoRoot = await getRepoRoot(resolvedTarget);
7404
7404
  writeSkillTemplate(repoRoot, logger);
7405
+ await applyDocScope(repoRoot, logger, options?.provideDocScope);
7405
7406
  await applyAutoInvokeDecision(repoRoot, logger, options?.confirmAutoInvoke);
7406
7407
  appendGitignoreLine(repoRoot, logger);
7407
7408
  }
7409
+ function parseScopeInput(answer) {
7410
+ return answer.split(/[\s,]+/u).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
7411
+ }
7412
+ function sanitiseScope(paths) {
7413
+ return paths.map((entry) => entry.trim()).filter((entry) => entry.length > 0);
7414
+ }
7415
+ async function applyDocScope(repoRoot, logger, provideDocScope) {
7416
+ const target = (0, import_node_path3.join)(repoRoot, DOC_SCOPE_RELATIVE_PATH);
7417
+ if (provideDocScope) {
7418
+ const paths2 = sanitiseScope(await provideDocScope());
7419
+ if (paths2.length === 0) {
7420
+ log(logger, `doc-scope.json \u2192 ${target} (no paths provided, no change)`);
7421
+ return;
7422
+ }
7423
+ await persistDocScope(repoRoot, logger, target, paths2);
7424
+ return;
7425
+ }
7426
+ if (await docScopeExists(repoRoot)) {
7427
+ log(logger, `doc-scope.json \u2192 ${target} (already configured, no change)`);
7428
+ return;
7429
+ }
7430
+ if (!process.stdin.isTTY) {
7431
+ log(
7432
+ logger,
7433
+ `doc-scope.json \u2192 ${target} (non-interactive shell: scope prompt skipped, no change)`
7434
+ );
7435
+ return;
7436
+ }
7437
+ const paths = await promptDocScope();
7438
+ if (paths.length === 0) {
7439
+ log(
7440
+ logger,
7441
+ `doc-scope.json \u2192 ${target} (no paths provided, no change \u2014 first /delfini run will prompt)`
7442
+ );
7443
+ return;
7444
+ }
7445
+ await persistDocScope(repoRoot, logger, target, paths);
7446
+ }
7447
+ async function promptDocScope() {
7448
+ const rl = (0, import_promises.createInterface)({ input: process.stdin, output: process.stdout });
7449
+ try {
7450
+ const answer = await rl.question(
7451
+ "Which docs should Delfini track? Enter one or more paths \u2014 directories (recursive .md scan), files, or globs, space- or comma-separated (e.g. `docs/ specs/architecture.md packages/*/README.md`). Leave blank to skip: "
7452
+ );
7453
+ return parseScopeInput(answer);
7454
+ } finally {
7455
+ rl.close();
7456
+ }
7457
+ }
7458
+ async function persistDocScope(repoRoot, logger, target, paths) {
7459
+ try {
7460
+ await writeDocScope(paths, { repoRoot });
7461
+ log(logger, `doc-scope.json \u2192 ${target} (wrote ${paths.length} path(s))`);
7462
+ } catch (err) {
7463
+ if (err instanceof DocScopeValidationError) {
7464
+ log(
7465
+ logger,
7466
+ `doc-scope.json \u2192 ${target} (skipped \u2014 ${err.message}). Fix the path(s) and re-run \`delfini install\`, edit the file directly, or set the scope on the first /delfini run.`
7467
+ );
7468
+ return;
7469
+ }
7470
+ throw err;
7471
+ }
7472
+ }
7408
7473
  function parseYesNo(answer) {
7409
7474
  const normalised = answer.trim().toLowerCase();
7410
7475
  return normalised === "y" || normalised === "yes";
@@ -8110,10 +8175,16 @@ async function main(argv) {
8110
8175
  });
8111
8176
  program.command("install <path>").description(
8112
8177
  "Scaffold .claude/skills/delfini/SKILL.md + CLAUDE.md auto-invoke + .gitignore append"
8113
- ).option("--tool <agent>", "Coding agent target (only 'CLAUDE' supported in V1)", "CLAUDE").option("--auto-invoke", "append the CLAUDE.md auto-invoke block without prompting").option("--no-auto-invoke", "strip the CLAUDE.md auto-invoke block without prompting").action(async (targetPath, opts) => {
8114
- const confirmAutoInvoke = opts.autoInvoke === void 0 ? void 0 : () => Promise.resolve(opts.autoInvoke);
8115
- await runInstall(targetPath, { tool: opts.tool, confirmAutoInvoke });
8116
- });
8178
+ ).option("--tool <agent>", "Coding agent target (only 'CLAUDE' supported in V1)", "CLAUDE").option("--auto-invoke", "append the CLAUDE.md auto-invoke block without prompting").option("--no-auto-invoke", "strip the CLAUDE.md auto-invoke block without prompting").option(
8179
+ "--scope <paths>",
8180
+ "Seed doc-scope.json with these paths (space- or comma-separated; overwrites any existing scope) without prompting. Omit to be prompted interactively on a TTY."
8181
+ ).action(
8182
+ async (targetPath, opts) => {
8183
+ const confirmAutoInvoke = opts.autoInvoke === void 0 ? void 0 : () => Promise.resolve(opts.autoInvoke);
8184
+ const provideDocScope = opts.scope === void 0 ? void 0 : () => Promise.resolve(parseScopeInput(opts.scope));
8185
+ await runInstall(targetPath, { tool: opts.tool, confirmAutoInvoke, provideDocScope });
8186
+ }
8187
+ );
8117
8188
  program.command("local-prepare").description(
8118
8189
  "Compute diff + doc-scope + prompt + token-budget gate; write .delfini-trace/"
8119
8190
  ).option("--scope <paths>", "Comma-separated doc-scope paths (overrides doc-scope.json)").option("--base <ref>", "Diff base ref (default: git merge-base HEAD origin/main)").option(
package/dist/index.d.cts CHANGED
@@ -63,6 +63,18 @@ interface RunInstallOptions {
63
63
  * non-TTY stdin (never blocks, never forces opt-in without consent).
64
64
  */
65
65
  confirmAutoInvoke?: () => Promise<boolean>;
66
+ /**
67
+ * Resolves the doc-scope path list. When provided, `runInstall` uses it
68
+ * directly (the `--scope` CLI flag and the test seam) and never prompts —
69
+ * a non-empty list is persisted to `doc-scope.json` (overwriting any
70
+ * existing file, since an explicit `--scope` is intent-to-overwrite); an
71
+ * empty list is a no-op. When omitted, `runInstall` prompts interactively
72
+ * on a TTY only if no `doc-scope.json` exists yet; on a non-TTY stdin, or
73
+ * when a scope is already configured, it leaves `doc-scope.json` untouched.
74
+ * Invalid paths (rejected by `writeDocScope`) warn-and-skip — the scaffold
75
+ * always completes; the SKILL.md first-run prompt re-seeds the scope later.
76
+ */
77
+ provideDocScope?: () => Promise<string[]>;
66
78
  }
67
79
  declare class InstallToolNotSupportedError extends Error {
68
80
  readonly code: "INSTALL_TOOL_NOT_SUPPORTED";
package/dist/index.d.ts CHANGED
@@ -63,6 +63,18 @@ interface RunInstallOptions {
63
63
  * non-TTY stdin (never blocks, never forces opt-in without consent).
64
64
  */
65
65
  confirmAutoInvoke?: () => Promise<boolean>;
66
+ /**
67
+ * Resolves the doc-scope path list. When provided, `runInstall` uses it
68
+ * directly (the `--scope` CLI flag and the test seam) and never prompts —
69
+ * a non-empty list is persisted to `doc-scope.json` (overwriting any
70
+ * existing file, since an explicit `--scope` is intent-to-overwrite); an
71
+ * empty list is a no-op. When omitted, `runInstall` prompts interactively
72
+ * on a TTY only if no `doc-scope.json` exists yet; on a non-TTY stdin, or
73
+ * when a scope is already configured, it leaves `doc-scope.json` untouched.
74
+ * Invalid paths (rejected by `writeDocScope`) warn-and-skip — the scaffold
75
+ * always completes; the SKILL.md first-run prompt re-seeds the scope later.
76
+ */
77
+ provideDocScope?: () => Promise<string[]>;
66
78
  }
67
79
  declare class InstallToolNotSupportedError extends Error {
68
80
  readonly code: "INSTALL_TOOL_NOT_SUPPORTED";
package/dist/index.js CHANGED
@@ -22,10 +22,10 @@ import {
22
22
  writeDocScope,
23
23
  writeRetryAttemptFile,
24
24
  writeTraceFile
25
- } from "./chunk-IDYMVTTU.js";
25
+ } from "./chunk-K5X5TSUR.js";
26
26
  import {
27
27
  init_esm_shims
28
- } from "./chunk-MUW24ZC4.js";
28
+ } from "./chunk-LJKEHO6F.js";
29
29
 
30
30
  // src/index.ts
31
31
  init_esm_shims();
package/package.json CHANGED
@@ -1,6 +1,12 @@
1
1
  {
2
2
  "name": "@delfini/cli",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
+ "license": "Apache-2.0",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/Legends-of-Tech/delfini.git",
8
+ "directory": "packages/cli"
9
+ },
4
10
  "type": "module",
5
11
  "publishConfig": {
6
12
  "access": "public"
@@ -26,7 +32,7 @@
26
32
  "simple-git": "^3.27.0",
27
33
  "tinyglobby": "^0.2.16",
28
34
  "zod": "^3.24.0",
29
- "@delfini/drift-engine": "0.2.0"
35
+ "@delfini/drift-engine": "0.2.1"
30
36
  },
31
37
  "devDependencies": {
32
38
  "@types/node": "^22.10.2",