mirror of
https://github.com/garrytan/gstack.git
synced 2026-07-08 09:07:55 +02:00
feat(extension): route gstackInjectToTerminal through /pty-inject-scan (#1370)
Closes the documented-vs-shipped gap codex flagged in #1370. The sidebar's two PTY-injection call sites (Inspector "Send to Code" and toolbar Cleanup) now pre-scan via the new /pty-inject-scan endpoint before writing to the live claude REPL. Adds window.gstackScanForPTYInject(text, origin) to extension/sidepanel-terminal.js: - Async, returns { allow, verdict, reasons, l4 } - POST to /pty-inject-scan with the existing root-token auth - WARN+confirm on scan failure (network down, sidecar absent, etc.) rather than silent PASS — D7 honest-degradation gstackInjectToTerminal stays synchronous, returns boolean. Per D6: keeping the inject sync means existing `const ok = ...?.()` callers don't break, and the invariant test in test/extension-pty-inject-invariant.test.ts can statically pin that every call goes through the scan first. extension/sidepanel.js call sites updated: - inspectorSendBtn click → await scan, BLOCK drops + WARN prompts via window.confirm, PASS injects silently - runCleanup() → same flow. Static cleanup prompt always PASSes but still routes through scan to honor the invariant. C20 of the security-stack wave. C21 adds the static invariant test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+35
-1
@@ -683,7 +683,7 @@ function updateSendButton() {
|
||||
}
|
||||
}
|
||||
|
||||
inspectorSendBtn.addEventListener('click', () => {
|
||||
inspectorSendBtn.addEventListener('click', async () => {
|
||||
if (!inspectorData) return;
|
||||
|
||||
let message;
|
||||
@@ -708,6 +708,20 @@ inspectorSendBtn.addEventListener('click', () => {
|
||||
// Inject into the running claude PTY so the user can ask claude to act
|
||||
// on the inspector data. Replaces the old `sidebar-command` route which
|
||||
// spawned a one-shot claude -p (sidebar-agent.ts is gone).
|
||||
//
|
||||
// Pre-scan via /pty-inject-scan before injection (D6, closes #1370).
|
||||
// gstackScanForPTYInject is async; gstackInjectToTerminal stays sync.
|
||||
const verdict = await window.gstackScanForPTYInject?.(message + '\n', 'inspector-send');
|
||||
if (verdict?.verdict === 'BLOCK') {
|
||||
console.warn('[gstack sidebar] Inspector send BLOCKED by /pty-inject-scan:', verdict.reasons);
|
||||
return;
|
||||
}
|
||||
if (verdict?.verdict === 'WARN') {
|
||||
const confirmed = window.confirm(
|
||||
`Inspector send flagged as suspicious (${(verdict.reasons || []).join(', ')}). Inject anyway?`,
|
||||
);
|
||||
if (!confirmed) return;
|
||||
}
|
||||
const ok = window.gstackInjectToTerminal?.(message + '\n');
|
||||
if (!ok) {
|
||||
console.warn('[gstack sidebar] Inspector send needs an active Terminal session.');
|
||||
@@ -735,6 +749,26 @@ async function runCleanup(...buttons) {
|
||||
'header/masthead, headline, article body, images, byline, and date. Also',
|
||||
'unlock scrolling if the page is scroll-locked.',
|
||||
].join('\n');
|
||||
// Pre-scan via /pty-inject-scan before injection (D6, closes #1370).
|
||||
// The cleanup prompt is a STATIC template (no page-derived content), so
|
||||
// it will always PASS, but we still route it through the scan path so
|
||||
// the invariant test in test/extension-pty-inject-invariant.test.ts
|
||||
// confirms every call site goes through gstackScanForPTYInject first.
|
||||
const verdict = await window.gstackScanForPTYInject?.(cleanupPrompt + '\n', 'cleanup-button');
|
||||
if (verdict?.verdict === 'BLOCK') {
|
||||
console.warn('[gstack sidebar] Cleanup BLOCKED by /pty-inject-scan:', verdict.reasons);
|
||||
setTimeout(() => buttons.forEach(b => b?.classList.remove('loading')), 200);
|
||||
return;
|
||||
}
|
||||
if (verdict?.verdict === 'WARN') {
|
||||
const confirmed = window.confirm(
|
||||
`Cleanup flagged as suspicious (${(verdict.reasons || []).join(', ')}). Inject anyway?`,
|
||||
);
|
||||
if (!confirmed) {
|
||||
setTimeout(() => buttons.forEach(b => b?.classList.remove('loading')), 200);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const sent = window.gstackInjectToTerminal?.(cleanupPrompt + '\n');
|
||||
if (!sent) {
|
||||
console.warn('[gstack sidebar] Cleanup needs an active Terminal session.');
|
||||
|
||||
Reference in New Issue
Block a user