career-compass-mcp 2.5.0 → 2.5.1

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/build/bin/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { homedir } from "os";
3
- import { join, resolve } from "path";
3
+ import { join, resolve, dirname } from "path";
4
4
  import { existsSync, mkdirSync } from "fs";
5
5
  import { createServer as createNetServer } from "net";
6
6
  import { spawn } from "child_process";
@@ -27,27 +27,27 @@ if (args.includes("--version") || args.includes("-v")) {
27
27
  }
28
28
  // ─── Help ────────────────────────────────────────────────────────────────────
29
29
  if (args.includes("--help") || args.includes("-h")) {
30
- console.log(`
31
- career-compass-mcp v${pkgVersion}
32
-
33
- Usage:
34
- career-compass-mcp Run MCP server (stdio)
35
- career-compass-mcp dashboard Open web dashboard (full if built, else lite)
36
- career-compass-mcp dashboard --sample Open the bundled Alex Rivera demo
37
- career-compass-mcp dashboard --lite Force the zero-build lite dashboard
38
- career-compass-mcp dashboard --port 3000 Specify port (default: 3141)
39
- career-compass-mcp dashboard --no-open Start without opening browser
40
-
41
- Options:
42
- -h, --help Show this help message
43
- -v, --version Show version number
44
- --sample Serve the bundled read-only demo (alias: --demo).
45
- Ignores CAREER_DATA_PATH; writes nothing.
46
- --lite Use the built-in zero-build dashboard (no Next.js build needed)
47
- --port <number> Dashboard port (default: 3141)
48
- --no-open Don't auto-open browser
49
-
50
- Your data folder is CAREER_DATA_PATH, or ~/.career-compass when that is unset.
30
+ console.log(`
31
+ career-compass-mcp v${pkgVersion}
32
+
33
+ Usage:
34
+ career-compass-mcp Run MCP server (stdio)
35
+ career-compass-mcp dashboard Open web dashboard (full if built, else lite)
36
+ career-compass-mcp dashboard --sample Open the bundled Alex Rivera demo
37
+ career-compass-mcp dashboard --lite Force the zero-build lite dashboard
38
+ career-compass-mcp dashboard --port 3000 Specify port (default: 3141)
39
+ career-compass-mcp dashboard --no-open Start without opening browser
40
+
41
+ Options:
42
+ -h, --help Show this help message
43
+ -v, --version Show version number
44
+ --sample Serve the bundled read-only demo (alias: --demo).
45
+ Ignores CAREER_DATA_PATH; writes nothing.
46
+ --lite Use the built-in zero-build dashboard (no Next.js build needed)
47
+ --port <number> Dashboard port (default: 3141)
48
+ --no-open Don't auto-open browser
49
+
50
+ Your data folder is CAREER_DATA_PATH, or ~/.career-compass when that is unset.
51
51
  `);
52
52
  process.exit(0);
53
53
  }
@@ -82,13 +82,26 @@ else {
82
82
  // Otherwise prefer the full Next.js dashboard when it has been built.
83
83
  // If the full build is absent (e.g. the npm install), fall back to lite
84
84
  // instead of erroring — the dashboard now always works.
85
- const useLite = forceLite || !existsSync(standalonePath);
85
+ // A standalone build that was never staged serves its HTML and none of its
86
+ // CSS or JS — `output: "standalone"` does not copy `.next/static`, and a page
87
+ // with no stylesheet still returns 200. Treat an unstaged build as no build:
88
+ // the lite dashboard is plain, but it is not BROKEN, and silently serving a
89
+ // stylesheet-less page is the worse of the two. `npm run build:dashboard`
90
+ // stages it (scripts/stage-standalone.mjs).
91
+ const standaloneStaged = existsSync(join(dirname(standalonePath), ".next", "static"));
92
+ const useLite = forceLite || !existsSync(standalonePath) || !standaloneStaged;
86
93
  if (useLite) {
87
94
  process.env.CAREER_DATA_PATH = dataPath; // loadPipeline() reads this
88
95
  const { startLiteDashboard } = await import("../src/dashboard-lite/server.js");
89
96
  if (!forceLite) {
90
- console.error("Full dashboard isn't built in this install — starting the built-in lite dashboard.");
91
- console.error("(Run `npm run build` from source for the full Next.js dashboard with kanban drag, analytics, and Career KB views.)");
97
+ if (existsSync(standalonePath) && !standaloneStaged) {
98
+ console.error("The full dashboard is built but not staged — its CSS and JS are missing, so it would");
99
+ console.error("render unstyled. Starting the lite dashboard instead. Fix with: npm run build:dashboard");
100
+ }
101
+ else {
102
+ console.error("Full dashboard isn't built in this install — starting the built-in lite dashboard.");
103
+ console.error("(Run `npm run build` from source for the full Next.js dashboard with kanban drag, analytics, and Career KB views.)");
104
+ }
92
105
  }
93
106
  const server = await startLiteDashboard(port);
94
107
  console.error(`Lite dashboard running at http://localhost:${port}`);
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/dashboard-lite/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAqB,MAAM,6BAA6B,CAAC;AAmF5F,UAAU,UAAU;IAAG,GAAG,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;CAAE;AAE/F,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,KAAK,OAAa,GAAG,UAAU,EAAE,CAwCvF;AAmBD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAiMhF"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/dashboard-lite/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAqB,MAAM,6BAA6B,CAAC;AAmF5F,UAAU,UAAU;IAAG,GAAG,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;CAAE;AAE/F,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,KAAK,OAAa,GAAG,UAAU,EAAE,CAwCvF;AA8BD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CA0MhF"}
@@ -122,18 +122,29 @@ export function deriveNextActions(apps, today = new Date()) {
122
122
  const rank = { overdue: 0, soon: 1, info: 2 };
123
123
  return out.sort((a, b) => rank[a.urgency] - rank[b.urgency]);
124
124
  }
125
+ /**
126
+ * One KPI card. A `null` value renders as an em dash, not a zero.
127
+ *
128
+ * "Prefer a blank to a zero" is not a style preference here, it is accuracy. A
129
+ * rate over an empty denominator is undefined, and printing `0%` for it states
130
+ * something false in the most discouraging possible place: a brand-new user's
131
+ * very first screen said `0% response rate` before they had applied to
132
+ * anything, which reads as *you are failing* rather than *you have not started*.
133
+ */
125
134
  function kpi(n, label, foot = "") {
126
- return `<div class="kpi"><div class="n">${esc(n)}</div><div class="l">${esc(label)}</div>${foot ? `<div class="foot">${esc(foot)}</div>` : ""}</div>`;
135
+ const value = n === null ? "—" : String(n);
136
+ const undefinedClass = n === null ? " is-undefined" : "";
137
+ return `<div class="kpi${undefinedClass}"><div class="n">${esc(value)}</div><div class="l">${esc(label)}</div>${foot ? `<div class="foot">${esc(foot)}</div>` : ""}</div>`;
127
138
  }
128
139
  function jobCard(a) {
129
140
  const color = STAGE_COLOR[a.status];
130
141
  const pr = a.priority ? `<span class="pill p-${esc(a.priority)}">${esc(a.priority)}</span>` : "";
131
142
  const exc = a.excitement != null ? `<span class="exc">🔥 ${esc(a.excitement)}/10</span>` : "";
132
143
  const prompt = `Give me a full status on my ${a.company} application (${a.role}) — where it stands, what's next, and anything I'm at risk of dropping.`;
133
- return `<div class="jc" style="--stage:${color}" data-prompt="${esc(prompt)}">
134
- <div class="co">${esc(a.company)}</div>
135
- <div class="ro">${esc(a.role)}</div>
136
- <div class="meta">${pr}${exc}</div>
144
+ return `<div class="jc" style="--stage:${color}" data-prompt="${esc(prompt)}">
145
+ <div class="co">${esc(a.company)}</div>
146
+ <div class="ro">${esc(a.role)}</div>
147
+ <div class="meta">${pr}${exc}</div>
137
148
  </div>`;
138
149
  }
139
150
  /**
@@ -151,14 +162,22 @@ export function renderLiteDashboard(pipeline, dataDir) {
151
162
  const s = computeStats(apps);
152
163
  const actions = deriveNextActions(apps);
153
164
  const lastUpdated = pipeline.lastUpdated ? new Date(pipeline.lastUpdated).toLocaleString() : "—";
154
- const kpis = [
155
- kpi(s.total, "Total applications"),
156
- kpi(s.active, "Active", "in play right now"),
157
- kpi(s.inConversation, "In conversation", "screening + interviewing"),
158
- kpi(s.offers, "Offers", s.offers > 0 ? "🎉 decision time" : ""),
159
- kpi(`${s.responseRate}%`, "Response rate"),
160
- kpi(`${s.ghostRate}%`, "Ghost rate"),
161
- ].join("");
165
+ // With nothing in the pipeline every one of these is either zero or undefined,
166
+ // and six cards saying so is a worse first impression than no cards at all —
167
+ // it tells a new user six times that they have nothing. The empty state below
168
+ // says it once, warmly, with the action attached.
169
+ const kpis = apps.length === 0
170
+ ? ""
171
+ : [
172
+ kpi(s.total, "Total applications"),
173
+ kpi(s.active, "Active", "in play right now"),
174
+ kpi(s.inConversation, "In conversation", "screening + interviewing"),
175
+ kpi(s.offers, "Offers", s.offers > 0 ? "🎉 decision time" : ""),
176
+ // A rate needs a denominator. Until something has been sent and had time
177
+ // to come back, these are unknown rather than zero.
178
+ kpi(s.sent > 0 ? `${s.responseRate}%` : null, "Response rate", s.sent > 0 ? "" : "no replies due yet"),
179
+ kpi(s.sent > 0 ? `${s.ghostRate}%` : null, "Ghost rate", s.sent > 0 ? "" : "no replies due yet"),
180
+ ].join("");
162
181
  // Only show a stage that has something in it, plus the handful of early
163
182
  // stages that read as "nothing here yet" rather than as clutter. Rendering
164
183
  // every active stage regardless meant a small pipeline still produced six
@@ -171,9 +190,9 @@ export function renderLiteDashboard(pipeline, dataDir) {
171
190
  const ALWAYS_SHOW = ["applied", "screening", "interviewing"];
172
191
  const stageCol = (st) => {
173
192
  const items = apps.filter((a) => a.status === st);
174
- return `<div class="col">
175
- <div class="h"><span class="sw" style="background:${STAGE_COLOR[st]}"></span> ${st} <span class="count">${items.length}</span></div>
176
- <div class="stack">${items.map(jobCard).join("") || '<div class="none">Nothing here yet</div>'}</div>
193
+ return `<div class="col">
194
+ <div class="h"><span class="sw" style="background:${STAGE_COLOR[st]}"></span> ${st} <span class="count">${items.length}</span></div>
195
+ <div class="stack">${items.map(jobCard).join("") || '<div class="none">Nothing here yet</div>'}</div>
177
196
  </div>`;
178
197
  };
179
198
  const liveStages = STAGE_ORDER.filter((st) => !CLOSED.includes(st) && (apps.some((a) => a.status === st) || ALWAYS_SHOW.includes(st)));
@@ -181,150 +200,151 @@ export function renderLiteDashboard(pipeline, dataDir) {
181
200
  const closedCount = apps.filter((a) => CLOSED.includes(a.status)).length;
182
201
  const board = liveStages.map(stageCol).join("");
183
202
  const closedBoard = closedCount
184
- ? `<details class="closed">
185
- <summary>Closed <span class="count">${closedCount}</span>
203
+ ? `<details class="closed">
204
+ <summary>Closed <span class="count">${closedCount}</span>
186
205
  <span class="dots">${closedStages
187
206
  .map((st) => `<span class="sw" style="background:${STAGE_COLOR[st]}" title="${st}"></span>`)
188
- .join("")}</span>
189
- </summary>
190
- <div class="board">${closedStages.map(stageCol).join("")}</div>
207
+ .join("")}</span>
208
+ </summary>
209
+ <div class="board">${closedStages.map(stageCol).join("")}</div>
191
210
  </details>`
192
211
  : "";
193
212
  const actionsHtml = actions.length
194
213
  ? actions.map((x) => `<div class="action ${x.urgency}"><span class="dot"></span><div class="t"><b>${esc(x.label)}</b><span>${esc(x.app.role)}</span></div></div>`).join("")
195
214
  : `<div class="none-lg">✅ Nothing overdue. Follow-ups, upcoming interviews, and expiring offers surface here.</div>`;
196
- const emptyState = `<div class="panel"><div class="state">
197
- <h3>Your pipeline is empty — let's fix that</h3>
198
- <div>Career Compass builds everything off your pipeline. Add your first opportunity and this dashboard lights up.</div>
199
- <div class="btns">
200
- <button class="btn primary" data-prompt="I found a job posting I want to track. Here it is: [paste posting]. Add it to my pipeline and give me a fit analysis.">Copy: track a job posting</button>
201
- <button class="btn" data-prompt="Add an application to my pipeline — I'll give you the company and role.">Copy: add manually</button>
202
- </div>
215
+ const emptyState = `<div class="panel"><div class="state">
216
+ <h3>Your pipeline is empty — let's fix that</h3>
217
+ <div>Career Compass builds everything off your pipeline. Add your first opportunity and this dashboard lights up.</div>
218
+ <div class="btns">
219
+ <button class="btn primary" data-prompt="I found a job posting I want to track. Here it is: [paste posting]. Add it to my pipeline and give me a fit analysis.">Copy: track a job posting</button>
220
+ <button class="btn" data-prompt="Add an application to my pipeline — I'll give you the company and role.">Copy: add manually</button>
221
+ </div>
203
222
  </div></div>`;
204
223
  const chartData = jsonForScript(ACTIVE.filter((st) => apps.some((a) => a.status === st))
205
224
  .map((st) => ({ label: st[0].toUpperCase() + st.slice(1), value: apps.filter((a) => a.status === st).length, color: STAGE_COLOR[st] })));
206
- return `<!doctype html>
207
- <html lang="en"><head>
208
- <meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
209
- <title>Career Compass — Pipeline</title>
210
- <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='7' fill='%231f1e1d'/%3E%3Ccircle cx='16' cy='16' r='10' fill='%23c2603c'/%3E%3Cpath d='M20.5 10.5 L14.5 17.5 L11.5 21.5 L17.5 14.5 Z' fill='%231f1e1d'/%3E%3C/svg%3E">
211
- <style>
212
- /* Warm neutrals + clay accent, so the page sits inside Claude rather than
213
- next to it, and follows the host's light/dark preference instead of
214
- blinding anyone running Claude Desktop in dark mode. */
215
- :root{color-scheme:light dark;--bg:#faf9f5;--card:#fff;--ink:#1f1e1d;--muted:#6b675f;--line:#e8e5dd;--accent:#c2603c;--accent-soft:#f6ece7;--sunk:#f5f3ed;--shadow:0 1px 2px rgba(31,30,29,.05),0 4px 14px rgba(31,30,29,.04)}
216
- @media(prefers-color-scheme:dark){:root{--bg:#1f1e1d;--card:#262624;--ink:#f2efe8;--muted:#a5a096;--line:#37352f;--accent:#e08560;--accent-soft:#33241d;--sunk:#221f1d;--shadow:0 1px 2px rgba(0,0,0,.3),0 4px 14px rgba(0,0,0,.22)}}
217
- *{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased}
218
- .wrap{max-width:1180px;margin:0 auto;padding:20px 20px 64px}
219
- header.top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:18px}
220
- h1{font-size:20px;margin:0 0 2px;letter-spacing:-.01em}.sub{color:var(--muted);font-size:12.5px}
221
- .chip{display:inline-flex;align-items:center;gap:6px;background:var(--accent-soft);color:var(--accent);border-radius:999px;padding:4px 10px;font-size:12px;font-weight:600}
222
- .kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:20px}
223
- .kpi{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:14px 16px;box-shadow:var(--shadow)}
224
- .kpi .n{font-size:26px;font-weight:700;letter-spacing:-.02em}.kpi .l{color:var(--muted);font-size:12px;margin-top:2px}.kpi .foot{font-size:11.5px;margin-top:6px;color:var(--muted)}
225
- /* minmax(0,…) is load-bearing, not decoration. A grid item's default
226
- min-width is auto — its min-content — so a bare 1fr track is a *floor*,
227
- not a cap: one long unbreakable token in a company name or a follow-up
228
- label grows its own rail past its share, and the sibling rail is squeezed
229
- to whatever is left. Measured on the sample pipeline at 1512px, the rails
230
- went 1263px / 175px, the chart track collapsed to 3px, and the page ran
231
- 135px off the right edge. minmax(0,1fr) lets the item shrink; the
232
- overflow-wrap below is what keeps the token itself inside the card once
233
- the box stops growing to fit it. */
234
- .grid2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;align-items:start}@media(max-width:900px){.grid2{grid-template-columns:minmax(0,1fr)}}
235
- .grid2>*,.board>*{min-width:0}
236
- .action .t b,.jc .co,.jc .ro{overflow-wrap:anywhere}
237
- .panel{background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow)}
238
- .panel h2{font-size:13px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:0;padding:14px 16px;border-bottom:1px solid var(--line)}
239
- .panel .body{padding:14px 16px}.chart-box{position:relative;display:flex;gap:10px}
240
- .bar-row{display:flex;flex-direction:column;gap:9px;width:100%}
241
- .bar{display:flex;align-items:center;gap:10px}.bar .lab{width:96px;font-size:12px;color:var(--muted);text-align:right;flex:0 0 auto}
242
- .bar .track{flex:1;background:var(--sunk);border-radius:6px;height:22px;overflow:hidden}
243
- /* display:block is load-bearing. These are <span>s, and width has no effect on
244
- an inline box — so every bar in this chart rendered as an empty track. */
245
- .bar .fill{display:block;height:100%;border-radius:6px;min-width:3px;transition:width .3s ease}
246
- .bar .val{font-size:12px;font-weight:600;width:22px}
247
- .action{display:flex;gap:10px;padding:11px 0;border-bottom:1px dashed var(--line)}.action:last-child{border-bottom:0}
248
- .action .dot{width:8px;height:8px;border-radius:50%;margin-top:6px;flex:0 0 auto;background:var(--accent)}
249
- .action.overdue .dot{background:#ef4444}.action.soon .dot{background:#f59e0b}
250
- .action .t{flex:1}.action .t b{display:block;font-size:13.5px}.action .t span{color:var(--muted);font-size:12px}
251
- .board{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:12px;align-items:start}
252
- .col{background:var(--sunk);border:1px solid var(--line);border-radius:12px;min-height:80px}
253
- .col .h{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--line);font-weight:600;font-size:12.5px;text-transform:capitalize}
254
- .col .h .sw{width:9px;height:9px;border-radius:50%}.col .h .count{margin-left:auto;background:var(--sunk);color:var(--muted);border:1px solid var(--line);border-radius:999px;font-size:11px;padding:1px 8px}
255
- .col .stack{padding:10px;display:flex;flex-direction:column;gap:9px}.none{color:var(--muted);font-size:11.5px;padding:4px 2px}.none-lg{color:var(--muted);font-size:13px}
256
- .jc{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--stage,#ccc);border-radius:10px;padding:10px 11px;cursor:pointer;transition:.12s}
257
- .jc:hover{box-shadow:var(--shadow);transform:translateY(-1px)}.jc .co{font-weight:650;font-size:13px}.jc .ro{color:var(--muted);font-size:12px;margin-top:1px}
258
- .jc .meta{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;align-items:center}
259
- .pill{font-size:10.5px;padding:2px 7px;border-radius:999px;font-weight:600}.p-high{background:color-mix(in srgb,#ef4444 16%,transparent);color:#c04a3a}.p-medium{background:color-mix(in srgb,#f59e0b 18%,transparent);color:#a06a1b}.p-low{background:color-mix(in srgb,var(--muted) 16%,transparent);color:var(--muted)}
260
- .exc{font-size:11px;color:var(--muted);margin-left:auto}
261
- .btn{border:1px solid var(--line);background:var(--card);color:var(--ink);border-radius:9px;padding:7px 12px;font-size:12.5px;font-weight:600;cursor:pointer;transition:.12s}
262
- .btn:hover{border-color:var(--accent);color:var(--accent)}.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}.btn.primary:hover{filter:brightness(.93)}
263
- .toolbar{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 14px}
264
- .state{text-align:center;padding:48px 20px;color:var(--muted)}.state h3{color:var(--ink);font-size:16px;margin:0 0 6px}.state .btns{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:16px}
265
- .foot-note{color:var(--muted);font-size:11.5px;margin-top:22px;text-align:center}
266
- #toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%) translateY(20px);background:var(--ink);color:var(--card);padding:10px 16px;border-radius:10px;font-size:13px;opacity:0;transition:.2s;pointer-events:none}
267
- #toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
268
- .closed{margin-top:12px;border-top:1px solid var(--line);padding-top:10px}
269
- .closed summary{cursor:pointer;list-style:none;display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;color:var(--muted);padding:4px 2px;border-radius:8px}
270
- .closed summary::-webkit-details-marker{display:none}
271
- .closed summary::before{content:"▸";display:inline-block;transition:transform .15s;color:var(--muted);font-size:11px}
272
- .closed[open] summary::before{transform:rotate(90deg)}
273
- .closed summary:hover{color:var(--ink)}
274
- .closed .dots{display:inline-flex;gap:4px;margin-left:2px}
275
- .closed .dots .sw{width:8px;height:8px;border-radius:50%}
276
- .closed .board{margin-top:10px}
277
- .hidden{display:none!important}
278
- </style></head>
279
- <body><div class="wrap">
280
- <header class="top">
281
- <div><h1>🧭 Career Compass — Pipeline</h1>
282
- <div class="sub">Live view of your job search · re-read from disk on every load · last write ${esc(lastUpdated)}</div></div>
283
- <div class="chip">● local</div>
284
- </header>
285
- <div class="toolbar">
286
- <button class="btn primary" data-prompt="What should I focus on in my job search today? Look at my pipeline and give me the 3 highest-leverage moves.">🎯 Copy: what should I do today?</button>
287
- <button class="btn" data-prompt="Review my whole pipeline and flag anything stale, single-threaded, or at risk of going cold.">🔍 Copy: health check</button>
288
- </div>
289
- <div class="kpis">${kpis}</div>
290
- ${apps.length === 0 ? emptyState : `
291
- <div class="panel" style="margin-bottom:16px">
292
- <h2>Pipeline by stage</h2>
293
- <div class="body"><div class="board">${board}</div>${closedBoard}</div>
294
- </div>
295
- <div class="grid2">
296
- <div class="panel"><h2>Next actions</h2><div class="body">${actionsHtml}</div></div>
297
- <div class="panel"><h2>Stage distribution</h2><div class="body"><div id="chart" class="chart-box"></div></div></div>
298
- </div>`}
299
- <div class="foot-note">${dataDir ? `Data stays local (<code>${esc(dataDir)}</code>).` : "Data stays local on this machine."} Click any card to copy a prompt for Claude — that's where the work happens. Refresh the page to re-read from disk.</div>
300
- </div>
301
- <div id="toast"></div>
302
- <script>
303
- const CHART=${chartData};
304
- (function(){
305
- const box=document.getElementById("chart");
306
- if(box&&CHART.length){
307
- const max=Math.max(...CHART.map(d=>d.value),1);
308
- // Escaped on the way into innerHTML for the same reason jsonForScript exists:
309
- // these values are enum-derived today and this is the only place on the page
310
- // that builds markup from data at runtime.
311
- const h=s=>String(s).replace(/[&<>"']/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c]));
312
- box.innerHTML='<div class="bar-row">'+CHART.map(d=>
313
- '<div class="bar"><span class="lab">'+h(d.label)+'</span><span class="track"><span class="fill" style="width:'+(Number(d.value)/max*100)+'%;background:'+h(d.color)+'"></span></span><span class="val">'+h(d.value)+'</span></div>'
314
- ).join("")+'</div>';
315
- } else if(box){ box.innerHTML='<div class="none-lg">No active applications yet.</div>'; }
316
- const toast=document.getElementById("toast"); let tmr;
317
- function flash(m){ toast.textContent=m; toast.classList.add("show"); clearTimeout(tmr); tmr=setTimeout(()=>toast.classList.remove("show"),1900); }
318
- document.querySelectorAll("[data-prompt]").forEach(el=>{
319
- el.addEventListener("click",()=>{
320
- const p=el.getAttribute("data-prompt");
321
- if(navigator.clipboard&&navigator.clipboard.writeText){
322
- navigator.clipboard.writeText(p).then(()=>flash("Prompt copied — paste it to Claude 🧭")).catch(()=>flash(p));
323
- } else { flash("Copy this: "+p); }
324
- });
325
- });
326
- })();
327
- </script>
225
+ return `<!doctype html>
226
+ <html lang="en"><head>
227
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
228
+ <title>Career Compass — Pipeline</title>
229
+ <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='7' fill='%231f1e1d'/%3E%3Ccircle cx='16' cy='16' r='10' fill='%23c2603c'/%3E%3Cpath d='M20.5 10.5 L14.5 17.5 L11.5 21.5 L17.5 14.5 Z' fill='%231f1e1d'/%3E%3C/svg%3E">
230
+ <style>
231
+ /* Warm neutrals + clay accent, so the page sits inside Claude rather than
232
+ next to it, and follows the host's light/dark preference instead of
233
+ blinding anyone running Claude Desktop in dark mode. */
234
+ :root{color-scheme:light dark;--bg:#faf9f5;--card:#fff;--ink:#1f1e1d;--muted:#6b675f;--line:#e8e5dd;--accent:#c2603c;--accent-soft:#f6ece7;--sunk:#f5f3ed;--shadow:0 1px 2px rgba(31,30,29,.05),0 4px 14px rgba(31,30,29,.04)}
235
+ @media(prefers-color-scheme:dark){:root{--bg:#1f1e1d;--card:#262624;--ink:#f2efe8;--muted:#a5a096;--line:#37352f;--accent:#e08560;--accent-soft:#33241d;--sunk:#221f1d;--shadow:0 1px 2px rgba(0,0,0,.3),0 4px 14px rgba(0,0,0,.22)}}
236
+ *{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased}
237
+ .wrap{max-width:1180px;margin:0 auto;padding:20px 20px 64px}
238
+ header.top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:18px}
239
+ h1{font-size:20px;margin:0 0 2px;letter-spacing:-.01em}.sub{color:var(--muted);font-size:12.5px}
240
+ .chip{display:inline-flex;align-items:center;gap:6px;background:var(--accent-soft);color:var(--accent);border-radius:999px;padding:4px 10px;font-size:12px;font-weight:600}
241
+ .kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:20px}
242
+ .kpi{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:14px 16px;box-shadow:var(--shadow)}
243
+ .kpi .n{font-size:26px;font-weight:700;letter-spacing:-.02em}
244
+ .kpi.is-undefined .n{color:var(--muted);font-weight:500}.kpi .l{color:var(--muted);font-size:12px;margin-top:2px}.kpi .foot{font-size:11.5px;margin-top:6px;color:var(--muted)}
245
+ /* minmax(0,…) is load-bearing, not decoration. A grid item's default
246
+ min-width is auto — its min-content — so a bare 1fr track is a *floor*,
247
+ not a cap: one long unbreakable token in a company name or a follow-up
248
+ label grows its own rail past its share, and the sibling rail is squeezed
249
+ to whatever is left. Measured on the sample pipeline at 1512px, the rails
250
+ went 1263px / 175px, the chart track collapsed to 3px, and the page ran
251
+ 135px off the right edge. minmax(0,1fr) lets the item shrink; the
252
+ overflow-wrap below is what keeps the token itself inside the card once
253
+ the box stops growing to fit it. */
254
+ .grid2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;align-items:start}@media(max-width:900px){.grid2{grid-template-columns:minmax(0,1fr)}}
255
+ .grid2>*,.board>*{min-width:0}
256
+ .action .t b,.jc .co,.jc .ro{overflow-wrap:anywhere}
257
+ .panel{background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow)}
258
+ .panel h2{font-size:13px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:0;padding:14px 16px;border-bottom:1px solid var(--line)}
259
+ .panel .body{padding:14px 16px}.chart-box{position:relative;display:flex;gap:10px}
260
+ .bar-row{display:flex;flex-direction:column;gap:9px;width:100%}
261
+ .bar{display:flex;align-items:center;gap:10px}.bar .lab{width:96px;font-size:12px;color:var(--muted);text-align:right;flex:0 0 auto}
262
+ .bar .track{flex:1;background:var(--sunk);border-radius:6px;height:22px;overflow:hidden}
263
+ /* display:block is load-bearing. These are <span>s, and width has no effect on
264
+ an inline box — so every bar in this chart rendered as an empty track. */
265
+ .bar .fill{display:block;height:100%;border-radius:6px;min-width:3px;transition:width .3s ease}
266
+ .bar .val{font-size:12px;font-weight:600;width:22px}
267
+ .action{display:flex;gap:10px;padding:11px 0;border-bottom:1px dashed var(--line)}.action:last-child{border-bottom:0}
268
+ .action .dot{width:8px;height:8px;border-radius:50%;margin-top:6px;flex:0 0 auto;background:var(--accent)}
269
+ .action.overdue .dot{background:#ef4444}.action.soon .dot{background:#f59e0b}
270
+ .action .t{flex:1}.action .t b{display:block;font-size:13.5px}.action .t span{color:var(--muted);font-size:12px}
271
+ .board{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:12px;align-items:start}
272
+ .col{background:var(--sunk);border:1px solid var(--line);border-radius:12px;min-height:80px}
273
+ .col .h{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--line);font-weight:600;font-size:12.5px;text-transform:capitalize}
274
+ .col .h .sw{width:9px;height:9px;border-radius:50%}.col .h .count{margin-left:auto;background:var(--sunk);color:var(--muted);border:1px solid var(--line);border-radius:999px;font-size:11px;padding:1px 8px}
275
+ .col .stack{padding:10px;display:flex;flex-direction:column;gap:9px}.none{color:var(--muted);font-size:11.5px;padding:4px 2px}.none-lg{color:var(--muted);font-size:13px}
276
+ .jc{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--stage,#ccc);border-radius:10px;padding:10px 11px;cursor:pointer;transition:.12s}
277
+ .jc:hover{box-shadow:var(--shadow);transform:translateY(-1px)}.jc .co{font-weight:650;font-size:13px}.jc .ro{color:var(--muted);font-size:12px;margin-top:1px}
278
+ .jc .meta{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;align-items:center}
279
+ .pill{font-size:10.5px;padding:2px 7px;border-radius:999px;font-weight:600}.p-high{background:color-mix(in srgb,#ef4444 16%,transparent);color:#c04a3a}.p-medium{background:color-mix(in srgb,#f59e0b 18%,transparent);color:#a06a1b}.p-low{background:color-mix(in srgb,var(--muted) 16%,transparent);color:var(--muted)}
280
+ .exc{font-size:11px;color:var(--muted);margin-left:auto}
281
+ .btn{border:1px solid var(--line);background:var(--card);color:var(--ink);border-radius:9px;padding:7px 12px;font-size:12.5px;font-weight:600;cursor:pointer;transition:.12s}
282
+ .btn:hover{border-color:var(--accent);color:var(--accent)}.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}.btn.primary:hover{filter:brightness(.93)}
283
+ .toolbar{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 14px}
284
+ .state{text-align:center;padding:48px 20px;color:var(--muted)}.state h3{color:var(--ink);font-size:16px;margin:0 0 6px}.state .btns{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:16px}
285
+ .foot-note{color:var(--muted);font-size:11.5px;margin-top:22px;text-align:center}
286
+ #toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%) translateY(20px);background:var(--ink);color:var(--card);padding:10px 16px;border-radius:10px;font-size:13px;opacity:0;transition:.2s;pointer-events:none}
287
+ #toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
288
+ .closed{margin-top:12px;border-top:1px solid var(--line);padding-top:10px}
289
+ .closed summary{cursor:pointer;list-style:none;display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;color:var(--muted);padding:4px 2px;border-radius:8px}
290
+ .closed summary::-webkit-details-marker{display:none}
291
+ .closed summary::before{content:"▸";display:inline-block;transition:transform .15s;color:var(--muted);font-size:11px}
292
+ .closed[open] summary::before{transform:rotate(90deg)}
293
+ .closed summary:hover{color:var(--ink)}
294
+ .closed .dots{display:inline-flex;gap:4px;margin-left:2px}
295
+ .closed .dots .sw{width:8px;height:8px;border-radius:50%}
296
+ .closed .board{margin-top:10px}
297
+ .hidden{display:none!important}
298
+ </style></head>
299
+ <body><div class="wrap">
300
+ <header class="top">
301
+ <div><h1>🧭 Career Compass — Pipeline</h1>
302
+ <div class="sub">Live view of your job search · re-read from disk on every load · last write ${esc(lastUpdated)}</div></div>
303
+ <div class="chip">● local</div>
304
+ </header>
305
+ <div class="toolbar">
306
+ <button class="btn primary" data-prompt="What should I focus on in my job search today? Look at my pipeline and give me the 3 highest-leverage moves.">🎯 Copy: what should I do today?</button>
307
+ <button class="btn" data-prompt="Review my whole pipeline and flag anything stale, single-threaded, or at risk of going cold.">🔍 Copy: health check</button>
308
+ </div>
309
+ ${kpis ? `<div class="kpis">${kpis}</div>` : ""}
310
+ ${apps.length === 0 ? emptyState : `
311
+ <div class="panel" style="margin-bottom:16px">
312
+ <h2>Pipeline by stage</h2>
313
+ <div class="body"><div class="board">${board}</div>${closedBoard}</div>
314
+ </div>
315
+ <div class="grid2">
316
+ <div class="panel"><h2>Next actions</h2><div class="body">${actionsHtml}</div></div>
317
+ <div class="panel"><h2>Stage distribution</h2><div class="body"><div id="chart" class="chart-box"></div></div></div>
318
+ </div>`}
319
+ <div class="foot-note">${dataDir ? `Data stays local (<code>${esc(dataDir)}</code>).` : "Data stays local on this machine."} Click any card to copy a prompt for Claude — that's where the work happens. Refresh the page to re-read from disk.</div>
320
+ </div>
321
+ <div id="toast"></div>
322
+ <script>
323
+ const CHART=${chartData};
324
+ (function(){
325
+ const box=document.getElementById("chart");
326
+ if(box&&CHART.length){
327
+ const max=Math.max(...CHART.map(d=>d.value),1);
328
+ // Escaped on the way into innerHTML for the same reason jsonForScript exists:
329
+ // these values are enum-derived today and this is the only place on the page
330
+ // that builds markup from data at runtime.
331
+ const h=s=>String(s).replace(/[&<>"']/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c]));
332
+ box.innerHTML='<div class="bar-row">'+CHART.map(d=>
333
+ '<div class="bar"><span class="lab">'+h(d.label)+'</span><span class="track"><span class="fill" style="width:'+(Number(d.value)/max*100)+'%;background:'+h(d.color)+'"></span></span><span class="val">'+h(d.value)+'</span></div>'
334
+ ).join("")+'</div>';
335
+ } else if(box){ box.innerHTML='<div class="none-lg">No active applications yet.</div>'; }
336
+ const toast=document.getElementById("toast"); let tmr;
337
+ function flash(m){ toast.textContent=m; toast.classList.add("show"); clearTimeout(tmr); tmr=setTimeout(()=>toast.classList.remove("show"),1900); }
338
+ document.querySelectorAll("[data-prompt]").forEach(el=>{
339
+ el.addEventListener("click",()=>{
340
+ const p=el.getAttribute("data-prompt");
341
+ if(navigator.clipboard&&navigator.clipboard.writeText){
342
+ navigator.clipboard.writeText(p).then(()=>flash("Prompt copied — paste it to Claude 🧭")).catch(()=>flash(p));
343
+ } else { flash("Copy this: "+p); }
344
+ });
345
+ });
346
+ })();
347
+ </script>
328
348
  </body></html>`;
329
349
  }
330
350
  //# sourceMappingURL=render.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/dashboard-lite/render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/dashboard-lite/render.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,76 +1,76 @@
1
- {
2
- "name": "career-compass-mcp",
3
- "version": "2.5.0",
4
- "description": "AI-native career co-pilot for Claude — Career KB, resume tailoring, job pipeline, interview prep, and offer evaluation via MCP",
5
- "type": "module",
6
- "main": "build/src/index.js",
7
- "bin": {
8
- "career-compass-mcp": "build/bin/cli.js"
9
- },
10
- "files": [
11
- "build/",
12
- "!build/**/__tests__/**",
13
- "!build/**/*.test.*",
14
- "data/example/",
15
- "README.md",
16
- "LICENSE"
17
- ],
18
- "engines": {
19
- "node": ">=18.0.0"
20
- },
21
- "scripts": {
22
- "build": "tsc && npm run build:dashboard",
23
- "build:dashboard": "cd dashboard && npx next build",
24
- "build:mcp": "tsc",
25
- "dev": "tsc --watch",
26
- "dev:dashboard": "cd dashboard && npx next dev --turbopack",
27
- "start": "node build/src/index.js",
28
- "dashboard": "node build/bin/cli.js dashboard",
29
- "test": "npm run test:mcp && npm run test:dashboard",
30
- "storybook": "cd dashboard && npx storybook dev -p 6006",
31
- "test:mcp": "vitest run --config vitest.config.ts",
32
- "screenshots": "npx tsx scripts/capture-screenshots.ts",
33
- "inspect": "mcp-inspector node build/src/index.js",
34
- "gen:manifest": "npm run build:mcp && node scripts/gen-manifest-tools.mjs",
35
- "pack:guard": "vitest run --config vitest.config.ts src/__tests__/npm-pack-leak-guard.test.ts",
36
- "pack:mcpb": "npm run build:mcp && node scripts/pack-mcpb.mjs",
37
- "pack:mcpb:guard": "node scripts/mcpb-guard.mjs",
38
- "prepublishOnly": "npm run build:mcp && npm run test:mcp && npm run pack:guard",
39
- "test:dashboard": "cd dashboard && npx vitest run"
40
- },
41
- "keywords": [
42
- "mcp",
43
- "mcp-server",
44
- "career",
45
- "job-search",
46
- "resume",
47
- "interview-prep",
48
- "application-tracking",
49
- "claude",
50
- "anthropic",
51
- "ai"
52
- ],
53
- "author": "Ben Schippers",
54
- "license": "MIT",
55
- "repository": {
56
- "type": "git",
57
- "url": "https://github.com/benskamps/career-compass-mcp.git"
58
- },
59
- "homepage": "https://github.com/benskamps/career-compass-mcp#readme",
60
- "bugs": {
61
- "url": "https://github.com/benskamps/career-compass-mcp/issues"
62
- },
63
- "dependencies": {
64
- "@modelcontextprotocol/sdk": "^1.28.0",
65
- "yaml": "^2.8.3",
66
- "zod": "^4.3.6"
67
- },
68
- "devDependencies": {
69
- "@modelcontextprotocol/inspector": "^0.21.1",
70
- "@types/node": "^25.5.0",
71
- "playwright": "^1.59.1",
72
- "tsx": "^4.21.0",
73
- "typescript": "^6.0.2",
74
- "vitest": "^4.1.2"
75
- }
76
- }
1
+ {
2
+ "name": "career-compass-mcp",
3
+ "version": "2.5.1",
4
+ "description": "AI-native career co-pilot for Claude — Career KB, resume tailoring, job pipeline, interview prep, and offer evaluation via MCP",
5
+ "type": "module",
6
+ "main": "build/src/index.js",
7
+ "bin": {
8
+ "career-compass-mcp": "build/bin/cli.js"
9
+ },
10
+ "files": [
11
+ "build/",
12
+ "!build/**/__tests__/**",
13
+ "!build/**/*.test.*",
14
+ "data/example/",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "engines": {
19
+ "node": ">=18.0.0"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc && npm run build:dashboard",
23
+ "build:dashboard": "cd dashboard && npx next build && cd .. && node scripts/stage-standalone.mjs",
24
+ "build:mcp": "tsc",
25
+ "dev": "tsc --watch",
26
+ "dev:dashboard": "cd dashboard && npx next dev --turbopack",
27
+ "start": "node build/src/index.js",
28
+ "dashboard": "node build/bin/cli.js dashboard",
29
+ "test": "npm run test:mcp && npm run test:dashboard",
30
+ "storybook": "cd dashboard && npx storybook dev -p 6006",
31
+ "test:mcp": "vitest run --config vitest.config.ts",
32
+ "inspect": "mcp-inspector node build/src/index.js",
33
+ "gen:manifest": "npm run build:mcp && node scripts/gen-manifest-tools.mjs",
34
+ "pack:guard": "vitest run --config vitest.config.ts src/__tests__/npm-pack-leak-guard.test.ts",
35
+ "pack:mcpb": "npm run build:mcp && node scripts/pack-mcpb.mjs",
36
+ "pack:mcpb:guard": "node scripts/mcpb-guard.mjs",
37
+ "prepublishOnly": "npm run build:mcp && npm run test:mcp && npm run pack:guard",
38
+ "test:dashboard": "cd dashboard && npx vitest run",
39
+ "visuals": "node scripts/visual-harness.mjs"
40
+ },
41
+ "keywords": [
42
+ "mcp",
43
+ "mcp-server",
44
+ "career",
45
+ "job-search",
46
+ "resume",
47
+ "interview-prep",
48
+ "application-tracking",
49
+ "claude",
50
+ "anthropic",
51
+ "ai"
52
+ ],
53
+ "author": "Ben Schippers",
54
+ "license": "MIT",
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "https://github.com/benskamps/career-compass-mcp.git"
58
+ },
59
+ "homepage": "https://github.com/benskamps/career-compass-mcp#readme",
60
+ "bugs": {
61
+ "url": "https://github.com/benskamps/career-compass-mcp/issues"
62
+ },
63
+ "dependencies": {
64
+ "@modelcontextprotocol/sdk": "^1.28.0",
65
+ "yaml": "^2.8.3",
66
+ "zod": "^4.3.6"
67
+ },
68
+ "devDependencies": {
69
+ "@modelcontextprotocol/inspector": "^0.21.1",
70
+ "@types/node": "^25.5.0",
71
+ "playwright": "^1.59.1",
72
+ "tsx": "^4.21.0",
73
+ "typescript": "^6.0.2",
74
+ "vitest": "^4.1.2"
75
+ }
76
+ }