@hypersocial/decks-cli 0.2.2 → 0.3.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/README.md CHANGED
@@ -2,12 +2,16 @@
2
2
 
3
3
  Command-line client for Hypersocial Decks live analytics and share management.
4
4
 
5
- Most users should install the friendlier package name:
5
+ Most users should start with the friendlier package name:
6
6
 
7
7
  ```bash
8
- npx hyperdecks whoami
8
+ npx hyperdecks init
9
9
  ```
10
10
 
11
+ `init` signs you in, installs the skill into your agents, sets up a voice,
12
+ builds and narrates a three-slide hello deck and prints its link. Re-running it
13
+ resumes where it stopped; `--json --yes` is the agent form.
14
+
11
15
  This package targets production by default:
12
16
 
13
17
  ```bash
@@ -128,7 +132,7 @@ normalize: hyper desk=hyperdecks
128
132
  ---
129
133
 
130
134
  ## hello
131
- hold: 1.1
135
+ hold: 1.5
132
136
  presenter: wave
133
137
 
134
138
  Hi, I'm Selçuk's mini avatar. [wave] This is Hyperdecks. [mood: excited]
@@ -137,6 +141,7 @@ Hi, I'm Selçuk's mini avatar. [wave] This is Hyperdecks. [mood: excited]
137
141
  - `## <slide-id>` is the slide's `<section id>` in `index.html`. Text before the first
138
142
  heading is notes for people and is ignored.
139
143
  - `hold`, `presenter` and `voice` lines directly under a heading are slide options.
144
+ `hold` is the pause in seconds after the line before the next slide (0.4 by default).
140
145
  - Sentences are the caption units, 4–85 characters each.
141
146
  - Stage tags (`[wave]`, `[mood: x]`, `[emote: x]`, `[reveal: x]`, `[play: x]`,
142
147
  `[pause: s]`, `[custom: name …]`) are not spoken. Each becomes a cue at the start
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypersocial/decks-cli",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
4
4
  "description": "Command-line client for Hypersocial Decks live analytics and share management.",
5
5
  "type": "module",
6
6
  "main": "./src/commands.mjs",
@@ -11,6 +11,32 @@ Hyperdecks is the CLI and MCP surface for Hypersocial Decks live analytics,
11
11
  recipient links, and deck activity. Treat real recipient activity, live deck
12
12
  stats, customer-facing links, and "what happened" questions as production work.
13
13
 
14
+ ## First run
15
+
16
+ When `hyperdecks whoami` says not authenticated, or `hyperdecks voice list`
17
+ shows no ready voice, run the first-run command instead of working around it:
18
+
19
+ ```bash
20
+ npx hyperdecks init --json --yes [--voice dash] [--name "<name>" --about "<one line>" --ask "<the ask>"]
21
+ ```
22
+
23
+ It signs in, installs this skill, scaffolds a three-slide hello deck from the
24
+ three answers, narrates it, releases one QA link and prints one JSON object
25
+ (`status`, `steps`, `slug`, `deckDir`, `shareUrl`, `next`). Re-running it
26
+ resumes where it stopped. Signed out, it first opens the sign-in page in the
27
+ user's browser and waits up to 3 minutes: tell them to finish signing in there
28
+ (a new account can be made on that page) before you run it, or have them run
29
+ `npx hyperdecks login` first. Inside a git repository it puts the deck in
30
+ `~/hyperdecks` rather than committing into that repository; `--dir` picks the
31
+ folder. Relay every step whose `status` is `needs-human` to the user, word for
32
+ word, and wait for them:
33
+
34
+ - deck: it needs `--name`, `--about` and `--ask`; ask the user, do not invent them;
35
+ - voice: cloning needs them to type their consent in a terminal (`hyperdecks
36
+ voice clone <file> --name <name>`), or to agree to the statement before you
37
+ call `clone_voice`. Never type or confirm consent for them. `--voice dash`
38
+ lets D.A.S.H., a character voice, present instead.
39
+
14
40
  ## Target Selection
15
41
 
16
42
  - Prefer production for real-world questions and actions. The published CLI is
@@ -69,6 +95,7 @@ Hyperdecks server; use the CLI where you have a shell and the tool otherwise.
69
95
  | One more link | `hyperdecks share new <slug> "<name>"` | `create_share` |
70
96
  | Who watched | `hyperdecks deck stats <slug>` | `deck_stats` |
71
97
  | All activity | `hyperdecks activity --deck <slug>` | `activity_overview` |
98
+ | What one person watched | `hyperdecks engagement "<name>" --deck <slug> --json` | `recipient_engagement` |
72
99
 
73
100
  ### 1. Ground it in the user's own material
74
101
 
@@ -81,6 +108,7 @@ Write `decks/<slug>/evidence.md` as you go: one row per fact with the slide, the
81
108
  claim, the source (file path, thread, doc title) and its date. Never put a
82
109
  number on a slide that has no row.
83
110
 
111
+ <!-- topic: format -->
84
112
  ### 2. Scaffold
85
113
 
86
114
  ```bash
@@ -126,6 +154,7 @@ The deck contract (`check` enforces each line):
126
154
  - Local images and files sit inside the deck folder and are referenced
127
155
  relatively (`img/chart.png`). Hosted images (`gen-image` URLs) are fine too.
128
156
 
157
+ <!-- topic: presenter -->
129
158
  #### Which presenter style
130
159
 
131
160
  Set the deck's on the player tag (`data-presenter-style="stage"`) or in
@@ -144,6 +173,45 @@ Below 650 px stage and glass become corner on their own. Run
144
173
  `hyperdecks check <deck> --layout` to be warned about any slide whose presenter
145
174
  would cover its title.
146
175
 
176
+ <!-- topic: transitions -->
177
+ #### Transitions
178
+
179
+ Every slide enters with `drift` unless it says otherwise. Use another only
180
+ where the slide's job matches its "use for"; never hand-write slide-change
181
+ animation in the deck's own JS (it fights the player's timing).
182
+
183
+ | Transition | Use for | What it does |
184
+ |---|---|---|
185
+ | `drift` (default) | most slides | the old slide drifts out, the new one in, its parts arriving title first |
186
+ | `cut` | a punchline, a fast beat | instant |
187
+ | `push` | the next step in a sequence | the new slide slides over; the old one sinks back and darkens |
188
+ | `wipe` | a new section | a band in the deck's second colour, then one in ink, sweeps across and leaves the new slide |
189
+ | `zoom <selector>` | going into the detail of one row, bar or card | the new slide opens out of that element on the slide before |
190
+ | `morph` (carry over) | a number or title on both slides | the element travels into its new place and size |
191
+ | `fly` | the deck's one big reveal | the presenter flies across and the new slide appears behind it |
192
+
193
+ Set the deck's in script.md's front matter (`transition: drift`) or on the
194
+ player tag (`data-transition`); a slide's under its `##` heading
195
+ (`transition: push`) or as `data-transition` on its `<section>`, which wins.
196
+ A slide's transition is how it enters; going back plays it in reverse.
197
+ A `transition:` in script.md reaches the player through the manifest, so it
198
+ takes effect after `narrate` (release runs it; nothing re-renders);
199
+ `data-transition` in index.html takes effect at once. Zoom
200
+ names its target on the slide before: `transition: zoom #dash-row`. Morph
201
+ pairs elements by name: put `data-morph="saved"` on the element on both
202
+ slides. Reduced motion turns every one into a short crossfade, and the
203
+ narration never waits for a transition.
204
+
205
+ `check` fails an unknown name, a `zoom` with no selector or one that matches
206
+ nothing on the slide before, a `morph` with no `data-morph` name on both
207
+ slides, and a second `fly`. It warns when a deck uses more than two kinds
208
+ besides its default: pick one or two and keep them for the same job.
209
+
210
+ Viewers can poke the live head: a click or tap makes it react (an "oof", a
211
+ flinch) and a drag pulls it a little before it springs back, without pausing
212
+ the narration.
213
+
214
+ <!-- topic: design -->
147
215
  ### Design: make it look good
148
216
 
149
217
  A narrated deck is only as convincing as it looks. Design before you write the
@@ -256,6 +324,7 @@ If review cannot run (no credits, the service is down), say so to the user and
256
324
  do the step 6 screenshot pass yourself as the reviewer: the same desktop and
257
325
  phone screenshots, the same `fix` bar.
258
326
 
327
+ <!-- topic: script -->
259
328
  ### 3. Write slides and script
260
329
 
261
330
  - One idea per slide; the title states it.
@@ -264,7 +333,7 @@ phone screenshots, the same `fix` bar.
264
333
  - Narration: short phrases, each sentence one caption of 4 to 85 characters
265
334
  (two lines in the bubble). Aim for 2.5 to 3 minutes in all; `maxTotalSeconds`
266
335
  in the front matter is the cap check uses (180 in the scaffold).
267
- - Holds: 1.1 s by default; `hold: 2` under the heading on interactive slides.
336
+ - Holds: 0.4 s by default. Give a slide `hold: 1.5` when the viewer needs time to read a number, a chart or a reveal, and `hold: 2` on interactive slides.
268
337
  - Cues: `[reveal: #id]` reveals `.reveal#id` at the word before it; also
269
338
  `[wave]`, `[mood: excited]`, `[pause: 0.5]`, `[custom: name]`.
270
339
  - Moves, to point at part of a slide: `[go: <selector>]` flies the presenter
@@ -305,6 +374,7 @@ A slide fails when the transcript does not match the script: read the error,
305
374
  reword the sentence (spell numbers and names the way they are said, or add a
306
375
  `normalize:` entry), and narrate again; only that slide re-renders.
307
376
 
377
+ <!-- topic: check -->
308
378
  ### 5. Check
309
379
 
310
380
  ```bash
@@ -340,6 +410,12 @@ an internal codename). Messages and what to do:
340
410
  | `slide <id>: title … needs a data-title-mobile` | add a shorter title |
341
411
  | `… presenter style "…" is not one of` | use stage, bubble, glass or corner |
342
412
  | `script.md line N: [go: …] matches nothing in slide <id>` | fix the selector, or add the element to that slide |
413
+ | `… transition "…" is not one of` | use drift, cut, push, wipe, zoom `<selector>`, morph or fly |
414
+ | `slide <id>: zoom target "…" matches nothing on the slide before it` | point the zoom at an element of the previous slide, or give that element the id |
415
+ | `slide <id>: morph needs an element with the same data-morph` | put `data-morph="<name>"` on the carried element on both slides, or use drift |
416
+ | `script.md says transition "…" but the manifest has "…"` | run `narrate` (no audio re-renders), or release, which runs it |
417
+ | `fly is for the deck's one big moment` | keep `fly` on one slide; use drift or push on the others |
418
+ | ⚠ `N kinds of transition besides the default` | use one or two kinds, each for its own job |
343
419
  | `slide <id>: its content runs …px past the slide on a 390×844 phone` | trim that slide on phones: smaller type, fewer items, or hide decoration in its `@media (max-width: 650px)` rules (an `#id` rule outranks them; restate it there) |
344
420
  | ⚠ `slide <id>: the … presenter would overlap the title` | move that slide's `.narration-slot`, pad the text away from it, or use `corner` |
345
421
 
@@ -396,6 +472,42 @@ hyperdecks activity --deck <slug> --limit 10
396
472
  Tell the user who opened it, how far they got and whether the narration
397
473
  finished. QA links never count.
398
474
 
475
+ ### 9. Follow up with a recipient
476
+
477
+ When the user wants to follow up with someone, read what that person watched:
478
+
479
+ ```bash
480
+ hyperdecks engagement "<name>" --deck <slug> --json # MCP: recipient_engagement
481
+ ```
482
+
483
+ Then draft the email:
484
+
485
+ 1. Lead with the slide they spent most time on (`summary.mostTime`) or
486
+ replayed (`replayedSlides`), and answer what that slide raises. Each
487
+ slide's `title` says what it is about.
488
+ 2. If they dropped off (`droppedOffOn`), offer the rest briefly, or a
489
+ 2-minute call, rather than asking them to rewatch.
490
+ 3. If they never opened it (`summary.visits` is 0), write a short nudge
491
+ instead.
492
+
493
+ Use what you know beyond the data: the email thread, who the person is, what
494
+ was promised, and the user's voice. Never tell the recipient they were
495
+ tracked: no "I saw you watched slide 7 three times", no percentages. The
496
+ signal decides what to talk about; it is never something to quote. Put the
497
+ draft in the user's mail tool (or show the text) and never send it without the
498
+ user's go-ahead. `null` means a field was not recorded for that visit (older
499
+ links), not zero.
500
+
501
+ ### Hosted source (chat agents and the connector)
502
+
503
+ A deck can also live on Hyperdecks with no folder: chat agents build it through
504
+ the hosted MCP (`deck_guide`, `new_deck`, `get_deck_source`, `write_deck_source`,
505
+ `upload_deck_asset`, `check_deck`, `release_deck`; see `chat.md`). Move between
506
+ the two with `hyperdecks source pull <slug> [dir]` (the hosted draft into a
507
+ folder) and `hyperdecks source push <slug> [dir]` (a folder's files back to the
508
+ draft), `hyperdecks asset add <slug> <file|url>` for an image, `hyperdecks guide
509
+ [topic]` for these sections, and `--hosted` on `deck new`, `check` and `release`.
510
+
399
511
  ## Safety
400
512
 
401
513
  - For read-only inspection, run commands directly and summarize the important
@@ -0,0 +1,49 @@
1
+ # Hyperdecks from a chat app (hosted MCP)
2
+
3
+ You are building a narrated deck through the Hyperdecks connector: no terminal,
4
+ no git, no folder. The deck's files (`index.html`, `script.md`, `evidence.md`)
5
+ live on Hyperdecks as a draft; you read and edit them with tools, and nothing
6
+ reaches a recipient until `release_deck`. Topics: call `deck_guide` with
7
+ `format`, `script`, `design`, `layouts`, `presenter`, `transitions` or `check`
8
+ before the step that needs it.
9
+
10
+ ## The loop
11
+
12
+ 1. `deck_guide` (this page), then `deck_guide { topic: "layouts" }` to pick slides.
13
+ 2. `new_deck { slug, title, layouts }`: registers your draft and returns the
14
+ full text of every file plus a `previewUrl` (the draft, untracked).
15
+ 3. Images: `generate_image`, `render_chart`, `capture_url`, or
16
+ `upload_deck_asset` for a picture the user gave you (a URL, or a file they
17
+ uploaded). Each returns a hosted URL: put that URL in the HTML. A hosted deck
18
+ has no folder, so a relative path like `img/a.png` is an error.
19
+ 4. `write_deck_source` to change a file: `edits: [{ find, replace }]` with
20
+ exact text that occurs once (copy it from `get_deck_source`), or `content`
21
+ to replace the file. Pass `baseRev` (the `rev` you last read) so a
22
+ concurrent edit fails instead of being overwritten.
23
+ 5. `check_deck { slug }` until it passes (the narration errors clear in step 6).
24
+ 6. `narrate_deck { slug }` with no `script` narrates the stored `script.md`;
25
+ poll `check_narration_job` until `done`. The draft's player tag then has its
26
+ `data-manifest`. No voice of their own yet? Pass `voice: "dash"`.
27
+ 7. `check_deck { slug }` again, then `review_deck { slug, draft: true }` and
28
+ `check_review_job`: it shoots desktop and 390×844 phone frames, which is how
29
+ you catch a slide that overflows a phone (the hosted check cannot measure
30
+ layout).
31
+ 8. `release_deck { slug, qa: true }` gives the user a QA link to watch first.
32
+ `release_deck { slug, recipients: [{ recipient, email }] }` makes one
33
+ tracked link each. Release creates live links: confirm the recipients with
34
+ the user before you call it.
35
+ 9. Later: `list_shares`, `deck_stats`, `activity_overview`.
36
+
37
+ ## Rules that matter
38
+
39
+ - Every slide is `<section class="slide" id="…" data-note="<source of its facts>">`,
40
+ in the same order as the `## <id>` blocks in `script.md`.
41
+ - Keep the player script tag and the `<style data-hd-loading>` block the
42
+ scaffold wrote; never write `data-manifest` yourself.
43
+ - Edit the draft freely: recipients keep seeing the last release until you call
44
+ `release_deck` again. A release is refused when the check fails, when
45
+ narration is stale (narrate again first), or when the draft changed after
46
+ the check.
47
+ - Files are capped at 800 KB each: use hosted image URLs, never inline base64.
48
+ - Facts come from the user's material; put the source of each in `evidence.md`
49
+ and the slide's `data-note`.