@rubytech/create-realagent-code 0.1.19 → 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.
- package/dist/index.js +1 -0
- package/dist/port-resolution.js +2 -0
- package/package.json +1 -1
- package/payload/platform/plugins/admin/hooks/onboarding-skill-drift.sh +100 -0
- package/payload/platform/scripts/check-no-direct-clipboard.mjs +54 -0
- package/payload/platform/scripts/seed-neo4j.sh +7 -0
- package/payload/platform/services/claude-session-manager/dist/config.d.ts +8 -0
- package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/config.js +66 -1
- package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +3 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +9 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +14 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +9 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js +35 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -0
- package/payload/server/public/assets/Checkbox-B79fVxpA.js +1 -0
- package/payload/server/public/assets/admin-DgB_IeWB.js +216 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DU8MnqOj.js → architectureDiagram-Q4EWVU46-D8e59YJ0.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DwBZc1na.js → blockDiagram-DXYQGD6D-CxaDkc0A.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-CtqEPPN5.css → brand-Cg9t5U6J.css} +1 -1
- package/payload/server/public/assets/brand-jT16ErmC.js +9 -0
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-C9ZHreVX.js → c4Diagram-AHTNJAMY-D0PAvq-q.js} +1 -1
- package/payload/server/public/assets/channel-BU_eIdRB.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-DNXqHk42.js → chunk-336JU56O-B-CXn-Et.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-DOLKkQGn.js → chunk-426QAEUC-BLzCQHKA.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-l8iZx-gQ.js → chunk-4TB4RGXK-Bql1UwLT.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-DQwRtUdO.js → chunk-5FUZZQ4R-CQK7jBtX.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CvvoBJnn.js → chunk-5PVQY5BW-AJc1-lvX.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-DV1J4-LR.js → chunk-EDXVE4YY-Cf3E3THL.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-Co6qpIQl.js → chunk-ENJZ2VHE-BNx6z6hJ.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-9v9O_mwr.js → chunk-ICPOFSXX-DBUEFs2-.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-D2X1NuKZ.js → chunk-OYMX7WX6-Csx2p315.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-DmqWEsN2.js → chunk-U2HBQHQK-x17h7UYW.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-C0b2a6Bq.js → chunk-X2U36JSP--Lkl5yjV.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BdBAquWg.js → chunk-YZCP3GAM-C4GsNX8A.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-C1AFspLM.js → chunk-ZZ45TVLE-YrhUPmZc.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DMpM1d2b.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-D_XbuPVj.js +1 -0
- package/payload/server/public/assets/clone-BBT00JUO.js +1 -0
- package/payload/server/public/assets/{dagre-KV5264BT-a88ylEXY.js → dagre-KV5264BT-D6JU6DW_.js} +1 -1
- package/payload/server/public/assets/{dagre-7eiQzAHj.js → dagre-YVALPG-M.js} +1 -1
- package/payload/server/public/assets/data-BdwO_kv-.js +1 -0
- package/payload/server/public/assets/device-url-actions-C8dD0ydz.js +33 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-XuINnSy-.js → diagram-5BDNPKRD-yeO06N5Q.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-B93iSQ8a.js → diagram-G4DWMVQ6-DzbVT_BC.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-Gcoj967k.js → diagram-MMDJMWI5-DwYO5VZF.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-C2BKnsAF.js → diagram-TYMM5635-BLUcdkDS.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DwbOuflI.js → erDiagram-SMLLAGMA-BiEUB19e.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CEExhdxC.js → flowDiagram-DWJPFMVM-TILIKxOp.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-kYNYeUK-.js → ganttDiagram-T4ZO3ILL-B7cGzYqT.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-D3X2eJPE.js → gitGraphDiagram-UUTBAWPF-DFOxN5bc.js} +1 -1
- package/payload/server/public/assets/graph-CfZJrc9u.js +1 -0
- package/payload/server/public/assets/graph-labels-DJ717p00.js +1 -0
- package/payload/server/public/assets/{graphlib-_S6i_Jn2.js → graphlib-BBibixaA.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-CQx0vDcC.js → infoDiagram-42DDH7IO-nH2azhY8.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-0eZUgqUP.js → ishikawaDiagram-UXIWVN3A-WD3tfqFi.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-D-B2Kd_J.js → journeyDiagram-VCZTEJTY-LUkaVSqw.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BmLn-OEz.js → kanban-definition-6JOO6SKY-Dk-lYgpJ.js} +1 -1
- package/payload/server/public/assets/{line-h25nWPBw.js → line-BDv6CEnp.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-CXXeaSZi.js → mermaid-parser.core-D2XsSGgp.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-BjFfgEHL.js → mermaid.core-FyN-UmQV.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-Dql4ILoK.js → mindmap-definition-QFDTVHPH-BRAHEUIS.js} +1 -1
- package/payload/server/public/assets/page-BWHYktEF.js +1 -0
- package/payload/server/public/assets/page-CZQd-W3C.js +50 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-nYaoTCKZ.js → pieDiagram-DEJITSTG-BqibVC2X.js} +1 -1
- package/payload/server/public/assets/public-BDUZIabs.js +8 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-XG8xivm9.js → quadrantDiagram-34T5L4WZ-DNuExGnr.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-C2GzfT-6.js → requirementDiagram-MS252O5E-5JXTdydh.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-3aI78p2X.js → sankeyDiagram-XADWPNL6-B_8rhvcR.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CvaNRYuS.js → sequenceDiagram-FGHM5R23-BznkBgjf.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DHT2Zyvj.js → stateDiagram-FHFEXIEX-BeAZOQfs.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-iVlXKz7S.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DqPjDUku.js → timeline-definition-GMOUNBTQ-CpJAs-Vw.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-lQB1LgjH.js → vennDiagram-DHZGUBPP-BzH3ItkG.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-sxSMxkwm.js → wardleyDiagram-NUSXRM2D-ax9AgwA1.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-4-dvvfSD.js → xychartDiagram-5P7HB3ND-CV6vt_tW.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +32 -5
- package/payload/server/public/assets/Checkbox-BmlrSRF8.js +0 -1
- package/payload/server/public/assets/admin-Drvl0Okz.js +0 -216
- package/payload/server/public/assets/channel-Boz4UHN2.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CRA6E97A.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-VnieTvEm.js +0 -1
- package/payload/server/public/assets/clone-6YhZHo8b.js +0 -1
- package/payload/server/public/assets/data-Dq_if_B4.js +0 -1
- package/payload/server/public/assets/device-url-actions-_s-UgHa3.js +0 -33
- package/payload/server/public/assets/graph-CNFkzAKU.js +0 -1
- package/payload/server/public/assets/graph-labels-C6ZZPglH.js +0 -1
- package/payload/server/public/assets/jsx-runtime-BSJRynxp.js +0 -9
- package/payload/server/public/assets/page-CdWWweCx.js +0 -1
- package/payload/server/public/assets/page-D20UnO_r.js +0 -50
- package/payload/server/public/assets/public-CXgyLdJU.js +0 -8
- 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);
|
package/dist/port-resolution.js
CHANGED
|
@@ -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
|
@@ -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
|
|
@@ -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;
|
|
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 {
|
|
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;
|
|
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":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGjD,MAAM,GAAG,GAAG,0BAA0B,CAAA;AACtC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAA;AAE3D,SAAS,eAAe,CACtB,GAAW,EACX,IAAc,EACd,GAAsB,EACtB,GAAW;IAEX,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE;QAChC,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,GAAG;QACT,IAAI,EAAE,EAAE;QACR,GAAG;QACH,GAAG,EAAE,GAAgC;KACtC,CAAC,CAAA;IACF,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACnF,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;QAClC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;KACrC,CAAA;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE,CAAA;IAChC,GAAG,CAAC,aAAa,MAAM,CAAC,IAAI,eAAe,MAAM,CAAC,UAAU,aAAa,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;
|
|
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,
|
|
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
|
|
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;
|
|
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};
|