@codeyam-editor/codeyam-editor 0.1.13 → 0.1.14-staging.ge9fdd0f
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/npm/fleet-build-data.js +22 -2
- package/npm/scenario-check.js +149 -5
- package/package.json +5 -5
- package/ui/dist/assets/{ContainerInspector-DKH4LjcY.js → ContainerInspector-DhV9O4qu.js} +1 -1
- package/ui/dist/assets/{EditorShell-BwNMzsnF.js → EditorShell-LcMPxnNk.js} +3 -3
- package/ui/dist/assets/{ScenarioDataPanel-CtYXcbIr.js → ScenarioDataPanel-DSW29BTV.js} +1 -1
- package/ui/dist/assets/{ScenarioDataPanelFullPage-DrhY8Okl.js → ScenarioDataPanelFullPage-DIm-kvtz.js} +1 -1
- package/ui/dist/assets/{ScenarioRenderer-kBIhG1qo.js → ScenarioRenderer-DDT3dneh.js} +1 -1
- package/ui/dist/assets/{index-mgNPDFlH.js → index-BDc44VP_.js} +2 -2
- package/ui/dist/index.html +1 -1
package/npm/fleet-build-data.js
CHANGED
|
@@ -55,6 +55,24 @@ function buildVmEnvelope(v, ctx) {
|
|
|
55
55
|
// a definite `false` that no probe had ever established.
|
|
56
56
|
...fr.normalizeReachability(v),
|
|
57
57
|
hasSession: !!v.hasSession,
|
|
58
|
+
// The three session-age signals the codeyam-fleet-latest Phase 1b idle
|
|
59
|
+
// triage reads by name. server.js computes all three per poll onto `v`, but
|
|
60
|
+
// they were never copied here, so /data carried none of them and the
|
|
61
|
+
// procedure's ACTIVE/ENDED table fell through to UNCLEAR on every HOLD VM.
|
|
62
|
+
// `sessionIdleSeconds`: seconds since the session last did anything, or null
|
|
63
|
+
// when the editor is too old to report it — never coerced to 0, which would
|
|
64
|
+
// read as "just active".
|
|
65
|
+
sessionIdleSeconds:
|
|
66
|
+
typeof v.sessionIdleSeconds === 'number' && Number.isFinite(v.sessionIdleSeconds)
|
|
67
|
+
? v.sessionIdleSeconds
|
|
68
|
+
: null,
|
|
69
|
+
// 'none' | 'active' | 'stale' | 'unknown' (npm/fleet-session-activity.js).
|
|
70
|
+
// An unpolled VM has no verdict at all; it reads 'unknown', which blocks
|
|
71
|
+
// like 'active', so an absent signal can never clear a VM as stale.
|
|
72
|
+
sessionActivity: v.sessionActivity || 'unknown',
|
|
73
|
+
// Boolean twin of the `session-wedged:` prose in degradedReasons, so a
|
|
74
|
+
// program can read it without parsing English.
|
|
75
|
+
sessionWedged: v.sessionWedged === true,
|
|
58
76
|
// Three-state: true = broker confirmed up, false = confirmed down, null =
|
|
59
77
|
// editor unreachable so broker state is unknown. Never conflate "down" with
|
|
60
78
|
// "unreachable" — that mismatch is what made the card show "broker down"
|
|
@@ -183,14 +201,16 @@ function buildVmEnvelope(v, ctx) {
|
|
|
183
201
|
};
|
|
184
202
|
}
|
|
185
203
|
|
|
186
|
-
// The fields the card UI
|
|
204
|
+
// The fields the card UI — and the codeyam-fleet-latest idle triage, which reads
|
|
205
|
+
// /data directly — depend on being present in every /data VM entry. This
|
|
187
206
|
// is the contract `buildVmEnvelope` must satisfy: the regression that prompted
|
|
188
207
|
// this module was a field the card read but the envelope didn't emit, so the
|
|
189
208
|
// test asserts the envelope keys are a superset of this list. Adding a field the
|
|
190
209
|
// card renders means adding it here AND in buildVmEnvelope — the test fails loud
|
|
191
210
|
// if you do one without the other.
|
|
192
211
|
const REQUIRED_CARD_FIELDS = [
|
|
193
|
-
'n', 'url', 'previewUrl', 'appPort', 'previewServing', 'previewIngress', 'reachable', 'reachableSource', 'hasSession',
|
|
212
|
+
'n', 'url', 'previewUrl', 'appPort', 'previewServing', 'previewIngress', 'reachable', 'reachableSource', 'hasSession',
|
|
213
|
+
'sessionIdleSeconds', 'sessionActivity', 'sessionWedged', 'brokerLive', 'brokerStatus',
|
|
194
214
|
'awaitingInput', 'needsCleanup', 'feature', 'selectedPlan', 'step', 'mode', 'label', 'cycleClosed', 'status', 'orphan',
|
|
195
215
|
'degradedReasons', 'setupSteps', 'attentionReasons',
|
|
196
216
|
'isHead', 'headHolderUnreachable', 'queuePos', 'queueLen',
|
package/npm/scenario-check.js
CHANGED
|
@@ -90,6 +90,110 @@ function isTransientLaunchCrash(error) {
|
|
|
90
90
|
);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
// Stable first token of the error a missing-system-library launch failure is
|
|
94
|
+
// rethrown as. The Rust side keys on it (`scenario_check.rs`
|
|
95
|
+
// `CAPTURE_BROWSER_DEPS_MISSING_MARKER`) to turn the failure into a blocked
|
|
96
|
+
// precondition, so the two spellings must stay greppable from each other.
|
|
97
|
+
const CAPTURE_BROWSER_DEPS_MISSING_MARKER = "CODEYAM_CAPTURE_BROWSER_DEPS_MISSING";
|
|
98
|
+
// The two shapes a missing shared library takes in a launch error: the dynamic
|
|
99
|
+
// loader's own line (Chromium starts and dies), and Playwright's host
|
|
100
|
+
// validation box listing every missing library before it even spawns.
|
|
101
|
+
const MISSING_SHARED_LIBRARY_PATTERNS = [
|
|
102
|
+
"error while loading shared libraries",
|
|
103
|
+
"Host system is missing dependencies",
|
|
104
|
+
];
|
|
105
|
+
const SHARED_LIBRARY_NAME_PATTERN = /\blib[\w+-]+(?:\.[\w+-]+)*?\.so(?:\.\d+)*/g;
|
|
106
|
+
const PLAYWRIGHT_INSTALL_DEPS_COMMAND = "npx playwright install-deps chromium";
|
|
107
|
+
// Nix package for the libraries Chromium most often lacks on Replit, keyed by
|
|
108
|
+
// the stem before `.so`. A library outside this map still gets a remedy — it is
|
|
109
|
+
// just named without a package suggestion.
|
|
110
|
+
const REPLIT_NIX_PACKAGE_FOR_LIBRARY = {
|
|
111
|
+
"libglib-2.0": "pkgs.glib",
|
|
112
|
+
"libgobject-2.0": "pkgs.glib",
|
|
113
|
+
"libgio-2.0": "pkgs.glib",
|
|
114
|
+
libnss3: "pkgs.nss",
|
|
115
|
+
libnssutil3: "pkgs.nss",
|
|
116
|
+
libsmime3: "pkgs.nss",
|
|
117
|
+
libnspr4: "pkgs.nspr",
|
|
118
|
+
"libatk-1.0": "pkgs.atk",
|
|
119
|
+
"libatk-bridge-2.0": "pkgs.at-spi2-atk",
|
|
120
|
+
"libatspi": "pkgs.at-spi2-core",
|
|
121
|
+
libcups: "pkgs.cups",
|
|
122
|
+
"libdbus-1": "pkgs.dbus",
|
|
123
|
+
libdrm: "pkgs.libdrm",
|
|
124
|
+
libgbm: "pkgs.mesa",
|
|
125
|
+
libxkbcommon: "pkgs.libxkbcommon",
|
|
126
|
+
libasound: "pkgs.alsa-lib",
|
|
127
|
+
"libpango-1.0": "pkgs.pango",
|
|
128
|
+
libcairo: "pkgs.cairo",
|
|
129
|
+
libexpat: "pkgs.expat",
|
|
130
|
+
libX11: "pkgs.xorg.libX11",
|
|
131
|
+
libXcomposite: "pkgs.xorg.libXcomposite",
|
|
132
|
+
libXdamage: "pkgs.xorg.libXdamage",
|
|
133
|
+
libXext: "pkgs.xorg.libXext",
|
|
134
|
+
libXfixes: "pkgs.xorg.libXfixes",
|
|
135
|
+
libXrandr: "pkgs.xorg.libXrandr",
|
|
136
|
+
libxcb: "pkgs.xorg.libxcb",
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Does this launch error say the host is missing a shared library Chromium
|
|
140
|
+
// needs? Not retryable and not fixed by downloading the browser again.
|
|
141
|
+
function isMissingSystemLibrary(error) {
|
|
142
|
+
return (
|
|
143
|
+
!!error &&
|
|
144
|
+
typeof error.message === "string" &&
|
|
145
|
+
MISSING_SHARED_LIBRARY_PATTERNS.some((pattern) =>
|
|
146
|
+
error.message.includes(pattern),
|
|
147
|
+
)
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Every distinct `lib*.so*` name a missing-library launch error mentions, in
|
|
152
|
+
// first-seen order. Covers both the loader line and Playwright's list.
|
|
153
|
+
function missingLibraryNames(error) {
|
|
154
|
+
const message = (error && error.message) || "";
|
|
155
|
+
return [...new Set(message.match(SHARED_LIBRARY_NAME_PATTERN) || [])];
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// The fix for the platform the capture is running on. Replit is detected by the
|
|
159
|
+
// same env signals `preview_host_provider/replit.rs` uses; there system
|
|
160
|
+
// packages come from replit.nix. Any other Linux host gets Playwright's own
|
|
161
|
+
// dependency installer; anything else gets the library names and a hint.
|
|
162
|
+
function missingLibraryRemedy(libraries, { env = process.env, platform = process.platform } = {}) {
|
|
163
|
+
const named = libraries.length > 0 ? libraries.join(", ") : "the missing libraries";
|
|
164
|
+
if (env.REPL_ID || env.REPLIT_DEV_DOMAIN) {
|
|
165
|
+
const packages = [
|
|
166
|
+
...new Set(
|
|
167
|
+
libraries
|
|
168
|
+
.map((lib) => REPLIT_NIX_PACKAGE_FOR_LIBRARY[lib.split(".so")[0]])
|
|
169
|
+
.filter(Boolean),
|
|
170
|
+
),
|
|
171
|
+
];
|
|
172
|
+
const suggestion =
|
|
173
|
+
packages.length > 0 ? ` (${packages.join(", ")})` : "";
|
|
174
|
+
return `add the Nix package(s) providing ${named}${suggestion} to the \`deps\` list in replit.nix, then restart the Repl and re-run the capture`;
|
|
175
|
+
}
|
|
176
|
+
if (platform === "linux") {
|
|
177
|
+
return `install Chromium's system libraries with \`${PLAYWRIGHT_INSTALL_DEPS_COMMAND}\` (may need sudo), then re-run the capture`;
|
|
178
|
+
}
|
|
179
|
+
return `install the system package(s) that provide ${named} for this OS, then re-run the capture`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// The rethrown error for a missing-library launch failure: marker line naming
|
|
183
|
+
// the libraries, a `remedy:` line, then the original Playwright message as
|
|
184
|
+
// diagnostic. Line-oriented so the Rust side can lift each part out.
|
|
185
|
+
function missingSystemLibraryError(error, { env, platform } = {}) {
|
|
186
|
+
const libraries = missingLibraryNames(error);
|
|
187
|
+
const remedy = missingLibraryRemedy(libraries, { env, platform });
|
|
188
|
+
const wrapped = new Error(
|
|
189
|
+
`${CAPTURE_BROWSER_DEPS_MISSING_MARKER} ${libraries.join(",")}\n` +
|
|
190
|
+
`remedy: ${remedy}\n` +
|
|
191
|
+
error.message,
|
|
192
|
+
);
|
|
193
|
+
wrapped.cause = error;
|
|
194
|
+
return wrapped;
|
|
195
|
+
}
|
|
196
|
+
|
|
93
197
|
// Self-heal around `chromium.launch()`. Two recoverable classes:
|
|
94
198
|
//
|
|
95
199
|
// 1. "missing browser" — run `npx playwright install chromium` synchronously
|
|
@@ -98,6 +202,12 @@ function isTransientLaunchCrash(error) {
|
|
|
98
202
|
// `CAPTURE_LAUNCH_SIGSEGV_RETRIES` times with a short backoff, since the
|
|
99
203
|
// crash is environmental (dbus-less cloud VM) and clears on a retry.
|
|
100
204
|
//
|
|
205
|
+
// A third class is diagnosed but deliberately NOT healed: a host missing a
|
|
206
|
+
// system library Chromium links against. Installing system packages changes
|
|
207
|
+
// the user's environment (replit.nix, apt, often root), so it is rethrown —
|
|
208
|
+
// with no retry and no browser install — as `missingSystemLibraryError`,
|
|
209
|
+
// naming the library and the platform's remedy.
|
|
210
|
+
//
|
|
101
211
|
// For any unrecognized error, or after exhausting retries, rethrow the
|
|
102
212
|
// ORIGINAL Playwright error so the existing `Scenario check failed: <stderr>`
|
|
103
213
|
// path keeps showing the actionable message — looping would hide a real ops
|
|
@@ -111,10 +221,15 @@ async function launchChromiumWithSelfHeal({
|
|
|
111
221
|
install = () => execSync(PLAYWRIGHT_INSTALL_COMMAND, { stdio: "inherit" }),
|
|
112
222
|
stderr = process.stderr,
|
|
113
223
|
sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
224
|
+
env = process.env,
|
|
225
|
+
platform = process.platform,
|
|
114
226
|
} = {}) {
|
|
115
227
|
try {
|
|
116
228
|
return await launch();
|
|
117
229
|
} catch (error) {
|
|
230
|
+
if (isMissingSystemLibrary(error)) {
|
|
231
|
+
throw missingSystemLibraryError(error, { env, platform });
|
|
232
|
+
}
|
|
118
233
|
const isMissingBrowser =
|
|
119
234
|
error &&
|
|
120
235
|
typeof error.message === "string" &&
|
|
@@ -147,7 +262,13 @@ async function launchChromiumWithSelfHeal({
|
|
|
147
262
|
}
|
|
148
263
|
try {
|
|
149
264
|
return await launch();
|
|
150
|
-
} catch (
|
|
265
|
+
} catch (retryError) {
|
|
266
|
+
// A fresh download onto a host without Chromium's system libraries
|
|
267
|
+
// (the common first-capture shape on Replit) fails HERE, and the
|
|
268
|
+
// original "missing browser" error would now be a lie.
|
|
269
|
+
if (isMissingSystemLibrary(retryError)) {
|
|
270
|
+
throw missingSystemLibraryError(retryError, { env, platform });
|
|
271
|
+
}
|
|
151
272
|
throw error;
|
|
152
273
|
}
|
|
153
274
|
}
|
|
@@ -1028,11 +1149,14 @@ async function verifyStorageSeedLanded(frame, config) {
|
|
|
1028
1149
|
// Rendering already reflows whitespace. Case-folding is the same argument one
|
|
1029
1150
|
// step further: an app that lowercases a value before putting it on the page
|
|
1030
1151
|
// has still put the value on the page.
|
|
1152
|
+
// Two statements rather than one chained return, so line coverage can see the
|
|
1153
|
+
// body run. As a single multi-line expression the whole function collapsed to
|
|
1154
|
+
// one instrumented line that the reporter then recorded as never executed
|
|
1155
|
+
// (`DA:1153,0`) while its own function counter said 105 calls — which read as
|
|
1156
|
+
// uncovered debt for an entity its tests exercise heavily.
|
|
1031
1157
|
function normalizeForMatch(text) {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
.trim()
|
|
1035
|
-
.toLowerCase();
|
|
1158
|
+
const raw = String(text == null ? "" : text);
|
|
1159
|
+
return raw.replace(/\s+/g, " ").trim().toLowerCase();
|
|
1036
1160
|
}
|
|
1037
1161
|
|
|
1038
1162
|
// Does an already-normalized surface carry `value`?
|
|
@@ -2135,6 +2259,22 @@ async function runScenarioCheck(
|
|
|
2135
2259
|
async function main() {
|
|
2136
2260
|
const config = JSON.parse(process.argv[2] || "{}");
|
|
2137
2261
|
|
|
2262
|
+
// Preview-preflight launch probe (`preview_preflight.rs`
|
|
2263
|
+
// `check_capture_browser_launch`): launch and close Chromium through the same
|
|
2264
|
+
// self-heal path so a missing system library surfaces before the first
|
|
2265
|
+
// capture. Installing the browser is a capture-time side effect, never a
|
|
2266
|
+
// preflight one, so the probe disables it.
|
|
2267
|
+
if (config.probeLaunch) {
|
|
2268
|
+
const browser = await launchChromiumWithSelfHeal({
|
|
2269
|
+
install: () => {
|
|
2270
|
+
throw new Error("browser install is disabled in the launch probe");
|
|
2271
|
+
},
|
|
2272
|
+
});
|
|
2273
|
+
await browser.close();
|
|
2274
|
+
console.log(JSON.stringify({ ok: true }));
|
|
2275
|
+
return;
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2138
2278
|
if (!config.url) {
|
|
2139
2279
|
console.error(
|
|
2140
2280
|
"Usage: node scenario-check.js '{\"url\":\"...\",\"outputPath\":\"...\",\"width\":1440,\"height\":900}'",
|
|
@@ -2177,6 +2317,10 @@ module.exports = {
|
|
|
2177
2317
|
main,
|
|
2178
2318
|
launchChromiumWithSelfHeal,
|
|
2179
2319
|
isTransientLaunchCrash,
|
|
2320
|
+
isMissingSystemLibrary,
|
|
2321
|
+
missingLibraryNames,
|
|
2322
|
+
missingLibraryRemedy,
|
|
2323
|
+
CAPTURE_BROWSER_DEPS_MISSING_MARKER,
|
|
2180
2324
|
CAPTURE_LAUNCH_ARGS,
|
|
2181
2325
|
CAPTURE_HOST_RESOLVER_RULES,
|
|
2182
2326
|
CAPTURE_LAUNCH_SIGSEGV_RETRIES,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeyam-editor/codeyam-editor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14-staging.ge9fdd0f",
|
|
4
4
|
"description": "Language-agnostic managed execution sandbox for scenario-driven development",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codeyam-editor": "./npm/cli.js"
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
"playwright": "^1.58.2"
|
|
10
10
|
},
|
|
11
11
|
"optionalDependencies": {
|
|
12
|
-
"@codeyam-editor/codeyam-editor-darwin-arm64": "0.1.
|
|
13
|
-
"@codeyam-editor/codeyam-editor-darwin-x64": "0.1.
|
|
14
|
-
"@codeyam-editor/codeyam-editor-linux-x64": "0.1.
|
|
15
|
-
"@codeyam-editor/codeyam-editor-win32-x64": "0.1.
|
|
12
|
+
"@codeyam-editor/codeyam-editor-darwin-arm64": "0.1.14-staging.ge9fdd0f",
|
|
13
|
+
"@codeyam-editor/codeyam-editor-darwin-x64": "0.1.14-staging.ge9fdd0f",
|
|
14
|
+
"@codeyam-editor/codeyam-editor-linux-x64": "0.1.14-staging.ge9fdd0f",
|
|
15
|
+
"@codeyam-editor/codeyam-editor-win32-x64": "0.1.14-staging.ge9fdd0f"
|
|
16
16
|
},
|
|
17
17
|
"keywords": [
|
|
18
18
|
"codeyam",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e}from"./markdown-C9tbsVHX.js";import{b as a}from"./react-nrLBr15I.js";import{u as k}from"./useEvents-DNb1olaj.js";import{k as E}from"./index-
|
|
1
|
+
import{j as e}from"./markdown-C9tbsVHX.js";import{b as a}from"./react-nrLBr15I.js";import{u as k}from"./useEvents-DNb1olaj.js";import{k as E}from"./index-BDc44VP_.js";function P({connected:t}){return e.jsx("span",{className:`inline-block rounded-full px-2 py-0.5 text-xs font-medium text-[var(--text-primary)] ${t?"bg-[var(--accent-green)]":"bg-[var(--accent-red)]"}`,children:t?"connected":"reconnecting…"})}const re=Object.freeze(Object.defineProperty({__proto__:null,ConnectionBadge:P},Symbol.toStringTag,{value:"Module"}));function N(){const[t,r]=a.useState(null),[o,s]=a.useState(!0),{events:l}=k(),n=a.useCallback(async()=>{try{const c=await(await fetch("/api/inspector/status")).json();r(c)}catch{}finally{s(!1)}},[]);return a.useEffect(()=>{n()},[n]),a.useEffect(()=>{const i=l[l.length-1];i&&i.type==="scenario_switch"&&n()},[l,n]),{scenario:(t==null?void 0:t.scenario)??null,previewScenario:(t==null?void 0:t.previewScenario)??null,routes:(t==null?void 0:t.routes)??[],routeCount:(t==null?void 0:t.routeCount)??0,loading:o,refetch:n}}function v({title:t}){return e.jsx("h2",{style:{fontSize:14,fontWeight:600,color:"#f0f6fc",margin:"0 0 8px 0",borderBottom:"1px solid #30363d",paddingBottom:8},children:t})}function f({color:t,children:r}){return e.jsx("span",{style:{background:`${t}22`,color:t,border:`1px solid ${t}55`,borderRadius:4,padding:"2px 8px",fontSize:11,fontWeight:600,letterSpacing:"0.5px",whiteSpace:"nowrap"},children:r})}const $={GET:"#D7FF63",POST:"#238636",PUT:"#d29922",DELETE:"#da3633",PATCH:"#bc8cff"};function O({method:t}){const r=$[t.toUpperCase()]??"#8b949e";return e.jsx("span",{style:{color:r,fontWeight:600,fontSize:11,minWidth:48,display:"inline-block"},children:t.toUpperCase()})}function C({color:t,children:r}){return e.jsx("div",{style:{padding:"12px 16px",borderRadius:6,border:`1px solid ${t}44`,background:`${t}11`,color:t},children:r})}const u={padding:"8px 12px",textAlign:"center",color:"#8b949e",fontWeight:500,fontSize:11,textTransform:"uppercase",letterSpacing:"0.5px"},h={padding:"6px 12px"},S={background:"#161b22",border:"1px solid #30363d",borderRadius:6,color:"#c9d1d9",padding:"6px 12px",fontSize:13,fontFamily:"inherit"},R={...S,appearance:"none",paddingRight:24,backgroundImage:`url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%238b949e' d='M6 8L1 3h10z'/%3E%3C/svg%3E")`,backgroundRepeat:"no-repeat",backgroundPosition:"right 8px center"},oe=Object.freeze(Object.defineProperty({__proto__:null,Badge:f,MethodBadge:O,SectionHeader:v,StatusBox:C,inputStyle:S,selectStyle:R,tdStyle:h,thStyle:u},Symbol.toStringTag,{value:"Module"}));function z({routes:t}){return e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:12},children:[e.jsx("thead",{children:e.jsxs("tr",{style:{borderBottom:"1px solid #30363d"},children:[e.jsx("th",{style:u,children:"Method"}),e.jsx("th",{style:{...u,textAlign:"left"},children:"Pattern"}),e.jsx("th",{style:u,children:"Status"})]})}),e.jsx("tbody",{children:t.map((r,o)=>e.jsxs("tr",{style:{borderBottom:"1px solid #21262d"},children:[e.jsx("td",{style:{...h,textAlign:"center"},children:e.jsx(O,{method:r.method})}),e.jsx("td",{style:h,children:r.pattern}),e.jsx("td",{style:{...h,textAlign:"center",color:"#8b949e"},children:r.status})]},o))})]})}const se=Object.freeze(Object.defineProperty({__proto__:null,InspectorRouteTable:z},Symbol.toStringTag,{value:"Module"}));function A(){const{scenario:t,previewScenario:r,routes:o,routeCount:s,loading:l}=N();return e.jsxs("section",{children:[e.jsx(v,{title:"Active Scenario"}),l?e.jsx(C,{color:"#8b949e",children:"Loading..."}):t?e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[e.jsx(f,{color:"#238636",children:"ACTIVE"}),e.jsx("span",{style:{color:"#f0f6fc",fontWeight:500},children:t.name}),e.jsxs("span",{style:{color:"#8b949e"},children:["(",t.slug,")"]})]}),e.jsxs("div",{style:{color:"#8b949e",fontSize:12},children:[s," mock route",s!==1?"s":""," loaded"]}),o.length>0&&e.jsx(z,{routes:o})]}):r?e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[e.jsx(f,{color:"#D7FF63",children:"PREVIEW"}),e.jsx("span",{style:{color:"#f0f6fc",fontWeight:500},children:r.name}),e.jsxs("span",{style:{color:"#8b949e"},children:["(",r.slug,")"]})]}),e.jsx("div",{style:{color:"#8b949e",fontSize:12},children:"Component preview — no HTTP mocks active"})]}):e.jsx(C,{color:"#d29922",children:"No scenario active — all requests pass through to upstream"})]})}const ne=Object.freeze(Object.defineProperty({__proto__:null,InspectorScenarioSection:A},Symbol.toStringTag,{value:"Module"}));function F({textUrlFilter:t,onTextUrlFilterChange:r,methodFilter:o,onMethodFilterChange:s,sourceFilter:l,onSourceFilterChange:n}){return e.jsxs("div",{style:{display:"flex",gap:8,marginBottom:12,alignItems:"center"},children:[e.jsx("input",{type:"text",placeholder:"Filter by URL...",value:t,onChange:i=>r(i.target.value),style:{...S,flex:1,minWidth:0}}),e.jsxs("select",{value:o,onChange:i=>s(i.target.value),style:R,children:[e.jsx("option",{value:"ALL",children:"All Methods"}),e.jsx("option",{value:"GET",children:"GET"}),e.jsx("option",{value:"POST",children:"POST"}),e.jsx("option",{value:"PUT",children:"PUT"}),e.jsx("option",{value:"DELETE",children:"DELETE"}),e.jsx("option",{value:"PATCH",children:"PATCH"})]}),e.jsxs("select",{value:l,onChange:i=>n(i.target.value),style:R,children:[e.jsx("option",{value:"ALL",children:"All Sources"}),e.jsx("option",{value:"MOCKED",children:"Mocked"}),e.jsx("option",{value:"PASSTHROUGH",children:"Passthrough"})]})]})}const ie=Object.freeze(Object.defineProperty({__proto__:null,InspectorTrafficFilterBar:F},Symbol.toStringTag,{value:"Module"})),G={color:"#8b949e",fontSize:11,fontWeight:600,textTransform:"uppercase",letterSpacing:"0.5px",marginBottom:4},M={background:"#161b22",border:"1px solid #30363d",borderRadius:4,padding:"8px 12px",margin:0,fontSize:11,color:"#c9d1d9",fontFamily:"monospace",maxHeight:200,overflow:"auto",whiteSpace:"pre-wrap",wordBreak:"break-all"};function _({label:t,children:r}){return e.jsxs("div",{style:{marginBottom:12},children:[e.jsx("div",{style:G,children:t}),r]})}function B({event:t}){let r=[];try{const n=new URL(t.url,"http://localhost");r=Array.from(n.searchParams.entries())}catch{}const o=t.requestHeaders&&Object.keys(t.requestHeaders).length>0,s=t.requestBody!=null,l=t.responseBody!=null;return e.jsxs("div",{style:{background:"#0d1117",padding:"12px 16px",borderTop:"1px solid #30363d"},children:[r.length>0&&e.jsx(_,{label:"Query Parameters",children:e.jsx("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:"2px 12px",fontSize:12},children:r.map(([n,i],c)=>e.jsxs("div",{style:{display:"contents"},children:[e.jsx("span",{style:{color:"#D7FF63",fontFamily:"monospace"},children:n}),e.jsx("span",{style:{color:"#c9d1d9",fontFamily:"monospace"},children:i})]},c))})}),o&&e.jsx(_,{label:"Request Headers",children:e.jsx("pre",{style:M,children:Object.entries(t.requestHeaders).map(([n,i])=>`${n}: ${i}`).join(`
|
|
2
2
|
`)})}),s&&e.jsx(_,{label:"Request Body",children:e.jsx("pre",{style:M,children:typeof t.requestBody=="string"?t.requestBody:JSON.stringify(t.requestBody,null,2)})}),l&&e.jsx(_,{label:"Response Body",children:e.jsx("pre",{style:M,children:typeof t.responseBody=="string"?t.responseBody:JSON.stringify(t.responseBody,null,2)})}),r.length===0&&!o&&!s&&!l&&e.jsx("div",{style:{color:"#8b949e",fontSize:12},children:"No additional details available for this request"})]})}const le=Object.freeze(Object.defineProperty({__proto__:null,DetailSection:_,InspectorTrafficDetail:B},Symbol.toStringTag,{value:"Module"}));function L({event:t}){const[r,o]=a.useState(!1),s=new Date(t.timestampMs).toLocaleTimeString(),l=t.mocked;return e.jsxs(e.Fragment,{children:[e.jsxs("tr",{onClick:()=>o(!r),style:{borderBottom:"1px solid #21262d",background:l?"transparent":"rgba(210, 153, 34, 0.05)",cursor:"pointer"},children:[e.jsxs("td",{style:{...h,color:"#8b949e",textAlign:"center"},children:[e.jsx("span",{style:{display:"inline-block",width:12,marginRight:4,fontSize:10,color:"#8b949e",transition:"transform 0.15s",transform:r?"rotate(90deg)":"rotate(0deg)"},children:"▶"}),s]}),e.jsx("td",{style:{...h,textAlign:"center"},children:e.jsx(O,{method:t.method})}),e.jsx("td",{style:{...h,maxWidth:400,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:t.url}),e.jsx("td",{style:{...h,textAlign:"center",color:"#8b949e"},children:t.status??"---"}),e.jsxs("td",{style:{...h,textAlign:"center",color:"#8b949e"},children:[t.durationMs,"ms"]}),e.jsx("td",{style:{...h,textAlign:"center"},children:l?t.mockSource==="default"?e.jsx(f,{color:"#1f6feb",children:"MOCKED (default)"}):e.jsx(f,{color:"#238636",children:"MOCKED (scenario)"}):e.jsx(f,{color:"#d29922",children:"PASSTHROUGH"})})]}),r&&e.jsx("tr",{children:e.jsx("td",{colSpan:6,style:{padding:0},children:e.jsx(B,{event:t})})})]})}const ae=Object.freeze(Object.defineProperty({__proto__:null,InspectorTrafficRow:L},Symbol.toStringTag,{value:"Module"}));function D({events:t}){return e.jsx("div",{style:{maxHeight:300,overflowY:"auto",border:"1px solid #30363d",borderRadius:6},children:e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:12},children:[e.jsx("thead",{children:e.jsxs("tr",{style:{borderBottom:"1px solid #30363d",position:"sticky",top:0,background:"#0d1117"},children:[e.jsx("th",{style:u,children:"Time"}),e.jsx("th",{style:u,children:"Method"}),e.jsx("th",{style:{...u,textAlign:"left"},children:"URL"}),e.jsx("th",{style:u,children:"Status"}),e.jsx("th",{style:u,children:"Duration"}),e.jsx("th",{style:u,children:"Source"})]})}),e.jsx("tbody",{children:t.map(r=>e.jsx(L,{event:r},r.id))})]})})}const ce=Object.freeze(Object.defineProperty({__proto__:null,InspectorTrafficTable:D},Symbol.toStringTag,{value:"Module"}));function K(t){if(t===void 0)return"checked";if(t==="checked")return"excluded"}function I({chips:t,chipStates:r,onChipStatesChange:o}){if(t.length===0)return null;const s=n=>{const i=new Map(r),c=K(i.get(n));c===void 0?i.delete(n):i.set(n,c),o(i)},l=()=>{o(new Map)};return e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:6,marginBottom:12},children:[r.size>0&&e.jsx("button",{onClick:l,style:{background:"#da363322",color:"#da3633",border:"1px solid #da363355",borderRadius:4,padding:"2px 8px",fontSize:11,fontWeight:600,cursor:"pointer",fontFamily:"inherit"},children:"Clear all"}),t.map(({path:n,count:i})=>{const c=r.get(n),d=c==="checked",g=c==="excluded";let m="#30363d",b="#8b949e",T="#30363d",y="";return d?(m="#D7FF6322",b="#D7FF63",T="#D7FF6355",y="✓ "):g&&(m="#da363322",b="#da3633",T="#da363355",y="✗ "),e.jsxs("button",{onClick:()=>s(n),style:{background:m,color:b,border:`1px solid ${T}`,borderRadius:4,padding:"2px 8px",fontSize:11,fontFamily:"monospace",cursor:"pointer",whiteSpace:"nowrap"},children:[y,n,e.jsxs("span",{style:{marginLeft:4,opacity:.6,fontFamily:"inherit"},children:["(",i,")"]})]},n)})]})}const de=Object.freeze(Object.defineProperty({__proto__:null,InspectorTrafficUrlChips:I},Symbol.toStringTag,{value:"Module"}));function H(){const{events:t}=k(),[r,o]=a.useState(""),[s,l]=a.useState(()=>new Map),[n,i]=a.useState("ALL"),[c,d]=a.useState("ALL"),g=t.filter(p=>p.type==="http_request"),m=a.useMemo(()=>{const p=new Map;for(const x of g){const j=E(x.url);p.set(j,(p.get(j)||0)+1)}return Array.from(p.entries()).sort((x,j)=>j[1]-x[1]).slice(0,10).map(([x,j])=>({path:x,count:j}))},[g]),b=a.useMemo(()=>Array.from(s.values()).some(p=>p==="checked"),[s]),y=g.filter(p=>{if(r&&!p.url.toLowerCase().includes(r.toLowerCase()))return!1;const x=E(p.url);return!(s.get(x)==="excluded"||b&&s.get(x)!=="checked"||n!=="ALL"&&p.method.toUpperCase()!==n||c==="MOCKED"&&!p.mocked||c==="PASSTHROUGH"&&p.mocked)}).slice(-50).reverse();return e.jsxs("section",{children:[e.jsx(v,{title:"Live Traffic"}),e.jsx(F,{textUrlFilter:r,onTextUrlFilterChange:o,methodFilter:n,onMethodFilterChange:i,sourceFilter:c,onSourceFilterChange:p=>d(p)}),e.jsx(I,{chips:m,chipStates:s,onChipStatesChange:l}),y.length===0?e.jsx(C,{color:"#8b949e",children:g.length>0?"No matching traffic — try adjusting the filters":"No HTTP traffic yet — requests will appear here in real-time"}):e.jsx(D,{events:y})]})}const pe=Object.freeze(Object.defineProperty({__proto__:null,InspectorTrafficSection:H},Symbol.toStringTag,{value:"Module"}));function J(){const[t,r]=a.useState(null),[o,s]=a.useState(!1);return{explain:a.useCallback(async(n,i)=>{s(!0);try{const d=await(await fetch("/api/inspector/explain",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({method:n,url:i})})).json();r(d)}catch{}finally{s(!1)}},[]),result:t,loading:o}}function U({result:t}){return e.jsxs("div",{style:{border:"1px solid #30363d",borderRadius:6,padding:12},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:12},children:[e.jsxs("span",{style:{color:"#f0f6fc",fontWeight:500},children:[t.method," ",t.url]}),t.wouldMatch?e.jsx(f,{color:"#238636",children:"WOULD MATCH"}):e.jsx(f,{color:"#da3633",children:"NO MATCH"})]}),t.attempts.length===0?e.jsx("div",{style:{color:"#8b949e"},children:"No routes loaded to match against"}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:6},children:t.attempts.map((r,o)=>e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"4px 8px",borderRadius:4,background:r.failure?"transparent":"rgba(35, 134, 54, 0.1)"},children:[e.jsx("span",{style:{color:r.failure?"#da3633":"#238636",fontWeight:600,width:16},children:r.failure?"x":"v"}),e.jsx(O,{method:r.method}),e.jsx("span",{children:r.pattern}),r.failure&&e.jsx("span",{style:{color:"#8b949e",fontSize:11},children:r.failure.reason==="methodMismatch"?`method: expected ${r.failure.expected}, got ${r.failure.actual}`:`path "${r.failure.path}" does not match "${r.failure.pattern}"`})]},o))})]})}const ue=Object.freeze(Object.defineProperty({__proto__:null,InspectorExplainerResult:U},Symbol.toStringTag,{value:"Module"}));function W(){const{explain:t,result:r,loading:o}=J(),[s,l]=a.useState("GET"),[n,i]=a.useState(""),c=d=>{d.preventDefault(),n.trim()&&t(s,n.trim())};return e.jsxs("section",{children:[e.jsx(v,{title:"Match Explainer"}),e.jsxs("form",{onSubmit:c,style:{display:"flex",gap:8,marginBottom:12},children:[e.jsx("select",{value:s,onChange:d=>l(d.target.value),style:{...S,width:100},children:["GET","POST","PUT","DELETE","PATCH"].map(d=>e.jsx("option",{value:d,children:d},d))}),e.jsx("input",{type:"text",value:n,onChange:d=>i(d.target.value),placeholder:"/api/users",style:{...S,flex:1}}),e.jsx("button",{type:"submit",disabled:o||!n.trim(),style:{background:"#238636",color:"#fff",border:"none",borderRadius:6,padding:"6px 16px",cursor:"pointer",fontSize:12,fontWeight:500,opacity:o||!n.trim()?.5:1},children:o?"Checking...":"Explain"})]}),r&&e.jsx(U,{result:r})]})}const he=Object.freeze(Object.defineProperty({__proto__:null,InspectorExplainerSection:W},Symbol.toStringTag,{value:"Module"})),w={"/api/health":"Health check — confirms the proxy and mock engine are running","/api/events":"SSE stream of real-time events (traffic, errors) powering this Inspector","/api/config":"Returns current CodeYam configuration for the project","/api/editor-dev-server":"Polls/controls the dev server status (start, stop, restart)","/api/inspector/status":"Returns active scenario and loaded mock routes","/api/inspector/explain":"Tests which mock route would match a given method + URL","/api/scenarios":"Lists all defined scenarios with metadata","/api/tests":"Returns the AI-maintained test registry joined with per-test-evidence, grouped by file","/api/test-results":"Returns latest test execution results","/api/screenshots/*":"Serves captured scenario screenshots","/api/session-info":"Returns current editor session metadata","/api/data-structure":"Returns the app's data structure definition","/api/dependency-graph":"Returns the project's component dependency graph","/api/app-route-entities":"Lists app routes and their associated entities","/api/glossary":"Returns the project's component glossary","/api/step":"Returns current editor workflow step","/api/editor-commands":"Lists available editor commands"};function V(t){if(w[t])return w[t];for(const[r,o]of Object.entries(w))if(r.endsWith("/*")){const s=r.slice(0,-1);if(t.startsWith(s))return o}}function Y(t){const r=new Set([...t,...Object.keys(w)]),o=[];for(const s of Array.from(r).sort()){if(s.endsWith("/*"))continue;const l=V(s);o.push({path:s,description:l??"Application endpoint"})}return o}function q(){const{events:t}=k(),r=a.useMemo(()=>{const o=[];for(const s of t)s.type==="http_request"&&o.push(E(s.url));return Y(o)},[t]);return r.length===0?null:e.jsxs("section",{children:[e.jsx(v,{title:"URL Glossary"}),e.jsx("div",{style:{border:"1px solid #30363d",borderRadius:6,overflow:"hidden"},children:e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:12},children:[e.jsx("thead",{children:e.jsxs("tr",{style:{borderBottom:"1px solid #30363d",background:"#161b22"},children:[e.jsx("th",{style:{padding:"6px 12px",textAlign:"left",color:"#8b949e",fontWeight:500,fontSize:11,textTransform:"uppercase",letterSpacing:"0.5px",width:"30%"},children:"Path"}),e.jsx("th",{style:{padding:"6px 12px",textAlign:"left",color:"#8b949e",fontWeight:500,fontSize:11,textTransform:"uppercase",letterSpacing:"0.5px"},children:"Description"})]})}),e.jsx("tbody",{children:r.map(({path:o,description:s})=>e.jsxs("tr",{style:{borderBottom:"1px solid #21262d"},children:[e.jsx("td",{style:{padding:"4px 12px",fontFamily:"monospace",color:"#D7FF63",fontSize:11},children:o}),e.jsx("td",{style:{padding:"4px 12px",color:"#8b949e"},children:s})]},o))})]})})]})}const xe=Object.freeze(Object.defineProperty({__proto__:null,InspectorUrlGlossary:q},Symbol.toStringTag,{value:"Module"}));function Q(){const{connected:t}=k();return e.jsxs("div",{style:{background:"#0d1117",color:"#c9d1d9",minHeight:"100vh",fontFamily:"'SF Mono', 'Fira Code', 'Cascadia Code', Menlo, monospace",fontSize:13,padding:24,display:"flex",flexDirection:"column",gap:24},children:[e.jsxs("header",{style:{display:"flex",alignItems:"center",gap:12},children:[e.jsx("h1",{style:{fontSize:18,fontWeight:600,color:"#f0f6fc",margin:0},children:"Container Inspector"}),e.jsx("span",{style:{color:"#8b949e",fontSize:12},children:"Read-only view of proxy and mock engine state"}),e.jsx(P,{connected:t})]}),e.jsx(A,{}),e.jsx(H,{}),e.jsx(W,{}),e.jsx(q,{})]})}const fe=Object.freeze(Object.defineProperty({__proto__:null,ContainerInspector:Q},Symbol.toStringTag,{value:"Module"}));export{f as B,Q as C,_ as D,L as I,O as M,v as S,xe as _,C as a,q as b,I as c,D as d,F as e,B as f,U as g,W as h,H as i,z as j,A as k,P as l,de as m,ce as n,pe as o,ae as p,ie as q,le as r,ne as s,u as t,se as u,oe as v,he as w,ue as x,fe as y,re as z};
|