@oscharko-dev/keiko-contracts 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/bff-wire.d.ts +33 -0
  3. package/dist/bff-wire.d.ts.map +1 -1
  4. package/dist/command-runner.d.ts +81 -0
  5. package/dist/command-runner.d.ts.map +1 -0
  6. package/dist/command-runner.js +209 -0
  7. package/dist/container-runtime.d.ts +125 -0
  8. package/dist/container-runtime.d.ts.map +1 -0
  9. package/dist/container-runtime.js +287 -0
  10. package/dist/context-engineering.js +2 -2
  11. package/dist/discussion-intelligence.d.ts +70 -0
  12. package/dist/discussion-intelligence.d.ts.map +1 -0
  13. package/dist/discussion-intelligence.js +440 -0
  14. package/dist/editor-agent-governance.d.ts +65 -0
  15. package/dist/editor-agent-governance.d.ts.map +1 -0
  16. package/dist/editor-agent-governance.js +180 -0
  17. package/dist/editor-agent.d.ts +29 -1
  18. package/dist/editor-agent.d.ts.map +1 -1
  19. package/dist/editor-agent.js +183 -6
  20. package/dist/editor-builtin-capabilities.d.ts +13 -0
  21. package/dist/editor-builtin-capabilities.d.ts.map +1 -0
  22. package/dist/editor-builtin-capabilities.js +135 -0
  23. package/dist/editor-language-mode-map.d.ts +11 -0
  24. package/dist/editor-language-mode-map.d.ts.map +1 -0
  25. package/dist/editor-language-mode-map.js +89 -0
  26. package/dist/editor-layout.d.ts +37 -0
  27. package/dist/editor-layout.d.ts.map +1 -1
  28. package/dist/editor-layout.js +125 -8
  29. package/dist/editor-workspace-path.d.ts +20 -0
  30. package/dist/editor-workspace-path.d.ts.map +1 -0
  31. package/dist/editor-workspace-path.js +133 -0
  32. package/dist/evidence.d.ts +3 -1
  33. package/dist/evidence.d.ts.map +1 -1
  34. package/dist/gateway.d.ts +72 -3
  35. package/dist/gateway.d.ts.map +1 -1
  36. package/dist/gateway.js +73 -3
  37. package/dist/git-commit-intent.d.ts +28 -0
  38. package/dist/git-commit-intent.d.ts.map +1 -0
  39. package/dist/git-commit-intent.js +155 -0
  40. package/dist/git-commit-policy.d.ts +29 -0
  41. package/dist/git-commit-policy.d.ts.map +1 -0
  42. package/dist/git-commit-policy.js +173 -0
  43. package/dist/git-delivery-action-sheet.d.ts +157 -0
  44. package/dist/git-delivery-action-sheet.d.ts.map +1 -0
  45. package/dist/git-delivery-action-sheet.js +430 -0
  46. package/dist/git-delivery-evidence.d.ts +92 -0
  47. package/dist/git-delivery-evidence.d.ts.map +1 -0
  48. package/dist/git-delivery-evidence.js +272 -0
  49. package/dist/git-delivery-policy.d.ts +40 -0
  50. package/dist/git-delivery-policy.d.ts.map +1 -0
  51. package/dist/git-delivery-policy.js +183 -0
  52. package/dist/git-delivery-provider.d.ts +53 -0
  53. package/dist/git-delivery-provider.d.ts.map +1 -0
  54. package/dist/git-delivery-provider.js +96 -0
  55. package/dist/git-delivery.d.ts +202 -0
  56. package/dist/git-delivery.d.ts.map +1 -0
  57. package/dist/git-delivery.js +410 -0
  58. package/dist/git-history.d.ts +27 -0
  59. package/dist/git-history.d.ts.map +1 -0
  60. package/dist/git-history.js +73 -0
  61. package/dist/git-merge.d.ts +67 -0
  62. package/dist/git-merge.d.ts.map +1 -0
  63. package/dist/git-merge.js +323 -0
  64. package/dist/git-pull-request.d.ts +112 -0
  65. package/dist/git-pull-request.d.ts.map +1 -0
  66. package/dist/git-pull-request.js +351 -0
  67. package/dist/git-repository-agent.d.ts +46 -0
  68. package/dist/git-repository-agent.d.ts.map +1 -0
  69. package/dist/git-repository-agent.js +198 -0
  70. package/dist/git-repository-summary.d.ts +54 -0
  71. package/dist/git-repository-summary.d.ts.map +1 -0
  72. package/dist/git-repository-summary.js +105 -0
  73. package/dist/git-repository.d.ts +60 -0
  74. package/dist/git-repository.d.ts.map +1 -0
  75. package/dist/git-repository.js +106 -0
  76. package/dist/git-sync.d.ts +49 -0
  77. package/dist/git-sync.d.ts.map +1 -0
  78. package/dist/git-sync.js +110 -0
  79. package/dist/index.d.ts +63 -9
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +33 -6
  82. package/dist/lsp-process.d.ts +38 -0
  83. package/dist/lsp-process.d.ts.map +1 -0
  84. package/dist/lsp-process.js +103 -0
  85. package/dist/runtime-capabilities.d.ts +44 -0
  86. package/dist/runtime-capabilities.d.ts.map +1 -0
  87. package/dist/runtime-capabilities.js +141 -0
  88. package/dist/task-workspace.d.ts +302 -0
  89. package/dist/task-workspace.d.ts.map +1 -0
  90. package/dist/task-workspace.js +1236 -0
  91. package/dist/voice-action-intent.d.ts +86 -0
  92. package/dist/voice-action-intent.d.ts.map +1 -0
  93. package/dist/voice-action-intent.js +387 -0
  94. package/dist/voice-playback.d.ts +50 -0
  95. package/dist/voice-playback.d.ts.map +1 -0
  96. package/dist/voice-playback.js +240 -0
  97. package/dist/voice-protocol.d.ts +165 -0
  98. package/dist/voice-protocol.d.ts.map +1 -0
  99. package/dist/voice-protocol.js +312 -0
  100. package/dist/voice-transcript.d.ts +57 -0
  101. package/dist/voice-transcript.d.ts.map +1 -0
  102. package/dist/voice-transcript.js +221 -0
  103. package/package.json +5 -1
  104. package/dist/conversation-budget.d.ts +0 -37
  105. package/dist/conversation-budget.d.ts.map +0 -1
  106. package/dist/conversation-budget.js +0 -97
@@ -0,0 +1,180 @@
1
+ // Agent editor action governance, policy, and bounded audit (Issue #1395, ADR-0062).
2
+ //
3
+ // This leaf adds two things on top of the frozen editor-agent control-plane contract
4
+ // (`editor-agent.ts`): a deterministic policy classifier that marks each action allowed,
5
+ // review-required, or denied (AC2), and a content-free audit record shape + pure builder for the
6
+ // bounded audit metadata every mutating action produces (AC1, AC3).
7
+ //
8
+ // Leaf-package rule (ADR-0019 direction 1): no `@oscharko-dev/keiko-*` imports. The classifier is a
9
+ // pure function over its inputs; workspace-sensitivity (`isDenied`) is a `keiko-workspace` concern,
10
+ // so the server computes that boolean and passes it in. Workspace containment reuses the existing
11
+ // `isContainedAgentPath` guard, which already lives in this package.
12
+ //
13
+ // Audit invariant (mirrors `MemoryAuditEvent` and `patchApplyEvidence`): the record NEVER carries
14
+ // raw source text, edit bodies, patch bodies, or secrets. The builder input type has no field that
15
+ // could hold raw content — only enums, counts, identifiers, a workspace-relative path, and a bounded
16
+ // summary — so a content leak is impossible by construction. The server additionally runs every
17
+ // record through the `keiko-security` redactor (defense in depth) before it is stored or served.
18
+ import { isContainedAgentPath, } from "./editor-agent.js";
19
+ // ─── Schema version ───────────────────────────────────────────────────────────
20
+ // Pinned to "1". A breaking change introduces a NEW literal rather than mutating "1", the same
21
+ // evolution rule as `EDITOR_AGENT_SCHEMA_VERSION` and the other audit surfaces.
22
+ export const EDITOR_AGENT_AUDIT_SCHEMA_VERSION = "1";
23
+ // Maximum length for the bounded, redacted `summary`. Audit summaries are dense one-line rationales,
24
+ // never bodies; the bound keeps a long target path or reason string from growing the record.
25
+ export const EDITOR_AGENT_AUDIT_SUMMARY_MAX_CHARS = 200;
26
+ export const EDITOR_AGENT_ACTION_EFFECT_CLASS = {
27
+ openFile: "navigation",
28
+ focusTab: "navigation",
29
+ setSelection: "navigation",
30
+ moveTab: "layout",
31
+ splitPane: "layout",
32
+ format: "content-mutation",
33
+ save: "content-mutation",
34
+ applyTextEdits: "content-mutation",
35
+ applyPatch: "content-mutation",
36
+ };
37
+ // The mutating action set — the classes that change buffer/file content or have an external effect.
38
+ // AC1: every mutating action produces a bounded audit record. Today this resolves to the four write
39
+ // action types; the predicate keeps that derived from the effect-class table rather than re-listed.
40
+ export function isMutatingEditorAgentAction(type) {
41
+ const effectClass = EDITOR_AGENT_ACTION_EFFECT_CLASS[type];
42
+ return effectClass === "content-mutation" || effectClass === "external-effect";
43
+ }
44
+ export const EDITOR_AGENT_ACTION_DISPOSITIONS = [
45
+ "allowed",
46
+ "review-required",
47
+ "denied",
48
+ ];
49
+ export const EDITOR_AGENT_ACTION_DENY_REASONS = [
50
+ "workspace-boundary-escape",
51
+ "denied-sensitive-path",
52
+ ];
53
+ export const EDITOR_AGENT_ACTION_REVIEW_REASONS = [
54
+ "content-mutation-requires-review",
55
+ "external-effect-requires-review",
56
+ ];
57
+ const ALLOWED = {
58
+ disposition: "allowed",
59
+ effectClass: "navigation",
60
+ };
61
+ function denyDecision(effectClass, denyReason) {
62
+ return { disposition: "denied", effectClass, denyReason };
63
+ }
64
+ function reviewDecision(effectClass, reviewReason) {
65
+ return { disposition: "review-required", effectClass, reviewReason };
66
+ }
67
+ // A content mutation is denied when its target escapes the workspace root or matches the deny-list,
68
+ // otherwise it requires human review (the existing #1394 browser diff-review is the review gate).
69
+ function classifyContentMutation(context) {
70
+ if (context.targetPath !== null && !isContainedAgentPath(context.targetPath)) {
71
+ return denyDecision("content-mutation", "workspace-boundary-escape");
72
+ }
73
+ if (context.targetSensitive) {
74
+ return denyDecision("content-mutation", "denied-sensitive-path");
75
+ }
76
+ return reviewDecision("content-mutation", "content-mutation-requires-review");
77
+ }
78
+ // Deterministic, fail-closed policy classifier (AC2). Pure: same (type, context) always yields the
79
+ // same decision, which is required for replay-safe audit and for idempotent action handling. The
80
+ // classifier governs policy posture only; it does NOT re-check the #1394 structural preconditions
81
+ // (version/hash/overlap), which remain upstream gates.
82
+ export function classifyEditorAgentAction(type, context) {
83
+ const effectClass = EDITOR_AGENT_ACTION_EFFECT_CLASS[type];
84
+ switch (effectClass) {
85
+ case "navigation":
86
+ case "layout":
87
+ return { ...ALLOWED, effectClass };
88
+ case "content-mutation":
89
+ return classifyContentMutation(context);
90
+ case "external-effect":
91
+ return reviewDecision("external-effect", "external-effect-requires-review");
92
+ }
93
+ }
94
+ function boundedSummary(text) {
95
+ return text.length <= EDITOR_AGENT_AUDIT_SUMMARY_MAX_CHARS
96
+ ? text
97
+ : text.slice(0, EDITOR_AGENT_AUDIT_SUMMARY_MAX_CHARS);
98
+ }
99
+ function buildAuditSummary(input) {
100
+ const parts = [
101
+ input.actionType,
102
+ input.decision.disposition,
103
+ `outcome=${input.outcome}`,
104
+ ];
105
+ if (typeof input.targetPath === "string" && input.targetPath.length > 0) {
106
+ parts.push(`file=${input.targetPath}`);
107
+ }
108
+ if (input.decision.denyReason !== undefined)
109
+ parts.push(`deny=${input.decision.denyReason}`);
110
+ if (input.decision.reviewReason !== undefined) {
111
+ parts.push(`review=${input.decision.reviewReason}`);
112
+ }
113
+ if (input.conflictCode !== undefined)
114
+ parts.push(`conflict=${input.conflictCode}`);
115
+ return boundedSummary(parts.join(" "));
116
+ }
117
+ // Pure builder for the bounded audit record. The summary is bounded here; secret redaction of the
118
+ // summary and path happens at the server boundary (the leaf cannot import the redactor).
119
+ export function buildEditorAgentActionAuditRecord(input) {
120
+ const targetPath = typeof input.targetPath === "string" && input.targetPath.length > 0
121
+ ? input.targetPath
122
+ : undefined;
123
+ return {
124
+ schemaVersion: EDITOR_AGENT_AUDIT_SCHEMA_VERSION,
125
+ auditId: input.auditId,
126
+ occurredAt: input.occurredAt,
127
+ sessionId: input.sessionId,
128
+ actionId: input.actionId,
129
+ actionType: input.actionType,
130
+ effectClass: input.decision.effectClass,
131
+ mutating: isMutatingEditorAgentAction(input.actionType),
132
+ disposition: input.decision.disposition,
133
+ ...(input.decision.denyReason === undefined ? {} : { denyReason: input.decision.denyReason }),
134
+ ...(input.decision.reviewReason === undefined
135
+ ? {}
136
+ : { reviewReason: input.decision.reviewReason }),
137
+ outcome: input.outcome,
138
+ ...(input.conflictCode === undefined ? {} : { conflictCode: input.conflictCode }),
139
+ ...(input.failureCode === undefined ? {} : { failureCode: input.failureCode }),
140
+ ...(targetPath === undefined ? {} : { targetPath }),
141
+ ...(input.editCount === undefined ? {} : { editCount: input.editCount }),
142
+ ...(input.patchByteLength === undefined ? {} : { patchByteLength: input.patchByteLength }),
143
+ summary: buildAuditSummary(input),
144
+ };
145
+ }
146
+ // ─── Guards ────────────────────────────────────────────────────────────────────
147
+ function isRecord(value) {
148
+ return typeof value === "object" && value !== null && !Array.isArray(value);
149
+ }
150
+ export function isEditorAgentActionDisposition(value) {
151
+ return (typeof value === "string" &&
152
+ EDITOR_AGENT_ACTION_DISPOSITIONS.includes(value));
153
+ }
154
+ export function isEditorAgentActionEffectClass(value) {
155
+ return (value === "navigation" ||
156
+ value === "layout" ||
157
+ value === "content-mutation" ||
158
+ value === "external-effect");
159
+ }
160
+ // Structural guard over a persisted/served audit record. Validates the schema version, required
161
+ // identifiers, the enum members, and the bounded summary. It does not attempt secret detection — the
162
+ // content-free input type plus server-side redaction already guarantee that — it guards shape so a
163
+ // consumer reading the audit feed off the wire cannot be handed a malformed record.
164
+ export function isEditorAgentActionAuditRecord(value) {
165
+ if (!isRecord(value))
166
+ return false;
167
+ return [
168
+ value.schemaVersion === EDITOR_AGENT_AUDIT_SCHEMA_VERSION,
169
+ typeof value.auditId === "string" && value.auditId.length > 0,
170
+ typeof value.occurredAt === "number" && Number.isFinite(value.occurredAt),
171
+ typeof value.sessionId === "string" && value.sessionId.length > 0,
172
+ typeof value.actionId === "string" && value.actionId.length > 0,
173
+ isEditorAgentActionEffectClass(value.effectClass),
174
+ typeof value.mutating === "boolean",
175
+ isEditorAgentActionDisposition(value.disposition),
176
+ typeof value.outcome === "string" && value.outcome.length > 0,
177
+ typeof value.summary === "string" &&
178
+ value.summary.length <= EDITOR_AGENT_AUDIT_SUMMARY_MAX_CHARS,
179
+ ].every(Boolean);
180
+ }
@@ -2,6 +2,7 @@ import type { EditorDocumentVersion } from "./editor-session.js";
2
2
  import type { LanguageRange } from "./language-service.js";
3
3
  export declare const EDITOR_AGENT_SCHEMA_VERSION: "1";
4
4
  export type EditorAgentSnapshotTextMode = "none" | "selection" | "activeFile";
5
+ export declare const DEFAULT_EDITOR_AGENT_SNAPSHOT_TEXT_MODE: EditorAgentSnapshotTextMode;
5
6
  export interface EditorAgentPaneSnapshot {
6
7
  readonly paneId: string;
7
8
  readonly activeFile: string | null;
@@ -26,6 +27,12 @@ export interface EditorAgentSessionSnapshot {
26
27
  readonly warnings: number;
27
28
  readonly infos: number;
28
29
  } | null;
30
+ readonly languageCapability?: {
31
+ readonly languageId: string;
32
+ readonly providerId: string | null;
33
+ readonly available: boolean;
34
+ readonly unavailableReason?: string | undefined;
35
+ } | null;
29
36
  readonly documentVersion?: EditorDocumentVersion | undefined;
30
37
  readonly activeFileContentHash?: string | undefined;
31
38
  readonly textMode: EditorAgentSnapshotTextMode;
@@ -56,6 +63,14 @@ export interface EditorAgentAction {
56
63
  readonly patch?: string | undefined;
57
64
  }
58
65
  export type EditorAgentActionStatus = "queued" | "succeeded" | "failed" | "conflict";
66
+ export type EditorAgentConflictCode = "DIRTY" | "VERSION_MISMATCH" | "CONTENT_HASH_MISMATCH" | "NO_ACTIVE_SESSION" | "NO_ACTIVE_BRIDGE" | "INVALID_EDITS" | "OUT_OF_SCOPE" | "PRECONDITION_REQUIRED";
67
+ export declare const EDITOR_AGENT_CONFLICT_CODES: readonly EditorAgentConflictCode[];
68
+ export type EditorAgentFailureCode = "TIMED_OUT" | "QUEUE_FULL";
69
+ export declare const EDITOR_AGENT_FAILURE_CODES: readonly EditorAgentFailureCode[];
70
+ export interface EditorAgentActionFailure {
71
+ readonly code: EditorAgentFailureCode;
72
+ readonly message: string;
73
+ }
59
74
  export interface EditorAgentActionResult {
60
75
  readonly schemaVersion: typeof EDITOR_AGENT_SCHEMA_VERSION;
61
76
  readonly actionId: string;
@@ -63,9 +78,10 @@ export interface EditorAgentActionResult {
63
78
  readonly status: EditorAgentActionStatus;
64
79
  readonly message?: string | undefined;
65
80
  readonly conflict?: {
66
- readonly code: "DIRTY" | "VERSION_MISMATCH" | "CONTENT_HASH_MISMATCH" | "NO_ACTIVE_SESSION";
81
+ readonly code: EditorAgentConflictCode;
67
82
  readonly message: string;
68
83
  } | undefined;
84
+ readonly failure?: EditorAgentActionFailure | undefined;
69
85
  }
70
86
  export type EditorAgentEvent = {
71
87
  readonly schemaVersion: typeof EDITOR_AGENT_SCHEMA_VERSION;
@@ -125,7 +141,19 @@ export interface EditorAgentParseFail {
125
141
  export type EditorAgentParse<T> = EditorAgentParseOk<T> | EditorAgentParseFail;
126
142
  export declare function isEditorAgentSessionSnapshot(value: unknown): value is EditorAgentSessionSnapshot;
127
143
  export declare function isEditorAgentAction(value: unknown): value is EditorAgentAction;
144
+ export declare const EDITOR_AGENT_WRITE_ACTION_TYPES: readonly EditorAgentActionType[];
145
+ export declare function isEditorAgentWriteActionType(value: unknown): value is EditorAgentActionType;
146
+ export declare function editorAgentActionHasWritePrecondition(action: EditorAgentAction): boolean;
147
+ export declare function editorAgentWritePreconditionError(action: EditorAgentAction): string | null;
128
148
  export declare function isEditorAgentActionResult(value: unknown): value is EditorAgentActionResult;
149
+ export declare function isEditorAgentConflictCode(value: unknown): value is EditorAgentConflictCode;
150
+ export declare function isEditorAgentFailureCode(value: unknown): value is EditorAgentFailureCode;
151
+ export declare function isEditorAgentEvent(value: unknown): value is EditorAgentEvent;
152
+ export declare function validateAgentTextEdits(edits: readonly {
153
+ readonly range: LanguageRange;
154
+ readonly newText: string;
155
+ }[]): string | null;
156
+ export declare function isContainedAgentPath(candidate: string): boolean;
129
157
  export declare function parseEditorAgentSnapshotRequest(value: unknown): EditorAgentParse<EditorAgentSnapshotRequest | EditorAgentBridgeSnapshotRequest>;
130
158
  export declare function parseEditorAgentActionsPostBody(value: unknown): EditorAgentParse<EditorAgentActionsPostBody>;
131
159
  //# sourceMappingURL=editor-agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-agent.d.ts","sourceRoot":"","sources":["../src/editor-agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editor-agent.d.ts","sourceRoot":"","sources":["../src/editor-agent.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,23 @@
1
1
  export const EDITOR_AGENT_SCHEMA_VERSION = "1";
2
+ // Issue #1391 AC1 — snapshot text defaults to `none`. An agent that does not explicitly opt into a
3
+ // text mode never receives document content: the default is the content-free projection. The read
4
+ // request parser fills this in when `textMode` is omitted (a present-but-invalid value is still
5
+ // rejected), so the resolved request always carries a concrete, safe-by-default mode.
6
+ export const DEFAULT_EDITOR_AGENT_SNAPSHOT_TEXT_MODE = "none";
7
+ export const EDITOR_AGENT_CONFLICT_CODES = [
8
+ "DIRTY",
9
+ "VERSION_MISMATCH",
10
+ "CONTENT_HASH_MISMATCH",
11
+ "NO_ACTIVE_SESSION",
12
+ "NO_ACTIVE_BRIDGE",
13
+ "INVALID_EDITS",
14
+ "OUT_OF_SCOPE",
15
+ "PRECONDITION_REQUIRED",
16
+ ];
17
+ export const EDITOR_AGENT_FAILURE_CODES = [
18
+ "TIMED_OUT",
19
+ "QUEUE_FULL",
20
+ ];
2
21
  const EDITOR_AGENT_ACTION_TYPES = [
3
22
  "openFile",
4
23
  "focusTab",
@@ -41,7 +60,7 @@ function isDocumentVersion(value) {
41
60
  isSha256Hex(value.contentHash));
42
61
  }
43
62
  function isPosition(value) {
44
- return isRecord(value) && isNonNegativeInteger(value.line) && isNonNegativeInteger(value.character);
63
+ return (isRecord(value) && isNonNegativeInteger(value.line) && isNonNegativeInteger(value.character));
45
64
  }
46
65
  function isRange(value) {
47
66
  return isRecord(value) && isPosition(value.start) && isPosition(value.end);
@@ -52,6 +71,17 @@ function isDiagnosticsSummary(value) {
52
71
  isNonNegativeInteger(value.warnings) &&
53
72
  isNonNegativeInteger(value.infos));
54
73
  }
74
+ // Issue #1379 AC4 — the content-free language-capability detail. languageId is a non-empty string,
75
+ // providerId is a string or null, available is a boolean, and unavailableReason (when present) is a
76
+ // string. Reuses the existing isRecord / string / isUndefinedOr helpers so the validator style
77
+ // matches the rest of this module.
78
+ function isLanguageCapability(value) {
79
+ return (isRecord(value) &&
80
+ isNonEmptyString(value.languageId) &&
81
+ (value.providerId === null || isString(value.providerId)) &&
82
+ typeof value.available === "boolean" &&
83
+ isUndefinedOr(value.unavailableReason, isString));
84
+ }
55
85
  function isPaneSnapshot(value) {
56
86
  return (isRecord(value) &&
57
87
  isNonEmptyString(value.paneId) &&
@@ -79,6 +109,7 @@ export function isEditorAgentSessionSnapshot(value) {
79
109
  isNullOr(value.cursor, isPosition),
80
110
  isNullOr(value.selection, isRange),
81
111
  isNullOr(value.diagnosticsSummary, isDiagnosticsSummary),
112
+ isUndefinedOr(value.languageCapability, (c) => c === null || isLanguageCapability(c)),
82
113
  isUndefinedOr(value.documentVersion, isDocumentVersion),
83
114
  isUndefinedOr(value.activeFileContentHash, isSha256Hex),
84
115
  isSnapshotTextMode(value.textMode),
@@ -88,7 +119,7 @@ export function isEditorAgentSessionSnapshot(value) {
88
119
  ].every(Boolean);
89
120
  }
90
121
  function isActionType(value) {
91
- return typeof value === "string" && EDITOR_AGENT_ACTION_TYPES.includes(value);
122
+ return (typeof value === "string" && EDITOR_AGENT_ACTION_TYPES.includes(value));
92
123
  }
93
124
  function isSplitDirection(value) {
94
125
  return value === "row" || value === "column";
@@ -128,16 +159,156 @@ export function isEditorAgentAction(value) {
128
159
  isUndefinedOr(value.patch, isString),
129
160
  ].every(Boolean);
130
161
  }
162
+ // Issue #1391 AC2 — write actions. These four action types mutate buffer or file content and must
163
+ // therefore assert an optimistic-concurrency precondition before they run. The remaining action types
164
+ // (openFile, focusTab, moveTab, splitPane, setSelection) are navigation/inspection and carry no such
165
+ // requirement. The server reuses this frozen table so "what is a write action" has a single source of
166
+ // truth across the contract, the BFF preflight, and any future agent.
167
+ export const EDITOR_AGENT_WRITE_ACTION_TYPES = [
168
+ "format",
169
+ "save",
170
+ "applyTextEdits",
171
+ "applyPatch",
172
+ ];
173
+ export function isEditorAgentWriteActionType(value) {
174
+ return (typeof value === "string" &&
175
+ EDITOR_AGENT_WRITE_ACTION_TYPES.includes(value));
176
+ }
177
+ // True when the action pins the document revision it expects to write against — by document version
178
+ // or by content hash. Either precondition is sufficient; both may be supplied. The mandatory
179
+ // `idempotencyKey` (validated by `isEditorAgentAction`) covers safe retry; this covers safe write.
180
+ export function editorAgentActionHasWritePrecondition(action) {
181
+ return action.expectedDocumentVersion !== undefined || action.expectedContentHash !== undefined;
182
+ }
183
+ // Issue #1391 AC2 — a write action must assert a version/hash precondition in addition to its
184
+ // mandatory idempotency key, so an agent can never blind-write over a buffer whose revision it has
185
+ // not pinned (lost-update prevention). Returns a stable, content-free error string when a write
186
+ // action is missing the precondition, or null when the action satisfies it or is not a write action.
187
+ // Pure and throw-free, consistent with the other editor-agent validators; consumers (the BFF
188
+ // preflight, tests, future agents) reuse it rather than re-deriving the rule.
189
+ export function editorAgentWritePreconditionError(action) {
190
+ if (!isEditorAgentWriteActionType(action.type))
191
+ return null;
192
+ if (editorAgentActionHasWritePrecondition(action))
193
+ return null;
194
+ return "Write actions require an expected document version or content hash precondition.";
195
+ }
131
196
  function isActionStatus(value) {
132
197
  return value === "queued" || value === "succeeded" || value === "failed" || value === "conflict";
133
198
  }
199
+ // A conflict detail, when present, must carry a code drawn from the taxonomy and a string message —
200
+ // so a result that claims a conflict cannot smuggle an out-of-taxonomy code past the guard.
201
+ function isEditorAgentConflictDetail(value) {
202
+ if (value === undefined)
203
+ return true;
204
+ return (isRecord(value) && isEditorAgentConflictCode(value.code) && typeof value.message === "string");
205
+ }
206
+ // Issue #1392 — a failure detail, when present, mirrors the conflict-detail guard against the
207
+ // lifecycle-failure taxonomy, so a "failed" result cannot smuggle an out-of-taxonomy code past it.
208
+ function isEditorAgentFailureDetail(value) {
209
+ if (value === undefined)
210
+ return true;
211
+ return (isRecord(value) && isEditorAgentFailureCode(value.code) && typeof value.message === "string");
212
+ }
134
213
  export function isEditorAgentActionResult(value) {
135
214
  return (isRecord(value) &&
136
215
  value.schemaVersion === EDITOR_AGENT_SCHEMA_VERSION &&
137
216
  isNonEmptyString(value.actionId) &&
138
217
  isNonEmptyString(value.sessionId) &&
139
218
  isActionStatus(value.status) &&
140
- (value.message === undefined || typeof value.message === "string"));
219
+ (value.message === undefined || typeof value.message === "string") &&
220
+ isEditorAgentConflictDetail(value.conflict) &&
221
+ isEditorAgentFailureDetail(value.failure));
222
+ }
223
+ export function isEditorAgentConflictCode(value) {
224
+ return (typeof value === "string" &&
225
+ EDITOR_AGENT_CONFLICT_CODES.includes(value));
226
+ }
227
+ export function isEditorAgentFailureCode(value) {
228
+ return (typeof value === "string" &&
229
+ EDITOR_AGENT_FAILURE_CODES.includes(value));
230
+ }
231
+ // Issue #1391 — structural guard over the full editor-agent event union. Validates the shared
232
+ // envelope fields (schemaVersion, eventId) and the payload of every event kind (session, action,
233
+ // result, heartbeat). Consumers that read events off the SSE stream (the browser bridge today, any
234
+ // future agent transport) use it to reject malformed frames at the trust boundary instead of casting
235
+ // untyped JSON. Pure and throw-free.
236
+ export function isEditorAgentEvent(value) {
237
+ if (!isRecord(value))
238
+ return false;
239
+ if (value.schemaVersion !== EDITOR_AGENT_SCHEMA_VERSION)
240
+ return false;
241
+ if (!isNonEmptyString(value.eventId))
242
+ return false;
243
+ switch (value.type) {
244
+ case "session":
245
+ return isEditorAgentSessionSnapshot(value.snapshot);
246
+ case "action":
247
+ return isEditorAgentAction(value.action);
248
+ case "result":
249
+ return isEditorAgentActionResult(value.result);
250
+ case "heartbeat":
251
+ return isNonNegativeInteger(value.updatedAt);
252
+ default:
253
+ return false;
254
+ }
255
+ }
256
+ function validateAgentTextEdit(edit, index) {
257
+ const { start, end } = edit.range;
258
+ const label = String(index);
259
+ if (start.line < 0 || start.character < 0 || end.line < 0 || end.character < 0) {
260
+ return `Edit ${label} has a negative line or character coordinate.`;
261
+ }
262
+ if (end.line < start.line || (end.line === start.line && end.character < start.character)) {
263
+ return `Edit ${label} has an inverted range (end before start).`;
264
+ }
265
+ return null;
266
+ }
267
+ function positionLessThan(a, b) {
268
+ return a.line < b.line || (a.line === b.line && a.character < b.character);
269
+ }
270
+ // Half-open ranges [start, end) overlap iff the later edit starts strictly before the earlier
271
+ // edit ends. Adjacency (next.start === current.end) does not overlap and is allowed.
272
+ function rangesOverlap(current, next) {
273
+ return positionLessThan(next.start, current.end);
274
+ }
275
+ function overlapError(edits) {
276
+ const ordered = edits
277
+ .map((edit, index) => ({ edit, index }))
278
+ .sort((a, b) => (positionLessThan(a.edit.range.start, b.edit.range.start) ? -1 : 1));
279
+ for (let i = 1; i < ordered.length; i += 1) {
280
+ const current = ordered[i - 1];
281
+ const next = ordered[i];
282
+ if (current === undefined || next === undefined)
283
+ continue;
284
+ if (rangesOverlap(current.edit.range, next.edit.range)) {
285
+ const [lo, hi] = [current.index, next.index].sort((x, y) => x - y);
286
+ return `Edits ${String(lo)} and ${String(hi)} overlap.`;
287
+ }
288
+ }
289
+ return null;
290
+ }
291
+ export function validateAgentTextEdits(edits) {
292
+ let index = 0;
293
+ for (const edit of edits) {
294
+ const error = validateAgentTextEdit(edit, index);
295
+ if (error !== null)
296
+ return error;
297
+ index += 1;
298
+ }
299
+ return overlapError(edits);
300
+ }
301
+ export function isContainedAgentPath(candidate) {
302
+ if (candidate.length === 0)
303
+ return false;
304
+ if (candidate.startsWith("/"))
305
+ return false;
306
+ if (/^[A-Za-z]:/u.test(candidate))
307
+ return false;
308
+ if (candidate.includes("\u0000"))
309
+ return false;
310
+ const segments = candidate.split(/[/\\]/u);
311
+ return !segments.includes("..");
141
312
  }
142
313
  function parseBridgeSnapshotRequest(value) {
143
314
  if (!isEditorAgentSessionSnapshot(value.snapshot)) {
@@ -156,7 +327,11 @@ function parseReadSnapshotRequest(value) {
156
327
  if (value.schemaVersion !== EDITOR_AGENT_SCHEMA_VERSION) {
157
328
  return { ok: false, errors: ["schemaVersion must be 1"] };
158
329
  }
159
- if (!isSnapshotTextMode(value.textMode)) {
330
+ // AC1 (#1391): snapshot text defaults to `none`. An omitted `textMode` resolves to the content-free
331
+ // default so an agent never receives document content it did not explicitly request; a value that is
332
+ // present but not one of the three modes is still a hard error.
333
+ const textMode = value.textMode === undefined ? DEFAULT_EDITOR_AGENT_SNAPSHOT_TEXT_MODE : value.textMode;
334
+ if (!isSnapshotTextMode(textMode)) {
160
335
  return { ok: false, errors: ["textMode must be none, selection, or activeFile"] };
161
336
  }
162
337
  if (value.sessionId !== undefined && typeof value.sessionId !== "string") {
@@ -170,7 +345,7 @@ function parseReadSnapshotRequest(value) {
170
345
  value: {
171
346
  schemaVersion: EDITOR_AGENT_SCHEMA_VERSION,
172
347
  ...(value.sessionId === undefined ? {} : { sessionId: value.sessionId }),
173
- textMode: value.textMode,
348
+ textMode,
174
349
  ...(value.maxBytes === undefined ? {} : { maxBytes: value.maxBytes }),
175
350
  },
176
351
  };
@@ -178,7 +353,9 @@ function parseReadSnapshotRequest(value) {
178
353
  export function parseEditorAgentSnapshotRequest(value) {
179
354
  if (!isRecord(value))
180
355
  return { ok: false, errors: ["request must be an object"] };
181
- return value.kind === "snapshot" ? parseBridgeSnapshotRequest(value) : parseReadSnapshotRequest(value);
356
+ return value.kind === "snapshot"
357
+ ? parseBridgeSnapshotRequest(value)
358
+ : parseReadSnapshotRequest(value);
182
359
  }
183
360
  export function parseEditorAgentActionsPostBody(value) {
184
361
  if (isEditorAgentAction(value))
@@ -0,0 +1,13 @@
1
+ export type EditorBuiltinFormattingSource = "monaco-builtin" | "keiko-language-service" | "none";
2
+ export interface EditorBuiltinCapability {
3
+ readonly languageId: string;
4
+ readonly syntaxHighlighting: boolean;
5
+ readonly bracketMatching: boolean;
6
+ readonly documentFormatting: EditorBuiltinFormattingSource;
7
+ }
8
+ export declare const EDITOR_BUILTIN_CAPABILITIES: readonly EditorBuiltinCapability[];
9
+ export declare const EDITOR_BUILTIN_CAPABILITY_BY_LANGUAGE: Readonly<Record<string, EditorBuiltinCapability>>;
10
+ export declare function editorBuiltinCapability(languageId: string): EditorBuiltinCapability | null;
11
+ export declare function editorBuiltinDocumentFormatting(languageId: string): EditorBuiltinFormattingSource;
12
+ export declare function isBuiltinFormattingAvailable(languageId: string): boolean;
13
+ //# sourceMappingURL=editor-builtin-capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-builtin-capabilities.d.ts","sourceRoot":"","sources":["../src/editor-builtin-capabilities.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,6BAA6B,GAAG,gBAAgB,GAAG,wBAAwB,GAAG,MAAM,CAAC;AAOjG,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,6BAA6B,CAAC;CAC5D;AAqGD,eAAO,MAAM,2BAA2B,EAAE,SAAS,uBAAuB,EAEzE,CAAC;AAGF,eAAO,MAAM,qCAAqC,EAAE,QAAQ,CAC1D,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CASxC,CAAC;AAGF,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI,CAE1F;AAID,wBAAgB,+BAA+B,CAAC,UAAU,EAAE,MAAM,GAAG,6BAA6B,CAEjG;AAID,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAExE"}