@predicatesystems/authority 0.3.2 → 0.3.3
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/canonicalization/desktop.d.ts +115 -0
- package/dist/canonicalization/desktop.d.ts.map +1 -0
- package/dist/canonicalization/desktop.js +187 -0
- package/dist/canonicalization/desktop.js.map +1 -0
- package/dist/canonicalization/index.d.ts +39 -0
- package/dist/canonicalization/index.d.ts.map +1 -0
- package/dist/canonicalization/index.js +68 -0
- package/dist/canonicalization/index.js.map +1 -0
- package/dist/canonicalization/terminal.d.ts +69 -0
- package/dist/canonicalization/terminal.d.ts.map +1 -0
- package/dist/canonicalization/terminal.js +98 -0
- package/dist/canonicalization/terminal.js.map +1 -0
- package/dist/canonicalization/utils.d.ts +108 -0
- package/dist/canonicalization/utils.d.ts.map +1 -0
- package/dist/canonicalization/utils.js +250 -0
- package/dist/canonicalization/utils.js.map +1 -0
- package/dist/evidence/non-web.d.ts +14 -0
- package/dist/evidence/non-web.d.ts.map +1 -1
- package/dist/evidence/non-web.js +41 -4
- package/dist/evidence/non-web.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desktop accessibility tree canonicalization for reproducible state hashes.
|
|
3
|
+
*
|
|
4
|
+
* This module provides canonical normalization for desktop accessibility snapshots,
|
|
5
|
+
* ensuring that equivalent UI states produce identical hashes regardless of
|
|
6
|
+
* superficial differences (whitespace, element order, transient attributes).
|
|
7
|
+
*/
|
|
8
|
+
import { type Platform } from "./utils.js";
|
|
9
|
+
/**
|
|
10
|
+
* Raw accessibility tree node from the runtime environment.
|
|
11
|
+
*/
|
|
12
|
+
export interface AccessibilityNode {
|
|
13
|
+
role?: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
children?: AccessibilityNode[];
|
|
16
|
+
pid?: number;
|
|
17
|
+
position?: {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
};
|
|
21
|
+
focused?: boolean;
|
|
22
|
+
selected?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Raw desktop accessibility snapshot from the runtime environment.
|
|
26
|
+
*/
|
|
27
|
+
export interface DesktopAccessibilitySnapshot {
|
|
28
|
+
app_name?: string;
|
|
29
|
+
window_title?: string;
|
|
30
|
+
focused_role?: string;
|
|
31
|
+
focused_name?: string;
|
|
32
|
+
ui_tree?: AccessibilityNode;
|
|
33
|
+
ui_tree_text?: string;
|
|
34
|
+
platform?: Platform;
|
|
35
|
+
observed_at?: string;
|
|
36
|
+
confidence?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Canonical accessibility node with normalized fields.
|
|
40
|
+
*/
|
|
41
|
+
export interface CanonicalAccessibilityNode {
|
|
42
|
+
role: string;
|
|
43
|
+
name_norm: string;
|
|
44
|
+
children: CanonicalAccessibilityNode[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Canonical desktop snapshot with normalized fields.
|
|
48
|
+
*
|
|
49
|
+
* This is the deterministic representation used for hashing.
|
|
50
|
+
*/
|
|
51
|
+
export interface CanonicalDesktopSnapshot {
|
|
52
|
+
app_name_norm: string;
|
|
53
|
+
window_title_norm: string;
|
|
54
|
+
focused_path: string;
|
|
55
|
+
tree_hash: string;
|
|
56
|
+
platform: Platform;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Canonicalize an accessibility tree node.
|
|
60
|
+
*
|
|
61
|
+
* Normalizes:
|
|
62
|
+
* - `role`: Lowercase, trimmed
|
|
63
|
+
* - `name`: Text normalization (whitespace, case, length)
|
|
64
|
+
* - `children`: Recursively canonicalized, sorted by (role, name)
|
|
65
|
+
*
|
|
66
|
+
* Ignores transient attributes: pid, position, focused, selected.
|
|
67
|
+
*
|
|
68
|
+
* @param node - Raw accessibility node
|
|
69
|
+
* @param depth - Current depth (for truncation)
|
|
70
|
+
* @returns Canonical node
|
|
71
|
+
*/
|
|
72
|
+
export declare function canonicalizeAccessibilityNode(node: AccessibilityNode | null | undefined, depth?: number): CanonicalAccessibilityNode;
|
|
73
|
+
/**
|
|
74
|
+
* Build a focused element path string.
|
|
75
|
+
*
|
|
76
|
+
* Creates a path like "window/toolbar/button[Save]" representing
|
|
77
|
+
* the path to the focused element in the accessibility tree.
|
|
78
|
+
*
|
|
79
|
+
* @param focusedRole - Role of the focused element
|
|
80
|
+
* @param focusedName - Name of the focused element
|
|
81
|
+
* @returns Path string
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildFocusedPath(focusedRole?: string, focusedName?: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* Canonicalize a desktop accessibility snapshot.
|
|
86
|
+
*
|
|
87
|
+
* Normalizes all fields to produce a deterministic representation:
|
|
88
|
+
* - `app_name`: Lowercase, trimmed
|
|
89
|
+
* - `window_title`: Text normalization (capped at 100 chars)
|
|
90
|
+
* - `focused_path`: Built from focused element info
|
|
91
|
+
* - `tree_hash`: SHA-256 of canonical tree JSON
|
|
92
|
+
*
|
|
93
|
+
* @param snapshot - Raw desktop accessibility snapshot
|
|
94
|
+
* @returns Canonical snapshot for hashing
|
|
95
|
+
*/
|
|
96
|
+
export declare function canonicalizeDesktopSnapshot(snapshot: DesktopAccessibilitySnapshot): CanonicalDesktopSnapshot;
|
|
97
|
+
/**
|
|
98
|
+
* Compute state hash for a desktop accessibility snapshot.
|
|
99
|
+
*
|
|
100
|
+
* The hash includes all canonical fields in a deterministic order.
|
|
101
|
+
* Platform is included because different platforms have different
|
|
102
|
+
* accessibility APIs and security contexts.
|
|
103
|
+
*
|
|
104
|
+
* @param snapshot - Raw or canonical desktop snapshot
|
|
105
|
+
* @returns SHA-256 hash prefixed with "sha256:"
|
|
106
|
+
*/
|
|
107
|
+
export declare function computeDesktopStateHash(snapshot: DesktopAccessibilitySnapshot | CanonicalDesktopSnapshot): string;
|
|
108
|
+
/**
|
|
109
|
+
* Current schema version for desktop canonicalization.
|
|
110
|
+
*
|
|
111
|
+
* Increment major version for breaking changes to canonical format.
|
|
112
|
+
* Increment minor version for additions that don't change existing hashes.
|
|
113
|
+
*/
|
|
114
|
+
export declare const DESKTOP_SCHEMA_VERSION = "desktop:v1.0";
|
|
115
|
+
//# sourceMappingURL=desktop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop.d.ts","sourceRoot":"","sources":["../../src/canonicalization/desktop.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,QAAQ,EAAyB,MAAM,YAAY,CAAC;AAMlE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAE/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,0BAA0B,EAAE,CAAC;CACxC;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAmBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,EAC1C,KAAK,SAAI,GACR,0BAA0B,CAyC5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAaR;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,4BAA4B,GACrC,wBAAwB,CAsB1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,4BAA4B,GAAG,wBAAwB,GAChE,MAAM,CAgBR;AAoCD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desktop accessibility tree canonicalization for reproducible state hashes.
|
|
3
|
+
*
|
|
4
|
+
* This module provides canonical normalization for desktop accessibility snapshots,
|
|
5
|
+
* ensuring that equivalent UI states produce identical hashes regardless of
|
|
6
|
+
* superficial differences (whitespace, element order, transient attributes).
|
|
7
|
+
*/
|
|
8
|
+
import { normalizeText, sha256 } from "./utils.js";
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Constants
|
|
11
|
+
// =============================================================================
|
|
12
|
+
/** Maximum depth for UI tree canonicalization */
|
|
13
|
+
const MAX_TREE_DEPTH = 10;
|
|
14
|
+
/** Maximum children per node */
|
|
15
|
+
const MAX_CHILDREN_PER_NODE = 50;
|
|
16
|
+
/** Maximum length for window title */
|
|
17
|
+
const MAX_WINDOW_TITLE_LENGTH = 100;
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// Accessibility Node Canonicalization
|
|
20
|
+
// =============================================================================
|
|
21
|
+
/**
|
|
22
|
+
* Canonicalize an accessibility tree node.
|
|
23
|
+
*
|
|
24
|
+
* Normalizes:
|
|
25
|
+
* - `role`: Lowercase, trimmed
|
|
26
|
+
* - `name`: Text normalization (whitespace, case, length)
|
|
27
|
+
* - `children`: Recursively canonicalized, sorted by (role, name)
|
|
28
|
+
*
|
|
29
|
+
* Ignores transient attributes: pid, position, focused, selected.
|
|
30
|
+
*
|
|
31
|
+
* @param node - Raw accessibility node
|
|
32
|
+
* @param depth - Current depth (for truncation)
|
|
33
|
+
* @returns Canonical node
|
|
34
|
+
*/
|
|
35
|
+
export function canonicalizeAccessibilityNode(node, depth = 0) {
|
|
36
|
+
if (!node) {
|
|
37
|
+
return { role: "", name_norm: "", children: [] };
|
|
38
|
+
}
|
|
39
|
+
const role = (node.role ?? "").toLowerCase().trim();
|
|
40
|
+
const nameNorm = normalizeText(node.name);
|
|
41
|
+
// Truncate at max depth
|
|
42
|
+
if (depth >= MAX_TREE_DEPTH) {
|
|
43
|
+
return {
|
|
44
|
+
role,
|
|
45
|
+
name_norm: nameNorm,
|
|
46
|
+
children: [], // Truncated
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Canonicalize children
|
|
50
|
+
let children = [];
|
|
51
|
+
if (node.children && Array.isArray(node.children)) {
|
|
52
|
+
// Limit children count
|
|
53
|
+
const limitedChildren = node.children.slice(0, MAX_CHILDREN_PER_NODE);
|
|
54
|
+
// Canonicalize each child
|
|
55
|
+
children = limitedChildren.map((child) => canonicalizeAccessibilityNode(child, depth + 1));
|
|
56
|
+
// Sort children by (role, name_norm) for determinism
|
|
57
|
+
children.sort((a, b) => {
|
|
58
|
+
const roleCompare = a.role.localeCompare(b.role);
|
|
59
|
+
if (roleCompare !== 0)
|
|
60
|
+
return roleCompare;
|
|
61
|
+
return a.name_norm.localeCompare(b.name_norm);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
role,
|
|
66
|
+
name_norm: nameNorm,
|
|
67
|
+
children,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Build a focused element path string.
|
|
72
|
+
*
|
|
73
|
+
* Creates a path like "window/toolbar/button[Save]" representing
|
|
74
|
+
* the path to the focused element in the accessibility tree.
|
|
75
|
+
*
|
|
76
|
+
* @param focusedRole - Role of the focused element
|
|
77
|
+
* @param focusedName - Name of the focused element
|
|
78
|
+
* @returns Path string
|
|
79
|
+
*/
|
|
80
|
+
export function buildFocusedPath(focusedRole, focusedName) {
|
|
81
|
+
const role = (focusedRole ?? "").toLowerCase().trim();
|
|
82
|
+
const name = normalizeText(focusedName);
|
|
83
|
+
if (!role && !name) {
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
if (!name) {
|
|
87
|
+
return role;
|
|
88
|
+
}
|
|
89
|
+
return `${role}[${name}]`;
|
|
90
|
+
}
|
|
91
|
+
// =============================================================================
|
|
92
|
+
// Desktop Snapshot Canonicalization
|
|
93
|
+
// =============================================================================
|
|
94
|
+
/**
|
|
95
|
+
* Canonicalize a desktop accessibility snapshot.
|
|
96
|
+
*
|
|
97
|
+
* Normalizes all fields to produce a deterministic representation:
|
|
98
|
+
* - `app_name`: Lowercase, trimmed
|
|
99
|
+
* - `window_title`: Text normalization (capped at 100 chars)
|
|
100
|
+
* - `focused_path`: Built from focused element info
|
|
101
|
+
* - `tree_hash`: SHA-256 of canonical tree JSON
|
|
102
|
+
*
|
|
103
|
+
* @param snapshot - Raw desktop accessibility snapshot
|
|
104
|
+
* @returns Canonical snapshot for hashing
|
|
105
|
+
*/
|
|
106
|
+
export function canonicalizeDesktopSnapshot(snapshot) {
|
|
107
|
+
const platform = snapshot.platform ?? detectPlatform();
|
|
108
|
+
// Canonicalize the UI tree if present
|
|
109
|
+
let treeHash;
|
|
110
|
+
if (snapshot.ui_tree) {
|
|
111
|
+
const canonicalTree = canonicalizeAccessibilityNode(snapshot.ui_tree);
|
|
112
|
+
treeHash = sha256(JSON.stringify(canonicalTree));
|
|
113
|
+
}
|
|
114
|
+
else if (snapshot.ui_tree_text) {
|
|
115
|
+
// Fallback: hash the raw text if no structured tree
|
|
116
|
+
treeHash = sha256(normalizeText(snapshot.ui_tree_text, 10000));
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
treeHash = sha256("");
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
app_name_norm: normalizeText(snapshot.app_name),
|
|
123
|
+
window_title_norm: normalizeText(snapshot.window_title, MAX_WINDOW_TITLE_LENGTH),
|
|
124
|
+
focused_path: buildFocusedPath(snapshot.focused_role, snapshot.focused_name),
|
|
125
|
+
tree_hash: treeHash,
|
|
126
|
+
platform,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Compute state hash for a desktop accessibility snapshot.
|
|
131
|
+
*
|
|
132
|
+
* The hash includes all canonical fields in a deterministic order.
|
|
133
|
+
* Platform is included because different platforms have different
|
|
134
|
+
* accessibility APIs and security contexts.
|
|
135
|
+
*
|
|
136
|
+
* @param snapshot - Raw or canonical desktop snapshot
|
|
137
|
+
* @returns SHA-256 hash prefixed with "sha256:"
|
|
138
|
+
*/
|
|
139
|
+
export function computeDesktopStateHash(snapshot) {
|
|
140
|
+
// Canonicalize if not already canonical
|
|
141
|
+
const canonical = isCanonicalDesktopSnapshot(snapshot)
|
|
142
|
+
? snapshot
|
|
143
|
+
: canonicalizeDesktopSnapshot(snapshot);
|
|
144
|
+
// Build deterministic JSON (sorted keys)
|
|
145
|
+
const hashInput = JSON.stringify({
|
|
146
|
+
app_name_norm: canonical.app_name_norm,
|
|
147
|
+
focused_path: canonical.focused_path,
|
|
148
|
+
platform: canonical.platform,
|
|
149
|
+
tree_hash: canonical.tree_hash,
|
|
150
|
+
window_title_norm: canonical.window_title_norm,
|
|
151
|
+
});
|
|
152
|
+
return `sha256:${sha256(hashInput)}`;
|
|
153
|
+
}
|
|
154
|
+
// =============================================================================
|
|
155
|
+
// Helpers
|
|
156
|
+
// =============================================================================
|
|
157
|
+
/**
|
|
158
|
+
* Detect the current platform.
|
|
159
|
+
*/
|
|
160
|
+
function detectPlatform() {
|
|
161
|
+
const p = process.platform;
|
|
162
|
+
if (p === "darwin" || p === "linux" || p === "win32") {
|
|
163
|
+
return p;
|
|
164
|
+
}
|
|
165
|
+
// Default to linux for unknown Unix-like platforms
|
|
166
|
+
return "linux";
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Type guard to check if a snapshot is already canonical.
|
|
170
|
+
*/
|
|
171
|
+
function isCanonicalDesktopSnapshot(snapshot) {
|
|
172
|
+
return ("app_name_norm" in snapshot &&
|
|
173
|
+
"window_title_norm" in snapshot &&
|
|
174
|
+
"focused_path" in snapshot &&
|
|
175
|
+
"tree_hash" in snapshot);
|
|
176
|
+
}
|
|
177
|
+
// =============================================================================
|
|
178
|
+
// Schema Version
|
|
179
|
+
// =============================================================================
|
|
180
|
+
/**
|
|
181
|
+
* Current schema version for desktop canonicalization.
|
|
182
|
+
*
|
|
183
|
+
* Increment major version for breaking changes to canonical format.
|
|
184
|
+
* Increment minor version for additions that don't change existing hashes.
|
|
185
|
+
*/
|
|
186
|
+
export const DESKTOP_SCHEMA_VERSION = "desktop:v1.0";
|
|
187
|
+
//# sourceMappingURL=desktop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop.js","sourceRoot":"","sources":["../../src/canonicalization/desktop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonicalization module for non-web state evidence.
|
|
3
|
+
*
|
|
4
|
+
* This module provides consistent normalization for terminal and desktop
|
|
5
|
+
* accessibility snapshots, ensuring reproducible state hashes across
|
|
6
|
+
* different runs, platforms, and environments.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import {
|
|
11
|
+
* canonicalizeTerminalSnapshot,
|
|
12
|
+
* computeTerminalStateHash,
|
|
13
|
+
* canonicalizeDesktopSnapshot,
|
|
14
|
+
* computeDesktopStateHash,
|
|
15
|
+
* } from "@predicatesystems/authority/canonicalization";
|
|
16
|
+
*
|
|
17
|
+
* // Terminal session
|
|
18
|
+
* const terminalHash = computeTerminalStateHash({
|
|
19
|
+
* session_id: "sess-123",
|
|
20
|
+
* cwd: "~/projects/myapp",
|
|
21
|
+
* command: "npm test", // Extra whitespace normalized
|
|
22
|
+
* transcript: "\x1b[32mPASS\x1b[0m all tests", // ANSI stripped
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Desktop accessibility
|
|
26
|
+
* const desktopHash = computeDesktopStateHash({
|
|
27
|
+
* app_name: "Firefox",
|
|
28
|
+
* window_title: " GitHub - My Repo ", // Whitespace normalized
|
|
29
|
+
* focused_role: "button",
|
|
30
|
+
* focused_name: "Submit",
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @module canonicalization
|
|
35
|
+
*/
|
|
36
|
+
export { type Platform, normalizeText, normalizeCommand, stripAnsi, normalizeTimestamps, normalizeTranscript, normalizePath, isSecretKey, hashEnvironment, sha256, } from "./utils.js";
|
|
37
|
+
export { type TerminalSessionSnapshot, type CanonicalTerminalSnapshot, canonicalizeTerminalSnapshot, computeTerminalStateHash, TERMINAL_SCHEMA_VERSION, } from "./terminal.js";
|
|
38
|
+
export { type AccessibilityNode, type DesktopAccessibilitySnapshot, type CanonicalAccessibilityNode, type CanonicalDesktopSnapshot, canonicalizeAccessibilityNode, buildFocusedPath, canonicalizeDesktopSnapshot, computeDesktopStateHash, DESKTOP_SCHEMA_VERSION, } from "./desktop.js";
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/canonicalization/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAMH,OAAO,EAEL,KAAK,QAAQ,EAEb,aAAa,EACb,gBAAgB,EAEhB,SAAS,EACT,mBAAmB,EAEnB,mBAAmB,EAEnB,aAAa,EAEb,WAAW,EACX,eAAe,EAEf,MAAM,GACP,MAAM,YAAY,CAAC;AAMpB,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAE9B,4BAA4B,EAC5B,wBAAwB,EAExB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAMvB,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAE7B,6BAA6B,EAC7B,gBAAgB,EAChB,2BAA2B,EAC3B,uBAAuB,EAEvB,sBAAsB,GACvB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonicalization module for non-web state evidence.
|
|
3
|
+
*
|
|
4
|
+
* This module provides consistent normalization for terminal and desktop
|
|
5
|
+
* accessibility snapshots, ensuring reproducible state hashes across
|
|
6
|
+
* different runs, platforms, and environments.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import {
|
|
11
|
+
* canonicalizeTerminalSnapshot,
|
|
12
|
+
* computeTerminalStateHash,
|
|
13
|
+
* canonicalizeDesktopSnapshot,
|
|
14
|
+
* computeDesktopStateHash,
|
|
15
|
+
* } from "@predicatesystems/authority/canonicalization";
|
|
16
|
+
*
|
|
17
|
+
* // Terminal session
|
|
18
|
+
* const terminalHash = computeTerminalStateHash({
|
|
19
|
+
* session_id: "sess-123",
|
|
20
|
+
* cwd: "~/projects/myapp",
|
|
21
|
+
* command: "npm test", // Extra whitespace normalized
|
|
22
|
+
* transcript: "\x1b[32mPASS\x1b[0m all tests", // ANSI stripped
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Desktop accessibility
|
|
26
|
+
* const desktopHash = computeDesktopStateHash({
|
|
27
|
+
* app_name: "Firefox",
|
|
28
|
+
* window_title: " GitHub - My Repo ", // Whitespace normalized
|
|
29
|
+
* focused_role: "button",
|
|
30
|
+
* focused_name: "Submit",
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @module canonicalization
|
|
35
|
+
*/
|
|
36
|
+
// =============================================================================
|
|
37
|
+
// Re-exports: Utilities
|
|
38
|
+
// =============================================================================
|
|
39
|
+
export {
|
|
40
|
+
// Text normalization
|
|
41
|
+
normalizeText, normalizeCommand,
|
|
42
|
+
// ANSI and timestamp handling
|
|
43
|
+
stripAnsi, normalizeTimestamps,
|
|
44
|
+
// Transcript normalization
|
|
45
|
+
normalizeTranscript,
|
|
46
|
+
// Path normalization
|
|
47
|
+
normalizePath,
|
|
48
|
+
// Environment hashing
|
|
49
|
+
isSecretKey, hashEnvironment,
|
|
50
|
+
// Core hashing
|
|
51
|
+
sha256, } from "./utils.js";
|
|
52
|
+
// =============================================================================
|
|
53
|
+
// Re-exports: Terminal Canonicalization
|
|
54
|
+
// =============================================================================
|
|
55
|
+
export {
|
|
56
|
+
// Functions
|
|
57
|
+
canonicalizeTerminalSnapshot, computeTerminalStateHash,
|
|
58
|
+
// Schema version
|
|
59
|
+
TERMINAL_SCHEMA_VERSION, } from "./terminal.js";
|
|
60
|
+
// =============================================================================
|
|
61
|
+
// Re-exports: Desktop Canonicalization
|
|
62
|
+
// =============================================================================
|
|
63
|
+
export {
|
|
64
|
+
// Functions
|
|
65
|
+
canonicalizeAccessibilityNode, buildFocusedPath, canonicalizeDesktopSnapshot, computeDesktopStateHash,
|
|
66
|
+
// Schema version
|
|
67
|
+
DESKTOP_SCHEMA_VERSION, } from "./desktop.js";
|
|
68
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/canonicalization/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF,OAAO;AAGL,qBAAqB;AACrB,aAAa,EACb,gBAAgB;AAChB,8BAA8B;AAC9B,SAAS,EACT,mBAAmB;AACnB,2BAA2B;AAC3B,mBAAmB;AACnB,qBAAqB;AACrB,aAAa;AACb,sBAAsB;AACtB,WAAW,EACX,eAAe;AACf,eAAe;AACf,MAAM,GACP,MAAM,YAAY,CAAC;AAEpB,gFAAgF;AAChF,wCAAwC;AACxC,gFAAgF;AAEhF,OAAO;AAIL,YAAY;AACZ,4BAA4B,EAC5B,wBAAwB;AACxB,iBAAiB;AACjB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAEvB,gFAAgF;AAChF,uCAAuC;AACvC,gFAAgF;AAEhF,OAAO;AAML,YAAY;AACZ,6BAA6B,EAC7B,gBAAgB,EAChB,2BAA2B,EAC3B,uBAAuB;AACvB,iBAAiB;AACjB,sBAAsB,GACvB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal session canonicalization for reproducible state hashes.
|
|
3
|
+
*
|
|
4
|
+
* This module provides canonical normalization for terminal sessions,
|
|
5
|
+
* ensuring that equivalent terminal states produce identical hashes
|
|
6
|
+
* regardless of superficial differences (whitespace, ANSI codes, timestamps).
|
|
7
|
+
*/
|
|
8
|
+
import { type Platform } from "./utils.js";
|
|
9
|
+
/**
|
|
10
|
+
* Raw terminal session snapshot from the runtime environment.
|
|
11
|
+
*/
|
|
12
|
+
export interface TerminalSessionSnapshot {
|
|
13
|
+
session_id: string;
|
|
14
|
+
terminal_id?: string;
|
|
15
|
+
cwd?: string;
|
|
16
|
+
command?: string;
|
|
17
|
+
transcript?: string;
|
|
18
|
+
exit_code?: number | null;
|
|
19
|
+
env?: Record<string, string>;
|
|
20
|
+
platform?: Platform;
|
|
21
|
+
observed_at?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Canonical terminal snapshot with normalized fields.
|
|
25
|
+
*
|
|
26
|
+
* This is the deterministic representation used for hashing.
|
|
27
|
+
*/
|
|
28
|
+
export interface CanonicalTerminalSnapshot {
|
|
29
|
+
session_id: string;
|
|
30
|
+
terminal_id: string;
|
|
31
|
+
cwd_normalized: string;
|
|
32
|
+
command_normalized: string;
|
|
33
|
+
transcript_normalized: string;
|
|
34
|
+
exit_code: number | null;
|
|
35
|
+
env_hash: string;
|
|
36
|
+
platform: Platform;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Canonicalize a terminal session snapshot.
|
|
40
|
+
*
|
|
41
|
+
* Normalizes all fields to produce a deterministic representation:
|
|
42
|
+
* - `cwd`: Resolved to absolute path
|
|
43
|
+
* - `command`: Trimmed and whitespace-collapsed (case preserved)
|
|
44
|
+
* - `transcript`: ANSI stripped, timestamps normalized, whitespace collapsed
|
|
45
|
+
* - `env`: Sorted, secrets redacted, then hashed
|
|
46
|
+
*
|
|
47
|
+
* @param snapshot - Raw terminal session snapshot
|
|
48
|
+
* @returns Canonical snapshot for hashing
|
|
49
|
+
*/
|
|
50
|
+
export declare function canonicalizeTerminalSnapshot(snapshot: TerminalSessionSnapshot): CanonicalTerminalSnapshot;
|
|
51
|
+
/**
|
|
52
|
+
* Compute state hash for a terminal session snapshot.
|
|
53
|
+
*
|
|
54
|
+
* The hash includes all canonical fields in a deterministic order.
|
|
55
|
+
* Platform is included because different platforms have different
|
|
56
|
+
* security contexts (e.g., Unix vs Windows permissions).
|
|
57
|
+
*
|
|
58
|
+
* @param snapshot - Raw or canonical terminal snapshot
|
|
59
|
+
* @returns SHA-256 hash prefixed with "sha256:"
|
|
60
|
+
*/
|
|
61
|
+
export declare function computeTerminalStateHash(snapshot: TerminalSessionSnapshot | CanonicalTerminalSnapshot): string;
|
|
62
|
+
/**
|
|
63
|
+
* Current schema version for terminal canonicalization.
|
|
64
|
+
*
|
|
65
|
+
* Increment major version for breaking changes to canonical format.
|
|
66
|
+
* Increment minor version for additions that don't change existing hashes.
|
|
67
|
+
*/
|
|
68
|
+
export declare const TERMINAL_SCHEMA_VERSION = "terminal:v1.0";
|
|
69
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/canonicalization/terminal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,QAAQ,EAMd,MAAM,YAAY,CAAC;AAMpB;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,uBAAuB,GAChC,yBAAyB,CAa3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,uBAAuB,GAAG,yBAAyB,GAC5D,MAAM,CAmBR;AAoCD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal session canonicalization for reproducible state hashes.
|
|
3
|
+
*
|
|
4
|
+
* This module provides canonical normalization for terminal sessions,
|
|
5
|
+
* ensuring that equivalent terminal states produce identical hashes
|
|
6
|
+
* regardless of superficial differences (whitespace, ANSI codes, timestamps).
|
|
7
|
+
*/
|
|
8
|
+
import { hashEnvironment, normalizeCommand, normalizePath, normalizeTranscript, sha256, } from "./utils.js";
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Canonicalization
|
|
11
|
+
// =============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Canonicalize a terminal session snapshot.
|
|
14
|
+
*
|
|
15
|
+
* Normalizes all fields to produce a deterministic representation:
|
|
16
|
+
* - `cwd`: Resolved to absolute path
|
|
17
|
+
* - `command`: Trimmed and whitespace-collapsed (case preserved)
|
|
18
|
+
* - `transcript`: ANSI stripped, timestamps normalized, whitespace collapsed
|
|
19
|
+
* - `env`: Sorted, secrets redacted, then hashed
|
|
20
|
+
*
|
|
21
|
+
* @param snapshot - Raw terminal session snapshot
|
|
22
|
+
* @returns Canonical snapshot for hashing
|
|
23
|
+
*/
|
|
24
|
+
export function canonicalizeTerminalSnapshot(snapshot) {
|
|
25
|
+
const platform = snapshot.platform ?? detectPlatform();
|
|
26
|
+
return {
|
|
27
|
+
session_id: snapshot.session_id,
|
|
28
|
+
terminal_id: snapshot.terminal_id ?? "",
|
|
29
|
+
cwd_normalized: normalizePath(snapshot.cwd),
|
|
30
|
+
command_normalized: normalizeCommand(snapshot.command),
|
|
31
|
+
transcript_normalized: normalizeTranscript(snapshot.transcript),
|
|
32
|
+
exit_code: snapshot.exit_code ?? null,
|
|
33
|
+
env_hash: hashEnvironment(snapshot.env),
|
|
34
|
+
platform,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Compute state hash for a terminal session snapshot.
|
|
39
|
+
*
|
|
40
|
+
* The hash includes all canonical fields in a deterministic order.
|
|
41
|
+
* Platform is included because different platforms have different
|
|
42
|
+
* security contexts (e.g., Unix vs Windows permissions).
|
|
43
|
+
*
|
|
44
|
+
* @param snapshot - Raw or canonical terminal snapshot
|
|
45
|
+
* @returns SHA-256 hash prefixed with "sha256:"
|
|
46
|
+
*/
|
|
47
|
+
export function computeTerminalStateHash(snapshot) {
|
|
48
|
+
// Canonicalize if not already canonical
|
|
49
|
+
const canonical = isCanonicalTerminalSnapshot(snapshot)
|
|
50
|
+
? snapshot
|
|
51
|
+
: canonicalizeTerminalSnapshot(snapshot);
|
|
52
|
+
// Build deterministic JSON (sorted keys)
|
|
53
|
+
const hashInput = JSON.stringify({
|
|
54
|
+
command_normalized: canonical.command_normalized,
|
|
55
|
+
cwd_normalized: canonical.cwd_normalized,
|
|
56
|
+
env_hash: canonical.env_hash,
|
|
57
|
+
exit_code: canonical.exit_code,
|
|
58
|
+
platform: canonical.platform,
|
|
59
|
+
session_id: canonical.session_id,
|
|
60
|
+
terminal_id: canonical.terminal_id,
|
|
61
|
+
transcript_normalized: canonical.transcript_normalized,
|
|
62
|
+
});
|
|
63
|
+
return `sha256:${sha256(hashInput)}`;
|
|
64
|
+
}
|
|
65
|
+
// =============================================================================
|
|
66
|
+
// Helpers
|
|
67
|
+
// =============================================================================
|
|
68
|
+
/**
|
|
69
|
+
* Detect the current platform.
|
|
70
|
+
*/
|
|
71
|
+
function detectPlatform() {
|
|
72
|
+
const p = process.platform;
|
|
73
|
+
if (p === "darwin" || p === "linux" || p === "win32") {
|
|
74
|
+
return p;
|
|
75
|
+
}
|
|
76
|
+
// Default to linux for unknown Unix-like platforms
|
|
77
|
+
return "linux";
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Type guard to check if a snapshot is already canonical.
|
|
81
|
+
*/
|
|
82
|
+
function isCanonicalTerminalSnapshot(snapshot) {
|
|
83
|
+
return ("cwd_normalized" in snapshot &&
|
|
84
|
+
"command_normalized" in snapshot &&
|
|
85
|
+
"transcript_normalized" in snapshot &&
|
|
86
|
+
"env_hash" in snapshot);
|
|
87
|
+
}
|
|
88
|
+
// =============================================================================
|
|
89
|
+
// Schema Version
|
|
90
|
+
// =============================================================================
|
|
91
|
+
/**
|
|
92
|
+
* Current schema version for terminal canonicalization.
|
|
93
|
+
*
|
|
94
|
+
* Increment major version for breaking changes to canonical format.
|
|
95
|
+
* Increment minor version for additions that don't change existing hashes.
|
|
96
|
+
*/
|
|
97
|
+
export const TERMINAL_SCHEMA_VERSION = "terminal:v1.0";
|
|
98
|
+
//# sourceMappingURL=terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/canonicalization/terminal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAEL,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,MAAM,GACP,MAAM,YAAY,CAAC;AAqCpB,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,4BAA4B,CAC1C,QAAiC;IAEjC,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,IAAI,cAAc,EAAE,CAAC;IAEvD,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,EAAE;QACvC,cAAc,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC3C,kBAAkB,EAAE,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC;QACtD,qBAAqB,EAAE,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC/D,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,IAAI;QACrC,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC;QACvC,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAA6D;IAE7D,wCAAwC;IACxC,MAAM,SAAS,GAAG,2BAA2B,CAAC,QAAQ,CAAC;QACrD,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC;IAE3C,yCAAyC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAC/B,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;QAChD,cAAc,EAAE,SAAS,CAAC,cAAc;QACxC,QAAQ,EAAE,SAAS,CAAC,QAAQ;QAC5B,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,QAAQ,EAAE,SAAS,CAAC,QAAQ;QAC5B,UAAU,EAAE,SAAS,CAAC,UAAU;QAChC,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,qBAAqB,EAAE,SAAS,CAAC,qBAAqB;KACvD,CAAC,CAAC;IAEH,OAAO,UAAU,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;AACvC,CAAC;AAED,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAEhF;;GAEG;AACH,SAAS,cAAc;IACrB,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC3B,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;QACrD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,mDAAmD;IACnD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,2BAA2B,CAClC,QAA6D;IAE7D,OAAO,CACL,gBAAgB,IAAI,QAAQ;QAC5B,oBAAoB,IAAI,QAAQ;QAChC,uBAAuB,IAAI,QAAQ;QACnC,UAAU,IAAI,QAAQ,CACvB,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,eAAe,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared canonicalization utilities for non-web contexts.
|
|
3
|
+
*
|
|
4
|
+
* These utilities provide consistent normalization for terminal and desktop
|
|
5
|
+
* accessibility snapshots, ensuring reproducible state hashes.
|
|
6
|
+
*/
|
|
7
|
+
export type Platform = "darwin" | "linux" | "win32";
|
|
8
|
+
/**
|
|
9
|
+
* Normalize text for canonical comparison.
|
|
10
|
+
*
|
|
11
|
+
* Transforms:
|
|
12
|
+
* - Trims leading/trailing whitespace
|
|
13
|
+
* - Collapses internal whitespace to single spaces
|
|
14
|
+
* - Lowercases (for non-command text)
|
|
15
|
+
* - Caps length
|
|
16
|
+
*
|
|
17
|
+
* @param text - Input text (may be null/undefined)
|
|
18
|
+
* @param maxLen - Maximum length to retain (default: 80)
|
|
19
|
+
* @returns Normalized text string (empty string if input is null/undefined)
|
|
20
|
+
*/
|
|
21
|
+
export declare function normalizeText(text: string | null | undefined, maxLen?: number): string;
|
|
22
|
+
/**
|
|
23
|
+
* Normalize a command string.
|
|
24
|
+
*
|
|
25
|
+
* Unlike normalizeText, this preserves case (commands are case-sensitive)
|
|
26
|
+
* but still trims and collapses whitespace.
|
|
27
|
+
*
|
|
28
|
+
* @param cmd - Command string
|
|
29
|
+
* @returns Normalized command
|
|
30
|
+
*/
|
|
31
|
+
export declare function normalizeCommand(cmd: string | null | undefined): string;
|
|
32
|
+
/**
|
|
33
|
+
* Remove all ANSI escape sequences from text.
|
|
34
|
+
*
|
|
35
|
+
* Handles:
|
|
36
|
+
* - Color codes: \x1b[31m (red), \x1b[0m (reset)
|
|
37
|
+
* - Cursor movement: \x1b[2J (clear screen)
|
|
38
|
+
* - Terminal control sequences
|
|
39
|
+
*
|
|
40
|
+
* @param text - Text potentially containing ANSI codes
|
|
41
|
+
* @returns Text with ANSI codes removed
|
|
42
|
+
*/
|
|
43
|
+
export declare function stripAnsi(text: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Replace common timestamp patterns with placeholder.
|
|
46
|
+
*
|
|
47
|
+
* This ensures that transcript hashes remain stable across runs
|
|
48
|
+
* even when timestamps differ.
|
|
49
|
+
*
|
|
50
|
+
* @param text - Text potentially containing timestamps
|
|
51
|
+
* @returns Text with timestamps replaced by [TIMESTAMP]
|
|
52
|
+
*/
|
|
53
|
+
export declare function normalizeTimestamps(text: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Normalize a terminal transcript for canonical hashing.
|
|
56
|
+
*
|
|
57
|
+
* Steps:
|
|
58
|
+
* 1. Strip ANSI escape codes
|
|
59
|
+
* 2. Normalize timestamps
|
|
60
|
+
* 3. For each line: trim trailing whitespace, collapse internal whitespace
|
|
61
|
+
* 4. Remove empty trailing lines
|
|
62
|
+
* 5. Cap total length
|
|
63
|
+
*
|
|
64
|
+
* @param transcript - Raw terminal transcript
|
|
65
|
+
* @returns Normalized transcript
|
|
66
|
+
*/
|
|
67
|
+
export declare function normalizeTranscript(transcript: string | null | undefined): string;
|
|
68
|
+
/**
|
|
69
|
+
* Normalize a file system path for canonical hashing.
|
|
70
|
+
*
|
|
71
|
+
* Handles:
|
|
72
|
+
* - Home directory expansion (~ on Unix, %USERPROFILE% on Windows)
|
|
73
|
+
* - Resolution of . and ..
|
|
74
|
+
* - Conversion to absolute path
|
|
75
|
+
* - Lowercase drive letter on Windows
|
|
76
|
+
*
|
|
77
|
+
* Note: Symlink resolution is not performed (would require async fs.realpath).
|
|
78
|
+
*
|
|
79
|
+
* @param inputPath - Path to normalize
|
|
80
|
+
* @returns Normalized absolute path in OS-native format
|
|
81
|
+
*/
|
|
82
|
+
export declare function normalizePath(inputPath: string | null | undefined): string;
|
|
83
|
+
/**
|
|
84
|
+
* Check if an environment variable key indicates a secret value.
|
|
85
|
+
*
|
|
86
|
+
* @param key - Environment variable name
|
|
87
|
+
* @returns True if the key matches a secret pattern
|
|
88
|
+
*/
|
|
89
|
+
export declare function isSecretKey(key: string): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Hash environment variables for canonical representation.
|
|
92
|
+
*
|
|
93
|
+
* - Redacts values for keys matching secret patterns
|
|
94
|
+
* - Sorts keys for determinism
|
|
95
|
+
* - Returns SHA-256 hash of canonical representation
|
|
96
|
+
*
|
|
97
|
+
* @param env - Environment variables
|
|
98
|
+
* @returns SHA-256 hash of canonical env representation
|
|
99
|
+
*/
|
|
100
|
+
export declare function hashEnvironment(env: Record<string, string> | null | undefined): string;
|
|
101
|
+
/**
|
|
102
|
+
* Compute SHA-256 hash of input string.
|
|
103
|
+
*
|
|
104
|
+
* @param input - String to hash
|
|
105
|
+
* @returns Hex-encoded SHA-256 hash
|
|
106
|
+
*/
|
|
107
|
+
export declare function sha256(input: string): string;
|
|
108
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/canonicalization/utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAMpD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,SAAK,GAAG,MAAM,CAelF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAKvE;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAeD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMxD;AASD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CA8BjF;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CA4B1E;AAgBD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAkBtF;AAMD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5C"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared canonicalization utilities for non-web contexts.
|
|
3
|
+
*
|
|
4
|
+
* These utilities provide consistent normalization for terminal and desktop
|
|
5
|
+
* accessibility snapshots, ensuring reproducible state hashes.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Text Normalization
|
|
11
|
+
// =============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Normalize text for canonical comparison.
|
|
14
|
+
*
|
|
15
|
+
* Transforms:
|
|
16
|
+
* - Trims leading/trailing whitespace
|
|
17
|
+
* - Collapses internal whitespace to single spaces
|
|
18
|
+
* - Lowercases (for non-command text)
|
|
19
|
+
* - Caps length
|
|
20
|
+
*
|
|
21
|
+
* @param text - Input text (may be null/undefined)
|
|
22
|
+
* @param maxLen - Maximum length to retain (default: 80)
|
|
23
|
+
* @returns Normalized text string (empty string if input is null/undefined)
|
|
24
|
+
*/
|
|
25
|
+
export function normalizeText(text, maxLen = 80) {
|
|
26
|
+
if (!text)
|
|
27
|
+
return "";
|
|
28
|
+
// Trim and collapse whitespace
|
|
29
|
+
let normalized = text.split(/\s+/).join(" ").trim();
|
|
30
|
+
// Lowercase
|
|
31
|
+
normalized = normalized.toLowerCase();
|
|
32
|
+
// Cap length
|
|
33
|
+
if (normalized.length > maxLen) {
|
|
34
|
+
normalized = normalized.slice(0, maxLen);
|
|
35
|
+
}
|
|
36
|
+
return normalized;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Normalize a command string.
|
|
40
|
+
*
|
|
41
|
+
* Unlike normalizeText, this preserves case (commands are case-sensitive)
|
|
42
|
+
* but still trims and collapses whitespace.
|
|
43
|
+
*
|
|
44
|
+
* @param cmd - Command string
|
|
45
|
+
* @returns Normalized command
|
|
46
|
+
*/
|
|
47
|
+
export function normalizeCommand(cmd) {
|
|
48
|
+
if (!cmd)
|
|
49
|
+
return "";
|
|
50
|
+
// Trim and collapse whitespace only (preserve case)
|
|
51
|
+
return cmd.split(/\s+/).join(" ").trim();
|
|
52
|
+
}
|
|
53
|
+
// =============================================================================
|
|
54
|
+
// ANSI Escape Code Handling
|
|
55
|
+
// =============================================================================
|
|
56
|
+
/**
|
|
57
|
+
* ANSI escape sequence pattern.
|
|
58
|
+
* Matches color codes, cursor movement, and terminal control sequences.
|
|
59
|
+
*/
|
|
60
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape codes require matching control characters
|
|
61
|
+
const ANSI_PATTERN = /\x1b\[[0-9;]*[a-zA-Z]/g;
|
|
62
|
+
/**
|
|
63
|
+
* Remove all ANSI escape sequences from text.
|
|
64
|
+
*
|
|
65
|
+
* Handles:
|
|
66
|
+
* - Color codes: \x1b[31m (red), \x1b[0m (reset)
|
|
67
|
+
* - Cursor movement: \x1b[2J (clear screen)
|
|
68
|
+
* - Terminal control sequences
|
|
69
|
+
*
|
|
70
|
+
* @param text - Text potentially containing ANSI codes
|
|
71
|
+
* @returns Text with ANSI codes removed
|
|
72
|
+
*/
|
|
73
|
+
export function stripAnsi(text) {
|
|
74
|
+
return text.replace(ANSI_PATTERN, "");
|
|
75
|
+
}
|
|
76
|
+
// =============================================================================
|
|
77
|
+
// Timestamp Normalization
|
|
78
|
+
// =============================================================================
|
|
79
|
+
/**
|
|
80
|
+
* Common timestamp patterns to normalize.
|
|
81
|
+
*/
|
|
82
|
+
const TIMESTAMP_PATTERNS = [
|
|
83
|
+
/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:?\d{2})?/g, // ISO 8601
|
|
84
|
+
/\d{2}:\d{2}:\d{2}/g, // HH:MM:SS
|
|
85
|
+
/\[\d+\.\d+s\]/g, // Duration [1.23s]
|
|
86
|
+
];
|
|
87
|
+
/**
|
|
88
|
+
* Replace common timestamp patterns with placeholder.
|
|
89
|
+
*
|
|
90
|
+
* This ensures that transcript hashes remain stable across runs
|
|
91
|
+
* even when timestamps differ.
|
|
92
|
+
*
|
|
93
|
+
* @param text - Text potentially containing timestamps
|
|
94
|
+
* @returns Text with timestamps replaced by [TIMESTAMP]
|
|
95
|
+
*/
|
|
96
|
+
export function normalizeTimestamps(text) {
|
|
97
|
+
let result = text;
|
|
98
|
+
for (const pattern of TIMESTAMP_PATTERNS) {
|
|
99
|
+
result = result.replace(pattern, "[TIMESTAMP]");
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
// =============================================================================
|
|
104
|
+
// Transcript Normalization
|
|
105
|
+
// =============================================================================
|
|
106
|
+
/** Maximum transcript length in bytes (10KB) */
|
|
107
|
+
const MAX_TRANSCRIPT_LENGTH = 10 * 1024;
|
|
108
|
+
/**
|
|
109
|
+
* Normalize a terminal transcript for canonical hashing.
|
|
110
|
+
*
|
|
111
|
+
* Steps:
|
|
112
|
+
* 1. Strip ANSI escape codes
|
|
113
|
+
* 2. Normalize timestamps
|
|
114
|
+
* 3. For each line: trim trailing whitespace, collapse internal whitespace
|
|
115
|
+
* 4. Remove empty trailing lines
|
|
116
|
+
* 5. Cap total length
|
|
117
|
+
*
|
|
118
|
+
* @param transcript - Raw terminal transcript
|
|
119
|
+
* @returns Normalized transcript
|
|
120
|
+
*/
|
|
121
|
+
export function normalizeTranscript(transcript) {
|
|
122
|
+
if (!transcript)
|
|
123
|
+
return "";
|
|
124
|
+
// Strip ANSI codes first
|
|
125
|
+
let normalized = stripAnsi(transcript);
|
|
126
|
+
// Normalize timestamps
|
|
127
|
+
normalized = normalizeTimestamps(normalized);
|
|
128
|
+
// Process line by line
|
|
129
|
+
const lines = normalized.split("\n").map((line) => {
|
|
130
|
+
// Trim trailing whitespace
|
|
131
|
+
let processed = line.trimEnd();
|
|
132
|
+
// Collapse internal whitespace (tabs -> space, multiple spaces -> single)
|
|
133
|
+
processed = processed.replace(/\t/g, " ").replace(/ +/g, " ");
|
|
134
|
+
return processed;
|
|
135
|
+
});
|
|
136
|
+
// Remove empty trailing lines
|
|
137
|
+
while (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
138
|
+
lines.pop();
|
|
139
|
+
}
|
|
140
|
+
// Join and cap length
|
|
141
|
+
let result = lines.join("\n");
|
|
142
|
+
if (result.length > MAX_TRANSCRIPT_LENGTH) {
|
|
143
|
+
result = result.slice(0, MAX_TRANSCRIPT_LENGTH);
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
// =============================================================================
|
|
148
|
+
// Path Normalization
|
|
149
|
+
// =============================================================================
|
|
150
|
+
/**
|
|
151
|
+
* Normalize a file system path for canonical hashing.
|
|
152
|
+
*
|
|
153
|
+
* Handles:
|
|
154
|
+
* - Home directory expansion (~ on Unix, %USERPROFILE% on Windows)
|
|
155
|
+
* - Resolution of . and ..
|
|
156
|
+
* - Conversion to absolute path
|
|
157
|
+
* - Lowercase drive letter on Windows
|
|
158
|
+
*
|
|
159
|
+
* Note: Symlink resolution is not performed (would require async fs.realpath).
|
|
160
|
+
*
|
|
161
|
+
* @param inputPath - Path to normalize
|
|
162
|
+
* @returns Normalized absolute path in OS-native format
|
|
163
|
+
*/
|
|
164
|
+
export function normalizePath(inputPath) {
|
|
165
|
+
if (!inputPath)
|
|
166
|
+
return "";
|
|
167
|
+
let normalized = inputPath;
|
|
168
|
+
// Expand home directory (cross-platform)
|
|
169
|
+
if (normalized.startsWith("~")) {
|
|
170
|
+
// Unix/macOS: ~/foo -> /Users/name/foo
|
|
171
|
+
normalized = normalized.replace(/^~/, process.env.HOME || "");
|
|
172
|
+
}
|
|
173
|
+
else if (normalized.includes("%USERPROFILE%")) {
|
|
174
|
+
// Windows: %USERPROFILE%\foo -> C:\Users\name\foo
|
|
175
|
+
normalized = normalized.replace(/%USERPROFILE%/gi, process.env.USERPROFILE || "");
|
|
176
|
+
}
|
|
177
|
+
// Resolve . and .. (uses OS-native separators)
|
|
178
|
+
normalized = path.normalize(normalized);
|
|
179
|
+
// Convert to absolute if relative
|
|
180
|
+
if (!path.isAbsolute(normalized)) {
|
|
181
|
+
normalized = path.resolve(normalized);
|
|
182
|
+
}
|
|
183
|
+
// Windows: lowercase drive letter for consistency (C: -> c:)
|
|
184
|
+
if (process.platform === "win32" && /^[A-Z]:/.test(normalized)) {
|
|
185
|
+
normalized = normalized[0].toLowerCase() + normalized.slice(1);
|
|
186
|
+
}
|
|
187
|
+
return normalized;
|
|
188
|
+
}
|
|
189
|
+
// =============================================================================
|
|
190
|
+
// Environment Variable Hashing
|
|
191
|
+
// =============================================================================
|
|
192
|
+
/**
|
|
193
|
+
* Patterns that indicate an environment variable contains a secret.
|
|
194
|
+
*/
|
|
195
|
+
const SECRET_PATTERNS = [
|
|
196
|
+
/^(AWS_|AZURE_|GCP_|GOOGLE_)/i, // Cloud providers
|
|
197
|
+
/(_KEY|_SECRET|_TOKEN|_PASSWORD)$/i, // Common suffixes
|
|
198
|
+
/^(API_KEY|AUTH_TOKEN|PRIVATE_KEY)$/i, // Common names
|
|
199
|
+
/^(DATABASE_URL|REDIS_URL)$/i, // Connection strings
|
|
200
|
+
];
|
|
201
|
+
/**
|
|
202
|
+
* Check if an environment variable key indicates a secret value.
|
|
203
|
+
*
|
|
204
|
+
* @param key - Environment variable name
|
|
205
|
+
* @returns True if the key matches a secret pattern
|
|
206
|
+
*/
|
|
207
|
+
export function isSecretKey(key) {
|
|
208
|
+
return SECRET_PATTERNS.some((p) => p.test(key));
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Hash environment variables for canonical representation.
|
|
212
|
+
*
|
|
213
|
+
* - Redacts values for keys matching secret patterns
|
|
214
|
+
* - Sorts keys for determinism
|
|
215
|
+
* - Returns SHA-256 hash of canonical representation
|
|
216
|
+
*
|
|
217
|
+
* @param env - Environment variables
|
|
218
|
+
* @returns SHA-256 hash of canonical env representation
|
|
219
|
+
*/
|
|
220
|
+
export function hashEnvironment(env) {
|
|
221
|
+
if (!env)
|
|
222
|
+
return sha256("");
|
|
223
|
+
// Filter out secrets
|
|
224
|
+
const safeEnv = {};
|
|
225
|
+
for (const [key, value] of Object.entries(env)) {
|
|
226
|
+
if (isSecretKey(key)) {
|
|
227
|
+
safeEnv[key] = "[REDACTED]";
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
safeEnv[key] = value;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Sort keys for determinism
|
|
234
|
+
const sortedKeys = Object.keys(safeEnv).sort();
|
|
235
|
+
const canonical = sortedKeys.map((k) => `${k}=${safeEnv[k]}`).join("\n");
|
|
236
|
+
return sha256(canonical);
|
|
237
|
+
}
|
|
238
|
+
// =============================================================================
|
|
239
|
+
// Hashing
|
|
240
|
+
// =============================================================================
|
|
241
|
+
/**
|
|
242
|
+
* Compute SHA-256 hash of input string.
|
|
243
|
+
*
|
|
244
|
+
* @param input - String to hash
|
|
245
|
+
* @returns Hex-encoded SHA-256 hash
|
|
246
|
+
*/
|
|
247
|
+
export function sha256(input) {
|
|
248
|
+
return createHash("sha256").update(input, "utf8").digest("hex");
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/canonicalization/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,13 @@ export interface TerminalStateEvidenceOptions {
|
|
|
33
33
|
schemaVersion?: string;
|
|
34
34
|
confidence?: number;
|
|
35
35
|
hasher?: EvidenceHasher;
|
|
36
|
+
/**
|
|
37
|
+
* Use canonical hashing with proper normalization.
|
|
38
|
+
* When true, applies ANSI stripping, timestamp normalization, whitespace
|
|
39
|
+
* collapsing, and other canonicalization rules for reproducible hashes.
|
|
40
|
+
* @default false (legacy mode for backward compatibility)
|
|
41
|
+
*/
|
|
42
|
+
useCanonicalHash?: boolean;
|
|
36
43
|
}
|
|
37
44
|
export interface DesktopStateEvidenceOptions {
|
|
38
45
|
snapshot: DesktopAccessibilitySnapshot;
|
|
@@ -40,6 +47,13 @@ export interface DesktopStateEvidenceOptions {
|
|
|
40
47
|
schemaVersion?: string;
|
|
41
48
|
confidence?: number;
|
|
42
49
|
hasher?: EvidenceHasher;
|
|
50
|
+
/**
|
|
51
|
+
* Use canonical hashing with proper normalization.
|
|
52
|
+
* When true, applies text normalization, tree sorting, and other
|
|
53
|
+
* canonicalization rules for reproducible hashes.
|
|
54
|
+
* @default false (legacy mode for backward compatibility)
|
|
55
|
+
*/
|
|
56
|
+
useCanonicalHash?: boolean;
|
|
43
57
|
}
|
|
44
58
|
export declare function buildTerminalStateEvidence(options: TerminalStateEvidenceOptions): StateEvidence;
|
|
45
59
|
export declare function buildDesktopAccessibilityStateEvidence(options: DesktopStateEvidenceOptions): StateEvidence;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"non-web.d.ts","sourceRoot":"","sources":["../../src/evidence/non-web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"non-web.d.ts","sourceRoot":"","sources":["../../src/evidence/non-web.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAE9G,MAAM,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;AAE1D,MAAM,WAAW,uBAAuB;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,WAAW,wBAAwB;IACvC,uBAAuB,IAAI,OAAO,CAAC,uBAAuB,CAAC,GAAG,uBAAuB,CAAC;CACvF;AAED,MAAM,WAAW,oCAAoC;IACnD,4BAA4B,IACxB,OAAO,CAAC,4BAA4B,CAAC,GACrC,4BAA4B,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,0BAA0B,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,GAAG,kBAAkB,EAAE,CAAC;CACpF;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,uBAAuB,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,4BAA4B,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,4BAA4B,GAAG,aAAa,CA2B/F;AAED,wBAAgB,sCAAsC,CACpD,OAAO,EAAE,2BAA2B,GACnC,aAAa,CA2Bf;AAED,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,0BAA0B,GACnC,OAAO,CAAC,oBAAoB,CAAC,CAE/B"}
|
package/dist/evidence/non-web.js
CHANGED
|
@@ -1,18 +1,55 @@
|
|
|
1
|
+
import { DESKTOP_SCHEMA_VERSION, TERMINAL_SCHEMA_VERSION, computeDesktopStateHash, computeTerminalStateHash, } from "../canonicalization/index.js";
|
|
1
2
|
export function buildTerminalStateEvidence(options) {
|
|
2
|
-
|
|
3
|
+
let stateHash;
|
|
4
|
+
let schemaVersion;
|
|
5
|
+
if (options.useCanonicalHash) {
|
|
6
|
+
// Use canonical hashing with proper normalization
|
|
7
|
+
const canonicalInput = {
|
|
8
|
+
session_id: options.snapshot.session_id ?? "",
|
|
9
|
+
terminal_id: options.snapshot.terminal_id,
|
|
10
|
+
cwd: options.snapshot.cwd,
|
|
11
|
+
command: options.snapshot.command,
|
|
12
|
+
transcript: options.snapshot.transcript_hash, // Note: expects raw transcript, not pre-hashed
|
|
13
|
+
};
|
|
14
|
+
stateHash = options.stateHash ?? computeTerminalStateHash(canonicalInput);
|
|
15
|
+
schemaVersion = options.schemaVersion ?? TERMINAL_SCHEMA_VERSION;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
// Legacy mode for backward compatibility
|
|
19
|
+
stateHash = options.stateHash ?? hashMaterial(materializeTerminalSnapshot(options.snapshot), options.hasher);
|
|
20
|
+
schemaVersion = options.schemaVersion ?? "terminal-v1";
|
|
21
|
+
}
|
|
3
22
|
return {
|
|
4
23
|
source: "terminal",
|
|
5
24
|
state_hash: stateHash,
|
|
6
|
-
schema_version:
|
|
25
|
+
schema_version: schemaVersion,
|
|
7
26
|
confidence: options.confidence ?? options.snapshot.confidence,
|
|
8
27
|
};
|
|
9
28
|
}
|
|
10
29
|
export function buildDesktopAccessibilityStateEvidence(options) {
|
|
11
|
-
|
|
30
|
+
let stateHash;
|
|
31
|
+
let schemaVersion;
|
|
32
|
+
if (options.useCanonicalHash) {
|
|
33
|
+
// Use canonical hashing with proper normalization
|
|
34
|
+
const canonicalInput = {
|
|
35
|
+
app_name: options.snapshot.app_name,
|
|
36
|
+
window_title: options.snapshot.window_title,
|
|
37
|
+
focused_role: options.snapshot.focused_role,
|
|
38
|
+
focused_name: options.snapshot.focused_name,
|
|
39
|
+
ui_tree_text: options.snapshot.ui_tree_hash, // Note: expects raw text, not pre-hashed
|
|
40
|
+
};
|
|
41
|
+
stateHash = options.stateHash ?? computeDesktopStateHash(canonicalInput);
|
|
42
|
+
schemaVersion = options.schemaVersion ?? DESKTOP_SCHEMA_VERSION;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Legacy mode for backward compatibility
|
|
46
|
+
stateHash = options.stateHash ?? hashMaterial(materializeDesktopSnapshot(options.snapshot), options.hasher);
|
|
47
|
+
schemaVersion = options.schemaVersion ?? "desktop-a11y-v1";
|
|
48
|
+
}
|
|
12
49
|
return {
|
|
13
50
|
source: "desktop_accessibility",
|
|
14
51
|
state_hash: stateHash,
|
|
15
|
-
schema_version:
|
|
52
|
+
schema_version: schemaVersion,
|
|
16
53
|
confidence: options.confidence ?? options.snapshot.confidence,
|
|
17
54
|
};
|
|
18
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"non-web.js","sourceRoot":"","sources":["../../src/evidence/non-web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"non-web.js","sourceRoot":"","sources":["../../src/evidence/non-web.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { ActionGuard, AuthorizationDeniedError, type ActionExecutionResult, type
|
|
|
8
8
|
export { guardedFileRead, guardedFileWrite, guardedHttp, guardedShell, type GuardedFileReadOptions, type GuardedFileWriteOptions, type GuardedHttpOptions, type GuardedShellOptions, } from "./wrappers/sensitive-operations.js";
|
|
9
9
|
export { buildWebStateEvidenceFromRuntimeSnapshot, buildWebStateEvidence, type RuntimeSnapshotLike, type WebStateEvidenceOptions, type WebStateSnapshot, webStateSnapshotFromRuntimeSnapshot, } from "./evidence/web-state.js";
|
|
10
10
|
export { buildDesktopAccessibilityStateEvidence, buildTerminalStateEvidence, collectVerificationEvidence, type DesktopAccessibilityEvidenceProvider, type DesktopAccessibilitySnapshot, type DesktopStateEvidenceOptions, type EvidenceHasher, type TerminalEvidenceProvider, type TerminalSessionSnapshot, type TerminalStateEvidenceOptions, type VerificationSignalProvider, } from "./evidence/non-web.js";
|
|
11
|
+
export { type Platform, type TerminalSessionSnapshot as CanonicalTerminalInput, type CanonicalTerminalSnapshot, type AccessibilityNode, type DesktopAccessibilitySnapshot as CanonicalDesktopInput, type CanonicalAccessibilityNode, type CanonicalDesktopSnapshot, normalizeText, normalizeCommand, stripAnsi, normalizeTimestamps, normalizeTranscript, normalizePath, isSecretKey, hashEnvironment, sha256, canonicalizeTerminalSnapshot, computeTerminalStateHash, TERMINAL_SCHEMA_VERSION, canonicalizeAccessibilityNode, buildFocusedPath, canonicalizeDesktopSnapshot, computeDesktopStateHash, DESKTOP_SCHEMA_VERSION, } from "./canonicalization/index.js";
|
|
11
12
|
export interface AuthorityClientOptions {
|
|
12
13
|
baseUrl: string;
|
|
13
14
|
timeoutMs?: number;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EAGtB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,aAAa,EACb,UAAU,EACV,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,uBAAuB,EACvB,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,2BAA2B,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,WAAW,EACX,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,wCAAwC,EACxC,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,mCAAmC,GACpC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sCAAsC,EACtC,0BAA0B,EAC1B,2BAA2B,EAC3B,KAAK,oCAAoC,EACzC,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,GAChC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,14 @@ export { ActionGuard, AuthorizationDeniedError, } from "./guard/action-guard.js"
|
|
|
8
8
|
export { guardedFileRead, guardedFileWrite, guardedHttp, guardedShell, } from "./wrappers/sensitive-operations.js";
|
|
9
9
|
export { buildWebStateEvidenceFromRuntimeSnapshot, buildWebStateEvidence, webStateSnapshotFromRuntimeSnapshot, } from "./evidence/web-state.js";
|
|
10
10
|
export { buildDesktopAccessibilityStateEvidence, buildTerminalStateEvidence, collectVerificationEvidence, } from "./evidence/non-web.js";
|
|
11
|
+
// Canonicalization module for reproducible state hashes
|
|
12
|
+
export {
|
|
13
|
+
// Utility functions
|
|
14
|
+
normalizeText, normalizeCommand, stripAnsi, normalizeTimestamps, normalizeTranscript, normalizePath, isSecretKey, hashEnvironment, sha256,
|
|
15
|
+
// Terminal canonicalization
|
|
16
|
+
canonicalizeTerminalSnapshot, computeTerminalStateHash, TERMINAL_SCHEMA_VERSION,
|
|
17
|
+
// Desktop canonicalization
|
|
18
|
+
canonicalizeAccessibilityNode, buildFocusedPath, canonicalizeDesktopSnapshot, computeDesktopStateHash, DESKTOP_SCHEMA_VERSION, } from "./canonicalization/index.js";
|
|
11
19
|
export class AuthorityClient {
|
|
12
20
|
baseUrl;
|
|
13
21
|
timeoutMs;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAGL,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAsBpB,OAAO,EAAE,oBAAoB,EAAiC,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,2BAA2B,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,YAAY,EAA0B,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,WAAW,EACX,wBAAwB,GAGzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,YAAY,GAKb,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,wCAAwC,EACxC,qBAAqB,EAIrB,mCAAmC,GACpC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sCAAsC,EACtC,0BAA0B,EAC1B,2BAA2B,GAS5B,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAGL,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAsBpB,OAAO,EAAE,oBAAoB,EAAiC,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,2BAA2B,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,YAAY,EAA0B,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,WAAW,EACX,wBAAwB,GAGzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,YAAY,GAKb,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,wCAAwC,EACxC,qBAAqB,EAIrB,mCAAmC,GACpC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sCAAsC,EACtC,0BAA0B,EAC1B,2BAA2B,GAS5B,MAAM,uBAAuB,CAAC;AAE/B,wDAAwD;AACxD,OAAO;AASL,oBAAoB;AACpB,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,WAAW,EACX,eAAe,EACf,MAAM;AACN,4BAA4B;AAC5B,4BAA4B,EAC5B,wBAAwB,EACxB,uBAAuB;AACvB,2BAA2B;AAC3B,6BAA6B,EAC7B,gBAAgB,EAChB,2BAA2B,EAC3B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AAUrC,MAAM,OAAO,eAAe;IACT,OAAO,CAAS;IAChB,SAAS,CAAS;IAClB,UAAU,CAAS;IACnB,gBAAgB,CAAS;IACzB,YAAY,CAAiC;IAE9D,YAAY,OAA+B;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;QAC3C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,GAAG,CAAC;QACxD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,eAAe,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,OAAyB;QACvC,MAAM,WAAW,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QAErC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YACvD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACnE,IAAI,CAAC;gBACH,IAAI,QAAkB,CAAC;gBACvB,IAAI,CAAC;oBACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE;wBAC5D,MAAM,EAAE,MAAM;wBACd,OAAO,EAAE;4BACP,cAAc,EAAE,kBAAkB;yBACnC;wBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;wBACjC,MAAM,EAAE,UAAU,CAAC,MAAM;qBAC1B,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;wBAC9B,MAAM,KAAK,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;wBACnD,SAAS;oBACX,CAAC;oBACD,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;wBAC1D,MAAM,IAAI,oBAAoB,CAAC,6BAA6B,EAAE;4BAC5D,IAAI,EAAE,SAAS;4BACf,KAAK,EAAE,KAAK;yBACb,CAAC,CAAC;oBACL,CAAC;oBACD,MAAM,IAAI,oBAAoB,CAAC,0CAA0C,EAAE;wBACzE,IAAI,EAAE,eAAe;wBACrB,KAAK,EAAE,KAAK;qBACb,CAAC,CAAC;gBACL,CAAC;gBAED,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;gBAEhD,2EAA2E;gBAC3E,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,uBAAuB,CAAC,OAAO,CAAC,EAAE,CAAC;oBAChE,OAAO,OAAO,CAAC;gBACjB,CAAC;gBAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;wBACxD,MAAM,KAAK,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;wBACnD,SAAS;oBACX,CAAC;oBACD,MAAM,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC/C,CAAC;gBAED,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,CAAC;oBACtC,MAAM,IAAI,oBAAoB,CAAC,oCAAoC,EAAE;wBACnE,IAAI,EAAE,gBAAgB;wBACtB,MAAM,EAAE,QAAQ,CAAC,MAAM;wBACvB,OAAO,EAAE,OAAO;qBACjB,CAAC,CAAC;gBACL,CAAC;gBAED,OAAO,OAAO,CAAC;YACjB,CAAC;oBAAS,CAAC;gBACT,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QAED,MAAM,IAAI,oBAAoB,CAAC,0CAA0C,EAAE;YACzE,IAAI,EAAE,eAAe;SACtB,CAAC,CAAC;IACL,CAAC;CACF;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,QAAkB;IAC/C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,oBAAoB,CAAC,0CAA0C,EAAE;YACzE,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,MAAc,EAAE,OAAgB;IACpD,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,oBAAoB,MAAM,EAAE,CAAC;IAC7E,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;QAClB,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AACjG,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAgB;IAC3C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,OAAkC,CAAC;IAC/C,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7D,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC/D,OAAO,GAAG,CAAC,MAAM,CAAC;IACpB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|