@omercnet/paseo-omp 0.4.0 → 1.0.0-next.148.1
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/README.md +8 -8
- package/client/external-url.ts +2 -11
- package/client/omp-config-styles.ts +284 -0
- package/client/omp-config-surface.tsx +16 -286
- package/client/omp-routing-editor.tsx +1 -3
- package/client/provider-launch-settings.tsx +118 -0
- package/index.client.tsx +21 -2
- package/index.server.ts +10 -0
- package/package.json +14 -9
- package/paseo-plugin.json +2 -1
- package/scripts/prepare-dependencies.mjs +44 -11
- package/server/omp-models.ts +2 -6
- package/server/package-version.ts +1 -1
- package/server/protocol-violation-diagnostics.ts +1 -1
- package/server/provider/catalog.ts +2 -1
- package/server/provider/config-normalization.ts +19 -3
- package/server/provider/connection.ts +30 -0
- package/server/provider/host-tools.ts +2 -2
- package/server/provider/mcp-transport.ts +9 -2
- package/server/provider/omp-rpc-environment.ts +368 -0
- package/server/provider/omp-rpc-process.ts +119 -0
- package/server/provider/omp-rpc-protocol.ts +1949 -0
- package/server/provider/omp-rpc-transport.ts +1373 -0
- package/server/provider/omp-rpc-values.ts +31 -0
- package/server/provider/omp-rpc.ts +267 -3311
- package/server/provider/profile-providers.ts +2 -1
- package/server/provider/prompt-payload.ts +253 -0
- package/server/provider/registration.ts +10 -2
- package/server/provider/session-compaction.ts +187 -0
- package/server/provider/session-descriptors.ts +52 -18
- package/server/provider/session-events.ts +42 -0
- package/server/provider/session-permissions.ts +987 -0
- package/server/provider/session-terminal.ts +307 -0
- package/server/provider/session-usage.ts +234 -0
- package/server/provider/session.ts +145 -1853
- package/server/provider/settings.ts +8 -5
- package/server/provider/subsessions.ts +30 -9
- package/server/provider/timeline-projector.ts +140 -29
- package/shared/external-url.ts +0 -9
- package/shared/provider-launch-settings.ts +18 -0
|
@@ -10,7 +10,6 @@ import { ExternalLink } from "@getpaseo/plugin/client/ui";
|
|
|
10
10
|
import { useIsMutating, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
11
11
|
import type { ReactNode } from "react";
|
|
12
12
|
import { useCallback, useMemo, useState } from "react";
|
|
13
|
-
import type { TextStyle, ViewStyle } from "react-native";
|
|
14
13
|
import { Pressable, ScrollView, Switch, Text, View } from "react-native";
|
|
15
14
|
import type { ComposerPillSettings } from "../shared/composer-pill-settings";
|
|
16
15
|
import { listOmpConfig, type OmpConfig } from "../shared/omp-config";
|
|
@@ -31,6 +30,7 @@ import { getOmpProviderHealth, type OmpProviderHealth } from "../shared/provider
|
|
|
31
30
|
import { getOmpSupportReport, OMP_SUPPORT_ISSUE_URL } from "../shared/support-diagnostics";
|
|
32
31
|
import { ComposerPillSettingsSection } from "./composer-pill-settings";
|
|
33
32
|
import { openOmpExternalUrl } from "./external-url";
|
|
33
|
+
import { type OmpConfigStyles, useConfigStyles } from "./omp-config-styles";
|
|
34
34
|
import { type OmpConfigSurfaceView as SurfaceView, surfaceViewsForScope } from "./omp-config-views";
|
|
35
35
|
import {
|
|
36
36
|
documentationForSettingCategory,
|
|
@@ -63,6 +63,7 @@ import {
|
|
|
63
63
|
summarizeProviderStatus,
|
|
64
64
|
summarizeRpcUiSupport,
|
|
65
65
|
} from "./provider-diagnostics-state";
|
|
66
|
+
import { ProviderLaunchSettingsSection } from "./provider-launch-settings";
|
|
66
67
|
import {
|
|
67
68
|
refreshSupportReport,
|
|
68
69
|
type SupportReportCopyState,
|
|
@@ -74,284 +75,6 @@ const CONFIG_POLL_MS = 30_000;
|
|
|
74
75
|
const HEALTH_QUERY_KEY = ["paseo-omp", "provider-health"] as const;
|
|
75
76
|
const PROVIDERS_QUERY_KEY = ["paseo-omp", "provider-snapshot"] as const;
|
|
76
77
|
|
|
77
|
-
export interface OmpConfigStyles {
|
|
78
|
-
root: ViewStyle;
|
|
79
|
-
pageTitle: TextStyle;
|
|
80
|
-
topTabs: ViewStyle;
|
|
81
|
-
topTab: ViewStyle;
|
|
82
|
-
topTabActive: ViewStyle;
|
|
83
|
-
topTabLabel: TextStyle;
|
|
84
|
-
topTabLabelActive: TextStyle;
|
|
85
|
-
workspace: ViewStyle;
|
|
86
|
-
categoryRail: ViewStyle;
|
|
87
|
-
categoryList: ViewStyle;
|
|
88
|
-
categoryButton: ViewStyle;
|
|
89
|
-
categoryButtonActive: ViewStyle;
|
|
90
|
-
categoryLabel: TextStyle;
|
|
91
|
-
categoryLabelActive: TextStyle;
|
|
92
|
-
categoryContent: ViewStyle;
|
|
93
|
-
search: TextStyle;
|
|
94
|
-
sectionHeader: ViewStyle;
|
|
95
|
-
sectionHeaderRow: ViewStyle;
|
|
96
|
-
sectionTitle: TextStyle;
|
|
97
|
-
source: TextStyle;
|
|
98
|
-
muted: TextStyle;
|
|
99
|
-
error: TextStyle;
|
|
100
|
-
refresh: ViewStyle;
|
|
101
|
-
docsActions: ViewStyle;
|
|
102
|
-
docLink: ViewStyle;
|
|
103
|
-
docLinkPressed: ViewStyle;
|
|
104
|
-
docLinkText: TextStyle;
|
|
105
|
-
refreshLabel: TextStyle;
|
|
106
|
-
helpActions: ViewStyle;
|
|
107
|
-
helpReport: ViewStyle;
|
|
108
|
-
helpReportText: TextStyle;
|
|
109
|
-
helpLinkText: TextStyle;
|
|
110
|
-
card: ViewStyle;
|
|
111
|
-
cardHeader: ViewStyle;
|
|
112
|
-
cardTitle: TextStyle;
|
|
113
|
-
row: ViewStyle;
|
|
114
|
-
rowLabel: TextStyle;
|
|
115
|
-
rowValue: TextStyle;
|
|
116
|
-
setting: ViewStyle;
|
|
117
|
-
settingHeader: ViewStyle;
|
|
118
|
-
settingPath: TextStyle;
|
|
119
|
-
settingDescription: TextStyle;
|
|
120
|
-
settingValue: TextStyle;
|
|
121
|
-
collectionSummary: TextStyle;
|
|
122
|
-
chipList: ViewStyle;
|
|
123
|
-
chip: ViewStyle;
|
|
124
|
-
chipText: TextStyle;
|
|
125
|
-
recordList: ViewStyle;
|
|
126
|
-
recordRow: ViewStyle;
|
|
127
|
-
recordKey: TextStyle;
|
|
128
|
-
recordValue: TextStyle;
|
|
129
|
-
editorActions: ViewStyle;
|
|
130
|
-
editorAction: ViewStyle;
|
|
131
|
-
editorActionPrimary: ViewStyle;
|
|
132
|
-
editorActionText: TextStyle;
|
|
133
|
-
editorActionTextPrimary: TextStyle;
|
|
134
|
-
scalarInput: TextStyle;
|
|
135
|
-
resetAction: TextStyle;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function useConfigStyles(theme: PluginSurfaceProps["theme"], compact: boolean): OmpConfigStyles {
|
|
139
|
-
return useMemo(
|
|
140
|
-
() => ({
|
|
141
|
-
root: {
|
|
142
|
-
flex: 1,
|
|
143
|
-
gap: compact ? 10 : 14,
|
|
144
|
-
padding: compact ? 16 : 24,
|
|
145
|
-
backgroundColor: theme.colors.surface0,
|
|
146
|
-
},
|
|
147
|
-
pageTitle: {
|
|
148
|
-
color: theme.colors.foreground,
|
|
149
|
-
fontSize: compact ? 22 : 26,
|
|
150
|
-
fontWeight: "700",
|
|
151
|
-
},
|
|
152
|
-
topTabs: {
|
|
153
|
-
flexWrap: "wrap",
|
|
154
|
-
flexDirection: "row",
|
|
155
|
-
alignSelf: "flex-start",
|
|
156
|
-
gap: 4,
|
|
157
|
-
padding: 4,
|
|
158
|
-
borderWidth: 1,
|
|
159
|
-
borderColor: theme.colors.border,
|
|
160
|
-
borderRadius: 10,
|
|
161
|
-
backgroundColor: theme.colors.surface1,
|
|
162
|
-
},
|
|
163
|
-
topTab: {
|
|
164
|
-
paddingHorizontal: compact ? 10 : 14,
|
|
165
|
-
paddingVertical: 8,
|
|
166
|
-
borderRadius: 7,
|
|
167
|
-
},
|
|
168
|
-
topTabActive: { backgroundColor: theme.colors.accent },
|
|
169
|
-
topTabLabel: { color: theme.colors.foregroundMuted, fontSize: 13, fontWeight: "600" },
|
|
170
|
-
topTabLabelActive: { color: theme.colors.accentForeground },
|
|
171
|
-
workspace: {
|
|
172
|
-
flexDirection: compact ? "column" : "row",
|
|
173
|
-
alignItems: compact ? "stretch" : "flex-start",
|
|
174
|
-
gap: compact ? 10 : 18,
|
|
175
|
-
},
|
|
176
|
-
categoryRail: {
|
|
177
|
-
width: compact ? "100%" : 220,
|
|
178
|
-
gap: 10,
|
|
179
|
-
padding: 10,
|
|
180
|
-
borderWidth: 1,
|
|
181
|
-
borderColor: theme.colors.border,
|
|
182
|
-
borderRadius: 10,
|
|
183
|
-
backgroundColor: theme.colors.surface1,
|
|
184
|
-
},
|
|
185
|
-
categoryList: { gap: 4 },
|
|
186
|
-
categoryButton: { paddingHorizontal: 10, paddingVertical: 9, borderRadius: 7 },
|
|
187
|
-
categoryButtonActive: { backgroundColor: theme.colors.surface2 },
|
|
188
|
-
categoryLabel: { color: theme.colors.foregroundMuted, fontSize: 13, fontWeight: "500" },
|
|
189
|
-
categoryLabelActive: { color: theme.colors.foreground, fontWeight: "700" },
|
|
190
|
-
categoryContent: { flex: compact ? undefined : 1, minWidth: 0, gap: 10 },
|
|
191
|
-
search: {
|
|
192
|
-
color: theme.colors.foreground,
|
|
193
|
-
borderWidth: 1,
|
|
194
|
-
borderColor: theme.colors.border,
|
|
195
|
-
borderRadius: 8,
|
|
196
|
-
backgroundColor: theme.colors.surface0,
|
|
197
|
-
paddingHorizontal: 10,
|
|
198
|
-
paddingVertical: 8,
|
|
199
|
-
fontSize: 13,
|
|
200
|
-
},
|
|
201
|
-
sectionHeader: { gap: 4, marginTop: compact ? 2 : 4 },
|
|
202
|
-
sectionHeaderRow: { flexDirection: "row", alignItems: "center", flexWrap: "wrap", gap: 10 },
|
|
203
|
-
sectionTitle: {
|
|
204
|
-
color: theme.colors.foreground,
|
|
205
|
-
fontSize: compact ? 16 : 18,
|
|
206
|
-
fontWeight: "600",
|
|
207
|
-
},
|
|
208
|
-
source: { color: theme.colors.foregroundMuted, fontSize: 12 },
|
|
209
|
-
muted: { color: theme.colors.foregroundMuted, fontSize: 13 },
|
|
210
|
-
error: { color: theme.colors.statusDanger, fontSize: 13 },
|
|
211
|
-
docsActions: { flexDirection: "row", alignItems: "center", flexWrap: "wrap", gap: 6 },
|
|
212
|
-
docLink: {
|
|
213
|
-
paddingHorizontal: 8,
|
|
214
|
-
paddingVertical: 5,
|
|
215
|
-
borderWidth: 1,
|
|
216
|
-
borderColor: theme.colors.border,
|
|
217
|
-
borderRadius: 7,
|
|
218
|
-
backgroundColor: theme.colors.surface1,
|
|
219
|
-
},
|
|
220
|
-
docLinkPressed: { opacity: 0.72 },
|
|
221
|
-
docLinkText: { color: theme.colors.accent, fontSize: 12, fontWeight: "600" },
|
|
222
|
-
refresh: {
|
|
223
|
-
flexDirection: "row",
|
|
224
|
-
alignItems: "center",
|
|
225
|
-
gap: 6,
|
|
226
|
-
paddingHorizontal: 10,
|
|
227
|
-
paddingVertical: 6,
|
|
228
|
-
borderWidth: 1,
|
|
229
|
-
borderColor: theme.colors.border,
|
|
230
|
-
borderRadius: 8,
|
|
231
|
-
backgroundColor: theme.colors.surface1,
|
|
232
|
-
},
|
|
233
|
-
refreshLabel: { color: theme.colors.foreground, fontSize: 13 },
|
|
234
|
-
helpActions: {
|
|
235
|
-
flexDirection: "row",
|
|
236
|
-
alignItems: "center",
|
|
237
|
-
flexWrap: "wrap",
|
|
238
|
-
gap: 8,
|
|
239
|
-
},
|
|
240
|
-
helpReport: {
|
|
241
|
-
maxWidth: "100%",
|
|
242
|
-
padding: compact ? 10 : 12,
|
|
243
|
-
borderWidth: 1,
|
|
244
|
-
borderColor: theme.colors.border,
|
|
245
|
-
borderRadius: 10,
|
|
246
|
-
backgroundColor: theme.colors.surface1,
|
|
247
|
-
},
|
|
248
|
-
helpReportText: {
|
|
249
|
-
color: theme.colors.foreground,
|
|
250
|
-
fontSize: compact ? 11 : 12,
|
|
251
|
-
lineHeight: compact ? 16 : 18,
|
|
252
|
-
},
|
|
253
|
-
helpLinkText: { color: theme.colors.accent, fontSize: 13, fontWeight: "600" },
|
|
254
|
-
cardHeader: {
|
|
255
|
-
flexDirection: "row",
|
|
256
|
-
alignItems: "center",
|
|
257
|
-
justifyContent: "space-between",
|
|
258
|
-
flexWrap: "wrap",
|
|
259
|
-
gap: 8,
|
|
260
|
-
},
|
|
261
|
-
card: {
|
|
262
|
-
gap: 8,
|
|
263
|
-
padding: compact ? 10 : 12,
|
|
264
|
-
borderWidth: 1,
|
|
265
|
-
borderColor: theme.colors.border,
|
|
266
|
-
borderRadius: 10,
|
|
267
|
-
backgroundColor: theme.colors.surface1,
|
|
268
|
-
},
|
|
269
|
-
cardTitle: { color: theme.colors.foreground, fontSize: 14, fontWeight: "600" },
|
|
270
|
-
row: { flexDirection: "row", gap: 8, flexWrap: "wrap" },
|
|
271
|
-
rowLabel: { color: theme.colors.foregroundMuted, fontSize: 13 },
|
|
272
|
-
rowValue: { color: theme.colors.foreground, fontSize: 13, flexShrink: 1 },
|
|
273
|
-
setting: {
|
|
274
|
-
gap: 5,
|
|
275
|
-
paddingVertical: 10,
|
|
276
|
-
borderTopWidth: 1,
|
|
277
|
-
borderTopColor: theme.colors.border,
|
|
278
|
-
},
|
|
279
|
-
settingHeader: {
|
|
280
|
-
flexDirection: "row",
|
|
281
|
-
alignItems: "baseline",
|
|
282
|
-
justifyContent: "space-between",
|
|
283
|
-
gap: 12,
|
|
284
|
-
},
|
|
285
|
-
settingPath: { color: theme.colors.foregroundMuted, fontSize: 11, flexShrink: 1 },
|
|
286
|
-
settingDescription: { color: theme.colors.foregroundMuted, fontSize: 12, lineHeight: 17 },
|
|
287
|
-
settingValue: { color: theme.colors.foreground, fontSize: 13, fontWeight: "600" },
|
|
288
|
-
collectionSummary: { color: theme.colors.foregroundMuted, fontSize: 12 },
|
|
289
|
-
chipList: { flexDirection: "row", flexWrap: "wrap", gap: 6 },
|
|
290
|
-
chip: {
|
|
291
|
-
paddingHorizontal: 8,
|
|
292
|
-
paddingVertical: 5,
|
|
293
|
-
borderWidth: 1,
|
|
294
|
-
borderColor: theme.colors.border,
|
|
295
|
-
borderRadius: 999,
|
|
296
|
-
backgroundColor: theme.colors.surface2,
|
|
297
|
-
},
|
|
298
|
-
chipText: { color: theme.colors.foreground, fontSize: 12 },
|
|
299
|
-
recordList: { gap: 6 },
|
|
300
|
-
recordRow: {
|
|
301
|
-
flexDirection: compact ? "column" : "row",
|
|
302
|
-
alignItems: compact ? "flex-start" : "baseline",
|
|
303
|
-
gap: compact ? 2 : 12,
|
|
304
|
-
paddingVertical: 5,
|
|
305
|
-
},
|
|
306
|
-
recordKey: {
|
|
307
|
-
width: compact ? undefined : 150,
|
|
308
|
-
color: theme.colors.foregroundMuted,
|
|
309
|
-
fontSize: 12,
|
|
310
|
-
fontWeight: "600",
|
|
311
|
-
},
|
|
312
|
-
recordValue: { flex: 1, color: theme.colors.foreground, fontSize: 12 },
|
|
313
|
-
editorActions: {
|
|
314
|
-
flexDirection: "row",
|
|
315
|
-
alignItems: "center",
|
|
316
|
-
justifyContent: "flex-end",
|
|
317
|
-
gap: 8,
|
|
318
|
-
padding: 10,
|
|
319
|
-
borderWidth: 1,
|
|
320
|
-
borderColor: theme.colors.border,
|
|
321
|
-
borderRadius: 10,
|
|
322
|
-
backgroundColor: theme.colors.surface1,
|
|
323
|
-
},
|
|
324
|
-
editorAction: {
|
|
325
|
-
paddingHorizontal: 12,
|
|
326
|
-
paddingVertical: 8,
|
|
327
|
-
borderWidth: 1,
|
|
328
|
-
borderColor: theme.colors.border,
|
|
329
|
-
borderRadius: 8,
|
|
330
|
-
},
|
|
331
|
-
editorActionPrimary: {
|
|
332
|
-
backgroundColor: theme.colors.accent,
|
|
333
|
-
borderColor: theme.colors.accent,
|
|
334
|
-
},
|
|
335
|
-
editorActionText: { color: theme.colors.foreground, fontSize: 13, fontWeight: "600" },
|
|
336
|
-
editorActionTextPrimary: { color: theme.colors.accentForeground },
|
|
337
|
-
scalarInput: {
|
|
338
|
-
minWidth: 180,
|
|
339
|
-
maxWidth: 420,
|
|
340
|
-
color: theme.colors.foreground,
|
|
341
|
-
borderWidth: 1,
|
|
342
|
-
borderColor: theme.colors.border,
|
|
343
|
-
borderRadius: 7,
|
|
344
|
-
backgroundColor: theme.colors.surface0,
|
|
345
|
-
paddingHorizontal: 9,
|
|
346
|
-
paddingVertical: 6,
|
|
347
|
-
fontSize: 13,
|
|
348
|
-
},
|
|
349
|
-
resetAction: { color: theme.colors.accent, fontSize: 12, fontWeight: "600" },
|
|
350
|
-
}),
|
|
351
|
-
[compact, theme],
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
|
|
355
78
|
function KeyValueRow({
|
|
356
79
|
styles,
|
|
357
80
|
label,
|
|
@@ -419,8 +142,10 @@ function ProviderSetupSection({ styles }: { styles: OmpConfigStyles }) {
|
|
|
419
142
|
return (
|
|
420
143
|
<SectionCard styles={styles} title="OMP Plugin">
|
|
421
144
|
<Text style={styles.muted}>
|
|
422
|
-
|
|
145
|
+
Host-wide inherited environment names apply to every OMP provider. Profile launch overrides
|
|
146
|
+
remain available for narrower exceptions.
|
|
423
147
|
</Text>
|
|
148
|
+
<KeyValueRow styles={styles} label="Host policy" value="Inherited daemon environment names" />
|
|
424
149
|
<KeyValueRow
|
|
425
150
|
styles={styles}
|
|
426
151
|
label="Per agent"
|
|
@@ -429,7 +154,7 @@ function ProviderSetupSection({ styles }: { styles: OmpConfigStyles }) {
|
|
|
429
154
|
<KeyValueRow
|
|
430
155
|
styles={styles}
|
|
431
156
|
label="Provider profile"
|
|
432
|
-
value="Command, environment, session directory, RPC timeout, role models, and denied tools"
|
|
157
|
+
value="Command, additional environment, session directory, RPC timeout, role models, and denied tools"
|
|
433
158
|
/>
|
|
434
159
|
</SectionCard>
|
|
435
160
|
);
|
|
@@ -440,15 +165,15 @@ function PluginConfigurationSection({ styles }: { styles: OmpConfigStyles }) {
|
|
|
440
165
|
<>
|
|
441
166
|
<SectionCard styles={styles} title="OMP Plugin launch options">
|
|
442
167
|
<Text style={styles.muted}>
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
168
|
+
Configure inherited daemon environment names below. Paseo does not expose effective
|
|
169
|
+
profile options for active launches, so this tab documents profile overrides without
|
|
170
|
+
claiming they are active.
|
|
446
171
|
</Text>
|
|
447
172
|
<KeyValueRow styles={styles} label="Command" value="Executable and argument prefix" />
|
|
448
173
|
<KeyValueRow
|
|
449
174
|
styles={styles}
|
|
450
175
|
label="Inherited environment"
|
|
451
|
-
value="
|
|
176
|
+
value="Additional profile names copied at OMP spawn time"
|
|
452
177
|
/>
|
|
453
178
|
<KeyValueRow
|
|
454
179
|
styles={styles}
|
|
@@ -1403,7 +1128,12 @@ function OmpConfigContent({
|
|
|
1403
1128
|
</>
|
|
1404
1129
|
) : null}
|
|
1405
1130
|
|
|
1406
|
-
{view === "plugin" ?
|
|
1131
|
+
{view === "plugin" ? (
|
|
1132
|
+
<>
|
|
1133
|
+
<PluginConfigurationSection styles={styles} />
|
|
1134
|
+
{!cwd ? <ProviderLaunchSettingsSection theme={theme} /> : null}
|
|
1135
|
+
</>
|
|
1136
|
+
) : null}
|
|
1407
1137
|
|
|
1408
1138
|
{view === "plugins" ? (
|
|
1409
1139
|
<OmpPluginManagerSection theme={theme} compact={layout.compact} cwd={cwd} store={store} />
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type OmpSetting,
|
|
9
9
|
parseOmpStructuredSettingValue,
|
|
10
10
|
} from "../shared/omp-settings";
|
|
11
|
-
import type { OmpConfigStyles } from "./omp-config-
|
|
11
|
+
import type { OmpConfigStyles } from "./omp-config-styles";
|
|
12
12
|
import { OmpModelPicker } from "./omp-model-picker";
|
|
13
13
|
import {
|
|
14
14
|
aliasChoices,
|
|
@@ -99,7 +99,6 @@ function OrderedRoleEditor({
|
|
|
99
99
|
return (
|
|
100
100
|
<View style={styles.recordList}>
|
|
101
101
|
{roles.map((role, index) => (
|
|
102
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: ordered rows are edited by position and must keep input identity while their value changes.
|
|
103
102
|
<View key={index} style={styles.recordRow}>
|
|
104
103
|
<Text style={styles.recordKey}>{index + 1}</Text>
|
|
105
104
|
<TextInput
|
|
@@ -172,7 +171,6 @@ function RecordRoutingEditor({
|
|
|
172
171
|
? rawValue
|
|
173
172
|
: "";
|
|
174
173
|
return (
|
|
175
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: record keys are editable, so row position preserves input identity.
|
|
176
174
|
<View key={index} style={styles.recordRow}>
|
|
177
175
|
<TextInput
|
|
178
176
|
accessibilityLabel={`${formatOmpSettingLabel(setting.path)} ${keyLabel} ${index + 1}`}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type PluginSurfaceProps, type SettingsState, useSettings } from "@getpaseo/plugin/client";
|
|
2
|
+
import {
|
|
3
|
+
SettingsAction,
|
|
4
|
+
SettingsCard,
|
|
5
|
+
SettingsInput,
|
|
6
|
+
SettingsSection,
|
|
7
|
+
} from "@getpaseo/plugin/client/ui";
|
|
8
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
9
|
+
import { Text, View } from "react-native";
|
|
10
|
+
import {
|
|
11
|
+
providerLaunchSettings,
|
|
12
|
+
providerLaunchSettingsSchema,
|
|
13
|
+
} from "../shared/provider-launch-settings";
|
|
14
|
+
|
|
15
|
+
type ReadySettings = Extract<
|
|
16
|
+
SettingsState<typeof providerLaunchSettings.schema>,
|
|
17
|
+
{ status: "ready" }
|
|
18
|
+
>;
|
|
19
|
+
|
|
20
|
+
function ProviderLaunchSettingsControls({ settings }: { settings: ReadySettings }) {
|
|
21
|
+
const savedNames = settings.values.inheritEnv.join(", ");
|
|
22
|
+
const [rawNames, setRawNames] = useState(() => savedNames);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
setRawNames(savedNames);
|
|
25
|
+
}, [savedNames]);
|
|
26
|
+
const inheritEnv = [
|
|
27
|
+
...new Set(
|
|
28
|
+
rawNames
|
|
29
|
+
.split(",")
|
|
30
|
+
.map((name) => name.trim())
|
|
31
|
+
.filter(Boolean),
|
|
32
|
+
),
|
|
33
|
+
];
|
|
34
|
+
const next = providerLaunchSettingsSchema.safeParse({ inheritEnv });
|
|
35
|
+
const error = next.success
|
|
36
|
+
? null
|
|
37
|
+
: (next.error.issues[0]?.message ?? "Enter valid variable names.");
|
|
38
|
+
const save = useCallback(async () => {
|
|
39
|
+
if (!next.success) return;
|
|
40
|
+
await settings.save(next.data, settings.revision);
|
|
41
|
+
}, [next, settings]);
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<View style={{ gap: 12 }}>
|
|
45
|
+
<SettingsSection
|
|
46
|
+
title="Inherited environment"
|
|
47
|
+
info="Applies to every OMP Plugin agent on this host. Names are stored, but values are read only from the daemon environment when OMP starts."
|
|
48
|
+
>
|
|
49
|
+
<SettingsCard>
|
|
50
|
+
<SettingsInput
|
|
51
|
+
key={savedNames}
|
|
52
|
+
label="Daemon variable names"
|
|
53
|
+
hint="Comma-separated names. Each selected value is available to OMP and its child processes."
|
|
54
|
+
initialValue={savedNames}
|
|
55
|
+
onChangeText={setRawNames}
|
|
56
|
+
placeholder="ACME_OMP_API_KEY, ACME_OMP_URL"
|
|
57
|
+
error={error ?? undefined}
|
|
58
|
+
disabled={settings.saving}
|
|
59
|
+
/>
|
|
60
|
+
<SettingsAction
|
|
61
|
+
label="Save inherited environment"
|
|
62
|
+
hint="Profile-specific names remain additive for narrow exceptions."
|
|
63
|
+
actionLabel="Save"
|
|
64
|
+
disabled={settings.saving || rawNames === savedNames || !next.success}
|
|
65
|
+
onPress={() => void save()}
|
|
66
|
+
/>
|
|
67
|
+
<SettingsAction
|
|
68
|
+
label="Clear inherited environment"
|
|
69
|
+
actionLabel="Clear"
|
|
70
|
+
disabled={settings.saving || settings.values.inheritEnv.length === 0}
|
|
71
|
+
onPress={async () => {
|
|
72
|
+
if (await settings.save({ inheritEnv: [] }, settings.revision)) setRawNames("");
|
|
73
|
+
}}
|
|
74
|
+
/>
|
|
75
|
+
{settings.saveError ? (
|
|
76
|
+
<SettingsAction
|
|
77
|
+
label="Reload host launch settings"
|
|
78
|
+
error={settings.saveError}
|
|
79
|
+
actionLabel="Reload"
|
|
80
|
+
disabled={settings.saving}
|
|
81
|
+
onPress={settings.reload}
|
|
82
|
+
/>
|
|
83
|
+
) : null}
|
|
84
|
+
</SettingsCard>
|
|
85
|
+
</SettingsSection>
|
|
86
|
+
</View>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function ProviderLaunchSettingsSection({ theme }: { theme: PluginSurfaceProps["theme"] }) {
|
|
91
|
+
const settings = useSettings(providerLaunchSettings);
|
|
92
|
+
const styles = useMemo(
|
|
93
|
+
() => ({
|
|
94
|
+
root: { gap: 12 },
|
|
95
|
+
text: { color: theme.colors.foreground },
|
|
96
|
+
error: { color: theme.colors.statusDanger },
|
|
97
|
+
}),
|
|
98
|
+
[theme],
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
if (settings.status === "loading")
|
|
102
|
+
return <Text style={styles.text}>Loading host launch settings…</Text>;
|
|
103
|
+
if (settings.status !== "ready") {
|
|
104
|
+
return (
|
|
105
|
+
<View style={styles.root}>
|
|
106
|
+
<Text accessibilityRole="alert" style={styles.error}>
|
|
107
|
+
{settings.error}
|
|
108
|
+
</Text>
|
|
109
|
+
<SettingsAction
|
|
110
|
+
label="Read host launch settings again"
|
|
111
|
+
actionLabel="Reload"
|
|
112
|
+
onPress={settings.reload}
|
|
113
|
+
/>
|
|
114
|
+
</View>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
return <ProviderLaunchSettingsControls settings={settings} />;
|
|
118
|
+
}
|
package/index.client.tsx
CHANGED
|
@@ -452,7 +452,25 @@ export default function contribute(client: PluginClientContext) {
|
|
|
452
452
|
}, RECONCILE_DEBOUNCE_MS);
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
-
|
|
455
|
+
let unsubscribeAgentDirectory = () => {};
|
|
456
|
+
let releaseAgentDirectory: (() => Promise<void>) | undefined;
|
|
457
|
+
void client.paseo.agents
|
|
458
|
+
.list({ subscribe: {} })
|
|
459
|
+
.then(({ subscription }) => {
|
|
460
|
+
if (!subscription) return;
|
|
461
|
+
if (disposed) {
|
|
462
|
+
void subscription.release().catch(() => {});
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
unsubscribeAgentDirectory = subscription.subscribe({
|
|
466
|
+
snapshot: scheduleReconcile,
|
|
467
|
+
update: scheduleReconcile,
|
|
468
|
+
error: () => {},
|
|
469
|
+
});
|
|
470
|
+
releaseAgentDirectory = () => subscription.release();
|
|
471
|
+
void subscription.ready.catch(() => {});
|
|
472
|
+
})
|
|
473
|
+
.catch(() => {});
|
|
456
474
|
const hubPoll = setInterval(() => {
|
|
457
475
|
void refreshHubStatus();
|
|
458
476
|
}, STATUS_POLL_MS);
|
|
@@ -467,7 +485,8 @@ export default function contribute(client: PluginClientContext) {
|
|
|
467
485
|
return () => {
|
|
468
486
|
disposed = true;
|
|
469
487
|
settingsGeneration += 1;
|
|
470
|
-
|
|
488
|
+
unsubscribeAgentDirectory();
|
|
489
|
+
if (releaseAgentDirectory) void releaseAgentDirectory().catch(() => {});
|
|
471
490
|
clearTimeout(reconcileTimer);
|
|
472
491
|
clearInterval(hubPoll);
|
|
473
492
|
clearInterval(quotaPoll);
|
package/index.server.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
discoverOmpProfilesSync,
|
|
25
25
|
} from "./server/provider/profile-providers";
|
|
26
26
|
import { createOmpProvider } from "./server/provider/registration";
|
|
27
|
+
import { OmpPublicError } from "./server/provider/security";
|
|
27
28
|
import { resolveGetOmpProviderHealth } from "./server/provider-diagnostics";
|
|
28
29
|
import { resolveListOmpQuotas } from "./server/quota";
|
|
29
30
|
import { resolveListOmpSessions } from "./server/sessions";
|
|
@@ -43,6 +44,7 @@ import {
|
|
|
43
44
|
import { listOmpSettings, updateOmpSettings } from "./shared/omp-settings";
|
|
44
45
|
import { listOmpStores, type OmpStore } from "./shared/omp-store";
|
|
45
46
|
import { getOmpProviderHealth } from "./shared/provider-diagnostics";
|
|
47
|
+
import { providerLaunchSettings } from "./shared/provider-launch-settings";
|
|
46
48
|
import { listOmpQuotas } from "./shared/quota";
|
|
47
49
|
import { listOmpSessions } from "./shared/sessions";
|
|
48
50
|
import { getOmpSupportReport } from "./shared/support-diagnostics";
|
|
@@ -53,6 +55,12 @@ function scoped<T extends { store?: OmpStore }, R>(handler: (input: T) => R) {
|
|
|
53
55
|
|
|
54
56
|
export default function contribute(server: PluginServerContext) {
|
|
55
57
|
server.registerSettings(composerPillSettings);
|
|
58
|
+
const launchSettings = server.registerSettings(providerLaunchSettings);
|
|
59
|
+
const resolveHostInheritEnv = async (): Promise<readonly string[]> => {
|
|
60
|
+
const current = await launchSettings.read();
|
|
61
|
+
if (current.status === "ready") return current.values.inheritEnv;
|
|
62
|
+
throw new OmpPublicError("OMP host launch settings are unavailable");
|
|
63
|
+
};
|
|
56
64
|
const browserAuthorizationRegistry = new OmpBrowserAuthorizationRegistry();
|
|
57
65
|
const protocolViolations = new OmpProtocolViolationCollector();
|
|
58
66
|
const operationalFailures = new OmpOperationalFailureCollector();
|
|
@@ -64,6 +72,7 @@ export default function contribute(server: PluginServerContext) {
|
|
|
64
72
|
browserAuthorizationRegistry,
|
|
65
73
|
reportProtocolViolation: protocolViolations.report,
|
|
66
74
|
reportOperationalFailure: operationalFailures.report,
|
|
75
|
+
resolveHostInheritEnv,
|
|
67
76
|
}),
|
|
68
77
|
);
|
|
69
78
|
}
|
|
@@ -97,6 +106,7 @@ export default function contribute(server: PluginServerContext) {
|
|
|
97
106
|
browserAuthorizationRegistry,
|
|
98
107
|
reportProtocolViolation: protocolViolations.report,
|
|
99
108
|
reportOperationalFailure: operationalFailures.report,
|
|
109
|
+
resolveHostInheritEnv,
|
|
100
110
|
}),
|
|
101
111
|
);
|
|
102
112
|
return () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omercnet/paseo-omp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-next.148.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Paseo integration for OMP, including its direct provider and workspace tooling.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
|
-
"packageManager": "
|
|
19
|
+
"packageManager": "bun@1.4.2",
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=22.18.0"
|
|
22
22
|
},
|
|
@@ -48,28 +48,33 @@
|
|
|
48
48
|
"test:integration:wsl": "node --import tsx scripts/test-wsl-host-tools.ts",
|
|
49
49
|
"test:integration:canary": "node --import tsx scripts/test-canary.ts",
|
|
50
50
|
"test:integration:install": "node --import tsx scripts/test-package-install.ts",
|
|
51
|
-
"typecheck": "tsc --noEmit"
|
|
51
|
+
"typecheck": "tsc --noEmit -p tsconfig.client.json && tsc --noEmit -p tsconfig.server.json && tsc --noEmit -p tsconfig.tests.json"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@getpaseo/protocol": "0.9.0
|
|
55
|
-
"@modelcontextprotocol/sdk": "1.
|
|
54
|
+
"@getpaseo/protocol": "0.9.0",
|
|
55
|
+
"@modelcontextprotocol/sdk": "1.30.0",
|
|
56
56
|
"yaml": "^2.9.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@biomejs/biome": "^2.5.10",
|
|
60
|
-
"@getpaseo/cli": "0.9.0
|
|
61
|
-
"@getpaseo/client": "0.9.0
|
|
62
|
-
"@getpaseo/plugin": "0.9.0
|
|
60
|
+
"@getpaseo/cli": "0.9.0",
|
|
61
|
+
"@getpaseo/client": "0.9.0",
|
|
62
|
+
"@getpaseo/plugin": "0.9.0",
|
|
63
|
+
"@getpaseo/server": "0.9.0",
|
|
64
|
+
"@oh-my-pi/pi-agent-core": "18.2.0",
|
|
65
|
+
"@oh-my-pi/pi-coding-agent": "18.2.0",
|
|
63
66
|
"@tanstack/react-query": "^5.102.3",
|
|
64
67
|
"@types/node": "^24.10.1",
|
|
65
68
|
"@types/react": "^19.2.18",
|
|
66
69
|
"@vitest/coverage-v8": "^5.0.0",
|
|
70
|
+
"esbuild": "0.28.2",
|
|
71
|
+
"pino": "10.3.1",
|
|
67
72
|
"react": "19.1.0",
|
|
68
73
|
"react-native": "0.81.5",
|
|
69
74
|
"tsx": "^4.20.6",
|
|
70
75
|
"typescript": "^7.0.2",
|
|
71
76
|
"vitest": "^5.0.0",
|
|
72
|
-
"zod": "
|
|
77
|
+
"zod": "4.4.3"
|
|
73
78
|
},
|
|
74
79
|
"overrides": {
|
|
75
80
|
"qs": "6.16.0"
|
package/paseo-plugin.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "paseo-omp",
|
|
3
|
-
"
|
|
3
|
+
"description": "Paseo integration for OMP, including its direct provider and workspace tooling.",
|
|
4
|
+
"requirements": { "paseo": "^0.9.0" },
|
|
4
5
|
"build": [["node", "scripts/prepare-dependencies.mjs"]]
|
|
5
6
|
}
|