@webskill/sdk 0.14.0 → 0.15.0

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.
Files changed (60) hide show
  1. package/dist/agent.d.ts +3 -3
  2. package/dist/agent.js +2442 -3
  3. package/dist/{dist-Bfga1TmS.js → approval-BnLLCOG0.js} +235 -2932
  4. package/dist/browser.d.ts +106 -5
  5. package/dist/browser.js +364 -10
  6. package/dist/{openUiLibrary-BKXW7Iwx-DjvEnMlJ.js → dist-CTsxblSD.js} +496 -28
  7. package/dist/{echarts-De78wXqV.js → echarts-BE7oV_Dl.js} +1 -1
  8. package/dist/{env-8cY40DXB-CGnEVZby.js → env-Bj1MI2Ww.js} +1 -1
  9. package/dist/errors-BDZNpC13.js +22 -0
  10. package/dist/{eventTypes-FllCrX-Z-DNDeHWoG.js → eventTypes-Y07N8IAC.js} +14 -2
  11. package/dist/external-_ZRQe-V9.js +53 -0
  12. package/dist/governance.d.ts +15 -3
  13. package/dist/governance.js +86 -4
  14. package/dist/{index-DQwGvHAI.d.ts → index-CQYo4tcT.d.ts} +85 -6
  15. package/dist/{index-sd-gVKey.d.ts → index-CU2md8R1.d.ts} +26 -18
  16. package/dist/{index-CWoKOFBP.d.ts → index-Oc3H89TJ.d.ts} +159 -3
  17. package/dist/index.d.ts +4 -4
  18. package/dist/index.js +1001 -5
  19. package/dist/kind-DxgS8LM-.js +77 -0
  20. package/dist/linkedDocument-xNXF-z8n.js +94 -0
  21. package/dist/llm-B7lLH0ZI.js +1767 -0
  22. package/dist/mcp.d.ts +2 -2
  23. package/dist/mcp.js +41 -4
  24. package/dist/memoryArtifactStore-D6dLeY55.js +48 -0
  25. package/dist/miniChart-owdCdaw-.js +533 -0
  26. package/dist/node.d.ts +3 -3
  27. package/dist/node.js +106 -9
  28. package/dist/openUiLibrary-CY_ADoe0.js +30 -0
  29. package/dist/openUiSpecLang-DuOCdw9G.js +1849 -0
  30. package/dist/pathSecurity-B1owvJAF.js +65 -0
  31. package/dist/processSandboxEntry.js +5 -1
  32. package/dist/renderResult-D9Q-Vu2x.js +143 -0
  33. package/dist/{rolldown-runtime-BOF7iYI8.js → rolldown-runtime-BHkdefai.js} +1 -2
  34. package/dist/sandboxWorkerEntry.js +5 -1
  35. package/dist/{dist-D5YhlCdY.js → skill-CAJMsLod.js} +44 -372
  36. package/dist/{skillVersionStore-D-qHk9ZE-C0OFDTQY.d.ts → skillVersionStore-B24Jjjry-C4zomhMZ.d.ts} +14 -2
  37. package/dist/surface-DVGiCmwq.js +145 -0
  38. package/dist/testing.d.ts +1 -1
  39. package/dist/testing.js +64 -3
  40. package/dist/{types-C3V6lAeO-BgeOvc1Y.d.ts → types-C3V6lAeO-BIf7UB2e.d.ts} +17 -1
  41. package/dist/types-TUydnxaj.js +78 -0
  42. package/dist/ui-react.d.ts +12 -5
  43. package/dist/ui-react.js +128548 -4729
  44. package/dist/ui-vue.d.ts +1 -1
  45. package/dist/ui-vue.js +11 -2
  46. package/dist/ui.d.ts +3 -3
  47. package/dist/ui.js +1254 -3
  48. package/dist/urlSafety-CiSuCJvX.js +65 -0
  49. package/dist/webSkillApi-DOOyz2G5.js +106 -0
  50. package/dist/{webskillLitCatalog-D_zCqeQF-swXsWoAe.js → webskillLitCatalog-DSqVFQjK.js} +11 -3
  51. package/package.json +1 -1
  52. package/dist/catalogComponents-BgAJN0p8-Cr55ouOg.js +0 -124384
  53. package/dist/client-BCM6Z3yq-qUQNkKrK.js +0 -7787
  54. package/dist/dist-BnqAkSS6.js +0 -2384
  55. package/dist/dist-CiaDIqkV.js +0 -3509
  56. package/dist/dist-DxyxmXPU-DGC-dpXf.js +0 -5621
  57. package/dist/memoryArtifactStore-52Zn9npI-BxtUkrgV.js +0 -86
  58. package/dist/stdio-CFMoANJJ-BxrTeXh7.js +0 -31
  59. package/dist/testing-Cm8MseLF.js +0 -142
  60. package/dist/types-WovEf4ED-CZSDiiBU.js +0 -6215
@@ -1,10 +1,7 @@
1
- import { Dt as uiCatalog } from "./dist-CiaDIqkV.js";
2
- import { t as CatalogNode } from "./catalogComponents-BgAJN0p8-Cr55ouOg.js";
3
- import { z } from "zod";
4
1
  import { Component, Fragment, createContext, useCallback, useContext, useEffect, useInsertionEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
5
2
  import { jsx, jsxs } from "react/jsx-runtime";
6
3
  import { object } from "zod/v4";
7
- import * as z$1 from "zod/v4/core";
4
+ import * as z from "zod/v4/core";
8
5
 
9
6
  //#region ../../node_modules/.pnpm/@openuidev+lang-core@0.2.9_@modelcontextprotocol+sdk@1.29.0_zod@4.4.3__zod@4.4.3/node_modules/@openuidev/lang-core/dist/index.mjs
10
7
  /** Resolve a field path on an object. Supports dot-paths: "state.name" → obj.state.name */
@@ -655,11 +652,23 @@ function generatePrompt(spec) {
655
652
  }
656
653
  /** WeakSet tracks reactive schemas without mutating the schema objects. */
657
654
  const reactiveSchemas = /* @__PURE__ */ new WeakSet();
655
+ /** Mark a schema as reactive. Called by framework adapters' reactive() function. */
656
+ function markReactive(schema) {
657
+ reactiveSchemas.add(schema);
658
+ }
658
659
  /** Check if a schema was marked reactive. Used by Zod introspection for $binding<> prefix. */
659
660
  function isReactiveSchema(schema) {
660
661
  return typeof schema === "object" && schema !== null && reactiveSchemas.has(schema);
661
662
  }
662
663
  const schemaIdTags = /* @__PURE__ */ new WeakMap();
664
+ /**
665
+ * Tag a schema with an ID for prompt signatures.
666
+ * Use for non-component schemas that need friendly type names (e.g. ActionExpression).
667
+ * This affects prompt output only, not JSON Schema $defs.
668
+ */
669
+ function tagSchemaId(schema, id) {
670
+ schemaIdTags.set(schema, id);
671
+ }
663
672
  function assertV4Schema(schema, componentName) {
664
673
  if (schema != null && typeof schema === "object" && "_def" in schema && !("_zod" in schema)) throw new Error(`[OpenUI] Component "${componentName}" was defined with a Zod 3 schema. OpenUI requires Zod 4 schemas. If you're on zod@3.25+, import from "zod/v4" instead of "zod". See: https://zod.dev/v4/versioning`);
665
674
  }
@@ -803,7 +812,7 @@ function buildComponentSpecs(components, reg) {
803
812
  */
804
813
  function createLibrary$1(input) {
805
814
  const componentsRecord = {};
806
- const reg = z$1.registry();
815
+ const reg = z.registry();
807
816
  for (const comp of input.components) {
808
817
  reg.add(comp.props, { id: comp.name });
809
818
  componentsRecord[comp.name] = comp;
@@ -840,7 +849,7 @@ function createLibrary$1(input) {
840
849
  };
841
850
  function buildJSONSchema() {
842
851
  const combinedSchema = object(Object.fromEntries(Object.entries(componentsRecord).map(([k, v]) => [k, v.props])));
843
- const schema = z$1.toJSONSchema(combinedSchema, { metadata: reg });
852
+ const schema = z.toJSONSchema(combinedSchema, { metadata: reg });
844
853
  for (const [name, comp] of Object.entries(componentsRecord)) {
845
854
  const def = schema.$defs?.[name];
846
855
  if (def && comp.description) def.description = comp.description;
@@ -2204,6 +2213,28 @@ function stripComments(input) {
2204
2213
  function preprocess(input) {
2205
2214
  return stripComments(stripFences(input.trim())).trim();
2206
2215
  }
2216
+ /**
2217
+ * Parse a complete openui-lang string in one pass.
2218
+ *
2219
+ * @param input - Full openui-lang source text (may be partial/streaming)
2220
+ * @param cat - Param map for positional-arg → named-prop mapping
2221
+ * @returns ParseResult with root ElementNode (or null) and metadata
2222
+ */
2223
+ function parse(input, cat, rootName) {
2224
+ const trimmed = preprocess(input);
2225
+ if (!trimmed) return emptyResult();
2226
+ const { text, wasIncomplete } = autoClose(trimmed);
2227
+ const stmts = split(tokenize(text));
2228
+ if (!stmts.length) return emptyResult(wasIncomplete);
2229
+ const stmtMap = /* @__PURE__ */ new Map();
2230
+ let firstId = "";
2231
+ for (const s of stmts) {
2232
+ const stmt = classifyStatement(s, parseExpression(s.tokens));
2233
+ stmtMap.set(s.id, stmt);
2234
+ if (!firstId) firstId = s.id;
2235
+ }
2236
+ return buildResult(stmtMap, [...stmtMap.values()], firstId, wasIncomplete, stmtMap.size, cat, rootName);
2237
+ }
2207
2238
  function createStreamParser(cat, rootName) {
2208
2239
  let buf = "";
2209
2240
  let cleaned = "";
@@ -2332,6 +2363,22 @@ function compileSchema(schema) {
2332
2363
  return map;
2333
2364
  }
2334
2365
  /**
2366
+ * Create a parser from a library JSON Schema document.
2367
+ * Pass `library.toJSONSchema()` to get the schema.
2368
+ *
2369
+ * @example
2370
+ * ```ts
2371
+ * const parser = createParser(library.toJSONSchema());
2372
+ * const result = parser.parse(openuiLangString);
2373
+ * ```
2374
+ */
2375
+ function createParser(schema, rootName) {
2376
+ const paramMap = compileSchema(schema);
2377
+ return { parse(input) {
2378
+ return parse(input, paramMap, rootName);
2379
+ } };
2380
+ }
2381
+ /**
2335
2382
  * Create a streaming parser from a library JSON Schema document.
2336
2383
  * Pass `library.toJSONSchema()` to get the schema.
2337
2384
  */
@@ -2365,6 +2412,126 @@ function enrichErrors(validationErrors, schema, componentNames) {
2365
2412
  return error;
2366
2413
  });
2367
2414
  }
2415
+ function splitStatementSource(input) {
2416
+ const stmts = [];
2417
+ let depth = 0;
2418
+ let inStr = false;
2419
+ let esc = false;
2420
+ let start = 0;
2421
+ for (let i = 0; i < input.length; i++) {
2422
+ const c = input[i];
2423
+ if (esc) {
2424
+ esc = false;
2425
+ continue;
2426
+ }
2427
+ if (c === "\\" && inStr) {
2428
+ esc = true;
2429
+ continue;
2430
+ }
2431
+ if (inStr) {
2432
+ if (c === inStr) inStr = false;
2433
+ continue;
2434
+ }
2435
+ if (c === "\"" || c === "'") {
2436
+ inStr = c;
2437
+ continue;
2438
+ }
2439
+ if (c === "(" || c === "[" || c === "{") depth++;
2440
+ else if (c === ")" || c === "]" || c === "}") depth = Math.max(0, depth - 1);
2441
+ else if (c === "\n" && depth <= 0) {
2442
+ const stmt = input.slice(start, i).trim();
2443
+ if (stmt) stmts.push(stmt);
2444
+ start = i + 1;
2445
+ }
2446
+ }
2447
+ const tail = input.slice(start).trim();
2448
+ if (tail) stmts.push(tail);
2449
+ return stmts;
2450
+ }
2451
+ function parseStatements(input) {
2452
+ const trimmed = input.trim();
2453
+ if (!trimmed) return [];
2454
+ const result = [];
2455
+ for (const raw of splitStatementSource(trimmed)) {
2456
+ const stmt = split(tokenize(raw))[0];
2457
+ if (!stmt) continue;
2458
+ result.push({
2459
+ id: stmt.id,
2460
+ ast: parseExpression(stmt.tokens),
2461
+ raw
2462
+ });
2463
+ }
2464
+ return result;
2465
+ }
2466
+ /**
2467
+ * Recursively collect all Ref names from an AST node.
2468
+ */
2469
+ function collectRefs(node, out) {
2470
+ walkAST(node, (current) => {
2471
+ if (current.k === "Ref") out.add(current.n);
2472
+ if (current.k === "RuntimeRef") out.add(current.n);
2473
+ });
2474
+ }
2475
+ /**
2476
+ * Remove statements unreachable from `root` (garbage collection).
2477
+ * Walks the AST graph from root, collecting all referenced statement IDs.
2478
+ * $state variables are always kept (they're referenced at runtime, not by Ref nodes).
2479
+ */
2480
+ function gcUnreachable(order, merged, asts, rootId = "root") {
2481
+ if (!asts.get(rootId)) return;
2482
+ const reachable = /* @__PURE__ */ new Set([rootId]);
2483
+ const queue = [rootId];
2484
+ while (queue.length > 0) {
2485
+ const id = queue.pop();
2486
+ const ast = asts.get(id);
2487
+ if (!ast) continue;
2488
+ const refs = /* @__PURE__ */ new Set();
2489
+ collectRefs(ast, refs);
2490
+ for (const ref of refs) if (!reachable.has(ref) && asts.has(ref)) {
2491
+ reachable.add(ref);
2492
+ queue.push(ref);
2493
+ }
2494
+ }
2495
+ for (const id of order) if (id.startsWith("$")) reachable.add(id);
2496
+ for (let i = order.length - 1; i >= 0; i--) if (!reachable.has(order[i])) {
2497
+ merged.delete(order[i]);
2498
+ order.splice(i, 1);
2499
+ }
2500
+ }
2501
+ /**
2502
+ * Merge an existing program with a patch (partial update).
2503
+ * Patch statements override existing ones by name.
2504
+ * Unreachable statements are automatically garbage-collected.
2505
+ * Returns the merged program as a string.
2506
+ */
2507
+ function mergeStatements(existing, patch, rootId = "root") {
2508
+ const existingStmts = parseStatements(existing);
2509
+ const patchStmts = parseStatements(stripFences(patch));
2510
+ if (!existingStmts.length) return patchStmts.map((stmt) => stmt.raw).join("\n");
2511
+ if (!patchStmts.length) return existing;
2512
+ const merged = /* @__PURE__ */ new Map();
2513
+ const asts = /* @__PURE__ */ new Map();
2514
+ const order = [];
2515
+ for (const stmt of existingStmts) {
2516
+ merged.set(stmt.id, stmt.raw);
2517
+ asts.set(stmt.id, stmt.ast);
2518
+ order.push(stmt.id);
2519
+ }
2520
+ for (const stmt of patchStmts) {
2521
+ if (stmt.ast.k === "Null") {
2522
+ merged.delete(stmt.id);
2523
+ asts.delete(stmt.id);
2524
+ const idx = order.indexOf(stmt.id);
2525
+ if (idx !== -1) order.splice(idx, 1);
2526
+ continue;
2527
+ }
2528
+ if (!merged.has(stmt.id)) order.push(stmt.id);
2529
+ merged.set(stmt.id, stmt.raw);
2530
+ asts.set(stmt.id, stmt.ast);
2531
+ }
2532
+ gcUnreachable(order, merged, asts, rootId);
2533
+ return order.filter((id) => merged.has(id)).map((id) => merged.get(id)).join("\n");
2534
+ }
2368
2535
  function isReactiveAssign(value) {
2369
2536
  return typeof value === "object" && value !== null && value.__reactive === "assign";
2370
2537
  }
@@ -3199,6 +3366,30 @@ function createQueryManager(toolProvider) {
3199
3366
  dispose
3200
3367
  };
3201
3368
  }
3369
+ function resolveStateField(name, bindingValue, store, evaluationContext, fieldGetter, fieldSetter) {
3370
+ if (isReactiveAssign(bindingValue) && store && evaluationContext) {
3371
+ const { target, expr } = bindingValue;
3372
+ return {
3373
+ name,
3374
+ value: store.get(target),
3375
+ setValue: (value) => {
3376
+ const extraScope = { $value: value };
3377
+ const nextValue = evaluate(expr, {
3378
+ ...evaluationContext,
3379
+ extraScope
3380
+ });
3381
+ store.set(target, nextValue);
3382
+ },
3383
+ isReactive: true
3384
+ };
3385
+ }
3386
+ return {
3387
+ name,
3388
+ value: fieldGetter(name) ?? bindingValue,
3389
+ setValue: (value) => fieldSetter(name, value),
3390
+ isReactive: false
3391
+ };
3392
+ }
3202
3393
  function createStore() {
3203
3394
  const state = /* @__PURE__ */ new Map();
3204
3395
  const listeners = /* @__PURE__ */ new Set();
@@ -3254,6 +3445,139 @@ function createStore() {
3254
3445
  dispose
3255
3446
  };
3256
3447
  }
3448
+ /**
3449
+ * Parse a rule string into a structured rule.
3450
+ * "required" → { type: "required" }
3451
+ * "min:8" → { type: "min", arg: 8 }
3452
+ * "minLength:3" → { type: "minLength", arg: 3 }
3453
+ * "pattern:^[a-z]" → { type: "pattern", arg: "^[a-z]" }
3454
+ */
3455
+ const NUMERIC_RULES = /* @__PURE__ */ new Set([
3456
+ "min",
3457
+ "max",
3458
+ "minLength",
3459
+ "maxLength"
3460
+ ]);
3461
+ function parseRule(rule) {
3462
+ const colonIdx = rule.indexOf(":");
3463
+ if (colonIdx === -1) return { type: rule };
3464
+ const type = rule.slice(0, colonIdx);
3465
+ const rawArg = rule.slice(colonIdx + 1);
3466
+ return {
3467
+ type,
3468
+ arg: NUMERIC_RULES.has(type) && !Number.isNaN(Number(rawArg)) ? Number(rawArg) : rawArg
3469
+ };
3470
+ }
3471
+ function parseRules(rules) {
3472
+ if (!Array.isArray(rules)) return [];
3473
+ return rules.filter((r) => typeof r === "string").map(parseRule);
3474
+ }
3475
+ function isEmpty(value) {
3476
+ if (value === null || value === void 0 || value === "") return true;
3477
+ if (Array.isArray(value) && value.length === 0) return true;
3478
+ if (value && typeof value === "object" && !Array.isArray(value) && "value" in value) return isEmpty(value.value);
3479
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length === 0) return true;
3480
+ return false;
3481
+ }
3482
+ const builtInValidators = {
3483
+ required: (value) => {
3484
+ if (isEmpty(value)) return "This field is required";
3485
+ if (typeof value === "object" && !Array.isArray(value) && value !== null) {
3486
+ const vals = Object.values(value);
3487
+ if (vals.length > 0 && vals.every((v) => typeof v === "boolean") && !vals.some(Boolean)) return "At least one option is required";
3488
+ }
3489
+ },
3490
+ email: (value) => {
3491
+ if (isEmpty(value)) return void 0;
3492
+ if (typeof value !== "string") return "Please enter a valid email";
3493
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) ? void 0 : "Please enter a valid email";
3494
+ },
3495
+ url: (value) => {
3496
+ if (isEmpty(value)) return void 0;
3497
+ if (typeof value !== "string") return "Please enter a valid URL";
3498
+ try {
3499
+ new URL(value);
3500
+ return;
3501
+ } catch {
3502
+ return "Please enter a valid URL";
3503
+ }
3504
+ },
3505
+ numeric: (value) => {
3506
+ if (isEmpty(value)) return void 0;
3507
+ if (typeof value === "number" && !isNaN(value)) return void 0;
3508
+ if (typeof value === "string" && !isNaN(parseFloat(value)) && value.trim() !== "") return void 0;
3509
+ return "Must be a number";
3510
+ },
3511
+ min: (value, arg) => {
3512
+ if (isEmpty(value)) return void 0;
3513
+ const n = typeof value === "number" ? value : parseFloat(String(value));
3514
+ if (isNaN(n)) return void 0;
3515
+ const min = Number(arg);
3516
+ return n >= min ? void 0 : `Must be at least ${min}`;
3517
+ },
3518
+ max: (value, arg) => {
3519
+ if (isEmpty(value)) return void 0;
3520
+ const n = typeof value === "number" ? value : parseFloat(String(value));
3521
+ if (isNaN(n)) return void 0;
3522
+ const max = Number(arg);
3523
+ return n <= max ? void 0 : `Must be no more than ${max}`;
3524
+ },
3525
+ minLength: (value, arg) => {
3526
+ if (isEmpty(value)) return void 0;
3527
+ if (typeof value !== "string") return void 0;
3528
+ const min = Number(arg);
3529
+ return value.length >= min ? void 0 : `Must be at least ${min} characters`;
3530
+ },
3531
+ maxLength: (value, arg) => {
3532
+ if (isEmpty(value)) return void 0;
3533
+ if (typeof value !== "string") return void 0;
3534
+ const max = Number(arg);
3535
+ return value.length <= max ? void 0 : `Must be no more than ${max} characters`;
3536
+ },
3537
+ pattern: (value, arg) => {
3538
+ if (isEmpty(value)) return void 0;
3539
+ if (typeof value !== "string" || typeof arg !== "string") return void 0;
3540
+ try {
3541
+ return new RegExp(arg).test(value) ? void 0 : "Invalid format";
3542
+ } catch {
3543
+ return;
3544
+ }
3545
+ }
3546
+ };
3547
+ /**
3548
+ * Run all rules against a value. Stop on first error.
3549
+ * Custom validators are checked first, then built-in ones.
3550
+ */
3551
+ function validate(value, rules, customValidators) {
3552
+ for (const rule of rules) {
3553
+ const validator = customValidators?.[rule.type] ?? builtInValidators[rule.type];
3554
+ if (!validator) {
3555
+ console.warn(`[openui] Unknown validation rule type: "${rule.type}"`);
3556
+ continue;
3557
+ }
3558
+ const error = validator(value, rule.arg);
3559
+ if (error) return error;
3560
+ }
3561
+ }
3562
+ /**
3563
+ * Parse a structured rules object into ParsedRule[].
3564
+ * Accepts: { required: true, minLength: 5, email: true, max: 100 }
3565
+ * Skips keys with false/undefined values.
3566
+ */
3567
+ function parseStructuredRules(rules) {
3568
+ if (!rules || typeof rules !== "object" || Array.isArray(rules)) return [];
3569
+ const obj = rules;
3570
+ const result = [];
3571
+ for (const [key, val] of Object.entries(obj)) {
3572
+ if (val === false || val === void 0 || val === null) continue;
3573
+ if (val === true) result.push({ type: key });
3574
+ else result.push({
3575
+ type: key,
3576
+ arg: val
3577
+ });
3578
+ }
3579
+ return result;
3580
+ }
3257
3581
 
3258
3582
  //#endregion
3259
3583
  //#region ../../node_modules/.pnpm/@openuidev+react-lang@0.2.8_@modelcontextprotocol+sdk@1.29.0_zod@4.4.3__react@19.2.8_zod@4.4.3/node_modules/@openuidev/react-lang/dist/index.mjs
@@ -3278,7 +3602,89 @@ function useOpenUI() {
3278
3602
  function useRenderNode() {
3279
3603
  return useOpenUI().renderNode;
3280
3604
  }
3605
+ /**
3606
+ * Get the triggerAction function for firing structured action events.
3607
+ *
3608
+ * @example
3609
+ * ```tsx
3610
+ * const triggerAction = useTriggerAction();
3611
+ * <button onClick={() => triggerAction("Submit", "myForm")}>
3612
+ * ```
3613
+ */
3614
+ function useTriggerAction() {
3615
+ return useOpenUI().triggerAction;
3616
+ }
3617
+ /**
3618
+ * Whether the LLM is currently streaming content.
3619
+ */
3620
+ function useIsStreaming() {
3621
+ return useOpenUI().isStreaming;
3622
+ }
3623
+ /**
3624
+ * Whether any Query is currently fetching data.
3625
+ * Useful for showing skeleton/loading states in data-driven components.
3626
+ */
3627
+ function useIsQueryLoading() {
3628
+ return useOpenUI().isQueryLoading;
3629
+ }
3630
+ /**
3631
+ * Get a form field value from the form state context.
3632
+ *
3633
+ * @example
3634
+ * ```tsx
3635
+ * const getFieldValue = useGetFieldValue();
3636
+ * const name = getFieldValue("contactForm", "name");
3637
+ * ```
3638
+ */
3639
+ function useGetFieldValue() {
3640
+ return useOpenUI().getFieldValue;
3641
+ }
3642
+ /**
3643
+ * Get the setFieldValue function for updating form field values.
3644
+ *
3645
+ * @example
3646
+ * ```tsx
3647
+ * const setFieldValue = useSetFieldValue();
3648
+ * <input onChange={(e) => setFieldValue("contactForm", "Input", "name", e.target.value, false)} />
3649
+ * ```
3650
+ */
3651
+ function useSetFieldValue() {
3652
+ return useOpenUI().setFieldValue;
3653
+ }
3281
3654
  const FormNameContext = createContext(void 0);
3655
+ /**
3656
+ * Get the current form name (set by the nearest parent Form component).
3657
+ * Returns undefined if not inside a Form.
3658
+ */
3659
+ function useFormName() {
3660
+ return useContext(FormNameContext);
3661
+ }
3662
+ /**
3663
+ * Persists a component's default/initial value into form state once streaming
3664
+ * finishes — but only if the user hasn't already set a value.
3665
+ *
3666
+ * Call this inside any form component that has a `defaultValue` or
3667
+ * `defaultChecked` prop. It is a no-op during streaming so that LLM
3668
+ * prop changes don't fight with partial state.
3669
+ *
3670
+ * @param shouldTriggerSaveCallback — defaults to `false` (only local state, no message persistence)
3671
+ */
3672
+ function useSetDefaultValue({ formName, componentType, name, existingValue, defaultValue, shouldTriggerSaveCallback = false }) {
3673
+ const setFieldValue = useSetFieldValue();
3674
+ const isStreaming = useIsStreaming();
3675
+ useEffect(() => {
3676
+ if (!isStreaming && existingValue === void 0 && defaultValue !== void 0) setFieldValue(formName, componentType, name, defaultValue, shouldTriggerSaveCallback);
3677
+ }, [
3678
+ defaultValue,
3679
+ existingValue,
3680
+ formName,
3681
+ componentType,
3682
+ name,
3683
+ isStreaming,
3684
+ setFieldValue,
3685
+ shouldTriggerSaveCallback
3686
+ ]);
3687
+ }
3282
3688
  /** Unwrap { value, componentType } wrapper from form field entries. Returns raw value. */
3283
3689
  function unwrapFieldValue(v) {
3284
3690
  if (v && typeof v === "object" && !Array.isArray(v) && "value" in v) return v.value;
@@ -3758,29 +4164,91 @@ function Renderer({ response, library, isStreaming = false, onAction, onStateUpd
3758
4164
  })
3759
4165
  });
3760
4166
  }
3761
- const FormValidationContext = createContext(null);
3762
-
3763
- //#endregion
3764
- //#region ../ui-react/dist/openUiLibrary-BKXW7Iwx.js
3765
- const propsFor = (props, container) => container ? props.extend({ children: z.array(z.any()).optional() }) : props;
3766
4167
  /**
3767
- * catalog OpenUI 投影:`defineComponent` 复用同一份 zod schema 与描述,
3768
- * 渲染实现取自共享的 ui-kit 组件表,因此 OpenUI 档渲染的是我们的设计系统而不是 OpenUI 默认组件。
4168
+ * Mark a schema prop as reactive so runtime evaluation can preserve $bindings.
4169
+ *
4170
+ * The widened return type carries the eventual value shape into helpers like
4171
+ * `useStateField()`. The actual bound value is still resolved at render time.
3769
4172
  */
3770
- const webskillOpenUiLibrary = createLibrary({
3771
- id: "webskill-shadcn",
3772
- components: uiCatalog.components.map((def) => defineComponent({
3773
- name: def.name,
3774
- description: def.description,
3775
- props: propsFor(def.props, def.children !== void 0),
3776
- component: ((input) => /* @__PURE__ */ jsx(CatalogNode, {
3777
- name: def.name,
3778
- props: input.props,
3779
- children: input.renderNode(input.props["children"])
3780
- }))
3781
- }))
3782
- });
3783
- const OPEN_UI_COMPONENTS = Object.keys(webskillOpenUiLibrary.components);
4173
+ function reactive(schema) {
4174
+ markReactive(schema);
4175
+ return schema;
4176
+ }
4177
+ function useStateField(name, value) {
4178
+ const ctx = useOpenUI();
4179
+ const formName = useFormName();
4180
+ return resolveStateField(name, value, ctx.store ?? null, ctx.evaluationContext ?? null, (fieldName) => ctx.getFieldValue(formName, fieldName), (fieldName, nextValue) => ctx.setFieldValue(formName, void 0, fieldName, nextValue));
4181
+ }
4182
+ const FormValidationContext = createContext(null);
4183
+ function useFormValidation() {
4184
+ return useContext(FormValidationContext);
4185
+ }
4186
+ function useCreateFormValidation() {
4187
+ const [errors, setErrors] = useState({});
4188
+ const errorsRef = useRef(errors);
4189
+ errorsRef.current = errors;
4190
+ const fieldsRef = useRef({});
4191
+ const getFieldError = useCallback((name) => errorsRef.current[name], []);
4192
+ const validateField = useCallback((name, value, rules) => {
4193
+ const error = validate(value, rules);
4194
+ setErrors((prev) => {
4195
+ if (prev[name] === error) return prev;
4196
+ return {
4197
+ ...prev,
4198
+ [name]: error
4199
+ };
4200
+ });
4201
+ return !error;
4202
+ }, []);
4203
+ const registerField = useCallback((name, rules, getValue) => {
4204
+ fieldsRef.current[name] = {
4205
+ rules,
4206
+ getValue
4207
+ };
4208
+ }, []);
4209
+ const unregisterField = useCallback((name) => {
4210
+ delete fieldsRef.current[name];
4211
+ }, []);
4212
+ const validateForm = useCallback(() => {
4213
+ let allValid = true;
4214
+ const newErrors = {};
4215
+ for (const [name, reg] of Object.entries(fieldsRef.current)) {
4216
+ let value = reg.getValue();
4217
+ if (value != null && typeof value === "object" && "value" in value && "componentType" in value) value = value.value;
4218
+ const error = validate(value, reg.rules);
4219
+ newErrors[name] = error;
4220
+ if (error) allValid = false;
4221
+ }
4222
+ setErrors(newErrors);
4223
+ return allValid;
4224
+ }, []);
4225
+ const clearFieldError = useCallback((name) => {
4226
+ setErrors((prev) => {
4227
+ if (prev[name] === void 0) return prev;
4228
+ return {
4229
+ ...prev,
4230
+ [name]: void 0
4231
+ };
4232
+ });
4233
+ }, []);
4234
+ return useMemo(() => ({
4235
+ errors,
4236
+ getFieldError,
4237
+ validateField,
4238
+ registerField,
4239
+ unregisterField,
4240
+ validateForm,
4241
+ clearFieldError
4242
+ }), [
4243
+ errors,
4244
+ getFieldError,
4245
+ validateField,
4246
+ registerField,
4247
+ unregisterField,
4248
+ validateForm,
4249
+ clearFieldError
4250
+ ]);
4251
+ }
3784
4252
 
3785
4253
  //#endregion
3786
- export { OPEN_UI_COMPONENTS, Renderer, webskillOpenUiLibrary };
4254
+ export { ACTION_STEPS, BuiltinActionType, FormNameContext, FormValidationContext, Renderer, ToolNotFoundError, builtInValidators, createLibrary, createParser, createStreamingParser, defineComponent, extractToolResult, generatePrompt, isReactiveAssign, mergeStatements, parseRules, parseStructuredRules, reactive, tagSchemaId, useCreateFormValidation, useFormName, useFormValidation, useGetFieldValue, useIsQueryLoading, useIsStreaming, useRenderNode, useSetDefaultValue, useSetFieldValue, useStateField, useTriggerAction, validate };
@@ -1,4 +1,4 @@
1
- import { r as __exportAll } from "./rolldown-runtime-BOF7iYI8.js";
1
+ import { r as __exportAll } from "./rolldown-runtime-BHkdefai.js";
2
2
 
3
3
  //#region ../../node_modules/.pnpm/tslib@2.3.0/node_modules/tslib/tslib.es6.js
4
4
  /*! *****************************************************************************
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from "node:fs";
2
2
 
3
- //#region ../node/dist/env-8cY40DXB.js
3
+ //#region ../node/src/env.ts
4
4
  /** 解析 .env(简单 KEY=VALUE 行解析,不引依赖);文件缺失返回 undefined */
5
5
  function readEnvVars(dotenvPath) {
6
6
  let raw;
@@ -0,0 +1,22 @@
1
+ //#region ../core/src/errors.ts
2
+ /**
3
+ * 所有公开 API 抛出的结构化错误,code 供上层可编程处理
4
+ * @stable
5
+ */
6
+ var WebSkillError = class extends Error {
7
+ code;
8
+ details;
9
+ constructor(code, message, details) {
10
+ super(message);
11
+ this.name = "WebSkillError";
12
+ this.code = code;
13
+ this.details = details;
14
+ }
15
+ };
16
+ /** unknown 异常取消息文本(全仓单一来源,勿再本地重复定义) */
17
+ function messageOf(e) {
18
+ return e instanceof Error ? e.message : String(e);
19
+ }
20
+
21
+ //#endregion
22
+ export { messageOf as n, WebSkillError as t };
@@ -1,4 +1,4 @@
1
- //#region ../governance/dist/eventTypes-FllCrX-Z.js
1
+ //#region ../governance/src/audit/eventTypes.ts
2
2
  /**
3
3
  * 审计事件类型常量(FR-13.4)。
4
4
  *
@@ -38,12 +38,24 @@ const AUDIT_EVENT_TYPES = {
38
38
  candidateSubmitted: "candidate.submitted",
39
39
  candidateApproved: "candidate.approved",
40
40
  candidateRejected: "candidate.rejected",
41
+ /** 候选记录被从审批队列里删除(仅 draft / pending-review / rejected 可删) */
42
+ candidateRemoved: "candidate.removed",
41
43
  pagePerceived: "page.perceived",
42
44
  pageAction: "page.action",
45
+ /**
46
+ * 一次页面操作引发了下载,但 `sandbox.downloadedFiles` 关着,模型因此一无所知
47
+ * (0.15.0 分册 15 · FR-15.7)。载荷只有计数与原因,不含文件名 / 大小 / 类型。
48
+ */
49
+ pageDownloadUnreported: "page.download.unreported",
43
50
  documentRead: "document.read",
44
51
  documentSurfaceOpen: "document.surface.open",
45
52
  /** 脚本按宿主声明的数据源取数(分册 16);被拒也记,否则反复试探看不见 */
46
- dataFetched: "data.fetch"
53
+ dataFetched: "data.fetch",
54
+ /**
55
+ * 技能脚本读用户本轮上传的文件(0.15.0 分册 17 · FR-17.7)。
56
+ * 载荷记文件名 / 类型 / 字节数与是否被拒,**不含文件内容**。
57
+ */
58
+ uploadFileRead: "upload.file.read"
47
59
  };
48
60
  /** 稳定展示序:筛选下拉与文档表格都从这里取,不各自维护一份顺序 */
49
61
  const AUDIT_EVENT_TYPE_LIST = Object.values(AUDIT_EVENT_TYPES);