@rubytech/create-sitedesk-code 0.1.402 → 0.1.405

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 (71) hide show
  1. package/dist/__tests__/launchd-plist.test.js +13 -1
  2. package/dist/__tests__/neo4j-darwin-dedicated.test.js +52 -0
  3. package/dist/__tests__/neo4j-datadir.test.js +8 -7
  4. package/dist/__tests__/neo4j-teardown.test.js +17 -1
  5. package/dist/index.js +183 -9
  6. package/dist/launchd-plist.js +21 -0
  7. package/dist/neo4j-darwin-dedicated.js +39 -0
  8. package/dist/neo4j-datadir.js +9 -5
  9. package/dist/neo4j-teardown.js +15 -0
  10. package/dist/uninstall.js +34 -8
  11. package/package.json +1 -1
  12. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +2 -2
  13. package/payload/platform/plugins/web-designer/skills/web-design/references/placeholders.md +19 -2
  14. package/payload/platform/plugins/web-designer/skills/web-design/templates/index.html +12 -12
  15. package/payload/platform/scripts/check-no-esm-require.mjs +3 -0
  16. package/payload/premium-plugins/sitedesk/BUNDLE.md +6 -4
  17. package/payload/premium-plugins/sitedesk/PLUGIN.md +2 -2
  18. package/payload/premium-plugins/sitedesk/agents/sitedesk--media-producer.md +18 -7
  19. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/.claude-plugin/plugin.json +1 -1
  20. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/PLUGIN.md +30 -26
  21. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/README.md +26 -36
  22. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/commands/make-media.md +2 -2
  23. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/microsite/SKILL.md +52 -75
  24. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/socials/SKILL.md +52 -120
  25. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/socials/references/sources.md +17 -52
  26. package/payload/server/public/assets/{AdminLoginScreens-rlk263u9.js → AdminLoginScreens-D36zz_SY.js} +1 -1
  27. package/payload/server/public/assets/AdminShell-DH6Lcj-d.js +1 -0
  28. package/payload/server/public/assets/{Checkbox-Chz6bfy-.js → Checkbox-54KtArF3.js} +1 -1
  29. package/payload/server/public/assets/{Transcript-Bsx-bGgY.js → Transcript-BCpiXt4J.js} +1 -1
  30. package/payload/server/public/assets/{admin-BnZH758N.js → admin-C0FCHcJj.js} +1 -1
  31. package/payload/server/public/assets/{browser-CIrfyZWe.js → browser-bKeZ5iLx.js} +1 -1
  32. package/payload/server/public/assets/{calendar-D6Z8Kmrn.js → calendar-BDPBArFA.js} +1 -1
  33. package/payload/server/public/assets/chat-Cp_1ebzU.js +1 -0
  34. package/payload/server/public/assets/chevron-left-S7Nk-se6.js +1 -0
  35. package/payload/server/public/assets/data-BshlTgIW.js +1 -0
  36. package/payload/server/public/assets/{graph-XZJZHzvv.js → graph-Dvru9CW9.js} +1 -1
  37. package/payload/server/public/assets/{graph-labels-Cabqmf35.js → graph-labels-DLhR6Rit.js} +1 -1
  38. package/payload/server/public/assets/{maximize-2-DPe-Noig.js → maximize-2-CyPKq7HZ.js} +1 -1
  39. package/payload/server/public/assets/{operator-BM_CDyCb.js → operator-Ql5iQXB-.js} +1 -1
  40. package/payload/server/public/assets/page-ClJOW2fk.js +32 -0
  41. package/payload/server/public/assets/{page-E7I5sEVt.js → page-YsTtZsn6.js} +1 -1
  42. package/payload/server/public/assets/{public-CrdWCSk2.js → public-BlDxwcmS.js} +1 -1
  43. package/payload/server/public/assets/{rotate-ccw-Dwtj0NJ7.js → rotate-ccw-DSynJPZX.js} +1 -1
  44. package/payload/server/public/assets/useSubAccountSwitcher-CJelLQK-.css +1 -0
  45. package/payload/server/public/browser.html +4 -4
  46. package/payload/server/public/calendar.html +5 -5
  47. package/payload/server/public/chat.html +9 -9
  48. package/payload/server/public/data.html +8 -8
  49. package/payload/server/public/graph.html +9 -9
  50. package/payload/server/public/index.html +11 -11
  51. package/payload/server/public/operator.html +11 -11
  52. package/payload/server/public/public.html +9 -9
  53. package/payload/server/server.js +34 -32
  54. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/brand-extract/SKILL.md +0 -86
  55. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/make-media/SKILL.md +0 -75
  56. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/make-media/references/intake-and-questions.md +0 -74
  57. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/microsite/references/placeholders.md +0 -96
  58. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/microsite/references/sections.md +0 -48
  59. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/microsite/templates/index.html +0 -1004
  60. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/microsite/templates/llms.txt +0 -32
  61. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/socials/references/pii-strip.md +0 -64
  62. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/socials/templates/og.html +0 -92
  63. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/socials/templates/social-posts.md +0 -47
  64. package/payload/premium-plugins/sitedesk/plugins/sitedesk-media/skills/socials/templates/socials.html +0 -87
  65. package/payload/server/public/assets/AdminShell-C5vWTy2n.js +0 -1
  66. package/payload/server/public/assets/chat-h7SytZHx.js +0 -1
  67. package/payload/server/public/assets/chevron-left-DSTeS1_g.js +0 -1
  68. package/payload/server/public/assets/data-CL7CyX1C.js +0 -1
  69. package/payload/server/public/assets/page-CMIbXzSg.js +0 -32
  70. package/payload/server/public/assets/useSubAccountSwitcher-BH-YjP0H.css +0 -1
  71. /package/payload/server/public/assets/{useSubAccountSwitcher-BVCMAnWK.js → useSubAccountSwitcher-DGKQxXDD.js} +0 -0
@@ -5,20 +5,20 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>SiteDesk</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/admin-BnZH758N.js"></script>
8
+ <script type="module" crossorigin src="/assets/admin-C0FCHcJj.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-BVCMAnWK.js">
11
- <link rel="modulepreload" crossorigin href="/assets/graph-labels-Cabqmf35.js">
12
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-C5vWTy2n.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DGKQxXDD.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/graph-labels-DLhR6Rit.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DH6Lcj-d.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/admin-types-hioowVct.js">
14
- <link rel="modulepreload" crossorigin href="/assets/Checkbox-Chz6bfy-.js">
15
- <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-rlk263u9.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/Checkbox-54KtArF3.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-D36zz_SY.js">
16
16
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-CvXuAEud.js">
17
- <link rel="modulepreload" crossorigin href="/assets/maximize-2-DPe-Noig.js">
18
- <link rel="modulepreload" crossorigin href="/assets/Transcript-Bsx-bGgY.js">
19
- <link rel="modulepreload" crossorigin href="/assets/chevron-left-DSTeS1_g.js">
20
- <link rel="modulepreload" crossorigin href="/assets/page-E7I5sEVt.js">
21
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-BH-YjP0H.css">
17
+ <link rel="modulepreload" crossorigin href="/assets/maximize-2-CyPKq7HZ.js">
18
+ <link rel="modulepreload" crossorigin href="/assets/Transcript-BCpiXt4J.js">
19
+ <link rel="modulepreload" crossorigin href="/assets/chevron-left-S7Nk-se6.js">
20
+ <link rel="modulepreload" crossorigin href="/assets/page-YsTtZsn6.js">
21
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-CJelLQK-.css">
22
22
  <link rel="stylesheet" crossorigin href="/assets/AdminLoginScreens-CWMpccrR.css">
23
23
  <link rel="stylesheet" href="/brand-defaults.css">
24
24
  </head>
@@ -5,20 +5,20 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Operator — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/operator-BM_CDyCb.js"></script>
8
+ <script type="module" crossorigin src="/assets/operator-Ql5iQXB-.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-BVCMAnWK.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-C5vWTy2n.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DGKQxXDD.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DH6Lcj-d.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/admin-types-hioowVct.js">
13
- <link rel="modulepreload" crossorigin href="/assets/Checkbox-Chz6bfy-.js">
14
- <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-rlk263u9.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/Checkbox-54KtArF3.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-D36zz_SY.js">
15
15
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-CvXuAEud.js">
16
- <link rel="modulepreload" crossorigin href="/assets/maximize-2-DPe-Noig.js">
17
- <link rel="modulepreload" crossorigin href="/assets/Transcript-Bsx-bGgY.js">
18
- <link rel="modulepreload" crossorigin href="/assets/chevron-left-DSTeS1_g.js">
19
- <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-Dwtj0NJ7.js">
20
- <link rel="modulepreload" crossorigin href="/assets/page-CMIbXzSg.js">
21
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-BH-YjP0H.css">
16
+ <link rel="modulepreload" crossorigin href="/assets/maximize-2-CyPKq7HZ.js">
17
+ <link rel="modulepreload" crossorigin href="/assets/Transcript-BCpiXt4J.js">
18
+ <link rel="modulepreload" crossorigin href="/assets/chevron-left-S7Nk-se6.js">
19
+ <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-DSynJPZX.js">
20
+ <link rel="modulepreload" crossorigin href="/assets/page-ClJOW2fk.js">
21
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-CJelLQK-.css">
22
22
  <link rel="stylesheet" crossorigin href="/assets/AdminLoginScreens-CWMpccrR.css">
23
23
  <link rel="stylesheet" href="/brand-defaults.css">
24
24
  </head>
@@ -5,18 +5,18 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>SiteDesk</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/public-CrdWCSk2.js"></script>
8
+ <script type="module" crossorigin src="/assets/public-BlDxwcmS.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-BVCMAnWK.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-C5vWTy2n.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DGKQxXDD.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DH6Lcj-d.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/admin-types-hioowVct.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-CvXuAEud.js">
14
- <link rel="modulepreload" crossorigin href="/assets/maximize-2-DPe-Noig.js">
15
- <link rel="modulepreload" crossorigin href="/assets/Transcript-Bsx-bGgY.js">
16
- <link rel="modulepreload" crossorigin href="/assets/chevron-left-DSTeS1_g.js">
17
- <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-Dwtj0NJ7.js">
18
- <link rel="modulepreload" crossorigin href="/assets/page-CMIbXzSg.js">
19
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-BH-YjP0H.css">
14
+ <link rel="modulepreload" crossorigin href="/assets/maximize-2-CyPKq7HZ.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/Transcript-BCpiXt4J.js">
16
+ <link rel="modulepreload" crossorigin href="/assets/chevron-left-S7Nk-se6.js">
17
+ <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-DSynJPZX.js">
18
+ <link rel="modulepreload" crossorigin href="/assets/page-ClJOW2fk.js">
19
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-CJelLQK-.css">
20
20
  <link rel="stylesheet" href="/brand-defaults.css">
21
21
  </head>
22
22
  <body class="public-surface">
@@ -1417,7 +1417,7 @@ function webchatChannelDescriptor(key) {
1417
1417
  }
1418
1418
 
1419
1419
  // app/lib/claude-auth.ts
1420
- import { readFileSync, writeFileSync } from "fs";
1420
+ import { readFileSync, writeFileSync, renameSync, unlinkSync } from "fs";
1421
1421
  import { sep } from "path";
1422
1422
  import { lock } from "proper-lockfile";
1423
1423
  if (!CLAUDE_CREDENTIALS_FILE.startsWith(MAXY_DIR + sep)) {
@@ -1473,7 +1473,17 @@ function writeOAuthCredentials(tokens) {
1473
1473
  ...tokens.refreshToken != null ? { refreshToken: tokens.refreshToken } : {},
1474
1474
  expiresAt: newExpiresAt
1475
1475
  };
1476
- writeFileSync(CLAUDE_CREDENTIALS_FILE, JSON.stringify(fileData, null, 2), "utf-8");
1476
+ const tmpPath = `${CLAUDE_CREDENTIALS_FILE}.${process.pid}.tmp`;
1477
+ try {
1478
+ writeFileSync(tmpPath, JSON.stringify(fileData, null, 2), "utf-8");
1479
+ renameSync(tmpPath, CLAUDE_CREDENTIALS_FILE);
1480
+ } catch (writeErr) {
1481
+ try {
1482
+ unlinkSync(tmpPath);
1483
+ } catch {
1484
+ }
1485
+ throw writeErr;
1486
+ }
1477
1487
  return newExpiresAt;
1478
1488
  } catch (err) {
1479
1489
  console.error(`[claude-auth] credential write failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -8315,6 +8325,8 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
8315
8325
  if (!isScheduleSource(text)) {
8316
8326
  renderOrSuppressChannelInbound(unwrapChannel(text), ts, out, queuedPendingSuppress);
8317
8327
  }
8328
+ } else if (row.isMeta === true) {
8329
+ out.push({ kind: "harness-internal", text, ts });
8318
8330
  } else {
8319
8331
  out.push({ kind: "operator-typed", text, ts });
8320
8332
  }
@@ -9259,10 +9271,10 @@ var public_reader_default = app5;
9259
9271
  // server/routes/webchat.ts
9260
9272
  import { basename as basename7, dirname as dirname6 } from "path";
9261
9273
  import { join as join18 } from "path";
9262
- import { existsSync as existsSync10, readdirSync as readdirSync11, readFileSync as readFileSync19, renameSync as renameSync3, statSync as statSync7, writeFileSync as writeFileSync7 } from "fs";
9274
+ import { existsSync as existsSync10, readdirSync as readdirSync11, readFileSync as readFileSync19, renameSync as renameSync4, statSync as statSync7, writeFileSync as writeFileSync7 } from "fs";
9263
9275
 
9264
9276
  // server/canonical-webchat-override.ts
9265
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync5, renameSync } from "fs";
9277
+ import { readFileSync as readFileSync17, writeFileSync as writeFileSync5, renameSync as renameSync2 } from "fs";
9266
9278
  import { join as join16 } from "path";
9267
9279
  var FILE = "canonical-webchat-session.json";
9268
9280
  var UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
@@ -9300,7 +9312,7 @@ function writeCanonicalOverrideId(accountDir, userId, sessionId) {
9300
9312
  const path2 = canonicalOverridePath(accountDir);
9301
9313
  const tmp = `${path2}.${process.pid}.tmp`;
9302
9314
  writeFileSync5(tmp, JSON.stringify({ byAdmin }, null, 2), "utf8");
9303
- renameSync(tmp, path2);
9315
+ renameSync2(tmp, path2);
9304
9316
  }
9305
9317
 
9306
9318
  // ../lib/models/src/index.ts
@@ -9346,7 +9358,7 @@ function isNewSessionEffortLevel(value) {
9346
9358
  }
9347
9359
 
9348
9360
  // ../services/claude-session-manager/src/sidecar-store.ts
9349
- import { existsSync as existsSync9, mkdirSync as mkdirSync3, readdirSync as readdirSync10, readFileSync as readFileSync18, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
9361
+ import { existsSync as existsSync9, mkdirSync as mkdirSync3, readdirSync as readdirSync10, readFileSync as readFileSync18, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
9350
9362
  import { join as join17 } from "path";
9351
9363
  function escapeRegExp(s) {
9352
9364
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -9363,11 +9375,11 @@ function createSidecarStore(config) {
9363
9375
  const tmp = `${path2}.tmp.${process.pid}`;
9364
9376
  try {
9365
9377
  writeFileSync6(tmp, JSON.stringify(record), "utf8");
9366
- renameSync2(tmp, path2);
9378
+ renameSync3(tmp, path2);
9367
9379
  return { ok: true };
9368
9380
  } catch (error) {
9369
9381
  try {
9370
- if (existsSync9(tmp)) unlinkSync(tmp);
9382
+ if (existsSync9(tmp)) unlinkSync2(tmp);
9371
9383
  } catch {
9372
9384
  }
9373
9385
  return { ok: false, error };
@@ -9424,7 +9436,7 @@ function createSidecarStore(config) {
9424
9436
  const path2 = pathFor(sessionsDir, id);
9425
9437
  try {
9426
9438
  if (existsSync9(path2)) {
9427
- unlinkSync(path2);
9439
+ unlinkSync2(path2);
9428
9440
  return { ok: true, removed: true };
9429
9441
  }
9430
9442
  return { ok: true, removed: false };
@@ -9974,7 +9986,7 @@ ${note}` : note;
9974
9986
  else parsed.adminPermissionMode = value;
9975
9987
  const tmp = `${accountJsonPath}.${process.pid}.tmp`;
9976
9988
  writeFileSync7(tmp, JSON.stringify(parsed, null, 2), "utf8");
9977
- renameSync3(tmp, accountJsonPath);
9989
+ renameSync4(tmp, accountJsonPath);
9978
9990
  } catch (err) {
9979
9991
  const detail = err instanceof Error ? err.message : String(err);
9980
9992
  console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=write-failed detail=${detail}`);
@@ -10373,7 +10385,7 @@ var telegram_default = app7;
10373
10385
 
10374
10386
  // server/routes/quickbooks.ts
10375
10387
  import { join as join21 } from "path";
10376
- import { existsSync as existsSync13, readFileSync as readFileSync22, writeFileSync as writeFileSync8, mkdirSync as mkdirSync4, rmSync, renameSync as renameSync4 } from "fs";
10388
+ import { existsSync as existsSync13, readFileSync as readFileSync22, writeFileSync as writeFileSync8, mkdirSync as mkdirSync4, rmSync, renameSync as renameSync5 } from "fs";
10377
10389
  var TAG24 = "[quickbooks]";
10378
10390
  var INTUIT_TOKEN_URL = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
10379
10391
  var STATE_RE = /^[A-Za-z0-9_-]+$/;
@@ -10392,7 +10404,7 @@ async function completeConsent(args) {
10392
10404
  }
10393
10405
  const claimFile = `${pendingPath(accountDir, state)}.claimed`;
10394
10406
  try {
10395
- renameSync4(pendingPath(accountDir, state), claimFile);
10407
+ renameSync5(pendingPath(accountDir, state), claimFile);
10396
10408
  } catch {
10397
10409
  console.error(`${TAG24} op=callback state=${state} stateValid=false realmId=${realmId ?? ""}`);
10398
10410
  return { ok: false, status: 400, message: "Invalid or unknown authorization state.", stateValid: false };
@@ -10481,20 +10493,10 @@ var quickbooks_default = app8;
10481
10493
 
10482
10494
  // server/routes/onboarding.ts
10483
10495
  import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync3 } from "child_process";
10484
- import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync10, writeSync, existsSync as existsSync15, readFileSync as readFileSync24, unlinkSync as unlinkSync2, renameSync as renameSync6 } from "fs";
10496
+ import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync10, writeSync, existsSync as existsSync15, readFileSync as readFileSync24, unlinkSync as unlinkSync3, renameSync as renameSync7 } from "fs";
10485
10497
  import { createHash as createHash3, randomUUID as randomUUID7 } from "crypto";
10486
10498
 
10487
10499
  // app/lib/claude-spawn-env.ts
10488
- var HOST_AUTH_REFRESH_TIMEOUT_MS = "30000";
10489
- function hostCredsEnv(platform, credsFile) {
10490
- if (platform === "darwin" && credsFile) {
10491
- return {
10492
- CLAUDE_CODE_HOST_CREDS_FILE: credsFile,
10493
- CLAUDE_CODE_HOST_AUTH_REFRESH_TIMEOUT_MS: HOST_AUTH_REFRESH_TIMEOUT_MS
10494
- };
10495
- }
10496
- return {};
10497
- }
10498
10500
  function claudeBin() {
10499
10501
  return process.env.CLAUDE_BIN ?? "claude";
10500
10502
  }
@@ -10586,7 +10588,7 @@ function readHostCredsBlob(service) {
10586
10588
  }
10587
10589
 
10588
10590
  // ../lib/admins-write/src/index.ts
10589
- import { existsSync as existsSync14, readFileSync as readFileSync23, writeFileSync as writeFileSync9, renameSync as renameSync5, mkdirSync as mkdirSync5, readdirSync as readdirSync13, statSync as statSync8, appendFileSync as appendFileSync2 } from "fs";
10591
+ import { existsSync as existsSync14, readFileSync as readFileSync23, writeFileSync as writeFileSync9, renameSync as renameSync6, mkdirSync as mkdirSync5, readdirSync as readdirSync13, statSync as statSync8, appendFileSync as appendFileSync2 } from "fs";
10590
10592
  import { dirname as dirname7, join as join22 } from "path";
10591
10593
  function id8(value) {
10592
10594
  return value.slice(0, 8);
@@ -10621,7 +10623,7 @@ function writeFileAtomic(filePath, contents, mode) {
10621
10623
  mkdirSync5(dirname7(filePath), { recursive: true });
10622
10624
  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
10623
10625
  writeFileSync9(tempPath, contents, mode !== void 0 ? { mode } : void 0);
10624
- renameSync5(tempPath, filePath);
10626
+ renameSync6(tempPath, filePath);
10625
10627
  }
10626
10628
  function writeAdminEntry(input) {
10627
10629
  const result = { usersJsonResult: "noop", accountJsonResult: "noop" };
@@ -10818,7 +10820,7 @@ app9.post("/claude-auth", async (c) => {
10818
10820
  let logoutError = null;
10819
10821
  try {
10820
10822
  execFileSync3(claudeBin(), ["auth", "logout"], {
10821
- env: { ...process.env, ...hostCredsEnv(process.platform, CLAUDE_CREDENTIALS_FILE) },
10823
+ env: { ...process.env },
10822
10824
  encoding: "utf-8",
10823
10825
  timeout: 8e3
10824
10826
  });
@@ -10866,7 +10868,7 @@ app9.post("/claude-auth", async (c) => {
10866
10868
  vncLog("claude-auth", { action: "start", transport: "native", platform: "darwin" });
10867
10869
  darwinCredsBefore = listHostCredsMdats();
10868
10870
  const claudeProc2 = spawn(claudeBin(), ["auth", "login"], {
10869
- env: { ...process.env, ...hostCredsEnv(process.platform, CLAUDE_CREDENTIALS_FILE) },
10871
+ env: { ...process.env },
10870
10872
  stdio: ["pipe", "pipe", "pipe"]
10871
10873
  });
10872
10874
  claudeProc2.unref();
@@ -10885,7 +10887,7 @@ app9.post("/claude-auth", async (c) => {
10885
10887
  writeFile: (blob) => {
10886
10888
  const tmp = `${CLAUDE_CREDENTIALS_FILE}.${process.pid}.tmp`;
10887
10889
  writeFileSync10(tmp, blob, { mode: 384 });
10888
- renameSync6(tmp, CLAUDE_CREDENTIALS_FILE);
10890
+ renameSync7(tmp, CLAUDE_CREDENTIALS_FILE);
10889
10891
  },
10890
10892
  log: (line) => console.log(line)
10891
10893
  });
@@ -11049,7 +11051,7 @@ app9.delete("/set-pin", requireAdminSession, async (c) => {
11049
11051
  }
11050
11052
  const remaining = users.filter((u) => u.userId !== sessionUserId);
11051
11053
  if (remaining.length === 0) {
11052
- unlinkSync2(USERS_FILE);
11054
+ unlinkSync3(USERS_FILE);
11053
11055
  console.log(`[set-pin] cleared users.json (last entry removed): userId=${sessionUserId.slice(0, 8)}\u2026`);
11054
11056
  } else {
11055
11057
  writeFileSync10(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
@@ -11151,7 +11153,7 @@ ${body.newPin}
11151
11153
  var onboarding_default = app9;
11152
11154
 
11153
11155
  // server/routes/client-error.ts
11154
- import { appendFileSync as appendFileSync3, existsSync as existsSync16, renameSync as renameSync7, statSync as statSync9 } from "fs";
11156
+ import { appendFileSync as appendFileSync3, existsSync as existsSync16, renameSync as renameSync8, statSync as statSync9 } from "fs";
11155
11157
  import { join as join23 } from "path";
11156
11158
  var CLIENT_ERRORS_LOG = join23(LOG_DIR, "client-errors.log");
11157
11159
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
@@ -11204,7 +11206,7 @@ function rotateIfNeeded() {
11204
11206
  if (!existsSync16(CLIENT_ERRORS_LOG)) return;
11205
11207
  const stats = statSync9(CLIENT_ERRORS_LOG);
11206
11208
  if (stats.size < MAX_LOG_SIZE) return;
11207
- renameSync7(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
11209
+ renameSync8(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
11208
11210
  } catch (err) {
11209
11211
  console.error(`[client-error] log rotation failed: ${err instanceof Error ? err.message : String(err)}`);
11210
11212
  }
@@ -11684,7 +11686,7 @@ var logs_default = app13;
11684
11686
  import { execFileSync as execFileSync4 } from "child_process";
11685
11687
  var app14 = new Hono();
11686
11688
  app14.get("/", (c) => {
11687
- const claudeEnv = { ...process.env, ...hostCredsEnv(process.platform, CLAUDE_CREDENTIALS_FILE) };
11689
+ const claudeEnv = { ...process.env };
11688
11690
  let version = "unknown";
11689
11691
  try {
11690
11692
  const raw = execFileSync4(claudeBin(), ["--version"], { env: claudeEnv, encoding: "utf-8", timeout: 5e3 });
@@ -1,86 +0,0 @@
1
- ---
2
- name: brand-extract
3
- description: Turn a business's existing website into a brand pack for the micro-site — a tokenized palette (ink/paper/rule/accent plus a deepened accent for legible text), the logo and icon saved as image files, and a brand.md recording the company facts the site exposes (name, contact, services, about copy, socials) together with an explicit list of what is still unknown. Use as the first step of make-media, or on its own when someone wants design tokens + logo + company facts pulled from a URL. Trigger phrases include "extract the brand from <url>", "get tokens and logo from <site>", "pull the company details from their website".
4
- allowed-tools:
5
- - Bash
6
- - Read
7
- - Write
8
- - WebFetch
9
- - Grep
10
- ---
11
-
12
- # brand-extract
13
-
14
- Reads an existing website and produces what the `microsite` and `socials`
15
- templates need to be branded: a **palette**, the **logo** and **icon** as files,
16
- and a **brand.md** of company facts with an honest "still unknown" list.
17
-
18
- ## Outputs
19
-
20
- ```
21
- <output>/site/images/logo.png # the wordmark/lockup, on a white or transparent ground
22
- <output>/site/images/icon.png # the square mark / monogram (favicon source)
23
- <output>/site/favicon.png # 64px icon
24
- <output>/brand.md # tokens + facts found + gaps
25
- ```
26
-
27
- ## Palette — the token contract
28
-
29
- The templates resolve every colour through ten CSS custom properties. Fill their
30
- values from the site; do not introduce new token names.
31
-
32
- | Token | Role | How to choose |
33
- |---|---|---|
34
- | `INK_900` | primary text, headings, dark surfaces | the site's darkest near-black text colour |
35
- | `INK_700` | secondary text | a step lighter than INK_900 |
36
- | `INK_400` | muted / captions | a mid grey |
37
- | `PAPER_100` | white surface | the lightest surface (usually `#FFFFFF`) |
38
- | `PAPER_200` | page-bg tint / bands | a faint off-white for alternating bands |
39
- | `RULE_100` | borders / dividers | a pale neutral hairline |
40
- | `ACCENT` | the brand accent (separators, hairlines, CTA hover) | the logo's accent colour, used verbatim |
41
- | `ACCENT_TEXT` | accent used as small text (eyebrows, links) | the accent **deepened** until it is legible at ~10px on white (aim for ≥ 3:1 contrast). This is the one token you compute rather than copy — a light brand accent is unreadable as tracked-caps text, so darken it while keeping the same hue. |
42
- | `ACCENT_SOFT` | soft tint behind accent text | a pale wash of the accent |
43
- | `BRAND_GREY` | logo/wordmark grey | the logo's neutral grey |
44
-
45
- If the operator supplied design tokens directly, use them verbatim and skip
46
- derivation. The three-font editorial system (Cormorant Garamond display, Lora
47
- body, Inter UI) is the template default and stays unless the operator asks to
48
- change it — brand identity lives in the logo, the accent, and the copy.
49
-
50
- ## Logo — make it usable on dark and light
51
-
52
- Save the site's primary logo as `images/logo.png`. Note its background: a logo on
53
- a **white ground** sits cleanly on a light nav but cannot be dropped onto a dark
54
- photo. The `socials` tiles place the logo on a white chip precisely so a
55
- white-ground logo still reads over any hero. Record in brand.md whether a
56
- transparent or light-art variant exists. Save the square mark as `images/icon.png`
57
- and a 64px `favicon.png`.
58
-
59
- Right-size the logo (a multi-megabyte original is overkill for a 42–84px display);
60
- keep it crisp but reasonable.
61
-
62
- ## Facts — record, and mark the gaps
63
-
64
- Write `brand.md` with everything the site exposes: trading name, legal name,
65
- tagline, sector, established year, phone, email, address, region, services,
66
- "about" copy, social links. For every field the site does **not** expose, write
67
- it under a `## Still unknown` heading. That list is exactly what `make-media`
68
- turns into questions for the operator.
69
-
70
- Do not promote a marketing line to a hard fact. "Over 35 years" is a claim about
71
- experience, not a company age; "since 1987" is a trading date, not necessarily an
72
- incorporation date. Keep claims as claims.
73
-
74
- ## The 2000px image rule
75
-
76
- Never `Read` an image whose longest edge exceeds 2000px — it can break the
77
- session. Measure first (`sips -g pixelWidth -g pixelHeight`), and if larger,
78
- downscale a preview into `/tmp`, read that, and delete it.
79
-
80
- ## Completion criteria
81
-
82
- - `images/logo.png`, `images/icon.png`, `favicon.png` exist and are right-sized.
83
- - `brand.md` lists the ten palette tokens with values, the company facts found,
84
- and an explicit "Still unknown" list.
85
- - No colour was invented beyond deriving `ACCENT_TEXT` from `ACCENT`; no marketing
86
- claim was recorded as a registration fact.
@@ -1,75 +0,0 @@
1
- ---
2
- name: make-media
3
- description: Single-entry orchestrator that turns an operator's raw inputs — a folder or zip of photos, an existing website URL, social-media links, and any free-text notes about the business — into a finished marketing micro-site plus a set of share-ready social tiles. Use whenever the deliverable is "a website and social images for this business" from mixed source material. Routes to brand-extract → microsite → socials, and asks the operator targeted questions to fill every field the sources do not supply. Trigger phrases include "make a site for this business", "build a microsite from these photos and their website", "turn this into a landing page and social tiles", "sitedesk media for <business>".
4
- allowed-tools:
5
- - Bash
6
- - Read
7
- - Write
8
- - Edit
9
- - Glob
10
- - Grep
11
- - WebFetch
12
- - Skill
13
- - AskUserQuestion
14
- ---
15
-
16
- # make-media
17
-
18
- Orchestrates the `brand-extract → microsite → socials` pipeline. The deliverable is a self-contained `site/` directory (a scrollable single-page micro-site, an `llms.txt`, and a `socials/` folder of Open Graph + social tiles with a gallery and captions) plus a zipped copy, built from whatever the operator provides and whatever the orchestrator has to ask for.
19
-
20
- This skill is a playbook, not a programmatic dispatcher. It tells you the routing and the gap-filling contract; you execute each step under the underlying skills' own contracts.
21
-
22
- ## What the operator gives, and what you do with it
23
-
24
- | Operator supplies | Used for | If missing |
25
- |---|---|---|
26
- | **Images** (folder or zip of photos) | hero rotator, photo grids, founder portrait, testimonial, social tiles | required — the site is image-led. If none, stop and ask. |
27
- | **Website URL** | brand tokens (palette, accent), logo, company name, contact, services, "about" copy | run `brand-extract`; anything it cannot read becomes a question |
28
- | **Social links** (Facebook / Instagram / TikTok / LinkedIn) | footer + drawer links, social handles, extra copy/ideas in the operator's own voice | login-walled platforms usually cannot be scraped — say so plainly and ask the operator to paste any posts they want used |
29
- | **Free-text notes / pasted posts / quotes** | founder section, testimonials, "from the site" updates, service descriptions, taglines | use verbatim where the operator marks a quote; never reword a real client testimonial into marketing prose |
30
- | **Design tokens** (if supplied directly) | the palette `:root` — use them verbatim, do not re-pick | if absent, `brand-extract` derives them from the site |
31
-
32
- ## The core rule: ask, never invent
33
-
34
- Every `{{ PLACEHOLDER }}` in the templates is a fact about a real business. The brand and the operator's notes fill most of them. **For every placeholder still unfilled after `brand-extract`, ask the operator — do not synthesise a plausible value.** A fabricated phone number, a guessed founding year, an invented testimonial, or a made-up company number is a defect, not a convenience. The reference list of questions is in [`references/intake-and-questions.md`](references/intake-and-questions.md); ask only for what is genuinely missing, grouped so the operator answers in as few turns as possible.
35
-
36
- Two facts are load-bearing and frequently wrong if guessed: the **founding/established year** (a business that "trades since 1987" may have incorporated much later — keep the two distinct), and any **company-registration detail** (number, registered office) which must come from the register or the operator, never from the website's marketing line.
37
-
38
- ## Process — high level
39
-
40
- 1. **Resolve the workspace.** Default output root is the images directory's parent, or the operator's stated path. The deliverable lands in `<output>/site/`.
41
- 2. **Run `brand-extract`** against the website URL: produces the brand tokens (palette + accent), the logo (placed as `site/images/logo.png`) and icon, the company facts it can read, and a `brand.md` recording what was found and what is still unknown. If the operator supplied design tokens directly, use those verbatim instead of re-deriving.
42
- 3. **Curate the images.** Verify each photo's *content* by eye (never trust filenames), measuring first and previewing any image whose longest edge exceeds 2000px (downscale to `/tmp`, read, delete) so a large photo never breaks the session. Pick the strongest, most varied shots for the hero rotator and the strongest finished result for the testimonial; map the rest to the photo grids. A person's portrait is for the founder section and a portrait-only social tile, never a landscape crop.
43
- 4. **Fill the gaps.** Compare the placeholder inventory ([`microsite/references/placeholders.md`](../microsite/references/placeholders.md)) against what brand-extract found and the operator's notes. Ask the operator for everything still missing, in grouped questions. Wait for answers. Do not proceed with blanks.
44
- 5. **Run `microsite`** to build `site/index.html` + `site/llms.txt` from the templates, substituting every placeholder. No `{{ }}` may survive into the output.
45
- 6. **Run `socials` in `microsite` mode** to render the Open Graph + social tiles into `site/socials/`, plus `site/socials.html` (gallery) and `site/social-posts.md` (captions), and to wire the site's `og:image` to the landscape tile.
46
- 7. **Verify and report.** Confirm no placeholder survived, every referenced asset resolves over a local HTTP server, the site renders at desktop and mobile, and the social tiles are at exact dimensions. Report the path to `site/` and the zip, and list any value you had to ask for.
47
-
48
- ## Outcome contract
49
-
50
- ```
51
- <output>/site/
52
- index.html # the scrollable micro-site
53
- llms.txt # answer-engine summary
54
- favicon.png
55
- images/ # curated, optimised webp + logo.png + icon.png
56
- socials/ # og-{landscape,square,portrait}-{main,interior,build}.png + og-portrait-founder.png
57
- socials.html # tile gallery with download links + OG snippet
58
- social-posts.md # captions per tile and platform
59
- og.html # tile render page (kept for re-runs)
60
- <output>/<brand-slug>-microsite.zip
61
- ```
62
-
63
- ## Completion criteria
64
-
65
- - `grep "{{" site/index.html site/llms.txt site/socials.html` returns nothing — every placeholder substituted.
66
- - No invented facts: every value traces to the website, the operator's notes, or an answer the operator gave. Anything still genuinely unknown is shown as a clear gap, not a guess.
67
- - The site renders at desktop and a 390px mobile viewport with no horizontal overflow and no broken images; the hero rotates; the back-to-top works.
68
- - Social tiles exist at exact sizes (1200×628 / 1200×1200 / 1080×1350); any person tile is portrait only.
69
- - The operator-facing report names the site path, the zip path, and every field that had to be asked for.
70
-
71
- ## When NOT to use this skill
72
-
73
- - The operator only wants the micro-site, or only the social tiles → call `microsite` or `socials` directly.
74
- - The operator only wants brand tokens and a logo from a URL → call `brand-extract` directly.
75
- - There are no usable photos of the business → the site is image-led; stop and ask for photos before anything else.
@@ -1,74 +0,0 @@
1
- # Intake & gap-filling questions
2
-
3
- Ask only for what the website and the operator's notes did not already supply.
4
- Group the questions so the operator answers in as few turns as possible, and
5
- present sensible candidates from the source material where you have them ("Your
6
- site says you've traded since 1994 — is that the year to show?").
7
-
8
- Never invent a value to avoid asking. A guessed phone number or founding year is
9
- a defect. If the operator does not know a field (e.g. company number), leave that
10
- slot out of the output rather than filling it with a placeholder or a guess.
11
-
12
- ## 1. Identity
13
-
14
- - Trading name and full legal name (e.g. "Acme Joinery" / "Acme Joinery Ltd").
15
- - Short monogram / initials, if any (used as a small brand mark).
16
- - Tagline / strapline, in their own words.
17
- - Sector label for the nav and tiles (e.g. "Builders", "Joiners", "Florist").
18
- - Established year. **Keep "trading since" separate from "company incorporated".**
19
- - Company registration number + jurisdiction, and registered office — only if the
20
- operator wants legal detail in the footer. Take these from the register or the
21
- operator, never from a marketing line.
22
-
23
- ## 2. Contact & place
24
-
25
- - Phone (display + dialable), mobile if separate.
26
- - Email.
27
- - Website domain and full URL (for canonical + Open Graph).
28
- - Address: street, post town, county, postcode (only the parts they want shown).
29
- - Service area / region phrase (e.g. "the South East" or "Greater Manchester").
30
- - Social profiles: Facebook, Instagram, TikTok, LinkedIn (URLs + handles).
31
-
32
- ## 3. The story (copy, in their voice)
33
-
34
- - One or two paragraphs on who they are and how long they've been going.
35
- - What they're proudest of / the standard they hold to.
36
- - A headline sentence that sums the business up.
37
- - The three or four "by the numbers" facts (established, experience, ownership,
38
- coverage, specialism, approach, promise).
39
-
40
- ## 4. What they do (services)
41
-
42
- - Up to six services, each a short name and a one-line description.
43
- - A one-line lede for the services section.
44
-
45
- ## 5. The founder / person on site
46
-
47
- - Name and role of the person who fronts the business.
48
- - A short intro in their voice (what they do, how hands-on they are).
49
- - A quote from them, ideally about a specific job or their approach.
50
- - 1–3 recent "from the site" updates in their own words (the social-post voice
51
- is good here — keep it, just drop the emoji per the plain register).
52
- - A portrait photo of them (used in the founder section and a portrait social
53
- tile — a person is never cropped to landscape).
54
-
55
- ## 6. Proof (testimonial)
56
-
57
- - A real client quote, used verbatim. Note the one phrase to highlight.
58
- - Who it's from and the context ("on their new kitchen").
59
- - Which finished-job photo best illustrates it.
60
- - Any thank-you artefact (a card, a gift photo) that adds a personal touch.
61
-
62
- ## 7. FAQ (answer-engine targets)
63
-
64
- - 3–5 plain questions a customer actually asks, each with a one or two sentence
65
- answer. Default set: what they do, how long they've been going, where they're
66
- based / areas covered, plus two specific to the trade.
67
-
68
- ## 8. Images (you curate, but confirm)
69
-
70
- - Confirm which photo is the strongest "arrive here" shot (hero / main tile).
71
- - Confirm the best finished-result shot (testimonial + interior tile).
72
- - Confirm a strong in-progress / scale shot (build tile, full-bleed).
73
- - Flag if the photo set is mostly work-in-progress so expectations are set, and
74
- ask for any finished-result photos that would strengthen the hero.