@oharness/server 0.9.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/i18n.js +356 -62
- package/dist/i18n.js.map +1 -1
- package/dist/main.js +4 -0
- package/dist/main.js.map +1 -1
- package/dist/page/client/account.js +430 -23
- package/dist/page/client/account.js.map +1 -1
- package/dist/page/client/base.js +20 -1
- package/dist/page/client/base.js.map +1 -1
- package/dist/page/client/composer.js +709 -58
- package/dist/page/client/composer.js.map +1 -1
- package/dist/page/client/computer.d.ts +27 -0
- package/dist/page/client/computer.js +358 -0
- package/dist/page/client/computer.js.map +1 -0
- package/dist/page/client/dialogs.js +93 -6
- package/dist/page/client/dialogs.js.map +1 -1
- package/dist/page/client/events.js +94 -7
- package/dist/page/client/events.js.map +1 -1
- package/dist/page/client/files.js +86 -1
- package/dist/page/client/files.js.map +1 -1
- package/dist/page/client/index.js +4 -0
- package/dist/page/client/index.js.map +1 -1
- package/dist/page/client/panels.js +12 -6
- package/dist/page/client/panels.js.map +1 -1
- package/dist/page/client/routines.js +296 -41
- package/dist/page/client/routines.js.map +1 -1
- package/dist/page/client/shell.js +229 -51
- package/dist/page/client/shell.js.map +1 -1
- package/dist/page/client/state.js +273 -19
- package/dist/page/client/state.js.map +1 -1
- package/dist/page/client/tasks.d.ts +8 -0
- package/dist/page/client/tasks.js +293 -0
- package/dist/page/client/tasks.js.map +1 -0
- package/dist/page/client/transcript.js +174 -6
- package/dist/page/client/transcript.js.map +1 -1
- package/dist/page/client/usage.js +1 -11
- package/dist/page/client/usage.js.map +1 -1
- package/dist/page/style.js +706 -104
- package/dist/page/style.js.map +1 -1
- package/dist/page.js +161 -54
- package/dist/page.js.map +1 -1
- package/dist/prefs.d.ts +14 -0
- package/dist/prefs.js +8 -1
- package/dist/prefs.js.map +1 -1
- package/dist/remote-crypto.d.ts +78 -0
- package/dist/remote-crypto.js +216 -0
- package/dist/remote-crypto.js.map +1 -0
- package/dist/remote.d.ts +103 -0
- package/dist/remote.js +498 -0
- package/dist/remote.js.map +1 -0
- package/dist/server.d.ts +70 -0
- package/dist/server.js +1291 -49
- package/dist/server.js.map +1 -1
- package/dist/starters.d.ts +92 -0
- package/dist/starters.js +213 -0
- package/dist/starters.js.map +1 -0
- package/dist/theme.js +5 -0
- package/dist/theme.js.map +1 -1
- package/dist/turn-shots.d.ts +27 -0
- package/dist/turn-shots.js +71 -0
- package/dist/turn-shots.js.map +1 -0
- package/package.json +2 -2
package/dist/page/style.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../src/page/style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAA;EAC7B,SAAS
|
|
1
|
+
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../src/page/style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAA;EAC7B,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwkHV,CAAC"}
|
package/dist/page.js
CHANGED
|
@@ -45,55 +45,100 @@ ${ANALYTICS_STUB}
|
|
|
45
45
|
</head>
|
|
46
46
|
<body>
|
|
47
47
|
<aside>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
</
|
|
66
|
-
<div id="
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
48
|
+
<!-- The top of the sidebar, in the tab strip's white and at its height, so
|
|
49
|
+
the two read as one bar across the window: the traffic lights sit in
|
|
50
|
+
it on a desktop, #nav-toggle beside them, then the mark and the name
|
|
51
|
+
together. Folded, the bar is the rail's width and the name goes with
|
|
52
|
+
the panel. -->
|
|
53
|
+
<div id="side-top">
|
|
54
|
+
<div class="brand">
|
|
55
|
+
<span class="mark" aria-hidden="true">
|
|
56
|
+
<svg viewBox="0 0 32 32" fill="none" stroke="currentColor" stroke-width="2.5"
|
|
57
|
+
stroke-linecap="round">
|
|
58
|
+
<path d="M20 6h-8a6 6 0 0 0-6 6v8"/>
|
|
59
|
+
<path d="M12 26h8a6 6 0 0 0 6-6v-8"/>
|
|
60
|
+
<circle cx="16" cy="16" r="3.5" fill="currentColor" stroke="none"/>
|
|
61
|
+
</svg>
|
|
62
|
+
</span>
|
|
63
|
+
<b class="wordmark">OHarness</b>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
<div id="side-body">
|
|
67
|
+
<!-- The app's places, as a rail of icons beside the work: they are where
|
|
68
|
+
you go, the panel beside them is what you are doing. The rail stays
|
|
69
|
+
when the panel folds away. -->
|
|
70
|
+
<nav id="rail">
|
|
71
|
+
<div id="nav">
|
|
72
|
+
<!-- The label goes in a span, like every other nav item: data-t on the
|
|
73
|
+
button itself makes applyStrings replace its children, which took the
|
|
74
|
+
icon with it.
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
76
|
+
Icons are Lucide (ISC) — square-pen, box, clock, settings-2 —
|
|
77
|
+
scaled from their 24 grid onto the 16 one every other icon here uses,
|
|
78
|
+
which is where the .33s come from. Scaling the geometry rather than
|
|
79
|
+
the viewBox keeps the 1.5 stroke shared with folder, copy and the
|
|
80
|
+
rest, so nothing in the sidebar sits at a different weight. -->
|
|
81
|
+
<!-- Search is the palette by another name: the same dialog, for a hand
|
|
82
|
+
already on the mouse. The chord beside it is filled in at boot,
|
|
83
|
+
because it is ⌘K on one machine and Ctrl K on the next. -->
|
|
84
|
+
<!-- Home is the start page: a fresh session in the project on screen,
|
|
85
|
+
the same thing New session does, at the top of the places.
|
|
86
|
+
Lucide house (the current one) on the 16 grid: a rounded roof and a
|
|
87
|
+
door that stops short of the eaves. The older house's sharp peak
|
|
88
|
+
and full-height door were the one hard-cornered shape in a rail of
|
|
89
|
+
rounded ones. -->
|
|
90
|
+
<button class="nav-item" id="nav-home" type="button"><svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 14V9.33a.67.67 0 0 0-.67-.66H6.67a.67.67 0 0 0-.67.66V14"/><path d="M2 6.67a1.33 1.33 0 0 1 .47-1.02l4.67-4a1.33 1.33 0 0 1 1.72 0l4.67 4A1.33 1.33 0 0 1 14 6.67v6a1.33 1.33 0 0 1-1.33 1.33H3.33A1.33 1.33 0 0 1 2 12.67Z"/></svg><span data-t="nav.home"></span></button>
|
|
91
|
+
<button class="nav-item" id="nav-search" type="button"><svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="7.33" cy="7.33" r="5.33"/><path d="m14 14-2.87-2.87"/></svg><span data-t="nav.search"></span><span class="count" id="palette-hint"></span></button>
|
|
92
|
+
<!-- Artifacts sit above Models because they belong to the work, not to the
|
|
93
|
+
configuration: this row answers "where did that chart go", which is a
|
|
94
|
+
question asked mid-task, while the three below it are settings.
|
|
95
|
+
Lucide shapes — things that were made. Two stacked rectangles read
|
|
96
|
+
as "copy" or "windows", and beside Sessions' two stacked bubbles
|
|
97
|
+
the pair were one icon drawn twice. -->
|
|
98
|
+
<button class="nav-item" id="nav-artifacts" type="button"><svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5.53 6.67a.47.47 0 0 1-.42-.72L7.6 2a.47.47 0 0 1 .8-.03l2.47 3.97a.47.47 0 0 1-.38.73Z"/><rect x="2" y="9.33" width="4.67" height="4.67" rx=".67"/><circle cx="11.67" cy="11.67" r="2.33"/></svg><span data-t="nav.artifacts"></span><span class="count" id="artifact-count"></span></button>
|
|
99
|
+
<!-- Lucide messages-square: two conversations. One bubble with text
|
|
100
|
+
lines read as "a message", and its lines blurred at 16px. -->
|
|
101
|
+
<button class="nav-item" id="nav-sessions" type="button"><svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9.33 6a1.33 1.33 0 0 1-1.33 1.33H4L1.33 10V2.67a1.33 1.33 0 0 1 1.34-1.34H8a1.33 1.33 0 0 1 1.33 1.34Z"/><path d="M12 6h1.33a1.33 1.33 0 0 1 1.34 1.33v7.34L12 12H8a1.33 1.33 0 0 1-1.33-1.33V10"/></svg><span data-t="nav.sessions"></span></button>
|
|
102
|
+
<!-- Usage, which Settings also reaches: what the account spent is looked
|
|
103
|
+
up often enough to earn a place of its own. Lucide chart-column-big:
|
|
104
|
+
a bar chart is what "usage" looks like everywhere else, and bars
|
|
105
|
+
drawn as columns rather than strokes still read as bars at 16px —
|
|
106
|
+
the thin-stroke chart's short bar was a dot, and a gauge was too
|
|
107
|
+
abstract to name the page. -->
|
|
108
|
+
<button class="nav-item" id="nav-usage" type="button"><svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 2v10.67A1.33 1.33 0 0 0 3.33 14H14"/><rect x="10" y="3.33" width="2.67" height="8" rx=".67"/><rect x="4.67" y="6.67" width="2.67" height="4.67" rx=".67"/></svg><span data-t="nav.usage"></span></button>
|
|
109
|
+
<button class="nav-item" id="nav-models" type="button"><svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 5.33a1.33 1.33 0 0 0-.67-1.15L8.67 1.51a1.33 1.33 0 0 0-1.33 0L2.67 4.18A1.33 1.33 0 0 0 2 5.33v5.33a1.33 1.33 0 0 0 .67 1.15l4.67 2.67a1.33 1.33 0 0 0 1.33 0l4.67-2.67A1.33 1.33 0 0 0 14 10.67Z"/><path d="m2.2 4.67 5.8 3.33 5.8-3.33"/><path d="M8 14.67V8"/></svg><span data-t="nav.models"></span><span class="count" id="model-count"></span></button>
|
|
110
|
+
<button class="nav-item" id="nav-routines" type="button"><svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="6.67"/><path d="M8 4v4l2.67 1.33"/></svg><span data-t="nav.routines"></span><span class="count" id="routine-count"></span></button>
|
|
111
|
+
<button class="nav-item" id="nav-settings" type="button"><svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12.67 4.67h-6"/><path d="M9.33 11.33H3.33"/><circle cx="4.67" cy="4.67" r="2"/><circle cx="11.33" cy="11.33" r="2"/></svg><span data-t="nav.settings"></span></button>
|
|
112
|
+
</div>
|
|
113
|
+
</nav>
|
|
114
|
+
<div id="side-panel">
|
|
115
|
+
<header>
|
|
116
|
+
<b class="wordmark">OHarness</b>
|
|
117
|
+
<button id="nav-close" type="button" aria-label="Close"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg></button>
|
|
118
|
+
</header>
|
|
119
|
+
<button id="project" class="project" type="button">
|
|
120
|
+
<span class="avatar" id="project-avatar"></span>
|
|
121
|
+
<span class="project-name" id="project-name">—</span>
|
|
122
|
+
<span class="chev"></span>
|
|
123
|
+
</button>
|
|
124
|
+
<div id="side-new">
|
|
125
|
+
<!-- A soft square left open at the corner the pen comes in through, and a
|
|
126
|
+
plain capsule for the pen: no nib facet, which at 16px was a
|
|
127
|
+
smudge rather than a detail. The search row under it draws the
|
|
128
|
+
same lens as the rail's Search, as a bare icon at the row's end: a
|
|
129
|
+
second full row read as a second thing to do, and it is not. -->
|
|
130
|
+
<button class="nav-item" id="new" type="button"><svg class="ico" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M7.33 2.67H5A2.33 2.33 0 0 0 2.67 5v6A2.33 2.33 0 0 0 5 13.33h6A2.33 2.33 0 0 0 13.33 11V8.67"/><path d="M12.1 2.9a1.27 1.27 0 0 1 1.8 1.8l-4.6 4.6a1.6 1.6 0 0 1-.72.4l-1.85.47.47-1.85a1.6 1.6 0 0 1 .4-.72Z"/></svg><span data-t="nav.new"></span></button>
|
|
131
|
+
<button id="side-search" type="button" data-t-title="nav.searchSessions" data-t-aria-label="nav.searchSessions"><svg class="ico-sm" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="7.33" cy="7.33" r="5.33"/><path d="m14 14-2.87-2.87"/></svg></button>
|
|
132
|
+
</div>
|
|
133
|
+
<div id="sessions"></div>
|
|
134
|
+
<!-- Pinned under the session list, where an account belongs and where
|
|
135
|
+
people look for one. Signing in is what turns on sync and what lets an
|
|
136
|
+
artifact be published, and until now the only door to it was inside the
|
|
137
|
+
model-provider setup — a place nobody goes to find their account. -->
|
|
138
|
+
<div id="update-hint" hidden></div>
|
|
139
|
+
<div id="account"></div>
|
|
140
|
+
</div>
|
|
89
141
|
</div>
|
|
90
|
-
<div id="sessions"></div>
|
|
91
|
-
<!-- Pinned under the session list, where an account belongs and where
|
|
92
|
-
people look for one. Signing in is what turns on sync and what lets an
|
|
93
|
-
artifact be published, and until now the only door to it was inside the
|
|
94
|
-
model-provider setup — a place nobody goes to find their account. -->
|
|
95
|
-
<div id="update-hint" hidden></div>
|
|
96
|
-
<div id="account"></div>
|
|
97
142
|
</aside>
|
|
98
143
|
<div id="scrim"></div>
|
|
99
144
|
|
|
@@ -105,9 +150,22 @@ ${ANALYTICS_STUB}
|
|
|
105
150
|
|
|
106
151
|
<div id="split">
|
|
107
152
|
<div id="main">
|
|
108
|
-
<!-- Shown only while the sidebar is folded away: the way back to it. -->
|
|
109
|
-
<button id="nav-expand" type="button" data-t-title="nav.expand" data-t-aria-label="nav.expand"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2.25" y="3.25" width="11.5" height="9.5" rx="2.5"/><path d="M6.25 3.25v9.5"/></svg></button>
|
|
110
153
|
<div id="tabs"></div>
|
|
154
|
+
<!-- The window Computer use is working in, live, floating over the
|
|
155
|
+
conversation while a turn works in it (see client/computer.ts).
|
|
156
|
+
Folded, it is the pill under it. -->
|
|
157
|
+
<div id="computer-float" hidden>
|
|
158
|
+
<!-- Over the picture, not above it: the app's name as a pill on the
|
|
159
|
+
left, the controls as round buttons on the right. -->
|
|
160
|
+
<div id="computer-head">
|
|
161
|
+
<span id="computer-label"><span id="computer-live" hidden><i></i></span><span id="computer-where"></span></span>
|
|
162
|
+
<button id="computer-grow" type="button" aria-pressed="false" data-t-title="computer.grow" data-t-aria-label="computer.grow"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 2.67h3.33V6"/><path d="M6 13.33H2.67V10"/><path d="m13.33 2.67-4 4"/><path d="m2.67 13.33 4-4"/></svg></button>
|
|
163
|
+
<button id="computer-stop" type="button" data-t-title="computer.stop" data-t-aria-label="computer.stop"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><rect x="4" y="4" width="8" height="8" rx="1.5"/></svg></button>
|
|
164
|
+
<button id="computer-hide" type="button" data-t-title="computer.hide" data-t-aria-label="computer.hide"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 8h8"/></svg></button>
|
|
165
|
+
</div>
|
|
166
|
+
<div id="computer-body"></div>
|
|
167
|
+
</div>
|
|
168
|
+
<button id="computer-pill" type="button" hidden data-t-title="computer.showPane"><i></i><span id="computer-pill-where"></span></button>
|
|
111
169
|
<div id="log">
|
|
112
170
|
<div id="empty">
|
|
113
171
|
<div class="empty-brand">
|
|
@@ -125,9 +183,9 @@ ${ANALYTICS_STUB}
|
|
|
125
183
|
</div>
|
|
126
184
|
<h1 data-t="empty.title"></h1>
|
|
127
185
|
<p><span data-t="empty.connected"></span> <span id="empty-cwd" class="mono"></span></p>
|
|
128
|
-
<!-- Filled by paintStarters():
|
|
129
|
-
|
|
130
|
-
|
|
186
|
+
<!-- Filled by paintStarters(): three rotating everyday offers for a
|
|
187
|
+
project with no memory, three written from its notes once it has
|
|
188
|
+
some. -->
|
|
131
189
|
<div id="starters"></div>
|
|
132
190
|
</div>
|
|
133
191
|
</div>
|
|
@@ -142,9 +200,25 @@ ${ANALYTICS_STUB}
|
|
|
142
200
|
rather than in it: what is in the box is the message being written,
|
|
143
201
|
and a row sharing that surface reads as part of it. -->
|
|
144
202
|
<div id="queued"></div>
|
|
203
|
+
<!-- What the message carries — pictures, clips, files, folders — as cards
|
|
204
|
+
above the box, not chips inside it (see renderTray). -->
|
|
205
|
+
<div id="tray"></div>
|
|
145
206
|
<div class="composer" id="composer-box">
|
|
146
207
|
<!-- The top edge is a grab handle: drag it to resize the field. -->
|
|
147
208
|
<div id="grip" role="separator" aria-orientation="horizontal" data-t-title="composer.resize"></div>
|
|
209
|
+
<!-- Dictation, floating over the box's top edge by the mic: listening
|
|
210
|
+
(the voice as bars, the time, cancel and done), then transcribing
|
|
211
|
+
and tidying, or what went wrong. -->
|
|
212
|
+
<div id="dictate-pop" class="dictate-pop" hidden role="status" aria-live="polite">
|
|
213
|
+
<span class="dp-dot" aria-hidden="true"></span>
|
|
214
|
+
<span class="dp-spin" aria-hidden="true"></span>
|
|
215
|
+
<span class="dp-text"></span>
|
|
216
|
+
<span class="dp-time"></span>
|
|
217
|
+
<canvas class="dp-wave" width="168" height="32" aria-hidden="true"></canvas>
|
|
218
|
+
<button type="button" class="dp-btn dp-cancel" data-t-title="dictate.cancel"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7"/></svg></button>
|
|
219
|
+
<button type="button" class="dp-btn dp-done" data-t-title="dictate.done"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7"/></svg></button>
|
|
220
|
+
<button type="button" class="dp-btn dp-close" data-t-title="dictate.close"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7"/></svg></button>
|
|
221
|
+
</div>
|
|
148
222
|
<div id="attachments"></div>
|
|
149
223
|
<!-- A textarea draws its own glyphs and cannot style a range of them, so
|
|
150
224
|
the chip behind a mention is painted on a layer underneath that
|
|
@@ -184,6 +258,7 @@ ${ANALYTICS_STUB}
|
|
|
184
258
|
<div class="menu" hidden></div>
|
|
185
259
|
</div>
|
|
186
260
|
<span class="composer-spacer"></span>
|
|
261
|
+
<button id="mic" class="icon-btn mic-btn" type="button" aria-pressed="false" data-t-title="composer.dictate"><svg class="mic-idle" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5.75" y="1.75" width="4.5" height="8" rx="2.25"/><path d="M3.25 7.5a4.75 4.75 0 0 0 9.5 0M8 12.25V14.5"/></svg><svg class="mic-stop" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><rect x="4.5" y="4.5" width="7" height="7" rx="2"/></svg></button>
|
|
187
262
|
<button id="stop" class="primary" type="button" hidden data-t-title="composer.stop"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><rect x="4" y="4" width="8" height="8" rx="1.5"/></svg></button>
|
|
188
263
|
<button id="send" class="primary" type="submit" data-t-title="composer.send"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 13V3.4M3.6 7.8 8 3.2l4.4 4.6"/></svg></button>
|
|
189
264
|
</div>
|
|
@@ -199,7 +274,7 @@ ${ANALYTICS_STUB}
|
|
|
199
274
|
<span id="cost"></span>
|
|
200
275
|
<span id="tokens"></span>
|
|
201
276
|
<span id="cache" data-t-title="usage.cacheHint"></span>
|
|
202
|
-
<
|
|
277
|
+
<button id="ctx" type="button" aria-haspopup="dialog" aria-expanded="false"></button>
|
|
203
278
|
<span id="ctxtext"></span>
|
|
204
279
|
</div>
|
|
205
280
|
</form>
|
|
@@ -239,7 +314,10 @@ ${ANALYTICS_STUB}
|
|
|
239
314
|
</span>
|
|
240
315
|
</div>
|
|
241
316
|
<div id="explorer-body">
|
|
242
|
-
<div id="explorer-
|
|
317
|
+
<div id="explorer-side">
|
|
318
|
+
<label id="explorer-find"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="7" cy="7" r="4.5"/><path d="M10.5 10.5 14 14"/></svg><input id="explorer-q" type="search" autocomplete="off" spellcheck="false" data-t-placeholder="files.search" data-t-aria-label="files.search"></label>
|
|
319
|
+
<div id="explorer-tree" role="tree"></div>
|
|
320
|
+
</div>
|
|
243
321
|
<div id="explorer-split" role="separator" tabindex="0" data-t-aria-label="files.resize"></div>
|
|
244
322
|
<div id="explorer-view"></div>
|
|
245
323
|
</div>
|
|
@@ -289,6 +367,12 @@ ${ANALYTICS_STUB}
|
|
|
289
367
|
</div>
|
|
290
368
|
</div>
|
|
291
369
|
</main>
|
|
370
|
+
<!-- One button folds the sidebar and brings it back, fixed in the top bar so
|
|
371
|
+
it stays where it was clicked. After everything else on purpose: Electron
|
|
372
|
+
applies drag regions in document order, so a no-drag button written before
|
|
373
|
+
the tab strip was covered again by the strip's drag and could not be
|
|
374
|
+
clicked once the sidebar was folded. -->
|
|
375
|
+
<button id="nav-toggle" type="button" data-t-title="nav.collapse" data-t-aria-label="nav.collapse"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2.25" y="3.25" width="11.5" height="9.5" rx="2.5"/><path d="M6.25 3.25v9.5"/></svg></button>
|
|
292
376
|
|
|
293
377
|
<dialog id="browse">
|
|
294
378
|
<div class="pp-head"><span id="browse-here" class="mono small"></span></div>
|
|
@@ -398,6 +482,29 @@ ${ANALYTICS_STUB}
|
|
|
398
482
|
<!-- Importing a sign-in from the person's own browser. The confirmation is
|
|
399
483
|
the only path that reads anything out of that browser, so it names the
|
|
400
484
|
browser, the sites and what the agent can do with them afterwards. -->
|
|
485
|
+
<!-- Feedback: what kind, what happened, sent as the signed-in account. -->
|
|
486
|
+
<dialog id="feedback-dialog">
|
|
487
|
+
<div class="cn-head">
|
|
488
|
+
<div class="cn-naming">
|
|
489
|
+
<div class="cn-title" data-t="feedback.title"></div>
|
|
490
|
+
</div>
|
|
491
|
+
</div>
|
|
492
|
+
<div class="cn-body">
|
|
493
|
+
<div id="fb-kinds" class="fb-kinds" role="radiogroup"></div>
|
|
494
|
+
<textarea id="fb-message" rows="7" maxlength="5000"></textarea>
|
|
495
|
+
<!-- Attachments as square tiles, the last one the way to add another. -->
|
|
496
|
+
<div id="fb-files" class="fb-media"></div>
|
|
497
|
+
<input id="fb-file" type="file" multiple hidden
|
|
498
|
+
accept="image/png,image/jpeg,image/gif,image/webp,video/mp4,video/webm,video/quicktime">
|
|
499
|
+
<!-- Empty until there is something to say: an error, or that it was sent. -->
|
|
500
|
+
<p id="fb-status" class="fb-note"></p>
|
|
501
|
+
</div>
|
|
502
|
+
<div class="dlg-actions">
|
|
503
|
+
<button id="fb-cancel" type="button" class="quiet" data-t="models.cancel"></button>
|
|
504
|
+
<button id="fb-send" type="button" class="approve" data-t="feedback.send"></button>
|
|
505
|
+
</div>
|
|
506
|
+
</dialog>
|
|
507
|
+
|
|
401
508
|
<dialog id="browser-import-dialog">
|
|
402
509
|
<div class="cn-head">
|
|
403
510
|
<div class="cn-naming">
|
package/dist/page.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.js","sourceRoot":"","sources":["../src/page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD;;;;;;;;;;;;;;GAcG;AAGH;;;;;;;GAOG;AACH,MAAM,OAAO,GAAG;;;;;yCAKyB,CAAC;AAE1C,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;4CAOwB,kBAAkB,CAAC,OAAO,CAAC;SAC9D,KAAK;EACZ,cAAc
|
|
1
|
+
{"version":3,"file":"page.js","sourceRoot":"","sources":["../src/page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD;;;;;;;;;;;;;;GAcG;AAGH;;;;;;;GAOG;AACH,MAAM,OAAO,GAAG;;;;;yCAKyB,CAAC;AAE1C,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;4CAOwB,kBAAkB,CAAC,OAAO,CAAC;SAC9D,KAAK;EACZ,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAsfK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;qBACvB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;EAC1C,aAAa;EACb,UAAU;EACV,gBAAgB;;;QAGV,CAAC"}
|
package/dist/prefs.d.ts
CHANGED
|
@@ -40,6 +40,20 @@ export interface Prefs {
|
|
|
40
40
|
* routines fire when they are due rather than when the lid is next opened.
|
|
41
41
|
*/
|
|
42
42
|
keepAwake?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Whether a phone on this account may reach this machine through the relay
|
|
45
|
+
* (remote.ts). Absent is off: a machine is not offered to a phone until
|
|
46
|
+
* somebody at it says so.
|
|
47
|
+
*/
|
|
48
|
+
remote?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Whether Computer Use may take the real mouse and keyboard when an action
|
|
51
|
+
* cannot run in the background. `never` keeps it strictly in the background;
|
|
52
|
+
* absent is "ask", through the permission prompt each time.
|
|
53
|
+
*/
|
|
54
|
+
computerTakeover?: "ask" | "never";
|
|
55
|
+
/** Apps Computer Use refuses outright, beyond the built-in list: ids or names. */
|
|
56
|
+
computerBlockedApps?: string[];
|
|
43
57
|
/**
|
|
44
58
|
* Sessions and projects kept at the top of their list.
|
|
45
59
|
*
|
package/dist/prefs.js
CHANGED
|
@@ -5,7 +5,7 @@ import { parseJson } from "@oharness/engine/util/json.ts";
|
|
|
5
5
|
import { isEffortChoice } from "@oharness/engine/providers/types.ts";
|
|
6
6
|
import { renameWithRetry } from "@oharness/engine/util/fs.ts";
|
|
7
7
|
/** The lists that are arrays of strings, checked the same way on read. */
|
|
8
|
-
const STRING_LISTS = ["pinnedSessions", "pinnedProjects", "projectOrder"];
|
|
8
|
+
const STRING_LISTS = ["pinnedSessions", "pinnedProjects", "projectOrder", "computerBlockedApps"];
|
|
9
9
|
const FILE = () => userPath("prefs.json");
|
|
10
10
|
export async function readPrefs() {
|
|
11
11
|
let raw;
|
|
@@ -28,6 +28,13 @@ export async function readPrefs() {
|
|
|
28
28
|
}
|
|
29
29
|
if (typeof parsed.value.analytics === "boolean")
|
|
30
30
|
prefs.analytics = parsed.value.analytics;
|
|
31
|
+
if (typeof parsed.value.keepAwake === "boolean")
|
|
32
|
+
prefs.keepAwake = parsed.value.keepAwake;
|
|
33
|
+
if (typeof parsed.value.remote === "boolean")
|
|
34
|
+
prefs.remote = parsed.value.remote;
|
|
35
|
+
if (parsed.value.computerTakeover === "ask" || parsed.value.computerTakeover === "never") {
|
|
36
|
+
prefs.computerTakeover = parsed.value.computerTakeover;
|
|
37
|
+
}
|
|
31
38
|
for (const key of STRING_LISTS) {
|
|
32
39
|
const value = parsed.value[key];
|
|
33
40
|
if (Array.isArray(value)) {
|
package/dist/prefs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefs.js","sourceRoot":"","sources":["../src/prefs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAErE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"prefs.js","sourceRoot":"","sources":["../src/prefs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { type KeyObject } from "node:crypto";
|
|
2
|
+
export declare function b64(bytes: Uint8Array): string;
|
|
3
|
+
export declare function unb64(text: unknown, length?: number): Buffer;
|
|
4
|
+
/** A long-term Ed25519 identity, kept as PKCS#8 so it can be stored and reloaded. */
|
|
5
|
+
export interface Identity {
|
|
6
|
+
privateKey: KeyObject;
|
|
7
|
+
publicRaw: Buffer;
|
|
8
|
+
}
|
|
9
|
+
export declare function newIdentity(): {
|
|
10
|
+
identity: Identity;
|
|
11
|
+
pkcs8: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function loadIdentity(pkcs8: string): Identity;
|
|
14
|
+
export declare function transcript(channel: string, phoneIdentity: Buffer, phoneEph: Buffer, macIdentity: Buffer, macEph: Buffer): Buffer;
|
|
15
|
+
export declare function pairingCode(t: Buffer): string;
|
|
16
|
+
/** One direction's key and counter. */
|
|
17
|
+
declare class Direction {
|
|
18
|
+
private counter;
|
|
19
|
+
private readonly key;
|
|
20
|
+
constructor(key: Buffer);
|
|
21
|
+
seal(plaintext: string): string;
|
|
22
|
+
open(frame: string): string;
|
|
23
|
+
}
|
|
24
|
+
export interface HelloFrame {
|
|
25
|
+
device: {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
};
|
|
29
|
+
identity: Buffer;
|
|
30
|
+
eph: Buffer;
|
|
31
|
+
}
|
|
32
|
+
export declare function readHello(message: Record<string, unknown>): HelloFrame;
|
|
33
|
+
/**
|
|
34
|
+
* The Mac's side of one channel's handshake: answer the hello, then check the
|
|
35
|
+
* proof. `welcome()` is sent as plaintext; after `accept()` every frame is sealed.
|
|
36
|
+
*/
|
|
37
|
+
export declare class MacHandshake {
|
|
38
|
+
readonly transcript: Buffer;
|
|
39
|
+
readonly code: string;
|
|
40
|
+
private readonly sendKey;
|
|
41
|
+
private readonly receiveKey;
|
|
42
|
+
private readonly welcomeFrame;
|
|
43
|
+
readonly hello: HelloFrame;
|
|
44
|
+
constructor(channel: string, hello: HelloFrame, identity: Identity);
|
|
45
|
+
welcome(): Record<string, unknown>;
|
|
46
|
+
/** Checks the phone's proof; on success, the sealed session for this channel. */
|
|
47
|
+
accept(message: Record<string, unknown>): SealedSession;
|
|
48
|
+
}
|
|
49
|
+
export declare class SealedSession {
|
|
50
|
+
private readonly outgoing;
|
|
51
|
+
private readonly incoming;
|
|
52
|
+
constructor(outgoing: Direction, incoming: Direction);
|
|
53
|
+
seal(message: Record<string, unknown>): string;
|
|
54
|
+
open(frame: string): Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
export declare class PhoneHandshake {
|
|
57
|
+
readonly eph: import("crypto").KeyPairKeyObjectResult;
|
|
58
|
+
private readonly ephRaw;
|
|
59
|
+
readonly channel: string;
|
|
60
|
+
readonly device: {
|
|
61
|
+
id: string;
|
|
62
|
+
name: string;
|
|
63
|
+
};
|
|
64
|
+
readonly identity: Identity;
|
|
65
|
+
constructor(channel: string, device: {
|
|
66
|
+
id: string;
|
|
67
|
+
name: string;
|
|
68
|
+
}, identity: Identity);
|
|
69
|
+
hello(): Record<string, unknown>;
|
|
70
|
+
/** Verifies the welcome and returns the proof to send, the code, and the sealed session. */
|
|
71
|
+
finish(welcome: Record<string, unknown>): {
|
|
72
|
+
proof: Record<string, unknown>;
|
|
73
|
+
code: string;
|
|
74
|
+
macIdentity: Buffer;
|
|
75
|
+
session: SealedSession;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export {};
|