dsh-run2skill 0.3.0 → 0.4.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.
package/lib/client.js CHANGED
@@ -614,6 +614,7 @@ window.__ModuleLoader__.load({
614
614
  const integer = /^-?\d+$/;
615
615
  const number$1 = /^-?\d+(?:\.\d+)?$/;
616
616
  const boolean$1 = /^(?:true|false)$/i;
617
+ const _null$2 = /^null$/i;
617
618
  const lowercase = /^[^A-Z]*$/;
618
619
  const uppercase = /^[^a-z]*$/;
619
620
  //#endregion
@@ -1430,6 +1431,22 @@ window.__ModuleLoader__.load({
1430
1431
  return payload;
1431
1432
  };
1432
1433
  });
1434
+ const $ZodNull = /*@__PURE__*/ $constructor("$ZodNull", (inst, def) => {
1435
+ $ZodType.init(inst, def);
1436
+ inst._zod.pattern = _null$2;
1437
+ inst._zod.values = /* @__PURE__ */ new Set([null]);
1438
+ inst._zod.parse = (payload, _ctx) => {
1439
+ const input = payload.value;
1440
+ if (input === null) return payload;
1441
+ payload.issues.push({
1442
+ expected: "null",
1443
+ code: "invalid_type",
1444
+ input,
1445
+ inst
1446
+ });
1447
+ return payload;
1448
+ };
1449
+ });
1433
1450
  const $ZodUnknown = /*@__PURE__*/ $constructor("$ZodUnknown", (inst, def) => {
1434
1451
  $ZodType.init(inst, def);
1435
1452
  inst._zod.parse = (payload) => payload;
@@ -1929,6 +1946,115 @@ window.__ModuleLoader__.load({
1929
1946
  result.value = merged.data;
1930
1947
  return result;
1931
1948
  }
1949
+ const $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
1950
+ $ZodType.init(inst, def);
1951
+ inst._zod.parse = (payload, ctx) => {
1952
+ const input = payload.value;
1953
+ if (!isPlainObject(input)) {
1954
+ payload.issues.push({
1955
+ expected: "record",
1956
+ code: "invalid_type",
1957
+ input,
1958
+ inst
1959
+ });
1960
+ return payload;
1961
+ }
1962
+ const proms = [];
1963
+ const values = def.keyType._zod.values;
1964
+ if (values) {
1965
+ payload.value = {};
1966
+ const recordKeys = /* @__PURE__ */ new Set();
1967
+ for (const key of values) if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
1968
+ recordKeys.add(typeof key === "number" ? key.toString() : key);
1969
+ const keyResult = def.keyType._zod.run({
1970
+ value: key,
1971
+ issues: []
1972
+ }, ctx);
1973
+ if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
1974
+ if (keyResult.issues.length) {
1975
+ payload.issues.push({
1976
+ code: "invalid_key",
1977
+ origin: "record",
1978
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
1979
+ input: key,
1980
+ path: [key],
1981
+ inst
1982
+ });
1983
+ continue;
1984
+ }
1985
+ const outKey = keyResult.value;
1986
+ const result = def.valueType._zod.run({
1987
+ value: input[key],
1988
+ issues: []
1989
+ }, ctx);
1990
+ if (result instanceof Promise) proms.push(result.then((result) => {
1991
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
1992
+ payload.value[outKey] = result.value;
1993
+ }));
1994
+ else {
1995
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
1996
+ payload.value[outKey] = result.value;
1997
+ }
1998
+ }
1999
+ let unrecognized;
2000
+ for (const key in input) if (!recordKeys.has(key)) {
2001
+ unrecognized = unrecognized ?? [];
2002
+ unrecognized.push(key);
2003
+ }
2004
+ if (unrecognized && unrecognized.length > 0) payload.issues.push({
2005
+ code: "unrecognized_keys",
2006
+ input,
2007
+ inst,
2008
+ keys: unrecognized
2009
+ });
2010
+ } else {
2011
+ payload.value = {};
2012
+ for (const key of Reflect.ownKeys(input)) {
2013
+ if (key === "__proto__") continue;
2014
+ if (!Object.prototype.propertyIsEnumerable.call(input, key)) continue;
2015
+ let keyResult = def.keyType._zod.run({
2016
+ value: key,
2017
+ issues: []
2018
+ }, ctx);
2019
+ if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
2020
+ if (typeof key === "string" && number$1.test(key) && keyResult.issues.length) {
2021
+ const retryResult = def.keyType._zod.run({
2022
+ value: Number(key),
2023
+ issues: []
2024
+ }, ctx);
2025
+ if (retryResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
2026
+ if (retryResult.issues.length === 0) keyResult = retryResult;
2027
+ }
2028
+ if (keyResult.issues.length) {
2029
+ if (def.mode === "loose") payload.value[key] = input[key];
2030
+ else payload.issues.push({
2031
+ code: "invalid_key",
2032
+ origin: "record",
2033
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
2034
+ input: key,
2035
+ path: [key],
2036
+ inst
2037
+ });
2038
+ continue;
2039
+ }
2040
+ const result = def.valueType._zod.run({
2041
+ value: input[key],
2042
+ issues: []
2043
+ }, ctx);
2044
+ if (result instanceof Promise) proms.push(result.then((result) => {
2045
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
2046
+ payload.value[keyResult.value] = result.value;
2047
+ }));
2048
+ else {
2049
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
2050
+ payload.value[keyResult.value] = result.value;
2051
+ }
2052
+ }
2053
+ }
2054
+ if (proms.length) return Promise.all(proms).then(() => payload);
2055
+ return payload;
2056
+ };
2057
+ });
1932
2058
  const $ZodEnum = /*@__PURE__*/ $constructor("$ZodEnum", (inst, def) => {
1933
2059
  $ZodType.init(inst, def);
1934
2060
  const values = getEnumValues(def.entries);
@@ -2167,6 +2293,21 @@ window.__ModuleLoader__.load({
2167
2293
  payload.value = Object.freeze(payload.value);
2168
2294
  return payload;
2169
2295
  }
2296
+ const $ZodLazy = /*@__PURE__*/ $constructor("$ZodLazy", (inst, def) => {
2297
+ $ZodType.init(inst, def);
2298
+ defineLazy(inst._zod, "innerType", () => {
2299
+ const d = def;
2300
+ if (!d._cachedInner) d._cachedInner = def.getter();
2301
+ return d._cachedInner;
2302
+ });
2303
+ defineLazy(inst._zod, "pattern", () => inst._zod.innerType?._zod?.pattern);
2304
+ defineLazy(inst._zod, "propValues", () => inst._zod.innerType?._zod?.propValues);
2305
+ defineLazy(inst._zod, "optin", () => inst._zod.innerType?._zod?.optin ?? void 0);
2306
+ defineLazy(inst._zod, "optout", () => inst._zod.innerType?._zod?.optout ?? void 0);
2307
+ inst._zod.parse = (payload, ctx) => {
2308
+ return inst._zod.innerType._zod.run(payload, ctx);
2309
+ };
2310
+ });
2170
2311
  const $ZodCustom = /*@__PURE__*/ $constructor("$ZodCustom", (inst, def) => {
2171
2312
  $ZodCheck.init(inst, def);
2172
2313
  $ZodType.init(inst, def);
@@ -2543,6 +2684,13 @@ window.__ModuleLoader__.load({
2543
2684
  });
2544
2685
  }
2545
2686
  // @__NO_SIDE_EFFECTS__
2687
+ function _null$1(Class, params) {
2688
+ return new Class({
2689
+ type: "null",
2690
+ ...normalizeParams(params)
2691
+ });
2692
+ }
2693
+ // @__NO_SIDE_EFFECTS__
2546
2694
  function _unknown(Class) {
2547
2695
  return new Class({ type: "unknown" });
2548
2696
  }
@@ -3095,6 +3243,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3095
3243
  const booleanProcessor = (_schema, _ctx, json, _params) => {
3096
3244
  json.type = "boolean";
3097
3245
  };
3246
+ const nullProcessor = (_schema, ctx, json, _params) => {
3247
+ if (ctx.target === "openapi-3.0") {
3248
+ json.type = "string";
3249
+ json.nullable = true;
3250
+ json.enum = [null];
3251
+ } else json.type = "null";
3252
+ };
3098
3253
  const neverProcessor = (_schema, _ctx, json, _params) => {
3099
3254
  json.not = {};
3100
3255
  };
@@ -3209,6 +3364,39 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3209
3364
  const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1;
3210
3365
  json.allOf = [...isSimpleIntersection(a) ? a.allOf : [a], ...isSimpleIntersection(b) ? b.allOf : [b]];
3211
3366
  };
3367
+ const recordProcessor = (schema, ctx, _json, params) => {
3368
+ const json = _json;
3369
+ const def = schema._zod.def;
3370
+ json.type = "object";
3371
+ const keyType = def.keyType;
3372
+ const patterns = keyType._zod.bag?.patterns;
3373
+ if (def.mode === "loose" && patterns && patterns.size > 0) {
3374
+ const valueSchema = process(def.valueType, ctx, {
3375
+ ...params,
3376
+ path: [
3377
+ ...params.path,
3378
+ "patternProperties",
3379
+ "*"
3380
+ ]
3381
+ });
3382
+ json.patternProperties = {};
3383
+ for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
3384
+ } else {
3385
+ if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process(def.keyType, ctx, {
3386
+ ...params,
3387
+ path: [...params.path, "propertyNames"]
3388
+ });
3389
+ json.additionalProperties = process(def.valueType, ctx, {
3390
+ ...params,
3391
+ path: [...params.path, "additionalProperties"]
3392
+ });
3393
+ }
3394
+ const keyValues = keyType._zod.values;
3395
+ if (keyValues) {
3396
+ const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
3397
+ if (validKeyValues.length > 0) json.required = validKeyValues;
3398
+ }
3399
+ };
3212
3400
  const nullableProcessor = (schema, ctx, json, params) => {
3213
3401
  const def = schema._zod.def;
3214
3402
  const inner = process(def.innerType, ctx, params);
@@ -3272,6 +3460,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3272
3460
  const seen = ctx.seen.get(schema);
3273
3461
  seen.ref = def.innerType;
3274
3462
  };
3463
+ const lazyProcessor = (schema, ctx, _json, params) => {
3464
+ const innerType = schema._zod.innerType;
3465
+ process(innerType, ctx, params);
3466
+ const seen = ctx.seen.get(schema);
3467
+ seen.ref = innerType;
3468
+ };
3275
3469
  //#endregion
3276
3470
  //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/iso.js
3277
3471
  const ZodISODateTime = /*@__PURE__*/ $constructor("ZodISODateTime", (inst, def) => {
@@ -3753,6 +3947,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3753
3947
  function boolean(params) {
3754
3948
  return /* @__PURE__ */ _boolean(ZodBoolean, params);
3755
3949
  }
3950
+ const ZodNull = /*@__PURE__*/ $constructor("ZodNull", (inst, def) => {
3951
+ $ZodNull.init(inst, def);
3952
+ ZodType.init(inst, def);
3953
+ inst._zod.processJSONSchema = (ctx, json, params) => nullProcessor(inst, ctx, json, params);
3954
+ });
3955
+ function _null(params) {
3956
+ return /* @__PURE__ */ _null$1(ZodNull, params);
3957
+ }
3756
3958
  const ZodUnknown = /*@__PURE__*/ $constructor("ZodUnknown", (inst, def) => {
3757
3959
  $ZodUnknown.init(inst, def);
3758
3960
  ZodType.init(inst, def);
@@ -3904,6 +4106,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3904
4106
  right
3905
4107
  });
3906
4108
  }
4109
+ const ZodRecord = /*@__PURE__*/ $constructor("ZodRecord", (inst, def) => {
4110
+ $ZodRecord.init(inst, def);
4111
+ ZodType.init(inst, def);
4112
+ inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params);
4113
+ inst.keyType = def.keyType;
4114
+ inst.valueType = def.valueType;
4115
+ });
4116
+ function record(keyType, valueType, params) {
4117
+ if (!valueType || !valueType._zod) return new ZodRecord({
4118
+ type: "record",
4119
+ keyType: string(),
4120
+ valueType: keyType,
4121
+ ...normalizeParams(valueType)
4122
+ });
4123
+ return new ZodRecord({
4124
+ type: "record",
4125
+ keyType,
4126
+ valueType,
4127
+ ...normalizeParams(params)
4128
+ });
4129
+ }
3907
4130
  const ZodEnum = /*@__PURE__*/ $constructor("ZodEnum", (inst, def) => {
3908
4131
  $ZodEnum.init(inst, def);
3909
4132
  ZodType.init(inst, def);
@@ -4113,6 +4336,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4113
4336
  innerType
4114
4337
  });
4115
4338
  }
4339
+ const ZodLazy = /*@__PURE__*/ $constructor("ZodLazy", (inst, def) => {
4340
+ $ZodLazy.init(inst, def);
4341
+ ZodType.init(inst, def);
4342
+ inst._zod.processJSONSchema = (ctx, json, params) => lazyProcessor(inst, ctx, json, params);
4343
+ inst.unwrap = () => inst._zod.def.getter();
4344
+ });
4345
+ function lazy(getter) {
4346
+ return new ZodLazy({
4347
+ type: "lazy",
4348
+ getter
4349
+ });
4350
+ }
4116
4351
  const ZodCustom = /*@__PURE__*/ $constructor("ZodCustom", (inst, def) => {
4117
4352
  $ZodCustom.init(inst, def);
4118
4353
  ZodType.init(inst, def);
@@ -4124,37 +4359,130 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4124
4359
  function superRefine(fn, params) {
4125
4360
  return /* @__PURE__ */ _superRefine(fn, params);
4126
4361
  }
4362
+ function json(params) {
4363
+ const jsonSchema = lazy(() => {
4364
+ return union([
4365
+ string(params),
4366
+ number(),
4367
+ boolean(),
4368
+ _null(),
4369
+ array(jsonSchema),
4370
+ record(string(), jsonSchema)
4371
+ ]);
4372
+ });
4373
+ return jsonSchema;
4374
+ }
4127
4375
  //#endregion
4128
- //#region src/domain/observe/observe-summary.ts
4129
- const safeCount = number().refine((value) => Number.isSafeInteger(value) && value >= 0, "Expected a non-negative safe integer");
4130
- const ObserveSummaryV1Schema = object({
4131
- apiVersion: literal(1),
4132
- status: _enum([
4133
- "READY",
4134
- "RECOVERING",
4135
- "DEGRADED",
4136
- "INCOMPATIBLE"
4137
- ]),
4138
- capturedCount: safeCount,
4139
- blockedCaptureCount: safeCount,
4140
- learning: object({
4141
- captured: safeCount,
4142
- analyzing: safeCount,
4143
- learned: safeCount,
4144
- needsAttention: safeCount
4145
- }).strict().optional(),
4146
- unsaved: object({
4147
- completeness: _enum(["KNOWN", "UNKNOWN"]),
4148
- knownCount: safeCount
4149
- }).strict(),
4150
- recoveryLag: boolean(),
4151
- lastRecoveryProgressAt: string().datetime({ offset: true }).optional(),
4152
- lastHealthCode: string().regex(/^[A-Z][A-Z0-9_]{0,63}$/).optional()
4376
+ //#region src/adapters/dsh-remote/contract.ts
4377
+ const RUN2SKILL_QUERY_ENDPOINTS = [
4378
+ "observe-summary",
4379
+ "attention",
4380
+ "proposals/list",
4381
+ "summary",
4382
+ "proposals/get",
4383
+ "recent-activity/list",
4384
+ "learning/status",
4385
+ "learning/issues/list",
4386
+ "purge/preview",
4387
+ "purge/status"
4388
+ ];
4389
+ const RUN2SKILL_COMMAND_ENDPOINTS = [
4390
+ "proposals/approve",
4391
+ "proposals/reject",
4392
+ "proposals/retry",
4393
+ "proposals/refresh",
4394
+ "proposals/revise",
4395
+ "coverage/confirm-discard",
4396
+ "learning/request",
4397
+ "learning/issues/retry",
4398
+ "learning/issues/dismiss",
4399
+ "purge/confirm",
4400
+ "purge/retry"
4401
+ ];
4402
+ const queryEndpoints = new Set(RUN2SKILL_QUERY_ENDPOINTS);
4403
+ const commandEndpoints = new Set(RUN2SKILL_COMMAND_ENDPOINTS);
4404
+ function routeRun2skillEndpoint(endpoint) {
4405
+ if (queryEndpoints.has(endpoint)) return "query";
4406
+ if (commandEndpoints.has(endpoint)) return "command";
4407
+ throw new TypeError(`unknown run2skill endpoint: ${endpoint}`);
4408
+ }
4409
+ const jsonValue = json();
4410
+ const queryRequest = object({
4411
+ endpoint: _enum(RUN2SKILL_QUERY_ENDPOINTS),
4412
+ payload: jsonValue
4413
+ }).strict();
4414
+ const commandRequest = object({
4415
+ endpoint: _enum(RUN2SKILL_COMMAND_ENDPOINTS),
4416
+ payload: jsonValue
4153
4417
  }).strict();
4418
+ const rpcResult = discriminatedUnion("ok", [object({
4419
+ ok: literal(true),
4420
+ value: jsonValue
4421
+ }).strict(), object({
4422
+ ok: literal(false),
4423
+ error: object({
4424
+ code: string().min(1),
4425
+ message: string(),
4426
+ details: record(string(), jsonValue)
4427
+ }).strict()
4428
+ }).strict()]);
4429
+ function descriptor(method, requestSchema) {
4430
+ const value = {
4431
+ id: `dsh-run2skill#run2skill/${method}`,
4432
+ service: "run2skillRemote",
4433
+ namespace: "run2skill",
4434
+ method,
4435
+ invocation: { kind: "direct" },
4436
+ parameters: [{
4437
+ name: "request",
4438
+ wire: "request",
4439
+ source: "json",
4440
+ codec: {
4441
+ mode: "strict",
4442
+ typeSymbol: method === "query" ? "Run2skillQueryRequest" : "Run2skillCommandRequest",
4443
+ schema: requestSchema
4444
+ }
4445
+ }],
4446
+ cancellation: { parameter: "signal" },
4447
+ result: {
4448
+ mode: "strict",
4449
+ typeSymbol: "Run2skillRpcResult",
4450
+ schema: rpcResult
4451
+ }
4452
+ };
4453
+ return Object.freeze(value);
4454
+ }
4455
+ const RUN2SKILL_REMOTE_DESCRIPTORS = Object.freeze([descriptor("query", queryRequest), descriptor("command", commandRequest)]);
4456
+ const RUN2SKILL_REMOTE = Object.freeze({
4457
+ package: "dsh-run2skill",
4458
+ descriptors: RUN2SKILL_REMOTE_DESCRIPTORS
4459
+ });
4154
4460
  //#endregion
4155
- //#region src/adapters/dsh-connection/observe-summary-rpc.ts
4156
- const RUN2SKILL_RPC_CHANNEL = "/run2skill";
4157
- object({ apiVersion: literal(1) }).strict();
4461
+ //#region src/adapters/dsh-remote/client.ts
4462
+ function carrierFailure(error) {
4463
+ return {
4464
+ ok: false,
4465
+ error: {
4466
+ code: error.code,
4467
+ message: error.message,
4468
+ details: error.details
4469
+ }
4470
+ };
4471
+ }
4472
+ async function createRun2skillRemoteCaller(remote) {
4473
+ return {
4474
+ dispose: await remote.$mount(RUN2SKILL_REMOTE),
4475
+ async call(endpoint, payload, signal) {
4476
+ const route = routeRun2skillEndpoint(endpoint);
4477
+ const request = {
4478
+ endpoint,
4479
+ payload
4480
+ };
4481
+ const result = route === "query" ? await remote.run2skill.query(request, signal) : await remote.run2skill.command(request, signal);
4482
+ return result.ok ? result.value : carrierFailure(result.error);
4483
+ }
4484
+ };
4485
+ }
4158
4486
  //#endregion
4159
4487
  //#region src/client/dialog-focus.ts
4160
4488
  const focusableSelector = [
@@ -4219,48 +4547,50 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4219
4547
  }
4220
4548
  //#endregion
4221
4549
  //#region \0run2skill-css:run2skill-settings-page.module.css.mjs
4222
- const css = ".run2skill_page_R4wX7a{width:min(100%,1040px);color:var(--dsw-alias-label-primary);gap:24px;padding:16px 0 48px;display:grid}.run2skill_intro_R4wX7a,.run2skill_muted_R4wX7a{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:1.5}.run2skill_section_R4wX7a{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);box-shadow:0 1px 2px var(--dsw-alias-border-l1);border-radius:16px;overflow:hidden}.run2skill_sectionHeader_R4wX7a{box-sizing:border-box;height:auto;min-height:56px;padding:14px 20px}.run2skill_sectionTitle_R4wX7a{font-size:15px}.run2skill_sectionBody_R4wX7a{gap:18px;padding:12px 24px 24px 56px;display:grid;container-type:inline-size}.run2skill_attentionGroup_R4wX7a{gap:16px;min-width:0;display:grid}.run2skill_empty_R4wX7a{min-height:56px;color:var(--dsw-alias-label-secondary);place-items:center;margin:0;font-size:13px;display:grid}.run2skill_toolbar_R4wX7a,.run2skill_actions_R4wX7a,.run2skill_modeGroup_R4wX7a{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.run2skill_attentionList_R4wX7a,.run2skill_proposalList_R4wX7a,.run2skill_activityList_R4wX7a{gap:8px;margin:0;padding:0;list-style:none;display:grid}.run2skill_activityItem_R4wX7a{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:12px;justify-content:space-between;align-items:center;gap:12px;padding:12px 14px;display:flex}.run2skill_activitySummary_R4wX7a{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.run2skill_proposalToolbar_R4wX7a{grid-template-columns:minmax(12rem,1fr) auto;align-items:center;gap:8px;display:grid}.run2skill_proposalToolbar_R4wX7a>:first-child{width:100%}.run2skill_proposalToolbarCompact_R4wX7a{justify-content:flex-end;display:flex}.run2skill_proposalToolbarCompact_R4wX7a>:first-child{width:auto}.run2skill_proposalLayout_R4wX7a{grid-template-columns:1fr;gap:12px;display:grid}.run2skill_proposalListButton_R4wX7a{text-align:start;white-space:normal;overflow-wrap:anywhere;border-radius:10px;flex-direction:column;justify-content:flex-start;align-items:flex-start;gap:2px;width:100%;height:auto;min-height:48px;padding:8px 12px}.run2skill_proposalListButton_R4wX7a[aria-current=true]{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);box-shadow:inset 3px 0 var(--dsw-alias-brand-primary)}.run2skill_proposalName_R4wX7a{max-width:100%;font-size:14px;font-weight:600;line-height:20px}.run2skill_proposalMeta_R4wX7a{max-width:100%;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}.run2skill_detail_R4wX7a{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:12px;min-width:0;max-height:640px;padding:18px;overflow:auto}.run2skill_detail_R4wX7a>:first-child{margin-top:0}.run2skill_detailFacts_R4wX7a{grid-template-columns:minmax(6rem,max-content) minmax(0,1fr);gap:8px 16px;margin:0 0 20px;display:grid}.run2skill_detailFacts_R4wX7a dt{color:var(--dsw-alias-label-secondary);font-size:13px}.run2skill_detailFacts_R4wX7a dd{overflow-wrap:anywhere;min-width:0;margin:0}.run2skill_detail_R4wX7a pre{white-space:pre-wrap;unicode-bidi:isolate;overflow:auto}.run2skill_technicalDetails_R4wX7a{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;margin:16px 0;padding:10px 12px}.run2skill_technicalDetails_R4wX7a summary{cursor:pointer;color:var(--dsw-alias-label-secondary);font-size:13px}.run2skill_technicalDetails_R4wX7a[open] summary{margin-bottom:12px}.run2skill_status_R4wX7a{min-height:20px;margin:0;font-size:13px}.run2skill_danger_R4wX7a{color:var(--dsw-alias-state-error-primary)}.run2skill_backdrop_R4wX7a,.run2skill_rejectOverlay_R4wX7a{background:var(--dsw-alias-bg-mask-1);position:fixed;inset:0}.run2skill_backdrop_R4wX7a{z-index:999}.run2skill_rejectOverlay_R4wX7a{z-index:1001;place-items:center;padding:16px;display:grid}.run2skill_legacyDialog_R4wX7a{z-index:1000;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);box-shadow:0 16px 48px var(--dsw-alias-bg-mask-1);border-radius:16px;grid-template-columns:minmax(16rem,24rem) minmax(0,1fr);gap:16px;padding:16px;display:grid;position:fixed;inset:5vh 5vw;overflow:hidden}.run2skill_blocked_R4wX7a{pointer-events:none;display:contents}.run2skill_queue_R4wX7a,.run2skill_legacyDetail_R4wX7a{min-width:0;overflow:auto}.run2skill_legacyHeader_R4wX7a{justify-content:space-between;align-items:center;gap:8px;display:flex}.run2skill_legacyList_R4wX7a{margin:0;padding:0;list-style:none}.run2skill_rejectCard_R4wX7a{background:var(--dsw-alias-bg-layer-1);border-radius:16px;max-width:32rem;padding:16px}.run2skill_textBlock_R4wX7a{white-space:pre-wrap;overflow-wrap:anywhere;unicode-bidi:isolate;overflow:auto}.run2skill_previewFacts_R4wX7a{grid-template-columns:max-content 1fr;gap:6px 12px;display:grid}.run2skill_previewFacts_R4wX7a dt,.run2skill_previewFacts_R4wX7a dd{margin:0}@container (width>=760px){.run2skill_proposalLayout_R4wX7a{grid-template-columns:minmax(240px,.8fr) minmax(0,1.6fr);gap:20px}}@container (width<=420px){.run2skill_proposalToolbar_R4wX7a,.run2skill_detailFacts_R4wX7a{grid-template-columns:1fr}.run2skill_proposalToolbar_R4wX7a>:last-child{justify-self:start}.run2skill_detailFacts_R4wX7a dt:not(:first-child){margin-top:8px}}@media (width<=720px){.run2skill_sectionBody_R4wX7a{padding:8px 18px 20px}.run2skill_activityItem_R4wX7a{flex-direction:column;align-items:flex-start}}";
4550
+ const css = ".run2skill_page_7aqZFq{width:min(100%,1040px);color:var(--dsw-alias-label-primary);gap:24px;padding:16px 0 48px;display:grid}.run2skill_intro_7aqZFq,.run2skill_muted_7aqZFq{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:1.5}.run2skill_section_7aqZFq{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);box-shadow:0 1px 2px var(--dsw-alias-border-l1);border-radius:16px;overflow:hidden}.run2skill_sectionHeader_7aqZFq{box-sizing:border-box;height:auto;min-height:56px;padding:14px 20px}.run2skill_sectionTitle_7aqZFq{font-size:15px}.run2skill_sectionBody_7aqZFq{gap:18px;padding:12px 24px 24px 56px;display:grid;container-type:inline-size}.run2skill_attentionGroup_7aqZFq{gap:16px;min-width:0;display:grid}.run2skill_empty_7aqZFq{min-height:56px;color:var(--dsw-alias-label-secondary);place-items:center;margin:0;font-size:13px;display:grid}.run2skill_toolbar_7aqZFq,.run2skill_actions_7aqZFq,.run2skill_modeGroup_7aqZFq{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.run2skill_learningStatusRow_7aqZFq{justify-content:space-between;align-items:center;gap:16px;min-width:0;display:flex}.run2skill_learningStatusRow_7aqZFq>:first-child{overflow-wrap:anywhere;min-width:0}@container (width<=30rem){.run2skill_learningStatusRow_7aqZFq{flex-direction:column;align-items:stretch}.run2skill_learningStatusRow_7aqZFq .run2skill_actions_7aqZFq{flex-direction:column;align-items:stretch;width:100%}.run2skill_learningStatusRow_7aqZFq .run2skill_actions_7aqZFq>*{box-sizing:border-box;white-space:normal;overflow-wrap:anywhere;flex:none;width:100%;min-width:0;max-width:100%;height:auto}}.run2skill_attentionList_7aqZFq,.run2skill_proposalList_7aqZFq,.run2skill_activityList_7aqZFq{gap:8px;margin:0;padding:0;list-style:none;display:grid}.run2skill_activityItem_7aqZFq{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:12px;justify-content:space-between;align-items:center;gap:12px;padding:12px 14px;display:flex}.run2skill_activitySummary_7aqZFq{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.run2skill_proposalToolbar_7aqZFq{grid-template-columns:minmax(12rem,1fr) auto;align-items:center;gap:8px;display:grid}.run2skill_proposalToolbar_7aqZFq>:first-child{width:100%}.run2skill_proposalToolbarCompact_7aqZFq{justify-content:flex-end;display:flex}.run2skill_proposalToolbarCompact_7aqZFq>:first-child{width:auto}.run2skill_proposalLayout_7aqZFq{grid-template-columns:1fr;gap:12px;display:grid}.run2skill_proposalListButton_7aqZFq{text-align:start;white-space:normal;overflow-wrap:anywhere;border-radius:10px;flex-direction:column;justify-content:flex-start;align-items:flex-start;gap:2px;width:100%;height:auto;min-height:48px;padding:8px 12px}.run2skill_proposalListButton_7aqZFq[aria-current=true]{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);box-shadow:inset 3px 0 var(--dsw-alias-brand-primary)}.run2skill_proposalName_7aqZFq{max-width:100%;font-size:14px;font-weight:600;line-height:20px}.run2skill_proposalMeta_7aqZFq{max-width:100%;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}.run2skill_detail_7aqZFq{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:12px;min-width:0;max-height:640px;padding:18px;overflow:auto}.run2skill_detail_7aqZFq>:first-child{margin-top:0}.run2skill_detailFacts_7aqZFq{grid-template-columns:minmax(6rem,max-content) minmax(0,1fr);gap:8px 16px;margin:0 0 20px;display:grid}.run2skill_detailFacts_7aqZFq dt{color:var(--dsw-alias-label-secondary);font-size:13px}.run2skill_detailFacts_7aqZFq dd{overflow-wrap:anywhere;min-width:0;margin:0}.run2skill_detail_7aqZFq pre{white-space:pre-wrap;unicode-bidi:isolate;overflow:auto}.run2skill_technicalDetails_7aqZFq{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;margin:16px 0;padding:10px 12px}.run2skill_technicalDetails_7aqZFq summary{cursor:pointer;color:var(--dsw-alias-label-secondary);font-size:13px}.run2skill_technicalDetails_7aqZFq[open] summary{margin-bottom:12px}.run2skill_status_7aqZFq{min-height:20px;margin:0;font-size:13px}.run2skill_revisionBox_7aqZFq{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:12px;gap:8px;margin:18px 0;padding:14px;display:grid}.run2skill_revisionBox_7aqZFq label{font-size:14px;font-weight:600}.run2skill_revisionBox_7aqZFq textarea{box-sizing:border-box;resize:vertical;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);width:100%;min-height:84px;color:var(--dsw-alias-label-primary);font:inherit;border-radius:10px;padding:10px 12px;line-height:1.5}.run2skill_revisionBox_7aqZFq textarea:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.run2skill_revisionBox_7aqZFq textarea:disabled{cursor:not-allowed;opacity:.65}.run2skill_revisionBox_7aqZFq>:last-child{justify-self:start}.run2skill_danger_7aqZFq{color:var(--dsw-alias-state-error-primary)}.run2skill_backdrop_7aqZFq,.run2skill_rejectOverlay_7aqZFq{background:var(--dsw-alias-bg-mask-1);position:fixed;inset:0}.run2skill_backdrop_7aqZFq{z-index:999}.run2skill_rejectOverlay_7aqZFq{z-index:1001;place-items:center;padding:16px;display:grid}.run2skill_legacyDialog_7aqZFq{z-index:1000;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);box-shadow:0 16px 48px var(--dsw-alias-bg-mask-1);border-radius:16px;grid-template-columns:minmax(16rem,24rem) minmax(0,1fr);gap:16px;padding:16px;display:grid;position:fixed;inset:5vh 5vw;overflow:hidden}.run2skill_blocked_7aqZFq{pointer-events:none;display:contents}.run2skill_queue_7aqZFq,.run2skill_legacyDetail_7aqZFq{min-width:0;overflow:auto}.run2skill_legacyHeader_7aqZFq{justify-content:space-between;align-items:center;gap:8px;display:flex}.run2skill_legacyList_7aqZFq{margin:0;padding:0;list-style:none}.run2skill_rejectCard_7aqZFq{background:var(--dsw-alias-bg-layer-1);border-radius:16px;max-width:32rem;padding:16px}.run2skill_textBlock_7aqZFq{white-space:pre-wrap;overflow-wrap:anywhere;unicode-bidi:isolate;overflow:auto}.run2skill_previewFacts_7aqZFq{grid-template-columns:max-content 1fr;gap:6px 12px;display:grid}.run2skill_previewFacts_7aqZFq dt,.run2skill_previewFacts_7aqZFq dd{margin:0}@container (width>=760px){.run2skill_proposalLayout_7aqZFq{grid-template-columns:minmax(240px,.8fr) minmax(0,1.6fr);gap:20px}}@container (width<=420px){.run2skill_proposalToolbar_7aqZFq,.run2skill_detailFacts_7aqZFq{grid-template-columns:1fr}.run2skill_proposalToolbar_7aqZFq>:last-child{justify-self:start}.run2skill_detailFacts_7aqZFq dt:not(:first-child){margin-top:8px}}@media (width<=720px){.run2skill_sectionBody_7aqZFq{padding:8px 18px 20px}.run2skill_activityItem_7aqZFq{flex-direction:column;align-items:flex-start}}";
4223
4551
  if (typeof document !== "undefined") upsertRun2skillStyle(css);
4224
4552
  var _run2skill_css_run2skill_settings_page_module_css_default = {
4225
- "textBlock": "run2skill_textBlock_R4wX7a",
4226
- "previewFacts": "run2skill_previewFacts_R4wX7a",
4227
- "attentionList": "run2skill_attentionList_R4wX7a",
4228
- "rejectCard": "run2skill_rejectCard_R4wX7a",
4229
- "status": "run2skill_status_R4wX7a",
4230
- "empty": "run2skill_empty_R4wX7a",
4231
- "proposalListButton": "run2skill_proposalListButton_R4wX7a",
4232
- "danger": "run2skill_danger_R4wX7a",
4233
- "page": "run2skill_page_R4wX7a",
4234
- "attentionGroup": "run2skill_attentionGroup_R4wX7a",
4235
- "sectionTitle": "run2skill_sectionTitle_R4wX7a",
4236
- "backdrop": "run2skill_backdrop_R4wX7a",
4237
- "blocked": "run2skill_blocked_R4wX7a",
4238
- "actions": "run2skill_actions_R4wX7a",
4239
- "legacyDialog": "run2skill_legacyDialog_R4wX7a",
4240
- "modeGroup": "run2skill_modeGroup_R4wX7a",
4241
- "activityItem": "run2skill_activityItem_R4wX7a",
4242
- "proposalToolbarCompact": "run2skill_proposalToolbarCompact_R4wX7a",
4243
- "detail": "run2skill_detail_R4wX7a",
4244
- "intro": "run2skill_intro_R4wX7a",
4245
- "technicalDetails": "run2skill_technicalDetails_R4wX7a",
4246
- "muted": "run2skill_muted_R4wX7a",
4247
- "activitySummary": "run2skill_activitySummary_R4wX7a",
4248
- "proposalList": "run2skill_proposalList_R4wX7a",
4249
- "detailFacts": "run2skill_detailFacts_R4wX7a",
4250
- "legacyHeader": "run2skill_legacyHeader_R4wX7a",
4251
- "sectionBody": "run2skill_sectionBody_R4wX7a",
4252
- "sectionHeader": "run2skill_sectionHeader_R4wX7a",
4253
- "proposalLayout": "run2skill_proposalLayout_R4wX7a",
4254
- "activityList": "run2skill_activityList_R4wX7a",
4255
- "rejectOverlay": "run2skill_rejectOverlay_R4wX7a",
4256
- "toolbar": "run2skill_toolbar_R4wX7a",
4257
- "section": "run2skill_section_R4wX7a",
4258
- "proposalToolbar": "run2skill_proposalToolbar_R4wX7a",
4259
- "queue": "run2skill_queue_R4wX7a",
4260
- "legacyDetail": "run2skill_legacyDetail_R4wX7a",
4261
- "proposalName": "run2skill_proposalName_R4wX7a",
4262
- "proposalMeta": "run2skill_proposalMeta_R4wX7a",
4263
- "legacyList": "run2skill_legacyList_R4wX7a"
4553
+ "empty": "run2skill_empty_7aqZFq",
4554
+ "sectionHeader": "run2skill_sectionHeader_7aqZFq",
4555
+ "activityList": "run2skill_activityList_7aqZFq",
4556
+ "proposalLayout": "run2skill_proposalLayout_7aqZFq",
4557
+ "rejectCard": "run2skill_rejectCard_7aqZFq",
4558
+ "rejectOverlay": "run2skill_rejectOverlay_7aqZFq",
4559
+ "page": "run2skill_page_7aqZFq",
4560
+ "detailFacts": "run2skill_detailFacts_7aqZFq",
4561
+ "legacyHeader": "run2skill_legacyHeader_7aqZFq",
4562
+ "revisionBox": "run2skill_revisionBox_7aqZFq",
4563
+ "proposalToolbar": "run2skill_proposalToolbar_7aqZFq",
4564
+ "attentionGroup": "run2skill_attentionGroup_7aqZFq",
4565
+ "textBlock": "run2skill_textBlock_7aqZFq",
4566
+ "modeGroup": "run2skill_modeGroup_7aqZFq",
4567
+ "detail": "run2skill_detail_7aqZFq",
4568
+ "proposalList": "run2skill_proposalList_7aqZFq",
4569
+ "backdrop": "run2skill_backdrop_7aqZFq",
4570
+ "proposalToolbarCompact": "run2skill_proposalToolbarCompact_7aqZFq",
4571
+ "legacyDialog": "run2skill_legacyDialog_7aqZFq",
4572
+ "legacyDetail": "run2skill_legacyDetail_7aqZFq",
4573
+ "actions": "run2skill_actions_7aqZFq",
4574
+ "activitySummary": "run2skill_activitySummary_7aqZFq",
4575
+ "activityItem": "run2skill_activityItem_7aqZFq",
4576
+ "attentionList": "run2skill_attentionList_7aqZFq",
4577
+ "sectionBody": "run2skill_sectionBody_7aqZFq",
4578
+ "blocked": "run2skill_blocked_7aqZFq",
4579
+ "muted": "run2skill_muted_7aqZFq",
4580
+ "legacyList": "run2skill_legacyList_7aqZFq",
4581
+ "proposalName": "run2skill_proposalName_7aqZFq",
4582
+ "technicalDetails": "run2skill_technicalDetails_7aqZFq",
4583
+ "queue": "run2skill_queue_7aqZFq",
4584
+ "section": "run2skill_section_7aqZFq",
4585
+ "danger": "run2skill_danger_7aqZFq",
4586
+ "proposalMeta": "run2skill_proposalMeta_7aqZFq",
4587
+ "status": "run2skill_status_7aqZFq",
4588
+ "toolbar": "run2skill_toolbar_7aqZFq",
4589
+ "sectionTitle": "run2skill_sectionTitle_7aqZFq",
4590
+ "proposalListButton": "run2skill_proposalListButton_7aqZFq",
4591
+ "intro": "run2skill_intro_7aqZFq",
4592
+ "learningStatusRow": "run2skill_learningStatusRow_7aqZFq",
4593
+ "previewFacts": "run2skill_previewFacts_7aqZFq"
4264
4594
  };
4265
4595
  //#endregion
4266
4596
  //#region src/client/purge-settings.ts
@@ -4931,8 +5261,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4931
5261
  }), "自动学习"), (0, react.createElement)("p", null, "关闭后暂停普通自动学习;显式“保存为 Skill”仍会持久保存。已开始的分析继续使用启动时快照。"), (0, react.createElement)("p", null, "分析时沿用发起会话已经选择的模型。"), state.error === void 0 ? null : (0, react.createElement)("p", { role: "status" }, "设置已变化,请刷新后重试。"), (0, react.createElement)(PurgeSettingsSection, { controller: props.purgeController })) : null);
4932
5262
  }
4933
5263
  function applyAutomaticLearningSettingsClient(context) {
5264
+ return applyAutomaticLearningSettingsClientRemote(context);
5265
+ }
5266
+ async function applyAutomaticLearningSettingsClientRemote(context) {
5267
+ const mounted = await createRun2skillRemoteCaller(context.remote);
4934
5268
  const controller = new AutomaticLearningSettingsController(context.settingsScope.bind({ namespace: "run2skill" }));
4935
- const callPurge = async (endpoint, payload, signal) => await context.connection.rpc.call(RUN2SKILL_RPC_CHANNEL, endpoint, payload, signal);
5269
+ const callPurge = mounted.call;
4936
5270
  const purgeController = new PurgeSettingsController(callPurge, () => {
4937
5271
  return context.workspaces.list.getSnapshot().recentWorkspaceId;
4938
5272
  });
@@ -4949,6 +5283,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4949
5283
  purgeController
4950
5284
  })
4951
5285
  }, AutomaticLearningSettingsCard));
5286
+ return mounted.dispose;
4952
5287
  }
4953
5288
  //#endregion
4954
5289
  //#region src/client/proposal-inbox-wire.ts
@@ -4965,6 +5300,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4965
5300
  }).strict();
4966
5301
  const processingState = _enum([
4967
5302
  "READY_FOR_REVIEW",
5303
+ "REVISING",
4968
5304
  "PUBLISHING",
4969
5305
  "NEEDS_ATTENTION",
4970
5306
  "TERMINAL"
@@ -5060,6 +5396,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5060
5396
  supportingExperienceIds: array(string().regex(/^exp_[a-f0-9]{64}$/)).min(1).max(3),
5061
5397
  catalogObservationDigest: sha256,
5062
5398
  curationRationale: string().min(1).max(4096),
5399
+ revisionParent: object({
5400
+ proposalId,
5401
+ revision: positiveInteger,
5402
+ digest: sha256,
5403
+ exactSkillBytes: string().min(1).max(65536)
5404
+ }).strict().optional(),
5063
5405
  actionBinding: actionBinding.optional(),
5064
5406
  proposalId,
5065
5407
  digest: sha256
@@ -5126,6 +5468,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5126
5468
  createdAt: string().min(1).max(64),
5127
5469
  processingState: _enum([
5128
5470
  "READY_FOR_REVIEW",
5471
+ "REVISING",
5129
5472
  "PUBLISHING",
5130
5473
  "NEEDS_ATTENTION"
5131
5474
  ]),
@@ -5214,6 +5557,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5214
5557
  reject: "proposals/reject",
5215
5558
  retry: "proposals/retry",
5216
5559
  refresh: "proposals/refresh",
5560
+ revise: "proposals/revise",
5217
5561
  confirmDiscard: "coverage/confirm-discard"
5218
5562
  };
5219
5563
  function describeProposalKind(kind) {
@@ -5229,6 +5573,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5229
5573
  return scope === "PROJECT" ? "本次经验来自当前项目" : "本次经验适用于所有项目";
5230
5574
  }
5231
5575
  function describeProposalOutcome(detail) {
5576
+ if (detail.processingState === "REVISING") return "正在按修改意见生成新草稿";
5232
5577
  if (detail.publicationOutcome === "PUBLISHED") return "Skill 已保存,DSH 已确认可以使用";
5233
5578
  if (detail.publicationOutcome === "DISCARDED") return "技能草稿已放弃,Skill 未更改";
5234
5579
  if (detail.publicationOutcome === "NEEDS_REFRESH") return "保存目标已变化,需要生成新的技能草稿";
@@ -5246,6 +5591,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5246
5591
  return "待决定";
5247
5592
  }
5248
5593
  function describeProcessingState(state) {
5594
+ if (state === "REVISING") return "正在生成新草稿";
5249
5595
  if (state === "PUBLISHING") return "正在保存";
5250
5596
  if (state === "NEEDS_ATTENTION") return "需要处理";
5251
5597
  if (state === "TERMINAL") return "已结束";
@@ -5315,6 +5661,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5315
5661
  #removeFocus;
5316
5662
  #removeVisibility;
5317
5663
  #removeOnline;
5664
+ #revisionAttempt;
5318
5665
  constructor(workspaceId, call, environment = browserEnvironment$1(), options = {}) {
5319
5666
  this.workspaceId = workspaceId;
5320
5667
  this.call = call;
@@ -5487,6 +5834,66 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5487
5834
  });
5488
5835
  });
5489
5836
  }
5837
+ async revise(feedback) {
5838
+ await this.whenIdle();
5839
+ const detail = this.#state.detail;
5840
+ const normalized = feedback.normalize("NFKC").trim();
5841
+ if (this.#disposed || detail === void 0 || this.#state.mutationPending || normalized.length === 0 || new TextEncoder().encode(normalized).byteLength > 2048) return;
5842
+ const proposalRef = detail.action?.proposalRef ?? {
5843
+ proposalId: detail.proposal.proposalId,
5844
+ revision: detail.proposal.revision,
5845
+ digest: detail.proposal.digest
5846
+ };
5847
+ const action = this.#scopeAccess().actions.find((candidate) => candidate.proposalRef.proposalId === proposalRef.proposalId) ?? detail.action;
5848
+ if (action === void 0) return;
5849
+ const attempt = this.#revisionAttempt?.workItemId === detail.workItemId && sameProposalRef(this.#revisionAttempt.proposalRef, proposalRef) && this.#revisionAttempt.feedback === normalized ? this.#revisionAttempt : {
5850
+ workItemId: detail.workItemId,
5851
+ proposalRef,
5852
+ feedback: normalized,
5853
+ actionId: createRevisionActionId()
5854
+ };
5855
+ this.#revisionAttempt = attempt;
5856
+ await this.#execute(async (signal) => {
5857
+ this.#publish({
5858
+ ...this.#state,
5859
+ mutationPending: true,
5860
+ announcement: "正在按修改意见生成新草稿…"
5861
+ });
5862
+ const raw = await this.call(endpoint.revise, {
5863
+ apiVersion: 1,
5864
+ workItemId: detail.workItemId,
5865
+ workItemRevision: detail.workItemRevision,
5866
+ proposalRef,
5867
+ currentScope: this.#scopeAccess().currentScope,
5868
+ action,
5869
+ actionId: attempt.actionId,
5870
+ feedback: normalized
5871
+ }, signal);
5872
+ const receipt = parseMutationReceipt(raw);
5873
+ if (receipt === void 0) {
5874
+ if (raw !== null && typeof raw === "object" && "ok" in raw && raw.ok === false) this.#revisionAttempt = void 0;
5875
+ throw new Error("invalid revision receipt");
5876
+ }
5877
+ this.#revisionAttempt = void 0;
5878
+ this.#publish({
5879
+ ...this.#state,
5880
+ mutationPending: false,
5881
+ selectedProposalId: receipt.proposalRef.proposalId,
5882
+ detailPhase: "LOADING",
5883
+ detail: void 0,
5884
+ announcement: "已生成新草稿,请重新审核"
5885
+ });
5886
+ await this.#loadListWithin(signal);
5887
+ }, () => {
5888
+ this.#publish({
5889
+ ...this.#state,
5890
+ mutationPending: false,
5891
+ detailPhase: "ERROR",
5892
+ detail: void 0,
5893
+ announcement: "修改未完成,原草稿未被替换;请重新打开后重试"
5894
+ });
5895
+ });
5896
+ }
5490
5897
  dispose() {
5491
5898
  if (this.#disposed) return;
5492
5899
  this.#disposed = true;
@@ -5545,7 +5952,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5545
5952
  }
5546
5953
  async #refreshPublishingDetailWithin(signal) {
5547
5954
  const selected = this.#state.selectedProposalId;
5548
- if (selected !== void 0 && this.#state.detail?.processingState === "PUBLISHING") {
5955
+ if (selected !== void 0 && ["PUBLISHING", "REVISING"].includes(this.#state.detail?.processingState ?? "")) {
5549
5956
  const scopeAccess = this.#scopeAccess();
5550
5957
  const action = scopeAccess.actions.find((candidate) => candidate.proposalRef.proposalId === selected);
5551
5958
  if (action === void 0) return;
@@ -5652,6 +6059,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5652
6059
  };
5653
6060
  }
5654
6061
  };
6062
+ function createRevisionActionId() {
6063
+ const bytes = /* @__PURE__ */ new Uint8Array(32);
6064
+ globalThis.crypto.getRandomValues(bytes);
6065
+ return `rev_${Array.from(bytes, (value) => value.toString(16).padStart(2, "0")).join("")}`;
6066
+ }
6067
+ function sameProposalRef(left, right) {
6068
+ return left.proposalId === right.proposalId && left.revision === right.revision && left.digest === right.digest;
6069
+ }
5655
6070
  const formatCharacters = /* @__PURE__ */ new Map([
5656
6071
  [0, "NULL"],
5657
6072
  [9, "CHARACTER TABULATION"],
@@ -5894,6 +6309,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5894
6309
  onRefresh: () => {
5895
6310
  controller.mutate("REFRESH");
5896
6311
  },
6312
+ onRevise: (feedback) => {
6313
+ controller.revise(feedback);
6314
+ },
6315
+ canRevise: false,
5897
6316
  onConfirmDiscard: () => {
5898
6317
  controller.mutate("CONFIRM_DISCARD");
5899
6318
  }
@@ -5993,6 +6412,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5993
6412
  }
5994
6413
  function ProposalDetailView(props) {
5995
6414
  const { detail, mutationPending } = props;
6415
+ const [revisionFeedback, setRevisionFeedback] = (0, react.useState)("");
6416
+ const [revisionSubmitted, setRevisionSubmitted] = (0, react.useState)(false);
6417
+ (0, react.useEffect)(() => {
6418
+ setRevisionFeedback("");
6419
+ setRevisionSubmitted(false);
6420
+ }, [detail.proposal.proposalId]);
5996
6421
  const proposal = detail.proposal;
5997
6422
  const action = proposalDetailAction(detail, mutationPending);
5998
6423
  const actionable = action === "REVIEW";
@@ -6001,6 +6426,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6001
6426
  const coveringBytes = proposal.actionBinding?.kind === "DISCARD" ? proposal.actionBinding.coveringCandidateBinding.content : void 0;
6002
6427
  const coveringCandidate = proposal.actionBinding?.kind === "DISCARD" ? proposal.actionBinding.coveringCandidateBinding : void 0;
6003
6428
  const diff = baseBytes === void 0 ? [] : makeExactLineDiff(baseBytes, proposal.exactSkillBytes);
6429
+ const revisionDiff = proposal.revisionParent === void 0 ? [] : makeExactLineDiff(proposal.revisionParent.exactSkillBytes, proposal.exactSkillBytes);
6430
+ const revisionFeedbackBytes = new TextEncoder().encode(revisionFeedback.trim()).byteLength;
6431
+ const revisionFeedbackValid = revisionFeedback.trim().length > 0 && revisionFeedbackBytes <= 2048;
6004
6432
  return (0, react.createElement)(react.Fragment, null, (0, react.createElement)("h3", null, coveringCandidate === void 0 ? `${describeProposalKind(proposal.kind)}:${makeSafeText(proposal.name)}` : `无需新建技能:继续使用 ${makeSafeText(coveringCandidate.name)}`), (0, react.createElement)("dl", { className: _run2skill_css_run2skill_settings_page_module_css_default.detailFacts }, coveringCandidate === void 0 ? (0, react.createElement)(react.Fragment, null, (0, react.createElement)("dt", null, "这个技能有什么用"), (0, react.createElement)("dd", null, makeSafeText(proposal.description)), (0, react.createElement)("dt", null, "什么时候会用到"), (0, react.createElement)("dd", null, makeSafeText(proposal.whenToUse)), (0, react.createElement)("dt", null, "保存后在哪里可用"), (0, react.createElement)("dd", null, describePersistenceScope(proposal.persistenceScope))) : (0, react.createElement)(react.Fragment, null, (0, react.createElement)("dt", null, "原本想保存的经验"), (0, react.createElement)("dd", null, makeSafeText(proposal.description)), (0, react.createElement)("dt", null, "适用场景"), (0, react.createElement)("dd", null, makeSafeText(proposal.whenToUse)), (0, react.createElement)("dt", null, "这次经验的范围"), (0, react.createElement)("dd", null, describeProposalScope(proposal.kind, proposal.persistenceScope))), (0, react.createElement)("dt", null, "当前进度"), (0, react.createElement)("dd", null, describeProposalOutcome(detail))), (0, react.createElement)("h4", null, coveringCandidate === void 0 ? "为什么建议保存" : "为什么无需新建"), (0, react.createElement)("p", null, makeSafeText(proposal.curationRationale)), ...detail.experiences.map((experience) => (0, react.createElement)("article", { key: experience.experienceId }, (0, react.createElement)("strong", null, `${describeExperienceType(experience.type)} · 来自明确表达`), (0, react.createElement)("p", null, makeSafeText(experience.lesson)))), (0, react.createElement)("h4", null, "参考的对话内容"), (0, react.createElement)("p", { className: _run2skill_css_run2skill_settings_page_module_css_default.muted }, "以下片段来自本次对话,并已过滤不可安全展示的内容。"), ...detail.evidenceRefs.map((evidence, index) => (0, react.createElement)("article", { key: `${String(evidence.messageSeq)}:${evidence.excerptDigest}` }, (0, react.createElement)("strong", null, `对话片段 ${String(index + 1)}${evidence.truncated ? "(内容较长,已节选)" : ""}`), (0, react.createElement)(ProposalTextView, {
6005
6433
  value: evidence.excerpt,
6006
6434
  mode: "SAFE",
@@ -6029,11 +6457,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6029
6457
  value: proposal.exactSkillBytes,
6030
6458
  mode: props.textMode,
6031
6459
  label: coveringCandidate === void 0 ? "确认要保存的技能说明" : "用于判断的草稿内容"
6032
- }), baseBytes === void 0 ? null : (0, react.createElement)(react.Fragment, null, (0, react.createElement)("h4", null, "现有技能内容"), (0, react.createElement)(ProposalTextView, {
6460
+ }), proposal.revisionParent === void 0 ? null : (0, react.createElement)(react.Fragment, null, (0, react.createElement)("h4", null, "相对上一版草稿的变化"), (0, react.createElement)("p", { className: _run2skill_css_run2skill_settings_page_module_css_default.muted }, "“+”表示新增内容,“-”表示被替换的内容。修改后需要重新审核。"), (0, react.createElement)("pre", { "aria-label": "相对上一版草稿的变化" }, revisionDiff.map((line) => `${line.kind === "ADD" ? "+" : line.kind === "REMOVE" ? "-" : " "} ${makeSafeText(line.text)}`).join("\n"))), baseBytes === void 0 ? null : (0, react.createElement)(react.Fragment, null, (0, react.createElement)("h4", null, "现有技能内容"), (0, react.createElement)(ProposalTextView, {
6033
6461
  value: baseBytes,
6034
6462
  mode: props.textMode,
6035
6463
  label: "现有技能内容"
6036
- }), (0, react.createElement)("h4", null, "将发生的内容变化"), (0, react.createElement)("p", { className: _run2skill_css_run2skill_settings_page_module_css_default.muted }, "“+”表示新增内容,“-”表示将被替换的内容。"), (0, react.createElement)("pre", { "aria-label": "将发生的内容变化" }, diff.map((line) => `${line.kind === "ADD" ? "+" : line.kind === "REMOVE" ? "-" : " "} ${makeSafeText(line.text)}`).join("\n"))), coveringBytes === void 0 ? null : (0, react.createElement)(react.Fragment, null, (0, react.createElement)("h4", null, "将继续使用的已有技能内容"), (0, react.createElement)(ProposalTextView, {
6464
+ }), (0, react.createElement)("h4", null, "将发生的内容变化"), (0, react.createElement)("p", { className: _run2skill_css_run2skill_settings_page_module_css_default.muted }, "“+”表示新增内容,“-”表示将被替换的内容。"), (0, react.createElement)("pre", { "aria-label": "将发生的内容变化" }, diff.map((line) => `${line.kind === "ADD" ? "+" : line.kind === "REMOVE" ? "-" : " "} ${makeSafeText(line.text)}`).join("\n"))), proposal.kind === "DISCARD" || props.canRevise !== true ? null : (0, react.createElement)("section", {
6465
+ className: _run2skill_css_run2skill_settings_page_module_css_default.revisionBox,
6466
+ "aria-label": "要求修改技能草稿"
6467
+ }, (0, react.createElement)("label", { htmlFor: `run2skill-revision-${proposal.proposalId}` }, "想怎么修改?"), (0, react.createElement)("p", {
6468
+ id: `run2skill-revision-help-${proposal.proposalId}`,
6469
+ className: _run2skill_css_run2skill_settings_page_module_css_default.muted
6470
+ }, "写一条简短意见。Run2Skill 会重新生成完整草稿,原草稿不会直接发布。"), (0, react.createElement)("textarea", {
6471
+ id: `run2skill-revision-${proposal.proposalId}`,
6472
+ value: revisionFeedback,
6473
+ rows: 3,
6474
+ disabled: mutationPending,
6475
+ "aria-describedby": `run2skill-revision-help-${proposal.proposalId} run2skill-revision-count-${proposal.proposalId}`,
6476
+ onChange: (event) => {
6477
+ setRevisionFeedback(event.currentTarget.value);
6478
+ }
6479
+ }), (0, react.createElement)("span", {
6480
+ id: `run2skill-revision-count-${proposal.proposalId}`,
6481
+ className: revisionFeedbackBytes > 2048 ? _run2skill_css_run2skill_settings_page_module_css_default.danger : _run2skill_css_run2skill_settings_page_module_css_default.muted,
6482
+ role: revisionFeedbackBytes > 2048 ? "alert" : void 0
6483
+ }, `${String(revisionFeedbackBytes)} / 2048 字节`), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
6484
+ variant: "outline",
6485
+ disabled: mutationPending || !revisionFeedbackValid,
6486
+ onClick: () => {
6487
+ setRevisionSubmitted(true);
6488
+ props.onRevise(revisionFeedback);
6489
+ }
6490
+ }, mutationPending && revisionSubmitted ? "正在生成新草稿…" : "按意见生成新草稿")), coveringBytes === void 0 ? null : (0, react.createElement)(react.Fragment, null, (0, react.createElement)("h4", null, "将继续使用的已有技能内容"), (0, react.createElement)(ProposalTextView, {
6037
6491
  value: coveringBytes,
6038
6492
  mode: props.textMode,
6039
6493
  label: "将继续使用的已有技能内容"
@@ -6118,6 +6572,133 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6118
6572
  }
6119
6573
  //#endregion
6120
6574
  //#region src/client/run2skill-settings-page.ts
6575
+ const learningStatusResultSchema = object({
6576
+ ok: literal(true),
6577
+ value: object({
6578
+ apiVersion: literal(1),
6579
+ state: _enum([
6580
+ "EMPTY",
6581
+ "RECORDED",
6582
+ "PROCESSING",
6583
+ "CHECKING",
6584
+ "COVERED",
6585
+ "NEEDS_ATTENTION"
6586
+ ]),
6587
+ canRequest: boolean()
6588
+ }).strict()
6589
+ }).strict();
6590
+ const learningRequestResultSchema = object({
6591
+ ok: literal(true),
6592
+ value: object({
6593
+ apiVersion: literal(1),
6594
+ changed: boolean(),
6595
+ disposition: _enum([
6596
+ "EMPTY",
6597
+ "PROCESSING",
6598
+ "QUEUED"
6599
+ ])
6600
+ }).strict()
6601
+ }).strict();
6602
+ const learningStatusCopy = {
6603
+ EMPTY: "暂无可整理的经验。",
6604
+ RECORDED: "已记下,待本次会话结束后整理。",
6605
+ PROCESSING: "正在整理本次经验…",
6606
+ CHECKING: "正在检查已有 Skill…",
6607
+ COVERED: "已有 Skill 已覆盖这次经验。",
6608
+ NEEDS_ATTENTION: "整理结果需要你处理。"
6609
+ };
6610
+ function LearningStatusSection(props) {
6611
+ const [state, setState] = (0, react.useState)({ phase: "LOADING" });
6612
+ const [refreshGeneration, setRefreshGeneration] = (0, react.useState)(0);
6613
+ const requestPending = (0, react.useRef)(false);
6614
+ const [submitting, setSubmitting] = (0, react.useState)(false);
6615
+ (0, react.useEffect)(() => {
6616
+ if (!props.active || props.sessionId === void 0) return;
6617
+ const abort = new AbortController();
6618
+ let timer;
6619
+ const refresh = async () => {
6620
+ try {
6621
+ const parsed = learningStatusResultSchema.safeParse(await props.call("learning/status", {
6622
+ apiVersion: 1,
6623
+ currentScope: currentScope(props.workspaceId, props.scopeGeneration ?? 1),
6624
+ sessionId: props.sessionId
6625
+ }, abort.signal));
6626
+ if (!abort.signal.aborted) setState(parsed.success ? {
6627
+ phase: "READY",
6628
+ value: parsed.data.value
6629
+ } : { phase: "ERROR" });
6630
+ } catch {
6631
+ if (!abort.signal.aborted) setState({ phase: "ERROR" });
6632
+ } finally {
6633
+ if (!abort.signal.aborted) timer = setTimeout(() => {
6634
+ refresh();
6635
+ }, props.pollMs ?? 5e3);
6636
+ }
6637
+ };
6638
+ refresh();
6639
+ return () => {
6640
+ abort.abort();
6641
+ if (timer !== void 0) clearTimeout(timer);
6642
+ };
6643
+ }, [
6644
+ props.active,
6645
+ props.call,
6646
+ props.pollMs,
6647
+ props.scopeGeneration,
6648
+ props.sessionId,
6649
+ props.workspaceId,
6650
+ refreshGeneration
6651
+ ]);
6652
+ const request = () => {
6653
+ if (!props.active || requestPending.current || state.phase !== "READY" || !state.value.canRequest || props.sessionId === void 0) return;
6654
+ requestPending.current = true;
6655
+ setSubmitting(true);
6656
+ const abort = new AbortController();
6657
+ (async () => {
6658
+ try {
6659
+ const result = learningRequestResultSchema.safeParse(await props.call("learning/request", {
6660
+ apiVersion: 1,
6661
+ currentScope: currentScope(props.workspaceId, props.scopeGeneration ?? 1),
6662
+ sessionId: props.sessionId
6663
+ }, abort.signal));
6664
+ if (!result.success) throw new Error("LEARNING_REQUEST_UNAVAILABLE");
6665
+ setState({
6666
+ phase: "READY",
6667
+ value: {
6668
+ apiVersion: 1,
6669
+ state: result.data.value.disposition === "PROCESSING" ? "PROCESSING" : result.data.value.disposition === "QUEUED" ? "RECORDED" : "EMPTY",
6670
+ canRequest: false
6671
+ }
6672
+ });
6673
+ setRefreshGeneration((value) => value + 1);
6674
+ } catch {
6675
+ setState({ phase: "ERROR" });
6676
+ } finally {
6677
+ requestPending.current = false;
6678
+ setSubmitting(false);
6679
+ }
6680
+ })();
6681
+ };
6682
+ const disabled = !props.active || state.phase !== "READY" || !state.value.canRequest || submitting;
6683
+ const statusText = props.sessionId === void 0 ? "请先打开一个会话。" : state.phase === "LOADING" ? "正在读取整理状态…" : state.phase === "ERROR" ? "整理状态暂不可用,请刷新后重试。" : learningStatusCopy[state.value.state];
6684
+ return (0, react.createElement)("div", { className: _run2skill_css_run2skill_settings_page_module_css_default.sectionBody }, (0, react.createElement)("div", { className: _run2skill_css_run2skill_settings_page_module_css_default.learningStatusRow }, (0, react.createElement)("p", {
6685
+ role: state.phase === "ERROR" ? "alert" : "status",
6686
+ "aria-live": "polite",
6687
+ className: _run2skill_css_run2skill_settings_page_module_css_default.status
6688
+ }, statusText), (0, react.createElement)("div", { className: _run2skill_css_run2skill_settings_page_module_css_default.actions }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
6689
+ variant: "primary",
6690
+ disabled,
6691
+ onClick: request
6692
+ }, submitting ? "正在提交…" : "立即整理本次经验"), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
6693
+ variant: "outline",
6694
+ "aria-label": "刷新整理状态",
6695
+ disabled: !props.active || props.sessionId === void 0 || submitting,
6696
+ onClick: () => {
6697
+ setState({ phase: "LOADING" });
6698
+ setRefreshGeneration((value) => value + 1);
6699
+ }
6700
+ }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16)))));
6701
+ }
6121
6702
  const recentSkillActivityResultSchema = object({
6122
6703
  ok: literal(true),
6123
6704
  value: object({
@@ -6529,6 +7110,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6529
7110
  }
6530
7111
  }, [controller, props.active]);
6531
7112
  const state = (0, react.useSyncExternalStore)(controller.subscribe, controller.snapshot, controller.snapshot);
7113
+ (0, react.useEffect)(() => {
7114
+ const selected = state.selectedProposalId;
7115
+ if (props.active && selected !== void 0 && state.detailPhase === "LOADING" && state.announcement === "已生成新草稿,请重新审核" && scopeAccessRef.current.actions.some((action) => action.proposalRef.proposalId === selected)) controller.select(selected);
7116
+ }, [
7117
+ controller,
7118
+ props.active,
7119
+ props.actions,
7120
+ state.announcement,
7121
+ state.detailPhase,
7122
+ state.selectedProposalId
7123
+ ]);
6532
7124
  const [filter, setFilter] = (0, react.useState)("");
6533
7125
  const [textMode, setTextMode] = (0, react.useState)("SAFE");
6534
7126
  const [rejectConfirm, setRejectConfirm] = (0, react.useState)(false);
@@ -6582,6 +7174,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6582
7174
  onRefresh: () => {
6583
7175
  controller.mutate("REFRESH").finally(props.onMutationSettled);
6584
7176
  },
7177
+ onRevise: (feedback) => {
7178
+ controller.revise(feedback).finally(props.onMutationSettled);
7179
+ },
7180
+ canRevise: props.actions.some((action) => action.proposalRef?.proposalId === state.detail?.proposal.proposalId && action.availableActions?.includes("REVISE") === true),
6585
7181
  onConfirmDiscard: () => {
6586
7182
  controller.mutate("CONFIRM_DISCARD").finally(props.onMutationSettled);
6587
7183
  }
@@ -6919,7 +7515,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6919
7515
  const liveWorkspaceId = props.useWorkspaces?.((state) => state.items.find((workspace) => workspace.sessionIds?.includes(liveSessionId ?? ""))?.workspaceId);
6920
7516
  const workspaceId = props.useSessions === void 0 ? props.workspaceId : liveWorkspaceId;
6921
7517
  const sessionId = props.useSessions === void 0 ? props.sessionId : liveSessionId;
6922
- const [open, setOpen] = (0, react.useState)(() => /* @__PURE__ */ new Set(["attention"]));
7518
+ const [open, setOpen] = (0, react.useState)(() => /* @__PURE__ */ new Set(["status", "attention"]));
6923
7519
  const hostTab = useHostTabVisibility();
6924
7520
  const [attention, setAttention] = (0, react.useState)();
6925
7521
  const [attentionRefresh, setAttentionRefresh] = (0, react.useState)(0);
@@ -6956,7 +7552,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6956
7552
  ref: hostTab.ref,
6957
7553
  className: _run2skill_css_run2skill_settings_page_module_css_default.page,
6958
7554
  "data-run2skill-settings-page": true
6959
- }, (0, react.createElement)("p", { className: _run2skill_css_run2skill_settings_page_module_css_default.intro }, "Run2Skill 在后台自动沉淀经验;这里只展示需要处理的事项和持久设置。"), disclosure("attention", "需要处理", (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutline16), (0, react.createElement)("div", { className: _run2skill_css_run2skill_settings_page_module_css_default.sectionBody }, (0, react.createElement)(AttentionSettingsSummary, {
7555
+ }, (0, react.createElement)("p", { className: _run2skill_css_run2skill_settings_page_module_css_default.intro }, "Run2Skill 在后台自动沉淀经验;这里展示当前状态、需要处理的事项和持久设置。"), props.callLearningStatus === void 0 ? null : disclosure("status", "整理状态", (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconSparkle16), (0, react.createElement)(LearningStatusSection, {
7556
+ key: JSON.stringify([
7557
+ sessionId ?? null,
7558
+ workspaceId ?? null,
7559
+ scopeGeneration,
7560
+ purgeState.hostDataEpoch
7561
+ ]),
7562
+ ...sessionId === void 0 ? {} : { sessionId },
7563
+ ...workspaceId === void 0 ? {} : { workspaceId },
7564
+ scopeGeneration,
7565
+ active: hostTab.visible && open.has("status") && !purgeDataChanging,
7566
+ call: props.callLearningStatus
7567
+ })), disclosure("attention", "需要处理", (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutline16), (0, react.createElement)("div", { className: _run2skill_css_run2skill_settings_page_module_css_default.sectionBody }, (0, react.createElement)(AttentionSettingsSummary, {
6960
7568
  active: hostTab.visible && open.has("attention"),
6961
7569
  ...sessionId === void 0 ? {} : { sessionId },
6962
7570
  ...workspaceId === void 0 ? {} : { workspaceId },
@@ -7012,12 +7620,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7012
7620
  if (sessionId === void 0) return void 0;
7013
7621
  return context.workspaces.list.getSnapshot().items.find((workspace) => workspace.sessionIds?.includes(sessionId))?.workspaceId;
7014
7622
  }
7015
- function applyRun2skillClient(context) {
7623
+ async function applyRun2skillClient(context) {
7624
+ const mounted = await createRun2skillRemoteCaller(context.remote);
7016
7625
  const controller = new AutomaticLearningSettingsController(context.settingsScope.bind({ namespace: "run2skill" }));
7017
- const callReview = async (endpoint, payload, signal) => await context.connection.rpc.call(RUN2SKILL_RPC_CHANNEL, endpoint, payload, signal);
7018
- const callAttention = async (payload, signal) => await context.connection.rpc.call(RUN2SKILL_RPC_CHANNEL, "attention", payload, signal);
7019
- const callActivity = async (payload, signal) => await context.connection.rpc.call(RUN2SKILL_RPC_CHANNEL, "recent-activity/list", payload, signal);
7020
- const callPurge = async (endpoint, payload, signal) => await context.connection.rpc.call(RUN2SKILL_RPC_CHANNEL, endpoint, payload, signal);
7626
+ const callReview = mounted.call;
7627
+ const callAttention = async (payload, signal) => await mounted.call("attention", payload, signal);
7628
+ const callActivity = async (payload, signal) => await mounted.call("recent-activity/list", payload, signal);
7629
+ const callLearningStatus = mounted.call;
7630
+ const callPurge = mounted.call;
7021
7631
  const purgeController = new PurgeSettingsController(callPurge, () => workspaceFor(context, currentSessionId(context)));
7022
7632
  context.effect(() => {
7023
7633
  const disposeStyle = acquireRun2skillStyle();
@@ -7039,7 +7649,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7039
7649
  sessionId: currentSessionId(context),
7040
7650
  callAttention,
7041
7651
  callReview,
7042
- callActivity
7652
+ callActivity,
7653
+ callLearningStatus
7043
7654
  })
7044
7655
  }, Run2skillSettingsPage));
7045
7656
  context.slots.inject("conversation.session.header.actions", () => context.slots.register({
@@ -7055,8 +7666,36 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7055
7666
  callAttention: props.callAttention
7056
7667
  });
7057
7668
  }));
7669
+ return mounted.dispose;
7058
7670
  }
7059
7671
  //#endregion
7672
+ //#region src/domain/observe/observe-summary.ts
7673
+ const safeCount = number().refine((value) => Number.isSafeInteger(value) && value >= 0, "Expected a non-negative safe integer");
7674
+ const ObserveSummaryV1Schema = object({
7675
+ apiVersion: literal(1),
7676
+ status: _enum([
7677
+ "READY",
7678
+ "RECOVERING",
7679
+ "DEGRADED",
7680
+ "INCOMPATIBLE"
7681
+ ]),
7682
+ capturedCount: safeCount,
7683
+ blockedCaptureCount: safeCount,
7684
+ learning: object({
7685
+ captured: safeCount,
7686
+ analyzing: safeCount,
7687
+ learned: safeCount,
7688
+ needsAttention: safeCount
7689
+ }).strict().optional(),
7690
+ unsaved: object({
7691
+ completeness: _enum(["KNOWN", "UNKNOWN"]),
7692
+ knownCount: safeCount
7693
+ }).strict(),
7694
+ recoveryLag: boolean(),
7695
+ lastRecoveryProgressAt: string().datetime({ offset: true }).optional(),
7696
+ lastHealthCode: string().regex(/^[A-Z][A-Z0-9_]{0,63}$/).optional()
7697
+ }).strict();
7698
+ //#endregion
7060
7699
  //#region src/client/observe-summary-poller.ts
7061
7700
  const OBSERVE_SUMMARY_POLL_INTERVAL_MS = 1e4;
7062
7701
  function browserEnvironment() {
@@ -7191,21 +7830,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7191
7830
  //#region src/client/index.ts
7192
7831
  const name = "run2skill-client";
7193
7832
  const inject = [
7194
- "connection",
7195
7833
  "slots",
7196
7834
  "workspaces",
7197
7835
  "sessions",
7198
7836
  "remote",
7199
7837
  "settingsScope"
7200
7838
  ];
7201
- function apply(context) {
7202
- applyRun2skillClient(context);
7839
+ async function apply(context) {
7840
+ return await applyRun2skillClient(context);
7203
7841
  }
7204
7842
  //#endregion
7205
7843
  exports.AttentionSettingsSummary = AttentionSettingsSummary;
7206
7844
  exports.AutomaticLearningSettingsCard = AutomaticLearningSettingsCard;
7207
7845
  exports.AutomaticLearningSettingsController = AutomaticLearningSettingsController;
7208
7846
  exports.LearningFailureSection = LearningFailureSection;
7847
+ exports.LearningStatusSection = LearningStatusSection;
7209
7848
  exports.OBSERVE_SUMMARY_POLL_INTERVAL_MS = OBSERVE_SUMMARY_POLL_INTERVAL_MS;
7210
7849
  exports.ObserveSummaryPoller = ObserveSummaryPoller;
7211
7850
  exports.PROPOSAL_ACTIVE_POLL_INTERVAL_MS = PROPOSAL_ACTIVE_POLL_INTERVAL_MS;