@termwright/protocol 0.2.0 → 0.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.
Files changed (40) hide show
  1. package/README.md +213 -605
  2. package/dist/action-model-BP9Znu6L.d.ts +219 -0
  3. package/dist/action-model.d.ts +3 -0
  4. package/dist/action-model.js +15 -0
  5. package/dist/action-model.js.map +1 -0
  6. package/dist/capability-graph.d.ts +90 -0
  7. package/dist/capability-graph.js +43 -0
  8. package/dist/capability-graph.js.map +1 -0
  9. package/dist/chunk-B4VUTTUE.js +59 -0
  10. package/dist/chunk-B4VUTTUE.js.map +1 -0
  11. package/dist/chunk-CZK6NNP3.js +389 -0
  12. package/dist/chunk-CZK6NNP3.js.map +1 -0
  13. package/dist/chunk-ODOJRXL6.js +84 -0
  14. package/dist/chunk-ODOJRXL6.js.map +1 -0
  15. package/dist/chunk-PUXRCPGY.js +112 -0
  16. package/dist/chunk-PUXRCPGY.js.map +1 -0
  17. package/dist/chunk-VBLS6E6U.js +1109 -0
  18. package/dist/chunk-VBLS6E6U.js.map +1 -0
  19. package/dist/chunk-ZZIYHDJ4.js +202 -0
  20. package/dist/chunk-ZZIYHDJ4.js.map +1 -0
  21. package/dist/contract-CH9gmj2Y.d.ts +746 -0
  22. package/dist/contract.d.ts +2 -0
  23. package/dist/contract.js +21 -0
  24. package/dist/contract.js.map +1 -0
  25. package/dist/index.d.ts +82 -798
  26. package/dist/index.js +1087 -766
  27. package/dist/index.js.map +1 -1
  28. package/dist/run-events.d.ts +158 -0
  29. package/dist/run-events.js +27 -0
  30. package/dist/run-events.js.map +1 -0
  31. package/dist/run-journal.d.ts +55 -0
  32. package/dist/run-journal.js +10 -0
  33. package/dist/run-journal.js.map +1 -0
  34. package/dist/run-state.d.ts +38 -0
  35. package/dist/run-state.js +19 -0
  36. package/dist/run-state.js.map +1 -0
  37. package/dist/test-provider.d.ts +22 -0
  38. package/dist/test-provider.js +32 -0
  39. package/dist/test-provider.js.map +1 -0
  40. package/package.json +33 -5
@@ -0,0 +1,112 @@
1
+ // src/artifact-safety.ts
2
+ var ARTIFACT_VALUE_POLICIES = ["none", "redacted", "raw"];
3
+ var DEFAULT_ARTIFACT_VALUE_POLICY = "redacted";
4
+ function sensitive(value) {
5
+ return Object.freeze({ sensitivity: "sensitive", value });
6
+ }
7
+ function publicValue(value) {
8
+ return Object.freeze({ sensitivity: "public", value });
9
+ }
10
+ function executableText(value) {
11
+ return typeof value === "string" ? value : value.value;
12
+ }
13
+ function valueSensitivity(value) {
14
+ return typeof value === "string" ? "sensitive" : value.sensitivity;
15
+ }
16
+ function recordValue(value, policy) {
17
+ const sensitivity = valueSensitivity(value);
18
+ if (policy === "raw" || policy === "redacted" && sensitivity === "public") {
19
+ return Object.freeze({ status: "known", value: executableText(value), sensitivity });
20
+ }
21
+ return Object.freeze({ status: "withheld", reason: "artifact-policy", sensitivity });
22
+ }
23
+ function projectSemanticSnapshotForArtifact(snapshot, policy = DEFAULT_ARTIFACT_VALUE_POLICY) {
24
+ return Object.freeze({
25
+ ...snapshot,
26
+ nodes: Object.freeze(
27
+ snapshot.nodes.map((node) => {
28
+ const value = node.value;
29
+ if (value?.status !== "known" || policy === "raw" || policy === "redacted" && value.sensitivity === "public") {
30
+ return Object.freeze({ ...node });
31
+ }
32
+ return Object.freeze({
33
+ ...node,
34
+ value: Object.freeze({
35
+ status: "withheld",
36
+ reason: "artifact-policy",
37
+ sensitivity: value.sensitivity
38
+ })
39
+ });
40
+ })
41
+ )
42
+ });
43
+ }
44
+
45
+ // src/action-model.ts
46
+ function recordDeviceOperation(operation, policy) {
47
+ if (operation.device === "mouse") return Object.freeze({ ...operation });
48
+ if (operation.kind === "press" && typeof operation.value === "string") {
49
+ return Object.freeze({
50
+ ...operation,
51
+ value: Object.freeze({
52
+ status: "known",
53
+ value: executableTextForPress(operation.value),
54
+ sensitivity: "public"
55
+ })
56
+ });
57
+ }
58
+ return Object.freeze({ ...operation, value: recordValue(operation.value, policy) });
59
+ }
60
+ function executableTextForPress(value) {
61
+ return typeof value === "string" ? value : value.value;
62
+ }
63
+ function recordActionPlan(plan, policy) {
64
+ return Object.freeze({
65
+ ...plan,
66
+ operations: Object.freeze(
67
+ plan.operations.map((operation) => recordDeviceOperation(operation, policy))
68
+ ),
69
+ valuePolicy: policy
70
+ });
71
+ }
72
+ function projectActionReceiptForArtifact(receipt, policy) {
73
+ const project = (operation) => {
74
+ if (operation.device === "mouse" || operation.value.status === "withheld") return operation;
75
+ if (operation.kind === "press" && operation.value.sensitivity === "public") return operation;
76
+ if (policy === "raw" || policy === "redacted" && operation.value.sensitivity === "public")
77
+ return operation;
78
+ return Object.freeze({
79
+ ...operation,
80
+ value: Object.freeze({
81
+ status: "withheld",
82
+ reason: "artifact-policy",
83
+ sensitivity: operation.value.sensitivity
84
+ })
85
+ });
86
+ };
87
+ const plan = Object.freeze({
88
+ ...receipt.plan,
89
+ valuePolicy: policy,
90
+ operations: Object.freeze(receipt.plan.operations.map(project))
91
+ });
92
+ return Object.freeze({
93
+ ...receipt,
94
+ plan,
95
+ executed: Object.freeze(receipt.executed.map(project))
96
+ });
97
+ }
98
+
99
+ export {
100
+ ARTIFACT_VALUE_POLICIES,
101
+ DEFAULT_ARTIFACT_VALUE_POLICY,
102
+ sensitive,
103
+ publicValue,
104
+ executableText,
105
+ valueSensitivity,
106
+ recordValue,
107
+ projectSemanticSnapshotForArtifact,
108
+ recordDeviceOperation,
109
+ recordActionPlan,
110
+ projectActionReceiptForArtifact
111
+ };
112
+ //# sourceMappingURL=chunk-PUXRCPGY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/artifact-safety.ts","../src/action-model.ts"],"sourcesContent":["import type { SemanticSnapshot } from './tree.js';\n\n/** Policy applied when runtime values cross an artifact/publication boundary. */\nexport const ARTIFACT_VALUE_POLICIES = ['none', 'redacted', 'raw'] as const;\nexport type ArtifactValuePolicy = (typeof ARTIFACT_VALUE_POLICIES)[number];\n\n/** Secure default. Recording raw input must always be an explicit choice. */\nexport const DEFAULT_ARTIFACT_VALUE_POLICY: ArtifactValuePolicy = 'redacted';\n\nexport type ValueSensitivity = 'public' | 'sensitive';\n\n/** Explicit wrapper for values which must not enter artifacts by default. */\nexport interface SensitiveValue {\n readonly sensitivity: 'sensitive';\n readonly value: string;\n}\n\nexport interface PublicValue {\n readonly sensitivity: 'public';\n readonly value: string;\n}\n/** Plain strings remain executable but are conservatively sensitive at artifact boundaries. */\nexport type ExecutableValue = string | PublicValue | SensitiveValue;\n\nexport type RecordedValue =\n | { readonly status: 'known'; readonly value: string; readonly sensitivity: ValueSensitivity }\n | {\n readonly status: 'withheld';\n readonly reason: 'artifact-policy';\n readonly sensitivity: ValueSensitivity | 'unknown';\n };\n\nexport function sensitive(value: string): SensitiveValue {\n return Object.freeze({ sensitivity: 'sensitive', value });\n}\n\nexport function publicValue(value: string): PublicValue {\n return Object.freeze({ sensitivity: 'public', value });\n}\n\nexport function executableText(value: ExecutableValue): string {\n return typeof value === 'string' ? value : value.value;\n}\n\nexport function valueSensitivity(value: ExecutableValue): ValueSensitivity {\n return typeof value === 'string' ? 'sensitive' : value.sensitivity;\n}\n\nexport function recordValue(value: ExecutableValue, policy: ArtifactValuePolicy): RecordedValue {\n const sensitivity = valueSensitivity(value);\n if (policy === 'raw' || (policy === 'redacted' && sensitivity === 'public')) {\n return Object.freeze({ status: 'known', value: executableText(value), sensitivity });\n }\n return Object.freeze({ status: 'withheld', reason: 'artifact-policy', sensitivity });\n}\n\nexport function projectSemanticSnapshotForArtifact(\n snapshot: SemanticSnapshot,\n policy: ArtifactValuePolicy = DEFAULT_ARTIFACT_VALUE_POLICY,\n): SemanticSnapshot {\n return Object.freeze({\n ...snapshot,\n nodes: Object.freeze(\n snapshot.nodes.map((node) => {\n const value = node.value;\n if (\n value?.status !== 'known' ||\n policy === 'raw' ||\n (policy === 'redacted' && value.sensitivity === 'public')\n ) {\n return Object.freeze({ ...node });\n }\n return Object.freeze({\n ...node,\n value: Object.freeze({\n status: 'withheld' as const,\n reason: 'artifact-policy' as const,\n sensitivity: value.sensitivity,\n }),\n });\n }),\n ),\n });\n}\n","import type { EvidenceProvenance } from './contract.js';\nimport type { Observation, ObservationStamp } from './observation.js';\nimport type { Rect } from './tree.js';\nimport {\n recordValue,\n type ArtifactValuePolicy,\n type ExecutableValue,\n type RecordedValue,\n} from './artifact-safety.js';\n\n/** Closed vocabulary shared by action planning, traces, Runner and MCP. */\nexport { CONDITION_KINDS } from './capability-graph.js';\nexport type { ConditionKind } from './capability-graph.js';\n\nexport type LocatorDomain = 'semantic' | 'screen';\nexport type SemanticLocatorRef = `semantic:${string}@${number}`;\nexport type ScreenLocatorRef = `screen:${number},${number},${number},${number}@${number}`;\nexport type LocatorRef = SemanticLocatorRef | ScreenLocatorRef;\n\nexport type ConditionTextMatcher =\n | { readonly kind: 'exact' | 'substring'; readonly text: string }\n | { readonly kind: 'regex'; readonly source: string; readonly flags: string };\n\nexport type Condition =\n | { readonly kind: 'attached'; readonly target: string }\n | { readonly kind: 'detached'; readonly target: string }\n | { readonly kind: 'displayed'; readonly target: string }\n | { readonly kind: 'hidden'; readonly target: string }\n | { readonly kind: 'visible'; readonly target: string }\n | { readonly kind: 'in-viewport'; readonly target: string; readonly minRatio: number }\n | { readonly kind: 'offscreen'; readonly target: string }\n | { readonly kind: 'receives-pointer'; readonly target: string }\n | { readonly kind: 'pointer-region'; readonly target: string }\n | { readonly kind: 'pointer-input'; readonly target: string }\n | { readonly kind: 'mouse-input-enabled'; readonly target: string }\n | { readonly kind: 'enabled'; readonly target: string }\n | { readonly kind: 'disabled'; readonly target: string }\n | { readonly kind: 'focused'; readonly target: string }\n | { readonly kind: 'checked'; readonly target: string; readonly value: boolean }\n | { readonly kind: 'selected'; readonly target: string; readonly value: boolean }\n | { readonly kind: 'expanded'; readonly target: string; readonly value: boolean }\n | { readonly kind: 'collapsed'; readonly target: string }\n | { readonly kind: 'value'; readonly target: string; readonly matcher: ConditionTextMatcher }\n | { readonly kind: 'not'; readonly condition: Condition }\n | { readonly kind: 'all' | 'any'; readonly conditions: readonly Condition[] };\n\nexport type ScreenLeafCondition = Extract<\n Condition,\n {\n readonly kind:\n | 'attached'\n | 'detached'\n | 'displayed'\n | 'hidden'\n | 'visible'\n | 'in-viewport'\n | 'offscreen'\n | 'receives-pointer'\n | 'pointer-region'\n | 'pointer-input'\n | 'mouse-input-enabled';\n }\n>;\nexport type ScreenCondition =\n | ScreenLeafCondition\n | { readonly kind: 'not'; readonly condition: ScreenCondition }\n | { readonly kind: 'all' | 'any'; readonly conditions: readonly ScreenCondition[] };\n\nexport interface ConditionResult {\n readonly condition: Condition;\n readonly checkpoint: ObservationStamp;\n readonly observation: Observation<boolean>;\n readonly verdict: 'satisfied' | 'unsatisfied' | 'inconclusive';\n}\n\n/** A disjoint physical region represented as canonical, non-overlapping row spans. */\nexport interface PhysicalRegion {\n readonly checkpoint: ObservationStamp;\n readonly coordinateSpace: 'viewport-cells';\n readonly intendedRect: Rect;\n readonly spans: readonly { readonly row: number; readonly from: number; readonly to: number }[];\n readonly evidence: EvidenceProvenance;\n}\n\nexport type ActionKind =\n | 'click'\n | 'double-click'\n | 'hover'\n | 'drag'\n | 'focus'\n | 'activate'\n | 'press'\n | 'type'\n | 'paste'\n | 'fill'\n | 'check'\n | 'uncheck'\n | 'wheel'\n | 'shell-command'\n | 'resize';\n\nexport interface ActionIntent {\n readonly kind: ActionKind;\n readonly selector?: string;\n readonly targetRef?: LocatorRef;\n}\n\nexport type ExecutableDeviceOperation =\n | {\n readonly device: 'keyboard';\n readonly kind: 'press' | 'type' | 'paste';\n readonly value: ExecutableValue;\n }\n | {\n readonly device: 'mouse';\n readonly kind: 'move' | 'down' | 'up' | 'wheel';\n readonly row: number;\n readonly column: number;\n readonly button?: 'left' | 'middle' | 'right';\n readonly modifiers?: readonly ('shift' | 'alt' | 'control')[];\n readonly deltaX?: number;\n readonly deltaY?: number;\n };\n\nexport type RecordedDeviceOperation =\n | {\n readonly device: 'keyboard';\n readonly kind: 'press' | 'type' | 'paste';\n readonly value: RecordedValue;\n }\n | Exclude<ExecutableDeviceOperation, { readonly device: 'keyboard' }>;\n\n/** Runtime-only plan. It must be projected before crossing an artifact boundary. */\nexport interface ExecutableActionPlan {\n readonly actionId: string;\n readonly contractId: string;\n readonly intent: ActionIntent;\n readonly checkpoint: ObservationStamp;\n readonly requirements: readonly ConditionResult[];\n readonly strategy: string;\n readonly physicalRegion?: PhysicalRegion;\n readonly operations: readonly ExecutableDeviceOperation[];\n}\n\nexport interface ActionPlan {\n readonly actionId: string;\n readonly contractId: string;\n readonly intent: ActionIntent;\n readonly checkpoint: ObservationStamp;\n readonly requirements: readonly ConditionResult[];\n readonly strategy: string;\n readonly physicalRegion?: PhysicalRegion;\n readonly operations: readonly RecordedDeviceOperation[];\n readonly valuePolicy: ArtifactValuePolicy;\n}\n\nexport interface ActionabilityExplanation {\n readonly actionable: boolean;\n readonly intent: ActionIntent;\n readonly checkpoint: ObservationStamp;\n readonly requirements: readonly ConditionResult[];\n readonly strategy?: string;\n readonly reason?: {\n readonly code: string;\n readonly message: string;\n readonly targetRef?: LocatorRef;\n };\n}\n\nexport interface ActionReceipt {\n readonly intent: ActionIntent;\n readonly plan: ActionPlan;\n readonly before: ObservationStamp;\n readonly after: ObservationStamp;\n readonly executed: readonly RecordedDeviceOperation[];\n readonly outcome: 'completed' | 'partial' | 'failed';\n}\n\nexport function recordDeviceOperation(\n operation: ExecutableDeviceOperation,\n policy: ArtifactValuePolicy,\n): RecordedDeviceOperation {\n if (operation.device === 'mouse') return Object.freeze({ ...operation });\n if (operation.kind === 'press' && typeof operation.value === 'string') {\n return Object.freeze({\n ...operation,\n value: Object.freeze({\n status: 'known',\n value: executableTextForPress(operation.value),\n sensitivity: 'public',\n }),\n });\n }\n return Object.freeze({ ...operation, value: recordValue(operation.value, policy) });\n}\n\nfunction executableTextForPress(value: ExecutableValue): string {\n return typeof value === 'string' ? value : value.value;\n}\n\nexport function recordActionPlan(\n plan: ExecutableActionPlan,\n policy: ArtifactValuePolicy,\n): ActionPlan {\n return Object.freeze({\n ...plan,\n operations: Object.freeze(\n plan.operations.map((operation) => recordDeviceOperation(operation, policy)),\n ),\n valuePolicy: policy,\n });\n}\n\nexport function projectActionReceiptForArtifact(\n receipt: ActionReceipt,\n policy: ArtifactValuePolicy,\n): ActionReceipt {\n const project = (operation: RecordedDeviceOperation): RecordedDeviceOperation => {\n if (operation.device === 'mouse' || operation.value.status === 'withheld') return operation;\n if (operation.kind === 'press' && operation.value.sensitivity === 'public') return operation;\n if (policy === 'raw' || (policy === 'redacted' && operation.value.sensitivity === 'public'))\n return operation;\n return Object.freeze({\n ...operation,\n value: Object.freeze({\n status: 'withheld' as const,\n reason: 'artifact-policy' as const,\n sensitivity: operation.value.sensitivity,\n }),\n });\n };\n const plan = Object.freeze({\n ...receipt.plan,\n valuePolicy: policy,\n operations: Object.freeze(receipt.plan.operations.map(project)),\n });\n return Object.freeze({\n ...receipt,\n plan,\n executed: Object.freeze(receipt.executed.map(project)),\n });\n}\n"],"mappings":"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","names":[]}