opencode-codex-security 0.1.0 → 0.1.2
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/README.md +30 -32
- package/dist/gui-experimental.cjs +8 -8
- package/docs/GLOBAL-CONFIG.md +82 -6
- package/docs/PUBLISHING.md +40 -29
- package/docs/RELEASING.md +5 -5
- package/docs/SDK.md +21 -9
- package/package.json +2 -1
- package/src/core/codex-adapter.ts +29 -19
- package/src/core/credential-guard.ts +47 -0
- package/src/core/planned-scan.ts +32 -1
- package/src/core/provider-config.ts +254 -0
- package/src/core/scan-plan.ts +3 -2
- package/src/core/sdk-settings.ts +135 -11
- package/src/core/security-operations.ts +16 -16
- package/src/operation-tools.ts +9 -3
- package/src/plan-view.ts +16 -1
- package/src/plugin.ts +5 -1
- package/src/security-operations-panel.tsx +6 -3
- package/src/security-panel.tsx +6 -5
- package/src/security-tui-operations.tsx +3 -2
- package/src/tui.tsx +3 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Security scans, policy drafts and finding validation inside **OpenCode V2**, with a native terminal view, an experimental Desktop panel and tools for your session's model.
|
|
4
4
|
|
|
5
|
-
This is an early project, not an official OpenCode or OpenAI product.
|
|
5
|
+
This is an early project, not an official OpenCode or OpenAI product. Published npm versions are available under [Apache 2.0](LICENSE). Releases use stage-only npm publishing, with human 2FA approval required before each version goes live. Tested GitHub release tarballs are also available. See [npm staging](docs/PUBLISHING.md).
|
|
6
6
|
|
|
7
7
|
## What works
|
|
8
8
|
|
|
@@ -17,51 +17,45 @@ Patch application and fix verification are not implemented. Findings arrive at s
|
|
|
17
17
|
|
|
18
18
|
## Requirements
|
|
19
19
|
|
|
20
|
-
-
|
|
20
|
+
- Node.js 24.x or 26.x for installation. Node 22 does not satisfy the plugin's published `>=24` requirement. Repository development/TUI tests use Node 26.4+ (tested on 26.8.1).
|
|
21
21
|
- For real SDK operations: Python 3.10+; Python 3.10 also needs `tomli`.
|
|
22
|
-
-
|
|
23
|
-
- OpenCode V2 2.2.6
|
|
24
|
-
- For real operations: supported
|
|
22
|
+
- Default ChatGPT authentication is currently POSIX-only; its credential guard deliberately rejects Windows. Full Windows SDK operation is unverified.
|
|
23
|
+
- OpenCode V2; 2.2.6 is the original test baseline, not an exact-patch requirement. Verify loading on the installed host. Desktop integration is experimental.
|
|
24
|
+
- For real operations: supported account/model access and either an existing private dedicated ChatGPT sign-in or an explicitly configured custom Responses provider with an existing environment key. The plugin does not perform login or create/import credentials. See [no-sign-in provider setup](docs/GLOBAL-CONFIG.md#use-an-existing-codexlitellm-provider-without-sign-in). Custom-provider routing is an upcoming `0.1.2` change, not functionality in the published `0.1.0`/`0.1.1` packages.
|
|
25
25
|
|
|
26
|
-
SDK mode uses `@openai/codex-security` 0.9.1. Repository source and selected context are sent to OpenAI
|
|
26
|
+
SDK mode uses `@openai/codex-security` 0.9.1. Repository source and selected context are sent to the provider shown in the approval preview, OpenAI by default or the explicitly selected gateway. Gateway upstream routing is not verified. SDK cost limits are estimates, **not guaranteed billing caps**. Account quota/availability can also limit scans.
|
|
27
27
|
|
|
28
28
|
## Install a released version
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
For a self-contained prompt to hand to another coding agent, see [install with an agent](https://github.com/strantalis/opencode-codex-security/blob/main/docs/AGENT-SETUP.md).
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
OpenCode V2 supports npm packages directly. Add this object to your existing `plugins` array, preserving other settings:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"package": "opencode-codex-security@0.1.0",
|
|
37
|
+
"options": { "engine": "fixture" }
|
|
38
|
+
}
|
|
36
39
|
```
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
Check that no scans, approval dialogs or policy forms are active before editing watched settings or reloading. Open `/security` to verify loading. Fixture mode uses bundled examples, not your repository.
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
Published `0.1.0`/`0.1.1` real mode supports [dedicated ChatGPT authentication](docs/SDK.md#default-dedicated-chatgpt-authentication). Upcoming `0.1.2` adds [opt-in Codex/LiteLLM provider configuration](docs/GLOBAL-CONFIG.md#use-an-existing-codexlitellm-provider-without-sign-in) without a sign-in flow. It does not automatically inherit OpenCode provider settings. Wait for a release or use an explicitly provided tested build containing this change; do not use an older version for gateway support. Change `engine` to `codex` only when the approved configuration is ready and the host is idle. This starts no scan; real operations still need authorized scope and source-data transfer.
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
Verified November 10, 2026: `latest` points to `0.1.0`; `0.1.1` is also public under `next`. Pin the full version you want rather than a moving tag. A staged version or `0.0.0-stage` placeholder is not installable functionality.
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
npm ci --ignore-scripts
|
|
46
|
-
npm run check
|
|
47
|
-
```
|
|
47
|
+
### Optional: manage the installation yourself
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
For explicit npm installation/audit control, use a new dedicated consumer outside source repositories:
|
|
50
50
|
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"options": { "engine": "codex" }
|
|
57
|
-
}
|
|
58
|
-
]
|
|
59
|
-
}
|
|
51
|
+
```sh
|
|
52
|
+
mkdir security-plugin && cd security-plugin
|
|
53
|
+
npm init -y
|
|
54
|
+
npm install --save-exact --ignore-scripts opencode-codex-security@0.1.0
|
|
55
|
+
npm audit --omit=dev --audit-level=high
|
|
60
56
|
```
|
|
61
57
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
Default package behavior without `engine: codex` is an explicitly labeled, offline fixture engine. That fixture is not a real security assessment.
|
|
58
|
+
Then set the plugin entry's `package` to the absolute path of `security-plugin/node_modules/opencode-codex-security`. Keep the lockfile; use `npm ci --ignore-scripts` for repeat installs into a separate directory. Keep the previous consumer for rollback and switch paths only when the host is idle. [Tested GitHub tarballs](docs/RELEASING.md) use the same local-path route.
|
|
65
59
|
|
|
66
60
|
## Configuration and model tools
|
|
67
61
|
|
|
@@ -71,7 +65,11 @@ See [global configuration](docs/GLOBAL-CONFIG.md), [scan lifecycle and tools](do
|
|
|
71
65
|
|
|
72
66
|
## Development
|
|
73
67
|
|
|
68
|
+
Use a separate source checkout, not an installed or watched consumer. The published package already contains its Desktop bundle; consumers do not need to build it.
|
|
69
|
+
|
|
74
70
|
```sh
|
|
71
|
+
npm ci --ignore-scripts
|
|
72
|
+
|
|
75
73
|
npm run lint # ESLint, including TypeScript
|
|
76
74
|
npm run format:check # Prettier
|
|
77
75
|
npm run typecheck
|
|
@@ -95,7 +93,7 @@ These launchers isolate configuration under `.runtime/`. The plan-host tests inj
|
|
|
95
93
|
|
|
96
94
|
## Tested builds and releases
|
|
97
95
|
|
|
98
|
-
CI produces an exact tested tarball with its source commit and SHA-256 checksums. A manual workflow can promote a successful main build to a GitHub prerelease at the explicitly selected repository visibility without npm tokens. See [testing and release readiness](docs/RELEASING.md) and [security reporting](SECURITY.md). The maintainer approved public GitHub distribution under Apache 2.0. npm registry publication remains a separate step.
|
|
96
|
+
CI produces an exact tested tarball with its source commit and SHA-256 checksums. A manual workflow can promote a successful main build to a GitHub prerelease at the explicitly selected repository visibility without npm tokens. See [testing and release readiness](docs/RELEASING.md) and [security reporting](SECURITY.md). The maintainer approved public GitHub distribution under Apache 2.0. npm registry publication remains a separate, human-approved step for every version.
|
|
99
97
|
|
|
100
98
|
## Verification limits
|
|
101
99
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require("solid-js/web"),t=require("@opencode/plugin/gui"),n=require("solid-js"),r=require("@opencode/plugin/rpc"),i=require("solid-js/store");var a={type:`object`,additionalProperties:!1},o={type:`object`,properties:{mode:{type:`string`,enum:[`standard`,`deep`],description:`Optional mode for this scan. Explicit user request wins; otherwise omit to use global mode (standard by default). Do not ask when the request is clear.`},repository:{type:`string`,description:`Optional local repository path. Defaults to the known current OpenCode workspace; use an absolute path when session context is unknown. This request only, never a global target.`},scopePaths:{type:`array`,items:{type:`string`},maxItems:32,description:`Existing paths relative to repository. Omit or use [] for whole repository. No globs or traversal.`},scanPrompt:{type:`string`,maxLength:8e3,description:`Focused security instructions and relevant architecture/threat assumptions. Ask the user for missing material context. Never copy whole conversation or include secrets.`},contextFiles:{type:`array`,items:{type:`string`},maxItems:8,description:`Repository-relative text documentation to add as supporting context. No credentials or files outside repository.`}},additionalProperties:!1},s={type:`object`,properties:{kind:{type:`string`,enum:[`policy`,`validation`]},repository:{type:`string`},path:{type:`string`},contextFiles:{type:`array`,items:{type:`string`},maxItems:8},finding:{anyOf:[{type:`string`},{type:`object`}]}},required:[`kind`],additionalProperties:!1},c={type:`object`,properties:{operationId:{type:`string`}},required:[`operationId`],additionalProperties:!1},l=r.Rpc.define({id:`gill.security`,methods:{capabilities:{input:a,output:{type:`object`}},operationPrepare:{input:s,output:{type:`object`}},operationStart:{input:{type:`object`,properties:{operationId:{type:`string`},approveOpenAIInference:{type:`boolean`},approveUncappedValidation:{type:`boolean`}},required:[`operationId`],additionalProperties:!1},output:{type:`object`}},operationStatus:{input:c,output:{type:`object`}},operationList:{input:a,output:{type:`object`}},operationAnswer:{input:{type:`object`,properties:{operationId:{type:`string`},questionId:{type:`string`},answer:{type:`string`,maxLength:16384}},required:[`operationId`,`questionId`,`answer`],additionalProperties:!1},output:{type:`object`}},operationCancel:{input:c,output:{type:`object`}},prepare:{input:o,output:{type:`object`}},start:{input:{type:`object`,properties:{planId:{type:`string`},approveOpenAIInference:{type:`boolean`}},additionalProperties:!1},output:{type:`object`}},list:{input:a,output:{type:`object`}},status:{input:{type:`object`,properties:{runId:{type:`string`},planId:{type:`string`}},additionalProperties:!1},output:{type:`object`}},cancel:{input:{type:`object`,properties:{runId:{type:`string`}},additionalProperties:!1},output:{type:`object`}}},events:{changed:{schema:{type:`object`}},operationChanged:{schema:{type:`object`}}}});function u(e){return`${e.mock?`MOCK SDK TEST: no model calls or uploads.
|
|
2
|
-
`:``}Repository: ${e.repository}\nScope: ${e.scopePaths.join(`, `)||`whole repository`}\nScan prompt:\n${e.scanPrompt||`(none)`}\nContext files: ${e.contextFiles.map(e=>`${e.path} (${e.bytes} bytes, SHA-256 ${e.sha256})`).join(`; `)||`(none)`}\nSDK settings: model ${e.settings.codex.model}, reasoning ${e.settings.codex.reasoningEffort}, Daybreak ${e.settings.codex.daybreak?`on`:`off`}; mode ${e.settings.scan.mode} (${e.inputs.mode?`per-scan choice`:`global default`}), access program ${e.settings.scan.cyberAccessProgram??`Codex default`}, estimated cost stop USD ${e.settings.scan.maxCostUsd}. Account/model/Daybreak access is not verified by these settings.\nGlobal config: ${e.globalConfigFile}${e.globalConfigDigest?``:` (not present)`}\nOnly this explicit prompt and these files are added as context; conversation history is not copied. Scoped paths guide the scan, not a filesystem sandbox.\n${e.mock?`Synthetic SDK responses only.`:`Repository source and listed context go to
|
|
3
|
-
`)[0].slice(0,72)||(e.plan?.scopePaths.length?e.plan.scopePaths.join(`, `):
|
|
4
|
-
`).map(e=>e.trim()).filter(Boolean)}function F(e){return e&&typeof e==`object`&&`message`in e?String(e.message):String(e)}function de(e){return`${e.title}\nSeverity: ${e.severity} · ${e.cwe}\nLocation: ${e.path}:${e.line}\n\n${e.summary}\n\nEvidence:\n${e.evidence}\n\nSuggested remediation:\n${e.remediation}`}var I=(0,e.template)(`<button class=gs-button>New `),L=(0,e.template)(`<p class="gs-notice gs-error"role=alert>`),R=(0,e.template)(`<label>Component directory <span class=gs-muted>Optional</span><input aria-label="Policy component directory"placeholder=src/api><span class=gs-help>Relative to the repository. Leave blank for the whole project.`),z=(0,e.template)(`<button class=gs-button type=button>Back`),B=(0,e.template)(`<form class=gs-form><label>Target repository<input aria-label="Operation repository"required><span class=gs-help></span></label><details><summary>Supporting documents</summary><label>Context files<textarea aria-label="Operation context files"placeholder=docs/architecture.md></textarea><span class=gs-help>One repository-relative text document per line. Do not include secrets.</span></label></details><div class=gs-actions><button class="gs-button gs-primary"type=submit></button></div><p class="gs-muted gs-small">Preparation makes no model calls.`),V=(0,e.template)(`<ul class=gs-run-list aria-label="Recent operations">`),fe=(0,e.template)(`<section><div class=gs-section-heading><h3></h3></div><p class="gs-muted gs-small">`),pe=(0,e.template)(`<label>Finding to assess<textarea aria-label="Finding to assess"required maxlength=16000 placeholder="Describe the suspected issue, location, and evidence."></textarea><span class=gs-help>Use finding text or JSON. Do not include credentials.`),me=(0,e.template)(`<li><button class=gs-run-button><div class=gs-run-top><span class=gs-run-title></span><span class=gs-status></span></div><div class=gs-run-target>Target: </div><div class=gs-run-meta> · `),he=(0,e.template)(`<dt>Component`),ge=(0,e.template)(`<dd>`),_e=(0,e.template)(`<dt>Supporting documents`),ve=(0,e.template)(`<details class=gs-advanced><summary>Finding to assess</summary><pre>`),H=(0,e.template)(`<p>Mock operation only. No model calls or source uploads.`),ye=(0,e.template)(`<label class=gs-check><input type=checkbox> I approve validation without a cost ceiling.`),U=(0,e.template)(`<p class=gs-error>This preview expired. Prepare a new one before starting.`),W=(0,e.template)(`<div class=gs-review><h3>Review </h3><dl><dt>Repository</dt><dd></dd></dl><div class=gs-approval></div><details class=gs-advanced><summary>Model settings</summary><p> · <!> reasoning · Daybreak </p><p class=gs-muted>Account and model access are not verified. </p></details><div class=gs-actions><button class="gs-button gs-primary"></button><button class=gs-button>Edit request`),G=(0,e.template)(`<span>Estimated usage USD `),be=(0,e.template)(`<div class=gs-facts><span>`),K=(0,e.template)(`<button class=gs-button>Cancel this operation`),xe=(0,e.template)(`<p class=gs-notice>Cancelled. No completed assessment is available.`),Se=(0,e.template)(`<article class=gs-detail aria-label="Selected operation"><div class=gs-detail-title><h3></h3><p>Target: </p></div><details class=gs-advanced><summary>Operation details</summary><p class=gs-id></p><p class=gs-muted> questions answered. Operation history is kept for this server session.`),q=(0,e.template)(`<p>Repository source<!> and selected context will be sent to OpenAI.`),Ce=(0,e.template)(`<p><strong>`),we=(0,e.template)(`<p>`),Te=(0,e.template)(`<form class="gs-form gs-questions"><h3>Your input is needed</h3><ol></ol><label>Your answer<textarea aria-label="Answer security questions"maxlength=8000 required></textarea><span class=gs-help>Answer each question, or say what is unknown. Your answer goes to OpenAI for this operation; do not include secrets.</span></label><button class="gs-button gs-primary"type=submit>Send answer and continue`),J=(0,e.template)(`<li>`),Ee=(0,e.template)(`<p class="gs-muted gs-small">Draft only. Review it before applying. No repository files were changed.`),De=(0,e.template)(`<p class=gs-notice>This preview is truncated. Read the full local SDK artifact before relying on it.`),Oe=(0,e.template)(`<section class=gs-operation-result><h3></h3><pre>`),ke=(0,e.template)(`<p><strong></strong> · Static review, not runtime reproduction.`),Ae=(0,e.template)(`<p class="gs-muted gs-small">`);function je(t){let[r,a]=(0,i.createStore)({operations:[]}),[o,s]=(0,n.createSignal)(),[c,l]=(0,n.createSignal)(!0),[u,d]=(0,n.createSignal)(t.seed?.repository??t.directory),[f,p]=(0,n.createSignal)(``),[m,g]=(0,n.createSignal)(``),[_,y]=(0,n.createSignal)(t.seed?.finding??``),[b,x]=(0,n.createSignal)(!!t.seed),[S,C]=(0,n.createSignal)(``),[ee,te]=(0,n.createSignal)(!1),[w,ne]=(0,n.createSignal)(!1),[re,T]=(0,n.createSignal)(``),[E,ie]=(0,n.createSignal)(Date.now()),[ae,D]=(0,n.createSignal)(!1),O=!1,k=!1,A=0,oe=e=>{A++,d(e?.repository??t.directory),x(!!e),y(e?.finding??``),p(``),g(``),C(``),te(!1),T(``),s(void 0),l(!0)};(0,n.createEffect)((0,n.on)(()=>[t.kind,t.directory,t.seed],()=>oe(t.seed),{defer:!0}));let j=(0,n.createMemo)(()=>r.operations.filter(e=>e.kind===t.kind)),M=(0,n.createMemo)(()=>j().find(e=>e.operationId===o())??j().find(e=>e.status===`awaiting_answers`)??j()[0]),se=()=>t.kind===`policy`?`Policy draft`:`Finding validation`;(0,n.createEffect)(()=>{M()?.question?.id,C(``)}),(0,n.createEffect)(()=>{M()?.operationId,te(!1)});let ce=async()=>{if(!(O||k)){k=!0;try{let e=await t.port.list(),n=Array.isArray(e)?e:e?.operations;if(!Array.isArray(n))throw Error(`Could not read security operations.`);O||(a(`operations`,(0,i.reconcile)(n,{key:`operationId`,merge:!0})),ae()||(D(!0),!t.seed&&n.some(e=>e.kind===t.kind)&&l(!1)))}catch(e){O||T(F(e))}finally{k=!1}}},N=async e=>{if(!(w()||O)){ne(!0),T(``);try{await e(),O||await ce()}catch(e){O||T(F(e))}finally{O||ne(!1)}}},le=e=>{e.preventDefault();let n=A;N(async()=>{let e=await t.port.prepare({kind:t.kind,repository:u().trim()||t.directory,contextFiles:P(m()),...t.kind===`policy`?f().trim()?{path:f().trim()}:{}:{finding:_()}});!O&&n===A&&(s(e.operationId),a(`operations`,(0,i.reconcile)([e,...r.operations.filter(t=>t.operationId!==e.operationId)],{key:`operationId`,merge:!0})),l(!1))})},de=e=>void N(()=>t.port.start({operationId:e.operationId,approveOpenAIInference:!0,...e.kind===`validation`?{approveUncappedValidation:!0}:{}}));ce();let je=setInterval(()=>{ie(Date.now()),ce()},1500);return(0,n.onCleanup)(()=>{O=!0,clearInterval(je)}),(()=>{var r=fe(),i=r.firstChild,a=i.firstChild,o=i.nextSibling;return(0,e.insert)(a,se),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return!c()},get children(){var n=I();return n.firstChild,n.$$click=()=>oe(),(0,e.insert)(n,()=>t.kind===`policy`?`draft`:`validation`,null),(0,e.effect)(()=>n.disabled=w()),n}}),null),(0,e.insert)(o,()=>t.kind===`policy`?`Build security guidance from the repository, with questions when context is missing. Draft only: existing files stay unchanged.`:`Assess a finding against the source. This does not run an exploit or prove runtime reproduction.`),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return re()},get children(){var t=L();return(0,e.insert)(t,re),t}}),null),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return c()},get children(){var r=B(),i=r.firstChild,a=i.firstChild.nextSibling,o=a.nextSibling,s=i.nextSibling,c=s.firstChild.nextSibling.firstChild.nextSibling,h=s.nextSibling,v=h.firstChild;return r.addEventListener(`submit`,le),a.$$input=e=>{d(e.currentTarget.value),p(``),g(``),y(``),x(!1)},(0,e.insert)(o,()=>b()?`Starts from the selected finding’s repository. Check the target before review.`:`Defaults to this workspace. Changing it affects only this operation.`),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return t.kind===`policy`},get fallback(){return(()=>{var t=pe(),n=t.firstChild.nextSibling;return n.$$input=e=>y(e.currentTarget.value),(0,e.effect)(()=>n.disabled=w()),(0,e.effect)(()=>n.value=_()),t})()},get children(){var t=R(),n=t.firstChild.nextSibling.nextSibling;return n.$$input=e=>p(e.currentTarget.value),(0,e.effect)(()=>n.disabled=w()),(0,e.effect)(()=>n.value=f()),t}}),s),c.$$input=e=>g(e.currentTarget.value),(0,e.insert)(v,(()=>{var n=(0,e.memo)(()=>!!w());return()=>n()?`Preparing…`:`Review `+(t.kind===`policy`?`policy draft`:`validation`)})()),(0,e.insert)(h,(0,e.createComponent)(n.Show,{get when(){return j().length},get children(){var t=z();return t.$$click=()=>l(!1),(0,e.effect)(()=>t.disabled=w()),t}}),null),(0,e.effect)(e=>{var t=w(),n=w(),r=w();return t!==e.e&&(a.disabled=e.e=t),n!==e.t&&(c.disabled=e.t=n),r!==e.a&&(v.disabled=e.a=r),e},{e:void 0,t:void 0,a:void 0}),(0,e.effect)(()=>a.value=u()),(0,e.effect)(()=>c.value=m()),r}}),null),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return j().length>1},get children(){var t=V();return(0,e.insert)(t,(0,e.createComponent)(n.For,{get each(){return j()},children:t=>(()=>{var n=me(),r=n.firstChild,i=r.firstChild,a=i.firstChild,o=a.nextSibling,c=i.nextSibling;c.firstChild;var u=c.nextSibling,d=u.firstChild;return r.$$click=()=>{s(t.operationId),l(!1)},(0,e.insert)(a,()=>h(t.repository),null),(0,e.insert)(a,(()=>{var n=(0,e.memo)(()=>!!t.plan.path);return()=>n()?` / `+t.plan.path:``})(),null),(0,e.insert)(o,(()=>{var n=(0,e.memo)(()=>t.status===`awaiting_answers`);return()=>n()?`Needs your answer`:v(t.status)})()),(0,e.insert)(c,()=>t.repository,null),(0,e.insert)(u,()=>new Date(t.createdAt).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}),d),(0,e.insert)(u,()=>t.operationId.slice(0,8),null),(0,e.effect)(n=>{var i=M()?.operationId===t.operationId,a=t.status;return i!==n.e&&(0,e.setAttribute)(r,`aria-pressed`,n.e=i),a!==n.t&&(0,e.setAttribute)(o,`data-status`,n.t=a),n},{e:void 0,t:void 0}),n})()})),t}}),null),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!c())()&&M()},children:r=>(()=>{var i=Se(),a=i.firstChild,o=a.firstChild,s=o.nextSibling;s.firstChild;var c=a.nextSibling,u=c.firstChild.nextSibling,f=u.nextSibling,m=f.firstChild;return(0,e.insert)(o,()=>v(r().phase)),(0,e.insert)(s,()=>r().repository,null),(0,e.insert)(s,(()=>{var t=(0,e.memo)(()=>!!r().plan.path);return()=>t()?` / `+r().plan.path:``})(),null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`prepared`},get children(){var i=W(),a=i.firstChild;a.firstChild;var o=a.nextSibling,s=o.firstChild.nextSibling,c=o.nextSibling,u=c.nextSibling,f=u.firstChild.nextSibling,m=f.firstChild,h=m.nextSibling;h.nextSibling;var _=f.nextSibling;_.firstChild;var v=u.nextSibling,b=v.firstChild,x=b.nextSibling;return(0,e.insert)(a,()=>t.kind===`policy`?`policy generation`:`source validation`,null),(0,e.insert)(s,()=>r().repository),(0,e.insert)(o,(0,e.createComponent)(n.Show,{get when(){return r().plan.path},get children(){return[he(),(()=>{var t=ge();return(0,e.insert)(t,()=>r().plan.path),t})()]}}),null),(0,e.insert)(o,(0,e.createComponent)(n.Show,{get when(){return r().plan.contextFiles.length},get children(){return[_e(),(()=>{var t=ge();return(0,e.insert)(t,()=>r().plan.contextFiles.map(e=>e.path).join(`, `)),t})()]}}),null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().kind===`validation`},get children(){var t=ve(),n=t.firstChild.nextSibling;return(0,e.insert)(n,()=>r().plan.finding),t}}),c),(0,e.insert)(c,(0,e.createComponent)(n.Show,{get when(){return r().plan.mock},get fallback(){return[(()=>{var t=q(),n=t.firstChild.nextSibling;return n.nextSibling,(0,e.insert)(t,()=>r().kind===`validation`?`, the finding,`:``,n),t})(),(()=>{var t=Ce(),n=t.firstChild;return(0,e.insert)(n,()=>r().plan.costNotice),t})(),(()=>{var t=we();return(0,e.insert)(t,()=>r().kind===`policy`?`A policy draft will be returned for review. No files will be applied.`:`This is static source assessment, not runtime reproduction. No patch will be applied.`),t})()]},get children(){return H()}})),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>r().kind===`validation`)()&&!r().plan.mock},get children(){var t=ye(),n=t.firstChild;return n.addEventListener(`change`,e=>te(e.currentTarget.checked)),(0,e.effect)(()=>n.checked=ee()),t}}),u),(0,e.insert)(f,()=>r().plan.settings.codex.model,m),(0,e.insert)(f,()=>r().plan.settings.codex.reasoningEffort,h),(0,e.insert)(f,()=>r().plan.settings.codex.daybreak?`on`:`off`,null),(0,e.insert)(_,()=>r().plan.globalConfigFile,null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return Date.parse(r().plan.expiresAt)<=E()},get children(){return U()}}),v),b.$$click=()=>de(r()),(0,e.insert)(b,(()=>{var t=(0,e.memo)(()=>!!w());return()=>t()?`Starting…`:r().plan.mock?`Start mock operation`:`Approve and start`})()),x.$$click=()=>{d(r().repository),p(r().plan.path??``),g(r().plan.contextFiles.map(e=>e.path).join(`
|
|
5
|
-
`)),
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require("solid-js/web"),t=require("@opencode/plugin/gui"),n=require("solid-js"),r=require("@opencode/plugin/rpc"),i=require("solid-js/store");var a={type:`object`,additionalProperties:!1},o={type:`object`,properties:{mode:{type:`string`,enum:[`standard`,`deep`],description:`Optional mode for this scan. Explicit user request wins; otherwise omit to use global mode (standard by default). Do not ask when the request is clear.`},repository:{type:`string`,description:`Optional local repository path. Defaults to the known current OpenCode workspace; use an absolute path when session context is unknown. This request only, never a global target.`},scopePaths:{type:`array`,items:{type:`string`},maxItems:32,description:`Existing paths relative to repository. Omit or use [] for whole repository. No globs or traversal.`},scanPrompt:{type:`string`,maxLength:8e3,description:`Focused security instructions and relevant architecture/threat assumptions. Ask the user for missing material context. Never copy whole conversation or include secrets.`},contextFiles:{type:`array`,items:{type:`string`},maxItems:8,description:`Repository-relative text documentation to add as supporting context. No credentials or files outside repository.`}},additionalProperties:!1},s={type:`object`,properties:{kind:{type:`string`,enum:[`policy`,`validation`]},repository:{type:`string`},path:{type:`string`},contextFiles:{type:`array`,items:{type:`string`},maxItems:8},finding:{anyOf:[{type:`string`},{type:`object`}]}},required:[`kind`],additionalProperties:!1},c={type:`object`,properties:{operationId:{type:`string`}},required:[`operationId`],additionalProperties:!1},l=r.Rpc.define({id:`gill.security`,methods:{capabilities:{input:a,output:{type:`object`}},operationPrepare:{input:s,output:{type:`object`}},operationStart:{input:{type:`object`,properties:{operationId:{type:`string`},approveOpenAIInference:{type:`boolean`},approveUncappedValidation:{type:`boolean`}},required:[`operationId`],additionalProperties:!1},output:{type:`object`}},operationStatus:{input:c,output:{type:`object`}},operationList:{input:a,output:{type:`object`}},operationAnswer:{input:{type:`object`,properties:{operationId:{type:`string`},questionId:{type:`string`},answer:{type:`string`,maxLength:16384}},required:[`operationId`,`questionId`,`answer`],additionalProperties:!1},output:{type:`object`}},operationCancel:{input:c,output:{type:`object`}},prepare:{input:o,output:{type:`object`}},start:{input:{type:`object`,properties:{planId:{type:`string`},approveOpenAIInference:{type:`boolean`}},additionalProperties:!1},output:{type:`object`}},list:{input:a,output:{type:`object`}},status:{input:{type:`object`,properties:{runId:{type:`string`},planId:{type:`string`}},additionalProperties:!1},output:{type:`object`}},cancel:{input:{type:`object`,properties:{runId:{type:`string`}},additionalProperties:!1},output:{type:`object`}}},events:{changed:{schema:{type:`object`}},operationChanged:{schema:{type:`object`}}}});function u(e){let{provider:t,auth:n,source:r,model:i}=e.codex;return`${t?`${t.id} (${t.baseUrl})`:`OpenAI`}; auth: ${n===`api-key`?`API key from environment variable ${t?.envKey??`OPENAI_API_KEY`} (name only)`:`dedicated ChatGPT sign-in`}; model: ${i}${r?`; config ${r.path}${r.profile?`, profile ${r.profile}`:``}, SHA-256 ${r.digest}`:``}${t?`; gateway upstream routing is not verified`:``}`}function d(e){return`${e.mock?`MOCK SDK TEST: no model calls or uploads.
|
|
2
|
+
`:``}Repository: ${e.repository}\nScope: ${e.scopePaths.join(`, `)||`whole repository`}\nScan prompt:\n${e.scanPrompt||`(none)`}\nContext files: ${e.contextFiles.map(e=>`${e.path} (${e.bytes} bytes, SHA-256 ${e.sha256})`).join(`; `)||`(none)`}\nSDK settings: model ${e.settings.codex.model}, reasoning ${e.settings.codex.reasoningEffort}, Daybreak ${e.settings.codex.daybreak?`on`:`off`}; mode ${e.settings.scan.mode} (${e.inputs.mode?`per-scan choice`:`global default`}), access program ${e.settings.scan.cyberAccessProgram??`Codex default`}, estimated cost stop USD ${e.settings.scan.maxCostUsd}. Account/model/Daybreak access is not verified by these settings.\nGlobal config: ${e.globalConfigFile}${e.globalConfigDigest?``:` (not present)`}\nOnly this explicit prompt and these files are added as context; conversation history is not copied. Scoped paths guide the scan, not a filesystem sandbox.\n${e.mock?`Synthetic SDK responses only.`:`Repository source and listed context go to ${u(e.settings)}. Local results. USD ${e.settings.scan.maxCostUsd} estimated stop threshold, not a hard cap; in-flight usage may exceed it.`}`}function f(e){if(e.server.id===`sidecar`&&p(e.directory)&&e.location?.directory===e.directory)return e.directory}function p(e){return!!e&&(e.startsWith(`/`)||/^[A-Za-z]:[\\/]/.test(e))}function m(e,t=Date.now(),n){let r=e=>!!e?.plan&&!e.planConsumed&&Date.parse(e.plan.expiresAt)>t;if(n)return e?.drafts.find(e=>e.plan?.id===n&&r(e));if(r(e?.preview))return e.preview}function h(e){if(!e||typeof e!=`object`||!(`status`in e)||!(`findings`in e)||!Array.isArray(e.findings))throw Error(`Invalid security state`);return e}var g=e=>e.replace(/[\\/]+$/,``).split(/[\\/]/).at(-1)||e||`Project`;function _(e){return e.plan?.scanPrompt?.split(`
|
|
3
|
+
`)[0].slice(0,72)||(e.plan?.scopePaths.length?e.plan.scopePaths.join(`, `):g(e.repository))}function v(e){return e.plan?.scopePaths.join(`, `)||`Whole repository`}function y(e){let t=e.replace(/\s*\((files|reviews)\)$/,``).replaceAll(`_`,` `),n={preflight:`Preparing scan`,discovery:`Reviewing source`,"attack path":`Reviewing attack paths`,"file review":`Reviewing source`,ranking:`Prioritizing findings`,validation:`Validating findings`,reporting:`Preparing report`};return n[t]?n[t]:t?t[0].toUpperCase()+t.slice(1):`Starting scan`}function b(e){let t=e.telemetry?.phaseProgress,n=t?t.reviews&&t.reviews.total>0?{...t.reviews,unit:`reviews`}:{...t.files,unit:`files`}:{...e.progress,unit:e.progress.unit??`files`};return{...n,done:Number.isFinite(n.done)?Math.max(0,n.done):0,total:Number.isFinite(n.total)?Math.max(0,n.total):0}}function x(e){return e.status===`running`&&e.telemetry?.lifecycle?.status===`completed`}function S(e){let t=e.telemetry?.lifecycle?.status;return e.status===`running`&&t!==void 0&&t!==`running`}function C(e){return e.status===`cancelled`?`Scan cancelled`:e.status===`error`?`Scan stopped`:e.status===`completed`?`Scan complete`:x(e)?`Finalizing results`:S(e)?e.telemetry?.lifecycle?.status===`failed`?`Finishing failed scan`:`Finishing cancelled scan`:e.deepProgress?.consolidating?`Consolidating deep review`:y(e.telemetry?.phaseProgress?.phase??e.phase)}function w(e){return e.status===`running`&&!S(e)&&!e.deepProgress?.consolidating}function ee(e){let{done:t,total:n}=b(e);return w(e)&&n>0&&t<=n}function te(e){let{done:t,total:n,unit:r}=b(e);return n>0?`${t} of ${n} ${r}`:t>0?`${t} ${r} completed`:`Waiting for progress details`}function T(e){let t=e.telemetry?.phaseProgress;return t?.reviews&&t.reviews.total>0&&t.files.total>0?`Current phase only · ${t.files.done} of ${t.files.total} files`:`Current phase only`}function ne(e){let t=e.deepProgress;return t?`${t.completed} deep ${t.completed===1?`pass`:`passes`} complete · ${t.active} active · cap ${t.maximum}`:``}function re(e){return S(e)&&!x(e)?`The SDK reported ${e.telemetry?.lifecycle?.status===`failed`?`a scan failure`:`cancellation`}. Waiting for the final result; this is not a completed assessment.`:x(e)?`Analysis complete. Waiting for the SDK’s final result and findings.`:`Findings will appear when the scan finishes.`}var E=e=>e>0&&e<.01?`<0.01`:e.toFixed(2);function D(e){let t=e.telemetry?.measurement;if(t){let e=t.cost;if(!e||!Number.isFinite(e.baselineUsd))return`Cost estimate unavailable`;let n=`USD ${E(e.baselineUsd)}`;return t.coverage===`partial`?`Partial estimate ${n}`:t.coverage===`unavailable`?`Last estimate ${n} · coverage unavailable`:`Estimated usage ${n}`}return e.estimatedCostUsd!==void 0&&Number.isFinite(e.estimatedCostUsd)?`Estimated usage USD ${E(e.estimatedCostUsd)} · coverage unknown`:`Cost estimate unavailable`}function ie(e){let t=e.telemetry?.measurement;if(!t)return`Usage coverage was not reported. Estimates are not invoices.`;let n=t.missingThreadCount;return t.coverage===`partial`?`Measured subtotal only${n?`; ${n} ${n===1?`session is`:`sessions are`} missing`:``}. The full estimate may be higher.`:t.coverage===`unavailable`?`The SDK could not establish usage coverage.`:`All reported sessions are included. This is a usage estimate, not an invoice.`}function ae(e){let t=e.telemetry?.measurement?.cost?.range;return t?t.max===null?`USD ${E(t.min)} or more; upper estimate unavailable`:`USD ${E(t.min)}–${E(t.max)}`:``}function O(e){return[...e.telemetry?.activity??[]].sort((e,t)=>t.updatedAt.localeCompare(e.updatedAt))}function k(e){let t=new Set;return O(e).filter(e=>{let n=e.worker??`coordinator`;return!t.has(n)&&(t.add(n),!0)})}function A(e){return e===void 0?`Coordinator`:`Worker ${e}`}function j(e,t){return e===`running`&&(t.status!==`running`||S(t)||t.deepProgress?.consolidating)?`Last reported running`:e===`running`?`Working`:e===`failed`?`Failed`:`Done`}function oe(e){let t=e.telemetry?.observedWorkers.length;return t?`${t} worker ${t===1?`session`:`sessions`} observed`:``}function M(e){let t=e.workers;return t?`${y(t.phase)}: ${t.started} started · ${t.planned} planned`:``}function N(e){let t=e.telemetry?.lastReconnect;if(!t)return``;let n=t.reason?` · ${t.reason.replaceAll(`_`,` `)}`:``;return`Last connection retry: ${t.attempt} of ${t.maxAttempts}${n}`}function se(e){let t=e.assessment?.returnedFindings;return t?t.total===null?`Returned finding counts unavailable`:[`${t.reportable??`Unknown`} reportable`,`${t.informational??`Unknown`} informational`,...t.unclassified?[`${t.unclassified} unclassified`]:[]].join(` · `):`${e.findings.length} ${e.findings.length===1?`finding`:`findings`} shown${e.skipped?` · ${e.skipped} other items omitted`:``}`}function ce(e){let t=e.assessment?.coverage;return!t||t.source===`unavailable`?`Coverage details unavailable`:[t.surfaces.total===null?`Surfaces unavailable`:`${t.surfaces.total} review ${t.surfaces.total===1?`surface`:`surfaces`}`,t.deferred.total===null?`Deferred work unavailable`:`${t.deferred.total} deferred`,t.openQuestions.total===null?`Open questions unavailable`:`${t.openQuestions.total} open ${t.openQuestions.total===1?`question`:`questions`}`].join(` · `)}function P(e){let t=e.assessment?.repositoryFindings;return t?.available?`${t.open??`Unknown`} open · ${t.closed??`Unknown`} closed · ${t.confirmedInLatestScan??`Unknown`} confirmed in this scan`:`Repository matching unavailable`}function le(e){let t=e.assessment?.coverage;if(!t)return[];let n=[],r=(e,t,r)=>{n.push({label:e,value:t.total===null?`Not reported`:t.total===0?`None reported`:`${t.total} reported${t.omitted?`; ${t.omitted} not shown`:``}`});for(let e of t.items)n.push({label:``,value:r(e)})};return r(`Review surfaces`,t.surfaces,e=>`${e.label??`Unnamed surface`} · ${e.disposition.replaceAll(`_`,` `)}${e.riskArea?` · ${e.riskArea}`:``}`),r(`Explicit exclusions`,t.explicitExclusions,e=>`${e.pattern??`Unspecified scope`}${e.reason?` · ${e.reason}`:``}`),r(`Deferred work`,t.deferred,e=>`${e.reason??`No reason reported`}${e.paths.items.length?` · ${e.paths.items.join(`, `)}`:``}`),r(`Resolved deferred work`,t.resolvedDeferred,e=>e.reason??`Resolution recorded`),r(`Open questions`,t.openQuestions,e=>e.question??`Question details unavailable`),r(`Included scope`,t.scopeIncludePaths,e=>e),r(`Excluded scope`,t.scopeExcludePaths,e=>e),r(`Review-excluded paths`,t.reviewExcludedPaths,e=>e),r(`Limitations`,t.limitations,e=>e),n}function ue(e,t,n=Date.now()){if(!e)return``;let r=Math.max(0,Math.floor(((t?Date.parse(t):n)-Date.parse(e))/1e3));return Number.isFinite(r)?r<60?`${r}s`:r<3600?`${Math.floor(r/60)}m ${r%60}s`:`${Math.floor(r/3600)}h ${Math.floor(r%3600/60)}m`:``}function F(e){return e.split(`
|
|
4
|
+
`).map(e=>e.trim()).filter(Boolean)}function I(e){return e&&typeof e==`object`&&`message`in e?String(e.message):String(e)}function de(e){return`${e.title}\nSeverity: ${e.severity} · ${e.cwe}\nLocation: ${e.path}:${e.line}\n\n${e.summary}\n\nEvidence:\n${e.evidence}\n\nSuggested remediation:\n${e.remediation}`}var fe=(0,e.template)(`<button class=gs-button>New `),L=(0,e.template)(`<p class="gs-notice gs-error"role=alert>`),R=(0,e.template)(`<label>Component directory <span class=gs-muted>Optional</span><input aria-label="Policy component directory"placeholder=src/api><span class=gs-help>Relative to the repository. Leave blank for the whole project.`),z=(0,e.template)(`<button class=gs-button type=button>Back`),B=(0,e.template)(`<form class=gs-form><label>Target repository<input aria-label="Operation repository"required><span class=gs-help></span></label><details><summary>Supporting documents</summary><label>Context files<textarea aria-label="Operation context files"placeholder=docs/architecture.md></textarea><span class=gs-help>One repository-relative text document per line. Do not include secrets.</span></label></details><div class=gs-actions><button class="gs-button gs-primary"type=submit></button></div><p class="gs-muted gs-small">Preparation makes no model calls.`),V=(0,e.template)(`<ul class=gs-run-list aria-label="Recent operations">`),pe=(0,e.template)(`<section><div class=gs-section-heading><h3></h3></div><p class="gs-muted gs-small">`),me=(0,e.template)(`<label>Finding to assess<textarea aria-label="Finding to assess"required maxlength=16000 placeholder="Describe the suspected issue, location, and evidence."></textarea><span class=gs-help>Use finding text or JSON. Do not include credentials.`),he=(0,e.template)(`<li><button class=gs-run-button><div class=gs-run-top><span class=gs-run-title></span><span class=gs-status></span></div><div class=gs-run-target>Target: </div><div class=gs-run-meta> · `),ge=(0,e.template)(`<dt>Component`),_e=(0,e.template)(`<dd>`),ve=(0,e.template)(`<dt>Supporting documents`),ye=(0,e.template)(`<details class=gs-advanced><summary>Finding to assess</summary><pre>`),H=(0,e.template)(`<p>Mock operation only. No model calls or source uploads.`),be=(0,e.template)(`<label class=gs-check><input type=checkbox> I approve validation without a cost ceiling.`),U=(0,e.template)(`<p class=gs-error>This preview expired. Prepare a new one before starting.`),W=(0,e.template)(`<div class=gs-review><h3>Review </h3><dl><dt>Repository</dt><dd></dd></dl><div class=gs-approval></div><details class=gs-advanced><summary>Model settings</summary><p> · <!> reasoning · Daybreak </p><p class=gs-muted>Account and model access are not verified. </p></details><div class=gs-actions><button class="gs-button gs-primary"></button><button class=gs-button>Edit request`),G=(0,e.template)(`<span>Estimated usage USD `),xe=(0,e.template)(`<div class=gs-facts><span>`),K=(0,e.template)(`<button class=gs-button>Cancel this operation`),Se=(0,e.template)(`<p class=gs-notice>Cancelled. No completed assessment is available.`),Ce=(0,e.template)(`<article class=gs-detail aria-label="Selected operation"><div class=gs-detail-title><h3></h3><p>Target: </p></div><details class=gs-advanced><summary>Operation details</summary><p class=gs-id></p><p class=gs-muted> questions answered. Operation history is kept for this server session.`),q=(0,e.template)(`<p>Repository source<!> and selected context will be sent to <!>.`),we=(0,e.template)(`<p><strong>`),Te=(0,e.template)(`<p>`),Ee=(0,e.template)(`<form class="gs-form gs-questions"><h3>Your input is needed</h3><ol></ol><label>Your answer<textarea aria-label="Answer security questions"maxlength=8000 required></textarea><span class=gs-help>Answer each question, or say what is unknown. Your answer goes to the already-approved route: <!>. Do not include secrets.</span></label><button class="gs-button gs-primary"type=submit>Send answer and continue`),J=(0,e.template)(`<li>`),De=(0,e.template)(`<p class="gs-muted gs-small">Draft only. Review it before applying. No repository files were changed.`),Oe=(0,e.template)(`<p class=gs-notice>This preview is truncated. Read the full local SDK artifact before relying on it.`),ke=(0,e.template)(`<section class=gs-operation-result><h3></h3><pre>`),Ae=(0,e.template)(`<p><strong></strong> · Static review, not runtime reproduction.`),je=(0,e.template)(`<p class="gs-muted gs-small">`);function Me(t){let[r,a]=(0,i.createStore)({operations:[]}),[o,s]=(0,n.createSignal)(),[c,l]=(0,n.createSignal)(!0),[d,f]=(0,n.createSignal)(t.seed?.repository??t.directory),[p,m]=(0,n.createSignal)(``),[h,_]=(0,n.createSignal)(``),[v,b]=(0,n.createSignal)(t.seed?.finding??``),[x,S]=(0,n.createSignal)(!!t.seed),[C,w]=(0,n.createSignal)(``),[ee,te]=(0,n.createSignal)(!1),[T,ne]=(0,n.createSignal)(!1),[re,E]=(0,n.createSignal)(``),[D,ie]=(0,n.createSignal)(Date.now()),[ae,O]=(0,n.createSignal)(!1),k=!1,A=!1,j=0,oe=e=>{j++,f(e?.repository??t.directory),S(!!e),b(e?.finding??``),m(``),_(``),w(``),te(!1),E(``),s(void 0),l(!0)};(0,n.createEffect)((0,n.on)(()=>[t.kind,t.directory,t.seed],()=>oe(t.seed),{defer:!0}));let M=(0,n.createMemo)(()=>r.operations.filter(e=>e.kind===t.kind)),N=(0,n.createMemo)(()=>M().find(e=>e.operationId===o())??M().find(e=>e.status===`awaiting_answers`)??M()[0]),se=()=>t.kind===`policy`?`Policy draft`:`Finding validation`;(0,n.createEffect)(()=>{N()?.question?.id,w(``)}),(0,n.createEffect)(()=>{N()?.operationId,te(!1)});let ce=async()=>{if(!(k||A)){A=!0;try{let e=await t.port.list(),n=Array.isArray(e)?e:e?.operations;if(!Array.isArray(n))throw Error(`Could not read security operations.`);k||(a(`operations`,(0,i.reconcile)(n,{key:`operationId`,merge:!0})),ae()||(O(!0),!t.seed&&n.some(e=>e.kind===t.kind)&&l(!1)))}catch(e){k||E(I(e))}finally{A=!1}}},P=async e=>{if(!(T()||k)){ne(!0),E(``);try{await e(),k||await ce()}catch(e){k||E(I(e))}finally{k||ne(!1)}}},le=e=>{e.preventDefault();let n=j;P(async()=>{let e=await t.port.prepare({kind:t.kind,repository:d().trim()||t.directory,contextFiles:F(h()),...t.kind===`policy`?p().trim()?{path:p().trim()}:{}:{finding:v()}});!k&&n===j&&(s(e.operationId),a(`operations`,(0,i.reconcile)([e,...r.operations.filter(t=>t.operationId!==e.operationId)],{key:`operationId`,merge:!0})),l(!1))})},de=e=>void P(()=>t.port.start({operationId:e.operationId,approveOpenAIInference:!0,...e.kind===`validation`?{approveUncappedValidation:!0}:{}}));ce();let Me=setInterval(()=>{ie(Date.now()),ce()},1500);return(0,n.onCleanup)(()=>{k=!0,clearInterval(Me)}),(()=>{var r=pe(),i=r.firstChild,a=i.firstChild,o=i.nextSibling;return(0,e.insert)(a,se),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return!c()},get children(){var n=fe();return n.firstChild,n.$$click=()=>oe(),(0,e.insert)(n,()=>t.kind===`policy`?`draft`:`validation`,null),(0,e.effect)(()=>n.disabled=T()),n}}),null),(0,e.insert)(o,()=>t.kind===`policy`?`Build security guidance from the repository, with questions when context is missing. Draft only: existing files stay unchanged.`:`Assess a finding against the source. This does not run an exploit or prove runtime reproduction.`),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return re()},get children(){var t=L();return(0,e.insert)(t,re),t}}),null),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return c()},get children(){var r=B(),i=r.firstChild,a=i.firstChild.nextSibling,o=a.nextSibling,s=i.nextSibling,c=s.firstChild.nextSibling.firstChild.nextSibling,u=s.nextSibling,g=u.firstChild;return r.addEventListener(`submit`,le),a.$$input=e=>{f(e.currentTarget.value),m(``),_(``),b(``),S(!1)},(0,e.insert)(o,()=>x()?`Starts from the selected finding’s repository. Check the target before review.`:`Defaults to this workspace. Changing it affects only this operation.`),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return t.kind===`policy`},get fallback(){return(()=>{var t=me(),n=t.firstChild.nextSibling;return n.$$input=e=>b(e.currentTarget.value),(0,e.effect)(()=>n.disabled=T()),(0,e.effect)(()=>n.value=v()),t})()},get children(){var t=R(),n=t.firstChild.nextSibling.nextSibling;return n.$$input=e=>m(e.currentTarget.value),(0,e.effect)(()=>n.disabled=T()),(0,e.effect)(()=>n.value=p()),t}}),s),c.$$input=e=>_(e.currentTarget.value),(0,e.insert)(g,(()=>{var n=(0,e.memo)(()=>!!T());return()=>n()?`Preparing…`:`Review `+(t.kind===`policy`?`policy draft`:`validation`)})()),(0,e.insert)(u,(0,e.createComponent)(n.Show,{get when(){return M().length},get children(){var t=z();return t.$$click=()=>l(!1),(0,e.effect)(()=>t.disabled=T()),t}}),null),(0,e.effect)(e=>{var t=T(),n=T(),r=T();return t!==e.e&&(a.disabled=e.e=t),n!==e.t&&(c.disabled=e.t=n),r!==e.a&&(g.disabled=e.a=r),e},{e:void 0,t:void 0,a:void 0}),(0,e.effect)(()=>a.value=d()),(0,e.effect)(()=>c.value=h()),r}}),null),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return M().length>1},get children(){var t=V();return(0,e.insert)(t,(0,e.createComponent)(n.For,{get each(){return M()},children:t=>(()=>{var n=he(),r=n.firstChild,i=r.firstChild,a=i.firstChild,o=a.nextSibling,c=i.nextSibling;c.firstChild;var u=c.nextSibling,d=u.firstChild;return r.$$click=()=>{s(t.operationId),l(!1)},(0,e.insert)(a,()=>g(t.repository),null),(0,e.insert)(a,(()=>{var n=(0,e.memo)(()=>!!t.plan.path);return()=>n()?` / `+t.plan.path:``})(),null),(0,e.insert)(o,(()=>{var n=(0,e.memo)(()=>t.status===`awaiting_answers`);return()=>n()?`Needs your answer`:y(t.status)})()),(0,e.insert)(c,()=>t.repository,null),(0,e.insert)(u,()=>new Date(t.createdAt).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}),d),(0,e.insert)(u,()=>t.operationId.slice(0,8),null),(0,e.effect)(n=>{var i=N()?.operationId===t.operationId,a=t.status;return i!==n.e&&(0,e.setAttribute)(r,`aria-pressed`,n.e=i),a!==n.t&&(0,e.setAttribute)(o,`data-status`,n.t=a),n},{e:void 0,t:void 0}),n})()})),t}}),null),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!c())()&&N()},children:r=>(()=>{var i=Ce(),a=i.firstChild,o=a.firstChild,s=o.nextSibling;s.firstChild;var c=a.nextSibling,d=c.firstChild.nextSibling,p=d.nextSibling,h=p.firstChild;return(0,e.insert)(o,()=>y(r().phase)),(0,e.insert)(s,()=>r().repository,null),(0,e.insert)(s,(()=>{var t=(0,e.memo)(()=>!!r().plan.path);return()=>t()?` / `+r().plan.path:``})(),null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`prepared`},get children(){var i=W(),a=i.firstChild;a.firstChild;var o=a.nextSibling,s=o.firstChild.nextSibling,c=o.nextSibling,d=c.nextSibling,p=d.firstChild.nextSibling,h=p.firstChild,g=h.nextSibling;g.nextSibling;var v=p.nextSibling;v.firstChild;var y=d.nextSibling,x=y.firstChild,S=x.nextSibling;return(0,e.insert)(a,()=>t.kind===`policy`?`policy generation`:`source validation`,null),(0,e.insert)(s,()=>r().repository),(0,e.insert)(o,(0,e.createComponent)(n.Show,{get when(){return r().plan.path},get children(){return[ge(),(()=>{var t=_e();return(0,e.insert)(t,()=>r().plan.path),t})()]}}),null),(0,e.insert)(o,(0,e.createComponent)(n.Show,{get when(){return r().plan.contextFiles.length},get children(){return[ve(),(()=>{var t=_e();return(0,e.insert)(t,()=>r().plan.contextFiles.map(e=>e.path).join(`, `)),t})()]}}),null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().kind===`validation`},get children(){var t=ye(),n=t.firstChild.nextSibling;return(0,e.insert)(n,()=>r().plan.finding),t}}),c),(0,e.insert)(c,(0,e.createComponent)(n.Show,{get when(){return r().plan.mock},get fallback(){return[(()=>{var t=q(),n=t.firstChild.nextSibling,i=n.nextSibling.nextSibling;return i.nextSibling,(0,e.insert)(t,()=>r().kind===`validation`?`, the finding,`:``,n),(0,e.insert)(t,()=>u(r().plan.settings),i),t})(),(()=>{var t=we(),n=t.firstChild;return(0,e.insert)(n,()=>r().plan.costNotice),t})(),(()=>{var t=Te();return(0,e.insert)(t,()=>r().kind===`policy`?`A policy draft will be returned for review. No files will be applied.`:`This is static source assessment, not runtime reproduction. No patch will be applied.`),t})()]},get children(){return H()}})),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>r().kind===`validation`)()&&!r().plan.mock},get children(){var t=be(),n=t.firstChild;return n.addEventListener(`change`,e=>te(e.currentTarget.checked)),(0,e.effect)(()=>n.checked=ee()),t}}),d),(0,e.insert)(p,()=>r().plan.settings.codex.model,h),(0,e.insert)(p,()=>r().plan.settings.codex.reasoningEffort,g),(0,e.insert)(p,()=>r().plan.settings.codex.daybreak?`on`:`off`,null),(0,e.insert)(v,()=>r().plan.globalConfigFile,null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return Date.parse(r().plan.expiresAt)<=D()},get children(){return U()}}),y),x.$$click=()=>de(r()),(0,e.insert)(x,(()=>{var t=(0,e.memo)(()=>!!T());return()=>t()?`Starting…`:r().plan.mock?`Start mock operation`:`Approve and start`})()),S.$$click=()=>{f(r().repository),m(r().plan.path??``),_(r().plan.contextFiles.map(e=>e.path).join(`
|
|
5
|
+
`)),b(r().plan.finding??``),l(!0)},(0,e.effect)(e=>{var t=T()||Date.parse(r().plan.expiresAt)<=D()||r().kind===`validation`&&!r().plan.mock&&!ee(),n=T();return t!==e.e&&(x.disabled=e.e=t),n!==e.t&&(S.disabled=e.t=n),e},{e:void 0,t:void 0}),i}}),c),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`running`||r().status===`awaiting_answers`},get children(){var t=xe(),i=t.firstChild;return(0,e.insert)(i,()=>ue(r().startedAt,null,D())),(0,e.insert)(t,(0,e.createComponent)(n.Show,{get when(){return r().estimatedCostUsd!==void 0},get children(){var t=G();return t.firstChild,(0,e.insert)(t,()=>(r().estimatedCostUsd??0).toFixed(2),null),t}}),null),t}}),c),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().question},children:i=>(()=>{var a=Ee(),o=a.firstChild.nextSibling,s=o.nextSibling,c=s.firstChild.nextSibling,l=c.nextSibling,d=l.firstChild.nextSibling;d.nextSibling;var f=s.nextSibling;return a.addEventListener(`submit`,e=>{e.preventDefault();let n=i();P(()=>t.port.answer({operationId:r().operationId,questionId:n.id,answer:C()}))}),(0,e.insert)(o,(0,e.createComponent)(n.For,{get each(){return i().questions},children:t=>(()=>{var n=J();return(0,e.insert)(n,t),n})()})),c.$$input=e=>w(e.currentTarget.value),(0,e.insert)(l,()=>u(r().plan.settings),d),(0,e.effect)(e=>{var t=T(),n=T()||!C().trim();return t!==e.e&&(c.disabled=e.e=t),n!==e.t&&(f.disabled=e.t=n),e},{e:void 0,t:void 0}),(0,e.effect)(()=>c.value=C()),a})()}),c),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`running`||r().status===`awaiting_answers`},get children(){var n=K();return n.$$click=()=>void P(()=>t.port.cancel({operationId:r().operationId})),(0,e.effect)(()=>n.disabled=T()),n}}),c),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().error},get children(){var t=L();return(0,e.insert)(t,()=>r().error),t}}),c),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`cancelled`},get children(){return Se()}}),c),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().result},children:t=>(()=>{var r=ke(),i=r.firstChild,a=i.nextSibling;return(0,e.insert)(i,()=>t().kind===`policy`?`Policy draft`:`Source assessment`),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return t().kind===`policy`},get fallback(){return(()=>{var n=Ae(),r=n.firstChild;return(0,e.insert)(r,()=>y(t().disposition)),n})()},get children(){return De()}}),a),(0,e.insert)(a,(()=>{var n=(0,e.memo)(()=>t().kind===`policy`);return()=>n()?t().content:t().report})()),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return t().kind===`policy`},get children(){return(0,e.createComponent)(n.For,{get each(){return t().reviewNotes},children:t=>(()=>{var n=je();return(0,e.insert)(n,t),n})()})}}),null),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return t().truncated},get children(){return Oe()}}),null),r})()}),c),(0,e.insert)(d,()=>r().operationId),(0,e.insert)(p,()=>r().answeredQuestionCount,h),i})()}),null),(0,e.effect)(()=>(0,e.setAttribute)(r,`aria-label`,se())),r})()}(0,e.delegateEvents)([`click`,`input`]);var Ne=`
|
|
6
6
|
.gill-security{--gs-bg:var(--background-base,#151515);--gs-panel:var(--background-raised,#202020);--gs-fg:var(--text-base,#eee);--gs-muted:var(--text-weak,#b5b5b5);--gs-line:var(--border-base,#454545);--gs-accent:#9be4c6;--gs-on-accent:#142b21;color:var(--gs-fg);background:var(--gs-bg);font-size:13px;line-height:1.5;font-family:inherit;height:100%;overflow:auto;container-type:inline-size;scrollbar-color:var(--gs-line) transparent;scrollbar-width:thin}
|
|
7
7
|
.gill-security *{box-sizing:border-box}.gill-security ::selection{background:#35634f;color:#fff}.gill-security button,.gill-security input,.gill-security textarea,.gill-security select{font:inherit;color:inherit}.gill-security button{cursor:pointer}.gill-security button:disabled{opacity:.45;cursor:not-allowed}.gill-security :focus-visible{outline:2px solid var(--gs-accent);outline-offset:3px}.gill-security input,.gill-security textarea{caret-color:var(--gs-accent)}
|
|
8
8
|
.gs-workspace{font-size:12px;color:var(--gs-muted);margin:0 0 20px}.gs-workspace>summary{cursor:pointer}.gs-workspace p{margin:8px 0;overflow-wrap:anywhere}.gs-run-target{font-size:12px;color:var(--gs-muted);margin-top:4px;overflow-wrap:anywhere}.gs-body{padding:24px;max-width:900px;margin:auto}.gs-header{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:24px}.gs-header h2{font-size:20px;font-weight:600;margin:0;letter-spacing:-.025em}.gs-muted{color:var(--gs-muted)}.gs-small{font-size:12px}.gs-header p{margin:3px 0 0;font-size:12px}.gs-button{padding:8px 13px;border:1px solid var(--gs-line);border-radius:6px;background:transparent;line-height:1.4;white-space:nowrap}.gs-button:hover:not(:disabled){background:var(--gs-panel)}.gs-button.gs-primary{background:var(--gs-accent);border-color:transparent;color:var(--gs-on-accent);font-weight:600}.gs-button.gs-primary:hover:not(:disabled){filter:brightness(1.08)}.gs-link{border:0;background:none;padding:4px 0;color:var(--gs-muted)!important;text-decoration:underline;text-underline-offset:3px}.gs-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:16px}.gs-notice{padding:10px 12px;border:1px solid var(--gs-line);border-radius:6px;font-size:12px;margin-bottom:18px}.gs-error{color:#ffb3b3;border-color:#985353;overflow-wrap:anywhere}.gs-form{padding-bottom:24px;margin-bottom:24px;border-bottom:1px solid var(--gs-line)}.gs-form h3,.gs-detail h3{font-size:15px;font-weight:600;margin:0 0 12px}.gs-form label{display:block;font-size:12px;font-weight:500;margin-bottom:14px}.gs-form input,.gs-form textarea,.gs-form select{display:block;width:100%;margin-top:6px;background:var(--gs-panel);border:1px solid var(--gs-line);padding:9px 10px;border-radius:5px;line-height:1.5}.gs-form textarea{resize:vertical;min-height:68px}.gs-form input::placeholder,.gs-form textarea::placeholder{color:var(--gs-muted)}.gs-form .gs-help{display:block;font-weight:400;color:var(--gs-muted);font-size:12px;margin-top:5px}.gs-row{display:flex;align-items:flex-start;gap:12px}.gs-row>*{flex:1;min-width:0}.gs-form details{margin:16px 0}.gs-form summary,.gs-detail summary{cursor:pointer;color:var(--gs-muted);padding:4px 0}.gs-form details[open]>summary,.gs-detail details[open]>summary{margin-bottom:12px}.gs-review{border:1px solid var(--gs-line);padding:16px;border-radius:8px}.gs-review dl,.gs-details-list{margin:0}.gs-review dt,.gs-details-list dt{color:var(--gs-muted);font-size:12px;margin-top:12px}.gs-review dt:first-child,.gs-details-list dt:first-child{margin-top:0}.gs-review dd,.gs-details-list dd{margin:3px 0 0;overflow-wrap:anywhere}.gs-review p{margin:12px 0 0}.gs-review .gs-approval{border-top:1px solid var(--gs-line);padding-top:12px;margin-top:16px;font-size:12px;color:var(--gs-muted)}.gs-section-heading{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px}.gs-section-heading h3{font-size:13px;margin:0;font-weight:600}.gs-section-heading span{color:var(--gs-muted);font-size:12px}.gs-runs{margin-bottom:28px;font-size:12px}.gs-runs>summary{cursor:pointer;color:var(--gs-muted);padding:0 0 12px;border-bottom:1px solid var(--gs-line)}.gs-runs>summary span{float:right}.gs-runs[open]>summary{margin-bottom:8px}.gs-run-list{list-style:none;padding:0;margin:0;max-height:240px;overflow:auto;scrollbar-width:thin}.gs-run-list li{border-bottom:1px solid var(--gs-line)}.gs-run-button{display:block;background:none;border:0;border-radius:4px;text-align:left;padding:12px 10px;width:100%;color:inherit}.gs-run-button:hover{background:var(--gs-panel)}.gs-run-button[aria-pressed=true]{background:var(--gs-panel);box-shadow:inset 2px 0 var(--gs-accent)}.gs-run-top{display:flex;justify-content:space-between;align-items:baseline;gap:12px}.gs-run-title{font-size:13px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.gs-run-meta{font-size:12px;color:var(--gs-muted);margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gs-status{font-size:11px;white-space:nowrap;flex-shrink:0;color:var(--gs-muted);text-transform:capitalize}.gs-status[data-status=running]{color:var(--gs-accent)}.gs-status[data-status=error]{color:#ffb3b3}.gs-detail{padding-top:0}.gs-detail-title{margin-bottom:24px}.gs-detail-title h3{margin:0;font-size:14px;line-height:1.5;font-weight:500;overflow-wrap:anywhere}.gs-detail-title p{margin:4px 0 0;overflow-wrap:anywhere;font-size:12px;color:var(--gs-muted)}.gs-progress-heading{display:flex;justify-content:space-between;align-items:baseline;gap:16px;margin:0 0 12px}.gs-progress-heading h3{font-size:24px;line-height:1.25;font-weight:600;letter-spacing:-.025em;margin:0}.gs-progress-heading span{font-size:12px;color:var(--gs-muted);font-variant-numeric:tabular-nums}.gs-progress{appearance:none;width:100%;height:6px;border:0;display:block;margin:16px 0 10px;background:var(--gs-line);border-radius:2px;overflow:hidden}.gs-progress::-webkit-progress-bar{background:var(--gs-line)}.gs-progress::-webkit-progress-value{background:var(--gs-accent)}.gs-progress::-moz-progress-bar{background:var(--gs-accent)}.gs-progress-meta{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;color:var(--gs-muted);font-size:12px}.gs-live-note{margin:24px 0;max-width:64ch;font-size:13px}.gs-scan-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:16px;font-variant-numeric:tabular-nums}.gs-activity{margin:0;font-size:12px}.gs-activity-list{padding:0;margin:8px 0 0;list-style:none;max-height:220px;overflow:auto;scrollbar-width:thin}.gs-activity-list li{display:flex;gap:12px;align-items:baseline;padding:6px 0;font-size:12px;overflow-wrap:anywhere}.gs-activity-list time{color:var(--gs-muted);font-variant-numeric:tabular-nums;white-space:nowrap;flex-shrink:0}.gs-activity-list li:first-child{color:var(--gs-fg)}.gs-findings{margin:28px 0 24px}.gs-findings .gs-section-heading h3{font-size:18px}.gs-findings details{padding:12px 0;border-bottom:1px solid var(--gs-line)}.gs-findings summary{color:var(--gs-fg);padding:0}.gs-severity{font-size:11px;text-transform:uppercase;margin-right:8px;color:#ebc28c}.gs-severity[data-severity=critical],.gs-severity[data-severity=high]{color:#ffb3b3}.gs-findings p{font-size:13px;margin:12px 0}.gs-findings pre{font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap;overflow-wrap:anywhere;padding:12px;background:var(--gs-panel);border-radius:5px;max-height:280px;overflow:auto}.gs-finding-location{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;color:var(--gs-muted);overflow-wrap:anywhere;margin:6px 0}.gs-empty{padding:22px 0;color:var(--gs-muted);font-size:13px}.gs-empty h3{color:var(--gs-fg);margin:0 0 6px;font-size:15px}.gs-empty p{margin:0;max-width:48ch}.gs-footer{font-size:11px;color:var(--gs-muted);margin-top:24px}.gs-advanced{margin-top:0;font-size:12px}.gs-detail>.gs-advanced,.gs-detail>.gs-activity,.gs-coverage{border-top:1px solid var(--gs-line)}.gs-detail>.gs-advanced>summary,.gs-detail>.gs-activity>summary,.gs-coverage>summary{padding:14px 0;color:var(--gs-fg)}.gs-detail>.gs-advanced[open],.gs-detail>.gs-activity[open],.gs-coverage[open]{padding-bottom:16px}.gs-advanced pre{white-space:pre-wrap;overflow-wrap:anywhere;font:11px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace}.gs-pending{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 0;margin-bottom:16px;border-bottom:1px solid var(--gs-line);font-size:12px}.gs-workers{font-size:12px;color:var(--gs-muted);padding:0;list-style:none}.gs-workers li{padding:3px 0}.gs-id{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;overflow-wrap:anywhere}
|
|
@@ -10,8 +10,8 @@ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{val
|
|
|
10
10
|
.gs-worker-activity{list-style:none;padding:0;margin:8px 0}.gs-worker-activity li{display:flex;justify-content:space-between;align-items:baseline;gap:16px;padding:9px 0;border-bottom:1px solid var(--gs-line);font-size:12px}.gs-activity-copy{display:flex;gap:12px;min-width:0;overflow-wrap:anywhere}.gs-activity-actor{color:var(--gs-muted);flex-shrink:0;min-width:78px}.gs-activity-state{color:var(--gs-muted);font-size:11px;text-align:right;flex-shrink:0}.gs-activity-state[data-status=failed]{color:#ffb3b3}.gs-activity-history{margin-top:12px;font-size:12px}.gs-activity-paths{display:block;color:var(--gs-muted);font-size:11px;overflow-wrap:anywhere}.gs-outcome{margin-top:24px}.gs-outcome-summary{font-size:12px;color:var(--gs-muted);margin:0 0 16px}.gs-coverage{font-size:12px;margin:0}.gs-coverage ul{padding-left:18px;margin:8px 0}.gs-coverage li{margin:5px 0}
|
|
11
11
|
@container(max-width:440px){.gs-body{padding:18px 16px}.gs-row{display:block}.gs-run-top{gap:8px}.gs-header{gap:10px}.gs-header h2{font-size:18px}.gs-run-title{max-width:65%}.gs-activity-copy{flex-direction:column;gap:2px}.gs-worker-activity li{gap:8px}.gs-activity-state{max-width:110px}.gs-progress-heading{align-items:flex-start}.gs-progress-heading h3{font-size:22px}.gs-progress-heading span{white-space:nowrap}}
|
|
12
12
|
@media(prefers-reduced-motion:no-preference){.gs-detail{animation:gs-appear .15s ease-out}@keyframes gs-appear{from{opacity:.85}to{opacity:1}}}
|
|
13
|
-
`,
|
|
13
|
+
`,Pe=(0,e.template)(`<button class="gs-button gs-primary">New scan`),Fe=(0,e.template)(`<button>Policy`),Ie=(0,e.template)(`<button>Validate`),Le=(0,e.template)(`<nav class=gs-tabs aria-label="Security actions"><button>Scans`),Re=(0,e.template)(`<div class=gs-pending><span>A policy draft needs your input.</span><button class=gs-button>Answer questions`),ze=(0,e.template)(`<div class="gs-notice gs-error"role=alert> <button class=gs-link>Retry connection`),Be=(0,e.template)(`<p class="gs-notice gs-error"role=alert>`),Ve=(0,e.template)(`<button class=gs-link>Close`),He=(0,e.template)(`<section class=gs-form aria-label="New scan"><div class=gs-section-heading><h3>New scan`),Ue=(0,e.template)(`<details class=gs-runs aria-label="Scan history"><summary>Switch scan <span> recent</span></summary><p class=gs-muted>Runs recorded in this workspace. Each target is shown below.</p><ul class=gs-run-list>`),We=(0,e.template)(`<section class=gill-security aria-label="Security scans"><style></style><div class=gs-body><header class=gs-header><div><h2>Security</h2><p class=gs-muted>Workspace · </p></div></header><details class=gs-workspace><summary>Workspace and history</summary><p class=gs-id></p><p>History belongs to this workspace, including runs with a different target.</p><p>Global settings share model and scan defaults, not a scan target or combined history.</p></details><footer class=gs-footer>`),Ge=(0,e.template)(`<div class=gs-pending><span>Prepared target: </span><button class=gs-button>Review draft`),Ke=(0,e.template)(`<p class="gs-muted gs-small">Synthetic fixture test. Local pattern matching only, with no source upload or model calls.`),qe=(0,e.template)(`<button class="gs-button gs-primary">Scan fixture`),Je=(0,e.template)(`<button type=button class=gs-link>Review prepared scan · `),Ye=(0,e.template)(`<form><label>Target repository<input required aria-label=Repository><span class=gs-help>Defaults to this workspace. Changing the target clears scope and context files.</span></label><label>Scan depth<select aria-label="Scan depth"><option value=default>Use global default</option><option value=standard>Standard</option><option value=deep>Deep</option></select><span class=gs-help>Deep can take longer and cost more. This choice applies only to this scan.</span></label><label>What should this scan focus on? <span class=gs-muted>Optional</span><textarea maxlength=8000 placeholder="For example, review authorization and tenant isolation."aria-label="Scan focus"></textarea></label><details><summary>Scope and supporting documents</summary><label>Paths to review<textarea placeholder="src/auth
|
|
14
14
|
src/api"aria-label="Scope paths"></textarea><span class=gs-help>One repository-relative path per line. Leave blank for the whole repository.</span></label><label>Context files<textarea placeholder="docs/architecture.md
|
|
15
|
-
SECURITY.md"aria-label="Context files"></textarea><span class=gs-help>Optional text documents within this repository. Do not include secrets.</span></label></details><div class=gs-actions><button type=submit class="gs-button gs-primary"></button><span class="gs-muted gs-small">
|
|
15
|
+
SECURITY.md"aria-label="Context files"></textarea><span class=gs-help>Optional text documents within this repository. Do not include secrets.</span></label></details><div class=gs-actions><button type=submit class="gs-button gs-primary"></button><span class="gs-muted gs-small">No source has been sent yet.`),Xe=(0,e.template)(`<dt>Focus`),Y=(0,e.template)(`<dd>`),Ze=(0,e.template)(`<dt>Supporting documents`),Qe=(0,e.template)(`<p>Mock SDK test. Synthetic responses only; no model calls or source uploads.`),$e=(0,e.template)(`<p role=status class="gs-small gs-muted"> scans are already running. Start this scan after one finishes.`),et=(0,e.template)(`<p class="gs-small gs-error">This preview has expired. Edit and review it again.`),tt=(0,e.template)(`<div class=gs-review><h3>Review this scan</h3><dl><dt>Repository</dt><dd></dd><dt>Scope</dt><dd></dd><dt>Depth</dt><dd></dd></dl><details class=gs-advanced><summary>Model and advanced settings</summary><dl class=gs-details-list><dt>Model</dt><dd> · <!> reasoning</dd><dt>Daybreak</dt><dd></dd><dt>Global configuration</dt><dd></dd><dt>Settings scope</dt><dd>Shared defaults only. This target and history belong to this workspace.</dd></dl><p class=gs-muted>Model and account access have not been verified.</p><details><summary>Full approval details</summary><pre></pre></details></details><div class=gs-approval></div><div class=gs-actions><button class="gs-button gs-primary"></button><button class=gs-button>Edit scan`),nt=(0,e.template)(`<p>Repository source and listed context will be sent to<!>. Results are stored locally.`),rt=(0,e.template)(`<p>Estimated cost stop: <strong>USD </strong> for this scan. This is not a hard cap; in-flight usage may exceed it.`),it=(0,e.template)(`<p>Only the focus and documents above are added as context, not your conversation. Scope guides the review; it is not a filesystem sandbox.`),at=(0,e.template)(`<div class=gs-empty><h3>No scans yet</h3><p>Start a scan to review findings and follow its activity here.`),ot=(0,e.template)(`<li><button class=gs-run-button><div class=gs-run-top><span class=gs-run-title></span><span class=gs-status></span></div><div class=gs-run-target>Target: </div><div class=gs-run-meta> · <!> · `),st=(0,e.template)(`<progress class=gs-progress>`),ct=(0,e.template)(`<div class=gs-progress-meta><span></span><span>`),lt=(0,e.template)(`<button class=gs-link>`),ut=(0,e.template)(`<p class=gs-live-note>`),dt=(0,e.template)(`<p class=gs-notice>Cancelled. This scan is incomplete and is not a clean result.`),ft=(0,e.template)(`<div class=gs-empty><h3>No reportable findings shown</h3><p>No findings does not guarantee security. Check coverage below.`),pt=(0,e.template)(`<section class=gs-findings aria-label="Scan findings"><div class=gs-section-heading><h3>Findings</h3><span> to review`),mt=(0,e.template)(`<dd class=gs-muted> records have matching finding IDs. <!> were not confirmed in this scan. These are repository records, not additional findings or deduplication progress.`),ht=(0,e.template)(`<p class=gs-muted>Informational and unclassified items are not shown in the four-severity findings list. Review the full local SDK result for those items.`),gt=(0,e.template)(`<section class=gs-outcome aria-label="Scan outcome"><p class=gs-outcome-summary></p><details class=gs-coverage><summary>Coverage and repository matching</summary><p></p><p class=gs-muted>Reported metadata, not proof of exhaustive review.</p><dl class=gs-details-list><dt>Repository matching</dt><dd>`),_t=(0,e.template)(`<p class="gs-muted gs-small">`),vt=(0,e.template)(`<ul class=gs-worker-activity>`),yt=(0,e.template)(`<p class="gs-muted gs-small">Scan milestones · latest first`),bt=(0,e.template)(`<ol class=gs-activity-list>`),xt=(0,e.template)(`<details class=gs-activity-history><summary>Activity history</summary><ol class=gs-activity-list>`),St=(0,e.template)(`<dt>Estimated range`),Ct=(0,e.template)(`<dt>Pricing model`),wt=(0,e.template)(`<dt>Pricing as of`),Tt=(0,e.template)(`<dt>Deep review`),Et=(0,e.template)(`<dd class=gs-muted>The cap is a maximum, not a target or completion percentage.`),Dt=(0,e.template)(`<dt>Connection`),Ot=(0,e.template)(`<dt>SDK scan ID`),kt=(0,e.template)(`<dd class=gs-id>`),At=(0,e.template)(`<dt>Model`),jt=(0,e.template)(`<p class=gs-muted>Restored from local history.`),Mt=(0,e.template)(`<article class=gs-detail aria-label="Selected scan"><div class=gs-detail-title><h3></h3><p>Target: </p><p> · </p></div><div class=gs-progress-heading role=status aria-live=polite><h3></h3><span></span></div><div class=gs-scan-actions><span class="gs-muted gs-small"></span></div><details class=gs-activity aria-label="Scan activity"><summary>Activity and workers</summary></details><details class=gs-advanced><summary>Usage and scan details</summary><dl class=gs-details-list><dt>Usage estimate</dt><dd></dd><dd class=gs-muted></dd><dt>Repository</dt><dd></dd><dt>Run ID</dt><dd class=gs-id></dd><dt>Scope</dt><dd></dd><dt>Depth</dt><dd>`),Nt=(0,e.template)(`<pre>`),Pt=(0,e.template)(`<button class=gs-button>Validate this finding`),Ft=(0,e.template)(`<details><summary><span class=gs-severity></span> </summary><div class=gs-finding-location>:<!> · </div><p></p><strong class=gs-small>Suggested next step</strong><p></p><p class="gs-muted gs-small">Confidence: <!>. Review the evidence before making changes.`),It=(0,e.template)(`<dt>`),Lt=(0,e.template)(`<p class=gs-muted>`),Rt=(0,e.template)(`<li><div class=gs-activity-copy><span class=gs-activity-actor></span><span></span></div><span class=gs-activity-state>`),zt=(0,e.template)(`<span class=gs-activity-paths>`),Bt=(0,e.template)(`<li><time></time><span> · <!> · `),Vt=(0,e.template)(`<li><time></time><span>`),Ht=(0,e.template)(`<dt>Reported tokens`),Ut=(0,e.template)(`<dd> input · <!> cached input · <!> output`);function Wt(e){if(!e||typeof e!=`object`||!(`runs`in e)||!Array.isArray(e.runs))throw Error(`Could not read scan history. Reopen Security after updating the server plugin.`);let t=e;return{...t,runs:t.runs.map(h),drafts:(t.drafts??[]).map(h),maxConcurrent:t.maxConcurrent??2}}var Gt=e=>new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`,second:`2-digit`}),Kt=e=>e?new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):``;function X(t){let[r,a]=(0,i.createStore)({runs:[],drafts:[],maxConcurrent:2}),o=()=>r,s=e=>a((0,i.reconcile)(typeof e==`function`?e(r):e,{key:`runId`,merge:!0})),[c,l]=(0,n.createSignal)(!1),[f,p]=(0,n.createSignal)(`scans`),[y,x]=(0,n.createSignal)(0),[S,E]=(0,n.createSignal)(),[fe,L]=(0,n.createSignal)(),[R,z]=(0,n.createSignal)(!0),[B,V]=(0,n.createSignal)(),[pe,me]=(0,n.createSignal)(t.directory),[he,ge]=(0,n.createSignal)(`default`),[_e,ve]=(0,n.createSignal)(``),[ye,H]=(0,n.createSignal)(``),[be,U]=(0,n.createSignal)(``),[W,G]=(0,n.createSignal)(null),[xe,K]=(0,n.createSignal)(``),[Se,Ce]=(0,n.createSignal)(``),[q,we]=(0,n.createSignal)(Date.now()),Te,Ee,J=!1,De=!1,Oe=!1,ke=0,Ae=0,je=0,X=(0,n.createMemo)(()=>o().runs.filter(e=>e.status===`running`).length),qt=(0,n.createMemo)(()=>o().runs.find(e=>e.runId===fe())??o().runs[0]);(0,n.createEffect)((0,n.on)(()=>qt()?.runId,()=>{Te?.querySelectorAll(`details[open]`).forEach(e=>e.removeAttribute(`open`)),Ee&&(Ee.open=!1)}));let Z=(0,n.createMemo)(()=>m(o(),q())),Jt=(0,n.createMemo)(()=>o().engine?.startsWith(`local-patterns`)||o().runs[0]?.engine?.startsWith(`local-patterns`)||o().drafts[0]?.engine?.startsWith(`local-patterns`)),Q=async()=>{if(De||J)return;De=!0;let e=++ke;try{let n=Wt(await t.port.list());if(J||e<Ae)return;if(Ae=e,s(n),Ce(``),t.operations)try{let e=await t.operations.list();J||x((e.operations??[]).filter(e=>e.status===`awaiting_answers`).length)}catch{}c()||(l(!0),!Oe&&n.runs.length&&z(!1))}catch(e){J||Ce(I(e))}finally{De=!1}},$=()=>{je++,Oe=!0,V(void 0)},Yt=()=>{$(),me(t.directory),ge(`default`),ve(``),H(``),U(``),z(!0),K(``)},Xt=e=>{$(),me(e.repository),ge(e.inputs.mode??`default`),ve(e.scanPrompt),H(e.scopePaths.join(`
|
|
16
16
|
`)),U(e.contextFiles.map(e=>e.path).join(`
|
|
17
|
-
`)),V(e),z(!0),K(``)},Xt=async e=>{if(e.preventDefault(),W()||J)return;G(`prepare`),K(``);let n=Ae;try{let e={repository:fe().trim()||t.directory,scanPrompt:ge(),scopePaths:P(ve()),contextFiles:P(ye()),...me()==="default"?{}:{mode:me()}},r=m(await t.port.prepare(e));if(J)return;if(!r.plan)throw Error(`The server did not return a scan preview. Nothing was started.`);Ae===n&&V(r.plan),await Q()}catch(e){J||K(F(e))}finally{J||G(null)}},Zt=async()=>{if(!(W()||J||!B()&&!qt())){G(`start`),K(``);try{let e=B(),n=m(await t.port.start(e?{planId:e.id,approveOpenAIInference:!0}:{}));if(J)return;ke=++Oe,L(n.runId),z(!1),V(void 0),s(e=>({...e,runs:[n,...e.runs.filter(e=>e.runId!==n.runId)]})),await Q()}catch(e){J||K(F(e))}finally{J||G(null)}}},Qt=async e=>{if(!(W()||J||!e.runId)){G(`cancel`),K(``);try{await t.port.cancel({runId:e.runId}),J||await Q()}catch(e){J||K(F(e))}finally{J||G(null)}}};Q();let $t=setInterval(()=>{Ce(Date.now()),Q()},t.pollMs??1500);return(0,n.onCleanup)(()=>{J=!0,clearInterval($t)}),(()=>{var r=Ue(),i=r.firstChild,a=i.nextSibling,s=a.firstChild,l=s.firstChild.firstChild.nextSibling;l.firstChild;var p=s.nextSibling,m=p.firstChild.nextSibling,b=p.nextSibling;return(0,e.insert)(i,Me),(0,e.insert)(l,()=>h(t.directory),null),(0,e.insert)(l,(()=>{var t=(0,e.memo)(()=>X()>0);return()=>t()?` · ${X()} running`:``})(),null),(0,e.insert)(s,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>d()===`scans`)()&&!R()},get children(){var e=Ne();return e.$$click=Jt,e}}),null),(0,e.insert)(m,()=>t.directory),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!!(t.operations&&c()))()&&!qt()},get children(){var r=Ie(),i=r.firstChild;return i.$$click=()=>f(`scans`),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return t.operations?.capabilities?.policy??!!t.operations},get children(){var t=Pe();return t.firstChild,t.$$click=()=>f(`policy`),(0,e.insert)(t,(()=>{var t=(0,e.memo)(()=>!!v());return()=>t()?` · ${v()} waiting`:``})(),null),(0,e.effect)(()=>(0,e.setAttribute)(t,`aria-current`,d()===`policy`?`page`:void 0)),t}}),null),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return t.operations?.capabilities?.validation??!!t.operations},get children(){var t=Fe();return t.$$click=()=>{T(void 0),f(`validation`)},(0,e.effect)(()=>(0,e.setAttribute)(t,`aria-current`,d()===`validation`?`page`:void 0)),t}}),null),(0,e.effect)(()=>(0,e.setAttribute)(i,`aria-current`,d()===`scans`?`page`:void 0)),r}}),b),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>d()!==`scans`)()?d():void 0},keyed:!0,children:n=>(0,e.createComponent)(je,{kind:n,get directory(){return t.directory},get port(){return t.operations},get seed(){return x()}})}),b),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return d()===`scans`},get children(){return[(0,e.createComponent)(n.Show,{get when(){return v()},get children(){var e=Le(),t=e.firstChild.nextSibling;return t.$$click=()=>f(`policy`),e}}),(0,e.createComponent)(n.Show,{get when(){return xe()},get children(){var t=Re(),n=t.firstChild,r=n.nextSibling;return(0,e.insert)(t,xe,n),r.$$click=()=>void Q(),t}}),(0,e.createComponent)(n.Show,{get when(){return o().historyError},get children(){var t=ze();return(0,e.insert)(t,()=>o().historyError),t}}),(0,e.createComponent)(n.Show,{get when(){return be()},get children(){var t=ze();return(0,e.insert)(t,be),t}}),(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!R())()&&Z()?.plan},children:t=>(()=>{var t=We(),n=t.firstChild;n.firstChild;var r=n.nextSibling;return(0,e.insert)(n,()=>Z()?.plan?.repository,null),r.$$click=()=>Yt(Z().plan),t})()}),(0,e.createComponent)(n.Show,{get when(){return R()},get children(){var t=Ve(),r=t.firstChild;return r.firstChild,(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return o().runs.length},get children(){var t=Be();return t.$$click=()=>z(!1),(0,e.effect)(()=>t.disabled=!!W()),t}}),null),(0,e.insert)(t,(0,e.createComponent)(n.Show,{get when(){return!qt()},get fallback(){return[Ge(),(()=>{var t=Ke();return t.$$click=()=>void Zt(),(0,e.effect)(()=>t.disabled=!!W()),t})()]},get children(){return(0,e.createComponent)(n.Show,{get when(){return B()},get fallback(){return(()=>{var t=Je(),r=t.firstChild,i=r.firstChild.nextSibling,a=r.nextSibling,o=a.firstChild.nextSibling,s=a.nextSibling,l=s.firstChild.nextSibling.nextSibling,u=s.nextSibling,d=u.firstChild.nextSibling,f=d.firstChild.nextSibling,p=d.nextSibling.firstChild.nextSibling,m=u.nextSibling.firstChild;return t.addEventListener(`submit`,e=>void Xt(e)),(0,e.insert)(t,(0,e.createComponent)(n.Show,{get when(){return Z()?.plan},get children(){var t=qe();return t.firstChild,t.$$click=()=>Yt(Z().plan),(0,e.insert)(t,()=>Z()?.plan?.repository,null),t}}),r),i.$$input=e=>{$(),pe(e.currentTarget.value),H(``),U(``)},(0,e.setAttribute)(i,`spellcheck`,!1),o.addEventListener(`change`,e=>{$(),he(e.currentTarget.value)}),l.$$input=e=>{$(),_e(e.currentTarget.value)},f.$$input=e=>{$(),H(e.currentTarget.value)},p.$$input=e=>{$(),U(e.currentTarget.value)},(0,e.insert)(m,()=>W()===`prepare`?`Preparing preview…`:`Review scan`),(0,e.effect)(()=>m.disabled=!!W()||!c()),(0,e.effect)(()=>i.value=fe()),(0,e.effect)(()=>o.value=me()),(0,e.effect)(()=>l.value=ge()),(0,e.effect)(()=>f.value=ve()),(0,e.effect)(()=>p.value=ye()),t})()},children:t=>(()=>{var r=et(),i=r.firstChild.nextSibling,a=i.firstChild.nextSibling,s=a.nextSibling.nextSibling,c=s.nextSibling.nextSibling,l=i.nextSibling,d=l.firstChild.nextSibling,f=d.firstChild.nextSibling,p=f.firstChild,m=p.nextSibling;m.nextSibling;var h=f.nextSibling.nextSibling,g=h.nextSibling.nextSibling,_=d.nextSibling.nextSibling.firstChild.nextSibling,v=l.nextSibling,y=v.nextSibling,b=y.firstChild,x=b.nextSibling;return(0,e.insert)(a,()=>t().repository),(0,e.insert)(s,()=>t().scopePaths.join(`, `)||`Whole repository`),(0,e.insert)(c,()=>t().settings.scan.mode===`deep`?`Deep`:`Standard`),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return t().scanPrompt},get children(){return[Ye(),(()=>{var n=Y();return(0,e.insert)(n,()=>t().scanPrompt),n})()]}}),null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return t().contextFiles.length},get children(){return[Xe(),(()=>{var n=Y();return(0,e.insert)(n,()=>t().contextFiles.map(e=>e.path).join(`, `)),n})()]}}),null),(0,e.insert)(f,()=>t().settings.codex.model,p),(0,e.insert)(f,()=>t().settings.codex.reasoningEffort,m),(0,e.insert)(h,()=>t().settings.codex.daybreak?`On`:`Off`),(0,e.insert)(g,()=>t().globalConfigFile),(0,e.insert)(_,()=>u(t())),(0,e.insert)(v,(0,e.createComponent)(n.Show,{get when(){return t().mock},get fallback(){return[tt(),(()=>{var n=nt(),r=n.firstChild.nextSibling;return r.firstChild,(0,e.insert)(r,()=>t().settings.scan.maxCostUsd,null),n})(),rt()]},get children(){return Ze()}})),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return X()>=o().maxConcurrent},get children(){var t=Qe(),n=t.firstChild;return(0,e.insert)(t,()=>o().maxConcurrent,n),t}}),y),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return Date.parse(t().expiresAt)<=q()},get children(){return $e()}}),y),b.$$click=()=>void Zt(),(0,e.insert)(b,(()=>{var n=(0,e.memo)(()=>W()===`start`);return()=>n()?`Starting…`:t().mock?`Start mock scan`:`Approve and start`})()),x.$$click=()=>V(void 0),(0,e.effect)(e=>{var n=!!W()||X()>=o().maxConcurrent||Date.parse(t().expiresAt)<=q(),r=!!W();return n!==e.e&&(b.disabled=e.e=n),r!==e.t&&(x.disabled=e.t=r),e},{e:void 0,t:void 0}),r})()})}}),null),t}}),(0,e.createComponent)(n.Show,{get when(){return o().runs.length},get fallback(){return(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!!c())()&&!R()},get children(){return it()}})},get children(){var t=He(),r=t.firstChild,i=r.firstChild.nextSibling,a=i.firstChild,s=r.nextSibling.nextSibling;return(0,e.use)(e=>Te=e,t),(0,e.insert)(i,()=>o().runs.length,a),(0,e.insert)(s,(0,e.createComponent)(n.For,{get each(){return o().runs},children:t=>(()=>{var n=at(),r=n.firstChild,i=r.firstChild,a=i.firstChild,o=a.nextSibling,s=i.nextSibling;s.firstChild;var c=s.nextSibling,l=c.firstChild,u=l.nextSibling;return u.nextSibling,r.$$click=()=>L(t.runId),(0,e.insert)(a,()=>g(t)),(0,e.insert)(o,(()=>{var n=(0,e.memo)(()=>t.status===`error`);return()=>n()?`Failed`:t.status})()),(0,e.insert)(s,()=>t.repository,null),(0,e.insert)(c,()=>t.mode??t.plan?.settings.scan.mode??`Fixture`,l),(0,e.insert)(c,()=>_(t),u),(0,e.insert)(c,()=>Gt(t.startedAt),null),(0,e.insert)(c,(()=>{var n=(0,e.memo)(()=>t.status===`completed`);return()=>n()?` · ${t.findings.length} ${t.findings.length===1?`finding`:`findings`} shown`:``})(),null),(0,e.effect)(n=>{var i=Kt()?.runId===t.runId,a=t.status;return i!==n.e&&(0,e.setAttribute)(r,`aria-pressed`,n.e=i),a!==n.t&&(0,e.setAttribute)(o,`data-status`,n.t=a),n},{e:void 0,t:void 0}),n})()})),t}}),(0,e.createComponent)(n.Show,{get when(){return Kt()},children:r=>(()=>{var i=jt(),a=i.firstChild,o=a.firstChild,s=o.nextSibling;s.firstChild;var c=s.nextSibling,l=c.firstChild,u=a.nextSibling,d=u.firstChild,p=d.nextSibling,m=u.nextSibling,h=m.firstChild,v=m.nextSibling;v.firstChild;var b=v.nextSibling,x=b.firstChild.nextSibling,P=x.firstChild.nextSibling,F=P.nextSibling,I=F.nextSibling,L=I.nextSibling,R=L.nextSibling.nextSibling,z=R.nextSibling,B=z.nextSibling,V=B.nextSibling.nextSibling;return(0,e.use)(e=>we=e,i),(0,e.insert)(o,()=>g(r())),(0,e.insert)(s,()=>r().repository,null),(0,e.insert)(c,()=>r().mode??r().plan?.settings.scan.mode??`Fixture`,l),(0,e.insert)(c,()=>_(r()),null),(0,e.insert)(d,()=>S(r())),(0,e.insert)(p,()=>ue(r().startedAt,r().finishedAt,q())),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return ee(r())},get children(){var t=ot();return(0,e.effect)(n=>{var i=`${S(r())}: reported phase progress`,a=y(r()).total;return i!==n.e&&(0,e.setAttribute)(t,`aria-label`,n.e=i),a!==n.t&&(0,e.setAttribute)(t,`max`,n.t=a),n},{e:void 0,t:void 0}),(0,e.effect)(()=>t.value=y(r()).done),t}}),m),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return C(r())},get children(){var t=st(),n=t.firstChild,i=n.nextSibling;return(0,e.insert)(n,()=>te(r())),(0,e.insert)(i,()=>w(r())),t}}),m),(0,e.insert)(h,()=>E(r())),(0,e.insert)(m,(0,e.createComponent)(n.Show,{get when(){return r().status===`running`},get children(){var t=ct();return t.$$click=()=>void Qt(r()),(0,e.insert)(t,()=>W()===`cancel`?`Requesting stop…`:`Cancel scan`),(0,e.effect)(()=>t.disabled=!!W()),t}}),null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`running`},get children(){var t=lt();return(0,e.insert)(t,()=>re(r())),t}}),v),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().error},get children(){var t=ze();return(0,e.insert)(t,()=>r().error),t}}),v),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`cancelled`},get children(){return ut()}}),v),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>r().status===`completed`)()&&r().findings.length===0},get children(){return dt()}}),v),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().findings.length},get children(){var i=ft(),a=i.firstChild.firstChild.nextSibling,o=a.firstChild;return(0,e.insert)(a,()=>r().findings.length,o),(0,e.insert)(i,(0,e.createComponent)(n.For,{get each(){return r().findings},children:i=>(()=>{var a=Pt(),o=a.firstChild,s=o.firstChild;s.nextSibling;var c=o.nextSibling,l=c.firstChild,u=l.nextSibling;u.nextSibling;var d=c.nextSibling,p=d.nextSibling,m=p.nextSibling,h=m.nextSibling,g=h.firstChild.nextSibling;return g.nextSibling,(0,e.insert)(s,()=>i.severity),(0,e.insert)(o,()=>i.title,null),(0,e.insert)(c,()=>i.path,l),(0,e.insert)(c,()=>i.line,u),(0,e.insert)(c,()=>i.cwe,null),(0,e.insert)(d,()=>i.summary),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return i.evidence},get children(){var t=Mt();return(0,e.insert)(t,()=>i.evidence),t}}),p),(0,e.insert)(m,()=>i.remediation),(0,e.insert)(h,()=>i.confidence,g),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!!(t.operations&&(t.operations.capabilities?.validation??!0)))()&&!qt()},get children(){var e=Nt();return e.$$click=()=>{T({repository:r().repository,finding:de(i)}),f(`validation`)},e}}),null),(0,e.effect)(()=>(0,e.setAttribute)(s,`data-severity`,i.severity)),a})()}),null),i}}),v),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`completed`},get children(){var t=ht(),i=t.firstChild,a=i.nextSibling,o=a.firstChild.nextSibling,s=o.nextSibling.nextSibling,c=s.firstChild,l=c.nextSibling;return(0,e.insert)(i,()=>se(r())),(0,e.insert)(o,()=>ce(r())),(0,e.insert)(s,(0,e.createComponent)(n.For,{get each(){return le(r())},children:t=>[(0,e.createComponent)(n.Show,{get when(){return t.label},get children(){var n=Ft();return(0,e.insert)(n,()=>t.label),n}}),(()=>{var n=Y();return(0,e.insert)(n,()=>t.value),n})()]}),c),(0,e.insert)(l,()=>N(r())),(0,e.insert)(s,(0,e.createComponent)(n.Show,{get when(){return r().assessment?.repositoryFindings.available},get children(){var t=pt(),n=t.firstChild,i=n.nextSibling;return i.nextSibling,(0,e.insert)(t,()=>r().assessment?.repositoryFindings.withMatchedFindingIds??`Unknown`,n),(0,e.insert)(t,()=>r().assessment?.repositoryFindings.notConfirmedInLatestScan??`Unknown`,i),t}}),null),(0,e.insert)(a,(0,e.createComponent)(n.For,{get each(){return r().assessment?.notes??[]},children:t=>(()=>{var n=It();return(0,e.insert)(n,t),n})()}),null),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return r().skipped||r().assessment?.returnedFindings.informational},get children(){return mt()}}),null),t}}),v),(0,e.insert)(v,(0,e.createComponent)(n.Show,{get when(){return oe(r())},get children(){var t=gt();return(0,e.insert)(t,()=>oe(r())),t}}),null),(0,e.insert)(v,(0,e.createComponent)(n.Show,{get when(){return j(r())},get children(){var t=gt();return(0,e.insert)(t,()=>j(r())),t}}),null),(0,e.insert)(v,(0,e.createComponent)(n.Show,{get when(){return D(r()).length},get fallback(){return(()=>{var t=gt();return(0,e.insert)(t,()=>r().status===`running`?`Waiting for detailed SDK activity.`:`No detailed activity was recorded for this run.`),t})()},get children(){var t=_t();return(0,e.insert)(t,(0,e.createComponent)(n.For,{get each(){return O(r()).slice(0,4)},children:t=>(()=>{var n=Lt(),i=n.firstChild,a=i.firstChild,o=a.nextSibling,s=i.nextSibling;return(0,e.insert)(a,()=>k(t.worker)),(0,e.insert)(o,()=>t.label),(0,e.insert)(s,()=>A(t.status,r())),(0,e.effect)(r=>{var i=t.id,a=t.status;return i!==r.e&&(0,e.setAttribute)(n,`data-activity-id`,r.e=i),a!==r.t&&(0,e.setAttribute)(s,`data-status`,r.t=a),r},{e:void 0,t:void 0}),n})()})),t}}),null),(0,e.insert)(v,(0,e.createComponent)(n.Show,{get when(){return D(r()).length||r().events.length},get children(){var t=bt(),i=t.firstChild.nextSibling;return(0,e.insert)(i,(0,e.createComponent)(n.For,{get each(){return D(r())},children:t=>(()=>{var i=zt(),a=i.firstChild,o=a.nextSibling,s=o.firstChild,c=s.nextSibling;return c.nextSibling,(0,e.insert)(a,()=>Wt(t.updatedAt)),(0,e.insert)(o,()=>k(t.worker),s),(0,e.insert)(o,()=>t.label,c),(0,e.insert)(o,()=>A(t.status,r()),null),(0,e.insert)(o,(0,e.createComponent)(n.Show,{get when(){return t.paths.length},get children(){var n=Rt();return(0,e.insert)(n,()=>t.paths.join(`, `)),n}}),null),(0,e.effect)(()=>(0,e.setAttribute)(a,`datetime`,t.updatedAt)),i})()})),(0,e.insert)(t,(0,e.createComponent)(n.Show,{get when(){return r().events.length},get children(){return[vt(),(()=>{var t=yt();return(0,e.insert)(t,(0,e.createComponent)(n.For,{get each(){return[...r().events].reverse().slice(0,20)},children:t=>(()=>{var n=Bt(),r=n.firstChild,i=r.nextSibling;return(0,e.insert)(r,()=>Wt(t.time)),(0,e.insert)(i,()=>t.message),(0,e.effect)(()=>(0,e.setAttribute)(r,`datetime`,t.time)),n})()})),t})()]}}),null),t}}),null),(0,e.insert)(P,()=>E(r())),(0,e.insert)(F,()=>ie(r())),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return ae(r())},get children(){return[xt(),(()=>{var t=Y();return(0,e.insert)(t,()=>ae(r())),t})()]}}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().telemetry?.measurement?.cost?.model},get children(){return[St(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().telemetry?.measurement?.cost?.model),t})()]}}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().telemetry?.measurement?.cost?.pricingAsOf},get children(){return[Ct(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().telemetry?.measurement?.cost?.pricingAsOf),t})()]}}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().telemetry?.measurement?.usage},children:t=>[Vt(),(()=>{var n=Ht(),r=n.firstChild,i=r.nextSibling,a=i.nextSibling.nextSibling;return a.nextSibling,(0,e.insert)(n,()=>t().inputTokens.toLocaleString(),r),(0,e.insert)(n,()=>t().cachedInputTokens.toLocaleString(),i),(0,e.insert)(n,()=>t().outputTokens.toLocaleString(),a),n})()]}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().deepProgress},get children(){return[wt(),(()=>{var t=Y();return(0,e.insert)(t,()=>ne(r())),t})(),Tt()]}}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return M(r())},get children(){return[Et(),(()=>{var t=Y();return(0,e.insert)(t,()=>M(r())),t})()]}}),I),(0,e.insert)(L,()=>r().repository),(0,e.insert)(R,()=>r().runId),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().scanId},get children(){return[Dt(),(()=>{var t=Ot();return(0,e.insert)(t,()=>r().scanId),t})()]}}),z),(0,e.insert)(B,()=>_(r())),(0,e.insert)(V,()=>r().mode??r().plan?.settings.scan.mode??`Fixture pattern checks`),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().model??r().plan?.settings.codex.model},get children(){return[kt(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().model??r().plan?.settings.codex.model),t})()]}}),null),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().plan?.scanPrompt},get children(){return[Ye(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().plan?.scanPrompt),t})()]}}),null),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().plan?.contextFiles.length},get children(){return[Xe(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().plan?.contextFiles.map(e=>e.path).join(`, `)),t})()]}}),null),(0,e.insert)(b,(0,e.createComponent)(n.Show,{get when(){return r().archived},get children(){return At()}}),null),i})()})]}}),b),(0,e.insert)(b,()=>qt()?`Fixture engine · not a security assessment`:`Codex Security · local results, OpenAI inference`,null),(0,e.insert)(b,(0,e.createComponent)(n.Show,{get when(){return o().runs.length},get children(){return[` `,`· Up to `,(0,e.memo)(()=>o().maxConcurrent),` concurrent scans per project`]}}),null),r})()}(0,e.delegateEvents)([`click`,`input`]);var Kt=(0,e.template)(`<section style=padding:24px><h2>Security</h2><p>Open a local project session to choose a scan target.</p><p>No repository is selected. Remote and unknown workspaces cannot start local scans.`),Z=t.Plugin.define({setup(r){let i={id:`security`,title:`Security`,tabbable:!0};r.add(t.Panel,{id:`security`,region:`side`,width:580,list:()=>[i],render(t){let i=(0,n.createMemo)(()=>d(t.session));return(0,e.createComponent)(n.Show,{get when(){return i()},keyed:!0,get fallback(){return Kt()},children:t=>{let i={directory:t},[a,o]=(0,n.createSignal)(),s=!1;return(0,n.onCleanup)(()=>{s=!0}),r.client.rpc(l).capabilities({},{location:i}).then(e=>{let t=e;!s&&(t.policy||t.validation)&&o(t)}).catch(()=>{}),(0,e.createComponent)(X,{directory:t,get operations(){return(0,e.memo)(()=>!!a())()?{capabilities:a(),list:()=>r.client.rpc(l).operationList({},{location:i}),prepare:e=>r.client.rpc(l).operationPrepare(e,{location:i}),start:e=>r.client.rpc(l).operationStart(e,{location:i}),answer:e=>r.client.rpc(l).operationAnswer(e,{location:i}),cancel:e=>r.client.rpc(l).operationCancel(e,{location:i})}:void 0},port:{list:()=>r.client.rpc(l).list({},{location:i}),prepare:e=>r.client.rpc(l).prepare(e,{location:i}),start:e=>r.client.rpc(l).start(e,{location:i}),cancel:e=>r.client.rpc(l).cancel(e,{location:i})}})}})}}),r.add(t.Command,{id:`open`,title:`Security: open scans`,group:`Security`,slash:{name:`security`},run:()=>{let e=r.sessions.current();e?r.layout.open(`${r.id}:security`,e):r.toast.show({title:`Open a local project session to view Security`})}})}});exports.default=Z;
|
|
17
|
+
`)),V(e),z(!0),K(``)},Zt=async e=>{if(e.preventDefault(),W()||J)return;G(`prepare`),K(``);let n=je;try{let e={repository:pe().trim()||t.directory,scanPrompt:_e(),scopePaths:F(ye()),contextFiles:F(be()),...he()==="default"?{}:{mode:he()}},r=h(await t.port.prepare(e));if(J)return;if(!r.plan)throw Error(`The server did not return a scan preview. Nothing was started.`);je===n&&V(r.plan),await Q()}catch(e){J||K(I(e))}finally{J||G(null)}},Qt=async()=>{if(!(W()||J||!B()&&!Jt())){G(`start`),K(``);try{let e=B(),n=h(await t.port.start(e?{planId:e.id,approveOpenAIInference:!0}:{}));if(J)return;Ae=++ke,L(n.runId),z(!1),V(void 0),s(e=>({...e,runs:[n,...e.runs.filter(e=>e.runId!==n.runId)]})),await Q()}catch(e){J||K(I(e))}finally{J||G(null)}}},$t=async e=>{if(!(W()||J||!e.runId)){G(`cancel`),K(``);try{await t.port.cancel({runId:e.runId}),J||await Q()}catch(e){J||K(I(e))}finally{J||G(null)}}};Q();let en=setInterval(()=>{we(Date.now()),Q()},t.pollMs??1500);return(0,n.onCleanup)(()=>{J=!0,clearInterval(en)}),(()=>{var r=We(),i=r.firstChild,a=i.nextSibling,s=a.firstChild,l=s.firstChild.firstChild.nextSibling;l.firstChild;var m=s.nextSibling,h=m.firstChild.nextSibling,x=m.nextSibling;return(0,e.insert)(i,Ne),(0,e.insert)(l,()=>g(t.directory),null),(0,e.insert)(l,(()=>{var t=(0,e.memo)(()=>X()>0);return()=>t()?` · ${X()} running`:``})(),null),(0,e.insert)(s,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>f()===`scans`)()&&!R()},get children(){var e=Pe();return e.$$click=Yt,e}}),null),(0,e.insert)(h,()=>t.directory),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!!(t.operations&&c()))()&&!Jt()},get children(){var r=Le(),i=r.firstChild;return i.$$click=()=>p(`scans`),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return t.operations?.capabilities?.policy??!!t.operations},get children(){var t=Fe();return t.firstChild,t.$$click=()=>p(`policy`),(0,e.insert)(t,(()=>{var t=(0,e.memo)(()=>!!y());return()=>t()?` · ${y()} waiting`:``})(),null),(0,e.effect)(()=>(0,e.setAttribute)(t,`aria-current`,f()===`policy`?`page`:void 0)),t}}),null),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return t.operations?.capabilities?.validation??!!t.operations},get children(){var t=Ie();return t.$$click=()=>{E(void 0),p(`validation`)},(0,e.effect)(()=>(0,e.setAttribute)(t,`aria-current`,f()===`validation`?`page`:void 0)),t}}),null),(0,e.effect)(()=>(0,e.setAttribute)(i,`aria-current`,f()===`scans`?`page`:void 0)),r}}),x),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>f()!==`scans`)()?f():void 0},keyed:!0,children:n=>(0,e.createComponent)(Me,{kind:n,get directory(){return t.directory},get port(){return t.operations},get seed(){return S()}})}),x),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return f()===`scans`},get children(){return[(0,e.createComponent)(n.Show,{get when(){return y()},get children(){var e=Re(),t=e.firstChild.nextSibling;return t.$$click=()=>p(`policy`),e}}),(0,e.createComponent)(n.Show,{get when(){return Se()},get children(){var t=ze(),n=t.firstChild,r=n.nextSibling;return(0,e.insert)(t,Se,n),r.$$click=()=>void Q(),t}}),(0,e.createComponent)(n.Show,{get when(){return o().historyError},get children(){var t=Be();return(0,e.insert)(t,()=>o().historyError),t}}),(0,e.createComponent)(n.Show,{get when(){return xe()},get children(){var t=Be();return(0,e.insert)(t,xe),t}}),(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!R())()&&Z()?.plan},children:t=>(()=>{var t=Ge(),n=t.firstChild;n.firstChild;var r=n.nextSibling;return(0,e.insert)(n,()=>Z()?.plan?.repository,null),r.$$click=()=>Xt(Z().plan),t})()}),(0,e.createComponent)(n.Show,{get when(){return R()},get children(){var t=He(),r=t.firstChild;return r.firstChild,(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return o().runs.length},get children(){var t=Ve();return t.$$click=()=>z(!1),(0,e.effect)(()=>t.disabled=!!W()),t}}),null),(0,e.insert)(t,(0,e.createComponent)(n.Show,{get when(){return!Jt()},get fallback(){return[Ke(),(()=>{var t=qe();return t.$$click=()=>void Qt(),(0,e.effect)(()=>t.disabled=!!W()),t})()]},get children(){return(0,e.createComponent)(n.Show,{get when(){return B()},get fallback(){return(()=>{var t=Ye(),r=t.firstChild,i=r.firstChild.nextSibling,a=r.nextSibling,o=a.firstChild.nextSibling,s=a.nextSibling,l=s.firstChild.nextSibling.nextSibling,u=s.nextSibling,d=u.firstChild.nextSibling,f=d.firstChild.nextSibling,p=d.nextSibling.firstChild.nextSibling,m=u.nextSibling.firstChild;return t.addEventListener(`submit`,e=>void Zt(e)),(0,e.insert)(t,(0,e.createComponent)(n.Show,{get when(){return Z()?.plan},get children(){var t=Je();return t.firstChild,t.$$click=()=>Xt(Z().plan),(0,e.insert)(t,()=>Z()?.plan?.repository,null),t}}),r),i.$$input=e=>{$(),me(e.currentTarget.value),H(``),U(``)},(0,e.setAttribute)(i,`spellcheck`,!1),o.addEventListener(`change`,e=>{$(),ge(e.currentTarget.value)}),l.$$input=e=>{$(),ve(e.currentTarget.value)},f.$$input=e=>{$(),H(e.currentTarget.value)},p.$$input=e=>{$(),U(e.currentTarget.value)},(0,e.insert)(m,()=>W()===`prepare`?`Preparing preview…`:`Review scan`),(0,e.effect)(()=>m.disabled=!!W()||!c()),(0,e.effect)(()=>i.value=pe()),(0,e.effect)(()=>o.value=he()),(0,e.effect)(()=>l.value=_e()),(0,e.effect)(()=>f.value=ye()),(0,e.effect)(()=>p.value=be()),t})()},children:t=>(()=>{var r=tt(),i=r.firstChild.nextSibling,a=i.firstChild.nextSibling,s=a.nextSibling.nextSibling,c=s.nextSibling.nextSibling,l=i.nextSibling,f=l.firstChild.nextSibling,p=f.firstChild.nextSibling,m=p.firstChild,h=m.nextSibling;h.nextSibling;var g=p.nextSibling.nextSibling,_=g.nextSibling.nextSibling,v=f.nextSibling.nextSibling.firstChild.nextSibling,y=l.nextSibling,b=y.nextSibling,x=b.firstChild,S=x.nextSibling;return(0,e.insert)(a,()=>t().repository),(0,e.insert)(s,()=>t().scopePaths.join(`, `)||`Whole repository`),(0,e.insert)(c,()=>t().settings.scan.mode===`deep`?`Deep`:`Standard`),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return t().scanPrompt},get children(){return[Xe(),(()=>{var n=Y();return(0,e.insert)(n,()=>t().scanPrompt),n})()]}}),null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return t().contextFiles.length},get children(){return[Ze(),(()=>{var n=Y();return(0,e.insert)(n,()=>t().contextFiles.map(e=>e.path).join(`, `)),n})()]}}),null),(0,e.insert)(p,()=>t().settings.codex.model,m),(0,e.insert)(p,()=>t().settings.codex.reasoningEffort,h),(0,e.insert)(g,()=>t().settings.codex.daybreak?`On`:`Off`),(0,e.insert)(_,()=>t().globalConfigFile),(0,e.insert)(v,()=>d(t())),(0,e.insert)(y,(0,e.createComponent)(n.Show,{get when(){return t().mock},get fallback(){return[(()=>{var n=nt(),r=n.firstChild.nextSibling;return r.nextSibling,(0,e.insert)(n,()=>u(t().settings),r),n})(),(()=>{var n=rt(),r=n.firstChild.nextSibling;return r.firstChild,(0,e.insert)(r,()=>t().settings.scan.maxCostUsd,null),n})(),it()]},get children(){return Qe()}})),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return X()>=o().maxConcurrent},get children(){var t=$e(),n=t.firstChild;return(0,e.insert)(t,()=>o().maxConcurrent,n),t}}),b),(0,e.insert)(r,(0,e.createComponent)(n.Show,{get when(){return Date.parse(t().expiresAt)<=q()},get children(){return et()}}),b),x.$$click=()=>void Qt(),(0,e.insert)(x,(()=>{var n=(0,e.memo)(()=>W()===`start`);return()=>n()?`Starting…`:t().mock?`Start mock scan`:`Approve and start`})()),S.$$click=()=>V(void 0),(0,e.effect)(e=>{var n=!!W()||X()>=o().maxConcurrent||Date.parse(t().expiresAt)<=q(),r=!!W();return n!==e.e&&(x.disabled=e.e=n),r!==e.t&&(S.disabled=e.t=r),e},{e:void 0,t:void 0}),r})()})}}),null),t}}),(0,e.createComponent)(n.Show,{get when(){return o().runs.length},get fallback(){return(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!!c())()&&!R()},get children(){return at()}})},get children(){var t=Ue(),r=t.firstChild,i=r.firstChild.nextSibling,a=i.firstChild,s=r.nextSibling.nextSibling;return(0,e.use)(e=>Ee=e,t),(0,e.insert)(i,()=>o().runs.length,a),(0,e.insert)(s,(0,e.createComponent)(n.For,{get each(){return o().runs},children:t=>(()=>{var n=ot(),r=n.firstChild,i=r.firstChild,a=i.firstChild,o=a.nextSibling,s=i.nextSibling;s.firstChild;var c=s.nextSibling,l=c.firstChild,u=l.nextSibling;return u.nextSibling,r.$$click=()=>L(t.runId),(0,e.insert)(a,()=>_(t)),(0,e.insert)(o,(()=>{var n=(0,e.memo)(()=>t.status===`error`);return()=>n()?`Failed`:t.status})()),(0,e.insert)(s,()=>t.repository,null),(0,e.insert)(c,()=>t.mode??t.plan?.settings.scan.mode??`Fixture`,l),(0,e.insert)(c,()=>v(t),u),(0,e.insert)(c,()=>Kt(t.startedAt),null),(0,e.insert)(c,(()=>{var n=(0,e.memo)(()=>t.status===`completed`);return()=>n()?` · ${t.findings.length} ${t.findings.length===1?`finding`:`findings`} shown`:``})(),null),(0,e.effect)(n=>{var i=qt()?.runId===t.runId,a=t.status;return i!==n.e&&(0,e.setAttribute)(r,`aria-pressed`,n.e=i),a!==n.t&&(0,e.setAttribute)(o,`data-status`,n.t=a),n},{e:void 0,t:void 0}),n})()})),t}}),(0,e.createComponent)(n.Show,{get when(){return qt()},children:r=>(()=>{var i=Mt(),a=i.firstChild,o=a.firstChild,s=o.nextSibling;s.firstChild;var c=s.nextSibling,l=c.firstChild,u=a.nextSibling,d=u.firstChild,f=d.nextSibling,m=u.nextSibling,h=m.firstChild,g=m.nextSibling;g.firstChild;var y=g.nextSibling,x=y.firstChild.nextSibling,S=x.firstChild.nextSibling,F=S.nextSibling,I=F.nextSibling,fe=I.nextSibling,L=fe.nextSibling.nextSibling,R=L.nextSibling,z=R.nextSibling,B=z.nextSibling.nextSibling;return(0,e.use)(e=>Te=e,i),(0,e.insert)(o,()=>_(r())),(0,e.insert)(s,()=>r().repository,null),(0,e.insert)(c,()=>r().mode??r().plan?.settings.scan.mode??`Fixture`,l),(0,e.insert)(c,()=>v(r()),null),(0,e.insert)(d,()=>C(r())),(0,e.insert)(f,()=>ue(r().startedAt,r().finishedAt,q())),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return ee(r())},get children(){var t=st();return(0,e.effect)(n=>{var i=`${C(r())}: reported phase progress`,a=b(r()).total;return i!==n.e&&(0,e.setAttribute)(t,`aria-label`,n.e=i),a!==n.t&&(0,e.setAttribute)(t,`max`,n.t=a),n},{e:void 0,t:void 0}),(0,e.effect)(()=>t.value=b(r()).done),t}}),m),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return w(r())},get children(){var t=ct(),n=t.firstChild,i=n.nextSibling;return(0,e.insert)(n,()=>te(r())),(0,e.insert)(i,()=>T(r())),t}}),m),(0,e.insert)(h,()=>D(r())),(0,e.insert)(m,(0,e.createComponent)(n.Show,{get when(){return r().status===`running`},get children(){var t=lt();return t.$$click=()=>void $t(r()),(0,e.insert)(t,()=>W()===`cancel`?`Requesting stop…`:`Cancel scan`),(0,e.effect)(()=>t.disabled=!!W()),t}}),null),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`running`},get children(){var t=ut();return(0,e.insert)(t,()=>re(r())),t}}),g),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().error},get children(){var t=Be();return(0,e.insert)(t,()=>r().error),t}}),g),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`cancelled`},get children(){return dt()}}),g),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>r().status===`completed`)()&&r().findings.length===0},get children(){return ft()}}),g),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().findings.length},get children(){var i=pt(),a=i.firstChild.firstChild.nextSibling,o=a.firstChild;return(0,e.insert)(a,()=>r().findings.length,o),(0,e.insert)(i,(0,e.createComponent)(n.For,{get each(){return r().findings},children:i=>(()=>{var a=Ft(),o=a.firstChild,s=o.firstChild;s.nextSibling;var c=o.nextSibling,l=c.firstChild,u=l.nextSibling;u.nextSibling;var d=c.nextSibling,f=d.nextSibling,m=f.nextSibling,h=m.nextSibling,g=h.firstChild.nextSibling;return g.nextSibling,(0,e.insert)(s,()=>i.severity),(0,e.insert)(o,()=>i.title,null),(0,e.insert)(c,()=>i.path,l),(0,e.insert)(c,()=>i.line,u),(0,e.insert)(c,()=>i.cwe,null),(0,e.insert)(d,()=>i.summary),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return i.evidence},get children(){var t=Nt();return(0,e.insert)(t,()=>i.evidence),t}}),f),(0,e.insert)(m,()=>i.remediation),(0,e.insert)(h,()=>i.confidence,g),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return(0,e.memo)(()=>!!(t.operations&&(t.operations.capabilities?.validation??!0)))()&&!Jt()},get children(){var e=Pt();return e.$$click=()=>{E({repository:r().repository,finding:de(i)}),p(`validation`)},e}}),null),(0,e.effect)(()=>(0,e.setAttribute)(s,`data-severity`,i.severity)),a})()}),null),i}}),g),(0,e.insert)(i,(0,e.createComponent)(n.Show,{get when(){return r().status===`completed`},get children(){var t=gt(),i=t.firstChild,a=i.nextSibling,o=a.firstChild.nextSibling,s=o.nextSibling.nextSibling,c=s.firstChild,l=c.nextSibling;return(0,e.insert)(i,()=>se(r())),(0,e.insert)(o,()=>ce(r())),(0,e.insert)(s,(0,e.createComponent)(n.For,{get each(){return le(r())},children:t=>[(0,e.createComponent)(n.Show,{get when(){return t.label},get children(){var n=It();return(0,e.insert)(n,()=>t.label),n}}),(()=>{var n=Y();return(0,e.insert)(n,()=>t.value),n})()]}),c),(0,e.insert)(l,()=>P(r())),(0,e.insert)(s,(0,e.createComponent)(n.Show,{get when(){return r().assessment?.repositoryFindings.available},get children(){var t=mt(),n=t.firstChild,i=n.nextSibling;return i.nextSibling,(0,e.insert)(t,()=>r().assessment?.repositoryFindings.withMatchedFindingIds??`Unknown`,n),(0,e.insert)(t,()=>r().assessment?.repositoryFindings.notConfirmedInLatestScan??`Unknown`,i),t}}),null),(0,e.insert)(a,(0,e.createComponent)(n.For,{get each(){return r().assessment?.notes??[]},children:t=>(()=>{var n=Lt();return(0,e.insert)(n,t),n})()}),null),(0,e.insert)(a,(0,e.createComponent)(n.Show,{get when(){return r().skipped||r().assessment?.returnedFindings.informational},get children(){return ht()}}),null),t}}),g),(0,e.insert)(g,(0,e.createComponent)(n.Show,{get when(){return oe(r())},get children(){var t=_t();return(0,e.insert)(t,()=>oe(r())),t}}),null),(0,e.insert)(g,(0,e.createComponent)(n.Show,{get when(){return M(r())},get children(){var t=_t();return(0,e.insert)(t,()=>M(r())),t}}),null),(0,e.insert)(g,(0,e.createComponent)(n.Show,{get when(){return O(r()).length},get fallback(){return(()=>{var t=_t();return(0,e.insert)(t,()=>r().status===`running`?`Waiting for detailed SDK activity.`:`No detailed activity was recorded for this run.`),t})()},get children(){var t=vt();return(0,e.insert)(t,(0,e.createComponent)(n.For,{get each(){return k(r()).slice(0,4)},children:t=>(()=>{var n=Rt(),i=n.firstChild,a=i.firstChild,o=a.nextSibling,s=i.nextSibling;return(0,e.insert)(a,()=>A(t.worker)),(0,e.insert)(o,()=>t.label),(0,e.insert)(s,()=>j(t.status,r())),(0,e.effect)(r=>{var i=t.id,a=t.status;return i!==r.e&&(0,e.setAttribute)(n,`data-activity-id`,r.e=i),a!==r.t&&(0,e.setAttribute)(s,`data-status`,r.t=a),r},{e:void 0,t:void 0}),n})()})),t}}),null),(0,e.insert)(g,(0,e.createComponent)(n.Show,{get when(){return O(r()).length||r().events.length},get children(){var t=xt(),i=t.firstChild.nextSibling;return(0,e.insert)(i,(0,e.createComponent)(n.For,{get each(){return O(r())},children:t=>(()=>{var i=Bt(),a=i.firstChild,o=a.nextSibling,s=o.firstChild,c=s.nextSibling;return c.nextSibling,(0,e.insert)(a,()=>Gt(t.updatedAt)),(0,e.insert)(o,()=>A(t.worker),s),(0,e.insert)(o,()=>t.label,c),(0,e.insert)(o,()=>j(t.status,r()),null),(0,e.insert)(o,(0,e.createComponent)(n.Show,{get when(){return t.paths.length},get children(){var n=zt();return(0,e.insert)(n,()=>t.paths.join(`, `)),n}}),null),(0,e.effect)(()=>(0,e.setAttribute)(a,`datetime`,t.updatedAt)),i})()})),(0,e.insert)(t,(0,e.createComponent)(n.Show,{get when(){return r().events.length},get children(){return[yt(),(()=>{var t=bt();return(0,e.insert)(t,(0,e.createComponent)(n.For,{get each(){return[...r().events].reverse().slice(0,20)},children:t=>(()=>{var n=Vt(),r=n.firstChild,i=r.nextSibling;return(0,e.insert)(r,()=>Gt(t.time)),(0,e.insert)(i,()=>t.message),(0,e.effect)(()=>(0,e.setAttribute)(r,`datetime`,t.time)),n})()})),t})()]}}),null),t}}),null),(0,e.insert)(S,()=>D(r())),(0,e.insert)(F,()=>ie(r())),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return ae(r())},get children(){return[St(),(()=>{var t=Y();return(0,e.insert)(t,()=>ae(r())),t})()]}}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().telemetry?.measurement?.cost?.model},get children(){return[Ct(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().telemetry?.measurement?.cost?.model),t})()]}}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().telemetry?.measurement?.cost?.pricingAsOf},get children(){return[wt(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().telemetry?.measurement?.cost?.pricingAsOf),t})()]}}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().telemetry?.measurement?.usage},children:t=>[Ht(),(()=>{var n=Ut(),r=n.firstChild,i=r.nextSibling,a=i.nextSibling.nextSibling;return a.nextSibling,(0,e.insert)(n,()=>t().inputTokens.toLocaleString(),r),(0,e.insert)(n,()=>t().cachedInputTokens.toLocaleString(),i),(0,e.insert)(n,()=>t().outputTokens.toLocaleString(),a),n})()]}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().deepProgress},get children(){return[Tt(),(()=>{var t=Y();return(0,e.insert)(t,()=>ne(r())),t})(),Et()]}}),I),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return N(r())},get children(){return[Dt(),(()=>{var t=Y();return(0,e.insert)(t,()=>N(r())),t})()]}}),I),(0,e.insert)(fe,()=>r().repository),(0,e.insert)(L,()=>r().runId),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().scanId},get children(){return[Ot(),(()=>{var t=kt();return(0,e.insert)(t,()=>r().scanId),t})()]}}),R),(0,e.insert)(z,()=>v(r())),(0,e.insert)(B,()=>r().mode??r().plan?.settings.scan.mode??`Fixture pattern checks`),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().model??r().plan?.settings.codex.model},get children(){return[At(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().model??r().plan?.settings.codex.model),t})()]}}),null),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().plan?.scanPrompt},get children(){return[Xe(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().plan?.scanPrompt),t})()]}}),null),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return r().plan?.contextFiles.length},get children(){return[Ze(),(()=>{var t=Y();return(0,e.insert)(t,()=>r().plan?.contextFiles.map(e=>e.path).join(`, `)),t})()]}}),null),(0,e.insert)(y,(0,e.createComponent)(n.Show,{get when(){return r().archived},get children(){return jt()}}),null),i})()})]}}),x),(0,e.insert)(x,()=>Jt()?`Fixture engine · not a security assessment`:`Codex Security · local results, configured inference`,null),(0,e.insert)(x,(0,e.createComponent)(n.Show,{get when(){return o().runs.length},get children(){return[` `,`· Up to `,(0,e.memo)(()=>o().maxConcurrent),` concurrent scans per project`]}}),null),r})()}(0,e.delegateEvents)([`click`,`input`]);var qt=(0,e.template)(`<section style=padding:24px><h2>Security</h2><p>Open a local project session to choose a scan target.</p><p>No repository is selected. Remote and unknown workspaces cannot start local scans.`),Z=t.Plugin.define({setup(r){let i={id:`security`,title:`Security`,tabbable:!0};r.add(t.Panel,{id:`security`,region:`side`,width:580,list:()=>[i],render(t){let i=(0,n.createMemo)(()=>f(t.session));return(0,e.createComponent)(n.Show,{get when(){return i()},keyed:!0,get fallback(){return qt()},children:t=>{let i={directory:t},[a,o]=(0,n.createSignal)(),s=!1;return(0,n.onCleanup)(()=>{s=!0}),r.client.rpc(l).capabilities({},{location:i}).then(e=>{let t=e;!s&&(t.policy||t.validation)&&o(t)}).catch(()=>{}),(0,e.createComponent)(X,{directory:t,get operations(){return(0,e.memo)(()=>!!a())()?{capabilities:a(),list:()=>r.client.rpc(l).operationList({},{location:i}),prepare:e=>r.client.rpc(l).operationPrepare(e,{location:i}),start:e=>r.client.rpc(l).operationStart(e,{location:i}),answer:e=>r.client.rpc(l).operationAnswer(e,{location:i}),cancel:e=>r.client.rpc(l).operationCancel(e,{location:i})}:void 0},port:{list:()=>r.client.rpc(l).list({},{location:i}),prepare:e=>r.client.rpc(l).prepare(e,{location:i}),start:e=>r.client.rpc(l).start(e,{location:i}),cancel:e=>r.client.rpc(l).cancel(e,{location:i})}})}})}}),r.add(t.Command,{id:`open`,title:`Security: open scans`,group:`Security`,slash:{name:`security`},run:()=>{let e=r.sessions.current();e?r.layout.open(`${r.id}:security`,e):r.toast.show({title:`Open a local project session to view Security`})}})}});exports.default=Z;
|
package/docs/GLOBAL-CONFIG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Global Codex Security settings
|
|
2
2
|
|
|
3
|
-
The plugin reads
|
|
3
|
+
The plugin reads one optional global settings file:
|
|
4
4
|
|
|
5
5
|
- `$XDG_CONFIG_HOME/opencode/codex-security.json` when XDG_CONFIG_HOME is set.
|
|
6
6
|
- Otherwise `~/.config/opencode/codex-security.json`.
|
|
@@ -9,7 +9,7 @@ There are **no project overrides**. Session tools provide repository, scoped pat
|
|
|
9
9
|
|
|
10
10
|
The file is read whenever a scan is prepared. Changing it invalidates an outstanding preview, so changed settings cannot silently reach an already-approved scan. No application restart is needed for setting changes.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Without provider opt-in, the defaults preserve dedicated ChatGPT authentication, the SDK model/reasoning settings, and a USD 1 estimated stop threshold:
|
|
13
13
|
|
|
14
14
|
```json
|
|
15
15
|
{
|
|
@@ -29,7 +29,12 @@ The initial Mac file preserves the installed SDK's model/reasoning/Daybreak defa
|
|
|
29
29
|
|
|
30
30
|
- `codex.model`: model ID, forwarded to SDK constructor `codexOverrides.model`.
|
|
31
31
|
- `codex.reasoningEffort`: none, minimal, low, medium, high or xhigh; forwarded as `model_reasoning_effort`. Actual support depends on the selected model.
|
|
32
|
-
- `codex.daybreak`: boolean, forwarded as `codexOverrides.daybreak`.
|
|
32
|
+
- `codex.daybreak`: boolean, forwarded as `codexOverrides.daybreak`. Custom-provider Daybreak is currently unsupported by this plugin.
|
|
33
|
+
- `codex.useCodexConfig`: set `true` to import the existing Codex provider from the standard config location without specifying a path. Omitted or `false` alone leaves import off. An explicit `configFile` independently opts in when the flag is omitted.
|
|
34
|
+
- `codex.configFile`: explicit absolute or `~/` TOML path that overrides the standard location. Existing configurations using this field alone remain supported.
|
|
35
|
+
- `codex.profile`: optional native `[profiles.name]` selection inside the imported file. Without it, the file's top-level `profile` is used if present.
|
|
36
|
+
- `codex.provider`: explicit custom-provider object as an alternative to `configFile`.
|
|
37
|
+
- `codex.auth`: optional `chatgpt` or `api-key`. Defaults to `chatgpt` without a custom provider and `api-key` with one. Contradictory choices fail closed.
|
|
33
38
|
- `scan.mode`: standard or deep, used only when no per-scan mode is supplied. The built-in fallback is standard.
|
|
34
39
|
- `scan.maxCostUsd`: positive estimated stop threshold. This is **not a hard billing cap**; in-flight usage may exceed it.
|
|
35
40
|
- `scan.maxTimeMinutes`: positive time limit.
|
|
@@ -37,13 +42,84 @@ The initial Mac file preserves the installed SDK's model/reasoning/Daybreak defa
|
|
|
37
42
|
- `scan.workers`: positive integer, relevant to deep scans.
|
|
38
43
|
- `scan.subagents`: nonnegative integer, relevant to deep scans; zero is valid.
|
|
39
44
|
|
|
40
|
-
Unknown keys and invalid values fail closed.
|
|
45
|
+
Unknown keys and invalid values fail closed. Credential **values**, arbitrary environment variables, runtime executable paths and approval policies are not configurable here. Only the selected provider's environment-variable **name** is accepted. Owner suggestions remain disabled. Do not place secrets in this file.
|
|
46
|
+
|
|
47
|
+
## Use an existing Codex/LiteLLM provider without sign-in
|
|
48
|
+
|
|
49
|
+
Source version `0.1.2` supports an opt-in custom Responses provider. Do not assume the published `0.1.0` or `0.1.1` package contains this change; install only a release whose notes include provider routing.
|
|
50
|
+
|
|
51
|
+
If your existing Codex configuration already defines a custom provider with `base_url` and `env_key`, using `wire_api = "responses"` (also the native default when omitted), add this to your global `codex-security.json`:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"codex": {
|
|
56
|
+
"useCodexConfig": true
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The default path is `$CODEX_HOME/config.toml` when `CODEX_HOME` is set and nonempty, otherwise `~/.codex/config.toml`. Exactly empty `CODEX_HOME` behaves as unset; whitespace-only, relative (including literal `~/...`) or control-character values fail clearly. `CODEX_HOME` must be an absolute directory; explicit `configFile` still supports `~/` expansion. Spaces in valid absolute directory names are preserved. A missing or invalid selected file fails without switching providers or falling back to ChatGPT.
|
|
62
|
+
|
|
63
|
+
For another location, add `"configFile": "/approved/path/config.toml"`; this takes precedence without inspecting `CODEX_HOME`. The existing `configFile`-only syntax also works. Add `"profile": "work"` to select `[profiles.work]` inside the imported file. To read a standalone `work.config.toml`, point `configFile` at that file instead. These are plugin import options, **not** SDK `profile` overrides. The plugin reads no Codex configuration without import opt-in, and does not import OpenCode provider settings. This feature is provider-agnostic for the supported custom HTTPS Responses + environment-key route; it is not support for every Codex transport, authentication method or feature.
|
|
64
|
+
|
|
65
|
+
Option combinations are explicit:
|
|
66
|
+
|
|
67
|
+
- `useCodexConfig: true` selects the standard location; an explicit `configFile` overrides it.
|
|
68
|
+
- `configFile` without `useCodexConfig` remains an import opt-in.
|
|
69
|
+
- Neither option, or `useCodexConfig: false` alone, preserves the default ChatGPT route.
|
|
70
|
+
- `useCodexConfig: false` with `configFile` is contradictory and rejected.
|
|
71
|
+
- Explicit `provider` settings work with import omitted/false, but cannot be combined with import enabled.
|
|
72
|
+
|
|
73
|
+
The resolved source path appears in the approval preview. Changing `CODEX_HOME` to select another file invalidates existing scan, policy and validation previews, even when the selected model/provider fields match.
|
|
74
|
+
|
|
75
|
+
The named environment key must already be available to the OpenCode service process. GUI launches and restarted services may not inherit terminal exports; a missing variable is a local setup blocker, not a request to display or copy its value. Never paste its value into chat, JSON, TOML, logs or screenshots. No sign-in is needed for this route. The plugin checks only the selected variable's presence after operation approval; the SDK consumes the value during the authorized operation. A missing key fails without falling back to ChatGPT or another key.
|
|
76
|
+
|
|
77
|
+
Only these fields are imported:
|
|
78
|
+
|
|
79
|
+
- Selected `model`, `model_reasoning_effort`, and `daybreak`.
|
|
80
|
+
- Selected `model_provider` and its provider's `base_url`, `env_key`, `wire_api`, and optional `requires_openai_auth = false`. The provider's display name is replaced by its ID. Root provider fields are inherited when the selected profile overrides only some fields.
|
|
81
|
+
|
|
82
|
+
Explicit global JSON model/reasoning/Daybreak options override the imported values, which override plugin defaults. To inherit the Codex model, remove an old explicit `codex.model` from the plugin JSON. Provider routing cannot be overridden by a session tool or project file. Do not combine `configFile` and `provider`.
|
|
83
|
+
|
|
84
|
+
The selected provider must use a custom ID. Built-in IDs such as `openai`, `ollama`, `lmstudio`, `amazon-bedrock`, and `gcp` have different authentication semantics and are rejected. An `OPENAI_BASE_URL` environment override or built-in OpenAI provider is not automatically converted into a custom route. Missing profiles, undefined providers, missing `env_key`, unsupported wire APIs, and `requires_openai_auth = true` fail closed.
|
|
85
|
+
|
|
86
|
+
Only credential-free HTTPS base URLs are supported. URL userinfo, query strings, fragments, encoded paths, inline keys, custom headers (including environment headers), auth commands, model catalogs and other provider extensions are rejected. Harmless `env_key_instructions`, `request_max_retries`, `stream_max_retries`, and `stream_idle_timeout_ms` hints are ignored, not forwarded or included in the digest. MCP servers, plugins, shell commands, hooks and security settings elsewhere in the source file are never copied. The import accepts a regular nonsymlink TOML file up to 256 KiB; parser errors do not echo source lines. The retained source digest covers only the validated selection, not raw TOML or credential values.
|
|
87
|
+
|
|
88
|
+
### Explicit provider alternative
|
|
89
|
+
|
|
90
|
+
If you do not want to import a file, configure the same non-secret routing fields directly:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"codex": {
|
|
95
|
+
"model": "gpt-5.6-sol",
|
|
96
|
+
"provider": {
|
|
97
|
+
"id": "litellm",
|
|
98
|
+
"baseUrl": "https://gateway.example.com/v1",
|
|
99
|
+
"envKey": "LITELLM_API_KEY",
|
|
100
|
+
"wireApi": "responses"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"scan": { "maxCostUsd": 1 }
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The hostname and model above are examples, not a working service or assurance of model access. Use your organization's approved gateway and its supported model name. Never substitute a credential value for `envKey` or embed credentials in the URL.
|
|
108
|
+
|
|
109
|
+
### Compatibility and cost limits
|
|
110
|
+
|
|
111
|
+
- Responses API support alone is insufficient. The gateway/model must support Codex Security's streaming, namespaced/function tools and any required web-search tools. No real LiteLLM endpoint has been tested for this change.
|
|
112
|
+
- Model aliases without SDK pricing fail the scan/policy cost guard. The plugin **does not remove the budget** to make them run. A recognized OpenAI model name's estimate is not proof of the gateway's billing rate or a hard cap. Do not rename a different model merely to obtain an estimate.
|
|
113
|
+
- Static finding validation still has **no SDK cost ceiling** and requires separate uncapped approval.
|
|
114
|
+
- Custom-provider Daybreak is not supported in this plugin version. Set `daybreak` false and omit `cyberAccessProgram` or use `standard`. Some current Codex proxy configurations support Daybreak, but their catalog/capability settings are not imported by this bounded implementation.
|
|
115
|
+
- Cloud publication, embedding configuration, patching, and fix verification are not enabled by this route. Native analytics are explicitly disabled for custom routes; unrelated telemetry settings are not imported. SDK private runtime state is still created during real operations. No-login does not mean no local state or no network activity.
|
|
116
|
+
- Previews and native permission prompts identify the selected provider/base URL, auth mode, key name, model and source selection. Source/context go to that gateway, which can route onward to its upstream providers. The plugin does not verify those upstream destinations.
|
|
41
117
|
|
|
42
118
|
## Daybreak is not a model
|
|
43
119
|
|
|
44
120
|
SDK 0.9.1 documents Daybreak as a separate toggle, available with Codex 0.163.0 or later. Set `codex.daybreak` to true to request it. Compatible OpenAI account access is still required; the toggle does not grant entitlement. A separate explicit `scan.cyberAccessProgram` selection takes precedence over the toggle. Omit that option when you want Codex to select the available program.
|
|
45
121
|
|
|
46
|
-
The plugin does not check entitlement, sign in, copy credentials or switch accounts while loading configuration. The existing Desktop Daybreak toggle does not configure the SDK's isolated runner.
|
|
122
|
+
The plugin does not check entitlement, sign in, copy credentials or switch accounts while loading configuration. The existing Desktop Daybreak toggle does not configure the SDK's isolated runner. The default OpenAI route still needs appropriately authorized dedicated sign-in and inference; an explicitly selected custom route uses its environment key instead. Neither model availability nor Daybreak entitlement has been verified on this account.
|
|
47
123
|
|
|
48
124
|
## Authorization and session inputs
|
|
49
125
|
|
|
@@ -55,7 +131,7 @@ No whole-conversation history is copied. Context files must be existing text doc
|
|
|
55
131
|
|
|
56
132
|
## Verification
|
|
57
133
|
|
|
58
|
-
Offline tests verify configuration propagation into constructor and scan options, ignored project config, changed-config rejection, input boundaries, model-tool preparation, host authorization allow/deny, and no SDK creation before approval. The actual OpenCode 2.2.6 host test uses an injected mock SDK. Mock findings and test settings do not prove model/Daybreak entitlement or real scan quality.
|
|
134
|
+
Offline tests also cover custom-provider propagation through scan/policy/validation, missing-key and no-ChatGPT fallback behavior, safe TOML selection, rejected credential-bearing routes, stale source/model/route/auth changes, and native permission refusal. They verify configuration propagation into constructor and scan options, ignored project config, changed-config rejection, input boundaries, model-tool preparation, host authorization allow/deny, and no SDK creation before approval. The actual OpenCode 2.2.6 host test uses an injected mock SDK. Mock findings and test settings do not prove model/Daybreak entitlement or real scan quality.
|
|
59
135
|
|
|
60
136
|
Official SDK sources checked:
|
|
61
137
|
|