@viberaven/cli 1.1.8 → 1.1.10

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.
Files changed (40) hide show
  1. package/AGENTS.md +62 -157
  2. package/LICENSE +21 -21
  3. package/README.md +94 -128
  4. package/dist/cli.js +2328 -15978
  5. package/dist/extension-icon.png +0 -0
  6. package/package.json +16 -23
  7. package/MCP.md +0 -34
  8. package/SECURITY.md +0 -53
  9. package/SKILL.md +0 -69
  10. package/assets/report/assets/provider-authjs.svg +0 -5
  11. package/assets/report/assets/provider-aws.svg +0 -5
  12. package/assets/report/assets/provider-logrocket.svg +0 -4
  13. package/assets/report/assets/viberaven-logo.png +0 -0
  14. package/assets/report/report-cli.css +0 -1466
  15. package/assets/report/station.css +0 -11854
  16. package/assets/report/station.js +0 -8319
  17. package/dist/cli.js.map +0 -7
  18. package/dist/console/app.js +0 -251
  19. package/dist/console/index.html +0 -46
  20. package/dist/console/styles.css +0 -267
  21. package/dist/playbooks/_stack-default.json +0 -11
  22. package/dist/playbooks/auth-supabase.json +0 -31
  23. package/dist/playbooks/stripe.json +0 -60
  24. package/dist/playbooks/supabase.json +0 -51
  25. package/dist/playbooks/vercel.json +0 -42
  26. package/dist/report/assets/provider-authjs.svg +0 -5
  27. package/dist/report/assets/provider-aws.svg +0 -5
  28. package/dist/report/assets/provider-logrocket.svg +0 -4
  29. package/dist/report/assets/viberaven-logo.png +0 -0
  30. package/dist/report/report-cli.css +0 -1466
  31. package/dist/report/station.css +0 -11854
  32. package/dist/report/station.js +0 -8319
  33. package/playbooks/_stack-default.json +0 -11
  34. package/playbooks/auth-supabase.json +0 -31
  35. package/playbooks/stripe.json +0 -60
  36. package/playbooks/supabase.json +0 -51
  37. package/playbooks/vercel.json +0 -42
  38. package/templates/AGENTS.snippet.md +0 -52
  39. package/templates/CLAUDE.snippet.md +0 -17
  40. package/templates/CURSOR.snippet.md +0 -17
@@ -1,251 +0,0 @@
1
- const endpoint = window.__VIBERAVEN_ACTIONS_ENDPOINT__ || '/api/actions';
2
- const commandEndpoint = '/api/command';
3
-
4
- const nodes = {
5
- actions: document.getElementById('actions'),
6
- actionCount: document.getElementById('actionCount'),
7
- artifactPath: document.getElementById('artifactPath'),
8
- gateStatus: document.getElementById('gateStatus'),
9
- generatedAt: document.getElementById('generatedAt'),
10
- message: document.getElementById('message'),
11
- refreshButton: document.getElementById('refreshButton'),
12
- };
13
-
14
- function text(value, fallback = '-') {
15
- if (value === undefined || value === null || value === '') return fallback;
16
- return String(value);
17
- }
18
-
19
- function payloadToText(value) {
20
- if (Array.isArray(value)) return value.join('\n');
21
- if (value && typeof value === 'object') return JSON.stringify(value, null, 2);
22
- return text(value, '');
23
- }
24
-
25
- async function copyPayload(value, button) {
26
- const content = payloadToText(value);
27
- const previous = button ? button.textContent : '';
28
-
29
- try {
30
- await navigator.clipboard.writeText(content);
31
- } catch {
32
- if (!button) return;
33
-
34
- button.textContent = 'Copy failed';
35
- window.setTimeout(() => {
36
- button.textContent = previous;
37
- }, 1200);
38
- return;
39
- }
40
-
41
- if (!button) return;
42
-
43
- button.textContent = 'Copied';
44
- button.disabled = true;
45
- window.setTimeout(() => {
46
- button.textContent = previous;
47
- button.disabled = false;
48
- }, 900);
49
- }
50
-
51
- function clearChildren(node) {
52
- while (node.firstChild) node.removeChild(node.firstChild);
53
- }
54
-
55
- function appendText(parent, className, value) {
56
- const node = document.createElement('p');
57
- node.className = className;
58
- node.textContent = value;
59
- parent.appendChild(node);
60
- return node;
61
- }
62
-
63
- function appendPill(parent, value, className = '') {
64
- const pill = document.createElement('span');
65
- pill.className = `pill ${className}`.trim();
66
- pill.textContent = value;
67
- parent.appendChild(pill);
68
- return pill;
69
- }
70
-
71
- function appendButton(parent, label, value) {
72
- const button = document.createElement('button');
73
- button.className = 'button secondary';
74
- button.type = 'button';
75
- button.textContent = label;
76
- button.addEventListener('click', () => copyPayload(value, button));
77
- parent.appendChild(button);
78
- return button;
79
- }
80
-
81
- function appendVerifyButton(parent, action, output) {
82
- const button = document.createElement('button');
83
- button.className = 'button secondary';
84
- button.type = 'button';
85
- const token = window.__VIBERAVEN_TOKEN__ || '';
86
- button.textContent = token ? 'Verify' : 'Verify unavailable';
87
- button.disabled = !token;
88
- button.addEventListener('click', async () => {
89
- if (!token) return;
90
-
91
- const previous = button.textContent;
92
- button.disabled = true;
93
- button.textContent = 'Verifying';
94
- output.hidden = false;
95
- output.textContent = 'Running verification...';
96
-
97
- try {
98
- const response = await fetch(commandEndpoint, {
99
- method: 'POST',
100
- headers: {
101
- 'Content-Type': 'application/json',
102
- Authorization: `Bearer ${window.__VIBERAVEN_TOKEN__ || ''}`,
103
- },
104
- body: JSON.stringify({ type: 'verify-action', actionId: action.id }),
105
- });
106
- const body = await response.json();
107
- if (!response.ok || !body.ok) {
108
- output.textContent = body && body.error ? body.error : 'Verification failed.';
109
- return;
110
- }
111
-
112
- const result = body.result || {};
113
- const outputParts = [];
114
- outputParts.push(`Exit code: ${text(result.exitCode, 'unknown')}`);
115
- if (result.stdout) outputParts.push(result.stdout);
116
- if (result.stderr) outputParts.push(result.stderr);
117
- output.textContent = outputParts.join('\n\n');
118
- } catch (error) {
119
- output.textContent = error instanceof Error ? error.message : 'Verification failed.';
120
- } finally {
121
- button.disabled = false;
122
- button.textContent = previous;
123
- }
124
- });
125
- parent.appendChild(button);
126
- return button;
127
- }
128
-
129
- function actionProvider(action) {
130
- return action.provider || (action.target && action.target.provider) || '';
131
- }
132
-
133
- function renderAction(action) {
134
- const card = document.createElement('article');
135
- card.className = 'action-card';
136
-
137
- const header = document.createElement('div');
138
- header.className = 'action-header';
139
- card.appendChild(header);
140
-
141
- const titleRow = document.createElement('div');
142
- titleRow.className = 'action-title-row';
143
- header.appendChild(titleRow);
144
-
145
- const title = document.createElement('h2');
146
- title.className = 'action-title';
147
- title.textContent = `${text(action.id)}: ${text(action.title, 'Untitled action')}`;
148
- titleRow.appendChild(title);
149
- appendPill(titleRow, text(action.status), 'status');
150
-
151
- const meta = document.createElement('div');
152
- meta.className = 'meta-row';
153
- header.appendChild(meta);
154
- appendPill(meta, text(action.kind, 'action'));
155
- appendPill(meta, text(action.primaryControl, 'none'));
156
- const provider = actionProvider(action);
157
- if (provider) appendPill(meta, provider);
158
-
159
- const target = document.createElement('section');
160
- card.appendChild(target);
161
- appendText(target, 'section-label', 'Target');
162
- appendText(target, 'target', `${text(action.target && action.target.label)} ${text(action.target && action.target.value, '')}`.trim());
163
-
164
- const readiness = document.createElement('section');
165
- card.appendChild(readiness);
166
- const readinessLabel = appendText(readiness, 'section-label', 'Readiness');
167
- const readinessItems = Array.isArray(action.readiness) ? action.readiness : [];
168
- readinessLabel.textContent = `Readiness (${readinessItems.length})`;
169
- if (readinessItems.length > 0) {
170
- const list = document.createElement('ul');
171
- list.className = 'readiness-list';
172
- readinessItems.slice(0, 5).forEach((item) => {
173
- const li = document.createElement('li');
174
- li.textContent = text(item);
175
- list.appendChild(li);
176
- });
177
- readiness.appendChild(list);
178
- } else {
179
- appendPill(readiness, 'No readiness evidence', 'ready');
180
- }
181
-
182
- const payload = Array.isArray(action.copyPayloads) ? action.copyPayloads[0] : undefined;
183
- const payloadSection = document.createElement('section');
184
- card.appendChild(payloadSection);
185
- appendText(payloadSection, 'section-label', payload ? `Copy: ${text(payload.label)}` : 'Copy payload');
186
- const commandBox = document.createElement('pre');
187
- commandBox.className = 'command-box';
188
- commandBox.textContent = payload ? payloadToText(payload.value) : 'No copy payload provided.';
189
- payloadSection.appendChild(commandBox);
190
-
191
- const footer = document.createElement('div');
192
- footer.className = 'action-footer';
193
- card.appendChild(footer);
194
- if (payload) appendButton(footer, `Copy ${text(payload.label, 'Payload')}`, payload.value);
195
- const verifyOutput = document.createElement('pre');
196
- verifyOutput.className = 'command-box';
197
- verifyOutput.hidden = true;
198
- if (action.verify && action.id) appendVerifyButton(footer, action, verifyOutput);
199
- if (action.resumeInstruction) appendButton(footer, 'Copy Resume', action.resumeInstruction);
200
- card.appendChild(verifyOutput);
201
-
202
- return card;
203
- }
204
-
205
- function renderState(state) {
206
- clearChildren(nodes.actions);
207
- nodes.message.hidden = true;
208
- nodes.message.textContent = '';
209
-
210
- nodes.artifactPath.textContent = text(state.artifactPath);
211
- if (!state.ok) {
212
- nodes.gateStatus.textContent = text(state.reason, 'Unavailable');
213
- nodes.actionCount.textContent = '0';
214
- nodes.generatedAt.textContent = '-';
215
- nodes.message.textContent = text(state.message, 'Unable to load VibeRaven actions.');
216
- nodes.message.hidden = false;
217
- return;
218
- }
219
-
220
- nodes.gateStatus.textContent = text(state.gateStatus);
221
- nodes.actionCount.textContent = String(state.actions.length);
222
- nodes.generatedAt.textContent = text(state.generatedAt);
223
- state.actions.forEach((action) => nodes.actions.appendChild(renderAction(action)));
224
- }
225
-
226
- async function refreshActions() {
227
- nodes.refreshButton.disabled = true;
228
- nodes.refreshButton.textContent = 'Refreshing';
229
- try {
230
- const response = await fetch(endpoint, { headers: { Accept: 'application/json' } });
231
- const state = await response.json();
232
- renderState(state);
233
- } catch (error) {
234
- clearChildren(nodes.actions);
235
- nodes.message.textContent = error instanceof Error ? error.message : 'Unable to load VibeRaven actions.';
236
- nodes.message.hidden = false;
237
- } finally {
238
- nodes.refreshButton.disabled = false;
239
- nodes.refreshButton.textContent = 'Refresh';
240
- }
241
- }
242
-
243
- nodes.refreshButton.addEventListener('click', refreshActions);
244
-
245
- if ('EventSource' in window) {
246
- const events = new EventSource('/api/events');
247
- events.addEventListener('actions', refreshActions);
248
- events.addEventListener('error', () => {});
249
- }
250
-
251
- refreshActions();
@@ -1,46 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>VibeRaven Console</title>
7
- <link rel="stylesheet" href="/styles.css" />
8
- <script>
9
- window.__VIBERAVEN_ACTIONS_ENDPOINT__ = "/api/actions";
10
- </script>
11
- <script defer src="/app.js"></script>
12
- </head>
13
- <body>
14
- <main class="console-shell">
15
- <header class="topbar">
16
- <div>
17
- <p class="eyebrow">Local readiness console</p>
18
- <h1>VibeRaven Console</h1>
19
- </div>
20
- <button id="refreshButton" class="button" type="button">Refresh</button>
21
- </header>
22
-
23
- <section class="summary-strip" aria-label="Console summary">
24
- <div>
25
- <span class="summary-label">Gate</span>
26
- <strong id="gateStatus">Loading</strong>
27
- </div>
28
- <div>
29
- <span class="summary-label">Actions</span>
30
- <strong id="actionCount">0</strong>
31
- </div>
32
- <div>
33
- <span class="summary-label">Generated</span>
34
- <strong id="generatedAt">-</strong>
35
- </div>
36
- <div>
37
- <span class="summary-label">Artifact</span>
38
- <strong id="artifactPath">-</strong>
39
- </div>
40
- </section>
41
-
42
- <section id="message" class="message" hidden></section>
43
- <section id="actions" class="actions-grid" aria-live="polite"></section>
44
- </main>
45
- </body>
46
- </html>
@@ -1,267 +0,0 @@
1
- :root {
2
- --console-bg: #101214;
3
- --console-panel: #15181b;
4
- --console-panel-strong: #1b2024;
5
- --console-border: rgba(214, 222, 230, 0.14);
6
- --console-border-strong: rgba(214, 222, 230, 0.24);
7
- --console-text: #edf2f7;
8
- --console-subtle: #aab4bf;
9
- --console-muted: #747f8b;
10
- --console-command: #0c0f11;
11
- --console-accent: #80d0ff;
12
- --console-ready: #76d49b;
13
- --console-warn: #e4bd63;
14
- --console-danger: #f08b8b;
15
- --console-radius: 8px;
16
- font-family:
17
- Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
18
- }
19
-
20
- * {
21
- box-sizing: border-box;
22
- }
23
-
24
- body {
25
- margin: 0;
26
- background: var(--console-bg);
27
- color: var(--console-text);
28
- font-size: 14px;
29
- }
30
-
31
- button {
32
- font: inherit;
33
- }
34
-
35
- .console-shell {
36
- width: min(1360px, calc(100vw - 32px));
37
- margin: 0 auto;
38
- padding: 20px 0 28px;
39
- }
40
-
41
- .topbar {
42
- display: flex;
43
- align-items: center;
44
- justify-content: space-between;
45
- gap: 16px;
46
- min-height: 56px;
47
- border-bottom: 1px solid var(--console-border);
48
- }
49
-
50
- .eyebrow {
51
- margin: 0 0 4px;
52
- color: var(--console-muted);
53
- font-size: 12px;
54
- font-weight: 700;
55
- text-transform: uppercase;
56
- }
57
-
58
- h1 {
59
- margin: 0;
60
- font-size: 22px;
61
- font-weight: 750;
62
- }
63
-
64
- .button {
65
- min-height: 34px;
66
- border: 1px solid var(--console-border-strong);
67
- border-radius: 7px;
68
- background: var(--console-panel-strong);
69
- color: var(--console-text);
70
- cursor: pointer;
71
- padding: 0 12px;
72
- font-weight: 700;
73
- }
74
-
75
- .button:hover {
76
- border-color: rgba(128, 208, 255, 0.58);
77
- }
78
-
79
- .button:focus-visible {
80
- outline: 2px solid var(--console-accent);
81
- outline-offset: 2px;
82
- }
83
-
84
- .button.secondary {
85
- min-height: 30px;
86
- padding: 0 10px;
87
- color: var(--console-subtle);
88
- font-size: 12px;
89
- }
90
-
91
- .summary-strip {
92
- display: grid;
93
- grid-template-columns: repeat(4, minmax(0, 1fr));
94
- gap: 1px;
95
- margin: 16px 0;
96
- overflow: hidden;
97
- border: 1px solid var(--console-border);
98
- border-radius: var(--console-radius);
99
- background: var(--console-border);
100
- }
101
-
102
- .summary-strip > div {
103
- min-width: 0;
104
- padding: 11px 12px;
105
- background: var(--console-panel);
106
- }
107
-
108
- .summary-label {
109
- display: block;
110
- margin-bottom: 3px;
111
- color: var(--console-muted);
112
- font-size: 11px;
113
- font-weight: 700;
114
- text-transform: uppercase;
115
- }
116
-
117
- .summary-strip strong {
118
- display: block;
119
- overflow: hidden;
120
- color: var(--console-text);
121
- font-size: 13px;
122
- font-weight: 700;
123
- text-overflow: ellipsis;
124
- white-space: nowrap;
125
- }
126
-
127
- .message {
128
- margin-bottom: 16px;
129
- border: 1px solid rgba(228, 189, 99, 0.34);
130
- border-radius: var(--console-radius);
131
- background: rgba(228, 189, 99, 0.08);
132
- color: #f2d994;
133
- padding: 12px;
134
- }
135
-
136
- .actions-grid {
137
- display: grid;
138
- grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
139
- gap: 12px;
140
- align-items: start;
141
- }
142
-
143
- .action-card {
144
- display: grid;
145
- gap: 12px;
146
- min-height: 320px;
147
- border: 1px solid var(--console-border);
148
- border-radius: var(--console-radius);
149
- background: var(--console-panel);
150
- padding: 13px;
151
- }
152
-
153
- .action-header {
154
- display: grid;
155
- gap: 8px;
156
- }
157
-
158
- .action-title-row,
159
- .meta-row,
160
- .control-row {
161
- display: flex;
162
- align-items: center;
163
- gap: 8px;
164
- min-width: 0;
165
- }
166
-
167
- .action-title-row {
168
- justify-content: space-between;
169
- }
170
-
171
- .action-title {
172
- margin: 0;
173
- overflow-wrap: anywhere;
174
- font-size: 15px;
175
- font-weight: 750;
176
- }
177
-
178
- .pill {
179
- display: inline-flex;
180
- align-items: center;
181
- min-height: 22px;
182
- max-width: 100%;
183
- border: 1px solid var(--console-border);
184
- border-radius: 999px;
185
- color: var(--console-subtle);
186
- font-size: 11px;
187
- font-weight: 700;
188
- padding: 2px 8px;
189
- white-space: nowrap;
190
- }
191
-
192
- .pill.status {
193
- border-color: rgba(128, 208, 255, 0.42);
194
- color: var(--console-accent);
195
- }
196
-
197
- .pill.ready {
198
- border-color: rgba(118, 212, 155, 0.38);
199
- color: var(--console-ready);
200
- }
201
-
202
- .section-label {
203
- margin: 0 0 5px;
204
- color: var(--console-muted);
205
- font-size: 11px;
206
- font-weight: 750;
207
- text-transform: uppercase;
208
- }
209
-
210
- .target,
211
- .readiness-list {
212
- margin: 0;
213
- color: var(--console-subtle);
214
- }
215
-
216
- .target {
217
- overflow-wrap: anywhere;
218
- }
219
-
220
- .readiness-list {
221
- padding-left: 18px;
222
- }
223
-
224
- .readiness-list li + li {
225
- margin-top: 4px;
226
- }
227
-
228
- .command-box {
229
- min-height: 58px;
230
- max-height: 112px;
231
- overflow: auto;
232
- border: 1px solid var(--console-border);
233
- border-radius: 7px;
234
- background: var(--console-command);
235
- color: #dce7ef;
236
- padding: 9px;
237
- font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
238
- font-size: 12px;
239
- line-height: 1.45;
240
- white-space: pre-wrap;
241
- overflow-wrap: anywhere;
242
- }
243
-
244
- .action-footer {
245
- display: flex;
246
- flex-wrap: wrap;
247
- gap: 8px;
248
- align-self: end;
249
- }
250
-
251
- @media (max-width: 760px) {
252
- .console-shell {
253
- width: min(100vw - 20px, 1360px);
254
- padding-top: 12px;
255
- }
256
-
257
- .topbar,
258
- .action-title-row {
259
- align-items: flex-start;
260
- flex-direction: column;
261
- }
262
-
263
- .summary-strip,
264
- .actions-grid {
265
- grid-template-columns: 1fr;
266
- }
267
- }
@@ -1,11 +0,0 @@
1
- {
2
- "id": "stack-default",
3
- "recommendation": {
4
- "frontend": "react",
5
- "ui": "tailwind + shadcn/ui",
6
- "database": "supabase",
7
- "auth": "supabase",
8
- "deploy": "vercel",
9
- "reason": "Highest agent training density; lowest friction for autonomous deploy loop"
10
- }
11
- }
@@ -1,31 +0,0 @@
1
- {
2
- "id": "auth-supabase",
3
- "provider": "auth-supabase",
4
- "title": "Supabase Auth providers",
5
- "steps": [
6
- {
7
- "id": "auth-providers",
8
- "title": "Enable providers",
9
- "instruction": "Enable Email and any OAuth providers your app uses (Google, GitHub, etc.).",
10
- "openUrl": "https://supabase.com/dashboard/project/_/auth/providers"
11
- },
12
- {
13
- "id": "auth-urls",
14
- "title": "Redirect URLs",
15
- "instruction": "Site URL and Redirect URLs must include your Vercel deployment URL.",
16
- "openUrl": "https://supabase.com/dashboard/project/_/auth/url-configuration"
17
- },
18
- {
19
- "id": "auth-email-templates",
20
- "title": "Email templates",
21
- "instruction": "Customize confirm signup and magic link templates if your app uses email auth.",
22
- "openUrl": "https://supabase.com/dashboard/project/_/auth/templates"
23
- },
24
- {
25
- "id": "auth-jwt",
26
- "title": "JWT settings",
27
- "instruction": "Confirm JWT expiry matches your session strategy. Use service role key only on the server.",
28
- "openUrl": "https://supabase.com/dashboard/project/_/settings/api"
29
- }
30
- ]
31
- }
@@ -1,60 +0,0 @@
1
- {
2
- "id": "stripe-launch",
3
- "provider": "stripe",
4
- "title": "Configure Stripe billing",
5
- "steps": [
6
- {
7
- "id": "stripe-dashboard",
8
- "title": "Stripe dashboard",
9
- "instruction": "Open Stripe. For development, turn Test mode ON.",
10
- "openUrl": "https://dashboard.stripe.com/"
11
- },
12
- {
13
- "id": "stripe-keys",
14
- "title": "API keys",
15
- "instruction": "Copy test (or live) keys into .env. Never commit secret keys.",
16
- "openUrl": "https://dashboard.stripe.com/test/apikeys",
17
- "pasteTarget": {
18
- "file": ".env",
19
- "keys": ["STRIPE_SECRET_KEY", "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY"]
20
- }
21
- },
22
- {
23
- "id": "stripe-product",
24
- "title": "Product and price",
25
- "instruction": "Create a product with a recurring price for your Pro or paid tier.",
26
- "openUrl": "https://dashboard.stripe.com/test/products"
27
- },
28
- {
29
- "id": "stripe-price-id",
30
- "title": "Price ID",
31
- "instruction": "Copy the Price ID (price_...) into .env as STRIPE_PRICE_ID."
32
- },
33
- {
34
- "id": "stripe-webhook",
35
- "title": "Webhook endpoint",
36
- "instruction": "Add endpoint URL: {APP_URL}/api/webhooks/stripe (replace {APP_URL} with your Vercel URL).",
37
- "openUrl": "https://dashboard.stripe.com/test/webhooks"
38
- },
39
- {
40
- "id": "stripe-webhook-events",
41
- "title": "Webhook events",
42
- "instruction": "Subscribe to these events at minimum.",
43
- "events": [
44
- "checkout.session.completed",
45
- "customer.subscription.updated",
46
- "customer.subscription.deleted",
47
- "invoice.payment_failed"
48
- ]
49
- },
50
- {
51
- "id": "stripe-signing-secret",
52
- "title": "Signing secret",
53
- "instruction": "Copy the webhook signing secret into .env as STRIPE_WEBHOOK_SECRET.",
54
- "pasteTarget": {
55
- "file": ".env",
56
- "keys": ["STRIPE_WEBHOOK_SECRET"]
57
- }
58
- }
59
- ]
60
- }