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.
Files changed (2) hide show
  1. package/index.js +101 -25
  2. 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://hedgeboard.com/dashboard\n\n" +
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
- console.log("\n ╔══════════════════════════════════════╗");
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(" Validating API key... ");
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("✓ (offline validation skipped)");
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(" Downloading toolkit... ");
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(`✓ (${(zipBuffer.length / 1024).toFixed(0)} KB)`);
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("\n Error: Failed to download toolkit. Check your internet connection.");
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(` Extracting to ${absDir}... `);
184
+ process.stdout.write(` ${c.gray}◆${c.reset} Extracting workspace ${c.dim}...${c.reset} `);
151
185
  try {
152
- extractZip(zipBuffer, path.dirname(absDir));
153
- // The ZIP contains hedgeboard/ so files land in the right place
154
- console.log("✓");
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("\n Error: Failed to extract toolkit.", err.message);
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
- // 5. Done!
169
- console.log("\n ✅ HedgeBoard workspace ready!\n");
170
- console.log(" Next steps:");
171
- console.log(` 1. Open ${dir}/ in Claude Code`);
172
- console.log(` 2. Ask: "Give me a company overview of Apple"`);
173
- console.log("");
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("\n Unexpected error:", err.message);
252
+ console.error(`\n ${c.yellow}Unexpected error:${c.reset}`, err.message);
178
253
  process.exit(1);
179
254
  });
255
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-hedgeboard",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Set up a HedgeBoard financial intelligence workspace",
5
5
  "bin": {
6
6
  "create-hedgeboard": "./index.js"