@p4code/cli 0.4.16 → 0.4.18
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/bin.mjs +283 -39
- package/dist/client/assets/{DiffPanel-tsLZVSg6.js → DiffPanel-Bbzx_GKV.js} +3 -3
- package/dist/client/assets/FilePreviewPanel-BgkHy3Kn.js +2230 -0
- package/dist/client/assets/PreviewPanel-CSdwriS1.js +2 -0
- package/dist/client/assets/{PullRequestCodeTab-DuIvmetg.js → PullRequestCodeTab-DzxStWKR.js} +4 -4
- package/dist/client/assets/{fileCommentAnnotations-lQZwvGUk.js → fileCommentAnnotations-BmPYMVTR.js} +2 -2
- package/dist/client/assets/{index-cqm4-bHh.css → index-CSQTlXxM.css} +1 -1
- package/dist/client/assets/{index-JYVF4HEF.js → index-DmvUg7MB.js} +176 -165
- package/dist/client/assets/previewAssetResource-CTnb3kvX.js +48 -0
- package/dist/client/assets/{renderFileChildren-B35v3AOr.js → renderFileChildren-Sa38-qVK.js} +2 -2
- package/dist/client/assets/{toggle-group-Dx-iwRbq.js → toggle-group-CzGdInUB.js} +2 -2
- package/dist/client/index.html +3 -3
- package/package.json +1 -1
- package/dist/client/assets/FilePreviewPanel-B-Nmz0HL.js +0 -2230
- package/dist/client/assets/PreviewPanel-D2u1DYbz.js +0 -2
- package/dist/client/assets/previewAssetResource-DdooihFl.js +0 -48
package/dist/bin.mjs
CHANGED
|
@@ -260,7 +260,7 @@ const make$115 = () => {
|
|
|
260
260
|
const layer$118 = Layer.sync(NetService, make$115);
|
|
261
261
|
//#endregion
|
|
262
262
|
//#region package.json
|
|
263
|
-
var version$1 = "0.4.
|
|
263
|
+
var version$1 = "0.4.18";
|
|
264
264
|
//#endregion
|
|
265
265
|
//#region src/config.ts
|
|
266
266
|
/**
|
|
@@ -1549,6 +1549,7 @@ const ServerSelfUpdateCapability = Schema$1.Literals([
|
|
|
1549
1549
|
"desktop-managed"
|
|
1550
1550
|
]);
|
|
1551
1551
|
const ExecutionEnvironmentCapabilities = Schema$1.Struct({
|
|
1552
|
+
computerUseControls: Schema$1.optionalKey(Schema$1.Boolean),
|
|
1552
1553
|
usagePriceOverrides: Schema$1.optionalKey(Schema$1.Boolean),
|
|
1553
1554
|
projectAutoPull: Schema$1.optionalKey(Schema$1.Boolean),
|
|
1554
1555
|
sharedProjectModelDefault: Schema$1.optionalKey(Schema$1.Boolean),
|
|
@@ -9794,6 +9795,11 @@ const LoadBalancingWeights = Schema$1.Record(TrimmedNonEmptyString, Schema$1.Int
|
|
|
9794
9795
|
minimum: 0,
|
|
9795
9796
|
maximum: 100
|
|
9796
9797
|
})));
|
|
9798
|
+
const ComputerUsePermissionHosts = Schema$1.Record(TrimmedNonEmptyString, Schema$1.Struct({
|
|
9799
|
+
environmentId: TrimmedNonEmptyString,
|
|
9800
|
+
hostId: TrimmedNonEmptyString,
|
|
9801
|
+
label: Schema$1.optionalKey(TrimmedNonEmptyString)
|
|
9802
|
+
}));
|
|
9797
9803
|
const ClientSettingsSchema = Schema$1.Struct({
|
|
9798
9804
|
loadBalancingEnabled: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(false))),
|
|
9799
9805
|
loadBalancingWeights: LoadBalancingWeights.pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
@@ -9805,6 +9811,7 @@ const ClientSettingsSchema = Schema$1.Struct({
|
|
|
9805
9811
|
confirmThreadDelete: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(true))),
|
|
9806
9812
|
dismissedProviderUpdateNotificationKeys: Schema$1.Array(TrimmedNonEmptyString).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
9807
9813
|
diffIgnoreWhitespace: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(true))),
|
|
9814
|
+
computerUsePermissionHosts: ComputerUsePermissionHosts.pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
9808
9815
|
environmentIdentificationMode: EnvironmentIdentificationMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_ENVIRONMENT_IDENTIFICATION_MODE))),
|
|
9809
9816
|
glassOpacity: GlassOpacity.pipe(Schema$1.withDecodingDefault(Effect.succeed(80))),
|
|
9810
9817
|
favorites: Schema$1.Array(Schema$1.Struct({
|
|
@@ -10389,6 +10396,7 @@ Schema$1.Struct({
|
|
|
10389
10396
|
confirmThreadArchive: Schema$1.optionalKey(Schema$1.Boolean),
|
|
10390
10397
|
confirmThreadDelete: Schema$1.optionalKey(Schema$1.Boolean),
|
|
10391
10398
|
diffIgnoreWhitespace: Schema$1.optionalKey(Schema$1.Boolean),
|
|
10399
|
+
computerUsePermissionHosts: Schema$1.optionalKey(ComputerUsePermissionHosts),
|
|
10392
10400
|
environmentIdentificationMode: Schema$1.optionalKey(EnvironmentIdentificationMode),
|
|
10393
10401
|
glassOpacity: Schema$1.optionalKey(GlassOpacity),
|
|
10394
10402
|
favorites: Schema$1.optionalKey(Schema$1.Array(Schema$1.Struct({
|
|
@@ -13338,6 +13346,9 @@ const ComputerUseHost = Schema$1.Struct({
|
|
|
13338
13346
|
nativeApps: Schema$1.Boolean
|
|
13339
13347
|
});
|
|
13340
13348
|
const ComputerUseSession = Schema$1.Struct({
|
|
13349
|
+
generationId: Schema$1.optional(TrimmedNonEmptyString),
|
|
13350
|
+
threadTitle: Schema$1.optional(Schema$1.String),
|
|
13351
|
+
environmentLabel: Schema$1.optional(Schema$1.String),
|
|
13341
13352
|
environmentId: EnvironmentId,
|
|
13342
13353
|
threadId: ThreadId,
|
|
13343
13354
|
providerSessionId: TrimmedNonEmptyString,
|
|
@@ -13364,7 +13375,9 @@ const ComputerUseHostRequest = Schema$1.Struct({
|
|
|
13364
13375
|
operation: Schema$1.Literals([
|
|
13365
13376
|
"js",
|
|
13366
13377
|
"js_reset",
|
|
13367
|
-
"close"
|
|
13378
|
+
"close",
|
|
13379
|
+
"stop",
|
|
13380
|
+
"resume"
|
|
13368
13381
|
]),
|
|
13369
13382
|
input: Schema$1.optional(ComputerUseJsInput)
|
|
13370
13383
|
});
|
|
@@ -13376,10 +13389,15 @@ var ComputerUseError = class extends Schema$1.TaggedErrorClass()("ComputerUseErr
|
|
|
13376
13389
|
"busy",
|
|
13377
13390
|
"timeout",
|
|
13378
13391
|
"reset",
|
|
13379
|
-
"execution-failed"
|
|
13392
|
+
"execution-failed",
|
|
13393
|
+
"stopped"
|
|
13380
13394
|
]),
|
|
13381
13395
|
detail: Schema$1.String
|
|
13382
|
-
}) {
|
|
13396
|
+
}) {
|
|
13397
|
+
get message() {
|
|
13398
|
+
return this.detail;
|
|
13399
|
+
}
|
|
13400
|
+
};
|
|
13383
13401
|
const ComputerUseHostRegistration = Schema$1.Struct({
|
|
13384
13402
|
hostId: TrimmedNonEmptyString,
|
|
13385
13403
|
environmentId: EnvironmentId,
|
|
@@ -13406,6 +13424,30 @@ const ComputerUseHostResponse = Schema$1.Struct({
|
|
|
13406
13424
|
error: ComputerUseError
|
|
13407
13425
|
})])
|
|
13408
13426
|
});
|
|
13427
|
+
const ComputerUseHostReport = Schema$1.Struct({
|
|
13428
|
+
hostId: TrimmedNonEmptyString,
|
|
13429
|
+
connectionId: TrimmedNonEmptyString,
|
|
13430
|
+
session: ComputerUseSession,
|
|
13431
|
+
state: Schema$1.Literals([
|
|
13432
|
+
"active",
|
|
13433
|
+
"closed",
|
|
13434
|
+
"stopped"
|
|
13435
|
+
])
|
|
13436
|
+
});
|
|
13437
|
+
const ComputerUseControlState = Schema$1.Struct({
|
|
13438
|
+
session: ComputerUseSession,
|
|
13439
|
+
host: ComputerUseHost,
|
|
13440
|
+
state: Schema$1.Literals([
|
|
13441
|
+
"active",
|
|
13442
|
+
"stopping",
|
|
13443
|
+
"stopped",
|
|
13444
|
+
"stop-unconfirmed"
|
|
13445
|
+
])
|
|
13446
|
+
});
|
|
13447
|
+
const ComputerUseControlInput = Schema$1.Struct({
|
|
13448
|
+
threadId: ThreadId,
|
|
13449
|
+
action: Schema$1.Literals(["stop", "resume"])
|
|
13450
|
+
});
|
|
13409
13451
|
const ComputerUseEnrollmentRequest = Schema$1.Struct({
|
|
13410
13452
|
environmentId: EnvironmentId,
|
|
13411
13453
|
desktopSessionId: TrimmedNonEmptyString,
|
|
@@ -13465,6 +13507,8 @@ const WS_METHODS = {
|
|
|
13465
13507
|
previewReportStatus: "preview.reportStatus",
|
|
13466
13508
|
computerUseConnect: "computerUse.connect",
|
|
13467
13509
|
computerUseList: "computerUse.list",
|
|
13510
|
+
computerUseControls: "computerUse.controls",
|
|
13511
|
+
computerUseControl: "computerUse.control",
|
|
13468
13512
|
computerUseRespond: "computerUse.respond",
|
|
13469
13513
|
previewAutomationConnect: "previewAutomation.connect",
|
|
13470
13514
|
previewAutomationRespond: "previewAutomation.respond",
|
|
@@ -14488,6 +14532,16 @@ const WsComputerUseListRpc = Rpc.make(WS_METHODS.computerUseList, {
|
|
|
14488
14532
|
success: Schema$1.Array(ComputerUseHost),
|
|
14489
14533
|
error: EnvironmentAuthorizationError
|
|
14490
14534
|
});
|
|
14535
|
+
const WsComputerUseControlsRpc = Rpc.make(WS_METHODS.computerUseControls, {
|
|
14536
|
+
payload: Schema$1.Struct({}),
|
|
14537
|
+
success: Schema$1.Array(ComputerUseControlState),
|
|
14538
|
+
error: EnvironmentAuthorizationError,
|
|
14539
|
+
stream: true
|
|
14540
|
+
});
|
|
14541
|
+
const WsComputerUseControlRpc = Rpc.make(WS_METHODS.computerUseControl, {
|
|
14542
|
+
payload: ComputerUseControlInput,
|
|
14543
|
+
error: Schema$1.Union([ComputerUseError, EnvironmentAuthorizationError])
|
|
14544
|
+
});
|
|
14491
14545
|
const WsComputerUseRespondRpc = Rpc.make(WS_METHODS.computerUseRespond, {
|
|
14492
14546
|
payload: ComputerUseHostResponse,
|
|
14493
14547
|
error: Schema$1.Union([ComputerUseError, EnvironmentAuthorizationError])
|
|
@@ -14594,7 +14648,7 @@ const WsSubscribeAuthAccessRpc = Rpc.make(WS_METHODS.subscribeAuthAccess, {
|
|
|
14594
14648
|
error: Schema$1.Union([AuthAccessStreamError, EnvironmentAuthorizationError]),
|
|
14595
14649
|
stream: true
|
|
14596
14650
|
});
|
|
14597
|
-
const WsRpcGroup = RpcGroup.make(WsDeviceGetStateRpc, WsDeviceListRpc, WsDeviceConfigureRpc, WsDeviceOpenRpc, WsDeviceCloseRpc, WsDeviceDetailRpc, WsDeviceActionRpc, WsSubscribeDevicesRpc, WsServerProbeRpc, WsServerGetConfigRpc, WsServerRefreshProvidersRpc, WsServerProviderAuthStartRpc, WsServerProviderAuthCompleteRpc, WsServerProviderAuthCancelRpc, WsServerProviderAuthLogoutRpc, WsServerProviderAuthSubscribeRpc, WsServerProviderInstallStartRpc, WsServerProviderInstallCancelRpc, WsServerProviderInstallRemoveRpc, WsServerProviderInstallSubscribeRpc, WsServerUpdateProviderRpc, WsServerUpdateServerRpc, WsServerUpsertKeybindingRpc, WsServerRemoveKeybindingRpc, WsServerGetSettingsRpc, WsServerUpdateSettingsRpc, WsServerDiscoverSourceControlRpc, WsServerGetProviderUsageRpc, WsServerGetHostResourcesRpc, WsServerGetResourceTelemetryRpc, WsServerGetResourceTelemetryHistoryRpc, WsServerRetryResourceTelemetryRpc, WsSubscribeResourceTelemetryRpc, WsBtwAskRpc, WsBtwCancelRpc, WsServerGetUsageSummaryRpc, WsServerGetTraceDiagnosticsRpc, WsServerGetProcessDiagnosticsRpc, WsServerGetProcessResourceHistoryRpc, WsServerSignalProcessRpc, WsPullRequestsListRpc, WsPullRequestsListStatsRpc, WsPullRequestsDetailRpc, WsPullRequestsStackRpc, WsPullRequestsActivityRpc, WsPullRequestsDiffFileContentsRpc, WsPullRequestsRunActionRpc, WsPullRequestsUpdateRpc, WsPullRequestsCommentRpc, WsPullRequestsUpdateCommentRpc, WsPullRequestsSubmitReviewRpc, WsPullRequestsReplyToThreadRpc, WsPullRequestsSetThreadResolutionRpc, WsPullRequestsSetReactionRpc, WsPullRequestsInvalidateRpc, WsPullRequestsReviewerCandidatesRpc, WsPullRequestsRequestReviewersRpc, WsSourceControlLookupRepositoryRpc, WsSourceControlCloneRepositoryRpc, WsSourceControlPublishRepositoryRpc, WsProjectsListEntriesRpc, WsProjectsReadFileRpc, WsProjectsSearchContentsRpc, WsProjectsSearchEntriesRpc, WsProjectsWriteFileRpc, WsShellOpenInEditorRpc, WsFilesystemBrowseRpc, WsAssetsCreateUrlRpc, WsSubscribeVcsStatusRpc, WsVcsPullRpc, WsVcsRefreshStatusRpc, WsGitRunStackedActionRpc, WsGitResolvePullRequestRpc, WsGitPreparePullRequestThreadRpc, WsVcsListRefsRpc, WsVcsCreateWorktreeRpc, WsVcsRemoveWorktreeRpc, WsVcsCreateRefRpc, WsVcsSwitchRefRpc, WsVcsInitRpc, WsReviewGetDiffPreviewRpc, WsTerminalOpenRpc, WsTerminalAttachRpc, WsTerminalWriteRpc, WsTerminalResizeRpc, WsTerminalClearRpc, WsTerminalRestartRpc, WsTerminalCloseRpc, WsSubscribeTerminalEventsRpc, WsSubscribeTerminalMetadataRpc, WsPreviewOpenRpc, WsPreviewNavigateRpc, WsPreviewResizeRpc, WsPreviewRefreshRpc, WsPreviewCloseRpc, WsPreviewListRpc, WsPreviewReportStatusRpc, WsComputerUseConnectRpc, WsComputerUseListRpc, WsComputerUseRespondRpc, WsPreviewAutomationConnectRpc, WsPreviewAutomationRespondRpc, WsPreviewAutomationFocusHostRpc, WsSubscribePreviewEventsRpc, WsSubscribeDiscoveredLocalServersRpc, WsSubscribeServerConfigRpc, WsSubscribeServerLifecycleRpc, WsSubscribeAuthAccessRpc, WsTasksListRpc, WsTasksGetRpc, WsTasksCreateRpc, WsTasksUpdateRpc, WsTasksDeleteRpc, WsTasksStartThreadRpc, WsFeedListRpc, WsFeedRefreshRpc, WsFeedSourcesListRpc, WsFeedSourcesUpsertRpc, WsFeedSourcesDeleteRpc, WsFeedMarkReadRpc, WsFeedCleanupRpc, WsSubscribeTasksRpc, WsHubGetSyncStatusRpc, WsHubConnectRpc, WsHubDisconnectRpc, WsHubSetSyncModeRpc, WsHubSetShareModeRpc, WsHubMintTokenRpc, WsSkillsSyncRpc, WsSkillsPublishRpc, WsSkillsPublishAllRpc, WsSkillsUnpublishRpc, WsAssetsReadRpc, WsAssetsSaveRpc, WsAssetsDeleteRpc, WsAssetsCreateLocalRpc, WsAssetsRemoveLocalRpc, WsSkillRegistrySearchRpc, WsSkillRegistryFetchRpc, WsMcpListRpc, WsMcpSaveRpc, WsMcpRemoveRpc, WsMcpSetSecretRpc, WsMcpOAuthBeginRpc, WsMcpOAuthDisconnectRpc, WsTrackerStatusRpc, WsTrackerSetApiKeyRpc, WsTrackerClearApiKeyRpc, WsOrchestrationDispatchCommandRpc, WsOrchestrationGetTurnDiffRpc, WsOrchestrationGetWorkflowScriptRpc, WsOrchestrationGetFullThreadDiffRpc, WsOrchestrationSearchThreadsRpc, WsOrchestrationGetArchivedShellSnapshotRpc, WsOrchestrationSubscribeShellRpc, WsOrchestrationSubscribeThreadRpc);
|
|
14651
|
+
const WsRpcGroup = RpcGroup.make(WsDeviceGetStateRpc, WsDeviceListRpc, WsDeviceConfigureRpc, WsDeviceOpenRpc, WsDeviceCloseRpc, WsDeviceDetailRpc, WsDeviceActionRpc, WsSubscribeDevicesRpc, WsServerProbeRpc, WsServerGetConfigRpc, WsServerRefreshProvidersRpc, WsServerProviderAuthStartRpc, WsServerProviderAuthCompleteRpc, WsServerProviderAuthCancelRpc, WsServerProviderAuthLogoutRpc, WsServerProviderAuthSubscribeRpc, WsServerProviderInstallStartRpc, WsServerProviderInstallCancelRpc, WsServerProviderInstallRemoveRpc, WsServerProviderInstallSubscribeRpc, WsServerUpdateProviderRpc, WsServerUpdateServerRpc, WsServerUpsertKeybindingRpc, WsServerRemoveKeybindingRpc, WsServerGetSettingsRpc, WsServerUpdateSettingsRpc, WsServerDiscoverSourceControlRpc, WsServerGetProviderUsageRpc, WsServerGetHostResourcesRpc, WsServerGetResourceTelemetryRpc, WsServerGetResourceTelemetryHistoryRpc, WsServerRetryResourceTelemetryRpc, WsSubscribeResourceTelemetryRpc, WsBtwAskRpc, WsBtwCancelRpc, WsServerGetUsageSummaryRpc, WsServerGetTraceDiagnosticsRpc, WsServerGetProcessDiagnosticsRpc, WsServerGetProcessResourceHistoryRpc, WsServerSignalProcessRpc, WsPullRequestsListRpc, WsPullRequestsListStatsRpc, WsPullRequestsDetailRpc, WsPullRequestsStackRpc, WsPullRequestsActivityRpc, WsPullRequestsDiffFileContentsRpc, WsPullRequestsRunActionRpc, WsPullRequestsUpdateRpc, WsPullRequestsCommentRpc, WsPullRequestsUpdateCommentRpc, WsPullRequestsSubmitReviewRpc, WsPullRequestsReplyToThreadRpc, WsPullRequestsSetThreadResolutionRpc, WsPullRequestsSetReactionRpc, WsPullRequestsInvalidateRpc, WsPullRequestsReviewerCandidatesRpc, WsPullRequestsRequestReviewersRpc, WsSourceControlLookupRepositoryRpc, WsSourceControlCloneRepositoryRpc, WsSourceControlPublishRepositoryRpc, WsProjectsListEntriesRpc, WsProjectsReadFileRpc, WsProjectsSearchContentsRpc, WsProjectsSearchEntriesRpc, WsProjectsWriteFileRpc, WsShellOpenInEditorRpc, WsFilesystemBrowseRpc, WsAssetsCreateUrlRpc, WsSubscribeVcsStatusRpc, WsVcsPullRpc, WsVcsRefreshStatusRpc, WsGitRunStackedActionRpc, WsGitResolvePullRequestRpc, WsGitPreparePullRequestThreadRpc, WsVcsListRefsRpc, WsVcsCreateWorktreeRpc, WsVcsRemoveWorktreeRpc, WsVcsCreateRefRpc, WsVcsSwitchRefRpc, WsVcsInitRpc, WsReviewGetDiffPreviewRpc, WsTerminalOpenRpc, WsTerminalAttachRpc, WsTerminalWriteRpc, WsTerminalResizeRpc, WsTerminalClearRpc, WsTerminalRestartRpc, WsTerminalCloseRpc, WsSubscribeTerminalEventsRpc, WsSubscribeTerminalMetadataRpc, WsPreviewOpenRpc, WsPreviewNavigateRpc, WsPreviewResizeRpc, WsPreviewRefreshRpc, WsPreviewCloseRpc, WsPreviewListRpc, WsPreviewReportStatusRpc, WsComputerUseConnectRpc, WsComputerUseListRpc, WsComputerUseControlsRpc, WsComputerUseControlRpc, WsComputerUseRespondRpc, WsPreviewAutomationConnectRpc, WsPreviewAutomationRespondRpc, WsPreviewAutomationFocusHostRpc, WsSubscribePreviewEventsRpc, WsSubscribeDiscoveredLocalServersRpc, WsSubscribeServerConfigRpc, WsSubscribeServerLifecycleRpc, WsSubscribeAuthAccessRpc, WsTasksListRpc, WsTasksGetRpc, WsTasksCreateRpc, WsTasksUpdateRpc, WsTasksDeleteRpc, WsTasksStartThreadRpc, WsFeedListRpc, WsFeedRefreshRpc, WsFeedSourcesListRpc, WsFeedSourcesUpsertRpc, WsFeedSourcesDeleteRpc, WsFeedMarkReadRpc, WsFeedCleanupRpc, WsSubscribeTasksRpc, WsHubGetSyncStatusRpc, WsHubConnectRpc, WsHubDisconnectRpc, WsHubSetSyncModeRpc, WsHubSetShareModeRpc, WsHubMintTokenRpc, WsSkillsSyncRpc, WsSkillsPublishRpc, WsSkillsPublishAllRpc, WsSkillsUnpublishRpc, WsAssetsReadRpc, WsAssetsSaveRpc, WsAssetsDeleteRpc, WsAssetsCreateLocalRpc, WsAssetsRemoveLocalRpc, WsSkillRegistrySearchRpc, WsSkillRegistryFetchRpc, WsMcpListRpc, WsMcpSaveRpc, WsMcpRemoveRpc, WsMcpSetSecretRpc, WsMcpOAuthBeginRpc, WsMcpOAuthDisconnectRpc, WsTrackerStatusRpc, WsTrackerSetApiKeyRpc, WsTrackerClearApiKeyRpc, WsOrchestrationDispatchCommandRpc, WsOrchestrationGetTurnDiffRpc, WsOrchestrationGetWorkflowScriptRpc, WsOrchestrationGetFullThreadDiffRpc, WsOrchestrationSearchThreadsRpc, WsOrchestrationGetArchivedShellSnapshotRpc, WsOrchestrationSubscribeShellRpc, WsOrchestrationSubscribeThreadRpc);
|
|
14598
14652
|
//#endregion
|
|
14599
14653
|
//#region ../../packages/contracts/src/deviceCommand.ts
|
|
14600
14654
|
const MAX_COORDINATE = 32768;
|
|
@@ -44553,6 +44607,7 @@ const make$88 = Effect.gen(function* () {
|
|
|
44553
44607
|
connectionProbe: true,
|
|
44554
44608
|
pullRequests: true,
|
|
44555
44609
|
hostResources: true,
|
|
44610
|
+
computerUseControls: true,
|
|
44556
44611
|
deviceSessionLeases: true,
|
|
44557
44612
|
deviceActionLeases: true,
|
|
44558
44613
|
pullRequestStackActions: true,
|
|
@@ -53049,6 +53104,7 @@ const COMPUTER_USE_HELPER_CREDENTIAL_TTL_MS = 300 * 1e3;
|
|
|
53049
53104
|
const HELPER_CREDENTIAL_BYTES = 32;
|
|
53050
53105
|
const MAX_PENDING_REQUESTS = 64;
|
|
53051
53106
|
const TRANSPORT_GRACE_MS = 2e3;
|
|
53107
|
+
const COMPUTER_USE_CONTROL_ACK_TIMEOUT_MS = 5e3;
|
|
53052
53108
|
const scopeKey = (scope) => JSON.stringify([
|
|
53053
53109
|
scope.environmentId,
|
|
53054
53110
|
scope.threadId,
|
|
@@ -53058,14 +53114,26 @@ const scopeKey = (scope) => JSON.stringify([
|
|
|
53058
53114
|
const hostSession = (scope) => ({
|
|
53059
53115
|
environmentId: scope.environmentId,
|
|
53060
53116
|
threadId: scope.threadId,
|
|
53117
|
+
...scope.threadTitle ? { threadTitle: scope.threadTitle } : {},
|
|
53061
53118
|
providerInstanceId: scope.providerInstanceId,
|
|
53062
53119
|
providerSessionId: scope.providerSessionId
|
|
53063
53120
|
});
|
|
53064
53121
|
var ComputerUseBroker = class extends Context.Service()("@p4code/cli/mcp/ComputerUseBroker") {};
|
|
53065
53122
|
const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
53123
|
+
const serviceScope = yield* Scope.Scope;
|
|
53066
53124
|
const crypto = yield* Crypto.Crypto;
|
|
53067
|
-
const
|
|
53125
|
+
const environment = yield* ServerEnvironment;
|
|
53126
|
+
const environmentId = yield* environment.getEnvironmentId;
|
|
53068
53127
|
const admission = yield* Semaphore.make(1);
|
|
53128
|
+
const controlAdmission = yield* Semaphore.make(1);
|
|
53129
|
+
const states = /* @__PURE__ */ new Map();
|
|
53130
|
+
const stoppedThreads = /* @__PURE__ */ new Set();
|
|
53131
|
+
const controls = yield* SubscriptionRef.make([]);
|
|
53132
|
+
const publish = () => SubscriptionRef.set(controls, [...states.values()]);
|
|
53133
|
+
const stopped = () => new ComputerUseError({
|
|
53134
|
+
reason: "stopped",
|
|
53135
|
+
detail: "Computer Use was stopped by the user. Ask the user to allow Computer Use again before retrying. Resetting cannot restore access."
|
|
53136
|
+
});
|
|
53069
53137
|
const connections = /* @__PURE__ */ new Map();
|
|
53070
53138
|
const helperCredentials = /* @__PURE__ */ new Map();
|
|
53071
53139
|
const leases = /* @__PURE__ */ new Map();
|
|
@@ -53084,6 +53152,15 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53084
53152
|
detail: "Computer Use host disconnected. Reset before selecting another host."
|
|
53085
53153
|
}));
|
|
53086
53154
|
}
|
|
53155
|
+
for (const [key, state] of states) {
|
|
53156
|
+
if (state.host.connectionId !== connection.host.connectionId) continue;
|
|
53157
|
+
if (state.state === "active") states.delete(key);
|
|
53158
|
+
else if (state.state === "stopping") states.set(key, {
|
|
53159
|
+
...state,
|
|
53160
|
+
state: "stop-unconfirmed"
|
|
53161
|
+
});
|
|
53162
|
+
}
|
|
53163
|
+
yield* publish();
|
|
53087
53164
|
yield* Queue.shutdown(connection.queue);
|
|
53088
53165
|
});
|
|
53089
53166
|
const revokeHelper = Effect.fn("ComputerUseBroker.revokeHelper")(function* (credential) {
|
|
@@ -53143,12 +53220,119 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53143
53220
|
requestId,
|
|
53144
53221
|
hostId: connection.host.hostId,
|
|
53145
53222
|
connectionId: connection.host.connectionId,
|
|
53146
|
-
session: hostSession(scope),
|
|
53223
|
+
session: states.get(key)?.session ?? hostSession(scope),
|
|
53147
53224
|
operation: "close"
|
|
53148
53225
|
}
|
|
53149
53226
|
});
|
|
53150
53227
|
}
|
|
53151
53228
|
}, admission.withPermits(1));
|
|
53229
|
+
const stopThread = Effect.fn("ComputerUseBroker.stopThread")(function* (threadId) {
|
|
53230
|
+
stoppedThreads.add(threadId);
|
|
53231
|
+
for (const [key, state] of states) {
|
|
53232
|
+
if (state.session.threadId !== threadId) continue;
|
|
53233
|
+
if (state.state !== "stopped") states.set(key, {
|
|
53234
|
+
...state,
|
|
53235
|
+
state: "stopping"
|
|
53236
|
+
});
|
|
53237
|
+
leases.delete(key);
|
|
53238
|
+
for (const [id, request] of pending) {
|
|
53239
|
+
if (request.scopeKey !== key) continue;
|
|
53240
|
+
pending.delete(id);
|
|
53241
|
+
yield* Deferred.fail(request.completion, stopped());
|
|
53242
|
+
}
|
|
53243
|
+
}
|
|
53244
|
+
yield* publish();
|
|
53245
|
+
});
|
|
53246
|
+
const sendControl = Effect.fn("ComputerUseBroker.sendControl")(function* (state, action) {
|
|
53247
|
+
const connection = connections.get(state.host.hostId);
|
|
53248
|
+
if (!connection || action === "stop" && connection.host.connectionId !== state.host.connectionId) {
|
|
53249
|
+
if (action === "resume") return yield* new ComputerUseError({
|
|
53250
|
+
reason: "disconnected",
|
|
53251
|
+
detail: "Reconnect this Mac before allowing Computer Use again. Access remains blocked."
|
|
53252
|
+
});
|
|
53253
|
+
if (state.state === "stopped") return;
|
|
53254
|
+
for (const [key, entry] of states) if (entry.session.threadId === state.session.threadId && entry.host.connectionId === state.host.connectionId) states.set(key, {
|
|
53255
|
+
...entry,
|
|
53256
|
+
state: "stop-unconfirmed"
|
|
53257
|
+
});
|
|
53258
|
+
yield* publish();
|
|
53259
|
+
return yield* new ComputerUseError({
|
|
53260
|
+
reason: "disconnected",
|
|
53261
|
+
detail: "Computer Use host is unreachable. Access is blocked, but the Mac has not confirmed Stop."
|
|
53262
|
+
});
|
|
53263
|
+
}
|
|
53264
|
+
const requestId = yield* crypto.randomUUIDv4.pipe(Effect.orDie);
|
|
53265
|
+
const completion = yield* Deferred.make();
|
|
53266
|
+
pending.set(requestId, {
|
|
53267
|
+
connection,
|
|
53268
|
+
completion,
|
|
53269
|
+
scopeKey: requestId
|
|
53270
|
+
});
|
|
53271
|
+
yield* Effect.gen(function* () {
|
|
53272
|
+
yield* Queue.offer(connection.queue, {
|
|
53273
|
+
type: "request",
|
|
53274
|
+
request: {
|
|
53275
|
+
requestId,
|
|
53276
|
+
hostId: connection.host.hostId,
|
|
53277
|
+
connectionId: connection.host.connectionId,
|
|
53278
|
+
session: state.session,
|
|
53279
|
+
operation: action
|
|
53280
|
+
}
|
|
53281
|
+
});
|
|
53282
|
+
yield* Deferred.await(completion).pipe(Effect.timeout(COMPUTER_USE_CONTROL_ACK_TIMEOUT_MS));
|
|
53283
|
+
}).pipe(Effect.catch(() => disconnect(connection).pipe(Effect.andThen(Effect.fail(new ComputerUseError({
|
|
53284
|
+
reason: "disconnected",
|
|
53285
|
+
detail: "Computer Use host did not confirm the control change. Access remains blocked. Check the Mac before allowing control again."
|
|
53286
|
+
}))))), Effect.ensuring(Effect.sync(() => pending.delete(requestId))));
|
|
53287
|
+
});
|
|
53288
|
+
const report = Effect.fn("ComputerUseBroker.report")(function* (owner, report) {
|
|
53289
|
+
const authorization = yield* authorize(owner);
|
|
53290
|
+
const connection = connections.get(report.hostId);
|
|
53291
|
+
if (!connection || connection.authorization !== authorization || connection.host.connectionId !== report.connectionId || report.session.environmentId !== environmentId) return yield* deny();
|
|
53292
|
+
const key = scopeKey(report.session);
|
|
53293
|
+
const state = states.get(key);
|
|
53294
|
+
if (!state || state.host.connectionId !== report.connectionId || state.session.generationId !== report.session.generationId) return;
|
|
53295
|
+
if (report.state === "stopped") {
|
|
53296
|
+
const others = [...states.values()].filter((entry) => entry.session.threadId === report.session.threadId && entry.state === "active" && entry.host.connectionId !== report.connectionId);
|
|
53297
|
+
yield* stopThread(report.session.threadId);
|
|
53298
|
+
for (const other of new Map(others.map((entry) => [entry.host.connectionId, entry])).values()) yield* sendControl(other, "stop").pipe(Effect.ignore, Effect.forkIn(serviceScope));
|
|
53299
|
+
for (const [entryKey, entry] of states) if (entry.session.threadId === report.session.threadId && entry.host.connectionId === report.connectionId) states.set(entryKey, {
|
|
53300
|
+
...entry,
|
|
53301
|
+
state: "stopped"
|
|
53302
|
+
});
|
|
53303
|
+
} else if (report.state === "closed") {
|
|
53304
|
+
leases.delete(key);
|
|
53305
|
+
if (state.state === "active") states.delete(key);
|
|
53306
|
+
else states.set(key, {
|
|
53307
|
+
...state,
|
|
53308
|
+
state: "stopped"
|
|
53309
|
+
});
|
|
53310
|
+
}
|
|
53311
|
+
if (report.state !== "active") yield* publish();
|
|
53312
|
+
}, admission.withPermits(1));
|
|
53313
|
+
const control = Effect.fn("ComputerUseBroker.control")(function* (input) {
|
|
53314
|
+
const targets = yield* admission.withPermits(1)(Effect.gen(function* () {
|
|
53315
|
+
const targets = [...states.values()].filter((state) => state.session.threadId === input.threadId);
|
|
53316
|
+
if (input.action === "stop" && targets.length > 0) yield* stopThread(input.threadId);
|
|
53317
|
+
return targets;
|
|
53318
|
+
}));
|
|
53319
|
+
const hosts = new Map(targets.map((state) => [state.host.connectionId, state]));
|
|
53320
|
+
let failure;
|
|
53321
|
+
yield* Effect.forEach([...hosts.values()], (state) => sendControl(state, input.action).pipe(Effect.catch((error) => Effect.sync(() => {
|
|
53322
|
+
failure = error;
|
|
53323
|
+
}))), { concurrency: "unbounded" });
|
|
53324
|
+
if (failure) return yield* failure;
|
|
53325
|
+
if (input.action === "resume") stoppedThreads.delete(input.threadId);
|
|
53326
|
+
for (const [key, state] of states) {
|
|
53327
|
+
if (state.session.threadId !== input.threadId) continue;
|
|
53328
|
+
if (input.action === "resume") states.delete(key);
|
|
53329
|
+
else states.set(key, {
|
|
53330
|
+
...state,
|
|
53331
|
+
state: "stopped"
|
|
53332
|
+
});
|
|
53333
|
+
}
|
|
53334
|
+
yield* publish();
|
|
53335
|
+
}, controlAdmission.withPermits(1), Effect.uninterruptible);
|
|
53152
53336
|
return ComputerUseBroker.of({
|
|
53153
53337
|
attachVerifiedHelper: (binding) => Effect.gen(function* () {
|
|
53154
53338
|
if (binding.host.environmentId !== environmentId || !binding.helperIdentity || !binding.desktopSessionId) return yield* deny();
|
|
@@ -53210,6 +53394,9 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53210
53394
|
expiresAt
|
|
53211
53395
|
};
|
|
53212
53396
|
}, admission.withPermits(1)),
|
|
53397
|
+
report,
|
|
53398
|
+
control,
|
|
53399
|
+
controls: SubscriptionRef.changes(controls),
|
|
53213
53400
|
list: Effect.sync(() => [...connections.values()].map((entry) => entry.host)),
|
|
53214
53401
|
connect: (owner, host) => authorize(owner).pipe(Effect.as(Stream.unwrap(Effect.acquireRelease(admission.withPermits(1)(acquire(owner, host)), (connection) => revokeHelper(connection.owner)).pipe(Effect.map((connection) => Stream.fromQueue(connection.queue)))))),
|
|
53215
53402
|
respond: Effect.fn("ComputerUseBroker.respond")(function* (owner, response) {
|
|
@@ -53225,19 +53412,20 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53225
53412
|
invoke: (scope, input, hostId) => Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
|
|
53226
53413
|
const { requestId, connection, completion, request } = yield* admission.withPermits(1)(Effect.gen(function* () {
|
|
53227
53414
|
if (scope.authorizationLifetime?.revoked === true || !scope.capabilities.has("computer-use") || scope.environmentId !== environmentId) return yield* deny();
|
|
53228
|
-
if (
|
|
53229
|
-
|
|
53415
|
+
if (scope.computerUseHostId && hostId !== void 0 && hostId !== scope.computerUseHostId) return yield* deny();
|
|
53416
|
+
if (stoppedThreads.has(scope.threadId)) return yield* stopped();
|
|
53417
|
+
const grantedHostId = scope.computerUseHostId ?? hostId;
|
|
53230
53418
|
const key = scopeKey(scope);
|
|
53231
53419
|
const existing = leases.get(key);
|
|
53232
53420
|
if (existing && (connections.get(existing.host.hostId) !== existing || hostId !== void 0 && hostId !== existing.host.hostId)) return yield* new ComputerUseError({
|
|
53233
53421
|
reason: "disconnected",
|
|
53234
53422
|
detail: "Reset Computer Use before changing host connections."
|
|
53235
53423
|
});
|
|
53236
|
-
const candidates = [...connections.values()].filter((entry) => (entry.host.browser || entry.host.nativeApps) && entry.host.hostId === grantedHostId);
|
|
53424
|
+
const candidates = [...connections.values()].filter((entry) => (entry.host.browser || entry.host.nativeApps) && (grantedHostId === void 0 || entry.host.hostId === grantedHostId));
|
|
53237
53425
|
const connection = existing ?? (candidates.length === 1 ? candidates[0] : void 0);
|
|
53238
53426
|
if (!connection) return yield* new ComputerUseError({
|
|
53239
53427
|
reason: "unavailable",
|
|
53240
|
-
detail: candidates.length > 1 ?
|
|
53428
|
+
detail: candidates.length > 1 ? `Select a Computer Use host with hostId: ${candidates.map((entry) => `${entry.host.label} (${entry.host.hostId})`).join(", ")}.` : "No Computer Use host is available."
|
|
53241
53429
|
});
|
|
53242
53430
|
if (pending.size >= MAX_PENDING_REQUESTS || [...pending.values()].some((request) => request.scopeKey === key)) return yield* new ComputerUseError({
|
|
53243
53431
|
reason: "busy",
|
|
@@ -53246,6 +53434,20 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53246
53434
|
yield* authorize(connection.owner);
|
|
53247
53435
|
const requestId = yield* crypto.randomUUIDv4.pipe(Effect.orDie);
|
|
53248
53436
|
const completion = yield* Deferred.make();
|
|
53437
|
+
const descriptor = yield* environment.getDescriptor;
|
|
53438
|
+
const session = existing ? states.get(key)?.session ?? hostSession(scope) : {
|
|
53439
|
+
...hostSession(scope),
|
|
53440
|
+
environmentLabel: descriptor.label,
|
|
53441
|
+
generationId: requestId
|
|
53442
|
+
};
|
|
53443
|
+
if (!existing) {
|
|
53444
|
+
states.set(key, {
|
|
53445
|
+
session,
|
|
53446
|
+
host: connection.host,
|
|
53447
|
+
state: "active"
|
|
53448
|
+
});
|
|
53449
|
+
yield* publish();
|
|
53450
|
+
}
|
|
53249
53451
|
leases.set(key, connection);
|
|
53250
53452
|
pending.set(requestId, {
|
|
53251
53453
|
connection,
|
|
@@ -53260,7 +53462,7 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53260
53462
|
requestId,
|
|
53261
53463
|
hostId: connection.host.hostId,
|
|
53262
53464
|
connectionId: connection.host.connectionId,
|
|
53263
|
-
session
|
|
53465
|
+
session,
|
|
53264
53466
|
operation: "js",
|
|
53265
53467
|
input
|
|
53266
53468
|
}
|
|
@@ -53285,7 +53487,7 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53285
53487
|
pending.delete(requestId);
|
|
53286
53488
|
})));
|
|
53287
53489
|
})),
|
|
53288
|
-
reset: (scope) => scope.authorizationLifetime?.revoked !== true && scope.environmentId === environmentId && scope.capabilities.has("computer-use") ? revoke(scope) : Effect.fail(deny()),
|
|
53490
|
+
reset: (scope) => scope.authorizationLifetime?.revoked !== true && scope.environmentId === environmentId && scope.capabilities.has("computer-use") ? stoppedThreads.has(scope.threadId) ? Effect.fail(stopped()) : revoke(scope) : Effect.fail(deny()),
|
|
53289
53491
|
revoke,
|
|
53290
53492
|
invalidate: (scope) => Effect.sync(() => {
|
|
53291
53493
|
if (scope.authorizationLifetime) scope.authorizationLifetime.revoked = true;
|
|
@@ -53388,6 +53590,14 @@ const respond = HttpRouter.add("POST", "/internal/computer-use/respond", Effect.
|
|
|
53388
53590
|
yield* broker.respond(bearer(request), response);
|
|
53389
53591
|
return HttpServerResponse.empty({ status: 204 });
|
|
53390
53592
|
}).pipe(Effect.catch(failure$1)));
|
|
53593
|
+
const decodeHostReport = Schema$1.decodeUnknownEffect(ComputerUseHostReport);
|
|
53594
|
+
const report = HttpRouter.add("POST", "/internal/computer-use/report", Effect.gen(function* () {
|
|
53595
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
53596
|
+
const broker = yield* ComputerUseBroker;
|
|
53597
|
+
const report = yield* decodeHostReport(yield* request.json);
|
|
53598
|
+
yield* broker.report(bearer(request), report);
|
|
53599
|
+
return HttpServerResponse.empty({ status: 204 });
|
|
53600
|
+
}).pipe(Effect.catch(failure$1)));
|
|
53391
53601
|
const environment = HttpRouter.add("GET", "/internal/computer-use/environment", Effect.gen(function* () {
|
|
53392
53602
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
53393
53603
|
const binding = yield* resolveDesktopBinding(bearer(request));
|
|
@@ -53415,7 +53625,7 @@ const renew = HttpRouter.add("POST", "/internal/computer-use/renew", Effect.gen(
|
|
|
53415
53625
|
if (binding.trust) yield* (yield* RemoteComputerUseBindings).touch(bearer(request));
|
|
53416
53626
|
return HttpServerResponse.empty({ status: 204 });
|
|
53417
53627
|
}).pipe(Effect.catch(failure$1)));
|
|
53418
|
-
const layer$66 = Layer.mergeAll(exchange, hubForward, hubExchange, connect, respond, environment, renew).pipe(Layer.provide(remoteComputerUseBindingsLayer));
|
|
53628
|
+
const layer$66 = Layer.mergeAll(exchange, hubForward, hubExchange, connect, respond, report, environment, renew).pipe(Layer.provide(remoteComputerUseBindingsLayer));
|
|
53419
53629
|
//#endregion
|
|
53420
53630
|
//#region src/device/DeviceHubSocketProtocol.ts
|
|
53421
53631
|
const MAX_DEVICE_INPUT_BYTES = 8 * 1024;
|
|
@@ -63291,7 +63501,7 @@ function formatAskUserQuestionAnswers(answers) {
|
|
|
63291
63501
|
*/
|
|
63292
63502
|
const FUSION_BUILDER_INSTRUCTIONS = `You are Fusion Builder in an already-created native server pair. Server owns pairing and coordination. Do not inspect or invoke the Fusion skill, create/pair/rename threads, or announce/setup Fusion. Start the user's task directly. Before editing, create and maintain the phase list with your provider's step-tracking tool (Claude Code: TaskCreate for each phase, then TaskUpdate for status, or TodoWrite when that is the tool offered; Codex: update_plan), never the MCP task board tools - one entry per phase in order, exactly one in progress at a time, marked completed at each phase end - so phases render in the task banner. That list holds phase entries only for the whole task; keep step-level or per-file todos out of it. Name each phase in 3-6 words by its outcome, never by a command, file path, or flag, because the banner shows the title verbatim. Prose alone leaves the banner empty. Split it into the fewest substantial phases the task genuinely needs plus a final integration/whole-task phase; most tasks need one to three work phases. Each phase is a complete reviewable slice of behavior. Never split per file, per function, or per trivial step: over-splitting spends review turns instead of finishing the job. Add a phase only when a real review boundary, risky decision, or independent behavior separates the work. Complete exactly one phase per turn, and finish the whole phase in that turn rather than stopping early. Do not run tests, typecheck, lint, or builds per phase; write the tests the change needs, then run verification once in the final phase over the whole task. Exception: a phase whose own correctness is unclear may run the single narrowest check that resolves it. End every phase turn with phase completed, todo status, changed behavior/files, and remaining phases; do not start the next phase in the same turn. Server then wakes the paired Supervisor, which resumes you through ${FUSION_ADVICE_PROMPT_PREFIX}; a user message may also revise or resume the work. Final phase verifies the entire task against the original request and labels it ready for whole-task review. Supervisor is unreachable during your turn. Never spawn/use another Supervisor thread/subagent or attribute Supervisor decisions without ${FUSION_ADVICE_PROMPT_PREFIX}. Within the current phase, continue when straightforward or evidence is clear. For a concrete unresolved tradeoff, correctness risk, or design decision materially needing judgment, stop safely before the risky choice; final response states the exact question and why review is needed. Evaluate/follow Supervisor advice unless conflicting with user request or verified repo state.`;
|
|
63293
63503
|
const FUSION_WATCHER_TOOL_INSTRUCTIONS = `Supervisor tools belong to the p4-code MCP server: thread_watch_review, thread_watch_events, thread_advise, and thread_gate_respond. If absent from the visible tool list, first use the available tool search/discovery facility to load those exact tools, including provider-prefixed names; absence from the initial list does not establish unavailability. If discovery or a call fails, report the exact missing capability or error and the need to restore the p4-code MCP connection. Do not offer manual relay, draft or implement the task yourself, or abandon the supervisor role as a workaround. For an actionable user requirement, read the relevant builder evidence and relay it through thread_advise; when a gate is open, answer through thread_gate_respond instead.`;
|
|
63294
|
-
const FUSION_WATCHER_INSTRUCTIONS = `You are Fusion Supervisor (watcher) in an already-created native server pair. Server owns pairing and coordination and wakes you with ${FUSION_REVIEW_PROMPT_PREFIX} or ${FUSION_GATE_PROMPT_PREFIX} prompts at builder turn boundaries. A plain message outside such a wake may arrive after your conversational memory of the pair is gone; its [fusion-pair] metadata block is authoritative: the builder thread exists and is the counterpart thread id. Never report that no builder thread exists. ${FUSION_WATCHER_TOOL_INSTRUCTIONS} To resume supervision, read builder evidence with thread_watch_review from lastReviewedImplementerSequence, capture its throughSequence on the first page and reuse that fixed bound while paging with nextAfterSequence until hasMore is false (including empty pages). Apply message append/replace operations by identity; recover truncated evidence through targeted raw thread_watch_events source ranges. Retain reviewed requirements and evidence for final review; recover missing context with targeted history reads rather than mandatory raw replay from zero, derive phase from artifacts (git log/status, PR, builder events, including its turn.plan.updated phase list), steer with thread_advise, and answer an open gate with thread_gate_respond. When a review or gate wake prompt specifies an explicit event range, that range wins over this metadata. Never poll or wait for the builder; deliver review or advice, then end the turn. Every thread_advise starts a builder turn whose completion wakes you again, so never advise a builder that is idle on an external wait or has nothing actionable; report the state in your own thread and end without advising.`;
|
|
63504
|
+
const FUSION_WATCHER_INSTRUCTIONS = `You are Fusion Supervisor (watcher) in an already-created native server pair. Server owns pairing and coordination and wakes you with ${FUSION_REVIEW_PROMPT_PREFIX} or ${FUSION_GATE_PROMPT_PREFIX} prompts at builder turn boundaries. A plain message outside such a wake may arrive after your conversational memory of the pair is gone; its [fusion-pair] metadata block is authoritative: the builder thread exists and is the counterpart thread id. Never report that no builder thread exists. For a new pair, the initial user request is yours: inspect the task and available project context, plan the work, then direct the first actionable phase to the idle builder through thread_advise. Include the original requirements, constraints, and authorized delivery scope in that direction. The builder has not received the initial prompt and must not start before your direction. Missing builder turn evidence is expected before that first direction; do not wait for it or implement the work yourself. Ask the user only when needed to resolve a blocking requirement. ${FUSION_WATCHER_TOOL_INSTRUCTIONS} To resume supervision, read builder evidence with thread_watch_review from lastReviewedImplementerSequence, capture its throughSequence on the first page and reuse that fixed bound while paging with nextAfterSequence until hasMore is false (including empty pages). Apply message append/replace operations by identity; recover truncated evidence through targeted raw thread_watch_events source ranges. Retain reviewed requirements and evidence for final review; recover missing context with targeted history reads rather than mandatory raw replay from zero, derive phase from artifacts (git log/status, PR, builder events, including its turn.plan.updated phase list), steer with thread_advise, and answer an open gate with thread_gate_respond. When a review or gate wake prompt specifies an explicit event range, that range wins over this metadata. Never poll or wait for the builder; deliver review or advice, then end the turn. Every thread_advise starts a builder turn whose completion wakes you again, so never advise a builder that is idle on an external wait or has nothing actionable; report the state in your own thread and end without advising.`;
|
|
63295
63505
|
/**
|
|
63296
63506
|
* The one-line stand-in for the full block on a message whose session already
|
|
63297
63507
|
* carries the role instructions.
|
|
@@ -124607,6 +124817,8 @@ const RPC_REQUIRED_SCOPE = /* @__PURE__ */ new Map([
|
|
|
124607
124817
|
[WS_METHODS.previewReportStatus, AuthOrchestrationOperateScope],
|
|
124608
124818
|
[WS_METHODS.computerUseConnect, AuthOrchestrationOperateScope],
|
|
124609
124819
|
[WS_METHODS.computerUseList, AuthOrchestrationReadScope],
|
|
124820
|
+
[WS_METHODS.computerUseControls, AuthOrchestrationReadScope],
|
|
124821
|
+
[WS_METHODS.computerUseControl, AuthOrchestrationOperateScope],
|
|
124610
124822
|
[WS_METHODS.computerUseRespond, AuthOrchestrationOperateScope],
|
|
124611
124823
|
[WS_METHODS.previewAutomationConnect, AuthOrchestrationOperateScope],
|
|
124612
124824
|
[WS_METHODS.previewAutomationRespond, AuthOrchestrationOperateScope],
|
|
@@ -125041,6 +125253,18 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker, computerUseBrok
|
|
|
125041
125253
|
branch: worktree.worktree.refName,
|
|
125042
125254
|
worktreePath: targetWorktreePath
|
|
125043
125255
|
});
|
|
125256
|
+
if (!bootstrap.createThread) {
|
|
125257
|
+
const snapshot = yield* projectionSnapshotQuery.getCommandReadModel();
|
|
125258
|
+
const pair = snapshot.threadPairs?.find((candidate) => candidate.detachedAt === null && candidate.watcherThreadId === command.threadId);
|
|
125259
|
+
const builder = pair && snapshot.threads.find((thread) => thread.id === pair.implementerThreadId && thread.deletedAt === null);
|
|
125260
|
+
if (builder && builder.latestTurn === null && builder.messages.length === 0 && builder.worktreePath === null) yield* orchestrationEngine.dispatch({
|
|
125261
|
+
type: "thread.meta.update",
|
|
125262
|
+
commandId: yield* serverCommandId("bootstrap-builder-meta-update"),
|
|
125263
|
+
threadId: builder.id,
|
|
125264
|
+
branch: worktree.worktree.refName,
|
|
125265
|
+
worktreePath: targetWorktreePath
|
|
125266
|
+
});
|
|
125267
|
+
}
|
|
125044
125268
|
yield* refreshGitStatus(targetWorktreePath);
|
|
125045
125269
|
}
|
|
125046
125270
|
yield* runSetupProgram();
|
|
@@ -125632,6 +125856,8 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker, computerUseBrok
|
|
|
125632
125856
|
[WS_METHODS.previewList]: (input) => observeRpcEffect$1(WS_METHODS.previewList, previewManager.list(input), { "rpc.aggregate": "preview" }),
|
|
125633
125857
|
[WS_METHODS.previewReportStatus]: (input) => observeRpcEffect$1(WS_METHODS.previewReportStatus, previewManager.reportStatus(input), { "rpc.aggregate": "preview" }),
|
|
125634
125858
|
[WS_METHODS.computerUseList]: () => computerUseBroker.list,
|
|
125859
|
+
[WS_METHODS.computerUseControls]: () => computerUseBroker.controls,
|
|
125860
|
+
[WS_METHODS.computerUseControl]: (input) => computerUseBroker.control(input),
|
|
125635
125861
|
[WS_METHODS.computerUseConnect]: () => Effect.fail(new ComputerUseError({
|
|
125636
125862
|
reason: "denied",
|
|
125637
125863
|
detail: "Ordinary environment clients cannot register Computer Use helpers."
|
|
@@ -126105,7 +126331,7 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
126105
126331
|
const providerSessionId = yield* crypto.randomUUIDv4.pipe(Effect.orDie);
|
|
126106
126332
|
const rawToken = yield* crypto.randomBytes(32).pipe(Effect.map(tokenFromBytes), Effect.orDie);
|
|
126107
126333
|
const tokenHash = yield* hashToken(rawToken);
|
|
126108
|
-
const computerUseToken = request.computerUseHostId ? yield* crypto.randomBytes(32).pipe(Effect.map(tokenFromBytes), Effect.orDie) : void 0;
|
|
126334
|
+
const computerUseToken = request.computerUseAccess || request.computerUseHostId ? yield* crypto.randomBytes(32).pipe(Effect.map(tokenFromBytes), Effect.orDie) : void 0;
|
|
126109
126335
|
const computerUseHash = computerUseToken ? yield* hashToken(computerUseToken) : void 0;
|
|
126110
126336
|
const watchThreadIds = new Set((request.watchThreadIds ?? []).map((threadId) => ThreadId.make(threadId)));
|
|
126111
126337
|
const adviseThreadIds = new Set((request.adviseThreadIds ?? []).map((threadId) => ThreadId.make(threadId)));
|
|
@@ -126127,6 +126353,7 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
126127
126353
|
},
|
|
126128
126354
|
environmentId,
|
|
126129
126355
|
threadId,
|
|
126356
|
+
...request.threadTitle ? { threadTitle: request.threadTitle } : {},
|
|
126130
126357
|
providerSessionId,
|
|
126131
126358
|
providerInstanceId: ProviderInstanceId.make(request.providerInstanceId),
|
|
126132
126359
|
capabilities,
|
|
@@ -126144,12 +126371,12 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
126144
126371
|
controlThreadIds: /* @__PURE__ */ new Set(),
|
|
126145
126372
|
lastAliveAt: issuedAt
|
|
126146
126373
|
});
|
|
126147
|
-
if (computerUseHash
|
|
126374
|
+
if (computerUseHash) next.set(computerUseHash, {
|
|
126148
126375
|
tokenHash: computerUseHash,
|
|
126149
126376
|
scope: {
|
|
126150
126377
|
...scopeWith(false, false, computerRevocation),
|
|
126151
126378
|
capabilities: /* @__PURE__ */ new Set(["computer-use"]),
|
|
126152
|
-
computerUseHostId: request.computerUseHostId
|
|
126379
|
+
...request.computerUseHostId ? { computerUseHostId: request.computerUseHostId } : {}
|
|
126153
126380
|
},
|
|
126154
126381
|
controlThreadIds: /* @__PURE__ */ new Set(),
|
|
126155
126382
|
lastAliveAt: issuedAt
|
|
@@ -126481,16 +126708,14 @@ const makeProviderService = Effect.fn("makeProviderService")(function* (options)
|
|
|
126481
126708
|
const thread = yield* projectionQuery.value.getThreadShellById(threadId);
|
|
126482
126709
|
return Option.isSome(thread) ? resolveProjectAgentBrowserAccess(settings, thread.value.projectId) : false;
|
|
126483
126710
|
})), Effect.catch((cause) => Effect.logWarning("Could not read settings; withholding agent browser access.", { cause }).pipe(Effect.as(false))));
|
|
126484
|
-
const
|
|
126485
|
-
|
|
126486
|
-
const thread = yield* projectionQuery.value.getThreadShellById(threadId);
|
|
126487
|
-
return Option.isSome(thread) ? thread.value.computerUseHostId ?? void 0 : void 0;
|
|
126488
|
-
}).pipe(Effect.catch(() => Effect.void));
|
|
126711
|
+
const computerUseAccess = yield* registry.getInstanceInfo(providerInstanceId).pipe(Effect.map((info) => info.driverKind !== "codex"), Effect.catch(() => Effect.succeed(false)));
|
|
126712
|
+
const threadTitle = Option.isSome(projectionQuery) ? yield* projectionQuery.value.getThreadShellById(threadId).pipe(Effect.map((thread) => Option.isSome(thread) ? thread.value.title : void 0), Effect.catch(() => Effect.succeed(void 0))) : void 0;
|
|
126489
126713
|
const credential = yield* issueActiveMcpCredential({
|
|
126490
126714
|
threadId,
|
|
126715
|
+
...threadTitle ? { threadTitle } : {},
|
|
126491
126716
|
providerInstanceId,
|
|
126492
126717
|
browserAccess,
|
|
126493
|
-
|
|
126718
|
+
computerUseAccess,
|
|
126494
126719
|
...watchThreadIds !== void 0 ? { watchThreadIds } : {},
|
|
126495
126720
|
...adviseThreadIds !== void 0 ? { adviseThreadIds } : {}
|
|
126496
126721
|
});
|
|
@@ -127279,6 +127504,25 @@ const makeProviderSessionReaper = (options) => Effect.gen(function* () {
|
|
|
127279
127504
|
const makeProviderSessionReaperLive = (options) => Layer.effect(ProviderSessionReaper, makeProviderSessionReaper(options));
|
|
127280
127505
|
const ProviderSessionReaperLive = makeProviderSessionReaperLive();
|
|
127281
127506
|
//#endregion
|
|
127507
|
+
//#region src/mcp/McpToolkit.ts
|
|
127508
|
+
const mcpInputSchema = (schema) => ({
|
|
127509
|
+
...schema,
|
|
127510
|
+
type: "object"
|
|
127511
|
+
});
|
|
127512
|
+
const mcpToolkit = (toolkit) => Layer.effectDiscard(Effect.gen(function* () {
|
|
127513
|
+
const server = yield* McpServer.McpServer;
|
|
127514
|
+
yield* McpServer.registerToolkit(toolkit).pipe(Effect.provideService(McpServer.McpServer, {
|
|
127515
|
+
...server,
|
|
127516
|
+
addTool: (options) => server.addTool({
|
|
127517
|
+
...options,
|
|
127518
|
+
tool: new McpSchema.Tool({
|
|
127519
|
+
...options.tool,
|
|
127520
|
+
inputSchema: mcpInputSchema(options.tool.inputSchema)
|
|
127521
|
+
})
|
|
127522
|
+
})
|
|
127523
|
+
}));
|
|
127524
|
+
}));
|
|
127525
|
+
//#endregion
|
|
127282
127526
|
//#region src/mcp/toolkits/computerUse/tools.ts
|
|
127283
127527
|
const ComputerUseJsTool = Tool.make("js", {
|
|
127284
127528
|
description: "Run JavaScript in a persistent P4 Computer Use REPL. Start with await cua.getState(). Use cua.createBrowserTab('iab', url, {visible:true}) or cua.getTab(tabId) for P4 browser tabs. Tab methods: getState(), goto(url), click({locator}), type({text,locator?,clear?}), press({key,modifiers?}), scroll({deltaY,deltaX?}). Print results with nodeRepl.write(value); emit PNG/JPEG with nodeRepl.emitImage({mimeType,data}) using base64 data. Top-level await and persistent let bindings are supported. Await each operation. Reset after timeout or host disconnect. For available native apps, use cua.getApp(exactNameOrBundleId), then getState(), activate(), click({elementId}), or type({elementId,text}) to replace a field value. Element IDs come from the latest app snapshot. List windows with app.windows(); capture a listed ID with app.screenshot(windowId), then nodeRepl.emitImage(image). Native app availability and macOS permission states are reported by the host; never assume native apps are supported. The host may be a different machine from the provider server.",
|
|
@@ -127320,7 +127564,7 @@ const register = Effect.fn("computerUse.register")(function* () {
|
|
|
127320
127564
|
tool: new McpSchema.Tool({
|
|
127321
127565
|
name: tool.name,
|
|
127322
127566
|
description: Tool.getDescription(tool),
|
|
127323
|
-
inputSchema: Tool.getJsonSchema(tool),
|
|
127567
|
+
inputSchema: mcpInputSchema(Tool.getJsonSchema(tool)),
|
|
127324
127568
|
annotations: {
|
|
127325
127569
|
readOnlyHint: false,
|
|
127326
127570
|
destructiveHint: true,
|
|
@@ -127711,7 +127955,7 @@ const registerScreenshot = Effect.fn("device.registerScreenshot")(function* () {
|
|
|
127711
127955
|
tool: new McpSchema.Tool({
|
|
127712
127956
|
name: DeviceScreenshotTool.name,
|
|
127713
127957
|
description: Tool.getDescription(DeviceScreenshotTool),
|
|
127714
|
-
inputSchema: Tool.getJsonSchema(DeviceScreenshotTool),
|
|
127958
|
+
inputSchema: mcpInputSchema(Tool.getJsonSchema(DeviceScreenshotTool)),
|
|
127715
127959
|
annotations: {
|
|
127716
127960
|
readOnlyHint: true,
|
|
127717
127961
|
destructiveHint: false,
|
|
@@ -127729,7 +127973,7 @@ const registerScreenshot = Effect.fn("device.registerScreenshot")(function* () {
|
|
|
127729
127973
|
}))))
|
|
127730
127974
|
});
|
|
127731
127975
|
});
|
|
127732
|
-
const DeviceToolkitRegistrationLive = Layer.mergeAll(
|
|
127976
|
+
const DeviceToolkitRegistrationLive = Layer.mergeAll(mcpToolkit(DeviceStandardToolkit), Layer.effectDiscard(registerScreenshot())).pipe(Layer.provide(DeviceToolkitHandlersLive));
|
|
127733
127977
|
//#endregion
|
|
127734
127978
|
//#region src/mcp/toolkits/preview/tools.ts
|
|
127735
127979
|
const dependencies$1 = [McpInvocationContext, PreviewAutomationBroker];
|
|
@@ -128467,7 +128711,7 @@ const AskUserQuestionTool = Tool.make("ask_user_question", {
|
|
|
128467
128711
|
]
|
|
128468
128712
|
}).annotate(Tool.Title, "Ask user question").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
128469
128713
|
const ThreadSpawnTool = Tool.make("thread_spawn", {
|
|
128470
|
-
description: "Start a new agent thread and send it a first message, then return its id. Use it to hand a piece of work to a fresh thread - a subtask you just planned, a job that wants its own transcript. Set fusion true to create two new threads as a separate Fusion pair and
|
|
128714
|
+
description: "Start a new agent thread and send it a first message, then return its id. Use it to hand a piece of work to a fresh thread - a subtask you just planned, a job that wants its own transcript. Set fusion true to create two new threads as a separate Fusion pair and send prompt to its supervisor, which plans and directs the builder later, even when this thread already belongs to a pair. Set fusionWatcher true only for a supervisor to pair with the current thread. Both use saved Fusion role models unless overridden. Act on the user's request; no special command syntax is required. The new thread inherits this one's project, model, permission mode, interaction mode, compression and subagent policy, and every one of those can be set here instead - what you set is already in force for the first turn, so a thread never has to be corrected after it starts. Set modelSelection to run it on another model: give the model id, and leave instanceId out to keep this thread's provider instance. Once started it can be watched with thread_watch_events and changed later with thread_configure. A thread that was itself started this way cannot start another.",
|
|
128471
128715
|
parameters: ThreadSpawnInput,
|
|
128472
128716
|
success: ThreadSpawnResult,
|
|
128473
128717
|
failure: ThreadControlToolError,
|
|
@@ -128871,21 +129115,21 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
128871
129115
|
yield* dispatchControl({
|
|
128872
129116
|
type: "thread.turn.start",
|
|
128873
129117
|
commandId: yield* newCommandId,
|
|
128874
|
-
threadId,
|
|
129118
|
+
threadId: fusionPair?.watcherThreadId ?? threadId,
|
|
128875
129119
|
message: {
|
|
128876
129120
|
messageId: MessageId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie)),
|
|
128877
129121
|
role: "user",
|
|
128878
129122
|
text: input.prompt,
|
|
128879
129123
|
attachments: []
|
|
128880
129124
|
},
|
|
128881
|
-
modelSelection,
|
|
129125
|
+
modelSelection: fusionPair ? settings?.fusionWatcherModelSelection ?? modelSelection : modelSelection,
|
|
128882
129126
|
titleSeed: input.title,
|
|
128883
129127
|
runtimeMode,
|
|
128884
|
-
interactionMode,
|
|
129128
|
+
interactionMode: fusionPair ? "default" : interactionMode,
|
|
128885
129129
|
compressMode,
|
|
128886
129130
|
unpromptedSubagents,
|
|
128887
129131
|
createdAt
|
|
128888
|
-
}, threadId);
|
|
129132
|
+
}, fusionPair?.watcherThreadId ?? threadId);
|
|
128889
129133
|
return {
|
|
128890
129134
|
threadId,
|
|
128891
129135
|
projectId,
|
|
@@ -129525,7 +129769,7 @@ const registerPreviewSnapshot = Effect.fn("McpHttpServer.registerPreviewSnapshot
|
|
|
129525
129769
|
tool: new McpSchema.Tool({
|
|
129526
129770
|
name: tool.name,
|
|
129527
129771
|
description: Tool.getDescription(tool),
|
|
129528
|
-
inputSchema: Tool.getJsonSchema(tool),
|
|
129772
|
+
inputSchema: mcpInputSchema(Tool.getJsonSchema(tool)),
|
|
129529
129773
|
annotations: {
|
|
129530
129774
|
...Context.getOption(tool.annotations, Tool.Title).pipe(Option.map((title) => ({ title })), Option.getOrUndefined),
|
|
129531
129775
|
readOnlyHint: Context.get(tool.annotations, Tool.Readonly),
|
|
@@ -129567,13 +129811,13 @@ const registerPreviewSnapshot = Effect.fn("McpHttpServer.registerPreviewSnapshot
|
|
|
129567
129811
|
})
|
|
129568
129812
|
});
|
|
129569
129813
|
});
|
|
129570
|
-
const PreviewStandardToolkitRegistrationLive =
|
|
129814
|
+
const PreviewStandardToolkitRegistrationLive = mcpToolkit(PreviewStandardToolkit).pipe(Layer.provide(PreviewStandardToolkitHandlersLive));
|
|
129571
129815
|
const PreviewSnapshotRegistrationLive = Layer.effectDiscard(registerPreviewSnapshot()).pipe(Layer.provide(PreviewSnapshotToolkitHandlersLive));
|
|
129572
129816
|
const PreviewToolkitRegistrationLive = Layer.mergeAll(PreviewStandardToolkitRegistrationLive, PreviewSnapshotRegistrationLive);
|
|
129573
|
-
const TaskToolkitRegistrationLive =
|
|
129574
|
-
const ThreadToolkitRegistrationLive =
|
|
129575
|
-
const WatchToolkitRegistrationLive =
|
|
129576
|
-
const AdviseToolkitRegistrationLive =
|
|
129817
|
+
const TaskToolkitRegistrationLive = mcpToolkit(TaskToolkit).pipe(Layer.provide(TaskToolkitHandlersLive));
|
|
129818
|
+
const ThreadToolkitRegistrationLive = mcpToolkit(ThreadToolkit).pipe(Layer.provide(ThreadToolkitHandlersLive));
|
|
129819
|
+
const WatchToolkitRegistrationLive = mcpToolkit(WatchToolkit).pipe(Layer.provide(WatchToolkitHandlersLive));
|
|
129820
|
+
const AdviseToolkitRegistrationLive = mcpToolkit(AdviseToolkit).pipe(Layer.provide(AdviseToolkitHandlersLive));
|
|
129577
129821
|
const McpTransportLive = McpServer.layerHttp({
|
|
129578
129822
|
name: "P4Code",
|
|
129579
129823
|
version: version$1,
|
|
@@ -129585,7 +129829,7 @@ const ComputerUseMcpLive = ComputerUseToolkitRegistrationLive.pipe(Layer.provide
|
|
|
129585
129829
|
version: version$1,
|
|
129586
129830
|
path: "/mcp/computer-use"
|
|
129587
129831
|
}).pipe(Layer.provide(McpAuthMiddlewareLive))));
|
|
129588
|
-
const layer$3 = Layer.mergeAll(StandardMcpLive, ComputerUseMcpLive);
|
|
129832
|
+
const layer$3 = Layer.mergeAll(Layer.fresh(StandardMcpLive), Layer.fresh(ComputerUseMcpLive));
|
|
129589
129833
|
//#endregion
|
|
129590
129834
|
//#region src/hub/HubActivityTransport.ts
|
|
129591
129835
|
const REQUEST_TIMEOUT_MS = 8e3;
|