intentdocs 0.11.0 → 0.12.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/index.js CHANGED
@@ -8,11 +8,11 @@ import {
8
8
  } from "./chunk-UQDMUKLP.js";
9
9
  import {
10
10
  ci
11
- } from "./chunk-65EDM7QH.js";
11
+ } from "./chunk-5GATVQEI.js";
12
12
  import {
13
13
  setup,
14
14
  sync
15
- } from "./chunk-IORMKLAQ.js";
15
+ } from "./chunk-SDXDVNNP.js";
16
16
  import {
17
17
  criterionPriority,
18
18
  criterionStatusLabel,
@@ -31,7 +31,7 @@ import {
31
31
  } from "./chunk-KPQ42YE6.js";
32
32
  import {
33
33
  scope
34
- } from "./chunk-ID4B5RZ2.js";
34
+ } from "./chunk-Q6BSSJK5.js";
35
35
  import {
36
36
  login,
37
37
  logout
@@ -57,7 +57,7 @@ import {
57
57
  readConfig,
58
58
  requireConfig,
59
59
  writeConfig
60
- } from "./chunk-K5SNF6CG.js";
60
+ } from "./chunk-RGFGTIIH.js";
61
61
  import {
62
62
  ask,
63
63
  closePrompt,
@@ -304,7 +304,7 @@ Connecting to "${map2.title}"${project.workspace ? ` in ${project.workspace.name
304
304
  await offerAllowList((q) => ask2(rl, q));
305
305
  const setUpCi = await ask2(rl, " Set up CI test reporting now? It creates a key and adds the workflow. (y/N): ");
306
306
  if (/^y(es)?$/i.test(setUpCi.trim())) {
307
- const { ci: ci2 } = await import("./ci-NOCV3XUV.js");
307
+ const { ci: ci2 } = await import("./ci-CWPLSRCQ.js");
308
308
  await ci2();
309
309
  } else {
310
310
  console.log(" You can run `npx intentdocs ci` any time to turn it on.\n");
@@ -1411,21 +1411,50 @@ async function add(title, opts) {
1411
1411
  }
1412
1412
 
1413
1413
  // src/lib/banner.ts
1414
+ import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
1415
+ import { dirname as dirname2, join as join5 } from "path";
1416
+ import { fileURLToPath } from "url";
1414
1417
  import chalk from "chalk";
1415
- var VERSION = "0.2.2";
1416
- var brand = chalk.hex("#6366F1");
1418
+
1419
+ // src/lib/wordmark.ts
1420
+ var WORDMARK = `\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
1421
+ \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
1422
+ \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
1423
+ \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551
1424
+ \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551
1425
+ \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D`;
1426
+
1427
+ // src/lib/banner.ts
1428
+ function packageVersion() {
1429
+ let dir = dirname2(fileURLToPath(import.meta.url));
1430
+ for (let i = 0; i < 4; i++) {
1431
+ const file = join5(dir, "package.json");
1432
+ if (existsSync5(file)) {
1433
+ const pkg = JSON.parse(readFileSync5(file, "utf8"));
1434
+ if (pkg.name === "intentdocs" && pkg.version) return pkg.version;
1435
+ }
1436
+ dir = dirname2(dir);
1437
+ }
1438
+ return "";
1439
+ }
1440
+ var version = packageVersion();
1441
+ var block = chalk.hex("#5B85FF");
1442
+ var shadow = chalk.hex("#1B4FD8");
1417
1443
  var muted = chalk.dim;
1418
1444
  var white = chalk.white.bold;
1419
- var PB_LOGO = `
1420
- ${brand("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
1421
- ${brand("\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557")} ${white("intentdocs")}
1422
- ${brand("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D")} ${muted("Specs \u2192 Code. Fast.")}
1423
- ${brand("\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557")}
1424
- ${brand("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551")} ${muted(`v${VERSION}`)}
1425
- ${brand("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D")}
1426
- `;
1445
+ function paint(line) {
1446
+ return line.replace(/█+|[^█]+/g, (run) => run[0] === "\u2588" ? block(run) : shadow(run));
1447
+ }
1448
+ function art(columns) {
1449
+ if (columns < 86) return ` ${white("intentdocs")}`;
1450
+ return WORDMARK.split("\n").map((line) => ` ${paint(line)}`).join("\n");
1451
+ }
1427
1452
  function printBanner(subtitle) {
1428
- console.log(PB_LOGO);
1453
+ console.log(`
1454
+ ${art(process.stdout.columns ?? 80)}
1455
+ `);
1456
+ console.log(` ${muted(`your idea, built to spec by your AI agent${version ? ` \xB7 v${version}` : ""}`)}
1457
+ `);
1429
1458
  if (subtitle) {
1430
1459
  console.log(` ${white(subtitle)}`);
1431
1460
  console.log(` ${muted("\u2500".repeat(subtitle.length))}
@@ -1634,19 +1663,19 @@ async function start() {
1634
1663
  closePrompt();
1635
1664
  return;
1636
1665
  }
1637
- const { scope: scope2 } = await import("./scope-RRGJHS2G.js");
1666
+ const { scope: scope2 } = await import("./scope-ORIFXV4P.js");
1638
1667
  await scope2(projectId);
1639
1668
  }
1640
1669
 
1641
1670
  // src/commands/propose.ts
1642
- import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync4, readFileSync as readFileSync5, existsSync as existsSync5, appendFileSync as appendFileSync2 } from "fs";
1643
- import { join as join5 } from "path";
1671
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync4, readFileSync as readFileSync6, existsSync as existsSync6, appendFileSync as appendFileSync2 } from "fs";
1672
+ import { join as join6 } from "path";
1644
1673
  function ensureChangesIgnored(cwd = process.cwd()) {
1645
- const gitignorePath = join5(cwd, ".gitignore");
1646
- if (!existsSync5(gitignorePath)) return;
1647
- const covered = readFileSync5(gitignorePath, "utf-8").split(/\r?\n/).some((line) => /^\/?intent-changes\/?(\*\*?)?$/.test(line.trim()));
1674
+ const gitignorePath = join6(cwd, ".gitignore");
1675
+ if (!existsSync6(gitignorePath)) return;
1676
+ const covered = readFileSync6(gitignorePath, "utf-8").split(/\r?\n/).some((line) => /^\/?intent-changes\/?(\*\*?)?$/.test(line.trim()));
1648
1677
  if (covered) return;
1649
- const gi = readFileSync5(gitignorePath, "utf-8");
1678
+ const gi = readFileSync6(gitignorePath, "utf-8");
1650
1679
  appendFileSync2(gitignorePath, `${gi.endsWith("\n") || gi === "" ? "" : "\n"}
1651
1680
  # intentdocs local change proposals
1652
1681
  intent-changes/
@@ -1744,8 +1773,8 @@ async function propose(changeName, opts = {}) {
1744
1773
  \u2717 Failed to create stories: ${err instanceof Error ? err.message : String(err)}`);
1745
1774
  console.log(" Saving proposal locally anyway...");
1746
1775
  }
1747
- const changesDir = join5(process.cwd(), "intent-changes", slug);
1748
- if (!existsSync5(changesDir)) mkdirSync2(changesDir, { recursive: true });
1776
+ const changesDir = join6(process.cwd(), "intent-changes", slug);
1777
+ if (!existsSync6(changesDir)) mkdirSync2(changesDir, { recursive: true });
1749
1778
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1750
1779
  const proposalMd = [
1751
1780
  `# Proposal: ${changeName}`,
@@ -1780,7 +1809,7 @@ async function propose(changeName, opts = {}) {
1780
1809
  `_Add notes here as you build._`,
1781
1810
  ``
1782
1811
  ].join("\n");
1783
- writeFileSync4(join5(changesDir, "proposal.md"), proposalMd);
1812
+ writeFileSync4(join6(changesDir, "proposal.md"), proposalMd);
1784
1813
  console.log(` \u2713 Saved intent-changes/${slug}/proposal.md`);
1785
1814
  ensureChangesIgnored();
1786
1815
  console.log(`
@@ -1797,7 +1826,7 @@ async function propose(changeName, opts = {}) {
1797
1826
  closePrompt();
1798
1827
  }
1799
1828
  function parseProposalFile(filePath) {
1800
- const raw = readFileSync5(filePath, "utf-8");
1829
+ const raw = readFileSync6(filePath, "utf-8");
1801
1830
  const lines = raw.split("\n");
1802
1831
  let changeName = "";
1803
1832
  let problem = "";
@@ -1871,7 +1900,7 @@ function parseProposalFile(filePath) {
1871
1900
  return { changeName, problem, solution, activity, priority, stories: stories2 };
1872
1901
  }
1873
1902
  async function proposeFromFile(filePath, config, nameOverride) {
1874
- if (!existsSync5(filePath)) {
1903
+ if (!existsSync6(filePath)) {
1875
1904
  console.error(`
1876
1905
  File not found: ${filePath}
1877
1906
  `);
@@ -1907,8 +1936,8 @@ async function proposeFromFile(filePath, config, nameOverride) {
1907
1936
  \u2717 Failed to create stories: ${err instanceof Error ? err.message : String(err)}`);
1908
1937
  console.log(" Saving proposal locally anyway...");
1909
1938
  }
1910
- const changesDir = join5(process.cwd(), "intent-changes", slug);
1911
- if (!existsSync5(changesDir)) mkdirSync2(changesDir, { recursive: true });
1939
+ const changesDir = join6(process.cwd(), "intent-changes", slug);
1940
+ if (!existsSync6(changesDir)) mkdirSync2(changesDir, { recursive: true });
1912
1941
  const proposalMd = [
1913
1942
  `# Proposal: ${changeName}`,
1914
1943
  ``,
@@ -1939,7 +1968,7 @@ async function proposeFromFile(filePath, config, nameOverride) {
1939
1968
  ].join("\n");
1940
1969
  })
1941
1970
  ].join("\n");
1942
- writeFileSync4(join5(changesDir, "proposal.md"), proposalMd);
1971
+ writeFileSync4(join6(changesDir, "proposal.md"), proposalMd);
1943
1972
  console.log(` \u2713 Saved intent-changes/${slug}/proposal.md`);
1944
1973
  ensureChangesIgnored();
1945
1974
  console.log(`
@@ -2971,9 +3000,9 @@ Registering intentdocs MCP with OpenClaw...`);
2971
3000
 
2972
3001
  // src/index.ts
2973
3002
  var require2 = createRequire2(import.meta.url);
2974
- var { version } = require2("../package.json");
3003
+ var { version: version2 } = require2("../package.json");
2975
3004
  var program = new Command();
2976
- program.name("intentdocs").description("Write specs, map stories, ship with AI \u2014 from your terminal").version(version);
3005
+ program.name("intentdocs").description("Write specs, map stories, ship with AI \u2014 from your terminal").version(version2);
2977
3006
  program.command("login").description("Log in to intentdocs (opens browser)").action(() => void login());
2978
3007
  program.command("logout").description("Log out of intentdocs").action(() => void logout());
2979
3008
  var keys = program.command("keys").description("Manage your Anthropic (sk-ant-), xAI (xai-), or OpenAI (sk- / sk-proj-) API key \u2014 unlock AI features on any plan");
@@ -3019,7 +3048,10 @@ program.command("projects").description("List the projects your token can reach
3019
3048
  import("./projects-AYAYVFKL.js").then((m) => void m.projects());
3020
3049
  });
3021
3050
  program.command("push").description("Upload this repo's nikOS intent/ folder: log in, create the project, and link the repo").action(() => {
3022
- import("./push-33V7ANJW.js").then((m) => m.push());
3051
+ import("./push-7LJ654MJ.js").then((m) => m.push());
3052
+ });
3053
+ program.command("pull").description("Show web edits to this repo's feature files as a diff, then write the ones you agree to").option("-y, --yes", "write web changes without asking (never settles a story changed on both sides)").action((opts) => {
3054
+ import("./pull-MDI63WI7.js").then((m) => m.pull(opts));
3023
3055
  });
3024
3056
  program.command("init [token]").description("Connect this project to a intentdocs story map").action((token) => void init(token));
3025
3057
  program.command("sync").description("Refresh INTENT.md from the live story map").option("--context", "Refresh only the CLAUDE.md/AGENTS.md context file (not stories)").action((opts) => void sync(opts));
@@ -3034,36 +3066,36 @@ program.command("done <id>").description("Mark a story as done (accepts its key
3034
3066
  program.command("stop <id>").description("Stop development of an in-progress story (resets to todo, signals agents to stop; accepts its key or an ID prefix)").action((id) => void stop(id));
3035
3067
  program.command("add <title>").description("Create a new story").option("-a, --activity <activity>", "Activity to add the story under").option("-p, --priority <priority>", "Priority: must, should, could", "should").option("-e, --effort <effort>", "Effort: S, M, L, XL", "M").action((title, opts) => void add(title, opts));
3036
3068
  var decide = program.command("decide [title]").description("Log an architectural or product decision").option("-d, --description <desc>", "Decision description").option("-c, --category <cat>", "Category: architecture, product, technical, trade-off", "technical").option("-s, --story <id>", "Link to a story (its key like PB-42, or an ID prefix)").action((title, opts) => {
3037
- import("./log-DFCCAAJN.js").then((m) => void m.logDecision(title, opts));
3069
+ import("./log-VTIAG4PC.js").then((m) => void m.logDecision(title, opts));
3038
3070
  });
3039
3071
  decide.command("list").description("List logged decisions (id, category, title)").action(() => {
3040
- import("./log-DFCCAAJN.js").then((m) => void m.listLoggedDecisions());
3072
+ import("./log-VTIAG4PC.js").then((m) => void m.listLoggedDecisions());
3041
3073
  });
3042
3074
  decide.command("amend <id>").description("Amend a logged decision's title, description, or category (accepts an ID prefix)").option("-t, --title <title>", "New title").option("-d, --description <desc>", "New description").option("-c, --category <cat>", "New category: architecture, product, technical, trade-off").action((id, opts) => {
3043
- import("./log-DFCCAAJN.js").then((m) => void m.amendDecision(id, opts));
3075
+ import("./log-VTIAG4PC.js").then((m) => void m.amendDecision(id, opts));
3044
3076
  });
3045
3077
  decide.command("delete <id>").alias("retract").description("Retract a logged decision \u2014 soft-deleted and audited, not removed (accepts an ID prefix)").option("-r, --reason <reason>", "Why this decision is being retracted").option("-y, --yes", "Skip the confirmation prompt (required when there's no TTY)").action((id, opts) => {
3046
- import("./log-DFCCAAJN.js").then((m) => void m.deleteDecision(id, opts));
3078
+ import("./log-VTIAG4PC.js").then((m) => void m.deleteDecision(id, opts));
3047
3079
  });
3048
3080
  program.command("note <storyId> [note]").description("Add an implementation note to a story (appended to its notes)").action((storyId, note) => {
3049
- import("./log-DFCCAAJN.js").then((m) => void m.logNote(storyId, note));
3081
+ import("./log-VTIAG4PC.js").then((m) => void m.logNote(storyId, note));
3050
3082
  });
3051
3083
  program.command("example").description("Add a few-shot reference pattern (before/after code) to the project").action(() => void example());
3052
3084
  program.command("complexity [storyId]").description("Analyze story complexity with AI \u2014 scores, risks, effort estimates").action((id) => {
3053
- import("./complexity-OJVM37NF.js").then((m) => void m.complexity(id));
3085
+ import("./complexity-HLJTXY55.js").then((m) => void m.complexity(id));
3054
3086
  });
3055
3087
  program.command("research [query]").description("Research a topic with AI using your project context").action((query) => {
3056
- import("./research-SHO5SXVQ.js").then((m) => void m.research(query));
3088
+ import("./research-L27DLYXC.js").then((m) => void m.research(query));
3057
3089
  });
3058
3090
  program.command("import [file]").description("Import a PRD or spec into your story map as stories (reads standard input when no file is given; needs --yes then)").option("-y, --yes", "Import without asking for confirmation (required when reading from standard input)").action((file, opts) => {
3059
- import("./import-prd-5FCVXCYO.js").then((m) => void m.importPrd(file, opts));
3091
+ import("./import-prd-FQI4J45M.js").then((m) => void m.importPrd(file, opts));
3060
3092
  });
3061
3093
  var map = program.command("map").description("Import or extract story maps from codebases");
3062
3094
  map.command("extract").description("Output a prompt for your coding agent to extract a story map from an existing codebase").action(() => {
3063
- import("./map-extract-YUCFLGJS.js").then((m) => void m.mapExtract());
3095
+ import("./map-extract-4C44YGGD.js").then((m) => void m.mapExtract());
3064
3096
  });
3065
3097
  map.command("import <file>").description("Import a storymap.json file generated by your coding agent").option("--yes", "Skip confirmation prompt").action((file, opts) => {
3066
- import("./map-import-7RN2NEUZ.js").then((m) => void m.mapImport(file, opts));
3098
+ import("./map-import-TSSDU766.js").then((m) => void m.mapImport(file, opts));
3067
3099
  });
3068
3100
  map.command("schema").description("Print the JSON Schema for storymap.json").action(() => {
3069
3101
  import("./map-schema-5BEIJM2J.js").then((m) => void m.mapSchema());
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-KTGQO3AE.js";
18
18
  import {
19
19
  requireConfig
20
- } from "./chunk-K5SNF6CG.js";
20
+ } from "./chunk-RGFGTIIH.js";
21
21
  import {
22
22
  ask,
23
23
  closePrompt,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  requireConfig
3
- } from "./chunk-K5SNF6CG.js";
3
+ } from "./chunk-RGFGTIIH.js";
4
4
  import "./chunk-UYTVTYNB.js";
5
5
 
6
6
  // src/commands/map-extract.ts
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-KTGQO3AE.js";
9
9
  import {
10
10
  requireConfig
11
- } from "./chunk-K5SNF6CG.js";
11
+ } from "./chunk-RGFGTIIH.js";
12
12
  import {
13
13
  closePrompt,
14
14
  confirm