create-hedgeboard 1.0.1 → 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 +101 -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,62 +154,102 @@ 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
|
-
// 3. Extract
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
186
|
+
const tmpDir = path.join(require("os").tmpdir(), `hb-extract-${Date.now()}`);
|
|
187
|
+
extractZip(zipBuffer, tmpDir);
|
|
188
|
+
|
|
189
|
+
// The ZIP contains hedgeboard/ folder — move its contents to target
|
|
190
|
+
const extractedDir = path.join(tmpDir, "hedgeboard");
|
|
191
|
+
if (fs.existsSync(extractedDir)) {
|
|
192
|
+
fs.mkdirSync(path.dirname(absDir), { recursive: true });
|
|
193
|
+
if (fs.existsSync(absDir)) {
|
|
194
|
+
const { execSync } = require("child_process");
|
|
195
|
+
execSync(`cp -r "${extractedDir}/"* "${absDir}/"`);
|
|
196
|
+
} else {
|
|
197
|
+
fs.renameSync(extractedDir, absDir);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
201
|
+
console.log(`${c.green}✓${c.reset}`);
|
|
155
202
|
} catch (err) {
|
|
156
|
-
console.log(
|
|
157
|
-
console.error(
|
|
203
|
+
console.log(`${c.yellow}✗${c.reset}`);
|
|
204
|
+
console.error(`\n ${c.yellow}Error:${c.reset} Failed to extract toolkit.`, err.message);
|
|
158
205
|
process.exit(1);
|
|
159
206
|
}
|
|
160
207
|
|
|
161
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} `);
|
|
162
210
|
const envPath = path.join(absDir, ".env");
|
|
163
211
|
fs.writeFileSync(
|
|
164
212
|
envPath,
|
|
165
213
|
`# HedgeBoard API\nHEDGEBOARD_API_KEY=${key}\nHEDGEBOARD_API_URL=${API_URL}\n`
|
|
166
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}
|
|
167
223
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
+
`);
|
|
174
249
|
}
|
|
175
250
|
|
|
176
251
|
main().catch((err) => {
|
|
177
|
-
console.error(
|
|
252
|
+
console.error(`\n ${c.yellow}Unexpected error:${c.reset}`, err.message);
|
|
178
253
|
process.exit(1);
|
|
179
254
|
});
|
|
255
|
+
|