storymaps 1.3.2 → 1.3.4

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
@@ -38,6 +38,16 @@ npm install
38
38
  npm link
39
39
  ```
40
40
 
41
+ ## Use with AI Coding Agents
42
+
43
+ A story map makes a good specification for an AI coding agent: the YAML lists every step of the journey and the cards under each one, slice by slice. **Build with AI** on storymaps.io writes the command for you:
44
+
45
+ ```bash
46
+ npx storymaps pull --force storymaps.io/abc123 && claude "The storymap file @storymap.yml describes a product plan in user story map format. Use it as a structured specification. Your task: build a functional prototype of the features listed in the 'MVP' slice."
47
+ ```
48
+
49
+ From there you steer the agent a slice or a feature at a time ("now build search from the V1 slice"). When a feature has been through QA, set its cards to `status: done` in `storymap.yml` and `storymaps push`, so the map shows the progress to everyone else. Pull again before the next round to pick up changes made in the browser.
50
+
41
51
  ## Quick Start
42
52
 
43
53
  ```bash
@@ -170,7 +180,9 @@ storymaps backup -m "Before the workshop" # with a note
170
180
  storymaps backup storymaps.io/abc123 # back up a map you haven't pulled
171
181
  ```
172
182
 
173
- The backup shows in the map's activity log, and in **Menu → Backups** in the app.
183
+ The backup shows in the map's activity log, and in **Menu → Backups** in the app. If the map hasn't changed since one of its backups, no new backup is made, and the CLI says which backup matches.
184
+
185
+ **Locked maps** use the password saved by `storymaps unlock`, or ask for it.
174
186
 
175
187
  ### `backups`
176
188
 
@@ -199,7 +211,8 @@ storymaps restore 6e40f124ae7e --force # restores without asking
199
211
  ### About backups
200
212
 
201
213
  - The CLI and the app share the same backups. A backup made in the app shows in `storymaps backups`, and one made with the CLI shows in the app.
202
- - The server keeps the newest 8 backups of each map.
214
+ - The server keeps the newest 8 backups of each map. Backups are protected from deletion, but can be removed if needed by contacting us.
215
+ - Making a backup of a locked map needs its password, so nobody else can push its backups out.
203
216
  - A self-hosted server needs updating before the CLI can make backups on it. An older one turns the request away, and the CLI says so.
204
217
 
205
218
  ### `validate`
@@ -317,16 +330,6 @@ Cards support: `name`, `body`, `color`, `status` (done / in-progress / planned /
317
330
 
318
331
  Slices support: `name`, `stories`, `goal` (up to 200 characters), `targetDate` (`YYYY-MM-DD`), and `collapsed` with `closedReason` (complete / closed).
319
332
 
320
- ## Use with AI Coding Agents
321
-
322
- A story map makes a good specification for an AI coding agent: the YAML lists every step of the journey and the cards under each one, slice by slice. **Build with AI** on storymaps.io writes the command for you:
323
-
324
- ```bash
325
- npx storymaps pull --force storymaps.io/abc123 && claude "The storymap file @storymap.yml describes a product plan in user story map format. Use it as a structured specification. Your task: build a functional prototype of the features listed in the 'MVP' slice."
326
- ```
327
-
328
- From there you steer the agent a slice or a feature at a time ("now build search from the V1 slice"). When a feature has been through QA, set its cards to `status: done` in `storymap.yml` and `storymaps push`, so the map shows the progress to everyone else. Pull again before the next round to pick up changes made in the browser.
329
-
330
333
  ## Self-Hosting
331
334
 
332
335
  The CLI works with any storymaps.io instance:
@@ -14,7 +14,12 @@ const cards = (n) => `${n} card${n === 1 ? '' : 's'}`;
14
14
 
15
15
  export async function backupCommand(target, opts) {
16
16
  const { id, baseUrl } = await resolveTarget(target, resolve(opts.file || 'storymap.yml'));
17
- const backup = await createBackup(baseUrl, id, opts.message || '');
17
+ const lockPasswordHash = await lockPassword(baseUrl, id);
18
+ const backup = await createBackup(baseUrl, id, opts.message || '', { lockPasswordHash });
19
+ if (backup.unchanged) {
20
+ console.log(`No changes since backup ${chalk.cyan(backup.id)} from ${formatTime(backup.timestamp)}, so no new backup was made.`);
21
+ return;
22
+ }
18
23
  console.log(chalk.green(`Backed up map ${id} as ${backup.id} (${cards(backup.cardCount)})`));
19
24
  }
20
25
 
@@ -82,7 +87,7 @@ export async function restoreCommand(backupId, target, opts) {
82
87
  const lockPasswordHash = await lockPassword(baseUrl, id);
83
88
 
84
89
  // Like the app: a backup of the map as it is now, so the restore can be undone
85
- const safety = await createBackup(baseUrl, id, 'Auto: before restore');
90
+ const safety = await createBackup(baseUrl, id, 'Auto: before restore', { lockPasswordHash });
86
91
  await putMap(baseUrl, id, backup.data, { contentType: 'application/json', lockPasswordHash, restoredBackup: backup.id });
87
92
 
88
93
  console.log(chalk.green(`Restored map ${id} from backup ${backup.id}`));
package/lib/util/api.js CHANGED
@@ -135,10 +135,13 @@ export async function getBackup(baseUrl, id, backupId) {
135
135
  return res.json();
136
136
  }
137
137
 
138
- export async function createBackup(baseUrl, id, note = '') {
138
+ // Answers with the new backup, or with a kept backup marked unchanged when the map matches it
139
+ export async function createBackup(baseUrl, id, note = '', { lockPasswordHash } = {}) {
140
+ const headers = { 'Content-Type': 'application/json' };
141
+ if (lockPasswordHash) headers['X-Lock-Password'] = lockPasswordHash;
139
142
  const res = await request(`${baseUrl}/api/backups/${id}`, {
140
143
  method: 'POST',
141
- headers: { 'Content-Type': 'application/json' },
144
+ headers,
142
145
  body: JSON.stringify({ note }),
143
146
  });
144
147
  // Servers from before the CLI could make backups turn the request away
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storymaps",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
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": {