storymaps 1.2.5 → 1.2.7

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 CHANGED
@@ -257,6 +257,8 @@ slices:
257
257
 
258
258
  Cards support: `name`, `body`, `color`, `status` (done / in-progress / planned / blocked), `points`, `tags`, and `url`.
259
259
 
260
+ Slices support: `name`, `stories`, `goal` (up to 200 characters), `targetDate` (`YYYY-MM-DD`), and `collapsed` with `closedReason` (complete / closed).
261
+
260
262
  ## Self-Hosting
261
263
 
262
264
  The CLI works with any storymaps.io instance:
@@ -267,6 +269,36 @@ storymaps init --site storymaps.yourcompany.com
267
269
 
268
270
  See the [main project README](https://github.com/jackgleeson/storymaps.io#self-hosting) for setup instructions.
269
271
 
272
+ ## Development
273
+
274
+ ```bash
275
+ npm install
276
+ npm test
277
+ ```
278
+
279
+ `npm test` runs the unit tests in `test/unit` with Node's built-in test runner (Node 22 or later). They cover the YAML format, the API client, the change summary, and how a target resolves to a map, with no server needed. CI runs them on Node 22 and 24 for every push to `main` and every pull request.
280
+
281
+ To try a change against a local storymaps.io server, run the CLI from the repo, for example `node bin/storymaps.js pull localhost/<map-id>`.
282
+
283
+ ### Releasing
284
+
285
+ 1. Commit your changes on `main`.
286
+ 2. Bump the version in `package.json` and commit it as "Bump version to x.y.z". Use a patch for fixes and a minor version for new features.
287
+ 3. Tag the commit and push both:
288
+ ```bash
289
+ git tag vx.y.z
290
+ git push origin main vx.y.z
291
+ ```
292
+ 4. Check you're logged in to npm, then publish:
293
+ ```bash
294
+ npm whoami # if this fails, run npm login
295
+ npm pack --dry-run # optional: list what will be published
296
+ npm publish
297
+ ```
298
+ 5. Confirm the new version is live with `npm view storymaps version`.
299
+
300
+ Only `bin/`, `lib/`, the README and the licence are published (see `files` in `package.json`).
301
+
270
302
  ## Licence
271
303
 
272
304
  AGPL-3.0 - see [LICENCE](LICENCE) for details.
@@ -29,14 +29,17 @@ export async function diffCommand(source, target, opts) {
29
29
  const sourcePath = resolve(source || 'storymap.yml');
30
30
  const sourceYaml = await readAndNormalise(sourcePath);
31
31
 
32
- let targetYaml;
33
- let targetLabel;
32
+ // Show changes from old to new. Two local files go from the first to the second. Against the
33
+ // remote, the local file is the new side, so the diff shows what a push would change.
34
+ let oldYaml, newYaml, oldLabel, newLabel;
34
35
 
35
36
  if (target) {
36
37
  // Two local files
37
38
  const targetPath = resolve(target);
38
- targetYaml = await readAndNormalise(targetPath);
39
- targetLabel = targetPath;
39
+ oldYaml = sourceYaml;
40
+ newYaml = await readAndNormalise(targetPath);
41
+ oldLabel = sourcePath;
42
+ newLabel = targetPath;
40
43
  } else {
41
44
  // Local vs remote
42
45
  const { id, baseUrl } = await resolveTarget(undefined, sourcePath);
@@ -44,11 +47,13 @@ export async function diffCommand(source, target, opts) {
44
47
  // Normalise remote YAML the same way
45
48
  const obj = jsyaml.load(data);
46
49
  const json = yamlObjToJson(obj);
47
- targetYaml = exportToYaml(json);
48
- targetLabel = `${baseUrl}/${id}`;
50
+ oldYaml = exportToYaml(json);
51
+ newYaml = sourceYaml;
52
+ oldLabel = `remote: ${baseUrl}/${id}`;
53
+ newLabel = `local: ${sourcePath}`;
49
54
  }
50
55
 
51
- const changes = diffLines(sourceYaml, targetYaml);
56
+ const changes = diffLines(oldYaml, newYaml);
52
57
  const hasChanges = changes.some(c => c.added || c.removed);
53
58
 
54
59
  if (!hasChanges) {
@@ -57,7 +62,7 @@ export async function diffCommand(source, target, opts) {
57
62
  }
58
63
 
59
64
  if (!opts.full) {
60
- printChangeSummary(sourceYaml, targetYaml);
65
+ printChangeSummary(oldYaml, newYaml);
61
66
  console.log(chalk.dim(`\nRun ${chalk.cyan('storymaps diff --full')} for the full file diff.`));
62
67
  return;
63
68
  }
@@ -65,25 +70,25 @@ export async function diffCommand(source, target, opts) {
65
70
  // --full: show line-level diff
66
71
  const CONTEXT = 3;
67
72
  const lines = [];
68
- let srcLine = 1;
69
- let dstLine = 1;
73
+ let oldLine = 1;
74
+ let newLine = 1;
70
75
  for (const part of changes) {
71
76
  for (const text of part.value.replace(/\n$/, '').split('\n')) {
72
77
  if (part.added) {
73
- lines.push({ tag: '+', text, src: null, dst: dstLine++ });
78
+ lines.push({ tag: '+', text, oldNum: null, newNum: newLine++ });
74
79
  } else if (part.removed) {
75
- lines.push({ tag: '-', text, src: srcLine++, dst: null });
80
+ lines.push({ tag: '-', text, oldNum: oldLine++, newNum: null });
76
81
  } else {
77
- lines.push({ tag: ' ', text, src: srcLine++, dst: dstLine++ });
82
+ lines.push({ tag: ' ', text, oldNum: oldLine++, newNum: newLine++ });
78
83
  }
79
84
  }
80
85
  }
81
86
 
82
- const width = String(Math.max(srcLine, dstLine)).length;
87
+ const width = String(Math.max(oldLine, newLine)).length;
83
88
  const pad = n => n === null ? ' '.repeat(width) : String(n).padStart(width);
84
89
 
85
- console.log(chalk.bold(`--- local: ${sourcePath}`));
86
- console.log(chalk.bold(`+++ remote: ${targetLabel}`));
90
+ console.log(chalk.bold(`--- ${oldLabel}`));
91
+ console.log(chalk.bold(`+++ ${newLabel}`));
87
92
 
88
93
  let lastPrinted = -1;
89
94
  for (let i = 0; i < lines.length; i++) {
@@ -92,8 +97,8 @@ export async function diffCommand(source, target, opts) {
92
97
  if (lastPrinted !== -1 && i - lastPrinted > 1) {
93
98
  console.log(chalk.dim(`${'·'.repeat(width * 2 + 5)}`));
94
99
  }
95
- const { tag, text, src, dst } = lines[i];
96
- const num = chalk.dim(`${pad(src)} ${pad(dst)}`);
100
+ const { tag, text, oldNum, newNum } = lines[i];
101
+ const num = chalk.dim(`${pad(oldNum)} ${pad(newNum)}`);
97
102
  if (tag === '+') console.log(`${num} ${chalk.green(`+ ${text}`)}`);
98
103
  else if (tag === '-') console.log(`${num} ${chalk.red(`- ${text}`)}`);
99
104
  else console.log(`${num} ${chalk.dim(` ${text}`)}`);
@@ -36,11 +36,6 @@ slices:
36
36
  stories:
37
37
  New Step:
38
38
  - name: New Task or Detail
39
- notes: >-
40
- Thanks for trying Storymaps.io! If you find it useful, please consider starring the open-source repo:
41
- https://github.com/jackgleeson/storymaps.io
42
-
43
- Have a great day!
44
39
  `;
45
40
  }
46
41
 
@@ -83,7 +78,8 @@ export async function initCommand(opts) {
83
78
  try {
84
79
  const { id } = await postMap(baseUrl, output, 'text/yaml');
85
80
  output = output.replace(/^(name: My Story Map\n)/, `$1id: ${id}\n`);
86
- console.log(chalk.green(`Created storymap.yml (map ID: ${id})\n`));
81
+ console.log(chalk.green(`Created storymap.yml (map ID: ${id})`));
82
+ console.log(`${chalk.cyan(`${baseUrl}/${id}`)}\n`);
87
83
  } catch {
88
84
  console.log(chalk.green('Created storymap.yml\n'));
89
85
  console.log(chalk.dim('Tip: run "storymaps push" to upload the map when you\'re ready to sync.\n'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storymaps",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "description": "CLI tool for storymaps.io - import, export, validate, and manage user story maps from the terminal",
5
5
  "type": "module",
6
6
  "bin": {