slidemind 0.3.19 → 0.4.0
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/AGENTS.md +591 -15
- package/README.md +202 -7
- package/bin/slidemind.mjs +50 -2
- package/package.json +2 -2
- package/skills/create-slides/SKILL.md +484 -886
- package/skills/search/SKILL.md +46 -23
- package/src/bridge/build-and-push.mjs +548 -73
- package/src/bridge/bundle.mjs +100 -31
- package/src/bridge/capture.mjs +14 -17
- package/src/bridge/client/brands.mjs +157 -18
- package/src/bridge/client/engine-routing.mjs +48 -13
- package/src/bridge/client/engine-search.mjs +24 -1
- package/src/bridge/client/engine-slides.mjs +1 -1
- package/src/bridge/client/render.mjs +27 -1
- package/src/bridge/client/transport.mjs +499 -23
- package/src/bridge/client.mjs +10 -0
- package/src/bridge/config.mjs +67 -6
- package/src/bridge/engine-download.mjs +0 -10
- package/src/bridge/graph-auth.mjs +55 -3
- package/src/bridge/image-intent-envelope.mjs +239 -0
- package/src/bridge/package-preview.mjs +67 -0
- package/src/bridge/sharepoint.mjs +914 -0
- package/src/builders/asset-fetch.mjs +203 -0
- package/src/builders/block-dividers.mjs +83 -0
- package/src/builders/build.mjs +171 -87
- package/src/builders/card-height.mjs +294 -0
- package/src/builders/chart-hole.mjs +183 -0
- package/src/builders/chart-jsx.mjs +410 -0
- package/src/builders/chart-labels.mjs +326 -0
- package/src/builders/concept-geometry.mjs +370 -0
- package/src/builders/concept-intent.mjs +200 -0
- package/src/builders/concept-layout.mjs +79 -0
- package/src/builders/concept-lines.mjs +509 -0
- package/src/builders/concept-lists.mjs +270 -0
- package/src/builders/concept-marks.mjs +84 -0
- package/src/builders/concept-relationships.mjs +12 -0
- package/src/builders/concept-spec.mjs +645 -0
- package/src/builders/concept-text.mjs +140 -0
- package/src/builders/concept-waves.mjs +57 -0
- package/src/builders/copy-fit.mjs +139 -0
- package/src/builders/design-tokens.mjs +347 -0
- package/src/builders/draft-check.mjs +552 -340
- package/src/builders/draft-lines.mjs +369 -0
- package/src/builders/edit-route.mjs +29 -0
- package/src/builders/figure-sketch.mjs +375 -0
- package/src/builders/fold-sets.mjs +639 -0
- package/src/builders/gate-server.mjs +9 -4
- package/src/builders/gate-session.js +273 -12
- package/src/builders/gate-shell.js +1494 -0
- package/src/builders/image-intent-check.mjs +308 -0
- package/src/builders/image-use-reconcile.mjs +107 -0
- package/src/builders/kit-helpers.mjs +121 -0
- package/src/builders/layout-names.mjs +32 -0
- package/src/builders/legacy-reference-uses.mjs +179 -0
- package/src/builders/line-fit.mjs +224 -0
- package/src/builders/line-native.mjs +895 -0
- package/src/builders/line-relations.mjs +230 -0
- package/src/builders/lint-fix.mjs +117 -9
- package/src/builders/lint.mjs +25 -20
- package/src/builders/list-jsx.mjs +88 -0
- package/src/builders/placement.mjs +133 -0
- package/src/builders/plan-checks.mjs +135 -0
- package/src/builders/plan-comments.mjs +19 -0
- package/src/builders/plan-handlers.mjs +95 -0
- package/src/builders/plan-markdown-edit.mjs +3 -3
- package/src/builders/plan-overlay.js +1530 -1608
- package/src/builders/plan.mjs +689 -186
- package/src/builders/preset-definitions.json +1 -0
- package/src/builders/preset-eval.mjs +244 -0
- package/src/builders/preview.html +51 -120
- package/src/builders/red-thread-backbone.mjs +135 -36
- package/src/builders/repair.mjs +205 -0
- package/src/builders/repeat-groups.mjs +540 -0
- package/src/builders/resolve-skill.mjs +5 -4
- package/src/builders/review-overlay.js +296 -293
- package/src/builders/review.mjs +305 -84
- package/src/builders/rule-shift.mjs +96 -0
- package/src/builders/seat.mjs +354 -0
- package/src/builders/settle-driver.mjs +236 -0
- package/src/builders/settle.mjs +1448 -0
- package/src/builders/slide-prep.mjs +67 -0
- package/src/builders/spec-assets.mjs +236 -0
- package/src/builders/spec-match.mjs +56 -0
- package/src/builders/stack.mjs +413 -0
- package/src/builders/storyboard-markdown.mjs +70 -27
- package/src/builders/storyboard-schema.mjs +54 -114
- package/src/builders/text-blocks.mjs +212 -0
- package/src/builders/text-card-fit.mjs +552 -0
- package/src/builders/text-stack.mjs +276 -0
- package/src/builders/transcribe.mjs +1069 -0
- package/src/cli/assets.mjs +164 -0
- package/src/cli/common.mjs +173 -12
- package/src/cli/concept-spec-support.mjs +76 -0
- package/src/cli/concepts.mjs +1002 -103
- package/src/cli/deck.mjs +401 -65
- package/src/cli/diagnose.mjs +4 -2
- package/src/cli/engine-helpers.mjs +17 -10
- package/src/cli/engine-results.mjs +76 -3
- package/src/cli/help.mjs +232 -28
- package/src/cli/install.mjs +9 -0
- package/src/cli/maintenance.mjs +104 -0
- package/src/cli/read.mjs +2 -1
- package/src/cli/ready.mjs +6 -3
- package/src/cli/record.mjs +522 -0
- package/src/cli/remote.mjs +818 -0
- package/src/cli/revision.mjs +686 -0
- package/src/cli/search.mjs +30 -11
- package/src/cli/session.mjs +56 -13
- package/src/cli/setup.mjs +46 -2
- package/src/cli/status.mjs +142 -33
- package/src/cli/tasks.mjs +246 -0
- package/src/cli/transcribe.mjs +854 -0
- package/src/cli/workspace-ui.mjs +260 -0
- package/src/cli/workspace.mjs +212 -34
- package/src/install-channel.mjs +64 -7
- package/src/lib/adopt.mjs +346 -25
- package/src/lib/concept-spec-binding.mjs +96 -0
- package/src/lib/conversions.mjs +70 -6
- package/src/lib/convert-folded.mjs +107 -0
- package/src/lib/deck-paths.mjs +418 -0
- package/src/lib/durable-ids.mjs +47 -0
- package/src/lib/edit-operations.mjs +316 -0
- package/src/lib/edit-state.mjs +1244 -0
- package/src/lib/edit-transitions.mjs +120 -0
- package/src/lib/extensions.mjs +501 -0
- package/src/lib/image-assets.mjs +465 -0
- package/src/lib/image-derivatives.mjs +234 -0
- package/src/lib/image-intent-fingerprint.mjs +70 -0
- package/src/lib/image-intent-tags.mjs +176 -0
- package/src/lib/image-intent.mjs +802 -0
- package/src/lib/image-use-overrides.mjs +279 -0
- package/src/lib/inline-components.mjs +613 -0
- package/src/lib/lint-converted.mjs +68 -4
- package/src/lib/merge-json.mjs +163 -0
- package/src/lib/overwrite-guard.mjs +3 -3
- package/src/lib/presentation-context.mjs +531 -0
- package/src/lib/preservation-tags.mjs +157 -0
- package/src/lib/preservation-verdict.mjs +1342 -0
- package/src/lib/publish.mjs +1557 -0
- package/src/lib/rebase.mjs +945 -0
- package/src/lib/reconcile-ack.mjs +4 -6
- package/src/lib/reconcile.mjs +62 -24
- package/src/lib/record-client.mjs +175 -0
- package/src/lib/record-state.mjs +151 -0
- package/src/lib/remote.mjs +661 -0
- package/src/lib/revision.mjs +1210 -0
- package/src/lib/slide-guids.mjs +4 -6
- package/src/lib/slide-preservation.mjs +423 -0
- package/src/lib/slide-selection.mjs +9 -0
- package/src/lib/workspace-transaction.mjs +117 -0
- package/src/pptx/content-digest.mjs +334 -0
- package/src/pptx/deck-assemble.mjs +1278 -0
- package/src/pptx/fill/engine.mjs +2 -3
- package/src/pptx/fill/freeform.mjs +6 -3
- package/src/pptx/ooxml.mjs +20 -0
- package/src/pptx/package-evidence.mjs +383 -0
- package/src/pptx/tags.mjs +163 -11
- package/src/update-check.mjs +22 -4
- package/src/workspace/adapters.mjs +222 -0
- package/src/workspace/auth.mjs +256 -0
- package/src/workspace/autostart.mjs +204 -0
- package/src/workspace/daemon.mjs +360 -0
- package/src/workspace/discovery.mjs +180 -0
- package/src/workspace/edit.mjs +167 -0
- package/src/workspace/events.mjs +52 -0
- package/src/workspace/gate-client.mjs +290 -0
- package/src/workspace/handback.mjs +73 -0
- package/src/workspace/lifecycle.mjs +635 -0
- package/src/workspace/operations.mjs +200 -0
- package/src/workspace/pick-folder.mjs +152 -0
- package/src/workspace/registry.mjs +359 -0
- package/src/workspace/remote-links.mjs +397 -0
- package/src/workspace/remote-status.mjs +359 -0
- package/src/workspace/routes.mjs +1331 -0
- package/src/workspace/server.mjs +159 -0
- package/src/workspace/sync.mjs +1119 -0
- package/src/workspace/task-actions.mjs +215 -0
- package/src/workspace/tasks.mjs +507 -0
- package/src/workspace/ui/app.js +1886 -0
- package/src/workspace/ui/index.html +141 -0
- package/src/workspace/ui/plan-bridge.js +120 -0
- package/src/workspace/ui/sharepoint.svg +59 -0
- package/src/workspace/ui/styles.css +423 -0
- package/src/builders/visual-families.mjs +0 -46
package/src/cli/diagnose.mjs
CHANGED
|
@@ -37,7 +37,7 @@ export async function runDiagnose(rest) {
|
|
|
37
37
|
// push/insert-slide and reading an open presentation. Reporting them
|
|
38
38
|
// separately is the point — a dead pane is not "cannot work".
|
|
39
39
|
const authoringBlocker = backendBlocker(status);
|
|
40
|
-
let engines = { available: false, envs: [] };
|
|
40
|
+
let engines = { available: false, envs: [], unknown: [] };
|
|
41
41
|
if (!authoringBlocker) {
|
|
42
42
|
try {
|
|
43
43
|
engines = await client.engineReachability({ backends: statusRaw.backends });
|
|
@@ -73,7 +73,9 @@ export async function runDiagnose(rest) {
|
|
|
73
73
|
` engine search (no window needed): ${
|
|
74
74
|
engines.available
|
|
75
75
|
? `yes [${engines.envs.join(", ")}]`
|
|
76
|
-
:
|
|
76
|
+
: engines.unknown?.length
|
|
77
|
+
? `could not be checked [${engines.unknown.join(", ")}] — the capability probe got no answer; retry`
|
|
78
|
+
: "no — relayed through an open pane"
|
|
77
79
|
}\n`,
|
|
78
80
|
);
|
|
79
81
|
// Human output only — the --json shape is a contract and the m365 state
|
|
@@ -387,18 +387,25 @@ export function writeAddSlideResult({ asJson, searchId, deckDir, deck, written,
|
|
|
387
387
|
|
|
388
388
|
// Map a `--icon-color` value onto the `--pick` list. Accepts either one colour
|
|
389
389
|
// (applied to every pick) or exactly one per pick (positional); an empty
|
|
390
|
-
// segment means "no colour for this pick".
|
|
390
|
+
// segment means "no colour for this pick". The `#` is optional: an unquoted
|
|
391
|
+
// `#0A7E8C` starts a shell comment (zsh, bash) that swallows the value and
|
|
392
|
+
// every flag after it, so the bare form is the one no shell eats (x74: 38
|
|
393
|
+
// failed downloads). `raw` is null when the flag is absent, "" when it arrived
|
|
394
|
+
// empty. Returns an array aligned to picks, each colour `#`-prefixed.
|
|
391
395
|
export function parseIconColors(raw, pickCount) {
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
if (c !== null && !/^#[0-9a-fA-F]{3,8}$/.test(c)) {
|
|
399
|
-
fail(`--icon-color expects hex colours like #0A7E8C, got '${c}'`);
|
|
400
|
-
}
|
|
396
|
+
if (raw == null) return new Array(pickCount).fill(null);
|
|
397
|
+
if (!raw.trim()) {
|
|
398
|
+
fail(
|
|
399
|
+
"--icon-color got no value — an unquoted '#RRGGBB' starts a shell comment in zsh and bash " +
|
|
400
|
+
"(which also drops every flag after it); pass 0A7E8C, or quote it: '#0A7E8C'",
|
|
401
|
+
);
|
|
401
402
|
}
|
|
403
|
+
const colors = raw.split(",").map((s) => {
|
|
404
|
+
const c = s.trim();
|
|
405
|
+
if (!c) return null;
|
|
406
|
+
if (!/^#?[0-9a-fA-F]{3,8}$/.test(c)) fail(`--icon-color expects hex colours like 0A7E8C or '#0A7E8C', got '${c}'`);
|
|
407
|
+
return c.startsWith("#") ? c : `#${c}`;
|
|
408
|
+
});
|
|
402
409
|
if (colors.length === 1) return new Array(pickCount).fill(colors[0]);
|
|
403
410
|
if (colors.length !== pickCount) {
|
|
404
411
|
fail(
|
|
@@ -187,6 +187,45 @@ export async function cmdReadSource(rest) {
|
|
|
187
187
|
* across every command.
|
|
188
188
|
*/
|
|
189
189
|
|
|
190
|
+
|
|
191
|
+
// Register a downloaded image with the deck's image registry (task 2.6 of the
|
|
192
|
+
// image-intent contract): the bytes get a digest-backed identity and engine
|
|
193
|
+
// provenance, so a later plan can bind a use to THIS result rather than to a
|
|
194
|
+
// file name someone might overwrite.
|
|
195
|
+
//
|
|
196
|
+
// Deliberately two things it is not: it is not a use — registering creates no
|
|
197
|
+
// obligation to place the picture on any slide — and it is not allowed to sink
|
|
198
|
+
// a download. A registry that cannot be written (the deck is held by another
|
|
199
|
+
// command, the format is one the registry does not ship) leaves the asset file
|
|
200
|
+
// exactly where it always landed and every existing output field untouched.
|
|
201
|
+
async function registerDownloadedAsset(deckDir, result, searchId) {
|
|
202
|
+
try {
|
|
203
|
+
const { importImageAsset } = await import(
|
|
204
|
+
pathToFileURL(path.join(SRC_DIR, "lib", "image-assets.mjs")).href
|
|
205
|
+
);
|
|
206
|
+
const { asset, reused } = await importImageAsset(deckDir, result.path, {
|
|
207
|
+
displayName: path.basename(result.path),
|
|
208
|
+
provenance: { kind: "engine", sourceId: `${searchId}:${result.selection}` },
|
|
209
|
+
});
|
|
210
|
+
return {
|
|
211
|
+
assetId: asset.assetId,
|
|
212
|
+
sha256: asset.sha256,
|
|
213
|
+
mimeType: asset.mimeType,
|
|
214
|
+
width: asset.width,
|
|
215
|
+
height: asset.height,
|
|
216
|
+
byteLength: asset.byteLength,
|
|
217
|
+
workspacePath: asset.workspacePath,
|
|
218
|
+
reused,
|
|
219
|
+
};
|
|
220
|
+
} catch (err) {
|
|
221
|
+
process.stderr.write(
|
|
222
|
+
`note: ${result.reference} was downloaded but not registered as an image asset ` +
|
|
223
|
+
`(${err?.code ?? "error"}: ${err?.message ?? err}).\n`,
|
|
224
|
+
);
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
190
229
|
export async function cmdDownloadResult(rest) {
|
|
191
230
|
let searchId = null;
|
|
192
231
|
let picks = null;
|
|
@@ -194,6 +233,7 @@ export async function cmdDownloadResult(rest) {
|
|
|
194
233
|
let to = null;
|
|
195
234
|
let asJson = false;
|
|
196
235
|
let iconColorsRaw = null;
|
|
236
|
+
let name = null;
|
|
197
237
|
for (let i = 0; i < rest.length; i++) {
|
|
198
238
|
const a = rest[i];
|
|
199
239
|
if (a === "--search") {
|
|
@@ -208,9 +248,16 @@ export async function cmdDownloadResult(rest) {
|
|
|
208
248
|
if (!to) fail("--to expects a presId");
|
|
209
249
|
} else if (a === "--json") {
|
|
210
250
|
asJson = true;
|
|
251
|
+
} else if (a === "--name") {
|
|
252
|
+
// The asset's file name under assets/ (one pick only): lets a fetcher
|
|
253
|
+
// write `02-card-1-icon.svg` so the slide author references a path it
|
|
254
|
+
// knew before the download ran — the wiring gap that left fetched icons
|
|
255
|
+
// unused (x25/x26 sims).
|
|
256
|
+
name = rest[++i];
|
|
257
|
+
if (!name || /[\\/]/.test(name)) fail("--name expects a bare file name (no directories)");
|
|
211
258
|
} else if (a === "--icon-color" || a === "--icon-colour") {
|
|
212
|
-
|
|
213
|
-
|
|
259
|
+
// Empty when the shell ate an unquoted '#…' as a comment: parseIconColors explains that.
|
|
260
|
+
iconColorsRaw = rest[++i] ?? "";
|
|
214
261
|
} else if (a.startsWith("-")) {
|
|
215
262
|
fail(`unknown flag: ${a}`);
|
|
216
263
|
} else {
|
|
@@ -222,6 +269,7 @@ export async function cmdDownloadResult(rest) {
|
|
|
222
269
|
"usage: slidemind download-result --search <id> --pick <n[,n,...]> --deck <deck> [--to <presId>] [--icon-color <hex[,hex,...]>] [--json]",
|
|
223
270
|
);
|
|
224
271
|
}
|
|
272
|
+
if (name && picks.length !== 1) fail("--name takes exactly one --pick");
|
|
225
273
|
const iconColors = parseIconColors(iconColorsRaw, picks.length);
|
|
226
274
|
const deckDir = resolveDeckArg(deck);
|
|
227
275
|
const assetsDir = path.join(deckDir, "assets");
|
|
@@ -292,6 +340,31 @@ export async function cmdDownloadResult(rest) {
|
|
|
292
340
|
continue;
|
|
293
341
|
}
|
|
294
342
|
ok++;
|
|
343
|
+
if (name && r.path) {
|
|
344
|
+
// Keep the extension the bytes decided; only the stem is the caller's.
|
|
345
|
+
const ext = path.extname(r.path);
|
|
346
|
+
// `NN-<id>.asset` is the placeholder a transcribed slide references
|
|
347
|
+
// before its bytes exist; the file takes the real extension and every
|
|
348
|
+
// slide pointing at the placeholder follows it. Kept as `.asset`, the
|
|
349
|
+
// renderer dropped the picture with a warning and the check stayed clean.
|
|
350
|
+
const placeholder = /\.asset$/i.test(name) ? name : null;
|
|
351
|
+
const target = path.join(assetsDir, placeholder ? name.replace(/\.asset$/i, ext) : path.extname(name) ? name : `${name}${ext}`);
|
|
352
|
+
fs.renameSync(r.path, target);
|
|
353
|
+
r.path = target;
|
|
354
|
+
r.reference = `./assets/${path.basename(target)}`;
|
|
355
|
+
if (placeholder) {
|
|
356
|
+
const slidesDir = path.join(deckDir, "slides");
|
|
357
|
+
for (const f of fs.existsSync(slidesDir) ? fs.readdirSync(slidesDir).filter((n) => n.endsWith(".jsx")) : []) {
|
|
358
|
+
const file = path.join(slidesDir, f);
|
|
359
|
+
const src = fs.readFileSync(file, "utf8");
|
|
360
|
+
const from = JSON.stringify(`./assets/${placeholder}`);
|
|
361
|
+
if (src.includes(from)) fs.writeFileSync(file, src.split(from).join(JSON.stringify(r.reference)));
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// Identity for the registry — additive: `file`, `size` and `recolor` below
|
|
366
|
+
// keep their exact shape for callers that predate the image contract.
|
|
367
|
+
r.asset = r.path ? await registerDownloadedAsset(deckDir, r, searchId) : null;
|
|
295
368
|
const note = r.recolor?.note ? ` — ${r.recolor.note}` : "";
|
|
296
369
|
// The intrinsic size is the agent's only handle on the asset's aspect
|
|
297
370
|
// ratio — without it the <img> box is a guess and the render stretches.
|
|
@@ -302,7 +375,7 @@ export async function cmdDownloadResult(rest) {
|
|
|
302
375
|
}
|
|
303
376
|
if (asJson) {
|
|
304
377
|
process.stdout.write(
|
|
305
|
-
`${JSON.stringify({ searchId, assetsDir, downloaded: ok, results: results.map((r) => (r.error ? { selection: r.selection, error: r.error } : { selection: r.selection, file: r.reference, size: r.size ?? null, recolor: r.recolor ?? null })) }, null, 2)}\n`,
|
|
378
|
+
`${JSON.stringify({ searchId, assetsDir, downloaded: ok, results: results.map((r) => (r.error ? { selection: r.selection, error: r.error } : { selection: r.selection, file: r.reference, size: r.size ?? null, recolor: r.recolor ?? null, asset: r.asset ?? null })) }, null, 2)}\n`,
|
|
306
379
|
);
|
|
307
380
|
if (ok === 0) process.exit(1);
|
|
308
381
|
return;
|
package/src/cli/help.mjs
CHANGED
|
@@ -29,8 +29,8 @@ export function printHelp(cmd = null) {
|
|
|
29
29
|
` --force re-download the bundle even if current\n` +
|
|
30
30
|
` --connect-only check the connection only (no design/bundle)\n` +
|
|
31
31
|
` --diagnose read-only report instead: both ladders (backend\n` +
|
|
32
|
-
` authoring / live PowerPoint),
|
|
33
|
-
`
|
|
32
|
+
` authoring / live PowerPoint), Microsoft 365 state\n` +
|
|
33
|
+
` and every registered window\n` +
|
|
34
34
|
` --json machine-readable readiness payload\n` +
|
|
35
35
|
` With a deck, also prints its stage (plan / concepts / assets / slides /\n` +
|
|
36
36
|
` draft check / review) and the next command — read from disk.\n` +
|
|
@@ -38,10 +38,15 @@ export function printHelp(cmd = null) {
|
|
|
38
38
|
` --brand <presFP> bind to a chosen (cached) design instead\n` +
|
|
39
39
|
` --to <presId> bind to a specific open window\n` +
|
|
40
40
|
` --no-bind skip the auto-bind\n` +
|
|
41
|
-
` slidemind plan <deck> Plan sign-off gate on <deck
|
|
42
|
-
`
|
|
43
|
-
`
|
|
44
|
-
`
|
|
41
|
+
` slidemind plan <deck> Plan sign-off gate on <deck>/.slidemind/plan.md (## Red thread +\n` +
|
|
42
|
+
` ## Per-slide storyboards, one storyboard-canvas block per slide):\n` +
|
|
43
|
+
` the user answers in the workspace. It asks there and returns at once:\n` +
|
|
44
|
+
` ASK: <link>, SAY: <the line to end your turn with>, DECISION: pending.\n` +
|
|
45
|
+
` The user's pasted message names this command again; that run prints\n` +
|
|
46
|
+
` their answer (DECISION: approved | comments). BLOCKED: <code> when the\n` +
|
|
47
|
+
` workspace cannot be used (exit 2). Only SLIDEMIND_WORKSPACE=0 serves\n` +
|
|
48
|
+
` the standalone page that blocks until the user decides\n` +
|
|
49
|
+
` --port <n> standalone page: a fixed port (default: per deck)\n` +
|
|
45
50
|
` slidemind concepts <deck> After plan sign-off, generate one concept mockup PNG per planned\n` +
|
|
46
51
|
` slide into <deck>/concepts/concept-slide-NN.png (bound deck,\n` +
|
|
47
52
|
` pane-free — no PowerPoint window needed).\n` +
|
|
@@ -51,19 +56,62 @@ export function printHelp(cmd = null) {
|
|
|
51
56
|
` mockup for slides N,M (default: all)\n` +
|
|
52
57
|
` --style <image>[@N,M] the user's look-and-feel reference,\n` +
|
|
53
58
|
` leads the generation (repeatable)\n` +
|
|
59
|
+
` --status whether a run is in progress and how many mockups and\n` +
|
|
60
|
+
` specs are on disk (read-only; never starts a run)\n` +
|
|
61
|
+
` Both flags IMPORT the file into the deck and record it in plan.md\n` +
|
|
62
|
+
` as an image use (--concept: rebuild this slide; --style: reference).\n` +
|
|
63
|
+
` A new use re-arms the plan gate — sign off again, then re-run.\n` +
|
|
54
64
|
` --json machine-readable result (paths, missing, status)\n` +
|
|
55
65
|
` Always ends on one line: CONCEPTS: <n>/<planned> <status>\n` +
|
|
56
|
-
`
|
|
57
|
-
`
|
|
58
|
-
`
|
|
59
|
-
`
|
|
66
|
+
` With an add-in that extracts concept specs, also writes\n` +
|
|
67
|
+
` state/concept-specs/concept-slide-NN.json (the mockup's element inventory)\n` +
|
|
68
|
+
` slidemind transcribe <deck> --read-spec [--only NN] Read complete specs through END OF SPEC\n` +
|
|
69
|
+
` slidemind transcribe <deck> Write each slide's JSX skeleton from its concept spec: one element per\n` +
|
|
70
|
+
` spec line at the spec's slot coordinates, connectors by id, icons as\n` +
|
|
71
|
+
` ./assets/NN-<icon id>.asset, fetched and renamed to the real file by\n` +
|
|
72
|
+
` transcribe itself (download-result --name NN-<id>.asset for a miss).\n` +
|
|
73
|
+
` --only NN write just this slide (a SELECTION, not permission to rewrite)\n` +
|
|
74
|
+
` --force rebuild a slide that already exists from its spec\n` +
|
|
75
|
+
` --discard-edits with --force: also rebuild a slide edited since transcribe\n` +
|
|
76
|
+
` --repair bounded repair of RECORDED source, inside an open repair scope\n` +
|
|
77
|
+
` (\`revision begin <deck> --operation repair --slides <sel>\`;\n` +
|
|
78
|
+
` a targeted-edit scope is refused). Runs the WHOLE scope —\n` +
|
|
79
|
+
` --only cannot carve a subset out of it. Budget: <=3 passes,\n` +
|
|
80
|
+
` <=8 slot-px move and <=10% size change per element measured\n` +
|
|
81
|
+
` from the ORIGINAL source, and zero text/asset/element-count/\n` +
|
|
82
|
+
` endpoint change. Refuses (before staging anything) unrecorded\n` +
|
|
83
|
+
` source, converted source, an unparseable slide, and a bundle\n` +
|
|
84
|
+
` with no capture engine. Not combinable with --force/--discard-edits.\n` +
|
|
85
|
+
` --no-assets do not fetch or retry the slides' icons/images\n` +
|
|
86
|
+
` --no-settle write the JSX as the spec gives it; no geometry settling\n` +
|
|
87
|
+
` --json machine-readable result\n` +
|
|
88
|
+
` A slide edited since transcribe wrote it, and any converted slide, is kept\n` +
|
|
89
|
+
` byte-for-byte — edit its JSX directly.\n` +
|
|
90
|
+
` A bare re-run RETRIES assets an earlier run could not resolve, including on\n` +
|
|
91
|
+
` slides it now skips: the missing picture is fetched without re-extracting\n` +
|
|
92
|
+
` the spec, regenerating the source or re-settling it. A reference you\n` +
|
|
93
|
+
` repointed at your own file is left alone.\n` +
|
|
94
|
+
` slidemind review <deck> Spatial preview review (host-free): builds the preview, asks in the\n` +
|
|
95
|
+
` workspace like \`plan\` and returns at once (ASK + SAY, DECISION:\n` +
|
|
96
|
+
` pending); the user's pasted message names it again to receive the answer\n` +
|
|
97
|
+
` --port <n> standalone page: a fixed port (default: per deck)\n` +
|
|
60
98
|
` slidemind build-pptx <deck> Export native .pptx — via the add-in for compose decks (pane-free: the deck's design, else the one design cached/listed; a window only with --to), LOCALLY for template packs (host-free)\n` +
|
|
61
99
|
` --pack <dir> explicit template-pack directory (plugin integrations)\n` +
|
|
62
100
|
` --to <presId> target a specific window (required if >1 open)\n` +
|
|
63
101
|
` --out <path> output path (default <deck>/<deck>.pptx)\n` +
|
|
64
102
|
` --force discard manual PowerPoint edits instead of reconciling them\n` +
|
|
65
|
-
` --
|
|
66
|
-
`
|
|
103
|
+
` --refresh-design adopted decks: also re-render the untouched slides onto the current\n` +
|
|
104
|
+
` corporate design (by default only what you changed renders)\n` +
|
|
105
|
+
` --no-publish keep this build local (see below)\n` +
|
|
106
|
+
` --json machine-readable result (\`publish\`: the publish outcome, or null)\n` +
|
|
107
|
+
` (writes per-slide PNGs of the built deck to <deck>/.slidemind/preview/build/)\n` +
|
|
108
|
+
` A compose deck connected to SharePoint — the file it was opened from, or a\n` +
|
|
109
|
+
` folder connected in the workspace — is PUBLISHED right after the build, as\n` +
|
|
110
|
+
` \`slidemind publish\` would; a publish that did not save exits 2.\n` +
|
|
111
|
+
` Refuses a slide whose recorded preservation obligations are unmet or\n` +
|
|
112
|
+
` unproven, naming the elements. A record is seeded by adopt / revision\n` +
|
|
113
|
+
` begin, so an adopted deck is protected WITHOUT opening a scope; a deck\n` +
|
|
114
|
+
` authored from scratch has no record and is never gated.\n` +
|
|
67
115
|
` slidemind inspect-template-deck <deck> Inspect a template deck as JSON for pack-owned validation\n` +
|
|
68
116
|
` --pack <dir> explicit template-pack directory (required)\n` +
|
|
69
117
|
` --allow-unrendered-freeform include JSX inserts without .pptx artifacts\n` +
|
|
@@ -71,18 +119,23 @@ export function printHelp(cmd = null) {
|
|
|
71
119
|
` slidemind view-draft <deck> Lint + build the HTML preview, then render the deck's slides to\n` +
|
|
72
120
|
` per-slide PNGs (no push, no .pptx)\n` +
|
|
73
121
|
` so the agent can look before review; host-free once the\n` +
|
|
74
|
-
` bundle is materialized. Prints the
|
|
122
|
+
` bundle is materialized. Prints the draft lines (which hold: workflow/create.md\n` +
|
|
123
|
+
` step 6) and, per unmet preservation obligation, a [preserve:warn] naming the\n` +
|
|
124
|
+
` element and its repair ([preserve:error] names a preservation record that\n` +
|
|
125
|
+
` cannot be read).\n` +
|
|
126
|
+
` review, build-pptx and push refuse a slide never checked, changed since its\n` +
|
|
127
|
+
` check, or with a measured defect standing.\n` +
|
|
75
128
|
` Also runs the server's export gate on the captured slides (slot-fit,\n` +
|
|
76
|
-
` diagram geometry,
|
|
129
|
+
` diagram geometry, text escape, chrome) so build-pptx's 422s surface here.\n` +
|
|
77
130
|
` --only <file|N>[,…] render just these slides (a per-slide builder's own check)\n` +
|
|
78
|
-
` --fix
|
|
131
|
+
` --no-fix skip the deterministic lint autofixes (on by default)\n` +
|
|
79
132
|
` --lint-only lint + HTML build, no render (fast fix loop)\n` +
|
|
80
133
|
` --strict converted slides: gate here like review does (they only warn by default)\n` +
|
|
81
134
|
` --no-translate skip the export gate (purely local check)\n` +
|
|
82
135
|
` --translate insist on the export gate (fail instead of skipping when the backend is unreachable)\n` +
|
|
83
136
|
` --json machine-readable result (slides, defects, reviewCanOpen)\n` +
|
|
84
137
|
` --to <presId> window to fetch the bundle from (only if not cached)\n` +
|
|
85
|
-
` --out <dir> output dir (default <deck>/.
|
|
138
|
+
` --out <dir> output dir (default <deck>/.slidemind/preview/draft/)\n` +
|
|
86
139
|
` --open open each rendered PNG\n` +
|
|
87
140
|
` slidemind search "<query>" Search an engine or scope for images or slides (no window needed on\n` +
|
|
88
141
|
` add-ins that serve the pane-free engine routes; older ones relay\n` +
|
|
@@ -92,7 +145,7 @@ export function printHelp(cmd = null) {
|
|
|
92
145
|
` --result-type <t> slide | image — required for a scope:* target\n` +
|
|
93
146
|
` --intent <i> auto | content | visual (slide engines)\n` +
|
|
94
147
|
` --top <N> max results\n` +
|
|
95
|
-
` --deck <deck>
|
|
148
|
+
` --deck <deck> use this deck's bound design\n` +
|
|
96
149
|
` --to <presId> pin a window on the relayed path (ignored pane-free)\n` +
|
|
97
150
|
` --json print the raw result payload (carries the searchId)\n` +
|
|
98
151
|
` slidemind view-slide [opts] Fetch a slide search result's preview image to a file\n` +
|
|
@@ -113,8 +166,7 @@ export function printHelp(cmd = null) {
|
|
|
113
166
|
` slidemind ls engines List the live engine catalog + search scopes\n` +
|
|
114
167
|
` --type <t> collection | search | scope\n` +
|
|
115
168
|
` --subtype <s> image | slide | template | content\n` +
|
|
116
|
-
` --to <presId> target a specific window
|
|
117
|
-
` --all include every paired backend\n` +
|
|
169
|
+
` --to <presId> target a specific window (relayed path only)\n` +
|
|
118
170
|
` --json print the raw engine list\n` +
|
|
119
171
|
` slidemind insert-slide [opts] Insert reused slide search results live into a window (requires a host)\n` +
|
|
120
172
|
` --search <id> searchId from 'slidemind search'\n` +
|
|
@@ -131,16 +183,162 @@ export function printHelp(cmd = null) {
|
|
|
131
183
|
` --json machine-readable result (carries the searchId)\n` +
|
|
132
184
|
` slidemind adopt <file.pptx> Rebuild a deck workspace from a file's embedded source; foreign\n` +
|
|
133
185
|
` slides are converted to editable jsx where the add-in offers it\n` +
|
|
186
|
+
` Repeatable: the SAME file again rewrites nothing, a wider --slides\n` +
|
|
187
|
+
` hydrates only the new slides, a DIFFERENT file reconciles onto the\n` +
|
|
188
|
+
` deck (with unpublished edits it refuses and names 'slidemind rebase')\n` +
|
|
134
189
|
` --deck <slug> deck folder to write (default: the file's name)\n` +
|
|
135
190
|
` --brand <presFP> design to convert against (when the file names none)\n` +
|
|
191
|
+
` --slides <sel> hydrate only these slides to editable jsx — '2,7',\n` +
|
|
192
|
+
` '2-4' or 'all'; every other slide stays a lossless\n` +
|
|
193
|
+
` native one-slide .pptx that keeps its notes,\n` +
|
|
194
|
+
` comments, animations and embeddings\n` +
|
|
136
195
|
` --no-convert fold every untagged slide as native .pptx instead\n` +
|
|
137
|
-
` slidemind
|
|
196
|
+
` slidemind adopt <deck>/.slidemind/slides/<NN-name>.pptx --in-place Convert ONE folded slide (add-slide) in place to\n` +
|
|
197
|
+
` editable jsx: same play position, the .pptx is replaced; a slide\n` +
|
|
198
|
+
` the add-in cannot convert stays native and nothing changes\n` +
|
|
199
|
+
` slidemind revision <sub> <deck> Local revision protocol for an ADOPTED deck: which bytes are the\n` +
|
|
200
|
+
` accepted base, and which build may replace them\n` +
|
|
201
|
+
` begin take ownership for a whole edit session; prints an\n` +
|
|
202
|
+
` owner token to export as SLIDEMIND_OWNER so nested\n` +
|
|
203
|
+
` commands and parallel lanes re-enter instead of blocking\n` +
|
|
204
|
+
` --operation targeted-edit|repair|redesign declare what this\n` +
|
|
205
|
+
` session may do; needs --slides <sel> (a scope with no\n` +
|
|
206
|
+
` slides would claim the deck). 'create' is a build's own\n` +
|
|
207
|
+
` inference for a new slide and is refused here.\n` +
|
|
208
|
+
` The operation PERMITS a named removal; it is not what\n` +
|
|
209
|
+
` makes a build a replacement — see build-pptx below.\n` +
|
|
210
|
+
` --scope <file.json> the elements and properties it may touch\n` +
|
|
211
|
+
` finish release it — work, candidates and journals are kept\n` +
|
|
212
|
+
` status accepted base, generation, dirty slides, added/removed,\n` +
|
|
213
|
+
` candidates, staged snapshots, conflicts, owner, journal\n` +
|
|
214
|
+
` accept --candidate <id>: make a validated local candidate the\n` +
|
|
215
|
+
` accepted base; refuses a stale candidate, a deck with\n` +
|
|
216
|
+
` unresolved conflicts, and a remote-bound deck\n` +
|
|
217
|
+
` --json machine-readable result (begin | status | accept)\n` +
|
|
218
|
+
` slidemind rebase <deck> [opts] Move an adopted deck onto a newer version of the same file:\n` +
|
|
219
|
+
` their edits, added/deleted slides and moves apply, reorders on both\n` +
|
|
220
|
+
` sides combine, local edits stay unpublished against the new base.\n` +
|
|
221
|
+
` Only a slide BOTH sides changed is a conflict, and it activates\n` +
|
|
222
|
+
` NOTHING — it writes a conflict manifest plus a resolution skeleton\n` +
|
|
223
|
+
` with every hash already filled in. There is deliberately no\n` +
|
|
224
|
+
` generic force flag\n` +
|
|
225
|
+
` --incoming <file.pptx|revisionId> the newer file, or a staged one\n` +
|
|
226
|
+
` --resolve <file.json> apply the filled-in resolution skeleton\n` +
|
|
227
|
+
` --dry-run classify only (incoming-only / local-only / unchanged /\n` +
|
|
228
|
+
` conflicts) and write the skeleton if any conflict\n` +
|
|
229
|
+
` --json machine-readable result\n` +
|
|
230
|
+
` (no flags) finish a rebase that was interrupted partway\n` +
|
|
231
|
+
` slidemind open <link|file> Open a SharePoint presentation as a deck: resolve the item the LINK\n` +
|
|
232
|
+
` names, take one consistent snapshot, adopt it, and bind the deck to\n` +
|
|
233
|
+
` that item. A local file path adopts only — it never infers where to\n` +
|
|
234
|
+
` publish. Metadata in the file never redirects the target\n` +
|
|
235
|
+
` --deck <slug> deck folder to write (default: the file's name)\n` +
|
|
236
|
+
` --slides <sel> hydrate only these slides to editable jsx (as adopt)\n` +
|
|
237
|
+
` --rebind point an already-bound deck at this item instead\n` +
|
|
238
|
+
` --ordinary classify unknown origin as ordinary (cannot remove gates)\n` +
|
|
239
|
+
` --companion id=<file|link> restore a hash-verified manual companion\n` +
|
|
240
|
+
` --keep local file: adopt these bytes, keep publishing where it does\n` +
|
|
241
|
+
` --detach local file: forget the binding, make it local-only\n` +
|
|
242
|
+
` --json machine-readable result\n` +
|
|
243
|
+
` slidemind pull <deck> Check the bound item and every independently mutable input it names.\n` +
|
|
244
|
+
` Unchanged costs one metadata call and downloads nothing. A newer save\n` +
|
|
245
|
+
` stages immutably and is merged in around unpublished local edits;\n` +
|
|
246
|
+
` only a slide both sides changed stops it (then: slidemind rebase)\n` +
|
|
247
|
+
` --check report freshness only (never stages, never rebases)\n` +
|
|
248
|
+
` --json machine-readable result\n` +
|
|
249
|
+
` slidemind publish <deck> Publish the accepted candidate back to the bound item: recover, pull,\n` +
|
|
250
|
+
` rebase, run every required extension's release checks on the FINAL\n` +
|
|
251
|
+
` bytes, then replace under a server-enforced expected revision. Only a\n` +
|
|
252
|
+
` confirmed receipt counts as saved; a 412 stages their save instead.\n` +
|
|
253
|
+
` build-pptx runs this itself for a connected deck; run it to retry one\n` +
|
|
254
|
+
` whose publish did not save. Unbound with no flags: the folder\n` +
|
|
255
|
+
` connected in the workspace is the first create's target\n` +
|
|
256
|
+
` --folder <link> --name <file.pptx> first create, refusing name conflicts\n` +
|
|
257
|
+
` --candidate <id> publish this candidate (default: the newest valid one)\n` +
|
|
258
|
+
` --manual prepare the validated handoff without any remote write\n` +
|
|
259
|
+
` --shared-workbook declare authority to replace a shared mutable input\n` +
|
|
260
|
+
` (without it a changed workbook FORKS, never overwrites)\n` +
|
|
261
|
+
` --json machine-readable result\n` +
|
|
262
|
+
` slidemind rename <deck> --name <file> Rename the bound item under its expected revision. Same item, no\n` +
|
|
263
|
+
` render, no second file; an existing name refuses\n` +
|
|
264
|
+
` --json machine-readable result\n` +
|
|
265
|
+
` slidemind workspace [<deck>] The user's workspace: one browser page with the deck library, plan\n` +
|
|
266
|
+
` and preview review, served by a detached daemon on 127.0.0.1 that\n` +
|
|
267
|
+
` outlives this shell; \`setup\` starts it at every login. \`plan\`/\`review\`\n` +
|
|
268
|
+
` ask there (SLIDEMIND_WORKSPACE=0 opts out). An answer given there\n` +
|
|
269
|
+
` copies a message the user pastes to their agent; it names the run\n` +
|
|
270
|
+
` that receives it\n` +
|
|
271
|
+
` (no sub) [<deck>] start or reuse the daemon, register <deck>, open the page only\n` +
|
|
272
|
+
` when none is open, print its sign-in link (Workspace: <link>)\n` +
|
|
273
|
+
` --no-open print the link only\n` +
|
|
274
|
+
` --foreground stay attached (when the environment forbids a detached process)\n` +
|
|
275
|
+
` start start it unless it runs — silent, never opens a browser (the login item runs this)\n` +
|
|
276
|
+
` status running | url | pages | protocolVersion | pendingJobs | reason\n` +
|
|
277
|
+
` stop drain local commits (<= 5s), keep queued remote work, exit\n` +
|
|
278
|
+
` add <path> register one deck folder\n` +
|
|
279
|
+
` discover <root> remember a root and scan it for decks (no symlinks, no scratch)\n` +
|
|
280
|
+
` list registered decks\n` +
|
|
281
|
+
` open-remote <url> resolve a SharePoint link (pptx | plan record | hosted page |\n` +
|
|
282
|
+
` folder); a folder answers a selection, never a guess\n` +
|
|
283
|
+
` select <jobId> --selection <id> --choice <id> pick one child of that selection\n` +
|
|
284
|
+
` connect <deck> --folder <url> [--name <file.pptx>] save the deck's SharePoint\n` +
|
|
285
|
+
` destination; the plan is created there once it is editable\n` +
|
|
286
|
+
` and the backend allows writes (destination-only until then)\n` +
|
|
287
|
+
` --json on every subcommand\n` +
|
|
288
|
+
` slidemind tasks <sub> Durable review tasks of a deck (survive agent exit; local, never published)\n` +
|
|
289
|
+
` list [<deck>] [--status pending] tasks of one deck or every registered deck\n` +
|
|
290
|
+
` (agents run \`slidemind plan\` / \`review\`; these are for packs and scripts)\n` +
|
|
291
|
+
` request <deck> --kind <k> plan-edit | plan-approval | preview-review;\n` +
|
|
292
|
+
` hashes the current subject, dedupes, prints the task, its\n` +
|
|
293
|
+
` view's sign-in link and the SAY line; returns at once\n` +
|
|
294
|
+
` get <deck> <id> the task and its verified outcome (records that you received it)\n` +
|
|
295
|
+
` wait <deck> <id> [--timeout 45] scripts only — saved answer first, else a\n` +
|
|
296
|
+
` bounded wait; {pending:true} means still waiting\n` +
|
|
297
|
+
` --json one JSON value on stdout, diagnostics on stderr\n` +
|
|
298
|
+
` Exit codes (workspace + tasks): 0 done or read (a pending wait included)\n` +
|
|
299
|
+
` | 1 operational error | 2 blocked, busy or incompatible | 3 conflict\n` +
|
|
300
|
+
` slidemind record <sub> Share ONE JSON file through the backend, which owns the merge:\n` +
|
|
301
|
+
` several people and their agents edit the same record and\n` +
|
|
302
|
+
` different fields combine instead of overwriting. The CLI never\n` +
|
|
303
|
+
` reads what is in the file — whichever pack owns the schema does\n` +
|
|
304
|
+
` create <deck> --folder <link> --name <file.json> --file <path>\n` +
|
|
305
|
+
` share the file into a SharePoint folder; prints the\n` +
|
|
306
|
+
` permanent link colleagues open\n` +
|
|
307
|
+
` open <link> --deck <slug> --file <path>\n` +
|
|
308
|
+
` fetch a shared record into a (new) deck workspace\n` +
|
|
309
|
+
` sync <deck> --file <path>\n` +
|
|
310
|
+
` send your version, get everyone's back merged into\n` +
|
|
311
|
+
` <path>; same-field clashes write\n` +
|
|
312
|
+
` state/record-conflicts.json and exit 3\n` +
|
|
313
|
+
` --approval also send the file's 'approval' field (stripped otherwise)\n` +
|
|
314
|
+
` --resolve <f> send this resolved version against the conflicts file\n` +
|
|
315
|
+
` status <deck> current | behind (v…) | local edits\n` +
|
|
316
|
+
` --json machine-readable result on every subcommand\n` +
|
|
317
|
+
` slidemind download-result [opts] Download image/icon search result(s) into a deck's assets/ (--name <file> to choose the asset's file name)\n` +
|
|
138
318
|
` --search <id> searchId from 'slidemind search'\n` +
|
|
139
319
|
` --pick <n,..> 1-based selection number(s)\n` +
|
|
140
320
|
` --deck <deck> deck to write the asset(s) into\n` +
|
|
141
321
|
` --to <presId> the window the search ran on (relayed path only)\n` +
|
|
142
322
|
` --icon-color <hex[,hex,..]> bake a colour into SVG result(s) (one for all, or one per --pick)\n` +
|
|
143
323
|
` --json machine-readable result (file, size, recolor per pick)\n` +
|
|
324
|
+
` slidemind assets <sub> The deck's image registry — immutable bytes, identified by their own\n` +
|
|
325
|
+
` digest. Registering an image creates NO obligation to place it:\n` +
|
|
326
|
+
` what it is FOR is an assetUses record in the plan, approved at the\n` +
|
|
327
|
+
` plan gate. Import BEFORE you plan — a use names an assetId.\n` +
|
|
328
|
+
` import <deck> <file> copy a file in (file paths only, never a URL),\n` +
|
|
329
|
+
` sniff its real format + size, verify and record it;\n` +
|
|
330
|
+
` the same bytes twice reuse the first assetId\n` +
|
|
331
|
+
` list <deck> what this deck has registered\n` +
|
|
332
|
+
` --json machine-readable result on both subcommands\n` +
|
|
333
|
+
` A use is original (place THESE bytes — never searched for, generated\n` +
|
|
334
|
+
` or substituted), reconstruct (rebuild it as editable slide content;\n` +
|
|
335
|
+
` reconstructionScope slide | element) or reference (the model sees it,\n` +
|
|
336
|
+
` no picture required). useId/assetId are durable — keep them byte-\n` +
|
|
337
|
+
` identical in plan.md, the spec and the slide's data-asset-use.\n` +
|
|
338
|
+
` view-draft reports unmet obligations; build-pptx/push refuse them.\n` +
|
|
339
|
+
` Needs an add-in advertising imageIntentV1 (else the command stops\n` +
|
|
340
|
+
` before generating, with image_intent_unsupported and nothing\n` +
|
|
341
|
+
` written). Decks with no assetUses are unaffected.\n` +
|
|
144
342
|
` slidemind imagen "<prompt>" Generate ONE image with the add-in's image model into a deck's assets/ (paired backend, pane-free)\n` +
|
|
145
343
|
` --deck <deck> bound deck to write the image into (required)\n` +
|
|
146
344
|
` --out <name> file name under assets/ (default imagen-N.png)\n` +
|
|
@@ -167,13 +365,18 @@ export function printHelp(cmd = null) {
|
|
|
167
365
|
` --at <index> insert after slide N (0-based); default = append\n` +
|
|
168
366
|
` --replace delete existing slides first (destructive)\n` +
|
|
169
367
|
` --slides <ids> comma-separated source slide ids to push\n` +
|
|
170
|
-
` --accept-conversions replace
|
|
171
|
-
` --force discard manual PowerPoint edits instead of reconciling them\n` +
|
|
368
|
+
` --accept-conversions replace an unconfirmed converted slide (only on the user's go-ahead)\n` +
|
|
369
|
+
` --force discard manual PowerPoint edits instead of reconciling them\n` + ` Refuses a slide whose recorded preservation obligations are unmet, same\n` +
|
|
370
|
+
` as build-pptx; view-draft is where they are reported and repaired.\n` +
|
|
371
|
+
` slidemind clean <deck> Delete the deck's regenerable renders (.slidemind/preview/ and\n` +
|
|
372
|
+
` abandoned .part downloads). Slides, assets, conversions, state,\n` +
|
|
373
|
+
` concepts and a download still in flight are never touched\n` +
|
|
172
374
|
` slidemind login Sign in to Microsoft 365 in your browser so SharePoint-backed\n` +
|
|
173
375
|
` slides and images download without an open PowerPoint window\n` +
|
|
174
|
-
`
|
|
175
|
-
`
|
|
176
|
-
`
|
|
376
|
+
` slidemind whoami Show the connection and its Microsoft 365 sign-in, named as\n` +
|
|
377
|
+
` the account that signed in\n` +
|
|
378
|
+
` --json machine-readable (microsoft365.username = that account)\n` +
|
|
379
|
+
` slidemind logout Disconnect the CLI (drops its Microsoft 365 sign-in too)\n` +
|
|
177
380
|
` slidemind init --for <t> Set up slidemind in a harness (deploys the skill; clears the bundle cache)\n` +
|
|
178
381
|
` <t> = claude | codex | opencode | all | auto (every harness found here)\n` +
|
|
179
382
|
` 'setup' already does this — only needed after installing a new agent\n` +
|
|
@@ -186,9 +389,10 @@ export function printHelp(cmd = null) {
|
|
|
186
389
|
` slidemind --version Print version\n` +
|
|
187
390
|
`\n` +
|
|
188
391
|
`Install targets: claude | codex | opencode | all\n` +
|
|
189
|
-
`Decks live in ./decks/ relative to your current directory
|
|
190
|
-
`
|
|
191
|
-
`
|
|
392
|
+
`Decks live in ./decks/ relative to your current directory. A deck keeps its\n` +
|
|
393
|
+
`deliverables at the root (<slug>.pptx, plan.html) and everything the CLI\n` +
|
|
394
|
+
`works with in <deck>/.slidemind/ — decks without it are used as-is.\n` +
|
|
395
|
+
`Override with env: SLIDEMIND_DECKS=/abs/path/to/decks\n`;
|
|
192
396
|
process.stdout.write(cmd ? commandBlock(text, cmd) : text);
|
|
193
397
|
}
|
|
194
398
|
|
package/src/cli/install.mjs
CHANGED
|
@@ -136,6 +136,15 @@ export async function cmdUninstall(rest) {
|
|
|
136
136
|
value: cleared ? `${cleared} bundle${cleared === 1 ? "" : "s"}` : "empty",
|
|
137
137
|
});
|
|
138
138
|
|
|
139
|
+
// Removing slidemind from every harness is removing it: the workspace's login
|
|
140
|
+
// item goes too (one harness out of several still needs it).
|
|
141
|
+
if (target === "all") {
|
|
142
|
+
const { removeAutostart } = await import("../workspace/autostart.mjs");
|
|
143
|
+
const r = removeAutostart();
|
|
144
|
+
await ui.section("workspace", "login item");
|
|
145
|
+
ui.step({ status: "remove", label: "at login", value: r.removed ? "removed" : "none" });
|
|
146
|
+
}
|
|
147
|
+
|
|
139
148
|
ui.done(target === "all" ? "removed from all harnesses" : `removed from ${target}`);
|
|
140
149
|
}
|
|
141
150
|
|