@rubytech/create-realagent-code 0.1.20 → 0.1.21

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 (103) hide show
  1. package/dist/index.js +1 -0
  2. package/dist/port-resolution.js +2 -0
  3. package/package.json +1 -1
  4. package/payload/platform/plugins/admin/hooks/onboarding-skill-drift.sh +100 -0
  5. package/payload/platform/plugins/docs/references/deployment.md +0 -4
  6. package/payload/platform/scripts/check-no-direct-clipboard.mjs +54 -0
  7. package/payload/platform/scripts/seed-neo4j.sh +7 -0
  8. package/payload/platform/services/claude-session-manager/dist/config.d.ts +8 -0
  9. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  10. package/payload/platform/services/claude-session-manager/dist/config.js +66 -1
  11. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  12. package/payload/platform/services/claude-session-manager/dist/index.js +3 -0
  13. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  14. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +9 -1
  15. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  16. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +14 -1
  17. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  18. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +9 -0
  19. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -0
  20. package/payload/platform/services/claude-session-manager/dist/system-prompt.js +35 -0
  21. package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -0
  22. package/payload/server/public/assets/Checkbox-B79fVxpA.js +1 -0
  23. package/payload/server/public/assets/admin-DgB_IeWB.js +216 -0
  24. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DU8MnqOj.js → architectureDiagram-Q4EWVU46-D8e59YJ0.js} +1 -1
  25. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DwBZc1na.js → blockDiagram-DXYQGD6D-CxaDkc0A.js} +1 -1
  26. package/payload/server/public/assets/{jsx-runtime-CtqEPPN5.css → brand-Cg9t5U6J.css} +1 -1
  27. package/payload/server/public/assets/brand-jT16ErmC.js +9 -0
  28. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-C9ZHreVX.js → c4Diagram-AHTNJAMY-D0PAvq-q.js} +1 -1
  29. package/payload/server/public/assets/channel-BU_eIdRB.js +1 -0
  30. package/payload/server/public/assets/{chunk-336JU56O-DNXqHk42.js → chunk-336JU56O-B-CXn-Et.js} +2 -2
  31. package/payload/server/public/assets/{chunk-426QAEUC-DOLKkQGn.js → chunk-426QAEUC-BLzCQHKA.js} +1 -1
  32. package/payload/server/public/assets/{chunk-4TB4RGXK-l8iZx-gQ.js → chunk-4TB4RGXK-Bql1UwLT.js} +1 -1
  33. package/payload/server/public/assets/{chunk-5FUZZQ4R-DQwRtUdO.js → chunk-5FUZZQ4R-CQK7jBtX.js} +1 -1
  34. package/payload/server/public/assets/{chunk-5PVQY5BW-CvvoBJnn.js → chunk-5PVQY5BW-AJc1-lvX.js} +1 -1
  35. package/payload/server/public/assets/{chunk-EDXVE4YY-DV1J4-LR.js → chunk-EDXVE4YY-Cf3E3THL.js} +1 -1
  36. package/payload/server/public/assets/{chunk-ENJZ2VHE-Co6qpIQl.js → chunk-ENJZ2VHE-BNx6z6hJ.js} +1 -1
  37. package/payload/server/public/assets/{chunk-ICPOFSXX-9v9O_mwr.js → chunk-ICPOFSXX-DBUEFs2-.js} +1 -1
  38. package/payload/server/public/assets/{chunk-OYMX7WX6-D2X1NuKZ.js → chunk-OYMX7WX6-Csx2p315.js} +1 -1
  39. package/payload/server/public/assets/{chunk-U2HBQHQK-DmqWEsN2.js → chunk-U2HBQHQK-x17h7UYW.js} +1 -1
  40. package/payload/server/public/assets/{chunk-X2U36JSP-C0b2a6Bq.js → chunk-X2U36JSP--Lkl5yjV.js} +1 -1
  41. package/payload/server/public/assets/{chunk-YZCP3GAM-BdBAquWg.js → chunk-YZCP3GAM-C4GsNX8A.js} +1 -1
  42. package/payload/server/public/assets/{chunk-ZZ45TVLE-C1AFspLM.js → chunk-ZZ45TVLE-YrhUPmZc.js} +1 -1
  43. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DMpM1d2b.js +1 -0
  44. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-D_XbuPVj.js +1 -0
  45. package/payload/server/public/assets/clone-BBT00JUO.js +1 -0
  46. package/payload/server/public/assets/{dagre-KV5264BT-a88ylEXY.js → dagre-KV5264BT-D6JU6DW_.js} +1 -1
  47. package/payload/server/public/assets/{dagre-7eiQzAHj.js → dagre-YVALPG-M.js} +1 -1
  48. package/payload/server/public/assets/data-BdwO_kv-.js +1 -0
  49. package/payload/server/public/assets/device-url-actions-C8dD0ydz.js +33 -0
  50. package/payload/server/public/assets/{diagram-5BDNPKRD-XuINnSy-.js → diagram-5BDNPKRD-yeO06N5Q.js} +1 -1
  51. package/payload/server/public/assets/{diagram-G4DWMVQ6-B93iSQ8a.js → diagram-G4DWMVQ6-DzbVT_BC.js} +1 -1
  52. package/payload/server/public/assets/{diagram-MMDJMWI5-Gcoj967k.js → diagram-MMDJMWI5-DwYO5VZF.js} +1 -1
  53. package/payload/server/public/assets/{diagram-TYMM5635-C2BKnsAF.js → diagram-TYMM5635-BLUcdkDS.js} +1 -1
  54. package/payload/server/public/assets/{erDiagram-SMLLAGMA-DwbOuflI.js → erDiagram-SMLLAGMA-BiEUB19e.js} +1 -1
  55. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CEExhdxC.js → flowDiagram-DWJPFMVM-TILIKxOp.js} +1 -1
  56. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-kYNYeUK-.js → ganttDiagram-T4ZO3ILL-B7cGzYqT.js} +1 -1
  57. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-D3X2eJPE.js → gitGraphDiagram-UUTBAWPF-DFOxN5bc.js} +1 -1
  58. package/payload/server/public/assets/graph-CfZJrc9u.js +1 -0
  59. package/payload/server/public/assets/graph-labels-DJ717p00.js +1 -0
  60. package/payload/server/public/assets/{graphlib-_S6i_Jn2.js → graphlib-BBibixaA.js} +1 -1
  61. package/payload/server/public/assets/{infoDiagram-42DDH7IO-CQx0vDcC.js → infoDiagram-42DDH7IO-nH2azhY8.js} +1 -1
  62. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-0eZUgqUP.js → ishikawaDiagram-UXIWVN3A-WD3tfqFi.js} +1 -1
  63. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-D-B2Kd_J.js → journeyDiagram-VCZTEJTY-LUkaVSqw.js} +1 -1
  64. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BmLn-OEz.js → kanban-definition-6JOO6SKY-Dk-lYgpJ.js} +1 -1
  65. package/payload/server/public/assets/{line-h25nWPBw.js → line-BDv6CEnp.js} +1 -1
  66. package/payload/server/public/assets/{mermaid-parser.core-CXXeaSZi.js → mermaid-parser.core-D2XsSGgp.js} +1 -1
  67. package/payload/server/public/assets/{mermaid.core-BjFfgEHL.js → mermaid.core-FyN-UmQV.js} +3 -3
  68. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-Dql4ILoK.js → mindmap-definition-QFDTVHPH-BRAHEUIS.js} +1 -1
  69. package/payload/server/public/assets/page-BWHYktEF.js +1 -0
  70. package/payload/server/public/assets/page-CZQd-W3C.js +50 -0
  71. package/payload/server/public/assets/{pieDiagram-DEJITSTG-nYaoTCKZ.js → pieDiagram-DEJITSTG-BqibVC2X.js} +1 -1
  72. package/payload/server/public/assets/public-BDUZIabs.js +8 -0
  73. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-XG8xivm9.js → quadrantDiagram-34T5L4WZ-DNuExGnr.js} +1 -1
  74. package/payload/server/public/assets/{requirementDiagram-MS252O5E-C2GzfT-6.js → requirementDiagram-MS252O5E-5JXTdydh.js} +1 -1
  75. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-3aI78p2X.js → sankeyDiagram-XADWPNL6-B_8rhvcR.js} +1 -1
  76. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CvaNRYuS.js → sequenceDiagram-FGHM5R23-BznkBgjf.js} +1 -1
  77. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DHT2Zyvj.js → stateDiagram-FHFEXIEX-BeAZOQfs.js} +1 -1
  78. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-iVlXKz7S.js +1 -0
  79. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DqPjDUku.js → timeline-definition-GMOUNBTQ-CpJAs-Vw.js} +1 -1
  80. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-lQB1LgjH.js → vennDiagram-DHZGUBPP-BzH3ItkG.js} +1 -1
  81. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-sxSMxkwm.js → wardleyDiagram-NUSXRM2D-ax9AgwA1.js} +1 -1
  82. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-4-dvvfSD.js → xychartDiagram-5P7HB3ND-CV6vt_tW.js} +1 -1
  83. package/payload/server/public/data.html +5 -5
  84. package/payload/server/public/graph.html +6 -6
  85. package/payload/server/public/index.html +8 -8
  86. package/payload/server/public/public.html +5 -5
  87. package/payload/server/server.js +32 -5
  88. package/payload/platform/scripts/qa/onboarding-fresh-install.sh +0 -435
  89. package/payload/server/public/assets/Checkbox-BmlrSRF8.js +0 -1
  90. package/payload/server/public/assets/admin-Drvl0Okz.js +0 -216
  91. package/payload/server/public/assets/channel-Boz4UHN2.js +0 -1
  92. package/payload/server/public/assets/classDiagram-6PBFFD2Q-CRA6E97A.js +0 -1
  93. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-VnieTvEm.js +0 -1
  94. package/payload/server/public/assets/clone-6YhZHo8b.js +0 -1
  95. package/payload/server/public/assets/data-Dq_if_B4.js +0 -1
  96. package/payload/server/public/assets/device-url-actions-_s-UgHa3.js +0 -33
  97. package/payload/server/public/assets/graph-CNFkzAKU.js +0 -1
  98. package/payload/server/public/assets/graph-labels-C6ZZPglH.js +0 -1
  99. package/payload/server/public/assets/jsx-runtime-BSJRynxp.js +0 -9
  100. package/payload/server/public/assets/page-CdWWweCx.js +0 -1
  101. package/payload/server/public/assets/page-D20UnO_r.js +0 -50
  102. package/payload/server/public/assets/public-CXgyLdJU.js +0 -8
  103. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-YmtuS9BN.js +0 -1
package/dist/index.js CHANGED
@@ -2998,6 +2998,7 @@ function installService() {
2998
2998
  installDir: INSTALL_DIR,
2999
2999
  persistDir,
3000
3000
  claudeSessionManagerPort: CLAUDE_SESSION_MANAGER_PORT_BRAND,
3001
+ brandPort: PORT,
3001
3002
  accountId: installAccountId,
3002
3003
  });
3003
3004
  writeFileSync(join(serviceDir, claudeSessionManagerUnitName), claudeSessionManagerUnit);
@@ -144,6 +144,8 @@ Environment=ACCOUNT_ID=${o.accountId}
144
144
  Environment=CLAUDE_SESSION_MANAGER_PORT=${o.claudeSessionManagerPort}
145
145
  Environment=CLAUDE_SESSION_MANAGER_PERSIST_DIR=${o.persistDir}
146
146
  Environment=CLAUDE_CONFIG_DIR=${o.persistDir}/.claude
147
+ Environment=PLATFORM_ROOT=${o.installDir}/platform
148
+ Environment=MAXY_BRAND_PORT=${o.brandPort}
147
149
  EnvironmentFile=-${o.persistDir}/.env
148
150
  StandardOutput=append:${o.persistDir}/logs/server.log
149
151
  StandardError=append:${o.persistDir}/logs/server.log
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-realagent-code",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Install Real Agent — Built for agents. By agents.",
5
5
  "bin": {
6
6
  "create-realagent-code": "./dist/index.js"
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env bash
2
+ # Task 038 Outcome E1 — Stop-event hook that flags the admin agent's
3
+ # onboarding-skill drift pattern: the prior /input carried an
4
+ # `<onboarding-state>` block, but the latest assistant turn did not call
5
+ # `render-component` AND did not end with a `?`-terminated sentence.
6
+ #
7
+ # Behaviour:
8
+ # 1. Read the transcript_path from the Stop event JSON on stdin.
9
+ # 2. Walk the JSONL backwards. Find the most recent user event whose
10
+ # `message.content` (string or text-block array) contains the literal
11
+ # `<onboarding-state ` marker — that is the injection signature.
12
+ # 3. If no such user event exists in this transcript, fail-open (exit 0).
13
+ # 4. Otherwise, find the most recent assistant event after that injection
14
+ # event. Extract its tool-use names and the trailing text characters.
15
+ # 5. If the tool-use list does NOT contain `render-component` AND the
16
+ # trailing prose does NOT end with `?`, the agent has drifted — log
17
+ # one `[precision-check] rule=onboarding-skill-drift` line to the
18
+ # admin-side log directory and exit 0.
19
+ #
20
+ # Exit 0 always — this hook is observation, not enforcement. The
21
+ # precision-check ledger increments via the log line; no retry is forced.
22
+ # Infrastructure failures (jq missing, transcript unreadable) also exit 0
23
+ # so a hook bug never blocks the agent's response.
24
+
25
+ set -uo pipefail
26
+ LOG_TAG="[precision-check]"
27
+
28
+ # fail-open if jq is unavailable — the transcript shape demands JSON parse
29
+ if ! command -v jq >/dev/null 2>&1; then
30
+ echo "$LOG_TAG rule=onboarding-skill-drift result=skip reason=jq-missing" >&2
31
+ exit 0
32
+ fi
33
+
34
+ INPUT=$(cat 2>/dev/null || echo '{}')
35
+ TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
36
+ if [ -z "$TRANSCRIPT" ] || [ ! -f "$TRANSCRIPT" ]; then
37
+ echo "$LOG_TAG rule=onboarding-skill-drift result=skip reason=no-transcript" >&2
38
+ exit 0
39
+ fi
40
+
41
+ # Locate the most recent injection signature in user events. The injection
42
+ # block is prepended verbatim to the operator's input on the first /input
43
+ # of an eligible session, so it appears as the leading bytes of a user
44
+ # event's message text. Search backwards to find the last one in this
45
+ # transcript window.
46
+ INJECTION_LINE=$(grep -n '<onboarding-state ' "$TRANSCRIPT" 2>/dev/null \
47
+ | grep '"type":"user"' \
48
+ | tail -n 1 \
49
+ | cut -d: -f1)
50
+
51
+ if [ -z "$INJECTION_LINE" ]; then
52
+ # No injection in this transcript window — nothing to enforce.
53
+ exit 0
54
+ fi
55
+
56
+ # Slice the file from just after the injection line to the end; the
57
+ # assistant's response sits in that suffix.
58
+ TAIL=$(tail -n "+$((INJECTION_LINE + 1))" "$TRANSCRIPT" 2>/dev/null)
59
+
60
+ # Last assistant message in the suffix.
61
+ ASSISTANT=$(echo "$TAIL" \
62
+ | grep '"type":"assistant"' \
63
+ | tail -n 1)
64
+
65
+ if [ -z "$ASSISTANT" ]; then
66
+ echo "$LOG_TAG rule=onboarding-skill-drift result=skip reason=no-assistant-turn" >&2
67
+ exit 0
68
+ fi
69
+
70
+ # Tool-use names from the assistant event.
71
+ TOOL_USES=$(echo "$ASSISTANT" | jq -r '
72
+ .message.content // []
73
+ | map(select(.type == "tool_use") | .name)
74
+ | join(",")
75
+ ' 2>/dev/null)
76
+
77
+ # Concatenated text content (final character matters for the `?` check).
78
+ ASSISTANT_TEXT=$(echo "$ASSISTANT" | jq -r '
79
+ .message.content // []
80
+ | map(select(.type == "text") | .text)
81
+ | join(" ")
82
+ ' 2>/dev/null)
83
+
84
+ HAS_RENDER_COMPONENT=0
85
+ case "$TOOL_USES" in
86
+ *render-component*) HAS_RENDER_COMPONENT=1 ;;
87
+ esac
88
+
89
+ # Trim trailing whitespace and check the last non-whitespace character.
90
+ TRIMMED=$(echo "$ASSISTANT_TEXT" | sed -E 's/[[:space:]]+$//')
91
+ LAST_CHAR=$(echo -n "$TRIMMED" | tail -c 1)
92
+
93
+ if [ "$HAS_RENDER_COMPONENT" = "0" ] && [ "$LAST_CHAR" != "?" ]; then
94
+ # Drift detected. Sample is the first 80 chars of the assistant text so
95
+ # the log line tells the operator what shape of drift fired.
96
+ SAMPLE=$(echo "$TRIMMED" | head -c 80 | tr '\n' ' ')
97
+ echo "$LOG_TAG rule=onboarding-skill-drift result=block class=PRECISION sample='${SAMPLE}'" >&2
98
+ fi
99
+
100
+ exit 0
@@ -62,10 +62,6 @@ Failure signals to grep in `~/.maxy/logs/server.log` (or `~/.realagent/logs/serv
62
62
  - `[onboarding-gate] step=null complete=true` (the pre-Task-033 bug)
63
63
  - missing `[skill-load] name=onboarding` while `[onboarding-gate]` reports `complete=false`
64
64
 
65
- ### QA regression replay
66
-
67
- `platform/scripts/qa/onboarding-fresh-install.sh <brand> [--watch]` replays the success chain end-to-end on a freshly-installed Pi. It exits zero only when every line above lands, and exits non-zero with the missing line named verbatim on any miss — so a future regression in this chain is caught by replay instead of by a customer. Pass `--watch` to keep polling Neo4j while the operator drives steps 1–9 in the UI; each `currentStep` advance asserts the matching `stepNCompletedAt` is persisted before the next step renders. Provide the admin PIN via `MAXY_ADMIN_PIN`.
68
-
69
65
  ## Service Management
70
66
 
71
67
  {{productName}} runs via systemd and starts automatically on boot. You don't need to start it manually. To check if it's running, ask {{productName}} "Check system status."
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ // Task 036 build-time gate: every clipboard write in `platform/ui/app/` must
3
+ // route through the canonical `copyToClipboard` export at
4
+ // `hooks/useSelectionMode.ts`. That helper holds the two-path implementation
5
+ // (Clipboard API then `document.execCommand('copy')` fallback) that lets the
6
+ // admin UI work on plain-HTTP hosts like `realagent-code.local`. A second
7
+ // direct call to `navigator.clipboard` would silently re-introduce the
8
+ // "Copy failed" regression on those hosts.
9
+ //
10
+ // Fails if any .ts/.tsx file under `platform/ui/app/` other than
11
+ // `hooks/useSelectionMode.ts` calls `navigator.clipboard.writeText`,
12
+ // `navigator.clipboard.readText`, or any other clipboard method directly.
13
+ // Bare `navigator.clipboard` (feature detection) and comment references are
14
+ // allowed — only the operation that bypasses the fallback is the regression.
15
+
16
+ import { readFileSync, readdirSync, statSync } from 'node:fs'
17
+ import { dirname, join, relative } from 'node:path'
18
+ import { fileURLToPath } from 'node:url'
19
+
20
+ const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url))
21
+ const REPO_ROOT = join(SCRIPT_DIR, '..', '..')
22
+ const SCAN_ROOT = join(REPO_ROOT, 'platform', 'ui', 'app')
23
+ const CANONICAL = join('hooks', 'useSelectionMode.ts')
24
+ const PATTERN = /navigator\.clipboard\.\w+\s*\(/
25
+
26
+ const offenders = []
27
+
28
+ function walk(dir) {
29
+ for (const entry of readdirSync(dir)) {
30
+ const full = join(dir, entry)
31
+ const stat = statSync(full)
32
+ if (stat.isDirectory()) {
33
+ walk(full)
34
+ continue
35
+ }
36
+ if (!/\.(ts|tsx)$/.test(entry)) continue
37
+ const rel = relative(SCAN_ROOT, full)
38
+ if (rel === CANONICAL) continue
39
+ const text = readFileSync(full, 'utf8')
40
+ const lines = text.split('\n')
41
+ lines.forEach((line, i) => {
42
+ if (PATTERN.test(line)) offenders.push(`${rel}:${i + 1}: ${line.trim()}`)
43
+ })
44
+ }
45
+ }
46
+
47
+ walk(SCAN_ROOT)
48
+
49
+ if (offenders.length > 0) {
50
+ console.error('check-no-direct-clipboard: found direct navigator.clipboard usage outside hooks/useSelectionMode.ts:')
51
+ for (const o of offenders) console.error(' ' + o)
52
+ console.error('Import { copyToClipboard } from \'./hooks/useSelectionMode\' (or relative equivalent) instead.')
53
+ process.exit(1)
54
+ }
@@ -192,6 +192,13 @@ cat > "$ACCOUNT_SETTINGS" << SETTINGS_EOF
192
192
  { "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
193
193
  ]
194
194
  }
195
+ ],
196
+ "Stop": [
197
+ {
198
+ "hooks": [
199
+ { "type": "command", "command": "bash $HOOKS_PATH/onboarding-skill-drift.sh" }
200
+ ]
201
+ }
195
202
  ]
196
203
  }
197
204
  }
@@ -1,3 +1,10 @@
1
+ import type { HostContext } from './system-prompt.js';
2
+ export interface HostResolution extends HostContext {
3
+ /** Comma-separated list of detected interface names — non-null only when
4
+ * lanIPv4 resolution failed. Surfaced as the `stderrTail` of a spawn
5
+ * rejection so the operator sees what was searched. */
6
+ lanIPv4Diagnostic: string | null;
7
+ }
1
8
  export interface ManagerConfig {
2
9
  port: number;
3
10
  persistDir: string;
@@ -6,6 +13,7 @@ export interface ManagerConfig {
6
13
  urlCaptureTimeoutMs: number;
7
14
  killGraceMs: number;
8
15
  jsonlReadMaxBytes: number;
16
+ host: HostResolution;
9
17
  }
10
18
  export declare function loadConfig(env?: NodeJS.ProcessEnv): ManagerConfig;
11
19
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAOD,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,aAAa,CAiB9E"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD;;4DAEwD;IACxD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;IACzB,IAAI,EAAE,cAAc,CAAA;CACrB;AAmED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,aAAa,CAkC9E"}
@@ -1,9 +1,59 @@
1
- import { homedir } from 'node:os';
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { homedir, hostname, networkInterfaces } from 'node:os';
2
3
  import { join } from 'node:path';
3
4
  const DEFAULT_PORT = 19400;
4
5
  const DEFAULT_URL_TIMEOUT_MS = 30_000;
5
6
  const DEFAULT_KILL_GRACE_MS = 5_000;
6
7
  const DEFAULT_JSONL_READ_MAX_BYTES = 1 * 1024 * 1024;
8
+ const DEFAULT_BRAND_PORT = 19200;
9
+ function loadBrand(env) {
10
+ const platformRoot = env.PLATFORM_ROOT ?? env.MAXY_PLATFORM_ROOT;
11
+ if (!platformRoot) {
12
+ throw new Error('[claude-session-manager] PLATFORM_ROOT (or MAXY_PLATFORM_ROOT) is not set — cannot resolve brand.json. ' +
13
+ 'The systemd unit must pass PLATFORM_ROOT=${installDir}/platform.');
14
+ }
15
+ const brandPath = join(platformRoot, 'config', 'brand.json');
16
+ if (!existsSync(brandPath)) {
17
+ throw new Error(`[claude-session-manager] brand.json missing at ${brandPath} — install is corrupted or PLATFORM_ROOT points to the wrong directory.`);
18
+ }
19
+ let brand;
20
+ try {
21
+ brand = JSON.parse(readFileSync(brandPath, 'utf-8'));
22
+ }
23
+ catch (err) {
24
+ const detail = (err instanceof Error ? err.message : String(err)).slice(0, 200);
25
+ throw new Error(`[claude-session-manager] brand.json at ${brandPath} parse failed: ${detail}`);
26
+ }
27
+ const hn = typeof brand.hostname === 'string' && brand.hostname.length > 0 ? brand.hostname : null;
28
+ if (!hn) {
29
+ throw new Error(`[claude-session-manager] brand.json at ${brandPath} missing required field: hostname`);
30
+ }
31
+ const domain = typeof brand.domain === 'string' && brand.domain.length > 0 ? brand.domain : null;
32
+ return { brandPath, fields: { hostname: hn, domain } };
33
+ }
34
+ function resolveLanIPv4() {
35
+ const ifaces = networkInterfaces();
36
+ for (const [, addrs] of Object.entries(ifaces)) {
37
+ if (!addrs)
38
+ continue;
39
+ for (const addr of addrs) {
40
+ if (addr.family === 'IPv4' && !addr.internal) {
41
+ return { ip: addr.address, diagnostic: null };
42
+ }
43
+ }
44
+ }
45
+ const names = Object.keys(ifaces).join(',') || '(no interfaces detected)';
46
+ return { ip: null, diagnostic: `no non-loopback IPv4 across interfaces: ${names}` };
47
+ }
48
+ function resolveBrandPort(env) {
49
+ const raw = env.MAXY_BRAND_PORT ?? env.PORT;
50
+ if (!raw)
51
+ return DEFAULT_BRAND_PORT;
52
+ const n = Number(raw);
53
+ if (!Number.isInteger(n) || n < 1 || n > 65535)
54
+ return DEFAULT_BRAND_PORT;
55
+ return n;
56
+ }
7
57
  export function loadConfig(env = process.env) {
8
58
  const port = Number(env.CLAUDE_SESSION_MANAGER_PORT ?? DEFAULT_PORT);
9
59
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
@@ -12,6 +62,14 @@ export function loadConfig(env = process.env) {
12
62
  const persistDir = env.CLAUDE_SESSION_MANAGER_PERSIST_DIR ?? join(homedir(), '.maxy');
13
63
  const claudeBin = env.CLAUDE_BIN ?? 'claude';
14
64
  const spawnCwd = env.CLAUDE_SESSION_MANAGER_SPAWN_CWD ?? process.cwd();
65
+ const brand = loadBrand(env);
66
+ const lan = resolveLanIPv4();
67
+ const brandPort = resolveBrandPort(env);
68
+ const osHost = hostname();
69
+ const adminUrl = `http://${brand.fields.hostname}.local:${brandPort}`;
70
+ const tunnelUrl = brand.fields.domain
71
+ ? `https://${brand.fields.hostname}.${brand.fields.domain}`
72
+ : null;
15
73
  return {
16
74
  port,
17
75
  persistDir,
@@ -20,6 +78,13 @@ export function loadConfig(env = process.env) {
20
78
  urlCaptureTimeoutMs: DEFAULT_URL_TIMEOUT_MS,
21
79
  killGraceMs: DEFAULT_KILL_GRACE_MS,
22
80
  jsonlReadMaxBytes: DEFAULT_JSONL_READ_MAX_BYTES,
81
+ host: {
82
+ hostname: osHost,
83
+ lanIPv4: lan.ip,
84
+ adminUrl,
85
+ tunnelUrl,
86
+ lanIPv4Diagnostic: lan.diagnostic,
87
+ },
23
88
  };
24
89
  }
25
90
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAYhC,MAAM,YAAY,GAAG,KAAK,CAAA;AAC1B,MAAM,sBAAsB,GAAG,MAAM,CAAA;AACrC,MAAM,qBAAqB,GAAG,KAAK,CAAA;AACnC,MAAM,4BAA4B,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;AAEpD,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,IAAI,YAAY,CAAC,CAAA;IACpE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,wCAAwC,GAAG,CAAC,2BAA2B,EAAE,CAAC,CAAA;IAC5F,CAAC;IACD,MAAM,UAAU,GAAG,GAAG,CAAC,kCAAkC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAA;IACrF,MAAM,SAAS,GAAG,GAAG,CAAC,UAAU,IAAI,QAAQ,CAAA;IAC5C,MAAM,QAAQ,GAAG,GAAG,CAAC,gCAAgC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACtE,OAAO;QACL,IAAI;QACJ,UAAU;QACV,SAAS;QACT,QAAQ;QACR,mBAAmB,EAAE,sBAAsB;QAC3C,WAAW,EAAE,qBAAqB;QAClC,iBAAiB,EAAE,4BAA4B;KAChD,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,8 @@ async function main() {
25
25
  const config = loadConfig();
26
26
  const store = new SessionStore();
27
27
  log(`boot port=${config.port} persistDir=${config.persistDir} spawnCwd=${config.spawnCwd}`);
28
+ log(`host hostname=${config.host.hostname} lanIPv4=${config.host.lanIPv4 ?? 'unresolved'} adminUrl=${config.host.adminUrl} tunnelUrl=${config.host.tunnelUrl ?? 'none'}` +
29
+ (config.host.lanIPv4Diagnostic ? ` diagnostic=${JSON.stringify(config.host.lanIPv4Diagnostic)}` : ''));
28
30
  const app = buildHttpApp({
29
31
  store,
30
32
  spawnCwd: config.spawnCwd,
@@ -34,6 +36,7 @@ async function main() {
34
36
  jsonlReadMaxBytes: config.jsonlReadMaxBytes,
35
37
  logger: log,
36
38
  spawnPty: (cmd, args, env) => spawnPtyAdapter(cmd, args, env, config.spawnCwd),
39
+ host: config.host,
37
40
  });
38
41
  serve({ fetch: app.fetch, port: config.port, hostname: '127.0.0.1' }, (info) => {
39
42
  log(`listening address=127.0.0.1:${info.port}`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,12 @@
1
1
  import type { Logger, PtyHandle, Role, Channel } from './types.js';
2
2
  import { SessionStore, type StoredSession } from './session-store.js';
3
+ import type { HostResolution } from './config.js';
3
4
  export type SpawnResult = {
4
5
  ok: true;
5
6
  session: StoredSession;
6
7
  } | {
7
8
  ok: false;
8
- reason: 'which-claude-not-found' | 'pty-spawn-failed' | 'url-capture-timeout';
9
+ reason: 'which-claude-not-found' | 'pty-spawn-failed' | 'url-capture-timeout' | 'host-context-unresolved';
9
10
  stderrTail: string;
10
11
  };
11
12
  export interface SpawnDeps {
@@ -15,6 +16,13 @@ export interface SpawnDeps {
15
16
  urlCaptureTimeoutMs: number;
16
17
  logger: Logger;
17
18
  store: SessionStore;
19
+ /** Task 037 — host context resolved at boot. Used both to compose the
20
+ * sentinel-wrapped block injected via `--append-system-prompt` (hostname,
21
+ * LAN IPv4, admin URL, tunnel URL + the 30 MiB attachment ceiling
22
+ * doctrine) and to surface a `host-context-unresolved` failure when
23
+ * `lanIPv4` is null. One edit to this block changes the doctrine for
24
+ * every agent in every session. */
25
+ host: HostResolution;
18
26
  }
19
27
  export interface SpawnArgs {
20
28
  senderId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"pty-spawner.d.ts","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAElE,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGrE,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GACpC;IACE,EAAE,EAAE,KAAK,CAAA;IACT,MAAM,EAAE,wBAAwB,GAAG,kBAAkB,GAAG,qBAAqB,CAAA;IAC7E,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAEL,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,SAAS,CAAA;IAC5E,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,YAAY,CAAA;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,EAAE,OAAO,CAAA;IAChB;;gCAE4B;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;8EAI0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAgE/F;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAqBzC"}
1
+ {"version":3,"file":"pty-spawner.d.ts","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAElE,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GACpC;IACE,EAAE,EAAE,KAAK,CAAA;IACT,MAAM,EACF,wBAAwB,GACxB,kBAAkB,GAClB,qBAAqB,GACrB,yBAAyB,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAEL,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,SAAS,CAAA;IAC5E,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,YAAY,CAAA;IACnB;;;;;uCAKmC;IACnC,IAAI,EAAE,cAAc,CAAA;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,EAAE,OAAO,CAAA;IAChB;;gCAE4B;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;8EAI0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CA8E/F;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAqBzC"}
@@ -11,11 +11,23 @@
11
11
  import { randomUUID } from 'node:crypto';
12
12
  import { startUrlCapture } from './url-capture.js';
13
13
  import { deriveJsonlPath } from './jsonl-path.js';
14
+ import { composeAppendSystemPrompt } from './system-prompt.js';
14
15
  export async function spawnClaudeSession(deps, args) {
15
16
  const sessionId = randomUUID();
16
17
  const startedAt = new Date().toISOString();
17
18
  const start = Date.now();
18
- const argv = ['--verbose', '--remote-control'];
19
+ const appendSystemPrompt = composeAppendSystemPrompt(deps.host);
20
+ if (!appendSystemPrompt) {
21
+ const stderrTail = deps.host.lanIPv4Diagnostic ?? 'append-system-prompt unresolved';
22
+ deps.logger(`spawn-failed reason=host-context-unresolved stderr-tail=${JSON.stringify(stderrTail)}`);
23
+ return { ok: false, reason: 'host-context-unresolved', stderrTail };
24
+ }
25
+ const argv = [
26
+ '--verbose',
27
+ '--remote-control',
28
+ '--append-system-prompt',
29
+ appendSystemPrompt,
30
+ ];
19
31
  if (args.resumeClaudeSessionId) {
20
32
  argv.push('--resume', args.resumeClaudeSessionId);
21
33
  }
@@ -63,6 +75,7 @@ export async function spawnClaudeSession(deps, args) {
63
75
  deps.logger(`kill pid=${pty.pid} reason=process-exited exit-code=0`);
64
76
  });
65
77
  deps.logger(`spawn pid=${pty.pid} sessionUrl=${url} jsonlPath=${jsonlPath ?? 'unknown'} senderId=${args.senderId} role=${args.role} channel=${args.channel} latency-ms=${Date.now() - start}`);
78
+ deps.logger(`[pty-spawn] sessionId=${sessionId} appendSystemPromptBytes=${Buffer.byteLength(appendSystemPrompt, 'utf8')} hostname=${deps.host.hostname} lanIPv4=${deps.host.lanIPv4} adminUrl=${deps.host.adminUrl} tunnelUrl=${deps.host.tunnelUrl ?? 'none'}`);
66
79
  resolve({ ok: true, session });
67
80
  },
68
81
  onTimeout: () => {
@@ -1 +1 @@
1
- {"version":3,"file":"pty-spawner.js","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,yEAAyE;AACzE,0DAA0D;AAC1D,0EAA0E;AAC1E,2EAA2E;AAC3E,eAAe;AACf,EAAE;AACF,0EAA0E;AAC1E,0EAA0E;AAC1E,iEAAiE;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAmCjD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAe,EAAE,IAAe;IACvE,MAAM,SAAS,GAAG,UAAU,EAAE,CAAA;IAC9B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,MAAM,IAAI,GAAa,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAA;IACxD,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAA;IACnD,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;QAC7B,CAAC;IACH,CAAC;IAED,IAAI,GAAc,CAAA;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE;YACxC,GAAG,OAAO,CAAC,GAAG;YACd,IAAI,EAAE,gBAAgB;SACvB,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,GAA4B,CAAA;QACtC,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,kBAAkB,CAAA;QAClF,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;QAC/C,IAAI,CAAC,MAAM,CAAC,uBAAuB,MAAM,gBAAgB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QACtF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAA;IAC1C,CAAC;IAED,OAAO,MAAM,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,EAAE;QAChD,eAAe,CAAC;YACd,GAAG;YACH,SAAS,EAAE,IAAI,CAAC,mBAAmB;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;gBACb,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;gBACrD,MAAM,OAAO,GAAkB;oBAC7B,SAAS;oBACT,GAAG,EAAE,GAAG,CAAC,GAAG;oBACZ,GAAG;oBACH,SAAS;oBACT,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,SAAS;oBACT,GAAG;oBACH,MAAM,EAAE,KAAK;iBACd,CAAA;gBACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBACvB,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;oBACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAA;oBACrB,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,GAAG,oCAAoC,CAAC,CAAA;gBACtE,CAAC,CAAC,CAAA;gBACF,IAAI,CAAC,MAAM,CACT,aAAa,GAAG,CAAC,GAAG,eAAe,GAAG,cAAc,SAAS,IAAI,SAAS,aAAa,IAAI,CAAC,QAAQ,SAAS,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,OAAO,eAAe,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAClL,CAAA;gBACD,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;YAChC,CAAC;YACD,SAAS,EAAE,GAAG,EAAE;gBACd,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;gBACnB,IAAI,CAAC,MAAM,CAAC,wDAAwD,CAAC,CAAA;gBACrE,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAA;YACvE,CAAC;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAgB,EAChB,SAAiB;IAEjB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACnC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IAC3C,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC5B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IACpC,CAAC;IACD,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACrB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAClC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,CAAC,CAAC,MAAM;gBAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACpC,OAAO,EAAE,CAAA;QACX,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;QACpB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;YAChB,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,OAAO,EAAE,CAAA;QACX,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAC5B,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,sCAAsC,CAAC,CAAA;IACpE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AACpC,CAAC"}
1
+ {"version":3,"file":"pty-spawner.js","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface HostContext {
2
+ hostname: string;
3
+ lanIPv4: string | null;
4
+ adminUrl: string;
5
+ tunnelUrl: string | null;
6
+ }
7
+ export declare const ATTACHMENT_CEILING_BYTES = 31457280;
8
+ export declare function composeAppendSystemPrompt(host: HostContext): string | null;
9
+ //# sourceMappingURL=system-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,eAAO,MAAM,wBAAwB,WAAa,CAAA;AAElD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAc1E"}
@@ -0,0 +1,35 @@
1
+ // Composes the `--append-system-prompt` block injected into every spawned
2
+ // `claude --verbose --remote-control` PTY. Two sentinel-wrapped sections:
3
+ //
4
+ // <host> ... </host> — hostname, LAN IPv4, admin URL,
5
+ // tunnel URL (or "none")
6
+ // <attachment-ceiling> ... </attachment-ceiling>
7
+ // — 30 MiB SendUserFile ceiling and
8
+ // the tunnel-link workaround for
9
+ // oversize files
10
+ //
11
+ // The block is the only doctrine surface that survives Claude Code SDK
12
+ // upgrades. Per Task 037, no skill carries a copy; one edit here changes the
13
+ // ceiling or workaround for every agent in every session.
14
+ //
15
+ // A null `lanIPv4` indicates host-context resolution failed at boot; the
16
+ // caller passes that case as `null` to indicate the spawner should reject
17
+ // with `host-context-unresolved` rather than emit a malformed block.
18
+ export const ATTACHMENT_CEILING_BYTES = 31_457_280; // 30 MiB, mirrors the SDK uploader
19
+ export function composeAppendSystemPrompt(host) {
20
+ if (!host.lanIPv4)
21
+ return null;
22
+ const tunnelLine = host.tunnelUrl ? host.tunnelUrl : 'none';
23
+ return [
24
+ '<host>',
25
+ `hostname: ${host.hostname}`,
26
+ `lan-ipv4: ${host.lanIPv4}`,
27
+ `admin-url: ${host.adminUrl}`,
28
+ `tunnel-url: ${tunnelLine}`,
29
+ '</host>',
30
+ '<attachment-ceiling>',
31
+ 'SendUserFile and any inline attachment surface accept at most 30 MiB per file. Over that ceiling, write the file under <spawn-cwd>/output/ and send the operator the public URL at <tunnel-url>/files/<relative-path>; never call SendUserFile with a file whose on-disk size exceeds 30 MiB. The tool returns "N files delivered to user" even when the byte upload silently fails, so the response is not evidence of delivery.',
32
+ '</attachment-ceiling>',
33
+ ].join('\n');
34
+ }
35
+ //# sourceMappingURL=system-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,0EAA0E;AAC1E,EAAE;AACF,2EAA2E;AAC3E,oEAAoE;AACpE,mDAAmD;AACnD,6EAA6E;AAC7E,4EAA4E;AAC5E,4DAA4D;AAC5D,EAAE;AACF,uEAAuE;AACvE,6EAA6E;AAC7E,0DAA0D;AAC1D,EAAE;AACF,yEAAyE;AACzE,0EAA0E;AAC1E,qEAAqE;AASrE,MAAM,CAAC,MAAM,wBAAwB,GAAG,UAAU,CAAA,CAAC,mCAAmC;AAEtF,MAAM,UAAU,yBAAyB,CAAC,IAAiB;IACzD,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAA;IAC3D,OAAO;QACL,QAAQ;QACR,aAAa,IAAI,CAAC,QAAQ,EAAE;QAC5B,aAAa,IAAI,CAAC,OAAO,EAAE;QAC3B,cAAc,IAAI,CAAC,QAAQ,EAAE;QAC7B,eAAe,UAAU,EAAE;QAC3B,SAAS;QACT,sBAAsB;QACtB,maAAma;QACna,uBAAuB;KACxB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC"}
@@ -0,0 +1 @@
1
+ import{a as e}from"./brand-jT16ErmC.js";var t=e();function n({checked:e,onChange:n,label:r,disabled:i}){return(0,t.jsxs)(`label`,{className:`maxy-checkbox${i?` maxy-checkbox--disabled`:``}`,children:[(0,t.jsx)(`input`,{type:`checkbox`,checked:e,onChange:e=>n(e.target.checked),disabled:i}),(0,t.jsx)(`span`,{className:`maxy-checkbox__box`,children:`✱`}),r&&(0,t.jsx)(`span`,{className:`maxy-checkbox__label`,children:r})]})}export{n as t};