@spotpatch/runtime 1.12.0 → 1.13.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.
@@ -1,4 +1,4 @@
1
- import { ExternalHandoffFramework, SpotPatchLocale, SpotAnnotation, ExternalHandoffCapability, ExternalAgentControlStatus, ErrorCode, ExternalHandoffPublishResult, ExternalAgentManagedResult, ExternalHandoffStatusResult } from '@spotpatch/shared/external-handoff-browser';
1
+ import { ExternalHandoffFramework, SpotPatchLocale, DispatchSummary, ExternalAgentControlStatus, SpotAnnotation, ExternalHandoffCapability, ErrorCode, ExternalHandoffPublishResult, ExternalAgentManagedResult, ExternalHandoffStatusResult } from '@spotpatch/shared/external-handoff-browser';
2
2
 
3
3
  interface ExternalHandoffPanel {
4
4
  readonly cancelManagedButton: HTMLButtonElement;
@@ -31,7 +31,7 @@ interface ExternalHandoffWorkflow {
31
31
  readonly mount: () => void;
32
32
  }
33
33
  interface ExternalHandoffExtension {
34
- readonly createPanel: (document: Document, framework: ExternalHandoffFramework, locale: () => SpotPatchLocale, sessionId: string, subscribeLocale: (listener: () => void) => () => void, onViewChange: () => void) => ExternalHandoffPanel;
34
+ readonly createPanel: (document: Document, framework: ExternalHandoffFramework, locale: () => SpotPatchLocale, sessionId: string, subscribeLocale: (listener: () => void) => () => void, onViewChange: () => void, onDispatchChange?: (dispatch: DispatchSummary | null) => void, onControlChange?: (status: ExternalAgentControlStatus | undefined) => void) => ExternalHandoffPanel;
35
35
  readonly createWorkflow: (fetch: typeof globalThis.fetch, panel: ExternalHandoffPanel, selectedAnnotation: () => SpotAnnotation | undefined, sessionToken: string, window: Window) => ExternalHandoffWorkflow;
36
36
  }
37
37
  declare function registerExternalHandoffExtension(extension: ExternalHandoffExtension): void;
@@ -39,6 +39,6 @@ declare function getExternalHandoffExtension(): ExternalHandoffExtension | undef
39
39
 
40
40
  declare function createExternalHandoffWorkflow(fetch: typeof globalThis.fetch, panel: ExternalHandoffPanel, selectedAnnotation: () => SpotAnnotation | undefined, sessionToken: string, window: Window): ExternalHandoffWorkflow;
41
41
 
42
- declare function createExternalHandoffPanel(document: Document, framework: "vite" | "next", locale: () => SpotPatchLocale, sessionId: string, subscribeLocale: (listener: () => void) => () => void, onViewChange: () => void): ExternalHandoffPanel;
42
+ declare function createExternalHandoffPanel(document: Document, framework: "vite" | "next", locale: () => SpotPatchLocale, sessionId: string, subscribeLocale: (listener: () => void) => () => void, onViewChange: () => void, onDispatchChange?: (dispatch: DispatchSummary | null) => void, onControlChange?: (status: ExternalAgentControlStatus | undefined) => void): ExternalHandoffPanel;
43
43
 
44
44
  export { type ExternalHandoffExtension, type ExternalHandoffPanel, type ExternalHandoffWorkflow, createExternalHandoffPanel, createExternalHandoffWorkflow, getExternalHandoffExtension, registerExternalHandoffExtension };
@@ -1,4 +1,4 @@
1
- import { ExternalHandoffFramework, SpotPatchLocale, SpotAnnotation, ExternalHandoffCapability, ExternalAgentControlStatus, ErrorCode, ExternalHandoffPublishResult, ExternalAgentManagedResult, ExternalHandoffStatusResult } from '@spotpatch/shared/external-handoff-browser';
1
+ import { ExternalHandoffFramework, SpotPatchLocale, DispatchSummary, ExternalAgentControlStatus, SpotAnnotation, ExternalHandoffCapability, ErrorCode, ExternalHandoffPublishResult, ExternalAgentManagedResult, ExternalHandoffStatusResult } from '@spotpatch/shared/external-handoff-browser';
2
2
 
3
3
  interface ExternalHandoffPanel {
4
4
  readonly cancelManagedButton: HTMLButtonElement;
@@ -31,7 +31,7 @@ interface ExternalHandoffWorkflow {
31
31
  readonly mount: () => void;
32
32
  }
33
33
  interface ExternalHandoffExtension {
34
- readonly createPanel: (document: Document, framework: ExternalHandoffFramework, locale: () => SpotPatchLocale, sessionId: string, subscribeLocale: (listener: () => void) => () => void, onViewChange: () => void) => ExternalHandoffPanel;
34
+ readonly createPanel: (document: Document, framework: ExternalHandoffFramework, locale: () => SpotPatchLocale, sessionId: string, subscribeLocale: (listener: () => void) => () => void, onViewChange: () => void, onDispatchChange?: (dispatch: DispatchSummary | null) => void, onControlChange?: (status: ExternalAgentControlStatus | undefined) => void) => ExternalHandoffPanel;
35
35
  readonly createWorkflow: (fetch: typeof globalThis.fetch, panel: ExternalHandoffPanel, selectedAnnotation: () => SpotAnnotation | undefined, sessionToken: string, window: Window) => ExternalHandoffWorkflow;
36
36
  }
37
37
  declare function registerExternalHandoffExtension(extension: ExternalHandoffExtension): void;
@@ -39,6 +39,6 @@ declare function getExternalHandoffExtension(): ExternalHandoffExtension | undef
39
39
 
40
40
  declare function createExternalHandoffWorkflow(fetch: typeof globalThis.fetch, panel: ExternalHandoffPanel, selectedAnnotation: () => SpotAnnotation | undefined, sessionToken: string, window: Window): ExternalHandoffWorkflow;
41
41
 
42
- declare function createExternalHandoffPanel(document: Document, framework: "vite" | "next", locale: () => SpotPatchLocale, sessionId: string, subscribeLocale: (listener: () => void) => () => void, onViewChange: () => void): ExternalHandoffPanel;
42
+ declare function createExternalHandoffPanel(document: Document, framework: "vite" | "next", locale: () => SpotPatchLocale, sessionId: string, subscribeLocale: (listener: () => void) => () => void, onViewChange: () => void, onDispatchChange?: (dispatch: DispatchSummary | null) => void, onControlChange?: (status: ExternalAgentControlStatus | undefined) => void): ExternalHandoffPanel;
43
43
 
44
44
  export { type ExternalHandoffExtension, type ExternalHandoffPanel, type ExternalHandoffWorkflow, createExternalHandoffPanel, createExternalHandoffWorkflow, getExternalHandoffExtension, registerExternalHandoffExtension };
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  getExternalHandoffExtension,
3
3
  registerExternalHandoffExtension
4
- } from "./chunk-BXRMVHNT.js";
4
+ } from "./chunk-ASRUAKA5.js";
5
5
  import {
6
6
  createButton,
7
7
  createMarkedElement
8
- } from "./chunk-7ES63LA7.js";
8
+ } from "./chunk-P6X75LO5.js";
9
9
 
10
10
  // src/controller/external-handoff-workflow.ts
11
11
  import {
@@ -1013,6 +1013,7 @@ var MESSAGES = Object.freeze({
1013
1013
  resultTitle: "Managed result",
1014
1014
  controlConnection: (state, mode) => `Connection: ${state} \xB7 Mode: ${mode}`,
1015
1015
  controlAuth: (auth, grant) => `Auth: ${auth} \xB7 Grant: ${grant}`,
1016
+ controlConsentRequired: 'Grant required: type "yes" in the terminal that started `pnpm dev`. If no prompt is visible, restart `pnpm dev` in an interactive terminal and connect again.',
1016
1017
  controlModel: (model) => `Model: ${model}`,
1017
1018
  controlRevision: (task) => `Revision ${String(task.revision)}: ${task.deliveryStatus} / ${task.executionStatus} / ${task.managedPhase}`,
1018
1019
  controlValidation: (outcome) => `Validation: ${outcome}`,
@@ -1021,11 +1022,11 @@ var MESSAGES = Object.freeze({
1021
1022
  controlErrorText: Object.freeze({
1022
1023
  AGENT_BINARY_NOT_FOUND: "Codex is not installed or is not on PATH.",
1023
1024
  AGENT_BINARY_UNTRUSTED: "The resolved Codex executable is not trusted.",
1024
- AGENT_VERSION_UNSUPPORTED: "The installed Codex version is unsupported.",
1025
+ AGENT_VERSION_UNSUPPORTED: "The installed Codex version is below SpotPatch's compatibility baseline.",
1025
1026
  APP_SERVER_HANDSHAKE_FAILED: "Codex App Server did not complete startup.",
1026
1027
  AGENT_AUTH_REQUIRED: "Codex requires an authenticated account.",
1027
1028
  AGENT_MODEL_UNAVAILABLE: "The configured Codex model is unavailable.",
1028
- AGENT_PROTOCOL_INCOMPATIBLE: "The Codex App Server protocol is incompatible.",
1029
+ AGENT_PROTOCOL_INCOMPATIBLE: "The generated Codex App Server schema is incompatible with SpotPatch's required protocol subset.",
1029
1030
  CODEX_CONFIG_ISOLATION_UNSUPPORTED: "This Codex version cannot prove managed configuration isolation.",
1030
1031
  MANAGED_GRANT_INVALID: "The saved project grant failed validation.",
1031
1032
  MANAGED_PLATFORM_UNSUPPORTED: "Managed execution is not proven safe on this platform.",
@@ -1033,14 +1034,14 @@ var MESSAGES = Object.freeze({
1033
1034
  MANAGED_SNAPSHOT_FAILED: "The independent workspace snapshot could not be created.",
1034
1035
  MANAGED_SCOPE_VIOLATION: "The candidate change exceeded its authorized paths.",
1035
1036
  MANAGED_CHANGE_LIMIT_EXCEEDED: "The candidate change exceeded safety limits.",
1036
- MANAGED_VALIDATION_FAILED: "A required check failed or changed the candidate diff.",
1037
+ MANAGED_VALIDATION_FAILED: "The candidate change did not pass audit or validation.",
1037
1038
  MANAGED_WORKSPACE_CONFLICT: "An authorized source file changed during execution.",
1038
1039
  MANAGED_APPLY_FAILED: "The audited change could not be applied safely.",
1039
1040
  MANAGED_CLEANUP_INCOMPLETE: "Managed thread or workspace cleanup is incomplete."
1040
1041
  }),
1041
1042
  controlActionText: Object.freeze({
1042
1043
  "install-agent": "Install Codex and retry.",
1043
- "use-supported-version": "Use a supported Codex version.",
1044
+ "use-supported-version": "Use a schema-compatible Codex version.",
1044
1045
  "sign-in": "Sign in with Codex, then retry.",
1045
1046
  "choose-available-model": "Choose an available model in Codex configuration.",
1046
1047
  "use-inbox": "Continue with the Agent inbox fallback.",
@@ -1099,6 +1100,7 @@ var MESSAGES = Object.freeze({
1099
1100
  resultTitle: "\u53D7\u7BA1\u6267\u884C\u7ED3\u679C",
1100
1101
  controlConnection: (state, mode) => `\u8FDE\u63A5\uFF1A${state} \xB7 \u6A21\u5F0F\uFF1A${mode}`,
1101
1102
  controlAuth: (auth, grant) => `\u8BA4\u8BC1\uFF1A${auth} \xB7 \u6388\u6743\uFF1A${grant}`,
1103
+ controlConsentRequired: "\u9700\u8981\u9879\u76EE\u6388\u6743\uFF1A\u8BF7\u5728\u542F\u52A8 `pnpm dev` \u7684\u7EC8\u7AEF\u8F93\u5165\u201Cyes\u201D\u3002\u82E5\u7EC8\u7AEF\u6CA1\u6709\u51FA\u73B0\u786E\u8BA4\u63D0\u793A\uFF0C\u8BF7\u5728\u53EF\u4EA4\u4E92\u7EC8\u7AEF\u91CD\u65B0\u542F\u52A8 `pnpm dev` \u540E\u518D\u8FDE\u63A5\u3002",
1102
1104
  controlModel: (model) => `\u6A21\u578B\uFF1A${model}`,
1103
1105
  controlRevision: (task) => `revision ${String(task.revision)}\uFF1A${task.deliveryStatus} / ${task.executionStatus} / ${task.managedPhase}`,
1104
1106
  controlValidation: (outcome) => `\u9A8C\u8BC1\uFF1A${outcome}`,
@@ -1107,11 +1109,11 @@ var MESSAGES = Object.freeze({
1107
1109
  controlErrorText: Object.freeze({
1108
1110
  AGENT_BINARY_NOT_FOUND: "\u672A\u5B89\u88C5 Codex\uFF0C\u6216 Codex \u4E0D\u5728 PATH \u4E2D\u3002",
1109
1111
  AGENT_BINARY_UNTRUSTED: "\u89E3\u6790\u5230\u7684 Codex \u53EF\u6267\u884C\u6587\u4EF6\u4E0D\u53EF\u4FE1\u3002",
1110
- AGENT_VERSION_UNSUPPORTED: "\u5DF2\u5B89\u88C5\u7684 Codex \u7248\u672C\u4E0D\u53D7\u652F\u6301\u3002",
1112
+ AGENT_VERSION_UNSUPPORTED: "\u5DF2\u5B89\u88C5\u7684 Codex \u7248\u672C\u4F4E\u4E8E SpotPatch \u517C\u5BB9\u57FA\u7EBF\u3002",
1111
1113
  APP_SERVER_HANDSHAKE_FAILED: "Codex App Server \u672A\u5B8C\u6210\u542F\u52A8\u63E1\u624B\u3002",
1112
1114
  AGENT_AUTH_REQUIRED: "Codex \u9700\u8981\u5DF2\u767B\u5F55\u7684\u8D26\u6237\u3002",
1113
1115
  AGENT_MODEL_UNAVAILABLE: "Codex \u914D\u7F6E\u7684\u6A21\u578B\u5F53\u524D\u4E0D\u53EF\u7528\u3002",
1114
- AGENT_PROTOCOL_INCOMPATIBLE: "Codex App Server \u534F\u8BAE\u4E0D\u517C\u5BB9\u3002",
1116
+ AGENT_PROTOCOL_INCOMPATIBLE: "Codex \u751F\u6210\u7684 App Server Schema \u4E0D\u6EE1\u8DB3 SpotPatch \u6240\u9700\u534F\u8BAE\u5B50\u96C6\u3002",
1115
1117
  CODEX_CONFIG_ISOLATION_UNSUPPORTED: "\u5F53\u524D Codex \u7248\u672C\u65E0\u6CD5\u8BC1\u660E\u53D7\u7BA1\u914D\u7F6E\u9694\u79BB\u3002",
1116
1118
  MANAGED_GRANT_INVALID: "\u4FDD\u5B58\u7684\u9879\u76EE\u6388\u6743\u672A\u901A\u8FC7\u6821\u9A8C\u3002",
1117
1119
  MANAGED_PLATFORM_UNSUPPORTED: "\u5F53\u524D\u5E73\u53F0\u5C1A\u672A\u8BC1\u660E\u53EF\u5B89\u5168\u8FD0\u884C\u53D7\u7BA1\u6267\u884C\u3002",
@@ -1119,14 +1121,14 @@ var MESSAGES = Object.freeze({
1119
1121
  MANAGED_SNAPSHOT_FAILED: "\u65E0\u6CD5\u521B\u5EFA\u72EC\u7ACB\u5DE5\u4F5C\u533A\u5FEB\u7167\u3002",
1120
1122
  MANAGED_SCOPE_VIOLATION: "\u5019\u9009\u4FEE\u6539\u8D85\u51FA\u6388\u6743\u8DEF\u5F84\u3002",
1121
1123
  MANAGED_CHANGE_LIMIT_EXCEEDED: "\u5019\u9009\u4FEE\u6539\u8D85\u8FC7\u5B89\u5168\u4E0A\u9650\u3002",
1122
- MANAGED_VALIDATION_FAILED: "required check \u5931\u8D25\u6216\u6539\u53D8\u4E86\u5019\u9009 diff\u3002",
1124
+ MANAGED_VALIDATION_FAILED: "\u5019\u9009\u4FEE\u6539\u672A\u901A\u8FC7\u5BA1\u8BA1\u6216\u9A8C\u8BC1\u3002",
1123
1125
  MANAGED_WORKSPACE_CONFLICT: "\u6267\u884C\u671F\u95F4\u6388\u6743\u6E90\u7801\u53D1\u751F\u4E86\u53D8\u5316\u3002",
1124
1126
  MANAGED_APPLY_FAILED: "\u5DF2\u5BA1\u8BA1\u4FEE\u6539\u65E0\u6CD5\u5B89\u5168\u5199\u5165\u3002",
1125
1127
  MANAGED_CLEANUP_INCOMPLETE: "\u53D7\u7BA1 thread \u6216\u5DE5\u4F5C\u533A\u6E05\u7406\u4E0D\u5B8C\u6574\u3002"
1126
1128
  }),
1127
1129
  controlActionText: Object.freeze({
1128
1130
  "install-agent": "\u5B89\u88C5 Codex \u540E\u91CD\u8BD5\u3002",
1129
- "use-supported-version": "\u6539\u7528\u53D7\u652F\u6301\u7684 Codex \u7248\u672C\u3002",
1131
+ "use-supported-version": "\u6539\u7528 Schema \u517C\u5BB9\u7684 Codex \u7248\u672C\u3002",
1130
1132
  "sign-in": "\u767B\u5F55 Codex \u540E\u91CD\u8BD5\u3002",
1131
1133
  "choose-available-model": "\u5728 Codex \u914D\u7F6E\u4E2D\u9009\u62E9\u53EF\u7528\u6A21\u578B\u3002",
1132
1134
  "use-inbox": "\u7EE7\u7EED\u4F7F\u7528 Agent \u6536\u4EF6\u7BB1\u964D\u7EA7\u8DEF\u5F84\u3002",
@@ -1263,6 +1265,7 @@ function controlStatusText(value, messages) {
1263
1265
  const parts = [
1264
1266
  messages.controlConnection(value.connectionState, value.mode),
1265
1267
  messages.controlAuth(value.authReadiness, value.grantState),
1268
+ ...value.connectionState === "awaiting-consent" && value.grantState === "missing" ? [messages.controlConsentRequired] : [],
1266
1269
  ...model === void 0 ? [] : [messages.controlModel(model)],
1267
1270
  ...task === void 0 ? [] : [
1268
1271
  messages.controlRevision(task),
@@ -1295,11 +1298,13 @@ function managedResultText(result, messages) {
1295
1298
  ...timings
1296
1299
  ].join("\n");
1297
1300
  }
1298
- function createExternalHandoffPanel(document, framework, locale, sessionId, subscribeLocale, onViewChange) {
1301
+ function createExternalHandoffPanel(document, framework, locale, sessionId, subscribeLocale, onViewChange, onDispatchChange, onControlChange) {
1299
1302
  const options = {
1300
1303
  document,
1301
1304
  framework,
1302
1305
  locale,
1306
+ ...onDispatchChange === void 0 ? {} : { onDispatchChange },
1307
+ ...onControlChange === void 0 ? {} : { onControlChange },
1303
1308
  onViewChange,
1304
1309
  sessionId,
1305
1310
  subscribeLocale
@@ -1324,6 +1329,7 @@ function createExternalHandoffPanel(document, framework, locale, sessionId, subs
1324
1329
  root.hidden = true;
1325
1330
  const heading = createMarkedElement(document, "div");
1326
1331
  heading.className = "spotpatch-external-heading";
1332
+ heading.setAttribute("data-spotpatch-agent-identity", "");
1327
1333
  const title = createMarkedElement(document, "strong");
1328
1334
  const refreshButton = createButton(document, "", "spotpatch-external-refresh");
1329
1335
  heading.append(title, refreshButton);
@@ -1552,6 +1558,7 @@ function createExternalHandoffPanel(document, framework, locale, sessionId, subs
1552
1558
  status.textContent = summaryMessage(result.handoff);
1553
1559
  }
1554
1560
  refreshActions();
1561
+ options.onDispatchChange?.(result.dispatch);
1555
1562
  options.onViewChange();
1556
1563
  };
1557
1564
  return Object.freeze({
@@ -1593,6 +1600,7 @@ function createExternalHandoffPanel(document, framework, locale, sessionId, subs
1593
1600
  status.dataset.state = capability.brokerReady ? "ready" : "error";
1594
1601
  status.textContent = capability.brokerReady ? capability.activeAdapter?.canDispatch === true ? messages.activeReady(agentName(capability.activeAdapter.kind)) : capability.dispatch !== null && capability.activeAdapter !== null ? dispatchMessage(messages, capability.dispatch) : capability.activeWaitCount > 0 ? messages.readyWaiting(capability.activeWaitCount) : messages.ready : messages.error("EXTERNAL_HANDOFF_UNAVAILABLE");
1595
1602
  refreshActions();
1603
+ options.onDispatchChange?.(capability.dispatch);
1596
1604
  options.onViewChange();
1597
1605
  },
1598
1606
  renderPublishing() {
@@ -1621,6 +1629,7 @@ function createExternalHandoffPanel(document, framework, locale, sessionId, subs
1621
1629
  controlStatus.dataset.state = value.connectionState;
1622
1630
  disclosureNoGuarantee.textContent = value.mode === "managed" ? messages.disclosureManagedGuarantee : messages.disclosureNoGuarantee;
1623
1631
  refreshControlActions();
1632
+ options.onControlChange?.(value);
1624
1633
  options.onViewChange();
1625
1634
  },
1626
1635
  renderControlUnavailable() {
@@ -1629,6 +1638,7 @@ function createExternalHandoffPanel(document, framework, locale, sessionId, subs
1629
1638
  controlStatus.textContent = messages.controlUnavailable;
1630
1639
  disclosureNoGuarantee.textContent = messages.disclosureNoGuarantee;
1631
1640
  refreshControlActions();
1641
+ options.onControlChange?.(void 0);
1632
1642
  options.onViewChange();
1633
1643
  },
1634
1644
  renderManagedResult(result) {
@@ -1646,6 +1656,7 @@ function createExternalHandoffPanel(document, framework, locale, sessionId, subs
1646
1656
  status.dataset.state = "error";
1647
1657
  status.textContent = canRetry ? `${messages.error(code)} ${messages.retry}.` : messages.error(code);
1648
1658
  refreshActions();
1659
+ options.onDispatchChange?.(null);
1649
1660
  options.onViewChange();
1650
1661
  },
1651
1662
  setBusy(nextBusy) {