@spotpatch/runtime 1.2.0 → 1.3.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/dist/index.js CHANGED
@@ -86,7 +86,6 @@ import {
86
86
  AGENT_CHECK_STATUSES,
87
87
  AGENT_FILE_CHANGE_KINDS,
88
88
  AGENT_JOB_STATUSES,
89
- AGENT_WORKSPACE_STATES,
90
89
  ERROR_CODES
91
90
  } from "@spotpatch/shared";
92
91
  var ERROR_CODE_VALUES = new Set(Object.values(ERROR_CODES));
@@ -94,7 +93,6 @@ var CAPABILITY_STATE_VALUES = new Set(AGENT_CAPABILITY_STATES);
94
93
  var CHECK_STATUS_VALUES = new Set(AGENT_CHECK_STATUSES);
95
94
  var FILE_CHANGE_KIND_VALUES = new Set(AGENT_FILE_CHANGE_KINDS);
96
95
  var JOB_STATUS_VALUES = new Set(AGENT_JOB_STATUSES);
97
- var WORKSPACE_STATE_VALUES = new Set(AGENT_WORKSPACE_STATES);
98
96
  var PROFILE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
99
97
  var JOB_ID_PATTERN = /^[A-Za-z0-9_-]+$/;
100
98
  var ISO_TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?Z$/;
@@ -155,7 +153,7 @@ function isAgentWorkspaceHealthSnapshot(value) {
155
153
  "changes",
156
154
  "canIncludeLocalChanges",
157
155
  "errorCode"
158
- ]) || typeof value.state !== "string" || !WORKSPACE_STATE_VALUES.has(value.state) || !isIsoTimestamp(value.checkedAt) || typeof value.canIncludeLocalChanges !== "boolean" || value.errorCode !== void 0 && !isAgentErrorCode(value.errorCode) || !isRecord(value.changes) || !hasOnlyKeys(value.changes, [
156
+ ]) || value.state !== "ready" && value.state !== "consent-required" && value.state !== "blocked" || !isIsoTimestamp(value.checkedAt) || typeof value.canIncludeLocalChanges !== "boolean" || value.errorCode !== void 0 && !isAgentErrorCode(value.errorCode) || !isRecord(value.changes) || !hasOnlyKeys(value.changes, [
159
157
  "staged",
160
158
  "unstaged",
161
159
  "untracked",
@@ -218,7 +216,7 @@ function isAgentEventBase(value) {
218
216
  "timestamp",
219
217
  "type",
220
218
  "data"
221
- ]) && value.schemaVersion === 1 && isPositiveInteger(value.sequence) && isJobId(value.jobId) && typeof value.status === "string" && JOB_STATUS_VALUES.has(value.status) && isIsoTimestamp(value.timestamp) && typeof value.type === "string" && isRecord(value.data);
219
+ ]) && value.schemaVersion === 2 && isPositiveInteger(value.sequence) && isJobId(value.jobId) && typeof value.status === "string" && JOB_STATUS_VALUES.has(value.status) && isIsoTimestamp(value.timestamp) && typeof value.type === "string" && isRecord(value.data);
222
220
  }
223
221
  function isAgentJobEvent(value) {
224
222
  if (!isAgentEventBase(value)) {
@@ -232,12 +230,13 @@ function isAgentJobEvent(value) {
232
230
  return hasOnlyKeys(data, ["message"]) && isBoundedString(data.message, 1024);
233
231
  case "tool":
234
232
  return hasOnlyKeys(data, [
233
+ "turn",
235
234
  "toolCallId",
236
235
  "toolName",
237
236
  "state",
238
237
  "relativePath",
239
238
  "checkLabel"
240
- ]) && isBoundedString(data.toolCallId, 256) && isBoundedString(data.toolName, 100) && (data.state === "started" || data.state === "succeeded" || data.state === "failed") && isOptionalBoundedString(data.relativePath, 1024) && isOptionalBoundedString(data.checkLabel, 100);
239
+ ]) && isPositiveInteger(data.turn) && isBoundedString(data.toolCallId, 256) && isBoundedString(data.toolName, 100) && (data.state === "started" || data.state === "succeeded" || data.state === "failed") && isOptionalBoundedString(data.relativePath, 1024) && isOptionalBoundedString(data.checkLabel, 100);
241
240
  case "check":
242
241
  return hasOnlyKeys(data, ["result"]) && isAgentCheckResult(data.result);
243
242
  case "result-ready":
@@ -1614,7 +1613,7 @@ var AGENT_PANEL_STYLES = `
1614
1613
  font-weight: 560;
1615
1614
  line-height: 1.35;
1616
1615
  outline: none;
1617
- transition: border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease;
1616
+ transition: 160ms ease;
1618
1617
  }
1619
1618
  .spotpatch-agent select:hover { border-color: rgb(148 163 184 / 38%); background-color: rgb(255 255 255 / 5%); }
1620
1619
  .spotpatch-agent select:focus-visible { border-color: rgb(139 124 247 / 76%); box-shadow: 0 0 0 3px rgb(109 93 246 / 18%); }
@@ -1625,7 +1624,7 @@ var AGENT_PANEL_STYLES = `
1625
1624
  .spotpatch-agent select { padding: 10px 13px; }
1626
1625
  .spotpatch-agent select::picker-icon {
1627
1626
  color: #9da6b5;
1628
- transition: rotate 180ms cubic-bezier(.2, .8, .2, 1), color 160ms ease;
1627
+ transition: rotate 180ms cubic-bezier(.2, .8, .2, 1);
1629
1628
  }
1630
1629
  .spotpatch-agent select:open::picker-icon { rotate: 180deg; color: #c4b5fd; }
1631
1630
  .spotpatch-agent select::picker(select) {
@@ -1638,12 +1637,10 @@ var AGENT_PANEL_STYLES = `
1638
1637
  border: 1px solid rgb(139 124 247 / 28%);
1639
1638
  border-radius: 12px;
1640
1639
  padding: 6px;
1641
- color: #e8ebf2;
1642
1640
  background: #10151e;
1643
- box-shadow: 0 18px 50px rgb(0 0 0 / 38%), 0 0 0 1px rgb(255 255 255 / 3%);
1641
+ box-shadow: 0 18px 50px rgb(0 0 0 / 38%);
1644
1642
  opacity: 0;
1645
1643
  transform: translateY(-5px) scale(.985);
1646
- transform-origin: top center;
1647
1644
  transition: opacity 150ms ease, transform 180ms cubic-bezier(.2, .8, .2, 1), overlay 180ms allow-discrete, display 180ms allow-discrete;
1648
1645
  }
1649
1646
  ::picker(select):popover-open { opacity: 1; transform: translateY(0) scale(1); }
@@ -1657,7 +1654,6 @@ var AGENT_PANEL_STYLES = `
1657
1654
  color: #dfe4ee;
1658
1655
  background: transparent;
1659
1656
  cursor: pointer;
1660
- transition: color 120ms ease, background-color 120ms ease;
1661
1657
  }
1662
1658
  .spotpatch-agent select option:hover,
1663
1659
  .spotpatch-agent select option:focus { color: #fff; background: rgb(109 93 246 / 16%); }
@@ -2343,20 +2339,22 @@ var ERROR_MESSAGES_EN = Object.freeze({
2343
2339
  [ERROR_CODES2.AGENT_BUSY]: "Another write Agent job is still active.",
2344
2340
  [ERROR_CODES2.AGENT_LIMIT_EXCEEDED]: "The Agent stopped at a configured time, turn, output, or size limit.",
2345
2341
  [ERROR_CODES2.AGENT_CANCELLED]: "The Agent job was cancelled.",
2346
- [ERROR_CODES2.WORKTREE_DIRTY]: "Local changes require explicit inclusion consent before running AI.",
2347
- [ERROR_CODES2.WORKTREE_NOT_REPOSITORY]: "The Vite root is not the top level of an initialized Git repository.",
2348
- [ERROR_CODES2.WORKTREE_OPERATION_IN_PROGRESS]: "Finish the active merge, rebase, cherry-pick, or revert before running AI.",
2349
- [ERROR_CODES2.WORKTREE_CONFLICTED]: "Resolve all merge conflicts before running AI; SpotPatch will not guess a resolution.",
2350
- [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_TOO_LARGE]: "Local untracked files exceed the safe isolation limit. Reduce their count or total size.",
2351
- [ERROR_CODES2.WORKTREE_UNTRACKED_UNSUPPORTED]: "An untracked item is missing, linked, or not a regular file and cannot be isolated safely.",
2352
- [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "Local changes include conflicts, unsupported files, or exceed the safe baseline limit.",
2353
- [ERROR_CODES2.TOOL_DENIED]: "A model tool request violated the local safety policy.",
2354
- [ERROR_CODES2.TOOL_INPUT_INVALID]: "The model sent invalid tool arguments or reused a tool call ID inconsistently.",
2355
- [ERROR_CODES2.TOOL_PATH_DENIED]: "The model tried to access a protected, non-text, linked, or out-of-project path.",
2356
- [ERROR_CODES2.PATCH_REJECTED]: "The proposed patch did not pass local policy.",
2357
- [ERROR_CODES2.VALIDATION_FAILED]: "Required project checks failed. The change cannot be applied.",
2358
- [ERROR_CODES2.APPLY_CONFLICT]: "Project files changed after the Agent baseline; no overwrite was performed.",
2359
- [ERROR_CODES2.INTERNAL_ERROR]: "The Agent job failed without exposing private details."
2342
+ [ERROR_CODES2.WORKTREE_DIRTY]: "Confirm inclusion of local changes before running AI.",
2343
+ [ERROR_CODES2.WORKTREE_NOT_REPOSITORY]: "Vite root must be an initialized Git repository root.",
2344
+ [ERROR_CODES2.WORKTREE_OPERATION_IN_PROGRESS]: "Finish the active merge, rebase, cherry-pick, or revert.",
2345
+ [ERROR_CODES2.WORKTREE_CONFLICTED]: "Resolve all Git conflicts before running AI.",
2346
+ [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_TOO_LARGE]: "Reduce untracked files below the safe count and size limits.",
2347
+ [ERROR_CODES2.WORKTREE_UNTRACKED_UNSUPPORTED]: "An untracked path is missing, linked, or not a regular file.",
2348
+ [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "Local changes cannot be isolated safely.",
2349
+ [ERROR_CODES2.TOOL_DENIED]: "A tool request violated local safety policy.",
2350
+ [ERROR_CODES2.TOOL_INPUT_INVALID]: "Invalid tool request.",
2351
+ [ERROR_CODES2.TOOL_ARGUMENTS_INVALID]: "Tool arguments are invalid.",
2352
+ [ERROR_CODES2.TOOL_CALL_ID_CONFLICT]: "Tool ID conflicts in this turn.",
2353
+ [ERROR_CODES2.TOOL_PATH_DENIED]: "The model requested a protected or external path.",
2354
+ [ERROR_CODES2.PATCH_REJECTED]: "The patch violated local policy.",
2355
+ [ERROR_CODES2.VALIDATION_FAILED]: "Required checks failed; changes cannot be applied.",
2356
+ [ERROR_CODES2.APPLY_CONFLICT]: "Agent-touched files changed; nothing was overwritten.",
2357
+ [ERROR_CODES2.INTERNAL_ERROR]: "The Agent failed without exposing private details."
2360
2358
  });
2361
2359
  var ERROR_MESSAGES_ZH = Object.freeze({
2362
2360
  [ERROR_CODES2.INVALID_REQUEST]: "Agent \u8BF7\u6C42\u65E0\u6548\uFF0C\u5DF2\u88AB\u62D2\u7EDD\u3002",
@@ -2379,17 +2377,19 @@ var ERROR_MESSAGES_ZH = Object.freeze({
2379
2377
  [ERROR_CODES2.WORKTREE_DIRTY]: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u660E\u786E\u540C\u610F\u5C06\u5F53\u524D\u672C\u5730\u4FEE\u6539\u7EB3\u5165\u9694\u79BB\u57FA\u7EBF\u3002",
2380
2378
  [ERROR_CODES2.WORKTREE_NOT_REPOSITORY]: "Vite \u6839\u76EE\u5F55\u4E0D\u662F\u5DF2\u521D\u59CB\u5316 Git \u4ED3\u5E93\u7684\u9876\u5C42\u76EE\u5F55\u3002",
2381
2379
  [ERROR_CODES2.WORKTREE_OPERATION_IN_PROGRESS]: "\u8BF7\u5148\u5B8C\u6210\u5F53\u524D merge\u3001rebase\u3001cherry-pick \u6216 revert\uFF0C\u518D\u8FD0\u884C AI\u3002",
2382
- [ERROR_CODES2.WORKTREE_CONFLICTED]: "\u8BF7\u5148\u89E3\u51B3\u5168\u90E8\u5408\u5E76\u51B2\u7A81\uFF1BSpotPatch \u4E0D\u4F1A\u731C\u6D4B\u51B2\u7A81\u89E3\u51B3\u65B9\u5F0F\u3002",
2383
- [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_TOO_LARGE]: "\u672C\u5730\u672A\u8DDF\u8E2A\u6587\u4EF6\u8D85\u8FC7\u5B89\u5168\u9694\u79BB\u4E0A\u9650\uFF0C\u8BF7\u51CF\u5C11\u6587\u4EF6\u6570\u91CF\u6216\u603B\u4F53\u79EF\u3002",
2384
- [ERROR_CODES2.WORKTREE_UNTRACKED_UNSUPPORTED]: "\u67D0\u4E2A\u672A\u8DDF\u8E2A\u9879\u5DF2\u4E22\u5931\u3001\u662F\u7B26\u53F7\u94FE\u63A5\u6216\u4E0D\u662F\u666E\u901A\u6587\u4EF6\uFF0C\u65E0\u6CD5\u5B89\u5168\u9694\u79BB\u3002",
2385
- [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "\u672C\u5730\u4FEE\u6539\u5B58\u5728\u51B2\u7A81\u3001\u4E0D\u652F\u6301\u7684\u6587\u4EF6\uFF0C\u6216\u8D85\u8FC7\u5B89\u5168\u57FA\u7EBF\u9650\u5236\u3002",
2386
- [ERROR_CODES2.TOOL_DENIED]: "\u6A21\u578B\u5DE5\u5177\u8BF7\u6C42\u8FDD\u53CD\u672C\u5730\u5B89\u5168\u7B56\u7565\u3002",
2387
- [ERROR_CODES2.TOOL_INPUT_INVALID]: "\u6A21\u578B\u53D1\u9001\u4E86\u65E0\u6548\u5DE5\u5177\u53C2\u6570\uFF0C\u6216\u4E0D\u4E00\u81F4\u5730\u590D\u7528\u4E86\u5DE5\u5177\u8C03\u7528 ID\u3002",
2388
- [ERROR_CODES2.TOOL_PATH_DENIED]: "\u6A21\u578B\u5C1D\u8BD5\u8BBF\u95EE\u53D7\u4FDD\u62A4\u3001\u975E\u6587\u672C\u3001\u7B26\u53F7\u94FE\u63A5\u6216\u9879\u76EE\u5916\u8DEF\u5F84\u3002",
2389
- [ERROR_CODES2.PATCH_REJECTED]: "\u5EFA\u8BAE\u8865\u4E01\u672A\u901A\u8FC7\u672C\u5730\u7B56\u7565\u68C0\u67E5\u3002",
2390
- [ERROR_CODES2.VALIDATION_FAILED]: "\u9879\u76EE\u5FC5\u9700\u68C0\u67E5\u5931\u8D25\uFF0C\u4E0D\u80FD\u5E94\u7528\u672C\u6B21\u53D8\u66F4\u3002",
2391
- [ERROR_CODES2.APPLY_CONFLICT]: "Agent \u5EFA\u7ACB\u57FA\u7EBF\u540E\u9879\u76EE\u6587\u4EF6\u5DF2\u53D8\u5316\uFF0C\u672A\u6267\u884C\u8986\u76D6\u3002",
2392
- [ERROR_CODES2.INTERNAL_ERROR]: "Agent \u4EFB\u52A1\u5931\u8D25\uFF0C\u79C1\u6709\u7EC6\u8282\u672A\u66B4\u9732\u5230\u6D4F\u89C8\u5668\u3002"
2380
+ [ERROR_CODES2.WORKTREE_CONFLICTED]: "\u8BF7\u5148\u89E3\u51B3\u5168\u90E8 Git \u51B2\u7A81\uFF0C\u518D\u8FD0\u884C AI\u3002",
2381
+ [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_TOO_LARGE]: "\u672A\u8DDF\u8E2A\u6587\u4EF6\u8D85\u8FC7\u5B89\u5168\u6570\u91CF\u6216\u4F53\u79EF\u4E0A\u9650\uFF0C\u8BF7\u5148\u7CBE\u7B80\u3002",
2382
+ [ERROR_CODES2.WORKTREE_UNTRACKED_UNSUPPORTED]: "\u672A\u8DDF\u8E2A\u9879\u5DF2\u4E22\u5931\u3001\u662F\u7B26\u53F7\u94FE\u63A5\u6216\u4E0D\u662F\u666E\u901A\u6587\u4EF6\u3002",
2383
+ [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "\u5F53\u524D\u672C\u5730\u4FEE\u6539\u65E0\u6CD5\u5B89\u5168\u9694\u79BB\u3002",
2384
+ [ERROR_CODES2.TOOL_DENIED]: "\u5DE5\u5177\u8BF7\u6C42\u8FDD\u53CD\u672C\u5730\u5B89\u5168\u7B56\u7565\u3002",
2385
+ [ERROR_CODES2.TOOL_INPUT_INVALID]: "\u5DE5\u5177\u8BF7\u6C42\u65E0\u6548\u3002",
2386
+ [ERROR_CODES2.TOOL_ARGUMENTS_INVALID]: "\u5DE5\u5177\u53C2\u6570\u65E0\u6548\u3002",
2387
+ [ERROR_CODES2.TOOL_CALL_ID_CONFLICT]: "\u672C\u8F6E\u5DE5\u5177 ID \u51B2\u7A81\u3002",
2388
+ [ERROR_CODES2.TOOL_PATH_DENIED]: "\u6A21\u578B\u8BF7\u6C42\u4E86\u53D7\u4FDD\u62A4\u6216\u9879\u76EE\u5916\u8DEF\u5F84\u3002",
2389
+ [ERROR_CODES2.PATCH_REJECTED]: "\u8865\u4E01\u8FDD\u53CD\u672C\u5730\u7B56\u7565\u3002",
2390
+ [ERROR_CODES2.VALIDATION_FAILED]: "\u5FC5\u9700\u68C0\u67E5\u5931\u8D25\uFF0C\u65E0\u6CD5\u5E94\u7528\u53D8\u66F4\u3002",
2391
+ [ERROR_CODES2.APPLY_CONFLICT]: "Agent \u89E6\u53CA\u6587\u4EF6\u5DF2\u53D8\u5316\uFF0C\u672A\u8986\u76D6\u3002",
2392
+ [ERROR_CODES2.INTERNAL_ERROR]: "Agent \u5931\u8D25\uFF0C\u672A\u66B4\u9732\u79C1\u6709\u7EC6\u8282\u3002"
2393
2393
  });
2394
2394
  var SUMMARY_MESSAGES_EN = Object.freeze({
2395
2395
  adapter: "React adapter",
@@ -4165,7 +4165,7 @@ function capabilityKey(providerProfileId, modelProfileId) {
4165
4165
  function activityFromEvent(event) {
4166
4166
  if (event.type === "tool") {
4167
4167
  return Object.freeze({
4168
- key: `tool:${event.data.toolCallId}`,
4168
+ key: `tool:${String(event.data.turn)}:${event.data.toolCallId}`,
4169
4169
  label: `${event.data.toolName} \xB7 ${event.data.state}`,
4170
4170
  state: event.data.state === "started" ? "active" : event.data.state === "succeeded" ? "success" : "failure"
4171
4171
  });