@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.
@@ -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 depends on being present in every /data VM entry. This
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', 'brokerLive', 'brokerStatus',
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',
@@ -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 (_retryError) {
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
- return String(text == null ? "" : text)
1033
- .replace(/\s+/g, " ")
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.13",
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",
13
- "@codeyam-editor/codeyam-editor-darwin-x64": "0.1.13",
14
- "@codeyam-editor/codeyam-editor-linux-x64": "0.1.13",
15
- "@codeyam-editor/codeyam-editor-win32-x64": "0.1.13"
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-mgNPDFlH.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(`
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};