Skip to content

Commit 04a323d

Browse files
GiniGini
authored andcommitted
feat: add task operating settings view
1 parent 30277eb commit 04a323d

4 files changed

Lines changed: 20 additions & 4 deletions

File tree

docs/IMPLEMENTATION-LOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@
6565
- Made immutable Computer-rail evidence URL-addressable. Selecting a recorded terminal, frame, preview, artifact, deck, diff, or approval event stores its event ID in the task URL and restores it on refresh; the header exposes sequence and a short evidence-hash marker. The live X11 display is deliberately excluded because it is a current view, not a historical evidence artifact.
6666
- Reworked the deck workspace into a review surface rather than an outline list: compact visual slide cards, position-aware previous/next controls, a focused deck canvas, and per-slide notes that open directly in the evidence-bound source editor. These are visual outline thumbnails, not an assertion that the PPTX itself has been rendered to images.
6767
- Replaced opaque click-to-cycle runtime selection with a server-derived readiness picker. It identifies the task boundary and availability for Safe demo, native Claude Agent SDK, ONEComputer sandbox, and remote runtime without exposing server credentials; unavailable remote/sandbox choices cannot be submitted, while the API remains the authority for enforcement.
68+
- Added a read-only task Settings workspace tab. It gathers the runtime/boundary, gateway-attestation, approval, artifact-contract, and attached-context record in one reviewable place while deliberately excluding credentials, VTI Wallet keys, provider controls, and X11/VNC/CDP channels.

docs/MANUS-PARITY.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ This is the implementation gate, not a marketing checklist. **I** means behavior
8585
63. **P** Syntax-highlighted code viewer — line-numbered source exists; token highlighting is pending.
8686
64. **I** Editable code surface — embedded text editor saves with optimistic hash protection, pre-edit snapshot, and evidence event.
8787
65. **I** Diff mode — Original, Modified, and line-oriented Diff views are available before save.
88-
66. **M** Dashboard workspace tab.
88+
66. **I** Dashboard workspace tab — task progress, artifact, evidence, boundary, and approval summaries are available in the workspace.
8989
67. **M** Database workspace tab.
9090
68. **I** Files workspace tab.
91-
69. **M** Settings workspace tab.
91+
69. **P** Settings workspace tab — read-only task runtime, security boundary, approval, artifact-contract, and context metadata are visible; organization-wide settings and permission management remain pending.
9292
70. **I** Workspace expansion — fullscreen overlay with explicit exit and Escape handling.
9393
71. **I** Vite project generation — Website, App, and Game modes emit a portable Vite scaffold.
9494
72. **I** React and TypeScript generation as a mode contract.

src/components/Workspace.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { Activity, ArrowLeft, ArrowRight, Check, Code2, Copy, Download, Eye, File, Files, Globe2, History, Maximize2, Minimize2, Network, Pencil, Presentation, RefreshCw, Save, ShieldCheck, TerminalSquare } from 'lucide-react'
1+
import { Activity, ArrowLeft, ArrowRight, Check, Code2, Copy, Download, Eye, File, Files, Globe2, History, Maximize2, Minimize2, Network, Pencil, Presentation, RefreshCw, Save, Settings2, ShieldCheck, TerminalSquare } from 'lucide-react'
22
import { AnimatePresence, motion } from 'framer-motion'
33
import { useEffect, useMemo, useState } from 'react'
44
import { copyTask, getEvidence, getFile, getFiles, getVersions, restoreVersion, updateFile } from '../lib/api'
55
import type { TaskSnapshot, WorkspaceFile, WorkspaceVersion } from '../types'
66
import { ComputerTimeline } from './ComputerTimeline'
77
import { HighlightedCode } from './HighlightedCode'
88

9-
type Tab = 'dashboard' | 'computer' | 'preview' | 'visual' | 'slides' | 'code' | 'files' | 'history' | 'evidence'
9+
type Tab = 'dashboard' | 'computer' | 'preview' | 'visual' | 'slides' | 'code' | 'files' | 'history' | 'evidence' | 'settings'
1010
type SlideOutline = { number: number; title: string; summary: string }
1111

1212
const formatBytes = (bytes: number) => bytes < 1024 ? `${bytes} B` : `${(bytes / 1024).toFixed(1)} KB`
@@ -95,6 +95,7 @@ export const Workspace = ({ task }: { task: TaskSnapshot }) => {
9595
<button className={tab === 'files' ? 'active' : ''} onClick={() => setTab('files')}><Files size={14} /> Files</button>
9696
<button className={tab === 'history' ? 'active' : ''} onClick={() => setTab('history')}><History size={14} /> History</button>
9797
<button className={tab === 'evidence' ? 'active' : ''} onClick={() => setTab('evidence')}><ShieldCheck size={14} /> Evidence</button>
98+
<button className={tab === 'settings' ? 'active' : ''} onClick={() => setTab('settings')}><Settings2 size={14} /> Settings</button>
9899
</div>
99100
<div className="workspace-tools"><button title="Make a provenance-linked copy" onClick={() => void copyTask(task.id).then((copy) => window.location.assign(`/tasks/${copy.id}`))}><Copy size={14} /></button><a title="Download source and evidence" href={`/api/tasks/${task.id}/download`}><Download size={14} /></a><button><RefreshCw size={14} /></button><button title={fullscreen ? 'Exit fullscreen' : 'Expand workspace'} onClick={() => setFullscreen((value) => !value)}>{fullscreen ? <Minimize2 size={14} /> : <Maximize2 size={14} />}</button></div>
100101
</header>
@@ -144,6 +145,19 @@ export const Workspace = ({ task }: { task: TaskSnapshot }) => {
144145
<p className="evidence-note"><Network size={13} /> Local hashes demonstrate ordering only. Production evidence must be anchored outside the workload through OpenVTC.</p>
145146
</motion.div>
146147
)}
148+
{tab === 'settings' && (
149+
<motion.div key="settings" initial={{ opacity: 0, y: 4 }} animate={{ opacity: 1, y: 0 }} className="task-settings-pane">
150+
<header><div><Settings2 size={17} /><div><span>Task operating settings</span><strong>Read-only runtime and context record</strong></div></div><em>Secrets never render here</em></header>
151+
<div className="task-settings-grid">
152+
<article><span>Runtime</span><strong>{task.provider === 'demo' ? 'Safe demo' : task.provider === 'claude_sdk' ? 'Claude Agent SDK' : task.provider === 'onecomputer' ? 'ONEComputer sandbox' : 'Remote runtime'}</strong><small>{task.securityContext?.executionBoundary?.replaceAll('_', ' ') ?? 'Awaiting run boundary'}</small></article>
153+
<article><span>Security boundary</span><strong>{task.securityContext?.gatewayEnforced ? 'Gateway attested' : 'No gateway attestation'}</strong><small>{task.securityContext?.sandboxState ? `Sandbox ${task.securityContext.sandboxState}` : 'No sandbox lifecycle recorded'}</small></article>
154+
<article><span>Approval authority</span><strong>{task.approval?.state ?? 'No approval pending'}</strong><small>{task.approval ? 'Decision remains outside the browser in VTI Wallet' : 'No consequential action has been requested'}</small></article>
155+
<article><span>Artifact contract</span><strong>{task.mode.replaceAll('_', ' ')} mode</strong><small>Validation reports distinguish static evidence from executed runtime checks.</small></article>
156+
</div>
157+
<section className="task-settings-context"><header><strong>Attached governed context</strong><span>Metadata only · treated as untrusted input</span></header><div>{task.skills.length > 0 ? <article><span>Skill guides</span><p>{task.skills.map((skill) => skill.replaceAll('_', ' ')).join(' · ')}</p></article> : <article><span>Skill guides</span><p>None selected for this task.</p></article>}{task.references.length > 0 ? <article><span>Website references</span><p>{task.references.map((reference) => new URL(reference).hostname).join(' · ')}</p></article> : <article><span>Website references</span><p>None attached.</p></article>}{task.attachments.length > 0 ? <article><span>Local attachments</span><p>{task.attachments.length} bounded file{task.attachments.length === 1 ? '' : 's'} staged under task inputs.</p></article> : <article><span>Local attachments</span><p>None attached.</p></article>}<article><span>Project</span><p>{task.projectId}</p></article></div></section>
158+
<p className="task-settings-note"><ShieldCheck size={13} /> Runtime credentials, wallet signing keys, X11/VNC/CDP channels, and provider control-plane access are intentionally absent from the browser.</p>
159+
</motion.div>
160+
)}
147161
</AnimatePresence>
148162
</div>
149163
</section>

src/index.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)