@ycodium-ai/plugin-pentest 0.0.0-stage → 0.2.2944
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 +71 -2
- package/assets/icon.svg +8 -0
- package/assets/ui.js +178 -0
- package/dist/index.js +1164 -0
- package/locales/en.json +128 -0
- package/locales/zh-CN.json +128 -0
- package/package.json +115 -3
package/README.md
CHANGED
|
@@ -1,3 +1,72 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ycodium-ai/plugin-pentest
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Records an assessment on a session: one goal, the intents that follow it, the evidence and assets they name, and the findings those intents support. The session panel, the report, and a preset appear after you install it.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
A model tool writes the graph for the current session. A delegated session can only submit one record onto its parent. The parent session cannot submit. Other tools are left alone.
|
|
8
|
+
|
|
9
|
+
After the first goal, the session shows a panel with the graph, findings, assets, and a Markdown report. You can copy the report or download it. `pentest_report` also writes `pentest/report.md` in the session workspace when that workspace can be written. The panel keeps a window of the latest records. The report reads the full store.
|
|
10
|
+
|
|
11
|
+
The authorization field is stored with the goal and can be included in the report. It is an audit note. It does not grant permission.
|
|
12
|
+
|
|
13
|
+
Choose the Assessment record preset before the first turn. The protocol is added to every later turn on every agent. The phone, the desktop app, and the browser use the same panel.
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
A Ycodium server that loads plugin API version 4, including system prompt sections, tool guards, session projections, agent presets, workspace write, and the conversation, hero, and settings seats.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
From a checkout, build first, then install the directory:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
vp run --filter @ycodium-ai/plugin-pentest build
|
|
25
|
+
ycodium plugin add ./plugins/pentest
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
From a published package:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
ycodium plugin add @ycodium-ai/plugin-pentest
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The plugin is not part of the default install. Approve the declared permissions before it runs: a prompt section, a tool guard, writing the session workspace, two session projections, a preset, and three seats.
|
|
35
|
+
|
|
36
|
+
## Read this before installing
|
|
37
|
+
|
|
38
|
+
The prompt section is added in front of every later turn. The guard can refuse this plugin's own record tools. It does not refuse the host's other tools. The authorization note is not a permission.
|
|
39
|
+
|
|
40
|
+
Disabling the plugin removes the tools, the prompt, the preset, and the panel. Records already stored under the plugin's data directory stay there. Uninstalling does not delete them. A report file already written under `pentest/` stays in the workspace.
|
|
41
|
+
|
|
42
|
+
## Upgrading
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
ycodium plugin add @ycodium-ai/plugin-pentest@<version>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Installing a newer version replaces the running one. Records in the data directory remain.
|
|
49
|
+
|
|
50
|
+
## Limits
|
|
51
|
+
|
|
52
|
+
- The panel shows at most 200 nodes, assets, and edges. You can lower that to 20 in settings. The stored record is not trimmed.
|
|
53
|
+
- Delegated sessions only have `pentest_submit`. The decision and read tools are refused there. This plugin does not refuse host tools by name.
|
|
54
|
+
- The session panel stays hidden until this session has a goal. The preset card is on the new-session hero.
|
|
55
|
+
- The host does not tell the panel which preset the session selected, so the panel uses the per-session `mounted` projection.
|
|
56
|
+
- Shell, files, and delegation stay on the host's own tools. This plugin does not open a terminal.
|
|
57
|
+
- There is no command that rewrites past session events.
|
|
58
|
+
- The same tools and prompt are used for every built-in agent. Live model runs are not part of this package's checks.
|
|
59
|
+
|
|
60
|
+
## Developing
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
vp run --filter @ycodium-ai/plugin-pentest typecheck
|
|
64
|
+
vp run --filter @ycodium-ai/plugin-pentest test
|
|
65
|
+
vp run --filter @ycodium-ai/plugin-pentest build
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The server bundle externalizes `@ycodium-ai/plugin-api`. The UI bundle reads React from the host. `dist/` and `assets/ui.js` are build output.
|
|
69
|
+
|
|
70
|
+
## License
|
|
71
|
+
|
|
72
|
+
UNLICENSED.
|
package/assets/icon.svg
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
|
|
2
|
+
<rect x="3" y="4" width="26" height="24" rx="6" stroke="#0f766e" stroke-width="2"/>
|
|
3
|
+
<circle cx="10" cy="16" r="2.2" fill="#0f766e"/>
|
|
4
|
+
<circle cx="16" cy="11" r="2.2" fill="#0f766e"/>
|
|
5
|
+
<circle cx="22" cy="16" r="2.2" fill="#0f766e"/>
|
|
6
|
+
<circle cx="16" cy="21" r="2.2" fill="#0f766e"/>
|
|
7
|
+
<path d="M12 15.2 14.2 12.4M17.8 12.4 20 15.2M20 16.8 17.8 19.6M14.2 19.6 12 16.8" stroke="#0f766e" stroke-width="1.4"/>
|
|
8
|
+
</svg>
|
package/assets/ui.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
var f=`
|
|
2
|
+
.pt-root, .pt-root * { box-sizing: border-box; }
|
|
3
|
+
.pt-root {
|
|
4
|
+
--pt-fg: var(--foreground, #14221c);
|
|
5
|
+
--pt-bg: var(--background, #f4f7f5);
|
|
6
|
+
--pt-card: var(--card, #ffffff);
|
|
7
|
+
--pt-border: var(--border, #d5e0da);
|
|
8
|
+
--pt-muted: var(--muted-foreground, #5c6f66);
|
|
9
|
+
--pt-accent: var(--primary, #0f766e);
|
|
10
|
+
--pt-soft: var(--muted, #e7eeea);
|
|
11
|
+
--pt-danger: var(--destructive, #b42318);
|
|
12
|
+
color: var(--pt-fg);
|
|
13
|
+
font: 13px/1.45 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
min-width: 0;
|
|
17
|
+
min-height: 320px;
|
|
18
|
+
max-height: min(72vh, 760px);
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
background:
|
|
21
|
+
radial-gradient(720px 240px at 0% -20%, color-mix(in srgb, var(--pt-accent) 18%, transparent), transparent 60%),
|
|
22
|
+
var(--pt-bg);
|
|
23
|
+
border-bottom: 1px solid var(--pt-border);
|
|
24
|
+
}
|
|
25
|
+
.pt-root[data-embedded] { min-height: 100vh; max-height: none; border-bottom: 0; }
|
|
26
|
+
.pt-hero, .pt-settings {
|
|
27
|
+
color: var(--pt-fg);
|
|
28
|
+
font: 13px/1.45 ui-sans-serif, system-ui, sans-serif;
|
|
29
|
+
}
|
|
30
|
+
.pt-root button, .pt-root input, .pt-root select, .pt-hero button, .pt-settings button, .pt-settings input {
|
|
31
|
+
font: inherit;
|
|
32
|
+
color: inherit;
|
|
33
|
+
}
|
|
34
|
+
.pt-root button, .pt-settings button, .pt-hero button {
|
|
35
|
+
min-height: 32px;
|
|
36
|
+
border: 1px solid var(--pt-border, var(--border, #d5e0da));
|
|
37
|
+
border-radius: 999px;
|
|
38
|
+
background: color-mix(in srgb, var(--pt-card, var(--card, #fff)) 88%, transparent);
|
|
39
|
+
padding: 0 12px;
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
}
|
|
42
|
+
.pt-root button[data-primary] {
|
|
43
|
+
background: var(--pt-accent);
|
|
44
|
+
color: var(--background, #f4f7f5);
|
|
45
|
+
border-color: transparent;
|
|
46
|
+
}
|
|
47
|
+
.pt-root button[aria-pressed="true"], .pt-root [role="button"][aria-pressed="true"] {
|
|
48
|
+
border-color: var(--pt-accent);
|
|
49
|
+
box-shadow: inset 0 0 0 1px var(--pt-accent);
|
|
50
|
+
}
|
|
51
|
+
.pt-root .pt-tabs button[aria-pressed="true"] {
|
|
52
|
+
background: var(--primary);
|
|
53
|
+
color: var(--primary-foreground);
|
|
54
|
+
}
|
|
55
|
+
.pt-root button:focus-visible, .pt-root input:focus-visible, .pt-root select:focus-visible,
|
|
56
|
+
.pt-settings button:focus-visible, .pt-settings input:focus-visible, .pt-hero button:focus-visible {
|
|
57
|
+
outline: 2px solid var(--pt-accent, var(--primary, #0f766e));
|
|
58
|
+
outline-offset: 2px;
|
|
59
|
+
}
|
|
60
|
+
.pt-root button:disabled { color: var(--control-disabled-foreground); cursor: default; }
|
|
61
|
+
@media (pointer: coarse) {
|
|
62
|
+
.pt-root button, .pt-root select, .pt-settings button, .pt-hero button { min-height: 44px; }
|
|
63
|
+
}
|
|
64
|
+
.pt-root .pt-bar, .pt-root .pt-tabs, .pt-root .pt-row, .pt-settings .pt-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
65
|
+
.pt-root .pt-bar { justify-content: space-between; padding: 12px 14px 8px; }
|
|
66
|
+
.pt-root .pt-title, .pt-hero .pt-title, .pt-settings .pt-title { font-size: 15px; font-weight: 650; letter-spacing: -0.02em; }
|
|
67
|
+
.pt-root .pt-muted, .pt-hero .pt-muted, .pt-settings .pt-muted, .pt-card-view .pt-muted { color: var(--pt-muted, var(--muted-foreground, #5c6f66)); font-size: 12px; }
|
|
68
|
+
.pt-root .pt-goal { display: grid; gap: 2px; min-width: 0; }
|
|
69
|
+
.pt-root .pt-goal strong { font-size: 14px; }
|
|
70
|
+
.pt-root .pt-tabs { padding: 0 14px 10px; }
|
|
71
|
+
.pt-root .pt-body { display: grid; grid-template-columns: minmax(0, 1fr) 240px; min-height: 0; flex: 1; }
|
|
72
|
+
.pt-root .pt-main, .pt-root .pt-side { min-width: 0; min-height: 0; overflow: auto; }
|
|
73
|
+
.pt-root .pt-side { border-left: 1px solid var(--pt-border); padding: 12px; display: flex; flex-direction: column; gap: 10px; }
|
|
74
|
+
.pt-root .pt-columns { display: flex; gap: 12px; padding: 4px 14px 16px; min-width: min-content; }
|
|
75
|
+
.pt-root .pt-column { display: flex; flex-direction: column; gap: 8px; width: min(240px, 72vw); flex: none; }
|
|
76
|
+
.pt-root .pt-card, .pt-root .pt-asset {
|
|
77
|
+
text-align: start;
|
|
78
|
+
border-radius: 14px;
|
|
79
|
+
padding: 10px 12px;
|
|
80
|
+
background: color-mix(in srgb, var(--pt-card) 92%, transparent);
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-direction: column;
|
|
83
|
+
gap: 4px;
|
|
84
|
+
width: 100%;
|
|
85
|
+
cursor: pointer;
|
|
86
|
+
white-space: normal;
|
|
87
|
+
}
|
|
88
|
+
.pt-root .pt-card:focus-visible, .pt-root .pt-asset:focus-visible {
|
|
89
|
+
outline: 2px solid var(--pt-accent, var(--primary, #0f766e));
|
|
90
|
+
outline-offset: 2px;
|
|
91
|
+
}
|
|
92
|
+
.pt-root .pt-card small { color: var(--pt-muted); }
|
|
93
|
+
.pt-root .pt-kicker, .pt-card-view .pt-kicker { font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--pt-muted, var(--muted-foreground, #5c6f66)); }
|
|
94
|
+
.pt-root .pt-pill, .pt-hero .pt-pill {
|
|
95
|
+
display: inline-flex;
|
|
96
|
+
align-items: center;
|
|
97
|
+
min-height: 22px;
|
|
98
|
+
padding: 0 8px;
|
|
99
|
+
border-radius: 999px;
|
|
100
|
+
background: var(--pt-soft);
|
|
101
|
+
color: var(--pt-muted);
|
|
102
|
+
font-size: 11px;
|
|
103
|
+
}
|
|
104
|
+
.pt-root .pt-card[data-tone="critical"] { border-color: var(--pt-danger); }
|
|
105
|
+
.pt-root .pt-card[data-tone="high"] { border-color: var(--destructive); }
|
|
106
|
+
.pt-root .pt-card[data-tone="medium"] { border-color: var(--warning, var(--primary)); }
|
|
107
|
+
.pt-root .pt-card[data-tone="low"], .pt-root .pt-card[data-tone="goal"] { border-color: var(--pt-accent); }
|
|
108
|
+
.pt-root .pt-list, .pt-root .pt-tree { display: flex; flex-direction: column; gap: 8px; padding: 0 14px 16px; }
|
|
109
|
+
.pt-root .pt-finding, .pt-root .pt-asset, .pt-root .pt-report, .pt-root .pt-detail, .pt-card-view {
|
|
110
|
+
border: 1px solid var(--pt-border);
|
|
111
|
+
border-radius: 14px;
|
|
112
|
+
background: color-mix(in srgb, var(--pt-card) 92%, transparent);
|
|
113
|
+
padding: 12px;
|
|
114
|
+
}
|
|
115
|
+
.pt-root .pt-finding h3, .pt-root .pt-detail h3, .pt-card-view h3 { margin: 0; font-size: 14px; }
|
|
116
|
+
.pt-root .pt-finding ol, .pt-root .pt-detail ol { margin: 8px 0 0; padding-left: 18px; }
|
|
117
|
+
.pt-root .pt-report pre {
|
|
118
|
+
margin: 0;
|
|
119
|
+
white-space: pre-wrap;
|
|
120
|
+
font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
121
|
+
}
|
|
122
|
+
.pt-root .pt-banner {
|
|
123
|
+
margin: 0 14px 8px;
|
|
124
|
+
padding: 8px 10px;
|
|
125
|
+
border-radius: 10px;
|
|
126
|
+
background: color-mix(in srgb, var(--pt-accent) 12%, var(--pt-card));
|
|
127
|
+
}
|
|
128
|
+
.pt-hero, .pt-settings {
|
|
129
|
+
display: flex;
|
|
130
|
+
flex-direction: column;
|
|
131
|
+
gap: 8px;
|
|
132
|
+
padding: 12px;
|
|
133
|
+
border: 1px solid var(--border, #d5e0da);
|
|
134
|
+
border-radius: 16px;
|
|
135
|
+
background: var(--card, #fff);
|
|
136
|
+
color: var(--foreground, #14221c);
|
|
137
|
+
}
|
|
138
|
+
.pt-hero .pt-chips { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
139
|
+
.pt-root .pt-tree-item { display: flex; flex-direction: column; gap: 6px; }
|
|
140
|
+
.pt-root .pt-filter, .pt-settings .pt-filter { min-height: 32px; border-radius: 10px; border: 1px solid var(--pt-border, var(--border, #d5e0da)); background: var(--pt-card, var(--card, #fff)); padding: 0 8px; }
|
|
141
|
+
.pt-seat {
|
|
142
|
+
border-bottom: 1px solid var(--border, #d5e0da);
|
|
143
|
+
background: var(--card, #fff);
|
|
144
|
+
color: var(--foreground, #14221c);
|
|
145
|
+
}
|
|
146
|
+
.pt-seat-summary {
|
|
147
|
+
cursor: pointer;
|
|
148
|
+
display: flex;
|
|
149
|
+
align-items: center;
|
|
150
|
+
gap: 6px;
|
|
151
|
+
padding: 8px 12px;
|
|
152
|
+
font-size: 12px;
|
|
153
|
+
letter-spacing: 0.04em;
|
|
154
|
+
text-transform: uppercase;
|
|
155
|
+
}
|
|
156
|
+
.pt-seat-chevron {
|
|
157
|
+
width: 14px;
|
|
158
|
+
height: 14px;
|
|
159
|
+
flex: none;
|
|
160
|
+
}
|
|
161
|
+
.pt-seat-summary:not([data-panel-open]) .pt-seat-chevron {
|
|
162
|
+
transform: rotate(-90deg);
|
|
163
|
+
}
|
|
164
|
+
.pt-seat-body {
|
|
165
|
+
max-height: min(240px, 32vh);
|
|
166
|
+
overflow: auto;
|
|
167
|
+
}
|
|
168
|
+
/* \u624B\u673A\u4E0A\u5185\u5D4C\u7684\u5EA7\u4F4D\u6309\u5185\u5BB9\u5B9A\u9AD8\uFF08\u5BBF\u4E3B\u7ED9 html \u6253 data-fit-content\uFF09\uFF1A\u90A3\u91CC\u7684\u89C6\u53E3\u5C31\u662F\u5EA7\u4F4D\u81EA\u5DF1\u4E0A\u4E00\u6B21\u62A5\u7684
|
|
169
|
+
\u9AD8\u5EA6\uFF0C\u6309 vh \u5C01\u9876\u4F1A\u8BA9\u9AD8\u5EA6\u4E00\u8F6E\u4E00\u8F6E\u5F80\u4E0B\u7F29\uFF0C\u6700\u540E\u6B63\u6587\u53EA\u5269\u4E00\u6761\u7F1D\u3002\u53EA\u6309\u50CF\u7D20\u5C01\u9876\u3002 */
|
|
170
|
+
html[data-fit-content] .pt-seat-body { max-height: 240px; }
|
|
171
|
+
.pt-seat .pt-root { min-height: 0; max-height: none; border: 0; border-radius: 0; }
|
|
172
|
+
.pt-seat > .pt-muted { margin: 0; padding: 0 12px 10px; color: var(--muted-foreground, #5c6f66); }
|
|
173
|
+
@media (max-width: 800px) {
|
|
174
|
+
.pt-root .pt-body { grid-template-columns: 1fr; }
|
|
175
|
+
.pt-root .pt-side { border-left: 0; border-top: 1px solid var(--pt-border); }
|
|
176
|
+
.pt-root { max-height: none; }
|
|
177
|
+
}
|
|
178
|
+
`;var{jsx:n,jsxs:i,Fragment:x}=window.__ycodiumPluginHost.jsxRuntime;function A(t){let e=st(t.presentation),r=t.colors;return i("article",{className:"pt-card-view",style:r===void 0?void 0:{color:r.foreground,background:r.surface,borderColor:r.border},children:[n("style",{children:f}),n("div",{className:"pt-kicker",children:t.t("board.title")}),n("h3",{children:e===null?t.t("card.summary"):t.t("card.recorded",{id:e.id})}),e!==null&&e.target.length>0?n("p",{children:e.target}):null,e!==null?n("p",{className:"pt-muted",children:t.t("board.counts",{intents:e.counts.intents,facts:e.counts.facts,findings:e.counts.findings,assets:e.counts.assets})}):null]})}function st(t){let e=L(t);if(e===null||e.kind!=="pentest")return null;let r=L(e.counts);return r===null?null:{id:typeof e.id=="string"?e.id:"",target:typeof e.target=="string"?e.target:"",counts:{intents:N(r.intents),facts:N(r.facts),findings:N(r.findings),assets:N(r.assets)}}}function L(t){return ct(t)?t:null}function ct(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function N(t){return typeof t=="number"?t:0}var ut=window.__ycodiumPluginHost.react;var{Activity:Rt,Children:_t,Component:Ot,Fragment:Lt,Profiler:At,PureComponent:Bt,StrictMode:zt,Suspense:Dt,__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE:Mt,__COMPILER_RUNTIME:Ht,act:Ut,cache:Gt,cacheSignal:Wt,captureOwnerStack:Vt,cloneElement:Ft,createContext:B,createElement:T,createRef:$t,forwardRef:jt,isValidElement:Jt,lazy:Yt,memo:Kt,startTransition:qt,unstable_useCacheRefresh:Qt,use:z,useActionState:Xt,useCallback:Zt,useContext:te,useDebugValue:ee,useDeferredValue:ne,useEffect:oe,useEffectEvent:re,useId:ae,useImperativeHandle:ie,useInsertionEffect:le,useLayoutEffect:de,useMemo:D,useOptimistic:se,useReducer:ce,useRef:ue,useState:y,useSyncExternalStore:pe,useTransition:ge,version:me}=ut;var pt="pentest";var M="pentest",gt=["add_goal","add_intent","add_fact","add_finding","add_asset","state","graph","report","submit"],H="submit",U=t=>`${pt}_${t}`,ye=new Set(gt.filter(t=>t!==H).map(t=>U(t))),be=U(H);var G=B(null);function C(t){return n(G,{value:t.bridge,children:t.children})}var mt=new Set(["Collapsible","CollapsiblePanel","CollapsibleTrigger"]);function u(t){let e=r=>{let d=z(G)?.ui?.[t];return d===void 0?mt.has(t)?T("div",{className:r.className},r.children):null:T(d,r)};return e.displayName=t,e}var v=u("Button"),W=u("Input"),S=u("Label"),V=u("Select"),P=u("SelectItem"),F=u("SelectPopup"),$=u("SelectTrigger"),j=u("SelectValue"),J=u("SearchInput"),Y=u("Switch"),K=u("Collapsible"),q=u("CollapsibleTrigger"),Q=u("CollapsiblePanel"),w=u("EmptyInline"),X=u("ChevronDown");function I(t){let e=()=>t.onClick(),r=o=>{o.key!=="Enter"&&o.key!==" "||(o.preventDefault(),e())};return n("div",{role:"button",tabIndex:0,className:t.className,"data-tone":t.tone,"aria-pressed":t.selected,onClick:e,onKeyDown:r,children:t.children})}var ft=/[.!?。!?]$/u;function Z(t){let e=t.trimEnd();return ft.test(e)?e:`${e}.`}function E(t){if(typeof t!="object"||t===null)return{present:!1,value:null};let e=t;return{present:e.present===!0,value:e.value??null}}function k(t){if(typeof t!="object"||t===null)return null;let e=t,r=e.prefs;return typeof e.mounted!="boolean"||typeof e.report!="string"||typeof r!="object"||r===null?null:{mounted:e.mounted,graph:R(e.graph),related:Array.isArray(e.related)?e.related.flatMap(o=>{if(typeof o!="object"||o===null)return[];let a=o;return typeof a.threadId!="string"||typeof a.title!="string"?[]:[{threadId:a.threadId,title:a.title}]}):[],prefs:{windowLimit:typeof r.windowLimit=="number"?r.windowLimit:200,includeAuthorization:r.includeAuthorization!==!1},report:e.report}}function R(t){if(typeof t!="object"||t===null)return null;let e=t;return typeof e.goal!="object"||e.goal===null||!Array.isArray(e.nodes)||!Array.isArray(e.assets)||!Array.isArray(e.edges)?null:e}function tt(t){let e=new Map;t.goal!==null&&e.set(t.goal.id,0);for(let d=0;d<t.edges.length+1;d+=1)for(let s of t.edges){if(s.kind==="parent")continue;let g=e.get(s.sourceId);if(g===void 0)continue;let m=g+1,p=e.get(s.targetId);(p===void 0||m>p)&&e.set(s.targetId,m)}let r=new Map,o=(d,s)=>{let g=r.get(s)??[];g.push(d),r.set(s,g)};t.goal!==null&&o({id:t.goal.id,kind:"goal",title:t.goal.target,subtitle:t.goal.objective,tone:"goal"},0);for(let d of t.nodes)o(yt(d),e.get(d.id)??1);return[...r.keys()].sort((d,s)=>d-s).map(d=>r.get(d)??[])}function et(t,e){return t.edges.filter(r=>r.sourceId===e||r.targetId===e)}function _(t,e){let r=new Set(t.edges.filter(o=>o.kind==="parent"&&(e===null||o.sourceId===e)).map(o=>o.targetId));if(e===null){let o=new Set(t.edges.filter(a=>a.kind==="parent").map(a=>a.targetId));return t.assets.filter(a=>!o.has(a.id))}return t.assets.filter(o=>r.has(o.id))}function yt(t){return t.kind==="intent"?{id:t.id,kind:"intent",title:t.title,subtitle:t.detail,tone:"intent"}:t.kind==="fact"?{id:t.id,kind:"fact",title:t.detail,subtitle:t.factKind,tone:"fact"}:{id:t.id,kind:"finding",title:t.title,subtitle:t.severity,tone:t.severity}}function nt(t){let[e,r]=y("explore"),[o,a]=y(null),[d,s]=y("all"),[g,m]=y("tree"),[p,b]=y(""),l=t.data.graph,h=["explore","findings","assets","report"];return i("section",{className:"pt-root","data-embedded":t.embedded?"":void 0,children:[n("style",{children:f}),i("header",{className:"pt-bar",children:[i("div",{className:"pt-goal",children:[n("strong",{children:l?.goal?.target??t.t("board.empty")}),l?.goal?n("span",{className:"pt-muted",children:l.goal.objective}):null]}),l?n("span",{className:"pt-muted",children:t.t("board.counts",{intents:l.totals.intents,facts:l.totals.facts,findings:l.totals.findings,assets:l.totals.assets})}):null]}),n("div",{className:"pt-tabs",role:"tablist",children:h.map(c=>n(v,{size:"xs",type:"button",role:"tab","aria-selected":e===c,"aria-pressed":e===c,variant:e===c?"default":"outline",onClick:()=>r(c),children:t.t(`board.tabs.${c}`)},c))}),l?.truncated?n("p",{className:"pt-banner",children:t.t("board.window",{shown:l.nodes.length+l.assets.length,total:l.totals.intents+l.totals.facts+l.totals.findings+l.totals.assets})}):null,i("div",{className:"pt-body",children:[i("div",{className:"pt-main",role:"tabpanel",children:[l===null?n(w,{title:t.t("board.empty")}):null,l!==null&&e==="explore"?n(bt,{t:t.t,graph:l,selected:o,onSelect:a}):null,l!==null&&e==="findings"?n(ht,{t:t.t,graph:l,severity:d,onSeverity:s,onSelect:a}):null,l!==null&&e==="assets"?n(vt,{t:t.t,graph:l,mode:g,query:p,onMode:m,onQuery:b,onSelect:a}):null,e==="report"?n(xt,{t:t.t,markdown:t.data.report,onCopy:()=>t.onCopy(t.data.report),onDownload:()=>t.onDownload(t.data.report)}):null]}),i("aside",{className:"pt-side",children:[n(wt,{t:t.t,graph:l,selected:o,onClose:()=>a(null)}),i("div",{children:[n("div",{className:"pt-kicker",children:t.t("board.related")}),t.data.related.length===0?n("p",{className:"pt-muted",children:t.t("board.relatedEmpty")}):null,t.data.related.map(c=>n(v,{size:"xs",variant:"outline",type:"button",onClick:()=>t.onOpenThread(c.threadId),children:c.title||t.t("board.open")},c.threadId))]}),l?.goal&&l.goal.authorization.length>0?i("p",{className:"pt-muted",children:[t.t("board.authorization"),": ",Z(l.goal.authorization)," ",t.t("board.authorizationHint")]}):null]})]})]})}function bt(t){let e=D(()=>tt(t.graph),[t.graph]);return e.length===0?n("p",{className:"pt-list pt-muted",children:t.t("explore.empty")}):n("div",{className:"pt-columns",children:e.map((r,o)=>n("div",{className:"pt-column",children:r.map(a=>i(I,{className:"pt-card",tone:a.tone,selected:t.selected===a.id,onClick:()=>t.onSelect(a.id),children:[n("span",{className:"pt-kicker",children:t.t(`node.${a.kind}`)}),n("strong",{children:a.title}),a.subtitle.length>0?n("small",{children:a.subtitle}):null,n("span",{className:"pt-row",children:et(t.graph,a.id).slice(0,3).map(d=>n("span",{className:"pt-pill",children:t.t(`explore.edge.${d.kind}`)},d.id))})]},a.id))},r[0]?.id??String(o)))})}function ht(t){let e=t.graph.nodes.filter(o=>o.kind==="finding"),r=t.severity==="all"?e:e.filter(o=>o.severity===t.severity);return i("div",{className:"pt-list",children:[i(S,{className:"pt-row",children:[t.t("findings.filter"),i(V,{value:t.severity,onValueChange:o=>t.onSeverity(o),children:[n($,{size:"xs","aria-label":t.t("findings.filter"),children:n(j,{})}),i(F,{children:[n(P,{value:"all",children:t.t("findings.all")}),["critical","high","medium","low","info"].map(o=>n(P,{value:o,children:t.t(`severity.${o}`)},o))]})]})]}),r.length===0?n(w,{title:t.t("findings.empty")}):null,r.map(o=>i("article",{className:"pt-finding",children:[i("div",{className:"pt-row",children:[n("span",{className:"pt-pill",children:t.t(`severity.${o.severity}`)}),n("h3",{children:o.title})]}),n("p",{className:"pt-muted",children:o.intentId}),o.description.length>0?n("p",{children:o.description}):null,n("div",{className:"pt-kicker",children:t.t("node.steps")}),n("ol",{children:o.steps.map(a=>n("li",{children:a},a))}),o.affectedAssetId?n(v,{size:"xs",variant:"outline",type:"button",onClick:()=>t.onSelect(o.affectedAssetId??o.id),children:t.t("findings.affected")}):null]},o.id))]})}function vt(t){let e=t.query.trim().toLowerCase(),r=t.graph.assets.filter(o=>e.length===0||o.value.toLowerCase().includes(e));return i("div",{className:"pt-list",children:[i("div",{className:"pt-row",children:[n(v,{size:"xs",variant:"outline",type:"button","aria-pressed":t.mode==="list",onClick:()=>t.onMode("list"),children:t.t("assets.list")}),n(v,{size:"xs",variant:"outline",type:"button","aria-pressed":t.mode==="tree",onClick:()=>t.onMode("tree"),children:t.t("assets.tree")}),n(J,{value:t.query,size:"sm",variant:"ghost","aria-label":t.t("assets.filter"),placeholder:t.t("assets.filter"),onValueChange:t.onQuery})]}),r.length===0?n(w,{title:t.t("assets.empty")}):null,t.mode==="list"?r.map(o=>i(I,{className:"pt-asset",onClick:()=>t.onSelect(o.id),children:[n("span",{className:"pt-kicker",children:t.t(`assetType.${o.type}`)}),n("strong",{children:o.value}),o.meta.length>0?n("small",{className:"pt-muted",children:o.meta}):null]},o.id)):_(t.graph,null).map(o=>n(ot,{t:t.t,graph:t.graph,id:o.id,depth:0,onSelect:t.onSelect},o.id))]})}function ot(t){let e=t.graph.assets.find(r=>r.id===t.id);return e===void 0?null:i("div",{className:"pt-tree-item",style:{marginLeft:t.depth*14},children:[i(I,{className:"pt-asset",onClick:()=>t.onSelect(e.id),children:[n("span",{className:"pt-kicker",children:t.t(`assetType.${e.type}`)}),n("strong",{children:e.value})]}),_(t.graph,e.id).map(r=>n(ot,{t:t.t,graph:t.graph,id:r.id,depth:t.depth+1,onSelect:t.onSelect},r.id))]})}function xt(t){return i("div",{className:"pt-list",children:[i("div",{className:"pt-row",children:[n(v,{size:"xs",type:"button",onClick:t.onCopy,children:t.t("report.copy")}),n(v,{size:"xs",variant:"outline",type:"button",onClick:t.onDownload,children:t.t("report.download")})]}),n("div",{className:"pt-report",children:n("pre",{children:t.markdown.length>0?t.markdown:t.t("report.empty")})})]})}function wt(t){if(t.graph===null||t.selected===null)return n("p",{className:"pt-muted",children:t.t("explore.empty")});let e=t.graph.goal?.id===t.selected?t.graph.goal:null,r=t.graph.nodes.find(a=>a.id===t.selected),o=t.graph.assets.find(a=>a.id===t.selected);return i("div",{className:"pt-detail",children:[i("div",{className:"pt-row",children:[n("span",{className:"pt-kicker",children:t.selected}),n(v,{size:"xs",variant:"outline",type:"button",onClick:t.onClose,children:t.t("node.close")})]}),e?i(x,{children:[n("h3",{children:e.target}),n("p",{children:e.objective})]}):null,r?.kind==="intent"?i(x,{children:[n("h3",{children:r.title}),n("p",{children:r.detail})]}):null,r?.kind==="fact"?i(x,{children:[n("h3",{children:t.t(`factKind.${r.factKind}`)}),n("p",{children:r.detail}),n("p",{className:"pt-muted",children:t.t("node.confidence",{value:r.confidence})})]}):null,r?.kind==="finding"?i(x,{children:[n("h3",{children:r.title}),n("p",{children:r.description}),n("ol",{children:r.steps.map(a=>n("li",{children:a},a))})]}):null,o?i(x,{children:[n("h3",{children:o.value}),n("p",{className:"pt-muted",children:t.t(`assetType.${o.type}`)}),o.meta.length>0?n("p",{children:o.meta}):null]}):null]})}function rt(t){return i("section",{className:"pt-hero",children:[n("style",{children:f}),n("strong",{className:"pt-title",children:t.t("hero.title")}),n("p",{className:"pt-muted",children:t.target===null?t.t("hero.body"):t.t("hero.current",{target:t.target})}),i("div",{className:"pt-chips",children:[n("span",{className:"pt-pill",children:t.t("hero.goal")}),n("span",{className:"pt-pill",children:t.t("hero.evidence")}),n("span",{className:"pt-pill",children:t.t("hero.assets")}),n("span",{className:"pt-pill",children:t.t("hero.findings")})]})]})}function at(t){let[e,r]=y(""),o=t.data?.prefs;return i("section",{className:"pt-settings",children:[n("style",{children:f}),n("strong",{className:"pt-title",children:t.t("settings.title")}),n("p",{className:"pt-muted",children:t.t("settings.lead")}),i(S,{className:"pt-row",children:[t.t("settings.window"),n(W,{type:"number",min:20,max:200,"aria-label":t.t("settings.window"),value:o?.windowLimit??200,onChange:a=>{let d=Number(a.target.value);Number.isFinite(d)&&(t.onSave({windowLimit:d}),r(t.t("settings.saved")))}})]}),n("p",{className:"pt-muted",children:t.t("settings.windowHint")}),i(S,{className:"pt-row",children:[n(Y,{checked:o?.includeAuthorization!==!1,"aria-label":t.t("settings.authorization"),onCheckedChange:a=>{t.onSave({includeAuthorization:a}),r(t.t("settings.saved"))}}),t.t("settings.authorization")]}),e.length>0?n("p",{className:"pt-muted",children:e}):null]})}function it(t){let e=t.bridge.i18n.usePluginTranslation(),r=t.environmentId??null,o=t.threadId??null,a=r===null?{}:{environmentId:r},d=t.bridge.commands.useSubscription("ycodium.sessionProjection",{name:"mounted",threadId:o&&o.length>0?o:"_"},a),s=t.bridge.commands.useSubscription("live",{threadId:o&&o.length>0?o:"_"},a),g=t.bridge.commands.useSubscription("ycodium.sessionProjection",{name:"graph",threadId:o&&o.length>0?o:"_"},a),m=E(d.data),p=k(s.data),b=p?.graph??R(E(g.data).value);if(t.presetId!==M||o===null||o.length===0)return null;let l=m.present&&m.value===!0||p?.mounted===!0,h=p??(l?{mounted:!0,graph:b,related:[],prefs:{windowLimit:200,includeAuthorization:!0},report:""}:null);return n(C,{bridge:t.bridge,children:i(K,{className:"pt-seat",defaultOpen:!0,children:[n("style",{children:f}),i(q,{className:"pt-seat-summary",children:[n(X,{className:"pt-seat-chevron"}),e("board.title")]}),n(Q,{children:n("div",{className:"pt-seat-body",children:l&&h!==null&&(h.graph!==null||p?.report!==void 0)?n(nt,{t:e,data:{...h,graph:h.graph??b},embedded:kt(),onOpenThread:c=>{r!==null&&t.bridge.openThread({environmentId:r,threadId:c})},onCopy:c=>{let O=navigator.clipboard;if(O===void 0){t.bridge.notify(e("report.copyFailed"),"warning");return}O.writeText(c).then(()=>t.bridge.notify(e("report.copied"),"success"),()=>t.bridge.notify(e("report.copyFailed"),"warning"))},onDownload:c=>St(c,e("report.download"))}):n(w,{title:e(p===null?"board.loading":"board.empty")})})})]})})}function lt(t){let e=t.bridge.i18n.usePluginTranslation(),r=t.environmentId??null,o=t.threadId??null,a=r===null?{}:{environmentId:r},d=t.bridge.commands.useSubscription("live",{threadId:o&&o.length>0?o:"_"},a),s=k(d.data);return n(C,{bridge:t.bridge,children:n(rt,{t:e,target:s?.graph?.goal?.target??null})})}function dt(t){let e=t.bridge.i18n.usePluginTranslation(),r=t.environmentId??null,o=t.threadId??null,a=r===null?{}:{environmentId:r},d=t.bridge.commands.useSubscription("live",{threadId:o&&o.length>0?o:"_"},a),[s,g]=y(null),m=s??k(d.data);return n(C,{bridge:t.bridge,children:n(at,{t:e,data:m,onSave:p=>{t.bridge.commands.invoke("preferences",{...p,...o?{threadId:o}:{}},a).then(b=>{let l=k(b);if(m!==null&&l===null&&typeof b=="object"&&b!==null){let h=b.prefs;h!==void 0&&g({...m,prefs:h})}})}})})}function St(t,e){let r=new Blob([t],{type:"text/markdown;charset=utf-8"}),o=URL.createObjectURL(r),a=document.createElement("a");a.href=o,a.download=e.endsWith(".md")?e:"assessment-record.md",a.click(),URL.revokeObjectURL(o)}function kt(){return typeof window<"u"&&"ReactNativeWebView"in window}function Nt(t){return{views:{card(e){return n(A,{...e,t:t.i18n.usePluginTranslation()})}},slots:[{name:"conversation.view",order:20,component(e){return n(it,{bridge:t,...e})}},{name:"conversation.hero.agentPreset",order:20,component(e){return n(lt,{bridge:t,...e})}},{name:"settings.section",order:20,component(e){return n(dt,{bridge:t,...e})}}]}}export{Nt as default};
|