@hypersocial/decks-cli 0.1.1 → 0.1.3

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,6 +2,12 @@
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:
6
+
7
+ ```bash
8
+ pnpm dlx hyperdecks whoami
9
+ ```
10
+
5
11
  This package targets production by default:
6
12
 
7
13
  ```bash
@@ -10,6 +16,7 @@ pnpm dlx @hypersocial/decks-cli whoami
10
16
  pnpm dlx @hypersocial/decks-cli deck list
11
17
  pnpm dlx @hypersocial/decks-cli deck stats netflix
12
18
  pnpm dlx @hypersocial/decks-cli activity --limit 20
19
+ pnpm dlx @hypersocial/decks-cli skills install
13
20
  ```
14
21
 
15
22
  Global install:
@@ -54,6 +61,7 @@ share rm <token>
54
61
  share url <token>
55
62
 
56
63
  recipient archive|unarchive <name>
64
+ skills install [--path <dir>] [--force]
57
65
  activity [--deck <slug>] [--limit <n>] [--json]
58
66
  ```
59
67
 
package/package.json CHANGED
@@ -1,8 +1,19 @@
1
1
  {
2
2
  "name": "@hypersocial/decks-cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Command-line client for Hypersocial Decks live analytics and share management.",
5
5
  "type": "module",
6
+ "main": "./src/commands.mjs",
7
+ "exports": {
8
+ ".": "./src/commands.mjs",
9
+ "./commands": "./src/commands.mjs",
10
+ "./ops": "./src/ops.mjs",
11
+ "./runtime": "./src/runtime.mjs",
12
+ "./src/commands.mjs": "./src/commands.mjs",
13
+ "./src/ops.mjs": "./src/ops.mjs",
14
+ "./src/runtime.mjs": "./src/runtime.mjs",
15
+ "./package.json": "./package.json"
16
+ },
6
17
  "license": "UNLICENSED",
7
18
  "bin": {
8
19
  "decks": "bin/decks.mjs"
@@ -10,6 +21,7 @@
10
21
  "files": [
11
22
  "bin/",
12
23
  "src/",
24
+ "skills/",
13
25
  "README.md"
14
26
  ],
15
27
  "engines": {
@@ -0,0 +1,55 @@
1
+ ---
2
+ name: hyperdecks
3
+ description: Use when working with Hypersocial Decks, Hyperdecks CLI, production deck analytics, recipient share links, deck activity, MCP deck tools, or real-world/customer-facing deck checks. Prefer production for real activity and analytics; use development only for local implementation/testing when explicitly requested.
4
+ ---
5
+
6
+ # Hyperdecks
7
+
8
+ ## Overview
9
+
10
+ Hyperdecks is the CLI and MCP surface for Hypersocial Decks live analytics,
11
+ recipient links, and deck activity. Treat real recipient activity, live deck
12
+ stats, customer-facing links, and "what happened" questions as production work.
13
+
14
+ ## Target Selection
15
+
16
+ - Prefer production for real-world questions and actions. The published CLI is
17
+ prod-first, so `hyperdecks whoami`, `hyperdecks deck list`, and
18
+ `hyperdecks activity` already target prod.
19
+ - Use development only for implementation/testing when the user explicitly asks
20
+ for dev/local behavior. Dev requires a Convex URL with `--dev --convex <url>`
21
+ or `HSDECKS_CONVEX_URL`.
22
+ - Do not use `decks.localhost` for production checks.
23
+
24
+ ## CLI Workflow
25
+
26
+ Use the installed CLI when available:
27
+
28
+ ```bash
29
+ hyperdecks whoami
30
+ hyperdecks deck list
31
+ hyperdecks activity --limit 10
32
+ hyperdecks deck stats <slug>
33
+ hyperdecks share list <slug>
34
+ ```
35
+
36
+ If the CLI is missing, recommend:
37
+
38
+ ```bash
39
+ pnpm dlx hyperdecks <command>
40
+ ```
41
+
42
+ If authentication is missing, run or ask the user to run:
43
+
44
+ ```bash
45
+ hyperdecks login
46
+ ```
47
+
48
+ ## Safety
49
+
50
+ - For read-only inspection, run commands directly and summarize the important
51
+ output.
52
+ - For share creation, revocation, deletion, recipient archive/unarchive, or other
53
+ live changes, state the action and target clearly before executing when user
54
+ intent is ambiguous.
55
+ - Avoid printing full share tokens unless the user needs the exact URL/token.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Hyperdecks"
3
+ short_description: "Use prod Hyperdecks CLI and MCP safely"
4
+ default_prompt: "Use $hyperdecks to inspect production deck activity."
package/src/commands.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { login, logout, openBrowser, parse, target, VERSION } from "./runtime.mjs";
1
+ import { installHyperdecksSkill, login, logout, openBrowser, parse, target, VERSION } from "./runtime.mjs";
2
2
  import * as ops from "./ops.mjs";
3
3
 
4
4
  const fmtMs = (ms) => (ms >= 60000 ? `${(ms / 60000).toFixed(1)}m` : `${Math.round(ms / 1000)}s`);
@@ -155,6 +155,8 @@ commands:
155
155
  deck list|stats|open
156
156
  share new|list|on|off|rm|url
157
157
  recipient archive|unarchive
158
+ skill install [--path <dir>] [--force]
159
+ skills install [--path <dir>] [--force]
158
160
  activity [--deck <slug>] [--limit <n>] [--json]
159
161
 
160
162
  global:
@@ -193,6 +195,8 @@ export async function runCli(argv = process.argv.slice(2)) {
193
195
  "share url": () => shareUrl(rest, opts),
194
196
  "recipient archive": () => recipientArchive(rest, opts, true),
195
197
  "recipient unarchive": () => recipientArchive(rest, opts, false),
198
+ "skill install": () => installHyperdecksSkill(opts),
199
+ "skills install": () => installHyperdecksSkill(opts),
196
200
  activity: () => activity(pos.slice(1), opts),
197
201
  };
198
202
 
package/src/runtime.mjs CHANGED
@@ -1,13 +1,14 @@
1
1
  import { execFile } from "node:child_process";
2
2
  import { createHash, randomBytes } from "node:crypto";
3
3
  import { createServer } from "node:http";
4
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
+ import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
5
5
  import { homedir } from "node:os";
6
- import { join } from "node:path";
6
+ import { dirname, join } from "node:path";
7
+ import { fileURLToPath } from "node:url";
7
8
  import { ConvexHttpClient } from "convex/browser";
8
9
  import { makeFunctionReference } from "convex/server";
9
10
 
10
- export const VERSION = "0.1.1";
11
+ export const VERSION = "0.1.3";
11
12
 
12
13
  export const PROD = {
13
14
  name: "prod",
@@ -37,10 +38,12 @@ export const api = {
37
38
  },
38
39
  };
39
40
 
40
- const BOOL = new Set(["prod", "dev", "json", "require-email", "help", "version"]);
41
+ const BOOL = new Set(["prod", "dev", "json", "require-email", "help", "version", "force"]);
41
42
 
42
43
  export const CRED_DIR = join(homedir(), ".config", "hypersocial-decks");
43
44
  export const CRED_FILE = join(CRED_DIR, "credentials.json");
45
+ const SRC_DIR = dirname(fileURLToPath(import.meta.url));
46
+ const PACKAGED_SKILL_DIR = join(SRC_DIR, "..", "skills", "hyperdecks");
44
47
 
45
48
  export function parse(args) {
46
49
  const opts = {};
@@ -167,6 +170,31 @@ export function openBrowser(url) {
167
170
  execFile(cmd, args, () => {});
168
171
  }
169
172
 
173
+ export function defaultSkillRoot() {
174
+ return process.env.CODEX_HOME ? join(process.env.CODEX_HOME, "skills") : join(homedir(), ".codex", "skills");
175
+ }
176
+
177
+ export function installHyperdecksSkill(opts = {}) {
178
+ const root = opts.path || opts.dir || defaultSkillRoot();
179
+ const dest = join(root, "hyperdecks");
180
+ if (!existsSync(PACKAGED_SKILL_DIR)) {
181
+ throw new Error(`packaged hyperdecks skill not found at ${PACKAGED_SKILL_DIR}`);
182
+ }
183
+ if (existsSync(dest)) {
184
+ if (!opts.force) {
185
+ console.log(`hyperdecks skill already installed at ${dest}`);
186
+ console.log("Run `hyperdecks skills install --force` to refresh it.");
187
+ return { installed: false, path: dest };
188
+ }
189
+ rmSync(dest, { recursive: true, force: true });
190
+ }
191
+ mkdirSync(root, { recursive: true });
192
+ cpSync(PACKAGED_SKILL_DIR, dest, { recursive: true });
193
+ console.log(`OK installed hyperdecks skill to ${dest}`);
194
+ console.log("Restart Codex or start a new session if the skill list is already loaded.");
195
+ return { installed: true, path: dest };
196
+ }
197
+
170
198
  async function verifyAndStampEmail(t, opts) {
171
199
  const c = await client(opts);
172
200
  const who = await c.query(api.decks.whoami, {});