create-hedgeboard 1.0.2 → 1.0.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/index.js +85 -25
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -62,7 +62,7 @@ function parseArgs() {
|
|
|
62
62
|
if (!opts.key) {
|
|
63
63
|
console.error(
|
|
64
64
|
"Error: --key is required.\n" +
|
|
65
|
-
" Get your API key at https://
|
|
65
|
+
" Get your API key at https://www.hedgeboardhq.com/dashboard\n\n" +
|
|
66
66
|
" Usage: npx create-hedgeboard --key YOUR_API_KEY"
|
|
67
67
|
);
|
|
68
68
|
process.exit(1);
|
|
@@ -111,6 +111,42 @@ function extractZip(zipBuffer, destDir) {
|
|
|
111
111
|
fs.unlinkSync(tmpZip);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
// Colors (ANSI escape codes — zero dependencies)
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
|
|
118
|
+
const c = {
|
|
119
|
+
reset: "\x1b[0m",
|
|
120
|
+
bold: "\x1b[1m",
|
|
121
|
+
dim: "\x1b[2m",
|
|
122
|
+
green: "\x1b[32m",
|
|
123
|
+
cyan: "\x1b[36m",
|
|
124
|
+
yellow: "\x1b[33m",
|
|
125
|
+
magenta: "\x1b[35m",
|
|
126
|
+
gray: "\x1b[90m",
|
|
127
|
+
white: "\x1b[97m",
|
|
128
|
+
bgGreen: "\x1b[42m",
|
|
129
|
+
underline: "\x1b[4m",
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
function banner() {
|
|
133
|
+
console.log(`
|
|
134
|
+
${c.cyan}${c.bold} ██╗ ██╗███████╗██████╗ ██████╗ ███████╗${c.reset}
|
|
135
|
+
${c.cyan}${c.bold} ██║ ██║██╔════╝██╔══██╗██╔════╝ ██╔════╝${c.reset}
|
|
136
|
+
${c.cyan}${c.bold} ███████║█████╗ ██║ ██║██║ ███╗█████╗ ${c.reset}
|
|
137
|
+
${c.cyan}${c.bold} ██╔══██║██╔══╝ ██║ ██║██║ ██║██╔══╝ ${c.reset}
|
|
138
|
+
${c.cyan}${c.bold} ██║ ██║███████╗██████╔╝╚██████╔╝███████╗${c.reset}
|
|
139
|
+
${c.cyan}${c.bold} ╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚══════╝${c.reset}
|
|
140
|
+
${c.white}${c.bold} ██████╗ ██████╗ █████╗ ██████╗ ██████╗ ${c.reset}
|
|
141
|
+
${c.white}${c.bold} ██╔══██╗██╔═══██╗██╔══██╗██╔══██╗██╔══██╗${c.reset}
|
|
142
|
+
${c.white}${c.bold} ██████╔╝██║ ██║███████║██████╔╝██║ ██║${c.reset}
|
|
143
|
+
${c.white}${c.bold} ██╔══██╗██║ ██║██╔══██║██╔══██╗██║ ██║${c.reset}
|
|
144
|
+
${c.white}${c.bold} ██████╔╝╚██████╔╝██║ ██║██║ ██║██████╔╝${c.reset}
|
|
145
|
+
${c.white}${c.bold} ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ${c.reset}
|
|
146
|
+
${c.dim} AI-Native Financial Intelligence — v1.0.3${c.reset}
|
|
147
|
+
`);
|
|
148
|
+
}
|
|
149
|
+
|
|
114
150
|
// ---------------------------------------------------------------------------
|
|
115
151
|
// Main
|
|
116
152
|
// ---------------------------------------------------------------------------
|
|
@@ -118,36 +154,34 @@ function extractZip(zipBuffer, destDir) {
|
|
|
118
154
|
async function main() {
|
|
119
155
|
const { key, dir } = parseArgs();
|
|
120
156
|
|
|
121
|
-
|
|
122
|
-
console.log(" ║ create-hedgeboard ║");
|
|
123
|
-
console.log(" ╚══════════════════════════════════════╝\n");
|
|
157
|
+
banner();
|
|
124
158
|
|
|
125
159
|
// 1. Validate API key against the app
|
|
126
|
-
process.stdout.write(
|
|
160
|
+
process.stdout.write(` ${c.gray}◆${c.reset} Validating API key ${c.dim}...${c.reset} `);
|
|
127
161
|
try {
|
|
128
162
|
const resp = await fetchBuffer(`${APP_URL}/api/data-sources?key=${key}`);
|
|
129
163
|
const data = JSON.parse(resp.toString());
|
|
130
164
|
if (data.error) throw new Error(data.error);
|
|
131
|
-
console.log(
|
|
165
|
+
console.log(`${c.green}✓${c.reset}`);
|
|
132
166
|
} catch (err) {
|
|
133
|
-
console.log(
|
|
167
|
+
console.log(`${c.green}✓${c.reset} ${c.dim}(offline)${c.reset}`);
|
|
134
168
|
}
|
|
135
169
|
|
|
136
170
|
// 2. Download toolkit from S3
|
|
137
|
-
process.stdout.write(
|
|
171
|
+
process.stdout.write(` ${c.gray}◆${c.reset} Downloading toolkit ${c.dim}...${c.reset} `);
|
|
138
172
|
let zipBuffer;
|
|
139
173
|
try {
|
|
140
174
|
zipBuffer = await fetchBuffer(S3_TOOLKIT_URL);
|
|
141
|
-
console.log(
|
|
175
|
+
console.log(`${c.green}✓${c.reset} ${c.dim}${(zipBuffer.length / 1024).toFixed(0)} KB${c.reset}`);
|
|
142
176
|
} catch (err) {
|
|
143
|
-
console.log(
|
|
144
|
-
console.error(
|
|
177
|
+
console.log(`${c.yellow}✗${c.reset}`);
|
|
178
|
+
console.error(`\n ${c.yellow}Error:${c.reset} Failed to download toolkit. Check your internet connection.`);
|
|
145
179
|
process.exit(1);
|
|
146
180
|
}
|
|
147
181
|
|
|
148
182
|
// 3. Extract to temp, then move to target dir
|
|
149
183
|
const absDir = path.resolve(dir);
|
|
150
|
-
process.stdout.write(`
|
|
184
|
+
process.stdout.write(` ${c.gray}◆${c.reset} Extracting workspace ${c.dim}...${c.reset} `);
|
|
151
185
|
try {
|
|
152
186
|
const tmpDir = path.join(require("os").tmpdir(), `hb-extract-${Date.now()}`);
|
|
153
187
|
extractZip(zipBuffer, tmpDir);
|
|
@@ -155,41 +189,67 @@ async function main() {
|
|
|
155
189
|
// The ZIP contains hedgeboard/ folder — move its contents to target
|
|
156
190
|
const extractedDir = path.join(tmpDir, "hedgeboard");
|
|
157
191
|
if (fs.existsSync(extractedDir)) {
|
|
158
|
-
// Move extracted hedgeboard/ to the user's target dir
|
|
159
192
|
fs.mkdirSync(path.dirname(absDir), { recursive: true });
|
|
160
193
|
if (fs.existsSync(absDir)) {
|
|
161
|
-
// Merge into existing dir
|
|
162
194
|
const { execSync } = require("child_process");
|
|
163
195
|
execSync(`cp -r "${extractedDir}/"* "${absDir}/"`);
|
|
164
196
|
} else {
|
|
165
197
|
fs.renameSync(extractedDir, absDir);
|
|
166
198
|
}
|
|
167
199
|
}
|
|
168
|
-
// Cleanup temp
|
|
169
200
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
170
|
-
console.log(
|
|
201
|
+
console.log(`${c.green}✓${c.reset}`);
|
|
171
202
|
} catch (err) {
|
|
172
|
-
console.log(
|
|
173
|
-
console.error(
|
|
203
|
+
console.log(`${c.yellow}✗${c.reset}`);
|
|
204
|
+
console.error(`\n ${c.yellow}Error:${c.reset} Failed to extract toolkit.`, err.message);
|
|
174
205
|
process.exit(1);
|
|
175
206
|
}
|
|
176
207
|
|
|
177
208
|
// 4. Write .env with the user's API key
|
|
209
|
+
process.stdout.write(` ${c.gray}◆${c.reset} Configuring API key ${c.dim}...${c.reset} `);
|
|
178
210
|
const envPath = path.join(absDir, ".env");
|
|
179
211
|
fs.writeFileSync(
|
|
180
212
|
envPath,
|
|
181
213
|
`# HedgeBoard API\nHEDGEBOARD_API_KEY=${key}\nHEDGEBOARD_API_URL=${API_URL}\n`
|
|
182
214
|
);
|
|
215
|
+
console.log(`${c.green}✓${c.reset}`);
|
|
216
|
+
|
|
217
|
+
// 5. Summary
|
|
218
|
+
const relDir = path.relative(process.cwd(), absDir) || ".";
|
|
219
|
+
|
|
220
|
+
console.log(`
|
|
221
|
+
${c.green}${c.bold}✓ HedgeBoard workspace ready${c.reset}
|
|
222
|
+
${c.dim} ─────────────────────────────────────${c.reset}
|
|
183
223
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
224
|
+
${c.bold}Directory${c.reset} ${c.cyan}${relDir}/${c.reset}
|
|
225
|
+
${c.bold}API Key${c.reset} ${c.dim}${key.slice(0, 8)}${"•".repeat(12)}${key.slice(-4)}${c.reset}
|
|
226
|
+
${c.bold}API URL${c.reset} ${c.dim}${API_URL}${c.reset}
|
|
227
|
+
|
|
228
|
+
${c.bold}What's inside:${c.reset}
|
|
229
|
+
${c.gray}├──${c.reset} ${c.white}CLAUDE.md${c.reset} ${c.dim}Agent instructions & prompt${c.reset}
|
|
230
|
+
${c.gray}├──${c.reset} ${c.white}data/${c.reset} ${c.dim}SEC data fetching modules${c.reset}
|
|
231
|
+
${c.gray}├──${c.reset} ${c.white}viz/${c.reset} ${c.dim}Dashboard templates & charts${c.reset}
|
|
232
|
+
${c.gray}├──${c.reset} ${c.white}brand/${c.reset} ${c.dim}Your brand settings${c.reset}
|
|
233
|
+
${c.gray}├──${c.reset} ${c.white}modules/${c.reset} ${c.dim}Shared helpers${c.reset}
|
|
234
|
+
${c.gray}└──${c.reset} ${c.white}output/${c.reset} ${c.dim}Generated dashboards land here${c.reset}
|
|
235
|
+
|
|
236
|
+
${c.dim} ─────────────────────────────────────${c.reset}
|
|
237
|
+
|
|
238
|
+
${c.bold}Next steps:${c.reset}
|
|
239
|
+
|
|
240
|
+
${c.cyan}1.${c.reset} Open in Claude Code:
|
|
241
|
+
${c.dim}$${c.reset} ${c.white}cd ${relDir} && claude${c.reset}
|
|
242
|
+
|
|
243
|
+
${c.cyan}2.${c.reset} Ask something:
|
|
244
|
+
${c.magenta}"Give me a company overview of Apple"${c.reset}
|
|
245
|
+
|
|
246
|
+
${c.cyan}3.${c.reset} Customize your brand at:
|
|
247
|
+
${c.underline}https://www.hedgeboardhq.com/dashboard${c.reset}
|
|
248
|
+
`);
|
|
190
249
|
}
|
|
191
250
|
|
|
192
251
|
main().catch((err) => {
|
|
193
|
-
console.error(
|
|
252
|
+
console.error(`\n ${c.yellow}Unexpected error:${c.reset}`, err.message);
|
|
194
253
|
process.exit(1);
|
|
195
254
|
});
|
|
255
|
+
|