Let the in-play Scripts panel show each script's code
The panel only showed a name + on/off toggle, so demo (server-owned) scripts — which never appear on the personal Scripts page — had no in-app way to inspect their code. AdventureScriptOut already ships the hook sources, so add a "View code" expander that renders the non-empty hooks (library / onInput / onModelContext / onOutput) read-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TEpWMjnfPqzZ13nPMoGhs5
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
2fc167327d
commit
73f43efbe7
@@ -440,6 +440,45 @@ button:disabled { opacity: 0.45; cursor: default; transform: none; box-shadow: n
|
|||||||
animation: panel-in 0.25s ease both;
|
animation: panel-in 0.25s ease both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------- In-play script viewer ---------- */
|
||||||
|
|
||||||
|
.adv-script {
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
.adv-script-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
||||||
|
.adv-script-desc { font-size: 0.82rem; margin-top: 4px; }
|
||||||
|
.linklike {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
padding: 0;
|
||||||
|
color: var(--accent-bright);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.linklike:hover { text-decoration: underline; }
|
||||||
|
.adv-script-code { margin-top: 8px; }
|
||||||
|
.adv-script-hook {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
color: var(--text-dim);
|
||||||
|
margin: 8px 0 2px;
|
||||||
|
}
|
||||||
|
.adv-script-code pre {
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px;
|
||||||
|
background: var(--bg-input);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow-x: auto;
|
||||||
|
font-family: var(--font-mono, monospace);
|
||||||
|
font-size: 0.76rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Left status drawer (script state) ---------- */
|
/* ---------- Left status drawer (script state) ---------- */
|
||||||
|
|
||||||
.status-drawer {
|
.status-drawer {
|
||||||
|
|||||||
@@ -283,8 +283,16 @@ function MemoryPanel({ adventure, setAdventure, refreshKey }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SCRIPT_HOOKS = [
|
||||||
|
['Shared library', 'library_js'],
|
||||||
|
['onInput', 'input_js'],
|
||||||
|
['onModelContext', 'context_js'],
|
||||||
|
['onOutput', 'output_js'],
|
||||||
|
]
|
||||||
|
|
||||||
function ScriptsPanel({ advId }) {
|
function ScriptsPanel({ advId }) {
|
||||||
const [scripts, setScripts] = useState(null)
|
const [scripts, setScripts] = useState(null)
|
||||||
|
const [openId, setOpenId] = useState(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
api.listAdventureScripts(advId).then(setScripts).catch(() => setScripts([]))
|
api.listAdventureScripts(advId).then(setScripts).catch(() => setScripts([]))
|
||||||
@@ -306,13 +314,38 @@ function ScriptsPanel({ advId }) {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{scripts.map((s) => (
|
{scripts.map((s) => {
|
||||||
<label key={s.id} className="script-attach">
|
const hooks = SCRIPT_HOOKS.filter(([, f]) => (s[f] || '').trim())
|
||||||
<input type="checkbox" checked={s.enabled} onChange={() => toggle(s)} />
|
const open = openId === s.id
|
||||||
<span>{s.name}</span>
|
return (
|
||||||
<span className="dim">{s.description}</span>
|
<div key={s.id} className="adv-script">
|
||||||
</label>
|
<div className="adv-script-head">
|
||||||
))}
|
<label className="script-attach" style={{ margin: 0 }}>
|
||||||
|
<input type="checkbox" checked={s.enabled} onChange={() => toggle(s)} />
|
||||||
|
<span>{s.name}</span>
|
||||||
|
</label>
|
||||||
|
<button className="linklike" onClick={() => setOpenId(open ? null : s.id)}>
|
||||||
|
{open ? 'Hide code' : 'View code'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{s.description && <div className="dim adv-script-desc">{s.description}</div>}
|
||||||
|
{open && (
|
||||||
|
<div className="adv-script-code">
|
||||||
|
{hooks.length === 0 ? (
|
||||||
|
<div className="empty">This script has no code.</div>
|
||||||
|
) : (
|
||||||
|
hooks.map(([label, f]) => (
|
||||||
|
<div key={f}>
|
||||||
|
<div className="adv-script-hook">{label}</div>
|
||||||
|
<pre>{s[f]}</pre>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user