emberflow-skills 1.1.2 → 1.2.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/README.md CHANGED
@@ -1,46 +1,64 @@
1
1
  # Emberflow Skills
2
2
 
3
- Agent skills for publishing beautiful docs from your AI coding tools to [Emberflow](https://emberflow.ai).
3
+ Publish beautiful docs from your AI coding tools to [Emberflow](https://www.emberflow.ai) — architecture diagrams, tables, and markdown, hosted instantly.
4
4
 
5
- ## Quick Install
5
+ ## Install
6
+
7
+ The fastest way to get started:
6
8
 
7
9
  ```bash
8
10
  npx emberflow-skills
9
11
  ```
10
12
 
11
- Auto-detects Claude Code and Cursor projects and installs the skill to the right place.
13
+ That's it. The installer auto-detects your project type (Claude Code or Cursor) and copies the skill to the right directory. You'll be publishing docs in under 10 seconds.
14
+
15
+ ### Options
12
16
 
13
17
  ```bash
18
+ # Install to current project (default)
19
+ npx emberflow-skills
20
+
14
21
  # Install globally for Claude Code (available in all projects)
15
22
  npx emberflow-skills --global
16
23
  ```
17
24
 
18
- ## Available Skills
25
+ ### What the installer does
19
26
 
20
- ### `ember-publish`
27
+ 1. Detects if you're in a Claude Code project (`.claude/`) or Cursor project (`.cursor/`)
28
+ 2. Copies the `ember-publish` skill into your project's skills directory
29
+ 3. Done — use `/ember-publish` in your next conversation
21
30
 
22
- Publish markdown documents with Mermaid diagrams, syntax highlighting, tables, and inline comments.
31
+ ## Usage
23
32
 
24
- **Usage:** `/ember-publish architecture overview for the payments service`
33
+ In Claude Code or Cursor, just type:
25
34
 
26
- Your AI writes the doc, generates diagrams, and publishes it — you get back a shareable URL.
35
+ ```
36
+ /ember-publish architecture overview for the payments service
37
+ ```
27
38
 
28
- **Works with:** Claude Code, Cursor, Codex CLI, and any tool that supports the SKILL.md format.
39
+ Your AI writes the markdown, generates Mermaid diagrams, and publishes it. You get back a shareable URL.
29
40
 
30
- ## What Emberflow renders
41
+ ## What gets published
31
42
 
32
43
  - Live Mermaid diagrams with zoom, pan, and fullscreen
33
44
  - Syntax-highlighted code blocks (190+ languages)
34
45
  - Auto-generated table of contents
35
46
  - Per-block inline comments and discussions
36
47
  - Dark mode with font selection
48
+ - Public or private docs with secret links
37
49
 
38
- ## Manual Installation
50
+ ## Manual install
39
51
 
40
52
  If you prefer not to use npx:
41
53
 
42
54
  ```bash
43
- # Clone and copy
44
- git clone https://github.com/toptalPatrick/emberflow-skills.git
55
+ git clone https://github.com/pmccurley87/emberflow-skills.git
45
56
  cp -r emberflow-skills/skills/ember-publish .claude/skills/
46
57
  ```
58
+
59
+ ## Works with
60
+
61
+ - Claude Code
62
+ - Cursor
63
+ - Codex CLI
64
+ - Any tool that supports the SKILL.md format
package/bin/install.js CHANGED
@@ -7,9 +7,9 @@ const http = require('http');
7
7
  const readline = require('readline');
8
8
  const os = require('os');
9
9
 
10
- const SKILL_NAME = 'ember-publish';
11
- const SKILL_SRC = path.join(__dirname, '..', 'skills', SKILL_NAME, 'SKILL.md');
12
- const EMBERFLOW_URL = 'https://emberflow.ai';
10
+ const SKILL_NAMES = ['ember-publish', 'ember-publish-json'];
11
+ const SKILLS_DIR = path.join(__dirname, '..', 'skills');
12
+ const EMBERFLOW_URL = 'https://www.emberflow.ai';
13
13
  const TOKEN_PATH = path.join(os.homedir(), '.emberflow', 'token.json');
14
14
 
15
15
  const dim = (s) => `\x1b[2m${s}\x1b[0m`;
@@ -80,11 +80,14 @@ function sleep(ms) {
80
80
  // ── Skill installer ──
81
81
 
82
82
  function install(destDir, label) {
83
- const skillDir = path.join(destDir, SKILL_NAME);
84
- const destFile = path.join(skillDir, 'SKILL.md');
85
- fs.mkdirSync(skillDir, { recursive: true });
86
- fs.copyFileSync(SKILL_SRC, destFile);
87
- console.log(` ${green('✓')} Installed to ${path.relative(process.cwd(), skillDir) || skillDir} ${dim(`(${label})`)}`);
83
+ for (const name of SKILL_NAMES) {
84
+ const src = path.join(SKILLS_DIR, name, 'SKILL.md');
85
+ const skillDir = path.join(destDir, name);
86
+ const destFile = path.join(skillDir, 'SKILL.md');
87
+ fs.mkdirSync(skillDir, { recursive: true });
88
+ fs.copyFileSync(src, destFile);
89
+ console.log(` ${green('✓')} Installed ${name} to ${path.relative(process.cwd(), skillDir) || skillDir} ${dim(`(${label})`)}`);
90
+ }
88
91
  return true;
89
92
  }
90
93
 
@@ -151,8 +154,10 @@ async function authenticate() {
151
154
  const status = await request('GET', `${EMBERFLOW_URL}/api/device-code/${code}`);
152
155
 
153
156
  if (status.data.status === 'approved' && status.data.session_token) {
157
+ // Strip cookie name prefix if present (e.g. "__Secure-better-auth.session_token=VALUE" -> "VALUE")
158
+ const raw = status.data.session_token.replace(/^(?:__Secure-)?better-auth\.session_token=/, '');
154
159
  fs.mkdirSync(path.dirname(TOKEN_PATH), { recursive: true });
155
- fs.writeFileSync(TOKEN_PATH, JSON.stringify({ token: status.data.session_token }, null, 2));
160
+ fs.writeFileSync(TOKEN_PATH, JSON.stringify({ token: raw }, null, 2));
156
161
  process.stdout.clearLine(0);
157
162
  process.stdout.cursorTo(0);
158
163
  console.log(` ${green('✓')} Signed in! Token saved to ${dim('~/.emberflow/token.json')}`);
@@ -222,7 +227,7 @@ async function main() {
222
227
 
223
228
  if (installed > 0) {
224
229
  console.log();
225
- console.log(` Use: ${cyan('/ember-publish')} ${dim('[topic]')}`);
230
+ console.log(` Use: ${cyan('/ember-publish')} ${dim('[topic]')} or ${cyan('/ember-publish-json')} ${dim('[data]')}`);
226
231
  }
227
232
  }
228
233
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emberflow-skills",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Install Emberflow skills for AI coding tools",
5
5
  "bin": {
6
6
  "emberflow-skills": "./bin/install.js"
@@ -13,12 +13,14 @@
13
13
  "mcp",
14
14
  "ai",
15
15
  "documentation",
16
- "mermaid"
16
+ "mermaid",
17
+ "json",
18
+ "json-explorer"
17
19
  ],
18
20
  "author": "Patrick",
19
21
  "license": "MIT",
20
22
  "repository": {
21
23
  "type": "git",
22
- "url": "https://github.com/toptalPatrick/emberflow-skills"
24
+ "url": "https://github.com/pmccurley87/emberflow-skills"
23
25
  }
24
26
  }
@@ -184,6 +184,8 @@ The response JSON includes the URL. Documents are viewable at:
184
184
 
185
185
  To **update** an existing document, publish again with the same slug — the API upserts for the same author.
186
186
 
187
+ > **JSON documents**: You can also publish JSON data by passing `content_type: "json"` in the API payload. The content should be valid JSON (either raw data or the multi-payload format `{"payloads": [{"label": "...", "data": ...}]}`). Use the `/ember-publish-json` skill for a dedicated JSON publishing workflow.
188
+
187
189
  ### Other Operations
188
190
 
189
191
  ```bash
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: ember-publish-json
3
+ description: Publish JSON data to Emberflow as an interactive explorer with expand/collapse, search, and multi-payload tabs
4
+ argument-hint: [JSON file path, API response, or description of data to publish]
5
+ ---
6
+
7
+ # Emberflow JSON Publisher
8
+
9
+ Publish JSON data to Emberflow and view it in an interactive explorer at **https://emberflow.ai** with collapsible tree nodes, property search, copy values/paths, and multi-payload tabs.
10
+
11
+ ## Step 1: Prepare the JSON
12
+
13
+ Collect the JSON data to publish. This can be:
14
+ - A JSON file on disk
15
+ - An API response
16
+ - Multiple JSON payloads to compare side-by-side
17
+
18
+ ### Multi-Payload Format
19
+
20
+ To publish multiple JSON payloads as tabs, wrap them in this format:
21
+
22
+ ```json
23
+ {
24
+ "payloads": [
25
+ { "label": "API Response", "data": { ... } },
26
+ { "label": "Config", "data": { ... } }
27
+ ]
28
+ }
29
+ ```
30
+
31
+ If you publish a single JSON value (object, array, etc.) without the wrapper, the explorer will display it as a single "Data" tab.
32
+
33
+ ## Step 2: Authenticate (if needed)
34
+
35
+ Session tokens are stored at `~/.emberflow/token.json`. Check if a valid session exists:
36
+
37
+ ```bash
38
+ cat ~/.emberflow/token.json 2>/dev/null
39
+ ```
40
+
41
+ If the file exists, verify the token still works:
42
+
43
+ ```bash
44
+ curl -s -H "Authorization: Bearer $(jq -r .token ~/.emberflow/token.json)" \
45
+ https://emberflow.ai/api/docs
46
+ ```
47
+
48
+ If no session exists, it's expired, or the verify call returns 401, authenticate using the device flow:
49
+
50
+ ```bash
51
+ EMBERFLOW_URL="https://emberflow.ai"
52
+
53
+ # Step 1: Request a device code
54
+ RESP=$(curl -s -X POST "$EMBERFLOW_URL/api/device-code")
55
+ CODE=$(echo "$RESP" | jq -r .code)
56
+ URL=$(echo "$RESP" | jq -r .verification_url)
57
+ ```
58
+
59
+ Tell the user to open the URL in their browser to sign in and approve the device. Then poll until approved:
60
+
61
+ ```bash
62
+ # Step 2: Poll until approved (every 3s)
63
+ while true; do
64
+ STATUS=$(curl -s "$EMBERFLOW_URL/api/device-code/$CODE")
65
+ S=$(echo "$STATUS" | jq -r .status)
66
+ if [ "$S" = "approved" ]; then
67
+ TOKEN=$(echo "$STATUS" | jq -r .session_token)
68
+ mkdir -p ~/.emberflow
69
+ echo "{\"token\":\"$TOKEN\"}" > ~/.emberflow/token.json
70
+ break
71
+ fi
72
+ if [ "$S" = "expired" ]; then
73
+ echo "Code expired. Please try again."
74
+ break
75
+ fi
76
+ sleep 3
77
+ done
78
+ ```
79
+
80
+ ## Step 3: Publish
81
+
82
+ Generate a slug from a title and publish with `content_type: "json"`:
83
+
84
+ ```bash
85
+ EMBERFLOW_URL="https://emberflow.ai"
86
+ TITLE="My JSON Data"
87
+ SLUG=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/^-//;s/-$//')
88
+ TOKEN=$(jq -r .token ~/.emberflow/token.json)
89
+
90
+ # For a single JSON file:
91
+ JSON_FILE="/path/to/data.json"
92
+ CONTENT=$(cat "$JSON_FILE")
93
+
94
+ # For multiple payloads, wrap them:
95
+ # CONTENT=$(jq -n --argjson a "$(cat file1.json)" --argjson b "$(cat file2.json)" \
96
+ # '{payloads: [{label: "Response", data: $a}, {label: "Config", data: $b}]}')
97
+
98
+ curl -s -X POST "$EMBERFLOW_URL/api/docs" \
99
+ -H 'Content-Type: application/json' \
100
+ -H "Authorization: Bearer $TOKEN" \
101
+ -d "$(jq -n --arg slug "$SLUG" --arg title "$TITLE" --arg content "$CONTENT" \
102
+ '{slug: $slug, title: $title, content: $content, content_type: "json", visibility: "public"}')"
103
+ ```
104
+
105
+ The response JSON includes the URL. Documents are viewable at:
106
+ - `https://emberflow.ai/d/<shortId>/<slug>`
107
+
108
+ To **update** an existing JSON document, publish again with the same slug — the API upserts for the same author.
109
+
110
+ ### Other Operations
111
+
112
+ ```bash
113
+ # List all your documents
114
+ curl -s -H "Authorization: Bearer $TOKEN" "$EMBERFLOW_URL/api/docs"
115
+
116
+ # Delete a document
117
+ curl -s -X DELETE -H "Authorization: Bearer $TOKEN" "$EMBERFLOW_URL/api/docs/SLUG_HERE"
118
+ ```