@uxnan/shared 0.0.1-alpha.20260627

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 (68) hide show
  1. package/README.md +96 -0
  2. package/dist/src/agents/agent-adapter.d.ts +78 -0
  3. package/dist/src/agents/agent-adapter.js +2 -0
  4. package/dist/src/agents/agent-adapter.js.map +1 -0
  5. package/dist/src/agents/agent-capabilities.d.ts +106 -0
  6. package/dist/src/agents/agent-capabilities.js +7 -0
  7. package/dist/src/agents/agent-capabilities.js.map +1 -0
  8. package/dist/src/agents/agent-config.d.ts +17 -0
  9. package/dist/src/agents/agent-config.js +2 -0
  10. package/dist/src/agents/agent-config.js.map +1 -0
  11. package/dist/src/constants.d.ts +30 -0
  12. package/dist/src/constants.js +31 -0
  13. package/dist/src/constants.js.map +1 -0
  14. package/dist/src/e2ee/envelope.d.ts +17 -0
  15. package/dist/src/e2ee/envelope.js +7 -0
  16. package/dist/src/e2ee/envelope.js.map +1 -0
  17. package/dist/src/e2ee/handshake.d.ts +82 -0
  18. package/dist/src/e2ee/handshake.js +14 -0
  19. package/dist/src/e2ee/handshake.js.map +1 -0
  20. package/dist/src/e2ee/pairing-payload.d.ts +44 -0
  21. package/dist/src/e2ee/pairing-payload.js +82 -0
  22. package/dist/src/e2ee/pairing-payload.js.map +1 -0
  23. package/dist/src/index.d.ts +25 -0
  24. package/dist/src/index.js +32 -0
  25. package/dist/src/index.js.map +1 -0
  26. package/dist/src/jsonrpc/envelope.d.ts +39 -0
  27. package/dist/src/jsonrpc/envelope.js +36 -0
  28. package/dist/src/jsonrpc/envelope.js.map +1 -0
  29. package/dist/src/jsonrpc/errors.d.ts +43 -0
  30. package/dist/src/jsonrpc/errors.js +73 -0
  31. package/dist/src/jsonrpc/errors.js.map +1 -0
  32. package/dist/src/jsonrpc/method-registry.d.ts +7 -0
  33. package/dist/src/jsonrpc/method-registry.js +79 -0
  34. package/dist/src/jsonrpc/method-registry.js.map +1 -0
  35. package/dist/src/jsonrpc/methods.d.ts +526 -0
  36. package/dist/src/jsonrpc/methods.js +2 -0
  37. package/dist/src/jsonrpc/methods.js.map +1 -0
  38. package/dist/src/jsonrpc/notifications.d.ts +85 -0
  39. package/dist/src/jsonrpc/notifications.js +19 -0
  40. package/dist/src/jsonrpc/notifications.js.map +1 -0
  41. package/dist/src/models/approval.d.ts +37 -0
  42. package/dist/src/models/approval.js +12 -0
  43. package/dist/src/models/approval.js.map +1 -0
  44. package/dist/src/models/git.d.ts +191 -0
  45. package/dist/src/models/git.js +8 -0
  46. package/dist/src/models/git.js.map +1 -0
  47. package/dist/src/models/project.d.ts +22 -0
  48. package/dist/src/models/project.js +5 -0
  49. package/dist/src/models/project.js.map +1 -0
  50. package/dist/src/models/session.d.ts +28 -0
  51. package/dist/src/models/session.js +7 -0
  52. package/dist/src/models/session.js.map +1 -0
  53. package/dist/src/models/thread.d.ts +104 -0
  54. package/dist/src/models/thread.js +8 -0
  55. package/dist/src/models/thread.js.map +1 -0
  56. package/dist/src/models/workspace.d.ts +133 -0
  57. package/dist/src/models/workspace.js +7 -0
  58. package/dist/src/models/workspace.js.map +1 -0
  59. package/dist/src/notifications/push-payload.d.ts +23 -0
  60. package/dist/src/notifications/push-payload.js +7 -0
  61. package/dist/src/notifications/push-payload.js.map +1 -0
  62. package/dist/src/validators/json-schema/schemas.d.ts +13 -0
  63. package/dist/src/validators/json-schema/schemas.js +82 -0
  64. package/dist/src/validators/json-schema/schemas.js.map +1 -0
  65. package/dist/src/validators/validate.d.ts +20 -0
  66. package/dist/src/validators/validate.js +46 -0
  67. package/dist/src/validators/validate.js.map +1 -0
  68. package/package.json +36 -0
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Git models exchanged over JSON-RPC (git/* methods).
3
+ *
4
+ * Source: architecture/02a-system-architecture.md §5.8.6 and
5
+ * architecture/02b-contracts-and-requirements.md.
6
+ */
7
+ export type GitFileStatus = 'added' | 'modified' | 'deleted' | 'renamed' | 'untracked' | 'conflicted';
8
+ export interface GitChangedFile {
9
+ path: string;
10
+ status: GitFileStatus;
11
+ /** Lines added (working tree vs HEAD). Untracked files report 0. */
12
+ additions?: number;
13
+ /** Lines removed (working tree vs HEAD). Untracked files report 0. */
14
+ deletions?: number;
15
+ }
16
+ export interface GitDiffTotals {
17
+ additions: number;
18
+ deletions: number;
19
+ changedFileCount: number;
20
+ }
21
+ export interface GitRepoStatus {
22
+ branch: string;
23
+ upstream?: string;
24
+ isDirty: boolean;
25
+ ahead: number;
26
+ behind: number;
27
+ files: GitChangedFile[];
28
+ /** Aggregate working-tree counters. */
29
+ diffTotals?: GitDiffTotals;
30
+ }
31
+ export interface GitDiff {
32
+ /** Unified diff text. */
33
+ diff: string;
34
+ additions: number;
35
+ deletions: number;
36
+ }
37
+ export interface GitCommitResult {
38
+ sha: string;
39
+ message: string;
40
+ }
41
+ export interface GitPushResult {
42
+ success: boolean;
43
+ remote: string;
44
+ branch: string;
45
+ }
46
+ export interface GitPullResult {
47
+ success: boolean;
48
+ }
49
+ export interface GitBranchResult {
50
+ branch: string;
51
+ }
52
+ export interface GitWorktreeResult {
53
+ path: string;
54
+ branch: string;
55
+ }
56
+ export interface GitBranchList {
57
+ /** The currently checked-out branch (`HEAD` when detached). */
58
+ current: string;
59
+ /** Local branch names. */
60
+ local: string[];
61
+ /** Remote-tracking branch names (e.g. `origin/main`). */
62
+ remote: string[];
63
+ }
64
+ export interface GitPrResult {
65
+ /** URL of the created (or pre-existing) pull request. */
66
+ url: string;
67
+ /** PR number when the host CLI reports it. */
68
+ number?: number;
69
+ }
70
+ /** Kind of ref pointing at a commit (decoration parsed from `git log %D`). */
71
+ export type GitRefType = 'head' | 'branch' | 'remoteBranch' | 'tag';
72
+ /**
73
+ * A ref (branch / remote branch / tag / HEAD) that points at a commit.
74
+ * Parsed from `git log`'s `%D` decoration so the phone can render branch
75
+ * and tag chips and colour HEAD distinctly in the graph.
76
+ */
77
+ export interface GitRef {
78
+ /** Display name (e.g. `main`, `origin/main`, `v1.2.0`, `HEAD`). */
79
+ name: string;
80
+ /** What the ref is. */
81
+ type: GitRefType;
82
+ }
83
+ /**
84
+ * A single commit in the repository log. The bridge parses `git log` into
85
+ * this shape; the phone renders it in either the flat list view or the
86
+ * graph (GitKraken-style) view. `parents` is what powers the graph —
87
+ * each parent is a "lane" the commit sits on.
88
+ */
89
+ export interface GitCommit {
90
+ /** Full 40-char SHA. */
91
+ sha: string;
92
+ /** Abbreviated SHA (7 chars, git's default). */
93
+ shortSha: string;
94
+ /** Parent commit SHAs in order (zero, one or two — merge commits have two). */
95
+ parents: string[];
96
+ /** Commit author display name. */
97
+ authorName: string;
98
+ /** Commit author email. */
99
+ authorEmail: string;
100
+ /** Author date, unix epoch seconds. */
101
+ authorTimestamp: number;
102
+ /** Committer display name (often equal to author). */
103
+ committerName: string;
104
+ /** Committer email. */
105
+ committerEmail: string;
106
+ /** Committer date, unix epoch seconds. */
107
+ committerTimestamp: number;
108
+ /** First line of the commit message (the "title"). */
109
+ messageTitle: string;
110
+ /** Rest of the commit message after the title (may be empty). */
111
+ messageBody: string;
112
+ /** Aggregate +/-/file-count stats for the commit (git log --shortstat). */
113
+ stats?: GitDiffTotals;
114
+ /**
115
+ * Refs that point at this commit (branches, remote branches, tags, HEAD),
116
+ * parsed from `git log`'s `%D` decoration. Absent/empty for commits with no
117
+ * decoration.
118
+ */
119
+ refs?: GitRef[];
120
+ }
121
+ /**
122
+ * A page of commits for a repository, newest-first in topological order.
123
+ * Pagination is by opaque cursor: when `hasMore` is true, pass `nextCursor`
124
+ * back as `GitLogParams.cursor` to fetch the next (older) page.
125
+ */
126
+ export interface GitLogResult {
127
+ commits: GitCommit[];
128
+ hasMore: boolean;
129
+ /**
130
+ * Opaque pagination token to pass back as `GitLogParams.cursor` for the next
131
+ * page. Undefined when `hasMore` is false. (Currently an offset over a
132
+ * topologically-ordered log — treat it as opaque.)
133
+ */
134
+ nextCursor?: string;
135
+ }
136
+ /** Parameters for `git/log`. */
137
+ export interface GitLogParams {
138
+ cwd: string;
139
+ /** Max commits to return. Defaults to 50 on the bridge. */
140
+ limit?: number;
141
+ /**
142
+ * Opaque pagination cursor from the previous result's `nextCursor`. Omit for
143
+ * the first (newest) page. Paging is offset-based over a topologically
144
+ * ordered log, so no commit is skipped across a merge boundary.
145
+ */
146
+ cursor?: string;
147
+ /**
148
+ * Optional ref (branch / tag / remote) to start from. Defaults to
149
+ ` HEAD. Use `origin/main` etc. for an explicit starting point.
150
+ */
151
+ ref?: string;
152
+ }
153
+ /**
154
+ * A single file touched by a commit (`git show --name-status --numstat`).
155
+ * Rename/copy entries carry the previous path in `oldPath`.
156
+ */
157
+ export interface GitCommitFile {
158
+ /** Repository-relative path after the change (the new path on a rename). */
159
+ path: string;
160
+ /** Previous path, set only for renames/copies. */
161
+ oldPath?: string;
162
+ /** Per-file change kind. */
163
+ status: GitFileStatus;
164
+ /** Lines added in this commit (0 for binary/unknown). */
165
+ additions: number;
166
+ /** Lines removed in this commit (0 for binary/unknown). */
167
+ deletions: number;
168
+ /** True when git reported the file as binary (no line counts). */
169
+ binary?: boolean;
170
+ }
171
+ /**
172
+ * Full detail of one commit: its metadata (incl. refs), the list of files it
173
+ * touched with per-file +/- counts, and the complete unified diff. Powers the
174
+ * mobile commit-detail view (`git/commitShow`).
175
+ */
176
+ export interface GitCommitDetails {
177
+ /** The commit's metadata (same shape as a `git/log` entry). */
178
+ commit: GitCommit;
179
+ /** Files touched by the commit, with per-file stats. */
180
+ files: GitCommitFile[];
181
+ /** The commit's full unified diff (may be truncated — see `diffTruncated`). */
182
+ diff: string;
183
+ /** True when `diff` was capped because the patch exceeded the size budget. */
184
+ diffTruncated?: boolean;
185
+ }
186
+ /** Parameters for `git/commitShow`. */
187
+ export interface GitCommitShowParams {
188
+ cwd: string;
189
+ /** The commit to inspect (full or abbreviated SHA, or any rev). */
190
+ sha: string;
191
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Git models exchanged over JSON-RPC (git/* methods).
3
+ *
4
+ * Source: architecture/02a-system-architecture.md §5.8.6 and
5
+ * architecture/02b-contracts-and-requirements.md.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/models/git.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Project models exchanged over JSON-RPC (project/* methods).
3
+ */
4
+ export interface Project {
5
+ id: string;
6
+ name: string;
7
+ /** Absolute working directory on the PC (never sent verbatim to mobile if sensitive). */
8
+ cwd: string;
9
+ /** Agent pinned for this project in bridge config (the thread's default agent). */
10
+ agentId?: string;
11
+ /** Model pinned for this project's agent in bridge config, when set. */
12
+ model?: string;
13
+ }
14
+ export interface AuthStatus {
15
+ agentId: string;
16
+ requiresLogin: boolean;
17
+ loginInProgress: boolean;
18
+ authenticatedProvider?: string;
19
+ displayName?: string;
20
+ transportMode: 'local' | 'relay';
21
+ platform: NodeJS.Platform | string;
22
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Project models exchanged over JSON-RPC (project/* methods).
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/models/project.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Session and trust models.
3
+ *
4
+ * Dart equivalents: `uxnanmobile/lib/domain/entities/{secure_session,trusted_device}.dart`.
5
+ */
6
+ export type HandshakeMode = 'qr_bootstrap' | 'trusted_reconnect';
7
+ export interface ConnectedPhone {
8
+ deviceId: string;
9
+ displayName: string;
10
+ connectedAt: number;
11
+ lastSeen: number;
12
+ }
13
+ export interface TrustedDevice {
14
+ deviceId: string;
15
+ displayName: string;
16
+ /** Phone Ed25519 identity public key (hex). */
17
+ publicKey: string;
18
+ pairedAt: number;
19
+ lastSeen?: number;
20
+ }
21
+ export interface BridgeStatus {
22
+ version: string;
23
+ relayConnected: boolean;
24
+ lanEnabled: boolean;
25
+ activeSessions: number;
26
+ platform: NodeJS.Platform | string;
27
+ uptimeMs: number;
28
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Session and trust models.
3
+ *
4
+ * Dart equivalents: `uxnanmobile/lib/domain/entities/{secure_session,trusted_device}.dart`.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/models/session.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Conversation models: Thread, Turn, Message.
3
+ *
4
+ * The Dart equivalents live in `uxnanmobile/lib/domain/entities/{thread,turn,message}.dart`
5
+ * and are kept in sync manually (see 02e-bridge-integration.md §4.2).
6
+ */
7
+ export type MessageRole = 'user' | 'assistant' | 'system' | 'tool';
8
+ export type TurnStatus = 'pending' | 'streaming' | 'completed' | 'error' | 'aborted';
9
+ export type ThreadStatus = 'active' | 'idle' | 'archived';
10
+ export interface Message {
11
+ id: string;
12
+ turnId: string;
13
+ role: MessageRole;
14
+ /** Serialized MessageContent blocks (text/code/image/tool/diff/...). */
15
+ content: unknown;
16
+ /** The agent's reasoning ("thinking") for this message, when it emitted any. */
17
+ thinking?: string;
18
+ /** Structured content blocks (command_execution/diff/tool) produced this turn. */
19
+ blocks?: unknown[];
20
+ /**
21
+ * The assistant message's text runs and structured blocks **in the exact
22
+ * order the agent produced them** — each entry is a serialized MessageContent
23
+ * (text runs as `{ type:'text', text }`, work-log/diff blocks as their own
24
+ * types). When present, a client SHOULD render from this so the work log sits
25
+ * inline with the response it precedes, instead of all activity collapsing
26
+ * above one merged paragraph. `content` (the full concatenated text) and
27
+ * `blocks` are retained for older clients and for re-sync reconciliation: the
28
+ * text runs in `segments` concatenate to `content`, and its non-text entries
29
+ * are exactly `blocks`. Absent for turns recovered without ordering info (an
30
+ * older bridge, or the on-disk history fallback) — clients fall back to
31
+ * `content` + `blocks` then. Only set on assistant messages.
32
+ */
33
+ segments?: unknown[];
34
+ /** Token usage for this turn, so the phone restores the context meter on re-sync. */
35
+ usage?: {
36
+ tokens: number;
37
+ contextWindow?: number;
38
+ };
39
+ createdAt: number;
40
+ }
41
+ export interface Turn {
42
+ id: string;
43
+ threadId: string;
44
+ status: TurnStatus;
45
+ messages: Message[];
46
+ createdAt: number;
47
+ completedAt?: number;
48
+ }
49
+ /**
50
+ * Per-thread access (approval) mode: how much the agent may do before it must
51
+ * pause for the user. Persisted on the bridge so the phone's choice survives a
52
+ * restart and is the source of truth across devices.
53
+ * - `requestApproval` — ask before each risky action.
54
+ * - `approveForMe` — auto-approve routine edits.
55
+ * - `fullAccess` — no approval gating.
56
+ */
57
+ export type AccessMode = 'requestApproval' | 'approveForMe' | 'fullAccess';
58
+ export interface Thread {
59
+ id: string;
60
+ projectId: string;
61
+ title: string;
62
+ status: ThreadStatus;
63
+ turnCount: number;
64
+ createdAt: number;
65
+ updatedAt: number;
66
+ /** Agent driving this thread (e.g. `opencode`, `echo`). */
67
+ agentId?: string;
68
+ /** Model the agent uses for this thread (e.g. `provider/model`). */
69
+ model?: string;
70
+ /** Absolute working directory the agent and git operations run in. */
71
+ cwd?: string;
72
+ /**
73
+ * The agent CLI's NATIVE session id (Claude `session_id`, Codex `thread_id`,
74
+ * OpenCode `sessionID`, pi session id), when known. Surfaced so the phone can
75
+ * show "resume this conversation from the CLI" beyond the bridge thread id.
76
+ */
77
+ agentSessionId?: string;
78
+ /** Per-thread access (approval) mode; see {@link AccessMode}. */
79
+ accessMode?: AccessMode;
80
+ }
81
+ export interface ThreadList {
82
+ threads: Thread[];
83
+ }
84
+ export interface TurnList {
85
+ turns: Turn[];
86
+ nextCursor?: string;
87
+ /**
88
+ * Total number of turns available for the thread, regardless of the page
89
+ * returned. Lets a client page from the end (newest-first) by computing
90
+ * offsets without first pulling the whole thread.
91
+ */
92
+ total?: number;
93
+ /**
94
+ * The turn currently in-flight for this thread (an agent is actively
95
+ * producing it RIGHT NOW in the bridge process), when one exists. This is the
96
+ * LIVE AgentManager state, NOT a stored turn's `streaming` status — the latter
97
+ * can be left dangling after a bridge restart (the agent child process died),
98
+ * whereas this is cleared the moment the turn completes/errors/aborts and is
99
+ * absent after a restart. The phone uses it on resync/reconnect to re-attach
100
+ * its streaming view (the "responding…" indicator + Stop button) to a turn it
101
+ * stopped tracking while backgrounded, instead of treating the turn as ended.
102
+ */
103
+ activeTurnId?: string;
104
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Conversation models: Thread, Turn, Message.
3
+ *
4
+ * The Dart equivalents live in `uxnanmobile/lib/domain/entities/{thread,turn,message}.dart`
5
+ * and are kept in sync manually (see 02e-bridge-integration.md §4.2).
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=thread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread.js","sourceRoot":"","sources":["../../../src/models/thread.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Workspace models exchanged over JSON-RPC (workspace/* methods).
3
+ *
4
+ * Source: architecture/02a-system-architecture.md §5.8.7.
5
+ */
6
+ export interface FileContent {
7
+ path: string;
8
+ content: string;
9
+ encoding: 'utf-8' | 'base64';
10
+ }
11
+ export interface ImageContent {
12
+ path: string;
13
+ base64Data: string;
14
+ mimeType: string;
15
+ }
16
+ /**
17
+ * An image (or other media) attached to a user turn (`turn/send { attachments }`).
18
+ * Tolerant by design — the phone sends inline base64 with the original
19
+ * `mimeType`; `path`/`width`/`height` are best-effort metadata. At least one of
20
+ * `base64Data`/`path` must be present for the bridge to deliver it to the agent.
21
+ */
22
+ export interface TurnAttachment {
23
+ /** Wire discriminator (always `image` today). */
24
+ type?: 'image';
25
+ /** MIME type, e.g. `image/png`. */
26
+ mimeType: string;
27
+ /** Inline base64 payload (no `data:` URI prefix). */
28
+ base64Data?: string;
29
+ /** Original/workspace path the image came from, if any. */
30
+ path?: string;
31
+ /** Pixel width, if known. */
32
+ width?: number;
33
+ /** Pixel height, if known. */
34
+ height?: number;
35
+ }
36
+ /**
37
+ * Result of a `workspace/exists` probe: whether a thread's `cwd` still exists
38
+ * on disk (folders/worktrees can be removed outside the app), so the phone can
39
+ * mark a thread unavailable instead of failing every action.
40
+ */
41
+ export interface WorkspaceExistsResult {
42
+ /** Whether the directory exists. */
43
+ exists: boolean;
44
+ /** Whether it is (still) a git repository / worktree, when it exists. */
45
+ isGitRepo?: boolean;
46
+ }
47
+ export type WorkspaceEntryType = 'file' | 'dir';
48
+ export interface WorkspaceEntry {
49
+ name: string;
50
+ type: WorkspaceEntryType;
51
+ /** Size in bytes (files only; absent for directories or unreadable entries). */
52
+ size?: number;
53
+ /**
54
+ * Last-modified time as epoch milliseconds (files only; absent for
55
+ * directories or unreadable entries). Lets the file browser show a "modified"
56
+ * timestamp without a second stat round-trip.
57
+ */
58
+ mtime?: number;
59
+ /**
60
+ * Whether git ignores this entry (matches a `.gitignore` / exclude rule),
61
+ * computed per-listing via `git check-ignore`. The file browser dims ignored
62
+ * entries (muted + italic) to set them apart from tracked/untracked files.
63
+ * `undefined`/`false` when the entry isn't ignored or the directory isn't a
64
+ * git repository. This is *not* a `GitFileStatus` — ignored entries never
65
+ * appear in `git/status`, so the flag rides on the listing instead.
66
+ */
67
+ ignored?: boolean;
68
+ }
69
+ export interface WorkspaceListing {
70
+ cwd: string;
71
+ entries: WorkspaceEntry[];
72
+ }
73
+ export interface Checkpoint {
74
+ id: string;
75
+ threadId?: string;
76
+ label?: string;
77
+ createdAt: number;
78
+ }
79
+ export type CheckpointFileStatus = 'added' | 'modified' | 'deleted';
80
+ export interface CheckpointDiff {
81
+ diff: string;
82
+ files: {
83
+ path: string;
84
+ status: CheckpointFileStatus;
85
+ }[];
86
+ }
87
+ export type PatchOp = 'add' | 'modify' | 'delete';
88
+ export interface PatchChange {
89
+ op: PatchOp;
90
+ path: string;
91
+ content?: string;
92
+ }
93
+ export interface ApplyResult {
94
+ success: boolean;
95
+ applied: number;
96
+ }
97
+ /**
98
+ * A configured base directory the phone may browse under. The phone can descend
99
+ * into sub-directories but never above the root (no per-project pre-config).
100
+ */
101
+ export interface BrowseRoot {
102
+ /** Stable id derived from the absolute path. */
103
+ id: string;
104
+ /** Display name (the root's basename). */
105
+ name: string;
106
+ /** Absolute path of the root. */
107
+ cwd: string;
108
+ }
109
+ /** A sub-directory under the current browse path. */
110
+ export interface BrowseDirEntry {
111
+ name: string;
112
+ /** Path relative to the browse root, POSIX separators (e.g. `projects/foo`). */
113
+ path: string;
114
+ /** Whether this directory is a git repository. */
115
+ isGitRepo: boolean;
116
+ }
117
+ /** Result of browsing one directory under a configured {@link BrowseRoot}. */
118
+ export interface BrowseResult {
119
+ /** All configured roots, so the phone can offer a root picker. */
120
+ roots: BrowseRoot[];
121
+ /** Id of the root currently being browsed. */
122
+ rootId: string;
123
+ /** Current path relative to the root (`''` = the root itself). */
124
+ path: string;
125
+ /** Parent path relative to the root, or `null` at the root (cannot go above it). */
126
+ parent: string | null;
127
+ /** Absolute directory — pass as `thread/start { cwd }` to root an agent here. */
128
+ cwd: string;
129
+ /** Whether the current directory is itself a git repository. */
130
+ isGitRepo: boolean;
131
+ /** Sub-directories the phone may open or descend into. */
132
+ dirs: BrowseDirEntry[];
133
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Workspace models exchanged over JSON-RPC (workspace/* methods).
3
+ *
4
+ * Source: architecture/02a-system-architecture.md §5.8.7.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/models/workspace.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Push notification payload sent from the bridge to the relay (POST /push/notify).
3
+ *
4
+ * Source: architecture/02a-system-architecture.md §5.10.2.
5
+ */
6
+ export type PushPlatform = 'ios' | 'android';
7
+ export interface PushNotifyRequest {
8
+ sessionId: string;
9
+ /** Secret that authenticates the bridge to the relay for this session. */
10
+ notificationSecret: string;
11
+ threadId: string;
12
+ turnId: string;
13
+ title: string;
14
+ body: string;
15
+ }
16
+ export interface PushRegisterRequest {
17
+ pushToken: string;
18
+ platform: PushPlatform;
19
+ }
20
+ export interface PushRegisterResult {
21
+ registered: boolean;
22
+ notificationSecret: string;
23
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Push notification payload sent from the bridge to the relay (POST /push/notify).
3
+ *
4
+ * Source: architecture/02a-system-architecture.md §5.10.2.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=push-payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push-payload.js","sourceRoot":"","sources":["../../../src/notifications/push-payload.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * JSON Schemas (draft-07) for runtime validation of messages at system
3
+ * boundaries. Authored as typed TS objects (instead of standalone `.json`
4
+ * files) so they are bundled, type-checked and import-attribute free.
5
+ *
6
+ * Source: architecture/02b-contracts-and-requirements.md §5 (validation).
7
+ */
8
+ import type { SchemaObject } from 'ajv';
9
+ export declare const jsonRpcRequestSchema: SchemaObject;
10
+ export declare const jsonRpcResponseSchema: SchemaObject;
11
+ export declare const e2eeEnvelopeSchema: SchemaObject;
12
+ export declare const pairingPayloadSchema: SchemaObject;
13
+ export declare const pushPayloadSchema: SchemaObject;
@@ -0,0 +1,82 @@
1
+ import { JSONRPC_VERSION, PAIRING_QR_VERSION } from '../../constants.js';
2
+ export const jsonRpcRequestSchema = {
3
+ $id: 'uxnan:jsonrpc-request',
4
+ type: 'object',
5
+ required: ['jsonrpc', 'id', 'method'],
6
+ properties: {
7
+ jsonrpc: { const: JSONRPC_VERSION },
8
+ id: { type: ['string', 'integer'] },
9
+ method: { type: 'string', minLength: 1 },
10
+ params: { type: ['object', 'array'] },
11
+ },
12
+ additionalProperties: false,
13
+ };
14
+ export const jsonRpcResponseSchema = {
15
+ $id: 'uxnan:jsonrpc-response',
16
+ type: 'object',
17
+ required: ['jsonrpc', 'id'],
18
+ properties: {
19
+ jsonrpc: { const: JSONRPC_VERSION },
20
+ id: { type: ['string', 'integer', 'null'] },
21
+ result: {},
22
+ error: {
23
+ type: 'object',
24
+ required: ['code', 'message'],
25
+ properties: {
26
+ code: { type: 'integer' },
27
+ message: { type: 'string' },
28
+ data: {},
29
+ },
30
+ additionalProperties: false,
31
+ },
32
+ },
33
+ oneOf: [{ required: ['result'] }, { required: ['error'] }],
34
+ additionalProperties: false,
35
+ };
36
+ export const e2eeEnvelopeSchema = {
37
+ $id: 'uxnan:e2ee-envelope',
38
+ type: 'object',
39
+ required: ['kind', 'sessionId', 'seq', 'nonce', 'ciphertext', 'tag'],
40
+ properties: {
41
+ kind: { const: 'encryptedEnvelope' },
42
+ sessionId: { type: 'string', minLength: 1 },
43
+ seq: { type: 'integer', minimum: 0 },
44
+ nonce: { type: 'string', minLength: 1 },
45
+ ciphertext: { type: 'string' },
46
+ tag: { type: 'string', minLength: 1 },
47
+ },
48
+ additionalProperties: false,
49
+ };
50
+ export const pairingPayloadSchema = {
51
+ $id: 'uxnan:pairing-payload',
52
+ type: 'object',
53
+ required: ['v', 'sessionId', 'macDeviceId', 'macIdentityPublicKey', 'expiresAt', 'displayName'],
54
+ // `relay` (string) and `hosts` (string[]) are optional transports — at least one.
55
+ anyOf: [{ required: ['relay'] }, { required: ['hosts'] }],
56
+ properties: {
57
+ v: { const: PAIRING_QR_VERSION },
58
+ relay: { type: 'string', minLength: 1 },
59
+ hosts: { type: 'array', items: { type: 'string', minLength: 1 }, minItems: 1 },
60
+ sessionId: { type: 'string', minLength: 1 },
61
+ macDeviceId: { type: 'string', minLength: 1 },
62
+ macIdentityPublicKey: { type: 'string', minLength: 1 },
63
+ expiresAt: { type: 'integer' },
64
+ displayName: { type: 'string', minLength: 1 },
65
+ },
66
+ additionalProperties: false,
67
+ };
68
+ export const pushPayloadSchema = {
69
+ $id: 'uxnan:push-payload',
70
+ type: 'object',
71
+ required: ['sessionId', 'notificationSecret', 'threadId', 'turnId', 'title', 'body'],
72
+ properties: {
73
+ sessionId: { type: 'string', minLength: 1 },
74
+ notificationSecret: { type: 'string', minLength: 1 },
75
+ threadId: { type: 'string', minLength: 1 },
76
+ turnId: { type: 'string', minLength: 1 },
77
+ title: { type: 'string' },
78
+ body: { type: 'string' },
79
+ },
80
+ additionalProperties: false,
81
+ };
82
+ //# sourceMappingURL=schemas.js.map