clementine-agent 1.18.157 → 1.18.159

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.
@@ -12,4 +12,5 @@ export declare function killExistingDashboards(): number;
12
12
  export declare function cmdDashboard(opts: {
13
13
  port?: string;
14
14
  }): Promise<void>;
15
+ export declare function getDashboardHTML(token: string): string;
15
16
  //# sourceMappingURL=dashboard.d.ts.map
@@ -1762,11 +1762,10 @@ export async function cmdDashboard(opts) {
1762
1762
  if (process.env.NO_BROWSER !== '1') {
1763
1763
  setTimeout(() => {
1764
1764
  try {
1765
- const tokenPath = path.join(BASE_DIR, '.dashboard-token');
1766
- const token = existsSync(tokenPath) ? readFileSync(tokenPath, 'utf-8').trim() : '';
1767
- if (!token)
1768
- return;
1769
- const url = `http://localhost:${childPort}/?token=${token}`;
1765
+ // 1.18.159 open the bare URL. Token comes from the meta tag
1766
+ // in the served HTML (persistent since 1.18.152). Bare URL also
1767
+ // sidesteps Chrome's per-query-string HTML cache entries.
1768
+ const url = `http://localhost:${childPort}`;
1770
1769
  const platform = process.platform;
1771
1770
  const cmd = platform === 'darwin' ? 'open'
1772
1771
  : platform === 'win32' ? 'start'
@@ -13550,7 +13549,10 @@ self.addEventListener('activate', e => {
13550
13549
  await new Promise(() => { });
13551
13550
  }
13552
13551
  // ── Inline HTML Dashboard ────────────────────────────────────────────
13553
- function getDashboardHTML(token) {
13552
+ // Exported for testability — see tests/dashboard-spa-parses.test.ts.
13553
+ // 1.18.158 added that test as a guard against the recurring "served
13554
+ // HTML inline JS doesn't parse" bug (1.18.142 + 1.18.155).
13555
+ export function getDashboardHTML(token) {
13554
13556
  const name = getAssistantName();
13555
13557
  return `<!DOCTYPE html>
13556
13558
  <html lang="en">
@@ -25616,7 +25618,13 @@ function renderScheduledTaskCard(task) {
25616
25618
  // less safe path, worth flagging) or when lean mode is in effect for a
25617
25619
  // meta-job (worth showing because it explains why the prompt is small).
25618
25620
  if (task.lean === true) {
25619
- badges += '<span class="badge badge-purple" title="Lean envelope drops every auto-injected context block (memory, progress, goal, criteria, skills) and prunes the MCP catalog. Used for meta-jobs that must stay under Haiku\'s prompt cap.">Lean</span>';
25621
+ // 1.18.158 hotfix apostrophe in title= breaks JS parser. Outer
25622
+ // template literal converts \' → ', the resulting served HTML has
25623
+ // 'Haiku's' inside a single-quoted JS string, which terminates the
25624
+ // string early and crashes the entire SPA. Use HTML entity to be
25625
+ // safe across both layers (also valid inside JS strings since &#39;
25626
+ // is just text characters, no special meaning).
25627
+ badges += '<span class="badge badge-purple" title="Lean envelope — drops every auto-injected context block (memory, progress, goal, criteria, skills) and prunes the MCP catalog. Used for meta-jobs that must stay under Haiku&#39;s prompt cap.">Lean</span>';
25620
25628
  } else if (task.predictable === false) {
25621
25629
  badges += '<span class="badge badge-yellow" title="Dynamic mode — fire-time injects MEMORY.md, recent team activity, and auto-matched skills. Can drift from chat-time intent.">Reads memory</span>';
25622
25630
  }
package/dist/cli/index.js CHANGED
@@ -497,25 +497,23 @@ async function relaunchDashboardDetached(opts = {}) {
497
497
  // print the URL. If it never binds, the URL still prints (user
498
498
  // can retry) but we surface the failure in logs.
499
499
  await new Promise(resolve => setTimeout(resolve, 3000));
500
- let token = '';
501
- try {
502
- const tokenPath = path.join(BASE_DIR, '.dashboard-token');
503
- if (existsSync(tokenPath))
504
- token = readFileSync(tokenPath, 'utf-8').trim();
505
- }
506
- catch { /* token may not be ready yet */ }
507
- if (token) {
508
- const url = `http://localhost:3030/?token=${token}`;
509
- console.log(` Dashboard relaunched: ${url}`);
510
- // 1.18.147 auto-open the browser by default. Restart/update
511
- // already imply user wants the dashboard back; making them copy a
512
- // URL was a UX papercut.
513
- if (opts.open !== false)
514
- openInBrowser(url);
515
- }
516
- else {
517
- console.log(' Dashboard relaunched (token not ready — check `clementine status`).');
518
- }
500
+ // 1.18.159 — print the bare URL, not the `?token=...` flavor.
501
+ // Token is delivered via meta tag in the served HTML (since 1.18.152
502
+ // when token persistence shipped). The token-in-URL flavor was a
503
+ // pre-1.18.152 habit and turned into a footgun: Chrome caches HTML
504
+ // by full URL including query string, so a stale `?token=ABC` cache
505
+ // entry survives across redeploys while bare `localhost:3030` pulls
506
+ // fresh HTML. Restart printing the bare URL also nudges users to
507
+ // bookmark THAT (which keeps working forever) instead of the
508
+ // token-flavored one (which would silently OK after a 1.18.152+
509
+ // restart but caches indefinitely on 1.18.151- installs).
510
+ const url = 'http://localhost:3030';
511
+ console.log(` Dashboard relaunched: ${url}`);
512
+ // 1.18.147 auto-open the browser by default. Restart/update
513
+ // already imply user wants the dashboard back; making them copy a
514
+ // URL was a UX papercut.
515
+ if (opts.open !== false)
516
+ openInBrowser(url);
519
517
  }
520
518
  catch {
521
519
  console.log(' Could not relaunch dashboard — run: clementine dashboard');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.18.157",
3
+ "version": "1.18.159",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",