@p4code/cli 0.5.2 → 0.5.4
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 +1065 -639
- package/dist/client/assets/{DiffPanel-TdFgWgnt.js → DiffPanel-CRatYkMr.js} +3 -3
- package/dist/client/assets/{FilePreviewPanel-CrfXacLI.js → FilePreviewPanel-Bj9oMAni.js} +2 -2
- package/dist/client/assets/PreviewPanel-BXk62FYk.js +2 -0
- package/dist/client/assets/{PullRequestCodeTab-C0yI6_el.js → PullRequestCodeTab-BftwY9yH.js} +2 -2
- package/dist/client/assets/{fileCommentAnnotations-gOajnpec.js → fileCommentAnnotations-2ZSnwBCq.js} +2 -2
- package/dist/client/assets/{index-X_nEJk29.css → index-Bb0jNtjG.css} +1 -1
- package/dist/client/assets/{index-CC1AdCS7.js → index-CUbaiNT9.js} +187 -174
- package/dist/client/assets/previewAssetResource-Bmv-dii0.js +48 -0
- package/dist/client/assets/{renderFileChildren-DIs5Nr3g.js → renderFileChildren-Bl4eZEU1.js} +2 -2
- package/dist/client/assets/{toggle-group-vOK_laZo.js → toggle-group-CfOTk4Pb.js} +2 -2
- package/dist/client/index.html +6 -6
- package/package.json +1 -1
- package/dist/client/assets/PreviewPanel-BeQWWrso.js +0 -2
- package/dist/client/assets/previewAssetResource-DZZapyaR.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.5.
|
|
263
|
+
var version$1 = "0.5.4";
|
|
264
264
|
//#endregion
|
|
265
265
|
//#region src/config.ts
|
|
266
266
|
/**
|
|
@@ -9806,6 +9806,7 @@ const FusionModelPair = Schema$1.Struct({
|
|
|
9806
9806
|
supervisor: ModelSelection
|
|
9807
9807
|
});
|
|
9808
9808
|
const ClientSettingsSchema = Schema$1.Struct({
|
|
9809
|
+
fusionHiddenSuggestionKeys: Schema$1.Array(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
9809
9810
|
fusionPairOrder: Schema$1.Record(Schema$1.String, Schema$1.Array(Schema$1.String)).pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
9810
9811
|
fusionRecentPairs: Schema$1.Array(FusionModelPair).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
9811
9812
|
fusionFavoritePairs: Schema$1.Array(FusionModelPair).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
@@ -10399,6 +10400,7 @@ const ServerSettingsPatch = Schema$1.Struct({
|
|
|
10399
10400
|
providerInstances: Schema$1.optionalKey(Schema$1.Record(ProviderInstanceId, ProviderInstanceConfig))
|
|
10400
10401
|
});
|
|
10401
10402
|
Schema$1.Struct({
|
|
10403
|
+
fusionHiddenSuggestionKeys: Schema$1.optionalKey(Schema$1.Array(Schema$1.String)),
|
|
10402
10404
|
fusionPairOrder: Schema$1.optionalKey(Schema$1.Record(Schema$1.String, Schema$1.Array(Schema$1.String))),
|
|
10403
10405
|
fusionRecentPairs: Schema$1.optionalKey(Schema$1.Array(FusionModelPair)),
|
|
10404
10406
|
fusionFavoritePairs: Schema$1.optionalKey(Schema$1.Array(FusionModelPair)),
|
|
@@ -11777,6 +11779,13 @@ const ThreadPairCreateResult = Schema$1.Struct({
|
|
|
11777
11779
|
watcherThreadId: ThreadId,
|
|
11778
11780
|
continuationMessageId: MessageId
|
|
11779
11781
|
});
|
|
11782
|
+
const ThreadPairDetachInput = Schema$1.Struct({ pairId: ThreadPairId.annotate({ description: "The active Fusion pair to detach. This session must be its implementer and must have created its watcher with thread_spawn." }) });
|
|
11783
|
+
const ThreadPairDetachResult = Schema$1.Struct({
|
|
11784
|
+
pairId: ThreadPairId,
|
|
11785
|
+
implementerThreadId: ThreadId,
|
|
11786
|
+
watcherThreadId: ThreadId,
|
|
11787
|
+
detachedAt: IsoDateTime
|
|
11788
|
+
});
|
|
11780
11789
|
const ThreadConfigureInput = Schema$1.Struct({
|
|
11781
11790
|
threadId: ControlTargetThreadId,
|
|
11782
11791
|
title: Schema$1.optional(TrimmedNonEmptyString),
|
|
@@ -13335,6 +13344,30 @@ var ProviderSetupError = class extends Schema$1.TaggedErrorClass()("ProviderSetu
|
|
|
13335
13344
|
}
|
|
13336
13345
|
};
|
|
13337
13346
|
//#endregion
|
|
13347
|
+
//#region ../../packages/contracts/src/deviceCommand.ts
|
|
13348
|
+
const MAX_COORDINATE = 32768;
|
|
13349
|
+
const MAX_TEXT_LENGTH = 4096;
|
|
13350
|
+
const target = {
|
|
13351
|
+
hostId: DeviceHostId,
|
|
13352
|
+
deviceId: DeviceId
|
|
13353
|
+
};
|
|
13354
|
+
const Coordinate = Schema$1.Int.check(Schema$1.isBetween({
|
|
13355
|
+
minimum: 0,
|
|
13356
|
+
maximum: MAX_COORDINATE
|
|
13357
|
+
}));
|
|
13358
|
+
/** Deliberately excludes arbitrary commands, flags, paths and daemon configuration. */
|
|
13359
|
+
const DeviceCommandInput = Schema$1.Union([Schema$1.Struct({
|
|
13360
|
+
...target,
|
|
13361
|
+
command: Schema$1.Literal("press"),
|
|
13362
|
+
x: Coordinate,
|
|
13363
|
+
y: Coordinate
|
|
13364
|
+
}), Schema$1.Struct({
|
|
13365
|
+
...target,
|
|
13366
|
+
command: Schema$1.Literal("type"),
|
|
13367
|
+
text: Schema$1.String.check(Schema$1.isMinLength(1), Schema$1.isMaxLength(MAX_TEXT_LENGTH))
|
|
13368
|
+
})]);
|
|
13369
|
+
const DeviceCommandResult = Schema$1.Struct({ ok: Schema$1.Literal(true) });
|
|
13370
|
+
//#endregion
|
|
13338
13371
|
//#region ../../packages/contracts/src/computerUse.ts
|
|
13339
13372
|
const COMPUTER_USE_MAX_CODE_CHARS = 1e5;
|
|
13340
13373
|
const COMPUTER_USE_MAX_TIMEOUT_MS = 6e4;
|
|
@@ -13374,9 +13407,36 @@ const ComputerUseJsInput = Schema$1.Struct({
|
|
|
13374
13407
|
title: Schema$1.optional(Schema$1.String.check(Schema$1.isMaxLength(COMPUTER_USE_MAX_TITLE_CHARS))),
|
|
13375
13408
|
timeout_ms: Schema$1.optional(Schema$1.Int.check(Schema$1.isGreaterThan(0), Schema$1.isLessThanOrEqualTo(COMPUTER_USE_MAX_TIMEOUT_MS)))
|
|
13376
13409
|
});
|
|
13410
|
+
const COMPUTER_USE_PREVIEW_MAX_IMAGE_CHARS = 5e5;
|
|
13411
|
+
const ComputerUseLogicalSize = Schema$1.Struct({
|
|
13412
|
+
width: Schema$1.Number.check(Schema$1.isGreaterThan(0)),
|
|
13413
|
+
height: Schema$1.Number.check(Schema$1.isGreaterThan(0))
|
|
13414
|
+
});
|
|
13415
|
+
const ComputerUsePreviewFrame = Schema$1.Struct({
|
|
13416
|
+
appName: Schema$1.String,
|
|
13417
|
+
windowId: Schema$1.String,
|
|
13418
|
+
sequence: Schema$1.Int,
|
|
13419
|
+
image: Schema$1.optional(Schema$1.Struct({
|
|
13420
|
+
mimeType: Schema$1.Literal("image/jpeg"),
|
|
13421
|
+
data: Schema$1.String.check(Schema$1.isMaxLength(COMPUTER_USE_PREVIEW_MAX_IMAGE_CHARS))
|
|
13422
|
+
})),
|
|
13423
|
+
logicalSize: Schema$1.optional(ComputerUseLogicalSize),
|
|
13424
|
+
pointer: Schema$1.optional(Schema$1.Struct({
|
|
13425
|
+
x: Schema$1.Number,
|
|
13426
|
+
y: Schema$1.Number,
|
|
13427
|
+
sequence: Schema$1.Int
|
|
13428
|
+
})),
|
|
13429
|
+
error: Schema$1.optional(Schema$1.String)
|
|
13430
|
+
});
|
|
13431
|
+
const ComputerUsePreview = Schema$1.Struct({
|
|
13432
|
+
session: ComputerUseSession,
|
|
13433
|
+
host: ComputerUseHost,
|
|
13434
|
+
frame: ComputerUsePreviewFrame
|
|
13435
|
+
});
|
|
13377
13436
|
const ComputerUseOutput = Schema$1.Struct({
|
|
13378
13437
|
text: Schema$1.String.check(Schema$1.isMaxLength(COMPUTER_USE_MAX_OUTPUT_CHARS)),
|
|
13379
13438
|
truncated: Schema$1.Boolean,
|
|
13439
|
+
preview: Schema$1.optional(ComputerUsePreviewFrame),
|
|
13380
13440
|
images: Schema$1.optional(Schema$1.Array(Schema$1.Struct({
|
|
13381
13441
|
mimeType: Schema$1.Literals(["image/png", "image/jpeg"]),
|
|
13382
13442
|
data: Schema$1.String.check(Schema$1.isMaxLength(COMPUTER_USE_MAX_IMAGE_CHARS))
|
|
@@ -13392,7 +13452,8 @@ const ComputerUseHostRequest = Schema$1.Struct({
|
|
|
13392
13452
|
"js_reset",
|
|
13393
13453
|
"close",
|
|
13394
13454
|
"stop",
|
|
13395
|
-
"resume"
|
|
13455
|
+
"resume",
|
|
13456
|
+
"preview"
|
|
13396
13457
|
]),
|
|
13397
13458
|
input: Schema$1.optional(ComputerUseJsInput)
|
|
13398
13459
|
});
|
|
@@ -13439,6 +13500,26 @@ const ComputerUseHostResponse = Schema$1.Struct({
|
|
|
13439
13500
|
error: ComputerUseError
|
|
13440
13501
|
})])
|
|
13441
13502
|
});
|
|
13503
|
+
const ComputerUseDeviceControl = Schema$1.Struct({
|
|
13504
|
+
hostId: DeviceHostId,
|
|
13505
|
+
deviceId: DeviceId,
|
|
13506
|
+
platform: DevicePlatform,
|
|
13507
|
+
leaseId: DeviceId,
|
|
13508
|
+
name: Schema$1.String,
|
|
13509
|
+
hostLabel: Schema$1.String,
|
|
13510
|
+
logicalSize: Schema$1.optional(ComputerUseLogicalSize),
|
|
13511
|
+
pointer: Schema$1.Struct({
|
|
13512
|
+
x: Schema$1.Number.check(Schema$1.isBetween({
|
|
13513
|
+
minimum: 0,
|
|
13514
|
+
maximum: 1
|
|
13515
|
+
})),
|
|
13516
|
+
y: Schema$1.Number.check(Schema$1.isBetween({
|
|
13517
|
+
minimum: 0,
|
|
13518
|
+
maximum: 1
|
|
13519
|
+
})),
|
|
13520
|
+
sequence: Schema$1.Int
|
|
13521
|
+
})
|
|
13522
|
+
});
|
|
13442
13523
|
const ComputerUseHostReport = Schema$1.Struct({
|
|
13443
13524
|
hostId: TrimmedNonEmptyString,
|
|
13444
13525
|
connectionId: TrimmedNonEmptyString,
|
|
@@ -13447,7 +13528,9 @@ const ComputerUseHostReport = Schema$1.Struct({
|
|
|
13447
13528
|
"active",
|
|
13448
13529
|
"closed",
|
|
13449
13530
|
"stopped"
|
|
13450
|
-
])
|
|
13531
|
+
]),
|
|
13532
|
+
previewApp: Schema$1.optional(Schema$1.String),
|
|
13533
|
+
deviceControl: Schema$1.optional(Schema$1.NullOr(ComputerUseDeviceControl))
|
|
13451
13534
|
});
|
|
13452
13535
|
const ComputerUseControlState = Schema$1.Struct({
|
|
13453
13536
|
session: ComputerUseSession,
|
|
@@ -13457,7 +13540,9 @@ const ComputerUseControlState = Schema$1.Struct({
|
|
|
13457
13540
|
"stopping",
|
|
13458
13541
|
"stopped",
|
|
13459
13542
|
"stop-unconfirmed"
|
|
13460
|
-
])
|
|
13543
|
+
]),
|
|
13544
|
+
previewApp: Schema$1.optional(Schema$1.String),
|
|
13545
|
+
deviceControl: Schema$1.optional(Schema$1.NullOr(ComputerUseDeviceControl))
|
|
13461
13546
|
});
|
|
13462
13547
|
const ComputerUseControlInput = Schema$1.Struct({
|
|
13463
13548
|
threadId: ThreadId,
|
|
@@ -13480,6 +13565,51 @@ const ComputerUseSourceAttestation = Schema$1.Struct({
|
|
|
13480
13565
|
connectionId: TrimmedNonEmptyString,
|
|
13481
13566
|
expiresAt: Schema$1.Number
|
|
13482
13567
|
});
|
|
13568
|
+
/** Device commands travel back to the environment through the live helper request lease. */
|
|
13569
|
+
const ComputerUseDeviceTarget = {
|
|
13570
|
+
hostId: DeviceHostId,
|
|
13571
|
+
deviceId: DeviceId,
|
|
13572
|
+
leaseId: DeviceId
|
|
13573
|
+
};
|
|
13574
|
+
const ComputerUseDeviceOperation = Schema$1.Union([
|
|
13575
|
+
Schema$1.Struct({ method: Schema$1.Literal("list") }),
|
|
13576
|
+
Schema$1.Struct({
|
|
13577
|
+
method: Schema$1.Literal("open"),
|
|
13578
|
+
hostId: DeviceHostId,
|
|
13579
|
+
deviceId: DeviceId,
|
|
13580
|
+
platform: DevicePlatform
|
|
13581
|
+
}),
|
|
13582
|
+
Schema$1.Struct({
|
|
13583
|
+
method: Schema$1.Literals([
|
|
13584
|
+
"state",
|
|
13585
|
+
"screenshot",
|
|
13586
|
+
"close"
|
|
13587
|
+
]),
|
|
13588
|
+
...ComputerUseDeviceTarget
|
|
13589
|
+
}),
|
|
13590
|
+
Schema$1.Struct({
|
|
13591
|
+
method: Schema$1.Literal("command"),
|
|
13592
|
+
leaseId: DeviceId,
|
|
13593
|
+
command: DeviceCommandInput
|
|
13594
|
+
})
|
|
13595
|
+
]);
|
|
13596
|
+
const ComputerUseDeviceRequest = Schema$1.Struct({
|
|
13597
|
+
hostId: TrimmedNonEmptyString,
|
|
13598
|
+
connectionId: TrimmedNonEmptyString,
|
|
13599
|
+
requestId: TrimmedNonEmptyString,
|
|
13600
|
+
callId: TrimmedNonEmptyString,
|
|
13601
|
+
operation: ComputerUseDeviceOperation
|
|
13602
|
+
});
|
|
13603
|
+
Schema$1.Struct({
|
|
13604
|
+
callId: TrimmedNonEmptyString,
|
|
13605
|
+
result: Schema$1.Union([Schema$1.Struct({
|
|
13606
|
+
ok: Schema$1.Literal(true),
|
|
13607
|
+
value: Schema$1.Unknown
|
|
13608
|
+
}), Schema$1.Struct({
|
|
13609
|
+
ok: Schema$1.Literal(false),
|
|
13610
|
+
error: ComputerUseError
|
|
13611
|
+
})])
|
|
13612
|
+
});
|
|
13483
13613
|
//#endregion
|
|
13484
13614
|
//#region ../../packages/contracts/src/rpc.ts
|
|
13485
13615
|
const WS_METHODS = {
|
|
@@ -13524,6 +13654,7 @@ const WS_METHODS = {
|
|
|
13524
13654
|
computerUseList: "computerUse.list",
|
|
13525
13655
|
computerUseControls: "computerUse.controls",
|
|
13526
13656
|
computerUseControl: "computerUse.control",
|
|
13657
|
+
computerUsePreview: "computerUse.preview",
|
|
13527
13658
|
computerUseRespond: "computerUse.respond",
|
|
13528
13659
|
previewAutomationConnect: "previewAutomation.connect",
|
|
13529
13660
|
previewAutomationRespond: "previewAutomation.respond",
|
|
@@ -14553,6 +14684,12 @@ const WsComputerUseControlsRpc = Rpc.make(WS_METHODS.computerUseControls, {
|
|
|
14553
14684
|
error: EnvironmentAuthorizationError,
|
|
14554
14685
|
stream: true
|
|
14555
14686
|
});
|
|
14687
|
+
const WsComputerUsePreviewRpc = Rpc.make(WS_METHODS.computerUsePreview, {
|
|
14688
|
+
payload: ComputerUseSession,
|
|
14689
|
+
success: ComputerUsePreview,
|
|
14690
|
+
error: Schema$1.Union([ComputerUseError, EnvironmentAuthorizationError]),
|
|
14691
|
+
stream: true
|
|
14692
|
+
});
|
|
14556
14693
|
const WsComputerUseControlRpc = Rpc.make(WS_METHODS.computerUseControl, {
|
|
14557
14694
|
payload: ComputerUseControlInput,
|
|
14558
14695
|
error: Schema$1.Union([ComputerUseError, EnvironmentAuthorizationError])
|
|
@@ -14663,31 +14800,7 @@ const WsSubscribeAuthAccessRpc = Rpc.make(WS_METHODS.subscribeAuthAccess, {
|
|
|
14663
14800
|
error: Schema$1.Union([AuthAccessStreamError, EnvironmentAuthorizationError]),
|
|
14664
14801
|
stream: true
|
|
14665
14802
|
});
|
|
14666
|
-
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);
|
|
14667
|
-
//#endregion
|
|
14668
|
-
//#region ../../packages/contracts/src/deviceCommand.ts
|
|
14669
|
-
const MAX_COORDINATE = 32768;
|
|
14670
|
-
const MAX_TEXT_LENGTH = 4096;
|
|
14671
|
-
const target = {
|
|
14672
|
-
hostId: DeviceHostId,
|
|
14673
|
-
deviceId: DeviceId
|
|
14674
|
-
};
|
|
14675
|
-
const Coordinate = Schema$1.Int.check(Schema$1.isBetween({
|
|
14676
|
-
minimum: 0,
|
|
14677
|
-
maximum: MAX_COORDINATE
|
|
14678
|
-
}));
|
|
14679
|
-
/** Deliberately excludes arbitrary commands, flags, paths and daemon configuration. */
|
|
14680
|
-
const DeviceCommandInput = Schema$1.Union([Schema$1.Struct({
|
|
14681
|
-
...target,
|
|
14682
|
-
command: Schema$1.Literal("press"),
|
|
14683
|
-
x: Coordinate,
|
|
14684
|
-
y: Coordinate
|
|
14685
|
-
}), Schema$1.Struct({
|
|
14686
|
-
...target,
|
|
14687
|
-
command: Schema$1.Literal("type"),
|
|
14688
|
-
text: Schema$1.String.check(Schema$1.isMinLength(1), Schema$1.isMaxLength(MAX_TEXT_LENGTH))
|
|
14689
|
-
})]);
|
|
14690
|
-
const DeviceCommandResult = Schema$1.Struct({ ok: Schema$1.Literal(true) });
|
|
14803
|
+
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, WsComputerUsePreviewRpc, 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);
|
|
14691
14804
|
//#endregion
|
|
14692
14805
|
//#region ../../packages/shared/src/oauthScope.ts
|
|
14693
14806
|
const OAUTH_SCOPE_TOKEN = /^[\u0021\u0023-\u005b\u005d-\u007e]+$/u;
|
|
@@ -20381,7 +20494,7 @@ function resolveFdPath(fd, platform) {
|
|
|
20381
20494
|
const modeFlag = Flag.choice("mode", RuntimeMode$1.literals).pipe(Flag.withDescription("Runtime mode. `desktop` keeps loopback defaults unless overridden."), Flag.optional);
|
|
20382
20495
|
const portFlag$1 = Flag.integer("port").pipe(Flag.withSchema(PortSchema), Flag.withDescription("Port for the HTTP/WebSocket server."), Flag.optional);
|
|
20383
20496
|
const hostFlag$1 = Flag.string("host").pipe(Flag.withDescription("Host/interface to bind (for example 127.0.0.1, 0.0.0.0, or a Tailnet IP)."), Flag.optional);
|
|
20384
|
-
const baseDirFlag$1 = Flag.string("base-dir").pipe(Flag.withDescription("Explicit
|
|
20497
|
+
const baseDirFlag$1 = Flag.string("base-dir").pipe(Flag.withDescription("Explicit P4 Code data directory; runtime state is stored under userdata (equivalent to P4CODE_HOME)."), Flag.optional);
|
|
20385
20498
|
const devUrlFlag = Flag.string("dev-url").pipe(Flag.withSchema(Schema$1.URLFromString), Flag.withDescription("Dev web URL to proxy/redirect to (equivalent to VITE_DEV_SERVER_URL)."), Flag.optional);
|
|
20386
20499
|
const noBrowserFlag = Flag.boolean("no-browser").pipe(Flag.withDescription("Disable automatic browser opening."), Flag.optional);
|
|
20387
20500
|
const bootstrapFdFlag = Flag.integer("bootstrap-fd").pipe(Flag.withSchema(Schema$1.Int), Flag.withDescription("Read one-time bootstrap secrets from the given file descriptor."), Flag.optional);
|
|
@@ -21597,7 +21710,7 @@ const renderTerminalQrCode = (value, margin = 2) => {
|
|
|
21597
21710
|
return rows.join("\n");
|
|
21598
21711
|
};
|
|
21599
21712
|
const formatHeadlessServeOutput = (accessInfo) => [
|
|
21600
|
-
"
|
|
21713
|
+
"P4 Code server is ready.",
|
|
21601
21714
|
`Connection string: ${accessInfo.connectionString}`,
|
|
21602
21715
|
`Token: ${accessInfo.token}`,
|
|
21603
21716
|
`Pairing URL: ${accessInfo.pairingUrl}`,
|
|
@@ -27810,7 +27923,7 @@ const announce = Layer.effectDiscard(Effect.gen(function* () {
|
|
|
27810
27923
|
const config = yield* HubConfig;
|
|
27811
27924
|
const address = (yield* HttpServer.HttpServer).address;
|
|
27812
27925
|
const port = address._tag === "TcpAddress" ? address.port : config.port;
|
|
27813
|
-
yield* Effect.log("
|
|
27926
|
+
yield* Effect.log("P4 Code hub listening", {
|
|
27814
27927
|
host: config.host,
|
|
27815
27928
|
port,
|
|
27816
27929
|
dbPath: config.dbPath,
|
|
@@ -32627,7 +32740,7 @@ const resolveHubPaths = Effect.fn("resolveHubPaths")(function* (baseDirFlag) {
|
|
|
32627
32740
|
tokensPath: path.join(hubDir, "tokens.json")
|
|
32628
32741
|
};
|
|
32629
32742
|
});
|
|
32630
|
-
const baseDirFlag = Flag.string("base-dir").pipe(Flag.withDescription("Base directory for hub state. Defaults to the
|
|
32743
|
+
const baseDirFlag = Flag.string("base-dir").pipe(Flag.withDescription("Base directory for hub state. Defaults to the P4 Code home directory."), Flag.optional);
|
|
32631
32744
|
const hostFlag = Flag.string("host").pipe(Flag.withDescription("Interface to bind. Defaults to 127.0.0.1; pass a Tailnet address to expose the hub to your other machines."), Flag.optional);
|
|
32632
32745
|
const portFlag = Flag.integer("port").pipe(Flag.withDescription("Port for the hub HTTP server."), Flag.optional);
|
|
32633
32746
|
const labelFlag = Flag.string("label").pipe(Flag.withDescription("Name of the server this token is for, for example `studio`."));
|
|
@@ -32635,7 +32748,7 @@ const serveHubCommand = Command.make("serve", {
|
|
|
32635
32748
|
baseDir: baseDirFlag,
|
|
32636
32749
|
host: hostFlag,
|
|
32637
32750
|
port: portFlag
|
|
32638
|
-
}).pipe(Command.withDescription("Run the
|
|
32751
|
+
}).pipe(Command.withDescription("Run the P4 Code hub: the shared task board for all of your servers."), Command.withHandler((flags) => Effect.gen(function* () {
|
|
32639
32752
|
const env = yield* HostProcessEnvironment;
|
|
32640
32753
|
const paths = yield* resolveHubPaths(flags.baseDir);
|
|
32641
32754
|
const tokenFile = yield* readHubTokenFile(paths.tokensPath);
|
|
@@ -32723,7 +32836,7 @@ const tokenCommand = Command.make("token", {}).pipe(Command.withDescription("Man
|
|
|
32723
32836
|
listTokensCommand,
|
|
32724
32837
|
revokeTokenCommand
|
|
32725
32838
|
]));
|
|
32726
|
-
const hubCommand = Command.make("hub", {}).pipe(Command.withDescription("Run and manage the
|
|
32839
|
+
const hubCommand = Command.make("hub", {}).pipe(Command.withDescription("Run and manage the P4 Code hub."), Command.withSubcommands([
|
|
32727
32840
|
serveHubCommand,
|
|
32728
32841
|
tokenCommand,
|
|
32729
32842
|
...hubLinkCommands
|
|
@@ -43864,7 +43977,7 @@ function quoteSystemdValue(value) {
|
|
|
43864
43977
|
function renderBootServiceUnit(plan) {
|
|
43865
43978
|
return [
|
|
43866
43979
|
"[Unit]",
|
|
43867
|
-
"Description=
|
|
43980
|
+
"Description=P4 Code server",
|
|
43868
43981
|
"StartLimitIntervalSec=300",
|
|
43869
43982
|
"StartLimitBurst=5",
|
|
43870
43983
|
"",
|
|
@@ -43971,7 +44084,7 @@ function formatCommandInvocation(command, args) {
|
|
|
43971
44084
|
}
|
|
43972
44085
|
var BootServiceInstallError = class extends Schema$1.TaggedErrorClass()("BootServiceInstallError", { cause: Schema$1.Defect() }) {
|
|
43973
44086
|
get message() {
|
|
43974
|
-
return "Could not set up the
|
|
44087
|
+
return "Could not set up the P4 Code background service.";
|
|
43975
44088
|
}
|
|
43976
44089
|
};
|
|
43977
44090
|
var BootService = class extends Context.Service()("@p4code/cli/service/bootService") {};
|
|
@@ -44328,7 +44441,7 @@ const make$89 = Effect.fn("cloud.server_self_update.make")(function* (options) {
|
|
|
44328
44441
|
contents
|
|
44329
44442
|
}).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path$1.Path, path));
|
|
44330
44443
|
const update = Effect.fn("cloud.server_self_update.update")(function* (input) {
|
|
44331
|
-
if (capability === "desktop-managed") return yield* failWith("This server is managed by the
|
|
44444
|
+
if (capability === "desktop-managed") return yield* failWith("This server is managed by the P4 Code desktop app on its machine; update the desktop app to update it.");
|
|
44332
44445
|
if (capability === null) return yield* failWith("This server cannot update itself; relaunch it manually with the new version.");
|
|
44333
44446
|
const activeMethod = capability;
|
|
44334
44447
|
const targetVersion = input.targetVersion.trim();
|
|
@@ -44944,6 +45057,7 @@ const startDeviceHub = Effect.fn("DeviceHubProcess.start")(function* (input) {
|
|
|
44944
45057
|
String(port),
|
|
44945
45058
|
"--host",
|
|
44946
45059
|
LOOPBACK_HOST,
|
|
45060
|
+
...input.platform ? ["--platform", input.platform] : [],
|
|
44947
45061
|
"--hide-sidebar",
|
|
44948
45062
|
"--hide-boot-device"
|
|
44949
45063
|
], {
|
|
@@ -45694,6 +45808,11 @@ const deviceHostEnvironment = (environment, sdkRoot, hostPlatform, path) => {
|
|
|
45694
45808
|
].join(hostPlatform === "win32" ? ";" : ":")
|
|
45695
45809
|
} : environment;
|
|
45696
45810
|
};
|
|
45811
|
+
/** Unavailable Android tooling must not turn a valid iOS inventory into a partial failure. */
|
|
45812
|
+
function deviceHubPlatform(platforms) {
|
|
45813
|
+
const available = platforms.filter((platform) => platform.available);
|
|
45814
|
+
return available.length === 1 ? available[0].platform : void 0;
|
|
45815
|
+
}
|
|
45697
45816
|
//#endregion
|
|
45698
45817
|
//#region src/device/LocalDeviceHost.ts
|
|
45699
45818
|
const COMMAND_TIMEOUT_MS$1 = 2e4;
|
|
@@ -45767,9 +45886,11 @@ const make$81 = Effect.fn("LocalDeviceHost.make")(function* () {
|
|
|
45767
45886
|
cause
|
|
45768
45887
|
})));
|
|
45769
45888
|
yield* onPhase("starting");
|
|
45889
|
+
const hubPlatform = deviceHubPlatform(yield* Effect.all([platformAvailability("ios"), platformAvailability("android")]));
|
|
45770
45890
|
const started = yield* startDeviceHub({
|
|
45771
45891
|
tool,
|
|
45772
|
-
environment: hostEnvironment
|
|
45892
|
+
environment: hostEnvironment,
|
|
45893
|
+
...hubPlatform ? { platform: hubPlatform } : {}
|
|
45773
45894
|
}).pipe(Effect.provideService(NetService, net), Effect.provideService(ChildProcessSpawner$1.ChildProcessSpawner, spawner), Effect.provideService(HttpClient.HttpClient, http), Effect.provideService(Scope.Scope, scope));
|
|
45774
45895
|
hub = started;
|
|
45775
45896
|
const dist = path.join(tool.installDir, "node_modules", "expo-device-hub", "vendor", "serve-sim", "dist");
|
|
@@ -47527,7 +47648,7 @@ const make$78 = Effect.gen(function* () {
|
|
|
47527
47648
|
} else {
|
|
47528
47649
|
yield* Effect.logDebug("startup phase: browser open check");
|
|
47529
47650
|
const startupBrowserTarget = yield* resolveStartupBrowserTarget;
|
|
47530
|
-
if (serverConfig.mode !== "desktop") yield* Effect.logInfo("Authentication required. Open
|
|
47651
|
+
if (serverConfig.mode !== "desktop") yield* Effect.logInfo("Authentication required. Open P4 Code using the pairing URL.").pipe(Effect.annotateLogs({ pairingUrl: startupBrowserTarget }));
|
|
47531
47652
|
yield* runStartupPhase("browser.open", maybeOpenBrowser(startupBrowserTarget));
|
|
47532
47653
|
}
|
|
47533
47654
|
yield* Effect.logDebug("startup phase: complete");
|
|
@@ -52173,7 +52294,7 @@ const prepareAntigravityProfile = Effect.fn("prepareAntigravityProfile")(functio
|
|
|
52173
52294
|
"--",
|
|
52174
52295
|
"%s"
|
|
52175
52296
|
].map(quoteBrowserArgument).join(" ");
|
|
52176
|
-
if (browserCommand.includes(platform === "win32" ? ";" : ":") || helperExecutable.includes("\r") || helperExecutable.includes("\n") || helperExecutable.includes("\0") || helperExecutable.includes("%s")) return yield* authSupportError("The
|
|
52297
|
+
if (browserCommand.includes(platform === "win32" ? ";" : ":") || helperExecutable.includes("\r") || helperExecutable.includes("\n") || helperExecutable.includes("\0") || helperExecutable.includes("%s")) return yield* authSupportError("The P4 Code runtime path cannot be used to suppress Antigravity browser launches.");
|
|
52177
52298
|
const geminiHome = path.resolve(input.profileDirectory);
|
|
52178
52299
|
const acpDirectory = path.join(geminiHome, "antigravity-acp");
|
|
52179
52300
|
const profile = {
|
|
@@ -52920,7 +53041,7 @@ const makeProviderAuthService = Effect.gen(function* () {
|
|
|
52920
53041
|
if (!instance?.auth) return yield* new ProviderSetupError({
|
|
52921
53042
|
instanceId,
|
|
52922
53043
|
operation,
|
|
52923
|
-
detail: instance ? "This provider does not support sign-in in
|
|
53044
|
+
detail: instance ? "This provider does not support sign-in in P4 Code." : "This provider instance is no longer available."
|
|
52924
53045
|
});
|
|
52925
53046
|
return instance.auth;
|
|
52926
53047
|
});
|
|
@@ -53113,6 +53234,489 @@ const remoteComputerUseBindingsLayer = Layer.effect(RemoteComputerUseBindings, E
|
|
|
53113
53234
|
});
|
|
53114
53235
|
}));
|
|
53115
53236
|
//#endregion
|
|
53237
|
+
//#region src/device/DeviceCommandProxy.ts
|
|
53238
|
+
var DeviceCommandProxyFailure = class extends Data.TaggedError("DeviceCommandProxyFailure") {};
|
|
53239
|
+
const COMMAND_TIMEOUT_MS = 3e4;
|
|
53240
|
+
const MAX_RESPONSE_BYTES$2 = 64 * 1024;
|
|
53241
|
+
const Reply = Schema$1.Struct({
|
|
53242
|
+
jsonrpc: Schema$1.Literal("2.0"),
|
|
53243
|
+
id: Schema$1.String,
|
|
53244
|
+
result: Schema$1.Struct({ ok: Schema$1.Boolean })
|
|
53245
|
+
});
|
|
53246
|
+
const make$75 = Effect.fn("DeviceCommandProxy.make")(function* () {
|
|
53247
|
+
const http = yield* HttpClient.HttpClient;
|
|
53248
|
+
const daemonSessions = /* @__PURE__ */ new WeakMap();
|
|
53249
|
+
return Effect.fn("DeviceCommandProxy.execute")(function* (endpoint, session, payload) {
|
|
53250
|
+
const input = yield* Schema$1.decodeUnknownEffect(DeviceCommandInput)(payload);
|
|
53251
|
+
if (input.hostId !== session.hostId || input.deviceId !== session.deviceId) return yield* new DeviceCommandProxyFailure({ message: "Target mismatch" });
|
|
53252
|
+
const origin = yield* Effect.try(() => new URL(endpoint.baseUrl));
|
|
53253
|
+
if (origin.protocol !== "http:" || origin.hostname !== "127.0.0.1" || !origin.port || origin.username || origin.password || origin.pathname !== "/" || origin.search || origin.hash) return yield* new DeviceCommandProxyFailure({ message: "Invalid owned daemon" });
|
|
53254
|
+
let daemonSession = daemonSessions.get(session);
|
|
53255
|
+
if (!daemonSession) {
|
|
53256
|
+
daemonSession = `p4-${NodeCrypto.randomUUID()}`;
|
|
53257
|
+
daemonSessions.set(session, daemonSession);
|
|
53258
|
+
}
|
|
53259
|
+
const id = NodeCrypto.randomUUID();
|
|
53260
|
+
const request = HttpClientRequest.post(`${origin.origin}/rpc`).pipe(HttpClientRequest.bodyJsonUnsafe({
|
|
53261
|
+
jsonrpc: "2.0",
|
|
53262
|
+
id,
|
|
53263
|
+
method: "agent_device.command",
|
|
53264
|
+
params: {
|
|
53265
|
+
token: endpoint.token,
|
|
53266
|
+
session: daemonSession,
|
|
53267
|
+
command: input.command,
|
|
53268
|
+
positionals: input.command === "press" ? [String(input.x), String(input.y)] : [input.text],
|
|
53269
|
+
flags: session.platform === "ios" ? {
|
|
53270
|
+
platform: "ios",
|
|
53271
|
+
udid: session.deviceId
|
|
53272
|
+
} : {
|
|
53273
|
+
platform: "android",
|
|
53274
|
+
serial: session.deviceId
|
|
53275
|
+
}
|
|
53276
|
+
}
|
|
53277
|
+
}));
|
|
53278
|
+
const response = yield* http.execute(request);
|
|
53279
|
+
if (response.status !== 200) return yield* new DeviceCommandProxyFailure({ message: "Command rejected" });
|
|
53280
|
+
let bytes = 0;
|
|
53281
|
+
const body = yield* collectUint8StreamText({
|
|
53282
|
+
stream: response.stream.pipe(Stream.mapEffect((chunk) => {
|
|
53283
|
+
bytes += chunk.byteLength;
|
|
53284
|
+
return bytes > MAX_RESPONSE_BYTES$2 ? Effect.fail(new DeviceCommandProxyFailure({ message: "Command response too large" })) : Effect.succeed(chunk);
|
|
53285
|
+
})),
|
|
53286
|
+
maxBytes: MAX_RESPONSE_BYTES$2
|
|
53287
|
+
});
|
|
53288
|
+
if (body.invalidUtf8 || body.truncated) return yield* new DeviceCommandProxyFailure({ message: "Invalid response" });
|
|
53289
|
+
const reply = yield* Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(Reply))(body.text);
|
|
53290
|
+
if (reply.id !== id || !reply.result.ok) return yield* new DeviceCommandProxyFailure({ message: "Command not acknowledged" });
|
|
53291
|
+
return { ok: true };
|
|
53292
|
+
}, Effect.scoped, Effect.timeout(Duration.millis(COMMAND_TIMEOUT_MS)), Effect.mapError(() => new DeviceOperationError({
|
|
53293
|
+
operation: "command",
|
|
53294
|
+
reason: "request_failed",
|
|
53295
|
+
cause: "Device command could not be completed."
|
|
53296
|
+
})));
|
|
53297
|
+
});
|
|
53298
|
+
var DeviceCommandProxy = class extends Context.Service()("@p4code/cli/device/DeviceCommandProxy") {};
|
|
53299
|
+
const layer$67 = Layer.effect(DeviceCommandProxy, make$75().pipe(Effect.map((execute) => ({ execute }))));
|
|
53300
|
+
//#endregion
|
|
53301
|
+
//#region src/device/DeviceScreenshot.ts
|
|
53302
|
+
const MAX_SCREENSHOT_BYTES = 8 * 1024 * 1024;
|
|
53303
|
+
var DeviceScreenshotFailure = class extends Data.TaggedError("DeviceScreenshotFailure") {};
|
|
53304
|
+
const MAX_DIMENSION = 16384;
|
|
53305
|
+
const MAX_PIXELS = 64 * 1024 * 1024;
|
|
53306
|
+
const SCREENSHOT_TIMEOUT_MS = 2e4;
|
|
53307
|
+
const PNG_HEADER_BYTES = 33;
|
|
53308
|
+
const PNG_CHUNK_OVERHEAD = 12;
|
|
53309
|
+
const PNG_SIGNATURE = Buffer.from([
|
|
53310
|
+
137,
|
|
53311
|
+
80,
|
|
53312
|
+
78,
|
|
53313
|
+
71,
|
|
53314
|
+
13,
|
|
53315
|
+
10,
|
|
53316
|
+
26,
|
|
53317
|
+
10
|
|
53318
|
+
]);
|
|
53319
|
+
function pngDimensions(png) {
|
|
53320
|
+
const buffer = Buffer.from(png.buffer, png.byteOffset, png.byteLength);
|
|
53321
|
+
if (buffer.length < PNG_HEADER_BYTES || buffer.length > 8388608 || !buffer.subarray(0, PNG_SIGNATURE.length).equals(PNG_SIGNATURE) || buffer.readUInt32BE(8) !== 13 || buffer.toString("ascii", 12, 16) !== "IHDR") throw new DeviceScreenshotFailure({ message: "Invalid PNG screenshot." });
|
|
53322
|
+
const width = buffer.readUInt32BE(16);
|
|
53323
|
+
const height = buffer.readUInt32BE(20);
|
|
53324
|
+
if (!width || !height || width > MAX_DIMENSION || height > MAX_DIMENSION || width * height > MAX_PIXELS) throw new DeviceScreenshotFailure({ message: "Screenshot dimensions exceed limits." });
|
|
53325
|
+
let offset = PNG_HEADER_BYTES;
|
|
53326
|
+
let imageData = false;
|
|
53327
|
+
let ended = false;
|
|
53328
|
+
while (offset + PNG_CHUNK_OVERHEAD <= buffer.length) {
|
|
53329
|
+
const length = buffer.readUInt32BE(offset);
|
|
53330
|
+
const type = buffer.toString("ascii", offset + 4, offset + 8);
|
|
53331
|
+
const next = offset + PNG_CHUNK_OVERHEAD + length;
|
|
53332
|
+
if (next > buffer.length || type === "IHDR") throw new DeviceScreenshotFailure({ message: "Invalid PNG chunk." });
|
|
53333
|
+
if (type === "IDAT") imageData = true;
|
|
53334
|
+
if (type === "IEND") {
|
|
53335
|
+
ended = length === 0 && next === buffer.length;
|
|
53336
|
+
break;
|
|
53337
|
+
}
|
|
53338
|
+
offset = next;
|
|
53339
|
+
}
|
|
53340
|
+
if (!imageData || !ended) throw new DeviceScreenshotFailure({ message: "Incomplete PNG screenshot." });
|
|
53341
|
+
return {
|
|
53342
|
+
width,
|
|
53343
|
+
height
|
|
53344
|
+
};
|
|
53345
|
+
}
|
|
53346
|
+
const make$74 = Effect.fn("DeviceScreenshot.make")(function* () {
|
|
53347
|
+
const http = yield* HttpClient.HttpClient;
|
|
53348
|
+
return Effect.fn("DeviceScreenshot.capture")(function* (ready, session) {
|
|
53349
|
+
const origin = yield* Effect.try(() => new URL(ready.hub.origin));
|
|
53350
|
+
if (origin.protocol !== "http:" || origin.hostname !== "127.0.0.1" || !origin.port || origin.username || origin.password || origin.pathname !== "/" || origin.search || origin.hash) return yield* new DeviceScreenshotFailure({ message: "Invalid owned hub." });
|
|
53351
|
+
const vendor = session.platform === "ios" ? "serve-sim" : "serve-emu";
|
|
53352
|
+
const response = yield* http.execute(HttpClientRequest.post(`${origin.origin}/vendor/${vendor}/api/screenshot?device=${encodeURIComponent(session.deviceId)}`));
|
|
53353
|
+
if (response.status !== 200) return yield* new DeviceScreenshotFailure({ message: "Screenshot rejected." });
|
|
53354
|
+
let bytes = 0;
|
|
53355
|
+
const chunks = [];
|
|
53356
|
+
yield* response.stream.pipe(Stream.runForEach((chunk) => Effect.gen(function* () {
|
|
53357
|
+
bytes += chunk.byteLength;
|
|
53358
|
+
if (bytes > 8388608) return yield* new DeviceScreenshotFailure({ message: "Screenshot too large." });
|
|
53359
|
+
chunks.push(chunk);
|
|
53360
|
+
})));
|
|
53361
|
+
const png = Buffer.concat(chunks, bytes);
|
|
53362
|
+
return {
|
|
53363
|
+
png,
|
|
53364
|
+
...yield* Effect.try(() => pngDimensions(png))
|
|
53365
|
+
};
|
|
53366
|
+
}, Effect.scoped, Effect.timeout(Duration.millis(SCREENSHOT_TIMEOUT_MS)), Effect.mapError(() => new DeviceOperationError({
|
|
53367
|
+
operation: "screenshot",
|
|
53368
|
+
reason: "request_failed",
|
|
53369
|
+
cause: "Device screenshot could not be captured."
|
|
53370
|
+
})));
|
|
53371
|
+
});
|
|
53372
|
+
var DeviceScreenshot = class extends Context.Service()("@p4code/cli/device/DeviceScreenshot") {};
|
|
53373
|
+
const layer$66 = Layer.effect(DeviceScreenshot, make$74().pipe(Effect.map((capture) => ({ capture }))));
|
|
53374
|
+
//#endregion
|
|
53375
|
+
//#region src/device/DeviceHubRoute.ts
|
|
53376
|
+
const DEVICE_HUB_PROXY_PREFIX = "/api/device-hub";
|
|
53377
|
+
const MAX_ROUTE_LENGTH = 16 * 1024;
|
|
53378
|
+
const MAX_TICKET_LENGTH = 2048;
|
|
53379
|
+
const decodeTarget = Schema$1.decodeUnknownSync(DeviceSessionDetailInput);
|
|
53380
|
+
const RESOURCES = [
|
|
53381
|
+
"video.avcc",
|
|
53382
|
+
"video.mjpeg",
|
|
53383
|
+
"socket",
|
|
53384
|
+
"screenshot",
|
|
53385
|
+
"ax",
|
|
53386
|
+
"foreground"
|
|
53387
|
+
];
|
|
53388
|
+
function segment(raw) {
|
|
53389
|
+
const value = decodeURIComponent(raw);
|
|
53390
|
+
if (!value || value === "." || value === ".." || /[%/\\\x00-\x1f\x7f]/.test(value) || encodeURIComponent(value) !== raw) throw new Error("Invalid device route segment.");
|
|
53391
|
+
return value;
|
|
53392
|
+
}
|
|
53393
|
+
/** Parse only P4 resources. Caller query parameters never reach the private hub. */
|
|
53394
|
+
function parseDeviceHubRoute(url, method, upgrade) {
|
|
53395
|
+
if (url.href.length > MAX_ROUTE_LENGTH || url.hash || method !== "GET") throw new Error("Invalid device route.");
|
|
53396
|
+
const parts = url.pathname.split("/");
|
|
53397
|
+
if (parts.length !== 10 || parts.slice(0, 3).join("/") !== "/api/device-hub" || parts[3] !== "thread" || parts[5] !== "host" || parts[7] !== "device") throw new Error("Invalid device route.");
|
|
53398
|
+
const resource = parts[9];
|
|
53399
|
+
if (!RESOURCES.some((value) => value === resource) || upgrade !== (resource === "socket")) throw new Error("Unsupported device resource.");
|
|
53400
|
+
const tickets = url.searchParams.getAll("wsTicket");
|
|
53401
|
+
if ([...url.searchParams.keys()].some((key) => key !== "wsTicket") || tickets.length > 1 || tickets.some((ticket) => !ticket || ticket.length > MAX_TICKET_LENGTH)) throw new Error("Invalid device query.");
|
|
53402
|
+
return {
|
|
53403
|
+
target: decodeTarget({
|
|
53404
|
+
threadId: segment(parts[4]),
|
|
53405
|
+
hostId: segment(parts[6]),
|
|
53406
|
+
deviceId: segment(parts[8])
|
|
53407
|
+
}),
|
|
53408
|
+
resource,
|
|
53409
|
+
requiredScope: resource === "socket" ? AuthOrchestrationOperateScope : AuthOrchestrationReadScope
|
|
53410
|
+
};
|
|
53411
|
+
}
|
|
53412
|
+
/** Resolve from the authoritative session, never from a caller-supplied upstream URL. */
|
|
53413
|
+
function resolveDeviceHubRoute(route, session, origin) {
|
|
53414
|
+
if (route.target.threadId !== session.threadId || route.target.hostId !== session.hostId || route.target.deviceId !== session.deviceId) throw new Error("Device session changed.");
|
|
53415
|
+
const hub = new URL(origin);
|
|
53416
|
+
if (hub.protocol !== "http:" || hub.hostname !== "127.0.0.1" || !hub.port || hub.username || hub.password || hub.pathname !== "/" || hub.search || hub.hash) throw new Error("Invalid owned device hub.");
|
|
53417
|
+
const device = encodeURIComponent(session.deviceId);
|
|
53418
|
+
let path;
|
|
53419
|
+
let method = "GET";
|
|
53420
|
+
if (session.platform === "ios") switch (route.resource) {
|
|
53421
|
+
case "video.avcc":
|
|
53422
|
+
path = `/vendor/serve-sim/helper/${device}/stream.avcc`;
|
|
53423
|
+
break;
|
|
53424
|
+
case "video.mjpeg":
|
|
53425
|
+
path = `/vendor/serve-sim/helper/${device}/stream.mjpeg`;
|
|
53426
|
+
break;
|
|
53427
|
+
case "socket":
|
|
53428
|
+
path = `/vendor/serve-sim/helper/ws?device=${device}`;
|
|
53429
|
+
break;
|
|
53430
|
+
case "screenshot":
|
|
53431
|
+
path = `/vendor/serve-sim/api/screenshot?device=${device}`;
|
|
53432
|
+
method = "POST";
|
|
53433
|
+
break;
|
|
53434
|
+
case "ax":
|
|
53435
|
+
path = `/vendor/serve-sim/helper/${device}/ax`;
|
|
53436
|
+
break;
|
|
53437
|
+
case "foreground":
|
|
53438
|
+
path = `/vendor/serve-sim/helper/${device}/foreground`;
|
|
53439
|
+
break;
|
|
53440
|
+
}
|
|
53441
|
+
else switch (route.resource) {
|
|
53442
|
+
case "socket":
|
|
53443
|
+
path = `/vendor/serve-emu/ws?device=${device}&frame-meta=1`;
|
|
53444
|
+
break;
|
|
53445
|
+
case "screenshot":
|
|
53446
|
+
path = `/vendor/serve-emu/api/screenshot?device=${device}`;
|
|
53447
|
+
method = "POST";
|
|
53448
|
+
break;
|
|
53449
|
+
case "ax":
|
|
53450
|
+
path = `/vendor/serve-emu/api/accessibility?device=${device}`;
|
|
53451
|
+
break;
|
|
53452
|
+
default: throw new Error("Device resource unavailable on this platform.");
|
|
53453
|
+
}
|
|
53454
|
+
const upstream = new URL(path, hub);
|
|
53455
|
+
if (route.resource === "socket") upstream.protocol = "ws:";
|
|
53456
|
+
return {
|
|
53457
|
+
url: upstream.href,
|
|
53458
|
+
method,
|
|
53459
|
+
streaming: route.resource === "video.avcc" || route.resource === "video.mjpeg" || route.resource === "socket"
|
|
53460
|
+
};
|
|
53461
|
+
}
|
|
53462
|
+
//#endregion
|
|
53463
|
+
//#region src/mcp/McpInvocationContext.ts
|
|
53464
|
+
var McpInvocationContext = class extends Context.Service()("@p4code/cli/mcp/McpInvocationContext") {};
|
|
53465
|
+
const requireMcpCapability = Effect.fn("mcp.requireCapability")(function* (capability) {
|
|
53466
|
+
const invocation = yield* McpInvocationContext;
|
|
53467
|
+
if (!invocation.capabilities.has(capability)) return yield* new PreviewAutomationUnavailableError({
|
|
53468
|
+
capability,
|
|
53469
|
+
environmentId: invocation.environmentId,
|
|
53470
|
+
threadId: invocation.threadId,
|
|
53471
|
+
providerSessionId: invocation.providerSessionId,
|
|
53472
|
+
providerInstanceId: invocation.providerInstanceId
|
|
53473
|
+
});
|
|
53474
|
+
return invocation;
|
|
53475
|
+
});
|
|
53476
|
+
/**
|
|
53477
|
+
* The task-board counterpart of {@link requireMcpCapability}. The two are
|
|
53478
|
+
* separate because each capability reports its own absence with the error type
|
|
53479
|
+
* its toolkit declares as a failure, and those unions do not overlap.
|
|
53480
|
+
*/
|
|
53481
|
+
const requireTaskCapability = Effect.fn("mcp.requireTaskCapability")(function* () {
|
|
53482
|
+
const invocation = yield* McpInvocationContext;
|
|
53483
|
+
if (!invocation.capabilities.has("tasks")) return yield* new TaskToolUnavailableError({
|
|
53484
|
+
capability: "tasks",
|
|
53485
|
+
environmentId: invocation.environmentId,
|
|
53486
|
+
threadId: invocation.threadId,
|
|
53487
|
+
providerSessionId: invocation.providerSessionId,
|
|
53488
|
+
providerInstanceId: invocation.providerInstanceId
|
|
53489
|
+
});
|
|
53490
|
+
return invocation;
|
|
53491
|
+
});
|
|
53492
|
+
/**
|
|
53493
|
+
* The watch capability's guard is two checks, not one: the capability must be
|
|
53494
|
+
* present AND the requested thread must be in the explicit grant set. The two
|
|
53495
|
+
* failures are distinct errors so a watcher can tell "this session cannot
|
|
53496
|
+
* watch at all" apart from "not this thread".
|
|
53497
|
+
*/
|
|
53498
|
+
const requireWatchCapability = Effect.fn("mcp.requireWatchCapability")(function* (watchedThreadId) {
|
|
53499
|
+
const invocation = yield* McpInvocationContext;
|
|
53500
|
+
if (!invocation.capabilities.has("watch")) return yield* new WatchToolUnavailableError({
|
|
53501
|
+
capability: "watch",
|
|
53502
|
+
environmentId: invocation.environmentId,
|
|
53503
|
+
threadId: invocation.threadId,
|
|
53504
|
+
providerSessionId: invocation.providerSessionId,
|
|
53505
|
+
providerInstanceId: invocation.providerInstanceId
|
|
53506
|
+
});
|
|
53507
|
+
if (!invocation.watchThreadIds?.has(watchedThreadId)) return yield* new ThreadWatchNotPermittedError({ threadId: watchedThreadId });
|
|
53508
|
+
return invocation;
|
|
53509
|
+
});
|
|
53510
|
+
/**
|
|
53511
|
+
* The advise guard mirrors the watch guard's two checks - capability present
|
|
53512
|
+
* AND thread in the explicit grant - because advising carries strictly more
|
|
53513
|
+
* power than watching. A watch-only credential fails the first check here no
|
|
53514
|
+
* matter what threads it can read.
|
|
53515
|
+
*/
|
|
53516
|
+
const requireAdviseCapability = Effect.fn("mcp.requireAdviseCapability")(function* (advisedThreadId) {
|
|
53517
|
+
const invocation = yield* McpInvocationContext;
|
|
53518
|
+
if (!invocation.capabilities.has("advise")) return yield* new AdviseToolUnavailableError({
|
|
53519
|
+
capability: "advise",
|
|
53520
|
+
environmentId: invocation.environmentId,
|
|
53521
|
+
threadId: invocation.threadId,
|
|
53522
|
+
providerSessionId: invocation.providerSessionId,
|
|
53523
|
+
providerInstanceId: invocation.providerInstanceId
|
|
53524
|
+
});
|
|
53525
|
+
if (!invocation.adviseThreadIds?.has(advisedThreadId)) return yield* new ThreadAdviseNotPermittedError({ threadId: advisedThreadId });
|
|
53526
|
+
return invocation;
|
|
53527
|
+
});
|
|
53528
|
+
/** Third of the trio, for the same reason the second exists. */
|
|
53529
|
+
const requireThreadCapability = Effect.fn("mcp.requireThreadCapability")(function* () {
|
|
53530
|
+
const invocation = yield* McpInvocationContext;
|
|
53531
|
+
if (!invocation.capabilities.has("threads")) return yield* new ThreadToolUnavailableError({
|
|
53532
|
+
capability: "threads",
|
|
53533
|
+
environmentId: invocation.environmentId,
|
|
53534
|
+
threadId: invocation.threadId,
|
|
53535
|
+
providerSessionId: invocation.providerSessionId,
|
|
53536
|
+
providerInstanceId: invocation.providerInstanceId
|
|
53537
|
+
});
|
|
53538
|
+
return invocation;
|
|
53539
|
+
});
|
|
53540
|
+
/**
|
|
53541
|
+
* The thread a control tool may act on, given what it was asked to act on.
|
|
53542
|
+
*
|
|
53543
|
+
* Two checks like `requireWatchCapability`, and for the same reason: the
|
|
53544
|
+
* capability says this session controls threads at all, the grant says which.
|
|
53545
|
+
* An omitted id resolves to the session's own thread, which is always in the
|
|
53546
|
+
* grant and is why the common call needs no id and so cannot name a wrong one.
|
|
53547
|
+
*/
|
|
53548
|
+
const requireThreadControlTarget = Effect.fn("mcp.requireThreadControlTarget")(function* (requested) {
|
|
53549
|
+
const invocation = yield* requireThreadCapability();
|
|
53550
|
+
if (requested === void 0 || requested === invocation.threadId) return {
|
|
53551
|
+
invocation,
|
|
53552
|
+
threadId: invocation.threadId
|
|
53553
|
+
};
|
|
53554
|
+
if (!invocation.controlThreadIds?.has(requested)) return yield* new ThreadControlNotPermittedError({ threadId: requested });
|
|
53555
|
+
return {
|
|
53556
|
+
invocation,
|
|
53557
|
+
threadId: requested
|
|
53558
|
+
};
|
|
53559
|
+
});
|
|
53560
|
+
/**
|
|
53561
|
+
* The guard on starting a thread, which is a different question from acting on
|
|
53562
|
+
* one: it is not "which thread" but "may this session make more of them".
|
|
53563
|
+
*/
|
|
53564
|
+
const requireThreadSpawn = Effect.fn("mcp.requireThreadSpawn")(function* (fusion = false) {
|
|
53565
|
+
const invocation = yield* requireThreadCapability();
|
|
53566
|
+
if (invocation.mayCreateThreads !== true && !(fusion && invocation.mayCreateFusionPairs === true)) return yield* new ThreadSpawnNotPermittedError({
|
|
53567
|
+
threadId: invocation.threadId,
|
|
53568
|
+
detail: "this thread was itself started by an agent, and spawning goes one level deep so a runaway loop has a bound"
|
|
53569
|
+
});
|
|
53570
|
+
return invocation;
|
|
53571
|
+
});
|
|
53572
|
+
//#endregion
|
|
53573
|
+
//#region src/mcp/DeviceInvocation.ts
|
|
53574
|
+
const isDeviceToolUnavailableError = Schema$1.is(DeviceToolUnavailableError);
|
|
53575
|
+
const isDeviceActionUnavailableError = Schema$1.is(DeviceActionUnavailableError);
|
|
53576
|
+
/** Internal bridge; tool payloads never choose thread identity or daemon credentials. */
|
|
53577
|
+
const withDeviceInvocation = (execute) => Effect.gen(function* () {
|
|
53578
|
+
const invocation = yield* McpInvocationContext;
|
|
53579
|
+
const service = yield* DeviceService;
|
|
53580
|
+
const lifetime = invocation.authorizationLifetime;
|
|
53581
|
+
const denied = () => new DeviceToolUnavailableError({ reason: "Device command unavailable or authorization changed." });
|
|
53582
|
+
if (!invocation.capabilities.has("devices") || !lifetime?.revocation || lifetime.revoked) return yield* denied();
|
|
53583
|
+
const work = execute(service, invocation.threadId).pipe(Effect.tap(() => lifetime.revoked ? Effect.fail(denied()) : Effect.void), Effect.mapError((error) => isDeviceToolUnavailableError(error) || isDeviceActionUnavailableError(error) ? error : denied()));
|
|
53584
|
+
return yield* Effect.raceFirst(work, Deferred.await(lifetime.revocation).pipe(Effect.andThen(Effect.fail(denied()))));
|
|
53585
|
+
});
|
|
53586
|
+
const withDeviceSession = (target, execute) => withDeviceInvocation((service, threadId) => service.withAgentCommand({
|
|
53587
|
+
hostId: target.hostId,
|
|
53588
|
+
deviceId: target.deviceId,
|
|
53589
|
+
threadId
|
|
53590
|
+
}, execute));
|
|
53591
|
+
//#endregion
|
|
53592
|
+
//#region src/mcp/ComputerUseDevices.ts
|
|
53593
|
+
const MAX_AX_BYTES = 512 * 1024;
|
|
53594
|
+
const AX_TIMEOUT_MS = 1e4;
|
|
53595
|
+
const MAX_AX_EXTENT = 32768;
|
|
53596
|
+
const MIN_AX_EXTENT = 2;
|
|
53597
|
+
const AxFrames = Schema$1.Array(Schema$1.Struct({ frame: Schema$1.Struct({
|
|
53598
|
+
x: Schema$1.Number,
|
|
53599
|
+
y: Schema$1.Number,
|
|
53600
|
+
width: Schema$1.Number.check(Schema$1.isBetween({
|
|
53601
|
+
minimum: MIN_AX_EXTENT,
|
|
53602
|
+
maximum: MAX_AX_EXTENT
|
|
53603
|
+
})),
|
|
53604
|
+
height: Schema$1.Number.check(Schema$1.isBetween({
|
|
53605
|
+
minimum: MIN_AX_EXTENT,
|
|
53606
|
+
maximum: MAX_AX_EXTENT
|
|
53607
|
+
}))
|
|
53608
|
+
}) }));
|
|
53609
|
+
const readAxFrames = Schema$1.decodeUnknownOption(AxFrames);
|
|
53610
|
+
const decodeAxDocument = Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(Schema$1.Unknown));
|
|
53611
|
+
/** Reuse consent and authoritative device leases. The helper never receives daemon credentials. */
|
|
53612
|
+
const makeComputerUseDevices = Effect.fn("ComputerUseDevices.make")(function* () {
|
|
53613
|
+
const devices = yield* DeviceService;
|
|
53614
|
+
const screenshots = yield* DeviceScreenshot;
|
|
53615
|
+
const commands = yield* DeviceCommandProxy;
|
|
53616
|
+
const http = yield* HttpClient.HttpClient;
|
|
53617
|
+
const stale = () => new DeviceOperationError({
|
|
53618
|
+
operation: "command",
|
|
53619
|
+
reason: "request_failed",
|
|
53620
|
+
cause: "Device lease changed. Select this host/device again."
|
|
53621
|
+
});
|
|
53622
|
+
return (scope, input) => withDeviceInvocation((service, threadId) => Effect.gen(function* () {
|
|
53623
|
+
if (input.method === "list") {
|
|
53624
|
+
const state = yield* service.agentList;
|
|
53625
|
+
return {
|
|
53626
|
+
hosts: state.hosts,
|
|
53627
|
+
devices: state.devices,
|
|
53628
|
+
hostStatuses: state.hostStatuses,
|
|
53629
|
+
open: state.sessions.filter((session) => session.threadId === threadId)
|
|
53630
|
+
};
|
|
53631
|
+
}
|
|
53632
|
+
if (input.method === "open") {
|
|
53633
|
+
const state = yield* service.agentList;
|
|
53634
|
+
const device = state.devices.find((device) => device.hostId === input.hostId && device.id === input.deviceId && device.platform === input.platform);
|
|
53635
|
+
if (!device) return yield* stale();
|
|
53636
|
+
const session = yield* service.agentOpen({
|
|
53637
|
+
threadId,
|
|
53638
|
+
hostId: input.hostId,
|
|
53639
|
+
deviceId: input.deviceId,
|
|
53640
|
+
platform: input.platform
|
|
53641
|
+
});
|
|
53642
|
+
if (!session.leaseId) return yield* stale();
|
|
53643
|
+
return {
|
|
53644
|
+
device,
|
|
53645
|
+
leaseId: session.leaseId,
|
|
53646
|
+
hostLabel: state.hosts.find((host) => host.id === device.hostId)?.label ?? device.hostId
|
|
53647
|
+
};
|
|
53648
|
+
}
|
|
53649
|
+
const target = input.method === "command" ? input.command : input;
|
|
53650
|
+
if (input.method === "close") {
|
|
53651
|
+
yield* service.agentClose({
|
|
53652
|
+
threadId,
|
|
53653
|
+
hostId: target.hostId,
|
|
53654
|
+
deviceId: target.deviceId,
|
|
53655
|
+
expectedLeaseId: input.leaseId
|
|
53656
|
+
});
|
|
53657
|
+
return { closed: true };
|
|
53658
|
+
}
|
|
53659
|
+
if (input.method === "command") return yield* service.withAgentCommand({
|
|
53660
|
+
threadId,
|
|
53661
|
+
hostId: target.hostId,
|
|
53662
|
+
deviceId: target.deviceId
|
|
53663
|
+
}, (endpoint, session) => {
|
|
53664
|
+
if (session.leaseId !== input.leaseId) return Effect.fail(stale());
|
|
53665
|
+
return commands.execute(endpoint, session, input.command);
|
|
53666
|
+
});
|
|
53667
|
+
return yield* service.withAgentDevice({
|
|
53668
|
+
threadId,
|
|
53669
|
+
hostId: target.hostId,
|
|
53670
|
+
deviceId: target.deviceId
|
|
53671
|
+
}, (ready, session) => Effect.gen(function* () {
|
|
53672
|
+
if (session.leaseId !== input.leaseId) return yield* stale();
|
|
53673
|
+
if (input.method === "screenshot") {
|
|
53674
|
+
const capture = yield* screenshots.capture(ready, session);
|
|
53675
|
+
return {
|
|
53676
|
+
mimeType: "image/png",
|
|
53677
|
+
data: capture.png.toString("base64"),
|
|
53678
|
+
width: capture.width,
|
|
53679
|
+
height: capture.height
|
|
53680
|
+
};
|
|
53681
|
+
}
|
|
53682
|
+
if (session.platform !== "ios") return yield* new DeviceToolUnavailableError({ reason: "CUA accessibility state is currently supported only for iOS Simulator. Use a screenshot for this device." });
|
|
53683
|
+
const route = resolveDeviceHubRoute({
|
|
53684
|
+
target: {
|
|
53685
|
+
threadId,
|
|
53686
|
+
hostId: target.hostId,
|
|
53687
|
+
deviceId: target.deviceId
|
|
53688
|
+
},
|
|
53689
|
+
resource: "ax",
|
|
53690
|
+
requiredScope: AuthOrchestrationReadScope
|
|
53691
|
+
}, session, ready.hub.origin);
|
|
53692
|
+
const response = yield* http.execute(HttpClientRequest.get(route.url));
|
|
53693
|
+
if (response.status !== 200) return yield* new DeviceToolUnavailableError({ reason: "Device hub accessibility state is unavailable for this simulator. Use getScreenshot() or check the hub helper." });
|
|
53694
|
+
const body = yield* collectUint8StreamText({
|
|
53695
|
+
stream: response.stream,
|
|
53696
|
+
maxBytes: MAX_AX_BYTES
|
|
53697
|
+
});
|
|
53698
|
+
if (body.truncated || body.invalidUtf8) return yield* new DeviceToolUnavailableError({ reason: "Device accessibility state exceeds the supported size." });
|
|
53699
|
+
const accessibility = yield* decodeAxDocument(body.text);
|
|
53700
|
+
const frames = readAxFrames(accessibility);
|
|
53701
|
+
const viewport = Option.isSome(frames) ? frames.value[0]?.frame : void 0;
|
|
53702
|
+
return {
|
|
53703
|
+
...viewport ? { viewport } : {},
|
|
53704
|
+
hostId: session.hostId,
|
|
53705
|
+
deviceId: session.deviceId,
|
|
53706
|
+
leaseId: session.leaseId,
|
|
53707
|
+
accessibility
|
|
53708
|
+
};
|
|
53709
|
+
}).pipe(Effect.scoped, Effect.timeout(AX_TIMEOUT_MS), Effect.mapError((error) => new DeviceOperationError({
|
|
53710
|
+
operation: "command",
|
|
53711
|
+
reason: "request_failed",
|
|
53712
|
+
cause: error.message
|
|
53713
|
+
}))));
|
|
53714
|
+
})).pipe(Effect.provideService(McpInvocationContext, scope), Effect.provideService(DeviceService, devices), Effect.mapError((error) => new ComputerUseError({
|
|
53715
|
+
reason: "unavailable",
|
|
53716
|
+
detail: error.message
|
|
53717
|
+
})));
|
|
53718
|
+
});
|
|
53719
|
+
//#endregion
|
|
53116
53720
|
//#region src/mcp/ComputerUseBroker.ts
|
|
53117
53721
|
const COMPUTER_USE_HELPER_CREDENTIAL_TTL_MS = 300 * 1e3;
|
|
53118
53722
|
const HELPER_CREDENTIAL_BYTES = 32;
|
|
@@ -53133,7 +53737,7 @@ const hostSession = (scope) => ({
|
|
|
53133
53737
|
providerSessionId: scope.providerSessionId
|
|
53134
53738
|
});
|
|
53135
53739
|
var ComputerUseBroker = class extends Context.Service()("@p4code/cli/mcp/ComputerUseBroker") {};
|
|
53136
|
-
const layer$
|
|
53740
|
+
const layer$65 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
53137
53741
|
const serviceScope = yield* Scope.Scope;
|
|
53138
53742
|
const crypto = yield* Crypto.Crypto;
|
|
53139
53743
|
const environment = yield* ServerEnvironment;
|
|
@@ -53322,7 +53926,12 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53322
53926
|
state: "stopped"
|
|
53323
53927
|
});
|
|
53324
53928
|
}
|
|
53325
|
-
if (report.state
|
|
53929
|
+
if (report.state === "active" && state.state === "active" && (report.previewApp !== void 0 || report.deviceControl !== void 0)) states.set(key, {
|
|
53930
|
+
...state,
|
|
53931
|
+
...report.previewApp !== void 0 ? { previewApp: report.previewApp } : {},
|
|
53932
|
+
...report.deviceControl !== void 0 ? { deviceControl: report.deviceControl } : {}
|
|
53933
|
+
});
|
|
53934
|
+
if (report.state !== "active" || report.previewApp !== void 0 || report.deviceControl !== void 0) yield* publish();
|
|
53326
53935
|
}, admission.withPermits(1));
|
|
53327
53936
|
const control = Effect.fn("ComputerUseBroker.control")(function* (input) {
|
|
53328
53937
|
const targets = yield* admission.withPermits(1)(Effect.gen(function* () {
|
|
@@ -53347,6 +53956,53 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53347
53956
|
}
|
|
53348
53957
|
yield* publish();
|
|
53349
53958
|
}, controlAdmission.withPermits(1), Effect.uninterruptible);
|
|
53959
|
+
const capturePreview = Effect.fn("ComputerUseBroker.capturePreview")(function* (session) {
|
|
53960
|
+
const key = scopeKey(session);
|
|
53961
|
+
const state = states.get(key);
|
|
53962
|
+
const connection = state ? connections.get(state.host.hostId) : void 0;
|
|
53963
|
+
if (!state || state.state !== "active" || stoppedThreads.has(session.threadId) || session.environmentId !== environmentId || state.session.generationId !== session.generationId || !connection || connection.host.connectionId !== state.host.connectionId || leases.get(key) !== connection) return yield* new ComputerUseError({
|
|
53964
|
+
reason: "unavailable",
|
|
53965
|
+
detail: "This Computer Use session is no longer active."
|
|
53966
|
+
});
|
|
53967
|
+
yield* authorize(connection.owner);
|
|
53968
|
+
if (pending.size >= MAX_PENDING_REQUESTS) return yield* new ComputerUseError({
|
|
53969
|
+
reason: "busy",
|
|
53970
|
+
detail: "Computer Use is busy."
|
|
53971
|
+
});
|
|
53972
|
+
const requestId = yield* crypto.randomUUIDv4.pipe(Effect.orDie);
|
|
53973
|
+
const completion = yield* Deferred.make();
|
|
53974
|
+
pending.set(requestId, {
|
|
53975
|
+
connection,
|
|
53976
|
+
completion,
|
|
53977
|
+
scopeKey: `preview:${key}`
|
|
53978
|
+
});
|
|
53979
|
+
return yield* Effect.gen(function* () {
|
|
53980
|
+
yield* Queue.offer(connection.queue, {
|
|
53981
|
+
type: "request",
|
|
53982
|
+
request: {
|
|
53983
|
+
requestId,
|
|
53984
|
+
hostId: connection.host.hostId,
|
|
53985
|
+
connectionId: connection.host.connectionId,
|
|
53986
|
+
session: state.session,
|
|
53987
|
+
operation: "preview"
|
|
53988
|
+
}
|
|
53989
|
+
});
|
|
53990
|
+
const output = yield* Deferred.await(completion).pipe(Effect.timeout(COMPUTER_USE_CONTROL_ACK_TIMEOUT_MS), Effect.mapError(() => new ComputerUseError({
|
|
53991
|
+
reason: "unavailable",
|
|
53992
|
+
detail: "Live view is unavailable. Retry after the host reconnects."
|
|
53993
|
+
})));
|
|
53994
|
+
const current = states.get(key);
|
|
53995
|
+
if (!output.preview || !current || current.state !== "active" || current.session.generationId !== session.generationId || connections.get(state.host.hostId) !== connection || leases.get(key) !== connection) return yield* new ComputerUseError({
|
|
53996
|
+
reason: "unavailable",
|
|
53997
|
+
detail: "This live view has ended."
|
|
53998
|
+
});
|
|
53999
|
+
return {
|
|
54000
|
+
session: state.session,
|
|
54001
|
+
host: state.host,
|
|
54002
|
+
frame: output.preview
|
|
54003
|
+
};
|
|
54004
|
+
}).pipe(Effect.ensuring(Effect.sync(() => pending.delete(requestId))));
|
|
54005
|
+
});
|
|
53350
54006
|
return ComputerUseBroker.of({
|
|
53351
54007
|
attachVerifiedHelper: (binding) => Effect.gen(function* () {
|
|
53352
54008
|
if (binding.host.environmentId !== environmentId || !binding.helperIdentity || !binding.desktopSessionId) return yield* deny();
|
|
@@ -53411,6 +54067,7 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53411
54067
|
report,
|
|
53412
54068
|
control,
|
|
53413
54069
|
controls: SubscriptionRef.changes(controls),
|
|
54070
|
+
preview: (session) => Stream.fromEffect(capturePreview(session)).pipe(Stream.repeat(Schedule.spaced(500))),
|
|
53414
54071
|
list: Effect.sync(() => [...connections.values()].map((entry) => entry.host)),
|
|
53415
54072
|
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)))))),
|
|
53416
54073
|
respond: Effect.fn("ComputerUseBroker.respond")(function* (owner, response) {
|
|
@@ -53423,6 +54080,13 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53423
54080
|
if (response.result.ok) yield* Deferred.succeed(request.completion, response.result.output);
|
|
53424
54081
|
else yield* Deferred.fail(request.completion, response.result.error);
|
|
53425
54082
|
}),
|
|
54083
|
+
device: Effect.fn("ComputerUseBroker.device")(function* (owner, input, execute) {
|
|
54084
|
+
yield* authorize(owner);
|
|
54085
|
+
const request = pending.get(input.requestId);
|
|
54086
|
+
const invocation = request?.invocation;
|
|
54087
|
+
if (!request || !invocation || request.connection.owner !== owner || request.connection.host.hostId !== input.hostId || request.connection.host.connectionId !== input.connectionId || connections.get(input.hostId) !== request.connection || leases.get(request.scopeKey) !== request.connection || stoppedThreads.has(invocation.threadId)) return yield* deny();
|
|
54088
|
+
return yield* Effect.raceFirst(execute(invocation).pipe(Effect.tap(() => pending.get(input.requestId) === request ? Effect.void : Effect.fail(deny()))), Deferred.await(request.completion).pipe(Effect.ignore, Effect.andThen(Effect.fail(deny()))));
|
|
54089
|
+
}),
|
|
53426
54090
|
invoke: (scope, input, hostId) => Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
|
|
53427
54091
|
const { requestId, connection, completion, request } = yield* admission.withPermits(1)(Effect.gen(function* () {
|
|
53428
54092
|
if (scope.authorizationLifetime?.revoked === true || !scope.capabilities.has("computer-use") || scope.environmentId !== environmentId) return yield* deny();
|
|
@@ -53466,7 +54130,8 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53466
54130
|
pending.set(requestId, {
|
|
53467
54131
|
connection,
|
|
53468
54132
|
completion,
|
|
53469
|
-
scopeKey: key
|
|
54133
|
+
scopeKey: key,
|
|
54134
|
+
invocation: scope
|
|
53470
54135
|
});
|
|
53471
54136
|
return {
|
|
53472
54137
|
requestId,
|
|
@@ -53510,9 +54175,12 @@ const layer$67 = Layer.effect(ComputerUseBroker, Effect.gen(function* () {
|
|
|
53510
54175
|
}));
|
|
53511
54176
|
//#endregion
|
|
53512
54177
|
//#region src/mcp/ComputerUseDesktopTransport.ts
|
|
54178
|
+
const COMPUTER_USE_HEARTBEAT_MS = 3e4;
|
|
54179
|
+
const keepComputerUseTransportAlive = (stream) => stream.pipe(Stream.merge(Stream.fromEffect(Effect.sleep(COMPUTER_USE_HEARTBEAT_MS).pipe(Effect.as({ type: "heartbeat" }))).pipe(Stream.forever), { haltStrategy: "left" }));
|
|
53513
54180
|
const Registration = Schema$1.Struct({
|
|
53514
54181
|
host: ComputerUseHostRegistration,
|
|
53515
|
-
helperIdentity: Schema$1.String.check(Schema$1.isMinLength(1), Schema$1.isMaxLength(200))
|
|
54182
|
+
helperIdentity: Schema$1.String.check(Schema$1.isMinLength(1), Schema$1.isMaxLength(200)),
|
|
54183
|
+
heartbeat: Schema$1.optional(Schema$1.Boolean)
|
|
53516
54184
|
});
|
|
53517
54185
|
const denied = () => new ComputerUseError({
|
|
53518
54186
|
reason: "denied",
|
|
@@ -53592,9 +54260,30 @@ const connect = HttpRouter.add("POST", "/internal/computer-use/connect", Effect.
|
|
|
53592
54260
|
connectionId: helper.connectionId
|
|
53593
54261
|
}), events);
|
|
53594
54262
|
}));
|
|
53595
|
-
return HttpServerResponse.stream(messages.pipe(Stream.map((message) => new TextEncoder().encode(JSON.stringify(message) + "\n"))), {
|
|
54263
|
+
return HttpServerResponse.stream((input.heartbeat ? keepComputerUseTransportAlive(messages) : messages).pipe(Stream.map((message) => new TextEncoder().encode(JSON.stringify(message) + "\n"))), {
|
|
53596
54264
|
contentType: "application/x-ndjson",
|
|
53597
|
-
headers: {
|
|
54265
|
+
headers: {
|
|
54266
|
+
"cache-control": "no-store",
|
|
54267
|
+
"x-accel-buffering": "no"
|
|
54268
|
+
}
|
|
54269
|
+
});
|
|
54270
|
+
}).pipe(Effect.catch(failure$1)));
|
|
54271
|
+
const decodeDeviceRequest = Schema$1.decodeUnknownEffect(ComputerUseDeviceRequest);
|
|
54272
|
+
const device = HttpRouter.add("POST", "/internal/computer-use/device", Effect.gen(function* () {
|
|
54273
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
54274
|
+
const broker = yield* ComputerUseBroker;
|
|
54275
|
+
const execute = yield* makeComputerUseDevices();
|
|
54276
|
+
const input = yield* decodeDeviceRequest(yield* request.json);
|
|
54277
|
+
const result = yield* broker.device(bearer(request), input, (scope) => execute(scope, input.operation)).pipe(Effect.map((value) => ({
|
|
54278
|
+
ok: true,
|
|
54279
|
+
value
|
|
54280
|
+
})), Effect.catch((error) => Effect.succeed({
|
|
54281
|
+
ok: false,
|
|
54282
|
+
error
|
|
54283
|
+
})));
|
|
54284
|
+
return HttpServerResponse.jsonUnsafe({
|
|
54285
|
+
callId: input.callId,
|
|
54286
|
+
result
|
|
53598
54287
|
});
|
|
53599
54288
|
}).pipe(Effect.catch(failure$1)));
|
|
53600
54289
|
const respond = HttpRouter.add("POST", "/internal/computer-use/respond", Effect.gen(function* () {
|
|
@@ -53639,7 +54328,7 @@ const renew = HttpRouter.add("POST", "/internal/computer-use/renew", Effect.gen(
|
|
|
53639
54328
|
if (binding.trust) yield* (yield* RemoteComputerUseBindings).touch(bearer(request));
|
|
53640
54329
|
return HttpServerResponse.empty({ status: 204 });
|
|
53641
54330
|
}).pipe(Effect.catch(failure$1)));
|
|
53642
|
-
const layer$
|
|
54331
|
+
const layer$64 = Layer.mergeAll(exchange, hubForward, hubExchange, connect, respond, device, report, environment, renew).pipe(Layer.provide(remoteComputerUseBindingsLayer));
|
|
53643
54332
|
//#endregion
|
|
53644
54333
|
//#region src/device/DeviceHubSocketProtocol.ts
|
|
53645
54334
|
const MAX_DEVICE_INPUT_BYTES = 8 * 1024;
|
|
@@ -53852,94 +54541,6 @@ const bridgeDeviceSockets = Effect.fn("DeviceHubSocketBridge.bridge")(function*
|
|
|
53852
54541
|
}));
|
|
53853
54542
|
});
|
|
53854
54543
|
//#endregion
|
|
53855
|
-
//#region src/device/DeviceHubRoute.ts
|
|
53856
|
-
const DEVICE_HUB_PROXY_PREFIX = "/api/device-hub";
|
|
53857
|
-
const MAX_ROUTE_LENGTH = 16 * 1024;
|
|
53858
|
-
const MAX_TICKET_LENGTH = 2048;
|
|
53859
|
-
const decodeTarget = Schema$1.decodeUnknownSync(DeviceSessionDetailInput);
|
|
53860
|
-
const RESOURCES = [
|
|
53861
|
-
"video.avcc",
|
|
53862
|
-
"video.mjpeg",
|
|
53863
|
-
"socket",
|
|
53864
|
-
"screenshot",
|
|
53865
|
-
"ax",
|
|
53866
|
-
"foreground"
|
|
53867
|
-
];
|
|
53868
|
-
function segment(raw) {
|
|
53869
|
-
const value = decodeURIComponent(raw);
|
|
53870
|
-
if (!value || value === "." || value === ".." || /[%/\\\x00-\x1f\x7f]/.test(value) || encodeURIComponent(value) !== raw) throw new Error("Invalid device route segment.");
|
|
53871
|
-
return value;
|
|
53872
|
-
}
|
|
53873
|
-
/** Parse only P4 resources. Caller query parameters never reach the private hub. */
|
|
53874
|
-
function parseDeviceHubRoute(url, method, upgrade) {
|
|
53875
|
-
if (url.href.length > MAX_ROUTE_LENGTH || url.hash || method !== "GET") throw new Error("Invalid device route.");
|
|
53876
|
-
const parts = url.pathname.split("/");
|
|
53877
|
-
if (parts.length !== 10 || parts.slice(0, 3).join("/") !== "/api/device-hub" || parts[3] !== "thread" || parts[5] !== "host" || parts[7] !== "device") throw new Error("Invalid device route.");
|
|
53878
|
-
const resource = parts[9];
|
|
53879
|
-
if (!RESOURCES.some((value) => value === resource) || upgrade !== (resource === "socket")) throw new Error("Unsupported device resource.");
|
|
53880
|
-
const tickets = url.searchParams.getAll("wsTicket");
|
|
53881
|
-
if ([...url.searchParams.keys()].some((key) => key !== "wsTicket") || tickets.length > 1 || tickets.some((ticket) => !ticket || ticket.length > MAX_TICKET_LENGTH)) throw new Error("Invalid device query.");
|
|
53882
|
-
return {
|
|
53883
|
-
target: decodeTarget({
|
|
53884
|
-
threadId: segment(parts[4]),
|
|
53885
|
-
hostId: segment(parts[6]),
|
|
53886
|
-
deviceId: segment(parts[8])
|
|
53887
|
-
}),
|
|
53888
|
-
resource,
|
|
53889
|
-
requiredScope: resource === "socket" ? AuthOrchestrationOperateScope : AuthOrchestrationReadScope
|
|
53890
|
-
};
|
|
53891
|
-
}
|
|
53892
|
-
/** Resolve from the authoritative session, never from a caller-supplied upstream URL. */
|
|
53893
|
-
function resolveDeviceHubRoute(route, session, origin) {
|
|
53894
|
-
if (route.target.threadId !== session.threadId || route.target.hostId !== session.hostId || route.target.deviceId !== session.deviceId) throw new Error("Device session changed.");
|
|
53895
|
-
const hub = new URL(origin);
|
|
53896
|
-
if (hub.protocol !== "http:" || hub.hostname !== "127.0.0.1" || !hub.port || hub.username || hub.password || hub.pathname !== "/" || hub.search || hub.hash) throw new Error("Invalid owned device hub.");
|
|
53897
|
-
const device = encodeURIComponent(session.deviceId);
|
|
53898
|
-
let path;
|
|
53899
|
-
let method = "GET";
|
|
53900
|
-
if (session.platform === "ios") switch (route.resource) {
|
|
53901
|
-
case "video.avcc":
|
|
53902
|
-
path = `/vendor/serve-sim/helper/${device}/stream.avcc`;
|
|
53903
|
-
break;
|
|
53904
|
-
case "video.mjpeg":
|
|
53905
|
-
path = `/vendor/serve-sim/helper/${device}/stream.mjpeg`;
|
|
53906
|
-
break;
|
|
53907
|
-
case "socket":
|
|
53908
|
-
path = `/vendor/serve-sim/helper/ws?device=${device}`;
|
|
53909
|
-
break;
|
|
53910
|
-
case "screenshot":
|
|
53911
|
-
path = `/vendor/serve-sim/api/screenshot?device=${device}`;
|
|
53912
|
-
method = "POST";
|
|
53913
|
-
break;
|
|
53914
|
-
case "ax":
|
|
53915
|
-
path = `/vendor/serve-sim/helper/${device}/ax`;
|
|
53916
|
-
break;
|
|
53917
|
-
case "foreground":
|
|
53918
|
-
path = `/vendor/serve-sim/helper/${device}/foreground`;
|
|
53919
|
-
break;
|
|
53920
|
-
}
|
|
53921
|
-
else switch (route.resource) {
|
|
53922
|
-
case "socket":
|
|
53923
|
-
path = `/vendor/serve-emu/ws?device=${device}&frame-meta=1`;
|
|
53924
|
-
break;
|
|
53925
|
-
case "screenshot":
|
|
53926
|
-
path = `/vendor/serve-emu/api/screenshot?device=${device}`;
|
|
53927
|
-
method = "POST";
|
|
53928
|
-
break;
|
|
53929
|
-
case "ax":
|
|
53930
|
-
path = `/vendor/serve-emu/api/accessibility?device=${device}`;
|
|
53931
|
-
break;
|
|
53932
|
-
default: throw new Error("Device resource unavailable on this platform.");
|
|
53933
|
-
}
|
|
53934
|
-
const upstream = new URL(path, hub);
|
|
53935
|
-
if (route.resource === "socket") upstream.protocol = "ws:";
|
|
53936
|
-
return {
|
|
53937
|
-
url: upstream.href,
|
|
53938
|
-
method,
|
|
53939
|
-
streaming: route.resource === "video.avcc" || route.resource === "video.mjpeg" || route.resource === "socket"
|
|
53940
|
-
};
|
|
53941
|
-
}
|
|
53942
|
-
//#endregion
|
|
53943
54544
|
//#region src/device/DeviceHubNodeSocket.ts
|
|
53944
54545
|
const OPEN_TIMEOUT_MS = 1e4;
|
|
53945
54546
|
const MAX_UPGRADE_HEAD_BYTES = 32 * 8206;
|
|
@@ -55105,7 +55706,7 @@ const logP4ProjectFileLoadError = (error) => Effect.logWarning(error).pipe(Effec
|
|
|
55105
55706
|
filePath: error.filePath,
|
|
55106
55707
|
errorTag: error._tag
|
|
55107
55708
|
}));
|
|
55108
|
-
const make$
|
|
55709
|
+
const make$73 = Effect.gen(function* () {
|
|
55109
55710
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
55110
55711
|
const path = yield* Path$1.Path;
|
|
55111
55712
|
const load = Effect.fn("P4ProjectFileLoader.load")(function* (workspaceRoot) {
|
|
@@ -55126,7 +55727,7 @@ const make$75 = Effect.gen(function* () {
|
|
|
55126
55727
|
});
|
|
55127
55728
|
return P4ProjectFileLoader.of({ load });
|
|
55128
55729
|
});
|
|
55129
|
-
const layer$
|
|
55730
|
+
const layer$63 = Layer.effect(P4ProjectFileLoader, make$73);
|
|
55130
55731
|
//#endregion
|
|
55131
55732
|
//#region src/project/ProjectFaviconResolver.ts
|
|
55132
55733
|
/**
|
|
@@ -55201,7 +55802,7 @@ function extractIconHref(source) {
|
|
|
55201
55802
|
return null;
|
|
55202
55803
|
}
|
|
55203
55804
|
const optionOnNotFound$1 = (effect) => effect.pipe(Effect.map(Option.some), Effect.catchTags({ PlatformError: (error) => error.reason._tag === "NotFound" ? Effect.succeed(Option.none()) : Effect.fail(error) }));
|
|
55204
|
-
const make$
|
|
55805
|
+
const make$72 = Effect.gen(function* () {
|
|
55205
55806
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
55206
55807
|
const path = yield* Path$1.Path;
|
|
55207
55808
|
const workspacePaths = yield* WorkspacePaths;
|
|
@@ -55270,7 +55871,7 @@ const make$74 = Effect.gen(function* () {
|
|
|
55270
55871
|
});
|
|
55271
55872
|
return ProjectFaviconResolver.of({ resolvePath });
|
|
55272
55873
|
});
|
|
55273
|
-
const layer$
|
|
55874
|
+
const layer$62 = Layer.effect(ProjectFaviconResolver, make$72);
|
|
55274
55875
|
//#endregion
|
|
55275
55876
|
//#region src/assets/AssetAccess.ts
|
|
55276
55877
|
const ASSET_ROUTE_PREFIX = "/api/assets";
|
|
@@ -55681,10 +56282,10 @@ const resolveAsset = Effect.fn("AssetAccess.resolveAsset")(function* (token, rel
|
|
|
55681
56282
|
//#endregion
|
|
55682
56283
|
//#region src/observability/BrowserTraceCollector.ts
|
|
55683
56284
|
var BrowserTraceCollector = class extends Context.Service()("@p4code/cli/observability/BrowserTraceCollector") {};
|
|
55684
|
-
const make$
|
|
56285
|
+
const make$71 = (sink) => BrowserTraceCollector.of({ record: (records) => Effect.sync(() => {
|
|
55685
56286
|
for (const record of records) sink.push(record);
|
|
55686
56287
|
}) });
|
|
55687
|
-
const layer$
|
|
56288
|
+
const layer$61 = (sink) => Layer.succeed(BrowserTraceCollector, make$71(sink));
|
|
55688
56289
|
//#endregion
|
|
55689
56290
|
//#region src/auth/http.ts
|
|
55690
56291
|
const CREDENTIAL_RESPONSE_HEADERS = {
|
|
@@ -56826,7 +57427,7 @@ const defaultCancelTimeout = Duration.seconds(15);
|
|
|
56826
57427
|
const defaultSessionLoadTimeout = Duration.seconds(90);
|
|
56827
57428
|
const defaultSessionLoadReplayIdleGap = Duration.seconds(2);
|
|
56828
57429
|
var AcpSessionRuntime = class extends Context.Service()("@p4code/cli/provider/acp/AcpSessionRuntime") {};
|
|
56829
|
-
const make$
|
|
57430
|
+
const make$70 = (options) => Effect.gen(function* () {
|
|
56830
57431
|
const crypto = yield* Crypto.Crypto;
|
|
56831
57432
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
56832
57433
|
const runtimeScope = yield* Scope.Scope;
|
|
@@ -57230,7 +57831,7 @@ const make$72 = (options) => Effect.gen(function* () {
|
|
|
57230
57831
|
notify: acp.raw.notify
|
|
57231
57832
|
};
|
|
57232
57833
|
});
|
|
57233
|
-
const layer$
|
|
57834
|
+
const layer$60 = (options) => Layer.effect(AcpSessionRuntime, make$70(options));
|
|
57234
57835
|
function sessionConfigOptionsFromSetup(response) {
|
|
57235
57836
|
return response?.configOptions ?? [];
|
|
57236
57837
|
}
|
|
@@ -57624,7 +58225,7 @@ const buildAntigravityPrompt = Effect.fn("buildAntigravityPrompt")(function* (in
|
|
|
57624
58225
|
});
|
|
57625
58226
|
/** Normal launches reject browser login; only the auth flow supplies `onAuthorizationUrl`. */
|
|
57626
58227
|
const makeAntigravityAcpRuntime = Effect.fn("makeAntigravityAcpRuntime")(function* (input) {
|
|
57627
|
-
const context = yield* Layer.build(layer$
|
|
58228
|
+
const context = yield* Layer.build(layer$60({
|
|
57628
58229
|
...input,
|
|
57629
58230
|
authMethodId: input.authMethod ?? "oauth-personal",
|
|
57630
58231
|
resumeMethod: "resume",
|
|
@@ -60363,7 +60964,7 @@ const makeAntigravityProvider = Effect.fn("makeAntigravityProvider")(function* (
|
|
|
60363
60964
|
status: "unknown",
|
|
60364
60965
|
...options.auth ? { type: options.auth.type } : {}
|
|
60365
60966
|
},
|
|
60366
|
-
message: settings.enabled ? "Checking Antigravity availability." : "Antigravity is disabled in
|
|
60967
|
+
message: settings.enabled ? "Checking Antigravity availability." : "Antigravity is disabled in P4 Code settings."
|
|
60367
60968
|
}
|
|
60368
60969
|
}),
|
|
60369
60970
|
setup: {
|
|
@@ -61601,7 +62202,7 @@ const BundledOnlyModelManifest = {
|
|
|
61601
62202
|
refreshInBackground: Effect.void
|
|
61602
62203
|
};
|
|
61603
62204
|
Layer.succeed(ModelManifest, BundledOnlyModelManifest);
|
|
61604
|
-
const make$
|
|
62205
|
+
const make$69 = Effect.gen(function* () {
|
|
61605
62206
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
61606
62207
|
const path = yield* Path$1.Path;
|
|
61607
62208
|
const config = yield* ServerConfig$1;
|
|
@@ -61646,7 +62247,7 @@ const make$71 = Effect.gen(function* () {
|
|
|
61646
62247
|
refreshInBackground: Effect.forkIn(guardedRefresh, serviceScope).pipe(Effect.asVoid)
|
|
61647
62248
|
});
|
|
61648
62249
|
});
|
|
61649
|
-
const layer$
|
|
62250
|
+
const layer$59 = Layer.effect(ModelManifest, make$69);
|
|
61650
62251
|
//#endregion
|
|
61651
62252
|
//#region src/provider/ProviderDriver.ts
|
|
61652
62253
|
function defaultProviderContinuationIdentity(input) {
|
|
@@ -61906,11 +62507,11 @@ const makeTextGenerationFromRegistry = (registry) => TextGeneration.of({
|
|
|
61906
62507
|
detail: "This provider does not report account usage."
|
|
61907
62508
|
}))))
|
|
61908
62509
|
});
|
|
61909
|
-
const make$
|
|
62510
|
+
const make$68 = Effect.gen(function* () {
|
|
61910
62511
|
const registry = yield* ProviderInstanceRegistry;
|
|
61911
62512
|
return makeTextGenerationFromRegistry(registry);
|
|
61912
62513
|
});
|
|
61913
|
-
const layer$
|
|
62514
|
+
const layer$58 = Layer.effect(TextGeneration, make$68);
|
|
61914
62515
|
//#endregion
|
|
61915
62516
|
//#region src/provider/Layers/claudeUsageLimits.ts
|
|
61916
62517
|
const SESSION_MINS$1 = 300;
|
|
@@ -62984,7 +63585,7 @@ const checkClaudeProviderStatus = Effect.fn("checkClaudeProviderStatus")(functio
|
|
|
62984
63585
|
version: null,
|
|
62985
63586
|
status: "warning",
|
|
62986
63587
|
auth: { status: "unknown" },
|
|
62987
|
-
message: "Claude is disabled in
|
|
63588
|
+
message: "Claude is disabled in P4 Code settings."
|
|
62988
63589
|
}
|
|
62989
63590
|
});
|
|
62990
63591
|
const versionProbe = yield* runClaudeCommand(claudeSettings, ["--version"], resolvedEnvironment).pipe(Effect.timeoutOption(DEFAULT_TIMEOUT_MS$5), Effect.result);
|
|
@@ -63102,7 +63703,7 @@ const makePendingClaudeProvider = (claudeSettings) => Effect.gen(function* () {
|
|
|
63102
63703
|
version: null,
|
|
63103
63704
|
status: "warning",
|
|
63104
63705
|
auth: { status: "unknown" },
|
|
63105
|
-
message: "Claude is disabled in
|
|
63706
|
+
message: "Claude is disabled in P4 Code settings."
|
|
63106
63707
|
}
|
|
63107
63708
|
});
|
|
63108
63709
|
return buildServerProvider({
|
|
@@ -63568,13 +64169,24 @@ function formatAskUserQuestionAnswers(answers) {
|
|
|
63568
64169
|
*
|
|
63569
64170
|
* They travel through the provider's session channel - Claude's system prompt
|
|
63570
64171
|
* append, Codex's per-turn developer instructions - rather than as a prefix on
|
|
63571
|
-
* every message.
|
|
63572
|
-
*
|
|
63573
|
-
*
|
|
64172
|
+
* every message. Each resolved block runs to roughly a thousand tokens and
|
|
64173
|
+
* grows as the protocol does, so a message-level copy would sit in the
|
|
64174
|
+
* conversation history for the rest of the thread, be re-read on every later
|
|
64175
|
+
* API call, and be lost at compaction anyway. The session channel is
|
|
63574
64176
|
* cached, never accumulates, and survives compaction. Messages then carry
|
|
63575
64177
|
* only a one-line reference and the mutable `[fusion-pair]` metadata.
|
|
63576
64178
|
*/
|
|
63577
|
-
|
|
64179
|
+
/**
|
|
64180
|
+
* The half of the protocol both roles share: how a pair message is written.
|
|
64181
|
+
*
|
|
64182
|
+
* The transport already carries the thread's compression mode - a Fusion child
|
|
64183
|
+
* inherits the composer's mode at creation, and `thread_advise` starts the
|
|
64184
|
+
* builder turn under the builder thread's stored mode - but neither role block
|
|
64185
|
+
* said that pair traffic is subject to it, so phase reports and advice were
|
|
64186
|
+
* written as if the setting applied only to user-facing answers.
|
|
64187
|
+
*/
|
|
64188
|
+
const FUSION_PAIR_COMMUNICATION_INSTRUCTIONS = `Everything you send the other half of the pair obeys the thread's active response-compression mode, exactly as a user-facing answer does: phase reports, advice, reviews, questions, and handoffs. When the mode is off, write normal prose. Compression governs form only - never drop a requirement, a negation, a number or unit, a file, symbol, or command name, code, security or warning text, the evidence behind a claim, or an exact protocol heading or token in order to save words.`;
|
|
64189
|
+
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. ${FUSION_PAIR_COMMUNICATION_INSTRUCTIONS}`;
|
|
63578
64190
|
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. Structure every actionable supervisor advice message with these Markdown headings, in order:
|
|
63579
64191
|
## Recommendation
|
|
63580
64192
|
State the decision or correction in one sentence. For a phase review, say whether the phase is approved or needs changes.
|
|
@@ -63582,7 +64194,7 @@ State the decision or correction in one sentence. For a phase review, say whethe
|
|
|
63582
64194
|
Give concise evidence, relevant file/line references, and any unresolved risk. Distinguish observed facts from assumptions; do not claim checks you did not run.
|
|
63583
64195
|
## Next step
|
|
63584
64196
|
Give ordered, concrete actions for the builder, including the next phase and its completion condition. Preserve user requirements, constraints, and delivery authorization. Keep each section short; omit empty bullets and repeated status. Formatting does not authorize an otherwise unnecessary advice turn or replace an exact protocol response.`;
|
|
63585
|
-
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:
|
|
64197
|
+
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, and its first turn is research, not relay. Research it: when the request names a ticket, read that ticket AND its comments, including replies and inline comments, and treat a later comment as newer intent than the description; read the code, docs, project instructions, and current state the request touches. Analyse what you found: root cause or the concrete design constraint, scope, what the user actually wants delivered, and which delivery steps they authorized. Only then direct the first actionable phase to the idle builder through thread_advise, stating the findings that make the direction actionable alongside the original requirements, constraints, and authorized delivery scope. Never echo the request back as its own direction, never hand over a plan you did not ground in evidence, and never send ${FUSION_NO_OBJECTION_TEXT} before the builder has received its first phase and produced a turn to review. 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. ${FUSION_PAIR_COMMUNICATION_INSTRUCTIONS}`;
|
|
63586
64198
|
/**
|
|
63587
64199
|
* The one-line stand-in for the full block on a message whose session already
|
|
63588
64200
|
* carries the role instructions.
|
|
@@ -83861,7 +84473,7 @@ const V2TurnStartParams__CollaborationMode = Schema$1.Struct({
|
|
|
83861
84473
|
mode: V2TurnStartParams__ModeKind,
|
|
83862
84474
|
settings: V2TurnStartParams__Settings
|
|
83863
84475
|
}).annotate({ description: "Collaboration mode for a Codex session." });
|
|
83864
|
-
Schema$1.Union([Schema$1.Literals(["explicitRequestOnly", "proactive"]), Schema$1.Struct({ custom: Schema$1.String }).annotate({ title: "CustomMultiAgentMode" })], { mode: "oneOf" }).annotate({ description: "Controls the effective multi-agent delegation instructions for a turn. `custom` means the configured mode hint defines the policy instead of a built-in policy." });
|
|
84476
|
+
const V2TurnStartParams__MultiAgentMode = Schema$1.Union([Schema$1.Literals(["explicitRequestOnly", "proactive"]), Schema$1.Struct({ custom: Schema$1.String }).annotate({ title: "CustomMultiAgentMode" })], { mode: "oneOf" }).annotate({ description: "Controls the effective multi-agent delegation instructions for a turn. `custom` means the configured mode hint defines the policy instead of a built-in policy." });
|
|
83865
84477
|
Schema$1.Literals(["restricted", "enabled"]);
|
|
83866
84478
|
Schema$1.Struct({
|
|
83867
84479
|
cwd: V2TurnStartParams__LegacyAppPathString,
|
|
@@ -84842,7 +85454,7 @@ const makeTerminationError = (handle) => Effect.match(handle.exitCode, {
|
|
|
84842
85454
|
//#endregion
|
|
84843
85455
|
//#region ../../packages/effect-codex-app-server/src/client.ts
|
|
84844
85456
|
var CodexAppServerClient = class extends Context.Service()("effect-codex-app-server/client/CodexAppServerClient") {};
|
|
84845
|
-
const make$
|
|
85457
|
+
const make$67 = Effect.fn("effect-codex-app-server/CodexAppServerClient.make")(function* (stdio, options = {}, terminationError) {
|
|
84846
85458
|
const requestHandlers = /* @__PURE__ */ new Map();
|
|
84847
85459
|
const notificationHandlers = /* @__PURE__ */ new Map();
|
|
84848
85460
|
let unknownRequestHandler;
|
|
@@ -84909,7 +85521,7 @@ const make$69 = Effect.fn("effect-codex-app-server/CodexAppServerClient.make")(f
|
|
|
84909
85521
|
const layerChildProcess = (handle, options = {}) => Layer.effect(CodexAppServerClient, makeChildProcessClient(handle, options));
|
|
84910
85522
|
const makeChildProcessClient = Effect.fn("effect-codex-app-server/CodexAppServerClient.makeChildProcessClient")(function* (handle, options) {
|
|
84911
85523
|
yield* Stream.runDrain(handle.stderr).pipe(Effect.ignore, Effect.forkScoped);
|
|
84912
|
-
return yield* make$
|
|
85524
|
+
return yield* make$67(makeChildStdio(handle), options, makeTerminationError(handle));
|
|
84913
85525
|
});
|
|
84914
85526
|
const resolveCodexLaunchArgs = (launchArgs, environment = process.env) => environment["P4CODE_CODEX_LAUNCH_ARGS"]?.trim() || launchArgs?.trim() || "";
|
|
84915
85527
|
const codexLaunchArgv = (launchArgs) => tokenizeCliArgs(launchArgs);
|
|
@@ -85205,7 +85817,7 @@ function buildCodexInitializeParams() {
|
|
|
85205
85817
|
return {
|
|
85206
85818
|
clientInfo: {
|
|
85207
85819
|
name: "p4code_desktop",
|
|
85208
|
-
title: "
|
|
85820
|
+
title: "P4 Code Desktop",
|
|
85209
85821
|
version: version$1
|
|
85210
85822
|
},
|
|
85211
85823
|
capabilities: { experimentalApi: true }
|
|
@@ -85237,7 +85849,7 @@ const probeCodexAppServerProvider = Effect.fn("probeCodexAppServerProvider")(fun
|
|
|
85237
85849
|
const initialize = yield* client.request("initialize", {
|
|
85238
85850
|
clientInfo: {
|
|
85239
85851
|
name: "p4code_desktop",
|
|
85240
|
-
title: "
|
|
85852
|
+
title: "P4 Code Desktop",
|
|
85241
85853
|
version: "0.1.0"
|
|
85242
85854
|
},
|
|
85243
85855
|
capabilities: { experimentalApi: true }
|
|
@@ -85294,7 +85906,7 @@ const makePendingCodexProvider = (codexSettings) => Effect.gen(function* () {
|
|
|
85294
85906
|
version: null,
|
|
85295
85907
|
status: "warning",
|
|
85296
85908
|
auth: { status: "unknown" },
|
|
85297
|
-
message: "Codex is disabled in
|
|
85909
|
+
message: "Codex is disabled in P4 Code settings."
|
|
85298
85910
|
}
|
|
85299
85911
|
});
|
|
85300
85912
|
return buildServerProvider({
|
|
@@ -85350,7 +85962,7 @@ const checkCodexProviderStatus = Effect.fn("checkCodexProviderStatus")(function*
|
|
|
85350
85962
|
version: null,
|
|
85351
85963
|
status: "warning",
|
|
85352
85964
|
auth: { status: "unknown" },
|
|
85353
|
-
message: "Codex is disabled in
|
|
85965
|
+
message: "Codex is disabled in P4 Code settings."
|
|
85354
85966
|
}
|
|
85355
85967
|
});
|
|
85356
85968
|
const probeResult = yield* probe({
|
|
@@ -86110,7 +86722,10 @@ const CodexResumeCursorSchema = Schema$1.Struct({ threadId: Schema$1.String });
|
|
|
86110
86722
|
const CodexUserInputAnswerObject = Schema$1.Struct({ answers: Schema$1.Array(Schema$1.String) });
|
|
86111
86723
|
const isCodexResumeCursorSchema$1 = Schema$1.is(CodexResumeCursorSchema);
|
|
86112
86724
|
const isCodexUserInputAnswerObject = Schema$1.is(CodexUserInputAnswerObject);
|
|
86113
|
-
const CodexTurnStartParamsWithCollaborationMode = V2TurnStartParams.pipe(Schema$1.fieldsAssign({
|
|
86725
|
+
const CodexTurnStartParamsWithCollaborationMode = V2TurnStartParams.pipe(Schema$1.fieldsAssign({
|
|
86726
|
+
collaborationMode: Schema$1.optionalKey(V2TurnStartParams__CollaborationMode),
|
|
86727
|
+
multiAgentMode: Schema$1.optionalKey(V2TurnStartParams__MultiAgentMode)
|
|
86728
|
+
}));
|
|
86114
86729
|
const decodeCodexTurnStartParamsWithCollaborationMode = Schema$1.decodeUnknownEffect(CodexTurnStartParamsWithCollaborationMode);
|
|
86115
86730
|
var CodexSessionRuntimePendingApprovalNotFoundError = class extends Schema$1.TaggedErrorClass()("CodexSessionRuntimePendingApprovalNotFoundError", { requestId: Schema$1.String }) {
|
|
86116
86731
|
get message() {
|
|
@@ -86236,6 +86851,7 @@ function buildTurnStartParams(input) {
|
|
|
86236
86851
|
...input.model ? { model: input.model } : {},
|
|
86237
86852
|
...input.serviceTier ? { serviceTier: input.serviceTier } : {},
|
|
86238
86853
|
...input.effort ? { effort: input.effort } : {},
|
|
86854
|
+
...input.unpromptedSubagents !== void 0 ? { multiAgentMode: input.unpromptedSubagents ? "proactive" : "explicitRequestOnly" } : {},
|
|
86239
86855
|
...collaborationMode ? { collaborationMode } : {}
|
|
86240
86856
|
}).pipe(compressRulesetUndeliverable ? Effect.tap(() => Effect.logWarning("codex.turn.compress-ruleset-undeliverable", {
|
|
86241
86857
|
threadId: input.threadId,
|
|
@@ -86811,7 +87427,8 @@ const makeCodexSessionRuntime = (options) => Effect.gen(function* () {
|
|
|
86811
87427
|
...input.effort ? { effort: input.effort } : {},
|
|
86812
87428
|
...input.interactionMode ? { interactionMode: input.interactionMode } : {},
|
|
86813
87429
|
...input.compressMode ? { compressMode: input.compressMode } : {},
|
|
86814
|
-
...options.guardrailPrompts ? { guardrailPrompts: options.guardrailPrompts } : {}
|
|
87430
|
+
...options.guardrailPrompts ? { guardrailPrompts: options.guardrailPrompts } : {},
|
|
87431
|
+
...input.unpromptedSubagents !== void 0 ? { unpromptedSubagents: input.unpromptedSubagents } : {}
|
|
86815
87432
|
});
|
|
86816
87433
|
const { collaborationMode: attachedCollaborationMode, ...paramsWithoutCollaboration } = params;
|
|
86817
87434
|
const lastCollaborationMode = yield* Ref.get(lastCollaborationModeRef);
|
|
@@ -87992,6 +88609,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
87992
88609
|
...input.interactionMode !== void 0 ? { interactionMode: input.interactionMode } : {},
|
|
87993
88610
|
...input.compressMode !== void 0 ? { compressMode: input.compressMode } : {},
|
|
87994
88611
|
...input.fusionRole !== void 0 ? { fusionRole: input.fusionRole } : {},
|
|
88612
|
+
...input.unpromptedSubagents !== void 0 ? { unpromptedSubagents: input.unpromptedSubagents } : {},
|
|
87995
88613
|
...codexAttachments.length > 0 ? { attachments: codexAttachments } : {}
|
|
87996
88614
|
}).pipe(Effect.mapError((cause) => mapCodexRuntimeError(input.threadId, "turn/start", cause)));
|
|
87997
88615
|
});
|
|
@@ -88562,7 +89180,7 @@ const CURSOR_PARAMETERIZED_MODEL_PICKER_MIN_VERSION_DATE = 20260408;
|
|
|
88562
89180
|
const CURSOR_CLI_INSTALLATION_DOCS_URL = "https://cursor.com/docs/cli/installation";
|
|
88563
89181
|
const CURSOR_ACP_MODEL_DISCOVERY_FAILED_MESSAGE = [
|
|
88564
89182
|
"Cursor ACP model discovery failed.",
|
|
88565
|
-
"Cursor CLI setup may be incomplete; install or enable the Cursor CLI, restart
|
|
89183
|
+
"Cursor CLI setup may be incomplete; install or enable the Cursor CLI, restart P4 Code, and try again.",
|
|
88566
89184
|
`See ${CURSOR_CLI_INSTALLATION_DOCS_URL}.`,
|
|
88567
89185
|
"Check server logs for ACP details."
|
|
88568
89186
|
].join(" ");
|
|
@@ -88581,7 +89199,7 @@ function buildInitialCursorProviderSnapshot(cursorSettings) {
|
|
|
88581
89199
|
version: null,
|
|
88582
89200
|
status: "warning",
|
|
88583
89201
|
auth: { status: "unknown" },
|
|
88584
|
-
message: "Cursor is disabled in
|
|
89202
|
+
message: "Cursor is disabled in P4 Code settings."
|
|
88585
89203
|
}
|
|
88586
89204
|
});
|
|
88587
89205
|
return buildServerProvider({
|
|
@@ -88747,7 +89365,7 @@ function buildCursorDiscoveredModelsFromAvailableModelsResponse(response) {
|
|
|
88747
89365
|
}
|
|
88748
89366
|
const makeCursorAcpProbeRuntime = (cursorSettings, environment) => Effect.gen(function* () {
|
|
88749
89367
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
88750
|
-
const acpContext = yield* Layer.build(layer$
|
|
89368
|
+
const acpContext = yield* Layer.build(layer$60({
|
|
88751
89369
|
spawn: {
|
|
88752
89370
|
command: cursorSettings.binaryPath,
|
|
88753
89371
|
args: [...cursorSettings.apiEndpoint ? ["-e", cursorSettings.apiEndpoint] : [], "acp"],
|
|
@@ -88859,7 +89477,7 @@ function joinProviderMessages(...messages) {
|
|
|
88859
89477
|
function buildCursorCliCommandMissingMessage(binaryPath) {
|
|
88860
89478
|
return [
|
|
88861
89479
|
`Cursor CLI command \`${binaryPath}\` was not found.`,
|
|
88862
|
-
`Install or enable the Cursor CLI, make sure \`${binaryPath}\` is on PATH, then restart
|
|
89480
|
+
`Install or enable the Cursor CLI, make sure \`${binaryPath}\` is on PATH, then restart P4 Code.`,
|
|
88863
89481
|
`See ${CURSOR_CLI_INSTALLATION_DOCS_URL}.`
|
|
88864
89482
|
].join(" ");
|
|
88865
89483
|
}
|
|
@@ -89099,7 +89717,7 @@ const checkCursorProviderStatus = Effect.fn("checkCursorProviderStatus")(functio
|
|
|
89099
89717
|
version: null,
|
|
89100
89718
|
status: "warning",
|
|
89101
89719
|
auth: { status: "unknown" },
|
|
89102
|
-
message: "Cursor is disabled in
|
|
89720
|
+
message: "Cursor is disabled in P4 Code settings."
|
|
89103
89721
|
}
|
|
89104
89722
|
});
|
|
89105
89723
|
const aboutProbe = yield* runCursorAboutCommand(cursorSettings, environment).pipe(Effect.timeoutOption(ABOUT_TIMEOUT_MS), Effect.result);
|
|
@@ -89197,7 +89815,7 @@ function buildCursorAcpSpawnInput(cursorSettings, cwd, environment) {
|
|
|
89197
89815
|
};
|
|
89198
89816
|
}
|
|
89199
89817
|
const makeCursorAcpRuntime = (input) => Effect.gen(function* () {
|
|
89200
|
-
const acpContext = yield* Layer.build(layer$
|
|
89818
|
+
const acpContext = yield* Layer.build(layer$60({
|
|
89201
89819
|
...input,
|
|
89202
89820
|
spawn: buildCursorAcpSpawnInput(input.cursorSettings, input.cwd, input.environment),
|
|
89203
89821
|
authMethodId: "cursor_login",
|
|
@@ -90390,7 +91008,7 @@ function resolveGrokAuthMethodId(environment) {
|
|
|
90390
91008
|
return environment?.[GROK_API_KEY_ENV]?.trim() ? GROK_AUTH_METHOD_API_KEY : GROK_AUTH_METHOD_CACHED_TOKEN;
|
|
90391
91009
|
}
|
|
90392
91010
|
const makeGrokAcpRuntime = (input) => Effect.gen(function* () {
|
|
90393
|
-
const acpContext = yield* Layer.build(layer$
|
|
91011
|
+
const acpContext = yield* Layer.build(layer$60({
|
|
90394
91012
|
...input,
|
|
90395
91013
|
spawn: buildGrokAcpSpawnInput(input.grokSettings, input.cwd, input.environment),
|
|
90396
91014
|
authMethodId: resolveGrokAuthMethodId(input.environment)
|
|
@@ -91457,7 +92075,7 @@ function buildInitialGrokProviderSnapshot(grokSettings) {
|
|
|
91457
92075
|
version: null,
|
|
91458
92076
|
status: "warning",
|
|
91459
92077
|
auth: { status: "unknown" },
|
|
91460
|
-
message: "Grok is disabled in
|
|
92078
|
+
message: "Grok is disabled in P4 Code settings."
|
|
91461
92079
|
}
|
|
91462
92080
|
});
|
|
91463
92081
|
return buildServerProvider({
|
|
@@ -91526,7 +92144,7 @@ const checkGrokProviderStatus = Effect.fn("checkGrokProviderStatus")(function* (
|
|
|
91526
92144
|
version: null,
|
|
91527
92145
|
status: "warning",
|
|
91528
92146
|
auth: { status: "unknown" },
|
|
91529
|
-
message: "Grok is disabled in
|
|
92147
|
+
message: "Grok is disabled in P4 Code settings."
|
|
91530
92148
|
}
|
|
91531
92149
|
});
|
|
91532
92150
|
const versionResult = yield* runGrokVersionCommand(grokSettings, environment).pipe(Effect.timeoutOption(VERSION_PROBE_TIMEOUT_MS$1), Effect.result);
|
|
@@ -93186,7 +93804,7 @@ function buildInitialMuseProviderSnapshot(museSettings) {
|
|
|
93186
93804
|
version: null,
|
|
93187
93805
|
status: "warning",
|
|
93188
93806
|
auth: { status: "unknown" },
|
|
93189
|
-
message: "Muse Code is disabled in
|
|
93807
|
+
message: "Muse Code is disabled in P4 Code settings."
|
|
93190
93808
|
}
|
|
93191
93809
|
});
|
|
93192
93810
|
});
|
|
@@ -93212,7 +93830,7 @@ const checkMuseProviderStatus = Effect.fn("checkMuseProviderStatus")(function* (
|
|
|
93212
93830
|
version: null,
|
|
93213
93831
|
status: "warning",
|
|
93214
93832
|
auth: { status: "unknown" },
|
|
93215
|
-
message: "Muse Code is disabled in
|
|
93833
|
+
message: "Muse Code is disabled in P4 Code settings."
|
|
93216
93834
|
}
|
|
93217
93835
|
});
|
|
93218
93836
|
const versionResult = yield* runMuseVersionCommand(museSettings, environment).pipe(Effect.timeoutOption(VERSION_PROBE_TIMEOUT_MS), Effect.result);
|
|
@@ -94024,7 +94642,7 @@ const makeOpenCodeTextGeneration = Effect.fn("makeOpenCodeTextGeneration")(funct
|
|
|
94024
94642
|
});
|
|
94025
94643
|
const session = yield* Effect.tryPromise({
|
|
94026
94644
|
try: () => client.session.create({
|
|
94027
|
-
title: `
|
|
94645
|
+
title: `P4 Code ${input.operation}`,
|
|
94028
94646
|
permission: [{
|
|
94029
94647
|
permission: "*",
|
|
94030
94648
|
pattern: "*",
|
|
@@ -95410,7 +96028,7 @@ const makePendingOpenCodeProvider = (openCodeSettings) => Effect.gen(function* (
|
|
|
95410
96028
|
version: null,
|
|
95411
96029
|
status: "warning",
|
|
95412
96030
|
auth: { status: "unknown" },
|
|
95413
|
-
message: openCodeSettings.serverUrl.trim().length > 0 ? "OpenCode is disabled in
|
|
96031
|
+
message: openCodeSettings.serverUrl.trim().length > 0 ? "OpenCode is disabled in P4 Code settings. A server URL is configured." : "OpenCode is disabled in P4 Code settings."
|
|
95414
96032
|
}
|
|
95415
96033
|
});
|
|
95416
96034
|
return buildServerProvider({
|
|
@@ -95463,7 +96081,7 @@ const checkOpenCodeProviderStatus = Effect.fn("checkOpenCodeProviderStatus")(fun
|
|
|
95463
96081
|
version: null,
|
|
95464
96082
|
status: "warning",
|
|
95465
96083
|
auth: { status: "unknown" },
|
|
95466
|
-
message: isExternalServer ? "OpenCode is disabled in
|
|
96084
|
+
message: isExternalServer ? "OpenCode is disabled in P4 Code settings. A server URL is configured." : "OpenCode is disabled in P4 Code settings."
|
|
95467
96085
|
}
|
|
95468
96086
|
});
|
|
95469
96087
|
let version = null;
|
|
@@ -95478,7 +96096,7 @@ const checkOpenCodeProviderStatus = Effect.fn("checkOpenCodeProviderStatus")(fun
|
|
|
95478
96096
|
}))));
|
|
95479
96097
|
if (versionExit._tag === "Failure") return fallback(Cause.squash(versionExit.cause));
|
|
95480
96098
|
version = parseGenericCliVersion(versionExit.value.stdout) ?? null;
|
|
95481
|
-
if (!version) return fallback(/* @__PURE__ */ new Error(`Unable to determine OpenCode version from \`opencode --version\` output.
|
|
96099
|
+
if (!version) return fallback(/* @__PURE__ */ new Error(`Unable to determine OpenCode version from \`opencode --version\` output. P4 Code requires OpenCode v${MINIMUM_OPENCODE_VERSION} or newer.`), null);
|
|
95482
96100
|
if (compareSemverVersions(version, MINIMUM_OPENCODE_VERSION) < 0) return buildServerProvider({
|
|
95483
96101
|
presentation: OPENCODE_PRESENTATION,
|
|
95484
96102
|
enabled: openCodeSettings.enabled,
|
|
@@ -96131,7 +96749,7 @@ const makeProviderInstallation = Effect.fn("makeProviderInstallation")(function*
|
|
|
96131
96749
|
})))).binaryPath) return yield* new ProviderSetupError({
|
|
96132
96750
|
instanceId,
|
|
96133
96751
|
operation,
|
|
96134
|
-
detail: "This instance uses a custom executable. Clear its binary path to manage installation in
|
|
96752
|
+
detail: "This instance uses a custom executable. Clear its binary path to manage installation in P4 Code."
|
|
96135
96753
|
});
|
|
96136
96754
|
});
|
|
96137
96755
|
const failure = (instanceId) => (error) => new ProviderSetupError({
|
|
@@ -96169,7 +96787,7 @@ const makeProviderInstallation = Effect.fn("makeProviderInstallation")(function*
|
|
|
96169
96787
|
});
|
|
96170
96788
|
//#endregion
|
|
96171
96789
|
//#region src/usage/usageSourceHttp.ts
|
|
96172
|
-
const MAX_RESPONSE_BYTES$
|
|
96790
|
+
const MAX_RESPONSE_BYTES$1 = 1024 * 1024;
|
|
96173
96791
|
const LOOPBACK_HOSTS$1 = /* @__PURE__ */ new Set([
|
|
96174
96792
|
"localhost",
|
|
96175
96793
|
"127.0.0.1",
|
|
@@ -96202,7 +96820,7 @@ async function readManagementJson(config, path, body, signal) {
|
|
|
96202
96820
|
const chunk = await reader.read();
|
|
96203
96821
|
if (chunk.done) break;
|
|
96204
96822
|
total += chunk.value.byteLength;
|
|
96205
|
-
if (total > MAX_RESPONSE_BYTES$
|
|
96823
|
+
if (total > MAX_RESPONSE_BYTES$1) throw new Error("Usage source response too large");
|
|
96206
96824
|
chunks.push(chunk.value);
|
|
96207
96825
|
}
|
|
96208
96826
|
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
@@ -96439,8 +97057,8 @@ const makeWithReader = (api) => Effect.gen(function* () {
|
|
|
96439
97057
|
}))
|
|
96440
97058
|
};
|
|
96441
97059
|
});
|
|
96442
|
-
const make$
|
|
96443
|
-
const layer$
|
|
97060
|
+
const make$66 = makeCliproxyApi.pipe(Effect.flatMap(makeWithReader));
|
|
97061
|
+
const layer$57 = Layer.effect(UsageLimitSources, make$66);
|
|
96444
97062
|
//#endregion
|
|
96445
97063
|
//#region src/resourceTelemetry/HostResources.ts
|
|
96446
97064
|
const CPU_SAMPLE_INTERVAL = "200 millis";
|
|
@@ -96475,7 +97093,7 @@ function darwinAvailableMemory(output) {
|
|
|
96475
97093
|
const available = (Number(free) + Number(inactive) + Number(speculative)) * Number(pageSize);
|
|
96476
97094
|
return Number.isSafeInteger(available) && Number(pageSize) > 0 ? available : null;
|
|
96477
97095
|
}
|
|
96478
|
-
const make$
|
|
97096
|
+
const make$65 = Effect.fn("makeHostResources")(function* () {
|
|
96479
97097
|
const fs = yield* FileSystem.FileSystem;
|
|
96480
97098
|
const platform = yield* HostProcessPlatform;
|
|
96481
97099
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
@@ -96509,7 +97127,7 @@ const make$67 = Effect.fn("makeHostResources")(function* () {
|
|
|
96509
97127
|
});
|
|
96510
97128
|
return HostResources.of({ read: Cache.get(cache, "host") });
|
|
96511
97129
|
});
|
|
96512
|
-
const layer$
|
|
97130
|
+
const layer$56 = Layer.effect(HostResources, make$65());
|
|
96513
97131
|
//#endregion
|
|
96514
97132
|
//#region src/resourceTelemetry/DesktopTelemetryReceiver.ts
|
|
96515
97133
|
const INITIAL_SAMPLE_DEADLINE_MS = 9e4;
|
|
@@ -96644,7 +97262,7 @@ function requireDesktopTelemetryWriteProgress(fd, remainingBytes, written) {
|
|
|
96644
97262
|
}));
|
|
96645
97263
|
}
|
|
96646
97264
|
/** @public Service construction is part of the canonical Effect module API. */
|
|
96647
|
-
const make$
|
|
97265
|
+
const make$64 = Effect.fn("resourceTelemetry.desktopTelemetryReceiver.make")(function* () {
|
|
96648
97266
|
const serverConfig = yield* ServerConfig$1;
|
|
96649
97267
|
const hasDescriptors = serverConfig.mode === "desktop" && serverConfig.desktopTelemetryFd === 4 && serverConfig.desktopTelemetryControlFd === 5;
|
|
96650
97268
|
const config = {
|
|
@@ -96801,7 +97419,7 @@ const make$66 = Effect.fn("resourceTelemetry.desktopTelemetryReceiver.make")(fun
|
|
|
96801
97419
|
setDiagnosticsDemand
|
|
96802
97420
|
});
|
|
96803
97421
|
});
|
|
96804
|
-
const layer$
|
|
97422
|
+
const layer$55 = Layer.effect(DesktopTelemetryReceiver, make$64());
|
|
96805
97423
|
//#endregion
|
|
96806
97424
|
//#region src/resourceTelemetry/Model.ts
|
|
96807
97425
|
const MAX_DELTA_INTERVAL_MS = 3e4;
|
|
@@ -97226,7 +97844,7 @@ function resourceMonitorRustTarget(platform, architecture, linuxLibc) {
|
|
|
97226
97844
|
}
|
|
97227
97845
|
if (platform === "win32") return architecture === "arm64" ? "aarch64-pc-windows-msvc" : architecture === "x64" ? "x86_64-pc-windows-msvc" : void 0;
|
|
97228
97846
|
}
|
|
97229
|
-
const make$
|
|
97847
|
+
const make$63 = Effect.fn("resourceTelemetry.resourceMonitorBinary.make")(function* () {
|
|
97230
97848
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
97231
97849
|
const path = yield* Path$1.Path;
|
|
97232
97850
|
const platform = yield* HostProcessPlatform;
|
|
@@ -97272,7 +97890,7 @@ const make$65 = Effect.fn("resourceTelemetry.resourceMonitorBinary.make")(functi
|
|
|
97272
97890
|
});
|
|
97273
97891
|
return ResourceMonitorBinary.of({ resolve });
|
|
97274
97892
|
});
|
|
97275
|
-
const layer$
|
|
97893
|
+
const layer$54 = Layer.effect(ResourceMonitorBinary, make$63());
|
|
97276
97894
|
//#endregion
|
|
97277
97895
|
//#region src/resourceTelemetry/NativeTelemetryClient.ts
|
|
97278
97896
|
const SAMPLE_INTERVAL_MS$1 = 1e3;
|
|
@@ -97422,7 +98040,7 @@ function canCommandNativeTelemetrySidecar(status, hasHandle) {
|
|
|
97422
98040
|
return hasHandle && (status === "healthy" || status === "degraded");
|
|
97423
98041
|
}
|
|
97424
98042
|
/** @public Service construction is part of the canonical Effect module API. */
|
|
97425
|
-
const make$
|
|
98043
|
+
const make$62 = Effect.fn("resourceTelemetry.nativeTelemetryClient.make")(function* () {
|
|
97426
98044
|
const binary = yield* ResourceMonitorBinary;
|
|
97427
98045
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
97428
98046
|
const crypto = yield* Crypto.Crypto;
|
|
@@ -97833,7 +98451,7 @@ const make$64 = Effect.fn("resourceTelemetry.nativeTelemetryClient.make")(functi
|
|
|
97833
98451
|
})
|
|
97834
98452
|
});
|
|
97835
98453
|
});
|
|
97836
|
-
const layer$
|
|
98454
|
+
const layer$53 = Layer.effect(NativeTelemetryClient, make$62());
|
|
97837
98455
|
//#endregion
|
|
97838
98456
|
//#region src/resourceTelemetry/ResourceAttribution.ts
|
|
97839
98457
|
var ResourceAttribution = class extends Context.Service()("@p4code/cli/resourceTelemetry/ResourceAttribution") {};
|
|
@@ -97845,7 +98463,7 @@ function nonNegativeInteger(value, fallback) {
|
|
|
97845
98463
|
if (!Number.isFinite(value)) return 0;
|
|
97846
98464
|
return Math.max(0, Math.round(value));
|
|
97847
98465
|
}
|
|
97848
|
-
const make$
|
|
98466
|
+
const make$61 = Effect.fn("resourceTelemetry.resourceAttribution.make")(function* () {
|
|
97849
98467
|
const entries = yield* Ref.make(/* @__PURE__ */ new Map());
|
|
97850
98468
|
const record = (input) => Ref.update(entries, (current) => {
|
|
97851
98469
|
const next = new Map(current);
|
|
@@ -97871,7 +98489,7 @@ const make$63 = Effect.fn("resourceTelemetry.resourceAttribution.make")(function
|
|
|
97871
98489
|
})
|
|
97872
98490
|
});
|
|
97873
98491
|
});
|
|
97874
|
-
const layer$
|
|
98492
|
+
const layer$52 = Layer.effect(ResourceAttribution, make$61());
|
|
97875
98493
|
//#endregion
|
|
97876
98494
|
//#region src/resourceTelemetry/ResourceTelemetryHistory.ts
|
|
97877
98495
|
const MAX_HISTORY_WINDOW_MS = 60 * 6e4;
|
|
@@ -98094,7 +98712,7 @@ function buildHealth(input) {
|
|
|
98094
98712
|
};
|
|
98095
98713
|
}
|
|
98096
98714
|
/** @public Service construction is part of the canonical Effect module API. */
|
|
98097
|
-
const make$
|
|
98715
|
+
const make$60 = Effect.fn("resourceTelemetry.resourceTelemetry.make")(function* () {
|
|
98098
98716
|
const nativeClient = yield* NativeTelemetryClient;
|
|
98099
98717
|
const desktopReceiver = yield* DesktopTelemetryReceiver;
|
|
98100
98718
|
const attribution = yield* ResourceAttribution;
|
|
@@ -98346,7 +98964,7 @@ const make$62 = Effect.fn("resourceTelemetry.resourceTelemetry.make")(function*
|
|
|
98346
98964
|
})))
|
|
98347
98965
|
});
|
|
98348
98966
|
});
|
|
98349
|
-
const layer$
|
|
98967
|
+
const layer$51 = Layer.effect(ResourceTelemetry, make$60());
|
|
98350
98968
|
//#endregion
|
|
98351
98969
|
//#region src/device/DeviceInspection.ts
|
|
98352
98970
|
const READ_TIMEOUT_MS = 1e4;
|
|
@@ -101501,7 +102119,7 @@ const classifyNonZeroExit = (command, stderr) => {
|
|
|
101501
102119
|
if (command === "gh" && (normalized.includes("could not resolve to a pullrequest") || normalized.includes("repository.pullrequest") || normalized.includes("no pull requests found for branch") || normalized.includes("pull request not found")) || command === "glab" && (normalized.includes("merge request not found") || normalized.includes("not found") || normalized.includes("404")) || command === "az" && normalized.includes("pull request") && (normalized.includes("not found") || normalized.includes("does not exist"))) return "not-found";
|
|
101502
102120
|
return "command-failed";
|
|
101503
102121
|
};
|
|
101504
|
-
const make$
|
|
102122
|
+
const make$59 = Effect.gen(function* () {
|
|
101505
102123
|
const processRunner = yield* ProcessRunner;
|
|
101506
102124
|
const run = Effect.fn("VcsProcess.run")(function* (input) {
|
|
101507
102125
|
const baseError = {
|
|
@@ -101560,7 +102178,7 @@ const make$61 = Effect.gen(function* () {
|
|
|
101560
102178
|
});
|
|
101561
102179
|
return VcsProcess.of({ run });
|
|
101562
102180
|
});
|
|
101563
|
-
const layer$
|
|
102181
|
+
const layer$50 = Layer.effect(VcsProcess, make$59).pipe(Layer.provide(layer$81));
|
|
101564
102182
|
//#endregion
|
|
101565
102183
|
//#region src/vcs/VcsDriver.ts
|
|
101566
102184
|
var VcsDriver = class extends Context.Service()("@p4code/cli/vcs/VcsDriver") {};
|
|
@@ -102011,12 +102629,12 @@ const makeVcsDriver = Effect.gen(function* () {
|
|
|
102011
102629
|
const driver = yield* makeVcsDriverShape();
|
|
102012
102630
|
return VcsDriver.of(driver);
|
|
102013
102631
|
});
|
|
102014
|
-
const make$
|
|
102632
|
+
const make$58 = Effect.gen(function* () {
|
|
102015
102633
|
const git = yield* makeGitVcsDriverCore();
|
|
102016
102634
|
return GitVcsDriver.of(git);
|
|
102017
102635
|
});
|
|
102018
102636
|
Layer.effect(VcsDriver, makeVcsDriver);
|
|
102019
|
-
const layer$
|
|
102637
|
+
const layer$49 = Layer.effect(GitVcsDriver, make$58);
|
|
102020
102638
|
//#endregion
|
|
102021
102639
|
//#region src/vcs/VcsProjectConfig.ts
|
|
102022
102640
|
const ProjectVcsConfigJson = fromLenientJson(Schema$1.Struct({
|
|
@@ -102048,7 +102666,7 @@ const logVcsProjectConfigError = (error) => Effect.logWarning(error).pipe(Effect
|
|
|
102048
102666
|
configPath: error.configPath,
|
|
102049
102667
|
errorTag: error._tag
|
|
102050
102668
|
}));
|
|
102051
|
-
const make$
|
|
102669
|
+
const make$57 = Effect.gen(function* () {
|
|
102052
102670
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
102053
102671
|
const path = yield* Path$1.Path;
|
|
102054
102672
|
const findConfigPath = Effect.fn("VcsProjectConfig.findConfigPath")(function* (cwd) {
|
|
@@ -102089,7 +102707,7 @@ const make$59 = Effect.gen(function* () {
|
|
|
102089
102707
|
});
|
|
102090
102708
|
return VcsProjectConfig.of({ resolveKind });
|
|
102091
102709
|
});
|
|
102092
|
-
const layer$
|
|
102710
|
+
const layer$48 = Layer.effect(VcsProjectConfig, make$57);
|
|
102093
102711
|
//#endregion
|
|
102094
102712
|
//#region src/vcs/VcsDriverRegistry.ts
|
|
102095
102713
|
const DETECTION_CACHE_CAPACITY = 2048;
|
|
@@ -102109,7 +102727,7 @@ function parseDetectionCacheKey(key) {
|
|
|
102109
102727
|
cwd: key.slice(separatorIndex + 1)
|
|
102110
102728
|
};
|
|
102111
102729
|
}
|
|
102112
|
-
const make$
|
|
102730
|
+
const make$56 = Effect.gen(function* () {
|
|
102113
102731
|
const projectConfig = yield* VcsProjectConfig;
|
|
102114
102732
|
const git = yield* makeVcsDriver;
|
|
102115
102733
|
const drivers = { git };
|
|
@@ -102166,7 +102784,7 @@ const make$58 = Effect.gen(function* () {
|
|
|
102166
102784
|
resolve
|
|
102167
102785
|
});
|
|
102168
102786
|
});
|
|
102169
|
-
const layer$
|
|
102787
|
+
const layer$47 = Layer.effect(VcsDriverRegistry, make$56).pipe(Layer.provide(layer$48));
|
|
102170
102788
|
//#endregion
|
|
102171
102789
|
//#region src/checkpointing/CheckpointStore.ts
|
|
102172
102790
|
/**
|
|
@@ -102186,7 +102804,7 @@ const layer$49 = Layer.effect(VcsDriverRegistry, make$58).pipe(Layer.provide(lay
|
|
|
102186
102804
|
*/
|
|
102187
102805
|
/** Service tag for checkpoint persistence and restore operations. */
|
|
102188
102806
|
var CheckpointStore = class extends Context.Service()("@p4code/cli/checkpointing/CheckpointStore") {};
|
|
102189
|
-
const make$
|
|
102807
|
+
const make$55 = Effect.gen(function* () {
|
|
102190
102808
|
const vcsRegistry = yield* VcsDriverRegistry;
|
|
102191
102809
|
const resolveCheckpoints = Effect.fn("CheckpointStore.resolveCheckpoints")(function* (operation, cwd) {
|
|
102192
102810
|
const handle = yield* vcsRegistry.resolve({ cwd });
|
|
@@ -102225,7 +102843,7 @@ const make$57 = Effect.gen(function* () {
|
|
|
102225
102843
|
deleteCheckpointRefs
|
|
102226
102844
|
});
|
|
102227
102845
|
});
|
|
102228
|
-
const layer$
|
|
102846
|
+
const layer$46 = Layer.effect(CheckpointStore, make$55);
|
|
102229
102847
|
//#endregion
|
|
102230
102848
|
//#region src/checkpointing/CheckpointDiffQuery.ts
|
|
102231
102849
|
/**
|
|
@@ -102247,7 +102865,7 @@ function buildTurnDiffResult(input, diff) {
|
|
|
102247
102865
|
diff
|
|
102248
102866
|
};
|
|
102249
102867
|
}
|
|
102250
|
-
const make$
|
|
102868
|
+
const make$54 = Effect.gen(function* () {
|
|
102251
102869
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
102252
102870
|
const checkpointStore = yield* CheckpointStore;
|
|
102253
102871
|
const threadActivities = yield* ProjectionThreadActivityRepository;
|
|
@@ -102418,7 +103036,7 @@ const make$56 = Effect.gen(function* () {
|
|
|
102418
103036
|
getFullThreadDiff
|
|
102419
103037
|
});
|
|
102420
103038
|
});
|
|
102421
|
-
const layer$
|
|
103039
|
+
const layer$45 = Layer.effect(CheckpointDiffQuery, make$54);
|
|
102422
103040
|
//#endregion
|
|
102423
103041
|
//#region src/orchestration/ThreadLiveEventCoalescer.ts
|
|
102424
103042
|
const COALESCE_WINDOW = Duration.millis(50);
|
|
@@ -102963,7 +103581,7 @@ const serversEqual = (left, right) => {
|
|
|
102963
103581
|
}
|
|
102964
103582
|
return true;
|
|
102965
103583
|
};
|
|
102966
|
-
const make$
|
|
103584
|
+
const make$53 = Effect.gen(function* PortDiscoveryMake() {
|
|
102967
103585
|
const net = yield* NetService;
|
|
102968
103586
|
const processRunner = yield* ProcessRunner;
|
|
102969
103587
|
const hostPlatform = yield* HostProcessPlatform;
|
|
@@ -103114,7 +103732,7 @@ const make$55 = Effect.gen(function* PortDiscoveryMake() {
|
|
|
103114
103732
|
unregisterTerminal
|
|
103115
103733
|
});
|
|
103116
103734
|
}).pipe(Effect.withSpan("PortDiscovery.make"));
|
|
103117
|
-
const layer$
|
|
103735
|
+
const layer$44 = Layer.effect(PortDiscovery, make$53);
|
|
103118
103736
|
//#endregion
|
|
103119
103737
|
//#region src/terminal/Manager.ts
|
|
103120
103738
|
/**
|
|
@@ -103792,7 +104410,7 @@ function normalizedRuntimeEnv(env) {
|
|
|
103792
104410
|
if (entries.length === 0) return null;
|
|
103793
104411
|
return Object.fromEntries(entries.toSorted(([left], [right]) => left.localeCompare(right)));
|
|
103794
104412
|
}
|
|
103795
|
-
const make$
|
|
104413
|
+
const make$52 = Effect.fn("TerminalManager.make")(function* () {
|
|
103796
104414
|
const { terminalLogsDir } = yield* ServerConfig$1;
|
|
103797
104415
|
const ptyAdapter = yield* PtyAdapter;
|
|
103798
104416
|
const portDiscovery = yield* PortDiscovery;
|
|
@@ -104754,7 +105372,7 @@ const makeWithOptions$1 = Effect.fn("TerminalManager.makeWithOptions")(function*
|
|
|
104754
105372
|
subscribeMetadata
|
|
104755
105373
|
});
|
|
104756
105374
|
});
|
|
104757
|
-
const layer$
|
|
105375
|
+
const layer$43 = Layer.effect(TerminalManager, make$52()).pipe(Layer.provide(layer$81));
|
|
104758
105376
|
//#endregion
|
|
104759
105377
|
//#region src/project/ProjectSetupScriptRunner.ts
|
|
104760
105378
|
var ProjectSetupScriptOperationError = class extends Schema$1.TaggedErrorClass()("ProjectSetupScriptOperationError", {
|
|
@@ -104786,7 +105404,7 @@ var ProjectSetupScriptProjectNotFoundError = class extends Schema$1.TaggedErrorC
|
|
|
104786
105404
|
};
|
|
104787
105405
|
Schema$1.Union([ProjectSetupScriptOperationError, ProjectSetupScriptProjectNotFoundError]);
|
|
104788
105406
|
var ProjectSetupScriptRunner = class extends Context.Service()("@p4code/cli/project/ProjectSetupScriptRunner") {};
|
|
104789
|
-
const make$
|
|
105407
|
+
const make$51 = Effect.gen(function* () {
|
|
104790
105408
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
104791
105409
|
const terminalManager = yield* TerminalManager;
|
|
104792
105410
|
const settingsService = yield* Effect.serviceOption(ServerSettingsService);
|
|
@@ -104849,7 +105467,7 @@ const make$53 = Effect.gen(function* () {
|
|
|
104849
105467
|
});
|
|
104850
105468
|
return ProjectSetupScriptRunner.of({ runForThread });
|
|
104851
105469
|
});
|
|
104852
|
-
const layer$
|
|
105470
|
+
const layer$42 = Layer.effect(ProjectSetupScriptRunner, make$51);
|
|
104853
105471
|
//#endregion
|
|
104854
105472
|
//#region src/sourceControl/azureDevOpsPullRequests.ts
|
|
104855
105473
|
const AzureDevOpsPullRequestSchema = Schema$1.Struct({
|
|
@@ -105177,7 +105795,7 @@ function decodeAzureDevOpsJson(raw, schema, operation, cwd) {
|
|
|
105177
105795
|
cause
|
|
105178
105796
|
})));
|
|
105179
105797
|
}
|
|
105180
|
-
const make$
|
|
105798
|
+
const make$50 = Effect.gen(function* () {
|
|
105181
105799
|
const process = yield* VcsProcess;
|
|
105182
105800
|
const execute = (input) => process.run({
|
|
105183
105801
|
operation: "AzureDevOpsCli.execute",
|
|
@@ -105319,7 +105937,7 @@ const make$52 = Effect.gen(function* () {
|
|
|
105319
105937
|
}).pipe(Effect.asVoid)
|
|
105320
105938
|
});
|
|
105321
105939
|
});
|
|
105322
|
-
const layer$
|
|
105940
|
+
const layer$41 = Layer.effect(AzureDevOpsCli, make$50);
|
|
105323
105941
|
//#endregion
|
|
105324
105942
|
//#region src/sourceControl/SourceControlProviderDiscovery.ts
|
|
105325
105943
|
function firstNonEmptyLine(text) {
|
|
@@ -105523,7 +106141,7 @@ function toChangeRequest$5(summary) {
|
|
|
105523
106141
|
isCrossRepository: false
|
|
105524
106142
|
};
|
|
105525
106143
|
}
|
|
105526
|
-
const make$
|
|
106144
|
+
const make$49 = Effect.gen(function* () {
|
|
105527
106145
|
const azure = yield* AzureDevOpsCli;
|
|
105528
106146
|
return SourceControlProvider.of({
|
|
105529
106147
|
kind: "azure-devops",
|
|
@@ -105616,7 +106234,7 @@ const make$51 = Effect.gen(function* () {
|
|
|
105616
106234
|
})))
|
|
105617
106235
|
});
|
|
105618
106236
|
});
|
|
105619
|
-
Layer.effect(SourceControlProvider, make$
|
|
106237
|
+
Layer.effect(SourceControlProvider, make$49);
|
|
105620
106238
|
//#endregion
|
|
105621
106239
|
//#region src/sourceControl/bitbucketPullRequests.ts
|
|
105622
106240
|
const BitbucketRepositoryRefSchema = Schema$1.Struct({
|
|
@@ -105993,7 +106611,7 @@ function responseError(operation, response) {
|
|
|
105993
106611
|
responseBodyLength: collected.text.length
|
|
105994
106612
|
}))));
|
|
105995
106613
|
}
|
|
105996
|
-
const make$
|
|
106614
|
+
const make$48 = Effect.gen(function* () {
|
|
105997
106615
|
const config = yield* BitbucketApiEnvConfig;
|
|
105998
106616
|
const httpClient = yield* HttpClient.HttpClient;
|
|
105999
106617
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
@@ -106209,7 +106827,7 @@ const make$50 = Effect.gen(function* () {
|
|
|
106209
106827
|
})))
|
|
106210
106828
|
});
|
|
106211
106829
|
});
|
|
106212
|
-
const layer$
|
|
106830
|
+
const layer$39 = Layer.effect(BitbucketApi, make$48);
|
|
106213
106831
|
//#endregion
|
|
106214
106832
|
//#region src/sourceControl/BitbucketSourceControlProvider.ts
|
|
106215
106833
|
function toChangeRequest$4(summary) {
|
|
@@ -106227,7 +106845,7 @@ function toChangeRequest$4(summary) {
|
|
|
106227
106845
|
...summary.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: summary.headRepositoryOwnerLogin } : {}
|
|
106228
106846
|
};
|
|
106229
106847
|
}
|
|
106230
|
-
const make$
|
|
106848
|
+
const make$47 = Effect.gen(function* () {
|
|
106231
106849
|
const bitbucket = yield* BitbucketApi;
|
|
106232
106850
|
return SourceControlProvider.of({
|
|
106233
106851
|
kind: "bitbucket",
|
|
@@ -106318,7 +106936,7 @@ const make$49 = Effect.gen(function* () {
|
|
|
106318
106936
|
})))
|
|
106319
106937
|
});
|
|
106320
106938
|
});
|
|
106321
|
-
Layer.effect(SourceControlProvider, make$
|
|
106939
|
+
Layer.effect(SourceControlProvider, make$47);
|
|
106322
106940
|
const makeDiscovery = Effect.gen(function* () {
|
|
106323
106941
|
return {
|
|
106324
106942
|
type: "api",
|
|
@@ -106566,7 +107184,7 @@ function deriveRepositoryCloneUrlsFromCreateOutput(stdout, repository) {
|
|
|
106566
107184
|
sshUrl: `git@${fallbackHost}:${repository}.git`
|
|
106567
107185
|
};
|
|
106568
107186
|
}
|
|
106569
|
-
const make$
|
|
107187
|
+
const make$46 = Effect.gen(function* () {
|
|
106570
107188
|
const process = yield* VcsProcess;
|
|
106571
107189
|
const execute = (input) => process.run({
|
|
106572
107190
|
operation: "GitHubCli.execute",
|
|
@@ -106684,7 +107302,7 @@ const make$48 = Effect.gen(function* () {
|
|
|
106684
107302
|
}).pipe(Effect.asVoid)
|
|
106685
107303
|
});
|
|
106686
107304
|
});
|
|
106687
|
-
const layer$
|
|
107305
|
+
const layer$37 = Layer.effect(GitHubCli, make$46);
|
|
106688
107306
|
//#endregion
|
|
106689
107307
|
//#region src/sourceControl/gitHubAuthStatus.ts
|
|
106690
107308
|
const GitHubAuthStatusAccountSchema = Schema$1.Struct({
|
|
@@ -106786,7 +107404,7 @@ const discovery$1 = {
|
|
|
106786
107404
|
parseAuth: parseGitHubAuth,
|
|
106787
107405
|
installHint: "Install the GitHub command-line tool (`gh`) via https://cli.github.com/ or your package manager (for example `brew install gh`)."
|
|
106788
107406
|
};
|
|
106789
|
-
const make$
|
|
107407
|
+
const make$45 = Effect.gen(function* () {
|
|
106790
107408
|
const github = yield* GitHubCli;
|
|
106791
107409
|
const listChangeRequests = (input) => {
|
|
106792
107410
|
if (input.state === "open") return github.listOpenPullRequests({
|
|
@@ -106902,7 +107520,7 @@ const make$47 = Effect.gen(function* () {
|
|
|
106902
107520
|
})))
|
|
106903
107521
|
});
|
|
106904
107522
|
});
|
|
106905
|
-
Layer.effect(SourceControlProvider, make$
|
|
107523
|
+
Layer.effect(SourceControlProvider, make$45);
|
|
106906
107524
|
//#endregion
|
|
106907
107525
|
//#region src/sourceControl/gitLabMergeRequests.ts
|
|
106908
107526
|
const GitLabProjectReferenceSchema = Schema$1.Struct({
|
|
@@ -107221,7 +107839,7 @@ function parseRepositoryPath(repository) {
|
|
|
107221
107839
|
projectPath
|
|
107222
107840
|
};
|
|
107223
107841
|
}
|
|
107224
|
-
const make$
|
|
107842
|
+
const make$44 = Effect.gen(function* () {
|
|
107225
107843
|
const process = yield* VcsProcess;
|
|
107226
107844
|
const run = (input, mapError) => process.run({
|
|
107227
107845
|
operation: "GitLabCli.execute",
|
|
@@ -107372,7 +107990,7 @@ const make$46 = Effect.gen(function* () {
|
|
|
107372
107990
|
}).pipe(Effect.asVoid)
|
|
107373
107991
|
});
|
|
107374
107992
|
});
|
|
107375
|
-
const layer$
|
|
107993
|
+
const layer$35 = Layer.effect(GitLabCli, make$44);
|
|
107376
107994
|
//#endregion
|
|
107377
107995
|
//#region src/sourceControl/gitLabAuthStatus.ts
|
|
107378
107996
|
const HOST_LINE_PATTERN = /^(?:[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?|\[[a-f0-9:.]+\])(?::\d+)?$/iu;
|
|
@@ -107470,7 +108088,7 @@ const discovery = {
|
|
|
107470
108088
|
refineUnknownRemote: refineUnknownGitLabRemote,
|
|
107471
108089
|
installHint: "Install the GitLab command-line tool (`glab`) from https://gitlab.com/gitlab-org/cli or your package manager (for example `brew install glab`)."
|
|
107472
108090
|
};
|
|
107473
|
-
const make$
|
|
108091
|
+
const make$43 = Effect.gen(function* () {
|
|
107474
108092
|
const gitlab = yield* GitLabCli;
|
|
107475
108093
|
return SourceControlProvider.of({
|
|
107476
108094
|
kind: "gitlab",
|
|
@@ -107559,7 +108177,7 @@ const make$45 = Effect.gen(function* () {
|
|
|
107559
108177
|
})))
|
|
107560
108178
|
});
|
|
107561
108179
|
});
|
|
107562
|
-
Layer.effect(SourceControlProvider, make$
|
|
108180
|
+
Layer.effect(SourceControlProvider, make$43);
|
|
107563
108181
|
//#endregion
|
|
107564
108182
|
//#region src/sourceControl/SourceControlProviderRegistry.ts
|
|
107565
108183
|
const PROVIDER_DETECTION_CACHE_CAPACITY = 2048;
|
|
@@ -107715,12 +108333,12 @@ const makeWithProviders = Effect.fn("makeSourceControlProviderRegistryWithProvid
|
|
|
107715
108333
|
})), { concurrency: "unbounded" })
|
|
107716
108334
|
});
|
|
107717
108335
|
});
|
|
107718
|
-
const make$
|
|
107719
|
-
const github = yield* make$
|
|
107720
|
-
const gitlab = yield* make$
|
|
107721
|
-
const bitbucket = yield* make$
|
|
108336
|
+
const make$42 = Effect.gen(function* () {
|
|
108337
|
+
const github = yield* make$45;
|
|
108338
|
+
const gitlab = yield* make$43;
|
|
108339
|
+
const bitbucket = yield* make$47;
|
|
107722
108340
|
const bitbucketDiscovery = yield* makeDiscovery;
|
|
107723
|
-
const azureDevOps = yield* make$
|
|
108341
|
+
const azureDevOps = yield* make$49;
|
|
107724
108342
|
return yield* makeWithProviders([
|
|
107725
108343
|
{
|
|
107726
108344
|
kind: "github",
|
|
@@ -107744,7 +108362,7 @@ const make$44 = Effect.gen(function* () {
|
|
|
107744
108362
|
}
|
|
107745
108363
|
]);
|
|
107746
108364
|
});
|
|
107747
|
-
const layer$
|
|
108365
|
+
const layer$33 = Layer.effect(SourceControlProviderRegistry, make$42);
|
|
107748
108366
|
//#endregion
|
|
107749
108367
|
//#region src/sourceControl/PrTemplateDetection.ts
|
|
107750
108368
|
const TEMPLATE_MAX_BYTES = 8e3;
|
|
@@ -108115,7 +108733,7 @@ function toPullRequestHeadRemoteInfo(pr) {
|
|
|
108115
108733
|
...pr.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: pr.headRepositoryOwnerLogin } : {}
|
|
108116
108734
|
};
|
|
108117
108735
|
}
|
|
108118
|
-
const make$
|
|
108736
|
+
const make$41 = Effect.gen(function* () {
|
|
108119
108737
|
const gitCore = yield* GitVcsDriver;
|
|
108120
108738
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
108121
108739
|
const textGeneration = yield* TextGeneration;
|
|
@@ -109089,7 +109707,7 @@ const make$43 = Effect.gen(function* () {
|
|
|
109089
109707
|
runStackedAction
|
|
109090
109708
|
});
|
|
109091
109709
|
});
|
|
109092
|
-
const layer$
|
|
109710
|
+
const layer$32 = Layer.effect(GitManager, make$41);
|
|
109093
109711
|
//#endregion
|
|
109094
109712
|
//#region src/git/GitWorkflowService.ts
|
|
109095
109713
|
var GitWorkflowService = class extends Context.Service()("@p4code/cli/git/GitWorkflowService") {};
|
|
@@ -109126,7 +109744,7 @@ function nonRepositoryListRefs() {
|
|
|
109126
109744
|
totalCount: 0
|
|
109127
109745
|
};
|
|
109128
109746
|
}
|
|
109129
|
-
const make$
|
|
109747
|
+
const make$40 = Effect.gen(function* () {
|
|
109130
109748
|
const registry = yield* VcsDriverRegistry;
|
|
109131
109749
|
const git = yield* GitVcsDriver;
|
|
109132
109750
|
const gitManager = yield* GitManager;
|
|
@@ -109212,7 +109830,7 @@ const make$42 = Effect.gen(function* () {
|
|
|
109212
109830
|
renameBranch: (input) => ensureGit("GitWorkflowService.renameBranch", input.cwd).pipe(Effect.andThen(git.renameBranch(input)))
|
|
109213
109831
|
});
|
|
109214
109832
|
});
|
|
109215
|
-
const layer$
|
|
109833
|
+
const layer$31 = Layer.effect(GitWorkflowService, make$40);
|
|
109216
109834
|
//#endregion
|
|
109217
109835
|
//#region src/pullRequest/PullRequestProvider.ts
|
|
109218
109836
|
/**
|
|
@@ -109573,7 +110191,7 @@ function isReviewerName(value) {
|
|
|
109573
110191
|
const name = value.trim();
|
|
109574
110192
|
return name.length > 0 && !name.startsWith("-");
|
|
109575
110193
|
}
|
|
109576
|
-
const make$
|
|
110194
|
+
const make$39 = Effect.gen(function* () {
|
|
109577
110195
|
const azure = yield* AzureDevOpsCli;
|
|
109578
110196
|
const detectArgs = ["--detect", "true"];
|
|
109579
110197
|
const executeJson = (input) => azure.execute({
|
|
@@ -109773,7 +110391,7 @@ const make$41 = Effect.gen(function* () {
|
|
|
109773
110391
|
}).pipe(Effect.asVoid)
|
|
109774
110392
|
});
|
|
109775
110393
|
});
|
|
109776
|
-
const layer$
|
|
110394
|
+
const layer$30 = Layer.effect(AzureDevOpsPullRequestCli, make$39);
|
|
109777
110395
|
//#endregion
|
|
109778
110396
|
//#region src/pullRequest/AzureDevOpsPullRequestProvider.ts
|
|
109779
110397
|
const CAPABILITIES$3 = {
|
|
@@ -109848,7 +110466,7 @@ function toChangeRequest$1(pullRequest) {
|
|
|
109848
110466
|
labels: []
|
|
109849
110467
|
};
|
|
109850
110468
|
}
|
|
109851
|
-
const make$
|
|
110469
|
+
const make$38 = Effect.gen(function* () {
|
|
109852
110470
|
const cli = yield* AzureDevOpsPullRequestCli;
|
|
109853
110471
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
109854
110472
|
provider: "azure-devops",
|
|
@@ -110588,7 +111206,7 @@ function mergeStrategy(method) {
|
|
|
110588
111206
|
default: return "merge_commit";
|
|
110589
111207
|
}
|
|
110590
111208
|
}
|
|
110591
|
-
const make$
|
|
111209
|
+
const make$37 = Effect.gen(function* () {
|
|
110592
111210
|
const bitbucket = yield* BitbucketApi;
|
|
110593
111211
|
/**
|
|
110594
111212
|
* The repository's own path, and the workspace above it — which the people who may review are
|
|
@@ -110868,7 +111486,7 @@ const make$39 = Effect.gen(function* () {
|
|
|
110868
111486
|
}).pipe(Effect.asVoid))
|
|
110869
111487
|
});
|
|
110870
111488
|
});
|
|
110871
|
-
const layer$
|
|
111489
|
+
const layer$29 = Layer.effect(BitbucketPullRequestApi, make$37);
|
|
110872
111490
|
//#endregion
|
|
110873
111491
|
//#region src/pullRequest/BitbucketPullRequestProvider.ts
|
|
110874
111492
|
const CAPABILITIES$2 = {
|
|
@@ -110948,7 +111566,7 @@ function toChangeRequest(pullRequest) {
|
|
|
110948
111566
|
labels: []
|
|
110949
111567
|
};
|
|
110950
111568
|
}
|
|
110951
|
-
const make$
|
|
111569
|
+
const make$36 = Effect.gen(function* () {
|
|
110952
111570
|
const api = yield* BitbucketPullRequestApi;
|
|
110953
111571
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
110954
111572
|
provider: "bitbucket",
|
|
@@ -113177,7 +113795,7 @@ function actionArgs$1(action, mergeMethod, updateMethod) {
|
|
|
113177
113795
|
case "reopen": return ["reopen"];
|
|
113178
113796
|
}
|
|
113179
113797
|
}
|
|
113180
|
-
const make$
|
|
113798
|
+
const make$35 = Effect.gen(function* () {
|
|
113181
113799
|
const github = yield* GitHubCli;
|
|
113182
113800
|
/**
|
|
113183
113801
|
* The pull request's own node id, which is what a mutation against the pull request itself is
|
|
@@ -113940,7 +114558,7 @@ const make$37 = Effect.gen(function* () {
|
|
|
113940
114558
|
})))
|
|
113941
114559
|
});
|
|
113942
114560
|
});
|
|
113943
|
-
const layer$
|
|
114561
|
+
const layer$28 = Layer.effect(GitHubPullRequestCli, make$35);
|
|
113944
114562
|
//#endregion
|
|
113945
114563
|
//#region src/pullRequest/GitHubPullRequestProvider.ts
|
|
113946
114564
|
const CAPABILITIES$1 = {
|
|
@@ -114057,7 +114675,7 @@ function loginAvatarUrl(login, host) {
|
|
|
114057
114675
|
}
|
|
114058
114676
|
/** True where markdown would render nothing: whitespace, or only HTML comments. */
|
|
114059
114677
|
const rendersEmpty = (body) => body.replace(/<!--[\s\S]*?-->/g, "").trim().length === 0;
|
|
114060
|
-
const make$
|
|
114678
|
+
const make$34 = Effect.gen(function* () {
|
|
114061
114679
|
const cli = yield* GitHubPullRequestCli;
|
|
114062
114680
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
114063
114681
|
provider: "github",
|
|
@@ -115079,7 +115697,7 @@ function actionArgs(action, mergeMethod) {
|
|
|
115079
115697
|
case "reopen": return ["reopen"];
|
|
115080
115698
|
}
|
|
115081
115699
|
}
|
|
115082
|
-
const make$
|
|
115700
|
+
const make$33 = Effect.gen(function* () {
|
|
115083
115701
|
const gitlab = yield* GitLabCli;
|
|
115084
115702
|
const api = (input) => gitlab.execute({
|
|
115085
115703
|
cwd: input.cwd,
|
|
@@ -115650,7 +116268,7 @@ const make$35 = Effect.gen(function* () {
|
|
|
115650
116268
|
}).pipe(Effect.asVoid)
|
|
115651
116269
|
});
|
|
115652
116270
|
});
|
|
115653
|
-
const layer$
|
|
116271
|
+
const layer$27 = Layer.effect(GitLabPullRequestCli, make$33);
|
|
115654
116272
|
//#endregion
|
|
115655
116273
|
//#region src/pullRequest/GitLabPullRequestProvider.ts
|
|
115656
116274
|
const CAPABILITIES = {
|
|
@@ -115730,7 +116348,7 @@ function reasonFor(error) {
|
|
|
115730
116348
|
if (error._tag === "GitLabCliAuthenticationError") return "unauthenticated";
|
|
115731
116349
|
return "failed";
|
|
115732
116350
|
}
|
|
115733
|
-
const make$
|
|
116351
|
+
const make$32 = Effect.gen(function* () {
|
|
115734
116352
|
const cli = yield* GitLabPullRequestCli;
|
|
115735
116353
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
115736
116354
|
provider: "gitlab",
|
|
@@ -115873,13 +116491,13 @@ function fromProviders(providers) {
|
|
|
115873
116491
|
* The hosts this build can read change requests from. A host with no entry here still shows up
|
|
115874
116492
|
* in the provider list as unimplemented, so its projects are explained rather than missing.
|
|
115875
116493
|
*/
|
|
115876
|
-
const make$
|
|
115877
|
-
make$36,
|
|
116494
|
+
const make$31 = Effect.map(Effect.all([
|
|
115878
116495
|
make$34,
|
|
115879
|
-
make$
|
|
115880
|
-
make$
|
|
116496
|
+
make$32,
|
|
116497
|
+
make$36,
|
|
116498
|
+
make$38
|
|
115881
116499
|
]), fromProviders);
|
|
115882
|
-
const layer$
|
|
116500
|
+
const layer$26 = Layer.effect(PullRequestProviderRegistry, make$31).pipe(Layer.provide(layer$28.pipe(Layer.provide(layer$37))), Layer.provide(layer$27.pipe(Layer.provide(layer$35))), Layer.provide(layer$29.pipe(Layer.provide(layer$39))), Layer.provide(layer$30.pipe(Layer.provide(layer$41))));
|
|
115883
116501
|
//#endregion
|
|
115884
116502
|
//#region src/pullRequest/PullRequestService.ts
|
|
115885
116503
|
/**
|
|
@@ -116067,7 +116685,7 @@ function repositoryIdentityOf(project) {
|
|
|
116067
116685
|
if (identity.displayName) return identity.displayName;
|
|
116068
116686
|
return identity.owner && identity.name ? `${identity.owner}/${identity.name}` : null;
|
|
116069
116687
|
}
|
|
116070
|
-
const make$
|
|
116688
|
+
const make$30 = Effect.gen(function* () {
|
|
116071
116689
|
const registry = yield* PullRequestProviderRegistry;
|
|
116072
116690
|
const projections = yield* ProjectionSnapshotQuery;
|
|
116073
116691
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
@@ -117065,7 +117683,7 @@ const make$32 = Effect.gen(function* () {
|
|
|
117065
117683
|
invalidate
|
|
117066
117684
|
});
|
|
117067
117685
|
});
|
|
117068
|
-
const layer$
|
|
117686
|
+
const layer$25 = Layer.effect(PullRequestService, make$30);
|
|
117069
117687
|
//#endregion
|
|
117070
117688
|
//#region src/orchestration/ThreadWorkspaceLifecycle.ts
|
|
117071
117689
|
var ThreadWorkspaceLifecycleError = class extends Data.TaggedError("ThreadWorkspaceLifecycleError") {};
|
|
@@ -117109,7 +117727,7 @@ const mapLifecycleError = Effect.mapError((cause) => cause instanceof ThreadWork
|
|
|
117109
117727
|
detail: "Thread workspace lifecycle operation failed.",
|
|
117110
117728
|
cause
|
|
117111
117729
|
}));
|
|
117112
|
-
const make$
|
|
117730
|
+
const make$29 = Effect.gen(function* () {
|
|
117113
117731
|
const snapshots = yield* ProjectionSnapshotQuery;
|
|
117114
117732
|
const engine = yield* OrchestrationEngineService;
|
|
117115
117733
|
const gitWorkflow = yield* GitWorkflowService;
|
|
@@ -117363,7 +117981,7 @@ const make$31 = Effect.gen(function* () {
|
|
|
117363
117981
|
record
|
|
117364
117982
|
};
|
|
117365
117983
|
});
|
|
117366
|
-
const layer$
|
|
117984
|
+
const layer$24 = Layer.effect(ThreadWorkspaceLifecycleService, make$29);
|
|
117367
117985
|
//#endregion
|
|
117368
117986
|
//#region src/textGeneration/BtwRequestCoordinator.ts
|
|
117369
117987
|
const MAX_PENDING_BTW_CANCELLATIONS = 256;
|
|
@@ -119636,7 +120254,7 @@ function makeUpdateState(input) {
|
|
|
119636
120254
|
output: input.output ?? null
|
|
119637
120255
|
};
|
|
119638
120256
|
}
|
|
119639
|
-
const make$
|
|
120257
|
+
const make$28 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
119640
120258
|
const providerRegistry = yield* ProviderRegistry;
|
|
119641
120259
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
119642
120260
|
const httpClient = yield* HttpClient.HttpClient;
|
|
@@ -119722,7 +120340,7 @@ const make$30 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
|
119722
120340
|
status: stillOutdated ? "unchanged" : "succeeded",
|
|
119723
120341
|
startedAt,
|
|
119724
120342
|
finishedAt,
|
|
119725
|
-
message: couldNotVerify ? "Update command completed, but
|
|
120343
|
+
message: couldNotVerify ? "Update command completed, but P4 Code could not verify the provider version." : stillOutdated ? "Update command completed, but P4 Code still detects an outdated provider version." : "Provider updated.",
|
|
119726
120344
|
output: commandOutput(result)
|
|
119727
120345
|
}));
|
|
119728
120346
|
});
|
|
@@ -119751,7 +120369,7 @@ const make$30 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
|
119751
120369
|
});
|
|
119752
120370
|
return ProviderMaintenanceRunner.of({ updateProvider });
|
|
119753
120371
|
});
|
|
119754
|
-
const layer$
|
|
120372
|
+
const layer$23 = Layer.effect(ProviderMaintenanceRunner, make$28());
|
|
119755
120373
|
//#endregion
|
|
119756
120374
|
//#region src/usage/usageTranscripts.ts
|
|
119757
120375
|
const EMPTY_TOTALS = {
|
|
@@ -120574,7 +121192,7 @@ Layer.succeed(UsageService, UsageService.of({ readSummary: (input) => Effect.suc
|
|
|
120574
121192
|
},
|
|
120575
121193
|
scanDurationMs: 0
|
|
120576
121194
|
}) }));
|
|
120577
|
-
const make$
|
|
121195
|
+
const make$27 = Effect.gen(function* () {
|
|
120578
121196
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
120579
121197
|
const path = yield* Path$1.Path;
|
|
120580
121198
|
const config = yield* ServerConfig$1;
|
|
@@ -120816,7 +121434,7 @@ const make$29 = Effect.gen(function* () {
|
|
|
120816
121434
|
};
|
|
120817
121435
|
}) };
|
|
120818
121436
|
});
|
|
120819
|
-
const layer$
|
|
121437
|
+
const layer$22 = Layer.effect(UsageService, make$27);
|
|
120820
121438
|
//#endregion
|
|
120821
121439
|
//#region src/feed/FeedStore.ts
|
|
120822
121440
|
const storageFailure = (message) => new FeedError({
|
|
@@ -121180,7 +121798,7 @@ const jsonRequest = Effect.fn("FeedService.jsonRequest")(function* (url, token,
|
|
|
121180
121798
|
catch: () => fail("hub_unavailable", "Hub returned invalid JSON.")
|
|
121181
121799
|
});
|
|
121182
121800
|
});
|
|
121183
|
-
const make$
|
|
121801
|
+
const make$26 = Effect.gen(function* () {
|
|
121184
121802
|
const hubLink = yield* HubLink;
|
|
121185
121803
|
const providers = yield* ProviderInstanceRegistry;
|
|
121186
121804
|
const config = yield* ServerConfig$1;
|
|
@@ -121418,7 +122036,7 @@ var FeedService = class extends Context.Reference("@p4code/cli/feed/FeedService"
|
|
|
121418
122036
|
markRead: unavailable,
|
|
121419
122037
|
cleanup: unavailable
|
|
121420
122038
|
}) }) {};
|
|
121421
|
-
const layer$
|
|
122039
|
+
const layer$21 = Layer.effect(FeedService, make$26);
|
|
121422
122040
|
const SKILL_MANIFEST_FILENAME = "SKILL.md";
|
|
121423
122041
|
/**
|
|
121424
122042
|
* Split a catalogue id (`owner/repo/skill-name`) into its parts.
|
|
@@ -121564,7 +122182,7 @@ const emptyFetch = (id, unavailable) => ({
|
|
|
121564
122182
|
skipped: [],
|
|
121565
122183
|
unavailable
|
|
121566
122184
|
});
|
|
121567
|
-
const make$
|
|
122185
|
+
const make$25 = Effect.gen(function* () {
|
|
121568
122186
|
const http = yield* HttpClient.HttpClient;
|
|
121569
122187
|
const request = Effect.fn("SkillRegistry.request")(function* (url) {
|
|
121570
122188
|
return yield* http.execute(HttpClientRequest.get(url).pipe(HttpClientRequest.setHeader("accept", "application/json"), HttpClientRequest.setHeader("user-agent", "p4code"))).pipe(Effect.timeout(REQUEST_TIMEOUT_MS$1));
|
|
@@ -121635,117 +122253,7 @@ const make$27 = Effect.gen(function* () {
|
|
|
121635
122253
|
fetch
|
|
121636
122254
|
};
|
|
121637
122255
|
});
|
|
121638
|
-
const layer$
|
|
121639
|
-
//#endregion
|
|
121640
|
-
//#region src/mcp/McpInvocationContext.ts
|
|
121641
|
-
var McpInvocationContext = class extends Context.Service()("@p4code/cli/mcp/McpInvocationContext") {};
|
|
121642
|
-
const requireMcpCapability = Effect.fn("mcp.requireCapability")(function* (capability) {
|
|
121643
|
-
const invocation = yield* McpInvocationContext;
|
|
121644
|
-
if (!invocation.capabilities.has(capability)) return yield* new PreviewAutomationUnavailableError({
|
|
121645
|
-
capability,
|
|
121646
|
-
environmentId: invocation.environmentId,
|
|
121647
|
-
threadId: invocation.threadId,
|
|
121648
|
-
providerSessionId: invocation.providerSessionId,
|
|
121649
|
-
providerInstanceId: invocation.providerInstanceId
|
|
121650
|
-
});
|
|
121651
|
-
return invocation;
|
|
121652
|
-
});
|
|
121653
|
-
/**
|
|
121654
|
-
* The task-board counterpart of {@link requireMcpCapability}. The two are
|
|
121655
|
-
* separate because each capability reports its own absence with the error type
|
|
121656
|
-
* its toolkit declares as a failure, and those unions do not overlap.
|
|
121657
|
-
*/
|
|
121658
|
-
const requireTaskCapability = Effect.fn("mcp.requireTaskCapability")(function* () {
|
|
121659
|
-
const invocation = yield* McpInvocationContext;
|
|
121660
|
-
if (!invocation.capabilities.has("tasks")) return yield* new TaskToolUnavailableError({
|
|
121661
|
-
capability: "tasks",
|
|
121662
|
-
environmentId: invocation.environmentId,
|
|
121663
|
-
threadId: invocation.threadId,
|
|
121664
|
-
providerSessionId: invocation.providerSessionId,
|
|
121665
|
-
providerInstanceId: invocation.providerInstanceId
|
|
121666
|
-
});
|
|
121667
|
-
return invocation;
|
|
121668
|
-
});
|
|
121669
|
-
/**
|
|
121670
|
-
* The watch capability's guard is two checks, not one: the capability must be
|
|
121671
|
-
* present AND the requested thread must be in the explicit grant set. The two
|
|
121672
|
-
* failures are distinct errors so a watcher can tell "this session cannot
|
|
121673
|
-
* watch at all" apart from "not this thread".
|
|
121674
|
-
*/
|
|
121675
|
-
const requireWatchCapability = Effect.fn("mcp.requireWatchCapability")(function* (watchedThreadId) {
|
|
121676
|
-
const invocation = yield* McpInvocationContext;
|
|
121677
|
-
if (!invocation.capabilities.has("watch")) return yield* new WatchToolUnavailableError({
|
|
121678
|
-
capability: "watch",
|
|
121679
|
-
environmentId: invocation.environmentId,
|
|
121680
|
-
threadId: invocation.threadId,
|
|
121681
|
-
providerSessionId: invocation.providerSessionId,
|
|
121682
|
-
providerInstanceId: invocation.providerInstanceId
|
|
121683
|
-
});
|
|
121684
|
-
if (!invocation.watchThreadIds?.has(watchedThreadId)) return yield* new ThreadWatchNotPermittedError({ threadId: watchedThreadId });
|
|
121685
|
-
return invocation;
|
|
121686
|
-
});
|
|
121687
|
-
/**
|
|
121688
|
-
* The advise guard mirrors the watch guard's two checks - capability present
|
|
121689
|
-
* AND thread in the explicit grant - because advising carries strictly more
|
|
121690
|
-
* power than watching. A watch-only credential fails the first check here no
|
|
121691
|
-
* matter what threads it can read.
|
|
121692
|
-
*/
|
|
121693
|
-
const requireAdviseCapability = Effect.fn("mcp.requireAdviseCapability")(function* (advisedThreadId) {
|
|
121694
|
-
const invocation = yield* McpInvocationContext;
|
|
121695
|
-
if (!invocation.capabilities.has("advise")) return yield* new AdviseToolUnavailableError({
|
|
121696
|
-
capability: "advise",
|
|
121697
|
-
environmentId: invocation.environmentId,
|
|
121698
|
-
threadId: invocation.threadId,
|
|
121699
|
-
providerSessionId: invocation.providerSessionId,
|
|
121700
|
-
providerInstanceId: invocation.providerInstanceId
|
|
121701
|
-
});
|
|
121702
|
-
if (!invocation.adviseThreadIds?.has(advisedThreadId)) return yield* new ThreadAdviseNotPermittedError({ threadId: advisedThreadId });
|
|
121703
|
-
return invocation;
|
|
121704
|
-
});
|
|
121705
|
-
/** Third of the trio, for the same reason the second exists. */
|
|
121706
|
-
const requireThreadCapability = Effect.fn("mcp.requireThreadCapability")(function* () {
|
|
121707
|
-
const invocation = yield* McpInvocationContext;
|
|
121708
|
-
if (!invocation.capabilities.has("threads")) return yield* new ThreadToolUnavailableError({
|
|
121709
|
-
capability: "threads",
|
|
121710
|
-
environmentId: invocation.environmentId,
|
|
121711
|
-
threadId: invocation.threadId,
|
|
121712
|
-
providerSessionId: invocation.providerSessionId,
|
|
121713
|
-
providerInstanceId: invocation.providerInstanceId
|
|
121714
|
-
});
|
|
121715
|
-
return invocation;
|
|
121716
|
-
});
|
|
121717
|
-
/**
|
|
121718
|
-
* The thread a control tool may act on, given what it was asked to act on.
|
|
121719
|
-
*
|
|
121720
|
-
* Two checks like `requireWatchCapability`, and for the same reason: the
|
|
121721
|
-
* capability says this session controls threads at all, the grant says which.
|
|
121722
|
-
* An omitted id resolves to the session's own thread, which is always in the
|
|
121723
|
-
* grant and is why the common call needs no id and so cannot name a wrong one.
|
|
121724
|
-
*/
|
|
121725
|
-
const requireThreadControlTarget = Effect.fn("mcp.requireThreadControlTarget")(function* (requested) {
|
|
121726
|
-
const invocation = yield* requireThreadCapability();
|
|
121727
|
-
if (requested === void 0 || requested === invocation.threadId) return {
|
|
121728
|
-
invocation,
|
|
121729
|
-
threadId: invocation.threadId
|
|
121730
|
-
};
|
|
121731
|
-
if (!invocation.controlThreadIds?.has(requested)) return yield* new ThreadControlNotPermittedError({ threadId: requested });
|
|
121732
|
-
return {
|
|
121733
|
-
invocation,
|
|
121734
|
-
threadId: requested
|
|
121735
|
-
};
|
|
121736
|
-
});
|
|
121737
|
-
/**
|
|
121738
|
-
* The guard on starting a thread, which is a different question from acting on
|
|
121739
|
-
* one: it is not "which thread" but "may this session make more of them".
|
|
121740
|
-
*/
|
|
121741
|
-
const requireThreadSpawn = Effect.fn("mcp.requireThreadSpawn")(function* (fusion = false) {
|
|
121742
|
-
const invocation = yield* requireThreadCapability();
|
|
121743
|
-
if (invocation.mayCreateThreads !== true && !(fusion && invocation.mayCreateFusionPairs === true)) return yield* new ThreadSpawnNotPermittedError({
|
|
121744
|
-
threadId: invocation.threadId,
|
|
121745
|
-
detail: "this thread was itself started by an agent, and spawning goes one level deep so a runaway loop has a bound"
|
|
121746
|
-
});
|
|
121747
|
-
return invocation;
|
|
121748
|
-
});
|
|
122256
|
+
const layer$20 = Layer.effect(SkillRegistry, make$25);
|
|
121749
122257
|
//#endregion
|
|
121750
122258
|
//#region src/mcp/PreviewAutomationBroker.ts
|
|
121751
122259
|
var PreviewAutomationBroker = class extends Context.Service()("@p4code/cli/mcp/PreviewAutomationBroker") {};
|
|
@@ -121863,7 +122371,7 @@ const classifyResponseError = (context, error) => {
|
|
|
121863
122371
|
});
|
|
121864
122372
|
}
|
|
121865
122373
|
};
|
|
121866
|
-
const make$
|
|
122374
|
+
const make$24 = Effect.gen(function* PreviewAutomationBrokerMake() {
|
|
121867
122375
|
const crypto = yield* Crypto.Crypto;
|
|
121868
122376
|
const state = yield* SynchronizedRef.make({
|
|
121869
122377
|
clients: /* @__PURE__ */ new Map(),
|
|
@@ -122097,7 +122605,7 @@ const make$26 = Effect.gen(function* PreviewAutomationBrokerMake() {
|
|
|
122097
122605
|
invoke
|
|
122098
122606
|
});
|
|
122099
122607
|
}).pipe(Effect.withSpan("PreviewAutomationBroker.make"));
|
|
122100
|
-
const layer$
|
|
122608
|
+
const layer$19 = Layer.effect(PreviewAutomationBroker, make$24);
|
|
122101
122609
|
//#endregion
|
|
122102
122610
|
//#region src/preview/Manager.ts
|
|
122103
122611
|
/**
|
|
@@ -122161,7 +122669,7 @@ const buildIdleSnapshot = (input) => ({
|
|
|
122161
122669
|
viewport: FILL_PREVIEW_VIEWPORT,
|
|
122162
122670
|
updatedAt: input.updatedAt
|
|
122163
122671
|
});
|
|
122164
|
-
const make$
|
|
122672
|
+
const make$23 = Effect.gen(function* PreviewManagerMake() {
|
|
122165
122673
|
const serverEpoch = NodeCrypto.randomUUID();
|
|
122166
122674
|
const stateRef = yield* SynchronizedRef.make(initialState);
|
|
122167
122675
|
const eventsPubSub = yield* PubSub.unbounded();
|
|
@@ -122392,7 +122900,7 @@ const make$25 = Effect.gen(function* PreviewManagerMake() {
|
|
|
122392
122900
|
subscribeEvents: PubSub.subscribe(eventsPubSub)
|
|
122393
122901
|
});
|
|
122394
122902
|
}).pipe(Effect.withSpan("PreviewManager.make"));
|
|
122395
|
-
const layer$
|
|
122903
|
+
const layer$18 = Layer.effect(PreviewManager, make$23);
|
|
122396
122904
|
//#endregion
|
|
122397
122905
|
//#region src/workspace/WorkspaceSearchIndex.ts
|
|
122398
122906
|
const WORKSPACE_INDEX_MAX_ENTRIES = 25e3;
|
|
@@ -122529,7 +123037,7 @@ const waitForScan = (cwd, finder, onFailure) => Effect.try({
|
|
|
122529
123037
|
timeout: WORKSPACE_INDEX_SCAN_TIMEOUT
|
|
122530
123038
|
})
|
|
122531
123039
|
}), Effect.withSpan("WorkspaceSearchIndex.waitForScan"));
|
|
122532
|
-
const make$
|
|
123040
|
+
const make$22 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd, contentSearch = false) {
|
|
122533
123041
|
const finder = yield* Effect.acquireRelease(createFinder(cwd, contentSearch), (finder) => Effect.try({
|
|
122534
123042
|
try: () => finder.destroy(),
|
|
122535
123043
|
catch: (cause) => new WorkspaceSearchIndexDestroyFailed({
|
|
@@ -122669,14 +123177,14 @@ const make$24 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd, contentSe
|
|
|
122669
123177
|
* workspace root. WorkspaceSearchIndexMap owns memoization and idle cleanup;
|
|
122670
123178
|
* using a default cwd here would mix resources from different workspaces.
|
|
122671
123179
|
*/
|
|
122672
|
-
const layer$
|
|
123180
|
+
const layer$17 = (cwd) => Layer.effect(WorkspaceSearchIndex, make$22(cwd));
|
|
122673
123181
|
var WorkspaceSearchIndexMap = class extends LayerMap.Service()("@p4code/cli/workspace/WorkspaceSearchIndexMap", {
|
|
122674
|
-
lookup: layer$
|
|
123182
|
+
lookup: layer$17,
|
|
122675
123183
|
idleTimeToLive: WORKSPACE_INDEX_IDLE_TTL
|
|
122676
123184
|
}) {};
|
|
122677
123185
|
/** Content indexing is allocated only when workspace content search is used. */
|
|
122678
123186
|
var WorkspaceContentSearchIndexMap = class extends LayerMap.Service()("@p4code/cli/workspace/WorkspaceContentSearchIndexMap", {
|
|
122679
|
-
lookup: (cwd) => Layer.effect(WorkspaceSearchIndex, make$
|
|
123187
|
+
lookup: (cwd) => Layer.effect(WorkspaceSearchIndex, make$22(cwd, true)),
|
|
122680
123188
|
idleTimeToLive: WORKSPACE_INDEX_IDLE_TTL
|
|
122681
123189
|
}) {};
|
|
122682
123190
|
//#endregion
|
|
@@ -122738,7 +123246,7 @@ const resolveBrowseTarget = Effect.fn("WorkspaceEntries.resolveBrowseTarget")(fu
|
|
|
122738
123246
|
if (!input.cwd) return yield* new WorkspaceEntriesCurrentProjectRequiredError({ partialPath: input.partialPath });
|
|
122739
123247
|
return path.resolve(expandHomePath$1(input.cwd, path), input.partialPath);
|
|
122740
123248
|
});
|
|
122741
|
-
const make$
|
|
123249
|
+
const make$21 = Effect.gen(function* () {
|
|
122742
123250
|
const path = yield* Path$1.Path;
|
|
122743
123251
|
const workspacePaths = yield* WorkspacePaths;
|
|
122744
123252
|
const contentSearchIndexes = yield* WorkspaceContentSearchIndexMap;
|
|
@@ -122820,7 +123328,7 @@ const make$23 = Effect.gen(function* () {
|
|
|
122820
123328
|
searchContents
|
|
122821
123329
|
});
|
|
122822
123330
|
});
|
|
122823
|
-
const layer$
|
|
123331
|
+
const layer$16 = Layer.effect(WorkspaceEntries, make$21).pipe(Layer.provide(WorkspaceSearchIndexMap.layer), Layer.provide(WorkspaceContentSearchIndexMap.layer));
|
|
122824
123332
|
//#endregion
|
|
122825
123333
|
//#region src/workspace/WorkspaceFileSystem.ts
|
|
122826
123334
|
/**
|
|
@@ -122879,7 +123387,7 @@ Schema$1.Union([
|
|
|
122879
123387
|
]);
|
|
122880
123388
|
/** Service tag for workspace file operations. */
|
|
122881
123389
|
var WorkspaceFileSystem = class extends Context.Service()("@p4code/cli/workspace/WorkspaceFileSystem") {};
|
|
122882
|
-
const make$
|
|
123390
|
+
const make$20 = Effect.gen(function* () {
|
|
122883
123391
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
122884
123392
|
const path = yield* Path$1.Path;
|
|
122885
123393
|
const workspacePaths = yield* WorkspacePaths;
|
|
@@ -123023,7 +123531,7 @@ const make$22 = Effect.gen(function* () {
|
|
|
123023
123531
|
writeFile
|
|
123024
123532
|
});
|
|
123025
123533
|
});
|
|
123026
|
-
const layer$
|
|
123534
|
+
const layer$15 = Layer.effect(WorkspaceFileSystem, make$20);
|
|
123027
123535
|
//#endregion
|
|
123028
123536
|
//#region src/vcs/VcsStatusBroadcaster.ts
|
|
123029
123537
|
const DEFAULT_VCS_STATUS_REFRESH_INTERVAL = Duration.seconds(30);
|
|
@@ -123105,7 +123613,7 @@ const autoPullPolicyLayer = Layer.effect(VcsAutoPullPolicy, Effect.gen(function*
|
|
|
123105
123613
|
return resolveProjectAutoPull(yield* settingsService.getSettings, project.value.id);
|
|
123106
123614
|
}, Effect.orElseSucceed(() => false)) };
|
|
123107
123615
|
}));
|
|
123108
|
-
const make$
|
|
123616
|
+
const make$19 = Effect.gen(function* () {
|
|
123109
123617
|
const autoPullPolicy = yield* VcsAutoPullPolicy;
|
|
123110
123618
|
const workflow = yield* GitWorkflowService;
|
|
123111
123619
|
const fs = yield* FileSystem.FileSystem;
|
|
@@ -123364,7 +123872,7 @@ const make$21 = Effect.gen(function* () {
|
|
|
123364
123872
|
streamStatus
|
|
123365
123873
|
});
|
|
123366
123874
|
});
|
|
123367
|
-
const layer$
|
|
123875
|
+
const layer$14 = Layer.effect(VcsStatusBroadcaster, make$19);
|
|
123368
123876
|
//#endregion
|
|
123369
123877
|
//#region src/vcs/VcsProvisioningService.ts
|
|
123370
123878
|
var VcsProvisioningService = class extends Context.Service()("@p4code/cli/vcs/VcsProvisioningService") {};
|
|
@@ -123377,7 +123885,7 @@ function resolveRequestedKind(kind) {
|
|
|
123377
123885
|
}));
|
|
123378
123886
|
return Effect.succeed(kind);
|
|
123379
123887
|
}
|
|
123380
|
-
const make$
|
|
123888
|
+
const make$18 = Effect.gen(function* () {
|
|
123381
123889
|
const registry = yield* VcsDriverRegistry;
|
|
123382
123890
|
const initRepository = Effect.fn("VcsProvisioningService.initRepository")(function* (input) {
|
|
123383
123891
|
const kind = yield* resolveRequestedKind(input.kind);
|
|
@@ -123385,11 +123893,11 @@ const make$20 = Effect.gen(function* () {
|
|
|
123385
123893
|
});
|
|
123386
123894
|
return VcsProvisioningService.of({ initRepository });
|
|
123387
123895
|
});
|
|
123388
|
-
const layer$
|
|
123896
|
+
const layer$13 = Layer.effect(VcsProvisioningService, make$18);
|
|
123389
123897
|
//#endregion
|
|
123390
123898
|
//#region src/review/ReviewService.ts
|
|
123391
123899
|
var ReviewService = class extends Context.Service()("@p4code/cli/review/ReviewService") {};
|
|
123392
|
-
const make$
|
|
123900
|
+
const make$17 = Effect.gen(function* () {
|
|
123393
123901
|
const config = yield* ServerConfig$1;
|
|
123394
123902
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
123395
123903
|
const path = yield* Path$1.Path;
|
|
@@ -123445,7 +123953,7 @@ const make$19 = Effect.gen(function* () {
|
|
|
123445
123953
|
});
|
|
123446
123954
|
return ReviewService.of({ getDiffPreview });
|
|
123447
123955
|
});
|
|
123448
|
-
const layer$
|
|
123956
|
+
const layer$12 = Layer.effect(ReviewService, make$17);
|
|
123449
123957
|
//#endregion
|
|
123450
123958
|
//#region src/diagnostics/ProcessDiagnostics.ts
|
|
123451
123959
|
const PROCESS_QUERY_TIMEOUT_MS = 1e3;
|
|
@@ -123740,7 +124248,7 @@ function assertDescendantPid(pid) {
|
|
|
123740
124248
|
}));
|
|
123741
124249
|
}));
|
|
123742
124250
|
}
|
|
123743
|
-
const make$
|
|
124251
|
+
const make$16 = Effect.gen(function* () {
|
|
123744
124252
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
123745
124253
|
const read = Effect.gen(function* () {
|
|
123746
124254
|
const readAt = yield* DateTime.now;
|
|
@@ -123784,7 +124292,7 @@ const make$18 = Effect.gen(function* () {
|
|
|
123784
124292
|
signal
|
|
123785
124293
|
});
|
|
123786
124294
|
});
|
|
123787
|
-
const layer$
|
|
124295
|
+
const layer$11 = Layer.effect(ProcessDiagnostics, make$16);
|
|
123788
124296
|
//#endregion
|
|
123789
124297
|
//#region src/diagnostics/ProcessResourceMonitor.ts
|
|
123790
124298
|
const SAMPLE_INTERVAL_MS = 5e3;
|
|
@@ -123935,7 +124443,7 @@ function aggregateProcessResourceHistory(input) {
|
|
|
123935
124443
|
}) : Option.none()
|
|
123936
124444
|
};
|
|
123937
124445
|
}
|
|
123938
|
-
const make$
|
|
124446
|
+
const make$15 = Effect.gen(function* () {
|
|
123939
124447
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
123940
124448
|
const state = yield* Ref.make({
|
|
123941
124449
|
samples: [],
|
|
@@ -123984,7 +124492,7 @@ const make$17 = Effect.gen(function* () {
|
|
|
123984
124492
|
});
|
|
123985
124493
|
return ProcessResourceMonitor.of({ readHistory });
|
|
123986
124494
|
});
|
|
123987
|
-
const layer$
|
|
124495
|
+
const layer$10 = Layer.effect(ProcessResourceMonitor, make$15);
|
|
123988
124496
|
//#endregion
|
|
123989
124497
|
//#region src/diagnostics/TraceDiagnostics.ts
|
|
123990
124498
|
var TraceFileReadError = class extends Schema$1.TaggedErrorClass()("TraceFileReadError", {
|
|
@@ -124232,7 +124740,7 @@ function readTraceFile(fileSystem, path) {
|
|
|
124232
124740
|
cause
|
|
124233
124741
|
})) }));
|
|
124234
124742
|
}
|
|
124235
|
-
const make$
|
|
124743
|
+
const make$14 = Effect.gen(function* () {
|
|
124236
124744
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
124237
124745
|
const read = Effect.fn("TraceDiagnostics.read")(function* (options) {
|
|
124238
124746
|
const readAt = options.readAt ?? (yield* DateTime.now);
|
|
@@ -124276,7 +124784,7 @@ const make$16 = Effect.gen(function* () {
|
|
|
124276
124784
|
});
|
|
124277
124785
|
return TraceDiagnostics.of({ read });
|
|
124278
124786
|
});
|
|
124279
|
-
const layer$
|
|
124787
|
+
const layer$9 = Layer.effect(TraceDiagnostics, make$14);
|
|
124280
124788
|
function readTraceDiagnostics(options) {
|
|
124281
124789
|
return Effect.gen(function* () {
|
|
124282
124790
|
return yield* (yield* TraceDiagnostics).read(options);
|
|
@@ -124311,7 +124819,7 @@ function snapshotFromDetail(link, detail, syncedAt) {
|
|
|
124311
124819
|
mergeability: detail.mergeability
|
|
124312
124820
|
};
|
|
124313
124821
|
}
|
|
124314
|
-
const make$
|
|
124822
|
+
const make$13 = Effect.gen(function* () {
|
|
124315
124823
|
const engine = yield* OrchestrationEngineService;
|
|
124316
124824
|
const projections = yield* ProjectionSnapshotQuery;
|
|
124317
124825
|
const pullRequests = yield* PullRequestService;
|
|
@@ -124405,7 +124913,7 @@ const make$15 = Effect.gen(function* () {
|
|
|
124405
124913
|
};
|
|
124406
124914
|
});
|
|
124407
124915
|
var PullRequestSyncReactor = class extends Context.Service()("@p4code/cli/orchestration/Layers/PullRequestSyncReactor") {};
|
|
124408
|
-
const PullRequestSyncReactorLive = Layer.effect(PullRequestSyncReactor, make$
|
|
124916
|
+
const PullRequestSyncReactorLive = Layer.effect(PullRequestSyncReactor, make$13);
|
|
124409
124917
|
//#endregion
|
|
124410
124918
|
//#region src/sourceControl/SourceControlDiscovery.ts
|
|
124411
124919
|
const VCS_PROBES = [{
|
|
@@ -124424,7 +124932,7 @@ const VCS_PROBES = [{
|
|
|
124424
124932
|
installHint: "Install Jujutsu with `brew install jj` or from https://github.com/jj-vcs/jj."
|
|
124425
124933
|
}];
|
|
124426
124934
|
var SourceControlDiscovery = class extends Context.Service()("@p4code/cli/sourceControl/SourceControlDiscovery") {};
|
|
124427
|
-
const make$
|
|
124935
|
+
const make$12 = Effect.gen(function* () {
|
|
124428
124936
|
const config = yield* ServerConfig$1;
|
|
124429
124937
|
const process = yield* VcsProcess;
|
|
124430
124938
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
@@ -124473,7 +124981,7 @@ const make$14 = Effect.gen(function* () {
|
|
|
124473
124981
|
sourceControlProviders: sourceControlProviders.discover
|
|
124474
124982
|
}) });
|
|
124475
124983
|
});
|
|
124476
|
-
const layer$
|
|
124984
|
+
const layer$8 = Layer.effect(SourceControlDiscovery, make$12);
|
|
124477
124985
|
//#endregion
|
|
124478
124986
|
//#region src/sourceControl/SourceControlRepositoryService.ts
|
|
124479
124987
|
const isSourceControlRepositoryError = Schema$1.is(SourceControlRepositoryError);
|
|
@@ -124506,7 +125014,7 @@ function expandHomePath(input, path) {
|
|
|
124506
125014
|
if (input.startsWith("~/") || input.startsWith("~\\")) return path.join(NodeOS.homedir(), input.slice(2));
|
|
124507
125015
|
return input;
|
|
124508
125016
|
}
|
|
124509
|
-
const make$
|
|
125017
|
+
const make$11 = Effect.gen(function* () {
|
|
124510
125018
|
const config = yield* ServerConfig$1;
|
|
124511
125019
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
124512
125020
|
const git = yield* GitVcsDriver;
|
|
@@ -124645,7 +125153,7 @@ const make$13 = Effect.gen(function* () {
|
|
|
124645
125153
|
publishRepository: (input) => publishRepository(input).pipe(mapRepositoryError("publishRepository", input.provider))
|
|
124646
125154
|
});
|
|
124647
125155
|
});
|
|
124648
|
-
const layer$
|
|
125156
|
+
const layer$7 = Layer.effect(SourceControlRepositoryService, make$11);
|
|
124649
125157
|
//#endregion
|
|
124650
125158
|
//#region src/ws.ts
|
|
124651
125159
|
/** Matches `p4c hub token add`, so a token minted here and one minted there are the same thing. */
|
|
@@ -124899,6 +125407,7 @@ const RPC_REQUIRED_SCOPE = /* @__PURE__ */ new Map([
|
|
|
124899
125407
|
[WS_METHODS.computerUseConnect, AuthOrchestrationOperateScope],
|
|
124900
125408
|
[WS_METHODS.computerUseList, AuthOrchestrationReadScope],
|
|
124901
125409
|
[WS_METHODS.computerUseControls, AuthOrchestrationReadScope],
|
|
125410
|
+
[WS_METHODS.computerUsePreview, AuthOrchestrationReadScope],
|
|
124902
125411
|
[WS_METHODS.computerUseControl, AuthOrchestrationOperateScope],
|
|
124903
125412
|
[WS_METHODS.computerUseRespond, AuthOrchestrationOperateScope],
|
|
124904
125413
|
[WS_METHODS.previewAutomationConnect, AuthOrchestrationOperateScope],
|
|
@@ -125989,6 +126498,7 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker, computerUseBrok
|
|
|
125989
126498
|
[WS_METHODS.previewReportStatus]: (input) => observeRpcEffect$1(WS_METHODS.previewReportStatus, previewManager.reportStatus(input), { "rpc.aggregate": "preview" }),
|
|
125990
126499
|
[WS_METHODS.computerUseList]: () => computerUseBroker.list,
|
|
125991
126500
|
[WS_METHODS.computerUseControls]: () => computerUseBroker.controls,
|
|
126501
|
+
[WS_METHODS.computerUsePreview]: (input) => computerUseBroker.preview(input),
|
|
125992
126502
|
[WS_METHODS.computerUseControl]: (input) => computerUseBroker.control(input),
|
|
125993
126503
|
[WS_METHODS.computerUseConnect]: () => Effect.fail(new ComputerUseError({
|
|
125994
126504
|
reason: "denied",
|
|
@@ -126083,7 +126593,7 @@ const websocketRpcRouteLayer = Layer.unwrap(Effect.gen(function* () {
|
|
|
126083
126593
|
const serverAuth = yield* EnvironmentAuth;
|
|
126084
126594
|
const sessions = yield* SessionStore;
|
|
126085
126595
|
const session = yield* serverAuth.authenticateWebSocketUpgrade(request).pipe(Effect.catchIf(isServerAuthCredentialError, (error) => failEnvironmentAuthInvalid(serverAuthCredentialReason(error))), Effect.catchIf(isServerAuthInternalError, (error) => failEnvironmentInternal("internal_error", error)));
|
|
126086
|
-
const rpcWebSocketHttpEffect = yield* RpcServer.toHttpEffectWebsocket(WsRpcGroup, { disableTracing: true }).pipe(Effect.provide(makeWsRpcLayer(session, previewAutomationBroker, computerUseBroker).pipe(Layer.provideMerge(RpcSerialization.layerJson), Layer.provide(layer$
|
|
126596
|
+
const rpcWebSocketHttpEffect = yield* RpcServer.toHttpEffectWebsocket(WsRpcGroup, { disableTracing: true }).pipe(Effect.provide(makeWsRpcLayer(session, previewAutomationBroker, computerUseBroker).pipe(Layer.provideMerge(RpcSerialization.layerJson), Layer.provide(layer$23), Layer.provide(Layer.succeed(ServerSelfUpdate, serverSelfUpdate)), Layer.provide(Layer.succeed(PullRequestService, pullRequests)), Layer.provide(Layer.succeed(TaskRepositoryRegistry, taskRepositories)), Layer.provide(Layer.succeed(ProjectionProjectRepository, projectionProjects)), Layer.provide(Layer.succeed(P4ProjectFileLoader, p4ProjectFileLoader)), Layer.provide(layer$8.pipe(Layer.provide(layer$33.pipe(Layer.provide(Layer.mergeAll(layer$41, layer$39, layer$37, layer$35)), Layer.provideMerge(layer$49), Layer.provide(layer$47.pipe(Layer.provide(layer$48))))), Layer.provide(layer$50))))));
|
|
126087
126597
|
return yield* Effect.acquireUseRelease(sessions.markConnected(session.sessionId), () => rpcWebSocketHttpEffect, () => sessions.markDisconnected(session.sessionId));
|
|
126088
126598
|
}).pipe(Effect.catchTags({
|
|
126089
126599
|
EnvironmentAuthInvalidError: HttpServerRespondable.toResponse,
|
|
@@ -126148,7 +126658,7 @@ function toPersistenceSqlOrDecodeError(sqlOperation, decodeOperation, correlatio
|
|
|
126148
126658
|
cause
|
|
126149
126659
|
});
|
|
126150
126660
|
}
|
|
126151
|
-
const make$
|
|
126661
|
+
const make$10 = Effect.gen(function* () {
|
|
126152
126662
|
const sql = yield* SqlClient.SqlClient;
|
|
126153
126663
|
const upsertRuntimeRow = SqlSchema.void({
|
|
126154
126664
|
Request: ProviderSessionRuntimeDbRowSchema,
|
|
@@ -126251,7 +126761,7 @@ const make$12 = Effect.gen(function* () {
|
|
|
126251
126761
|
deleteByThreadId
|
|
126252
126762
|
};
|
|
126253
126763
|
});
|
|
126254
|
-
const layer$
|
|
126764
|
+
const layer$6 = Layer.effect(ProviderSessionRuntimeRepository, make$10);
|
|
126255
126765
|
//#endregion
|
|
126256
126766
|
//#region src/provider/Layers/ProviderSessionDirectory.ts
|
|
126257
126767
|
const decodeProviderDriverKindValue = Schema$1.decodeUnknownEffect(ProviderDriverKind);
|
|
@@ -126704,7 +127214,7 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
126704
127214
|
});
|
|
126705
127215
|
});
|
|
126706
127216
|
let activeMcpSessionRegistry;
|
|
126707
|
-
const make$
|
|
127217
|
+
const make$9 = Effect.acquireRelease(Effect.gen(function* () {
|
|
126708
127218
|
const broker = yield* Effect.serviceOption(ComputerUseBroker);
|
|
126709
127219
|
return yield* makeWithOptions(Option.isSome(broker) ? { onRevoke: broker.value.invalidate } : {});
|
|
126710
127220
|
}).pipe(Effect.tap((registry) => Effect.sync(() => {
|
|
@@ -126712,7 +127222,7 @@ const make$11 = Effect.acquireRelease(Effect.gen(function* () {
|
|
|
126712
127222
|
}))), (registry) => registry.revokeAll.pipe(Effect.andThen(Effect.sync(() => {
|
|
126713
127223
|
if (activeMcpSessionRegistry === registry) activeMcpSessionRegistry = void 0;
|
|
126714
127224
|
}))));
|
|
126715
|
-
const layer$
|
|
127225
|
+
const layer$5 = Layer.effect(McpSessionRegistry, make$9);
|
|
126716
127226
|
const issueActiveMcpCredential = (request) => activeMcpSessionRegistry ? activeMcpSessionRegistry.revokeThread(request.threadId).pipe(Effect.andThen(activeMcpSessionRegistry.issue(request))) : Effect.sync(() => void 0);
|
|
126717
127227
|
/**
|
|
126718
127228
|
* Refreshes the liveness of a thread's MCP credential. Called on every provider
|
|
@@ -127094,7 +127604,7 @@ const makeProviderService = Effect.fn("makeProviderService")(function* (options)
|
|
|
127094
127604
|
threadId,
|
|
127095
127605
|
provider: resolvedProvider
|
|
127096
127606
|
};
|
|
127097
|
-
if (!instanceInfo.enabled) return yield* toValidationError("ProviderService.startSession", `Provider instance '${resolvedInstanceId}' is disabled in
|
|
127607
|
+
if (!instanceInfo.enabled) return yield* toValidationError("ProviderService.startSession", `Provider instance '${resolvedInstanceId}' is disabled in P4 Code settings.`);
|
|
127098
127608
|
const persistedBinding = Option.getOrUndefined(yield* directory.getBinding(threadId));
|
|
127099
127609
|
const effectiveResumeCursor = input.resumeCursor ?? (persistedBinding?.providerInstanceId === resolvedInstanceId ? persistedBinding.resumeCursor : void 0);
|
|
127100
127610
|
const effectiveCwd = input.cwd ?? (persistedBinding?.providerInstanceId === resolvedInstanceId ? readPersistedCwd(persistedBinding.runtimePayload) : void 0);
|
|
@@ -127183,7 +127693,10 @@ const makeProviderService = Effect.fn("makeProviderService")(function* (options)
|
|
|
127183
127693
|
status: "running",
|
|
127184
127694
|
...turn.resumeCursor !== void 0 ? { resumeCursor: turn.resumeCursor } : {},
|
|
127185
127695
|
runtimePayload: {
|
|
127186
|
-
...input.modelSelection !== void 0 ? {
|
|
127696
|
+
...input.modelSelection !== void 0 ? {
|
|
127697
|
+
model: input.modelSelection.model,
|
|
127698
|
+
modelSelection: input.modelSelection
|
|
127699
|
+
} : {},
|
|
127187
127700
|
activeTurnId: turn.turnId,
|
|
127188
127701
|
lastRuntimeEvent: "provider.sendTurn",
|
|
127189
127702
|
lastRuntimeEventAt: yield* nowIso
|
|
@@ -127657,7 +128170,7 @@ const mcpToolkit = (toolkit) => Layer.effectDiscard(Effect.gen(function* () {
|
|
|
127657
128170
|
//#endregion
|
|
127658
128171
|
//#region src/mcp/toolkits/computerUse/tools.ts
|
|
127659
128172
|
const ComputerUseJsTool = Tool.make("js", {
|
|
127660
|
-
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
|
|
128173
|
+
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 getAXState(), click(elementIndex), or setValue(elementIndex,text) to replace a field value in the background. Selection and getAXState print numbered accessibility state; Several deterministic actions against distinct unchanged elements may share one snapshot. Each used handle expires; the host revalidates remaining native handles and rejects changed elements. Read fresh state after the action batch before deciding the next action. getScreenshot() emits the selected app window; getAXStateAndScreenshot() emits both. Legacy getState(), click({elementId}), type({elementId,text}), windows(), and screenshot(windowId) remain supported. Native control preserves foreground focus and the system pointer. Coordinate, key, drag, scroll, and activation input are unsupported; do not use global input or activate the app as a fallback. P4Code shows the controlled native window and a persistent independent white pointer with a blue glow in its embedded live view. Hide closes only the view; use Show live view in the Computer Use control to reopen it. Stop ends thread control; reset clears the view and handles. Google Chrome can be controlled as a native app using cua.getApp('Google Chrome'); Chrome extension/CDP tab APIs are not exposed by this host. 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. Device hub simulators are scoped to the provider environment: await cua.listDevices(), then await cua.getDevice({hostId,deviceId,platform}) using exact discovered IDs. The device handle supports getAXState() (raw iOS accessibility state), getScreenshot(), getAXStateAndScreenshot(), click([x,y]) in device coordinates from fresh AX state, typeText(text), and close(). No device key, scroll, or drag APIs are currently exposed. Device consent must already be enabled in P4 Settings. Use timeout_ms:60000 for initial device startup. Reset invalidates device handles; device viewer sessions remain under Devices until explicitly closed. Never substitute macOS Simulator.app AX for simulated-app state.",
|
|
127661
128174
|
parameters: Schema$1.Struct({
|
|
127662
128175
|
...ComputerUseJsInput.fields,
|
|
127663
128176
|
hostId: Schema$1.optional(TrimmedNonEmptyString).annotate({ description: "Select an available host when more than one is connected. Reset before changing hosts." })
|
|
@@ -127730,163 +128243,6 @@ const register = Effect.fn("computerUse.register")(function* () {
|
|
|
127730
128243
|
/** Images use MCP image blocks instead of returning base64 in text output. */
|
|
127731
128244
|
const ComputerUseToolkitRegistrationLive = Layer.effectDiscard(register()).pipe(Layer.provide(ComputerUseToolkitHandlersLive));
|
|
127732
128245
|
//#endregion
|
|
127733
|
-
//#region src/device/DeviceScreenshot.ts
|
|
127734
|
-
const MAX_SCREENSHOT_BYTES = 8 * 1024 * 1024;
|
|
127735
|
-
var DeviceScreenshotFailure = class extends Data.TaggedError("DeviceScreenshotFailure") {};
|
|
127736
|
-
const MAX_DIMENSION = 16384;
|
|
127737
|
-
const MAX_PIXELS = 64 * 1024 * 1024;
|
|
127738
|
-
const SCREENSHOT_TIMEOUT_MS = 2e4;
|
|
127739
|
-
const PNG_HEADER_BYTES = 33;
|
|
127740
|
-
const PNG_CHUNK_OVERHEAD = 12;
|
|
127741
|
-
const PNG_SIGNATURE = Buffer.from([
|
|
127742
|
-
137,
|
|
127743
|
-
80,
|
|
127744
|
-
78,
|
|
127745
|
-
71,
|
|
127746
|
-
13,
|
|
127747
|
-
10,
|
|
127748
|
-
26,
|
|
127749
|
-
10
|
|
127750
|
-
]);
|
|
127751
|
-
function pngDimensions(png) {
|
|
127752
|
-
const buffer = Buffer.from(png.buffer, png.byteOffset, png.byteLength);
|
|
127753
|
-
if (buffer.length < PNG_HEADER_BYTES || buffer.length > 8388608 || !buffer.subarray(0, PNG_SIGNATURE.length).equals(PNG_SIGNATURE) || buffer.readUInt32BE(8) !== 13 || buffer.toString("ascii", 12, 16) !== "IHDR") throw new DeviceScreenshotFailure({ message: "Invalid PNG screenshot." });
|
|
127754
|
-
const width = buffer.readUInt32BE(16);
|
|
127755
|
-
const height = buffer.readUInt32BE(20);
|
|
127756
|
-
if (!width || !height || width > MAX_DIMENSION || height > MAX_DIMENSION || width * height > MAX_PIXELS) throw new DeviceScreenshotFailure({ message: "Screenshot dimensions exceed limits." });
|
|
127757
|
-
let offset = PNG_HEADER_BYTES;
|
|
127758
|
-
let imageData = false;
|
|
127759
|
-
let ended = false;
|
|
127760
|
-
while (offset + PNG_CHUNK_OVERHEAD <= buffer.length) {
|
|
127761
|
-
const length = buffer.readUInt32BE(offset);
|
|
127762
|
-
const type = buffer.toString("ascii", offset + 4, offset + 8);
|
|
127763
|
-
const next = offset + PNG_CHUNK_OVERHEAD + length;
|
|
127764
|
-
if (next > buffer.length || type === "IHDR") throw new DeviceScreenshotFailure({ message: "Invalid PNG chunk." });
|
|
127765
|
-
if (type === "IDAT") imageData = true;
|
|
127766
|
-
if (type === "IEND") {
|
|
127767
|
-
ended = length === 0 && next === buffer.length;
|
|
127768
|
-
break;
|
|
127769
|
-
}
|
|
127770
|
-
offset = next;
|
|
127771
|
-
}
|
|
127772
|
-
if (!imageData || !ended) throw new DeviceScreenshotFailure({ message: "Incomplete PNG screenshot." });
|
|
127773
|
-
return {
|
|
127774
|
-
width,
|
|
127775
|
-
height
|
|
127776
|
-
};
|
|
127777
|
-
}
|
|
127778
|
-
const make$10 = Effect.fn("DeviceScreenshot.make")(function* () {
|
|
127779
|
-
const http = yield* HttpClient.HttpClient;
|
|
127780
|
-
return Effect.fn("DeviceScreenshot.capture")(function* (ready, session) {
|
|
127781
|
-
const origin = yield* Effect.try(() => new URL(ready.hub.origin));
|
|
127782
|
-
if (origin.protocol !== "http:" || origin.hostname !== "127.0.0.1" || !origin.port || origin.username || origin.password || origin.pathname !== "/" || origin.search || origin.hash) return yield* new DeviceScreenshotFailure({ message: "Invalid owned hub." });
|
|
127783
|
-
const vendor = session.platform === "ios" ? "serve-sim" : "serve-emu";
|
|
127784
|
-
const response = yield* http.execute(HttpClientRequest.post(`${origin.origin}/vendor/${vendor}/api/screenshot?device=${encodeURIComponent(session.deviceId)}`));
|
|
127785
|
-
if (response.status !== 200) return yield* new DeviceScreenshotFailure({ message: "Screenshot rejected." });
|
|
127786
|
-
let bytes = 0;
|
|
127787
|
-
const chunks = [];
|
|
127788
|
-
yield* response.stream.pipe(Stream.runForEach((chunk) => Effect.gen(function* () {
|
|
127789
|
-
bytes += chunk.byteLength;
|
|
127790
|
-
if (bytes > 8388608) return yield* new DeviceScreenshotFailure({ message: "Screenshot too large." });
|
|
127791
|
-
chunks.push(chunk);
|
|
127792
|
-
})));
|
|
127793
|
-
const png = Buffer.concat(chunks, bytes);
|
|
127794
|
-
return {
|
|
127795
|
-
png,
|
|
127796
|
-
...yield* Effect.try(() => pngDimensions(png))
|
|
127797
|
-
};
|
|
127798
|
-
}, Effect.scoped, Effect.timeout(Duration.millis(SCREENSHOT_TIMEOUT_MS)), Effect.mapError(() => new DeviceOperationError({
|
|
127799
|
-
operation: "screenshot",
|
|
127800
|
-
reason: "request_failed",
|
|
127801
|
-
cause: "Device screenshot could not be captured."
|
|
127802
|
-
})));
|
|
127803
|
-
});
|
|
127804
|
-
var DeviceScreenshot = class extends Context.Service()("@p4code/cli/device/DeviceScreenshot") {};
|
|
127805
|
-
const layer$6 = Layer.effect(DeviceScreenshot, make$10().pipe(Effect.map((capture) => ({ capture }))));
|
|
127806
|
-
//#endregion
|
|
127807
|
-
//#region src/device/DeviceCommandProxy.ts
|
|
127808
|
-
var DeviceCommandProxyFailure = class extends Data.TaggedError("DeviceCommandProxyFailure") {};
|
|
127809
|
-
const COMMAND_TIMEOUT_MS = 3e4;
|
|
127810
|
-
const MAX_RESPONSE_BYTES$1 = 64 * 1024;
|
|
127811
|
-
const Reply = Schema$1.Struct({
|
|
127812
|
-
jsonrpc: Schema$1.Literal("2.0"),
|
|
127813
|
-
id: Schema$1.String,
|
|
127814
|
-
result: Schema$1.Struct({ ok: Schema$1.Boolean })
|
|
127815
|
-
});
|
|
127816
|
-
const make$9 = Effect.fn("DeviceCommandProxy.make")(function* () {
|
|
127817
|
-
const http = yield* HttpClient.HttpClient;
|
|
127818
|
-
const daemonSessions = /* @__PURE__ */ new WeakMap();
|
|
127819
|
-
return Effect.fn("DeviceCommandProxy.execute")(function* (endpoint, session, payload) {
|
|
127820
|
-
const input = yield* Schema$1.decodeUnknownEffect(DeviceCommandInput)(payload);
|
|
127821
|
-
if (input.hostId !== session.hostId || input.deviceId !== session.deviceId) return yield* new DeviceCommandProxyFailure({ message: "Target mismatch" });
|
|
127822
|
-
const origin = yield* Effect.try(() => new URL(endpoint.baseUrl));
|
|
127823
|
-
if (origin.protocol !== "http:" || origin.hostname !== "127.0.0.1" || !origin.port || origin.username || origin.password || origin.pathname !== "/" || origin.search || origin.hash) return yield* new DeviceCommandProxyFailure({ message: "Invalid owned daemon" });
|
|
127824
|
-
let daemonSession = daemonSessions.get(session);
|
|
127825
|
-
if (!daemonSession) {
|
|
127826
|
-
daemonSession = `p4-${NodeCrypto.randomUUID()}`;
|
|
127827
|
-
daemonSessions.set(session, daemonSession);
|
|
127828
|
-
}
|
|
127829
|
-
const id = NodeCrypto.randomUUID();
|
|
127830
|
-
const request = HttpClientRequest.post(`${origin.origin}/rpc`).pipe(HttpClientRequest.bodyJsonUnsafe({
|
|
127831
|
-
jsonrpc: "2.0",
|
|
127832
|
-
id,
|
|
127833
|
-
method: "agent_device.command",
|
|
127834
|
-
params: {
|
|
127835
|
-
token: endpoint.token,
|
|
127836
|
-
session: daemonSession,
|
|
127837
|
-
command: input.command,
|
|
127838
|
-
positionals: input.command === "press" ? [String(input.x), String(input.y)] : [input.text],
|
|
127839
|
-
flags: session.platform === "ios" ? {
|
|
127840
|
-
platform: "ios",
|
|
127841
|
-
udid: session.deviceId
|
|
127842
|
-
} : {
|
|
127843
|
-
platform: "android",
|
|
127844
|
-
serial: session.deviceId
|
|
127845
|
-
}
|
|
127846
|
-
}
|
|
127847
|
-
}));
|
|
127848
|
-
const response = yield* http.execute(request);
|
|
127849
|
-
if (response.status !== 200) return yield* new DeviceCommandProxyFailure({ message: "Command rejected" });
|
|
127850
|
-
let bytes = 0;
|
|
127851
|
-
const body = yield* collectUint8StreamText({
|
|
127852
|
-
stream: response.stream.pipe(Stream.mapEffect((chunk) => {
|
|
127853
|
-
bytes += chunk.byteLength;
|
|
127854
|
-
return bytes > MAX_RESPONSE_BYTES$1 ? Effect.fail(new DeviceCommandProxyFailure({ message: "Command response too large" })) : Effect.succeed(chunk);
|
|
127855
|
-
})),
|
|
127856
|
-
maxBytes: MAX_RESPONSE_BYTES$1
|
|
127857
|
-
});
|
|
127858
|
-
if (body.invalidUtf8 || body.truncated) return yield* new DeviceCommandProxyFailure({ message: "Invalid response" });
|
|
127859
|
-
const reply = yield* Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(Reply))(body.text);
|
|
127860
|
-
if (reply.id !== id || !reply.result.ok) return yield* new DeviceCommandProxyFailure({ message: "Command not acknowledged" });
|
|
127861
|
-
return { ok: true };
|
|
127862
|
-
}, Effect.scoped, Effect.timeout(Duration.millis(COMMAND_TIMEOUT_MS)), Effect.mapError(() => new DeviceOperationError({
|
|
127863
|
-
operation: "command",
|
|
127864
|
-
reason: "request_failed",
|
|
127865
|
-
cause: "Device command could not be completed."
|
|
127866
|
-
})));
|
|
127867
|
-
});
|
|
127868
|
-
var DeviceCommandProxy = class extends Context.Service()("@p4code/cli/device/DeviceCommandProxy") {};
|
|
127869
|
-
const layer$5 = Layer.effect(DeviceCommandProxy, make$9().pipe(Effect.map((execute) => ({ execute }))));
|
|
127870
|
-
//#endregion
|
|
127871
|
-
//#region src/mcp/DeviceInvocation.ts
|
|
127872
|
-
const isDeviceToolUnavailableError = Schema$1.is(DeviceToolUnavailableError);
|
|
127873
|
-
const isDeviceActionUnavailableError = Schema$1.is(DeviceActionUnavailableError);
|
|
127874
|
-
/** Internal bridge; tool payloads never choose thread identity or daemon credentials. */
|
|
127875
|
-
const withDeviceInvocation = (execute) => Effect.gen(function* () {
|
|
127876
|
-
const invocation = yield* McpInvocationContext;
|
|
127877
|
-
const service = yield* DeviceService;
|
|
127878
|
-
const lifetime = invocation.authorizationLifetime;
|
|
127879
|
-
const denied = () => new DeviceToolUnavailableError({ reason: "Device command unavailable or authorization changed." });
|
|
127880
|
-
if (!invocation.capabilities.has("devices") || !lifetime?.revocation || lifetime.revoked) return yield* denied();
|
|
127881
|
-
const work = execute(service, invocation.threadId).pipe(Effect.tap(() => lifetime.revoked ? Effect.fail(denied()) : Effect.void), Effect.mapError((error) => isDeviceToolUnavailableError(error) || isDeviceActionUnavailableError(error) ? error : denied()));
|
|
127882
|
-
return yield* Effect.raceFirst(work, Deferred.await(lifetime.revocation).pipe(Effect.andThen(Effect.fail(denied()))));
|
|
127883
|
-
});
|
|
127884
|
-
const withDeviceSession = (target, execute) => withDeviceInvocation((service, threadId) => service.withAgentCommand({
|
|
127885
|
-
hostId: target.hostId,
|
|
127886
|
-
deviceId: target.deviceId,
|
|
127887
|
-
threadId
|
|
127888
|
-
}, execute));
|
|
127889
|
-
//#endregion
|
|
127890
128246
|
//#region src/mcp/toolkits/devices/tools.ts
|
|
127891
128247
|
const DeviceCommandTool = Tool.make("device_command", {
|
|
127892
128248
|
description: "Press explicit screen coordinates or type text into the focused field on a device already opened in this thread. Requires separate agent device consent and the exact host/device session. Coordinates are device screen coordinates. No arbitrary CLI commands or flags are accepted.",
|
|
@@ -128867,14 +129223,29 @@ const ThreadPairCreateTool = Tool.make("thread_pair_create", {
|
|
|
128867
129223
|
Crypto.Crypto
|
|
128868
129224
|
]
|
|
128869
129225
|
}).annotate(Tool.Title, "Create a Fusion pair").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
129226
|
+
const ThreadPairDetachTool = Tool.make("thread_pair_detach", {
|
|
129227
|
+
description: "Detach this agent session's active Fusion pair, stopping future automatic supervisor reviews while preserving both threads. The session must be the pair's implementer and must have created its supervisor through thread_spawn.",
|
|
129228
|
+
parameters: ThreadPairDetachInput,
|
|
129229
|
+
success: ThreadPairDetachResult,
|
|
129230
|
+
failure: ThreadControlToolError,
|
|
129231
|
+
dependencies: [
|
|
129232
|
+
McpInvocationContext,
|
|
129233
|
+
OrchestrationEngineService,
|
|
129234
|
+
ProjectionSnapshotQuery,
|
|
129235
|
+
Crypto.Crypto
|
|
129236
|
+
]
|
|
129237
|
+
}).annotate(Tool.Title, "Detach Fusion pair").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
128870
129238
|
const ThreadConfigureTool = Tool.make("thread_configure", {
|
|
128871
|
-
description: "Change a thread's settings: title, model, permission mode, interaction mode, compression, and whether it may use subagents without asking. Omit threadId to configure this session's own thread; name one only if this session started it. Every field is optional and an omitted field is left alone; the settings actually changed come back in the result.",
|
|
129239
|
+
description: "Change a thread's settings: title, model, permission mode, interaction mode, compression, and whether it may use subagents without asking. Omit threadId to configure this session's own thread; name one only if this session started it. Supported model changes apply to the next turn, including automatic Fusion continuation. Started conversations cannot switch provider drivers or incompatible provider instances; such requests fail before any setting is changed. To use another provider, create a new thread with that selection (thread_spawn, optionally fusion: true) and preserve the current thread. Every field is optional and an omitted field is left alone; the settings actually changed come back in the result.",
|
|
128872
129240
|
parameters: ThreadConfigureInput,
|
|
128873
129241
|
success: ThreadConfigureResult,
|
|
128874
129242
|
failure: ThreadControlToolError,
|
|
128875
129243
|
dependencies: [
|
|
128876
129244
|
McpInvocationContext,
|
|
128877
129245
|
OrchestrationEngineService,
|
|
129246
|
+
ProjectionThreadRepository,
|
|
129247
|
+
ProjectionThreadSessionRepository,
|
|
129248
|
+
ProviderRegistry,
|
|
128878
129249
|
Crypto.Crypto
|
|
128879
129250
|
]
|
|
128880
129251
|
}).annotate(Tool.Title, "Configure a thread").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, true);
|
|
@@ -128963,7 +129334,7 @@ const ThreadPlanUpdateTool = Tool.make("thread_plan_update", {
|
|
|
128963
129334
|
Crypto.Crypto
|
|
128964
129335
|
]
|
|
128965
129336
|
}).annotate(Tool.Title, "Update task phases").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
128966
|
-
const ThreadToolkit = Toolkit.make(ThreadPlanUpdateTool, AskUserQuestionTool, ThreadSpawnTool, ThreadPairCreateTool, ThreadConfigureTool, ThreadSettleTool, ThreadCleanupTool, ThreadSnoozeTool, ThreadRenameTool, MemoryAppendTool, AssetCompressTool);
|
|
129337
|
+
const ThreadToolkit = Toolkit.make(ThreadPlanUpdateTool, AskUserQuestionTool, ThreadSpawnTool, ThreadPairCreateTool, ThreadPairDetachTool, ThreadConfigureTool, ThreadSettleTool, ThreadCleanupTool, ThreadSnoozeTool, ThreadRenameTool, MemoryAppendTool, AssetCompressTool);
|
|
128967
129338
|
//#endregion
|
|
128968
129339
|
//#region src/orchestration/pendingMcpUserInputs.ts
|
|
128969
129340
|
/**
|
|
@@ -129290,10 +129661,69 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
129290
129661
|
continuationMessageId
|
|
129291
129662
|
};
|
|
129292
129663
|
}),
|
|
129664
|
+
thread_pair_detach: (input) => Effect.gen(function* () {
|
|
129665
|
+
const invocation = yield* requireThreadCapability();
|
|
129666
|
+
const pair = ((yield* (yield* ProjectionSnapshotQuery).getCommandReadModel().pipe(Effect.mapError((cause) => new ThreadControlRejectedError({
|
|
129667
|
+
threadId: invocation.threadId,
|
|
129668
|
+
commandType: "thread-pair.detach",
|
|
129669
|
+
detail: `The active Fusion pair could not be read: ${cause.message}`
|
|
129670
|
+
})))).threadPairs ?? []).find((candidate) => candidate.id === input.pairId && candidate.detachedAt === null);
|
|
129671
|
+
if (pair === void 0) return yield* new ThreadControlRejectedError({
|
|
129672
|
+
threadId: invocation.threadId,
|
|
129673
|
+
commandType: "thread-pair.detach",
|
|
129674
|
+
detail: `Active Fusion pair '${input.pairId}' was not found.`
|
|
129675
|
+
});
|
|
129676
|
+
if (pair.implementerThreadId !== invocation.threadId) return yield* new ThreadControlRejectedError({
|
|
129677
|
+
threadId: invocation.threadId,
|
|
129678
|
+
commandType: "thread-pair.detach",
|
|
129679
|
+
detail: "This session is not the pair's implementer."
|
|
129680
|
+
});
|
|
129681
|
+
if (!invocation.controlThreadIds?.has(pair.watcherThreadId)) return yield* new ThreadControlRejectedError({
|
|
129682
|
+
threadId: invocation.threadId,
|
|
129683
|
+
commandType: "thread-pair.detach",
|
|
129684
|
+
detail: "This session did not create the pair's supervisor with thread_spawn."
|
|
129685
|
+
});
|
|
129686
|
+
const detachedAt = DateTime.formatIso(yield* DateTime.now);
|
|
129687
|
+
yield* dispatchControl({
|
|
129688
|
+
type: "thread-pair.detach",
|
|
129689
|
+
commandId: yield* newCommandId,
|
|
129690
|
+
pairId: pair.id,
|
|
129691
|
+
createdAt: detachedAt
|
|
129692
|
+
}, invocation.threadId);
|
|
129693
|
+
return {
|
|
129694
|
+
pairId: pair.id,
|
|
129695
|
+
implementerThreadId: pair.implementerThreadId,
|
|
129696
|
+
watcherThreadId: pair.watcherThreadId,
|
|
129697
|
+
detachedAt
|
|
129698
|
+
};
|
|
129699
|
+
}),
|
|
129293
129700
|
thread_configure: (input) => Effect.gen(function* () {
|
|
129294
129701
|
const { threadId } = yield* requireThreadControlTarget(input.threadId);
|
|
129295
129702
|
const createdAt = DateTime.formatIso(yield* DateTime.now);
|
|
129296
129703
|
const applied = [];
|
|
129704
|
+
if (input.modelSelection !== void 0) {
|
|
129705
|
+
const requested = input.modelSelection;
|
|
129706
|
+
const providers = yield* (yield* ProviderRegistry).getProviders;
|
|
129707
|
+
const target = providers.find((provider) => provider.instanceId === requested.instanceId);
|
|
129708
|
+
const rejectSelection = (detail) => new ThreadControlRejectedError({
|
|
129709
|
+
threadId,
|
|
129710
|
+
commandType: "thread.meta.update",
|
|
129711
|
+
detail
|
|
129712
|
+
});
|
|
129713
|
+
if (!target) return yield* rejectSelection(`Provider instance '${requested.instanceId}' is not configured.`);
|
|
129714
|
+
const session = yield* (yield* ProjectionThreadSessionRepository).getByThreadId({ threadId }).pipe(Effect.mapError((cause) => rejectSelection(cause.message)));
|
|
129715
|
+
if (Option.isSome(session)) {
|
|
129716
|
+
const thread = yield* (yield* ProjectionThreadRepository).getById({ threadId }).pipe(Effect.mapError((cause) => rejectSelection(cause.message)));
|
|
129717
|
+
if (Option.isSome(thread)) {
|
|
129718
|
+
const currentInstanceId = session.value.providerInstanceId ?? thread.value.modelSelection.instanceId;
|
|
129719
|
+
const current = providers.find((provider) => provider.instanceId === currentInstanceId);
|
|
129720
|
+
const instanceChanged = requested.instanceId !== currentInstanceId;
|
|
129721
|
+
const incompatible = instanceChanged && (!current || current.driver !== target.driver || !current.continuation || current.continuation.groupKey !== target.continuation?.groupKey);
|
|
129722
|
+
const requiresNewThread = (instanceChanged || requested.model !== thread.value.modelSelection.model) && (current?.requiresNewThreadForModelChange === true || target.requiresNewThreadForModelChange === true);
|
|
129723
|
+
if (incompatible || requiresNewThread) return yield* rejectSelection(`This conversation cannot switch to '${requested.model}' on '${requested.instanceId}'. Start a new thread with that provider and model, then enable Fusion there with the same supervisor settings. The current thread, checkout, history and Fusion pair are unchanged.`);
|
|
129724
|
+
}
|
|
129725
|
+
}
|
|
129726
|
+
}
|
|
129297
129727
|
if (input.title !== void 0 || input.modelSelection !== void 0) {
|
|
129298
129728
|
yield* dispatchControl({
|
|
129299
129729
|
type: "thread.meta.update",
|
|
@@ -133081,7 +133511,7 @@ const make$5 = Effect.gen(function* () {
|
|
|
133081
133511
|
const thread = yield* resolveThread(threadId);
|
|
133082
133512
|
if (!thread) return yield* Effect.die(/* @__PURE__ */ new Error(`Thread '${threadId}' was not found in read model.`));
|
|
133083
133513
|
const desiredRuntimeMode = thread.runtimeMode;
|
|
133084
|
-
const requestedModelSelection = options?.modelSelection;
|
|
133514
|
+
const requestedModelSelection = options?.modelSelection ?? thread.modelSelection;
|
|
133085
133515
|
const commandReadModel = yield* projectionSnapshotQuery.getCommandReadModel();
|
|
133086
133516
|
const watchThreadIds = (commandReadModel.threadPairs ?? []).filter((pair) => pair.detachedAt === null && pair.watcherThreadId === threadId).map((pair) => pair.implementerThreadId);
|
|
133087
133517
|
yield* Effect.forEach(watchThreadIds, (watchedThreadId) => grantActiveMcpWatchThread({
|
|
@@ -133100,7 +133530,7 @@ const make$5 = Effect.gen(function* () {
|
|
|
133100
133530
|
method: "thread.turn.start",
|
|
133101
133531
|
detail: `Thread '${threadId}' has an active provider session without a provider instance id.`
|
|
133102
133532
|
});
|
|
133103
|
-
const currentInstanceId = activeThreadSession !== null && activeSession !== void 0 && activeSession.providerInstanceId !== void 0 ? activeSession.providerInstanceId : thread.modelSelection.instanceId;
|
|
133533
|
+
const currentInstanceId = activeThreadSession !== null && activeSession !== void 0 && activeSession.providerInstanceId !== void 0 ? activeSession.providerInstanceId : thread.session?.providerInstanceId ?? thread.modelSelection.instanceId;
|
|
133104
133534
|
const desiredModelSelection = requestedModelSelection ?? thread.modelSelection;
|
|
133105
133535
|
const desiredInstanceId = desiredModelSelection.instanceId;
|
|
133106
133536
|
const currentInfo = yield* providerService.getInstanceInfo(currentInstanceId).pipe(Effect.mapError(() => new ProviderAdapterRequestError({
|
|
@@ -133264,11 +133694,18 @@ const make$5 = Effect.gen(function* () {
|
|
|
133264
133694
|
const thread = yield* resolveThread(input.threadId);
|
|
133265
133695
|
if (!thread) return yield* Effect.die(/* @__PURE__ */ new Error(`Thread '${input.threadId}' was not found in read model.`));
|
|
133266
133696
|
const hadActiveSession = thread.session !== null && thread.session.status !== "stopped";
|
|
133697
|
+
const modelForTurn = input.modelSelection ?? thread.modelSelection;
|
|
133267
133698
|
yield* ensureSessionForThread(input.threadId, input.createdAt, {
|
|
133268
|
-
|
|
133699
|
+
modelSelection: modelForTurn,
|
|
133269
133700
|
pendingTurnStart: true
|
|
133270
133701
|
});
|
|
133271
|
-
|
|
133702
|
+
threadModelSelections.set(input.threadId, modelForTurn);
|
|
133703
|
+
if (!Equal.equals(thread.modelSelection, modelForTurn)) yield* orchestrationEngine.dispatch({
|
|
133704
|
+
type: "thread.meta.update",
|
|
133705
|
+
commandId: yield* serverCommandId("turn-model-selection"),
|
|
133706
|
+
threadId: input.threadId,
|
|
133707
|
+
modelSelection: modelForTurn
|
|
133708
|
+
});
|
|
133272
133709
|
const normalizedInput = toNonEmptyProviderInput(input.messageText);
|
|
133273
133710
|
const expandedInput = normalizedInput === void 0 ? void 0 : (yield* expandUserInvokedSkill({
|
|
133274
133711
|
text: normalizedInput,
|
|
@@ -133326,16 +133763,6 @@ const make$5 = Effect.gen(function* () {
|
|
|
133326
133763
|
].join("\n\n");
|
|
133327
133764
|
const providerHasStructuredQuestionSystemPrompt = activeSession?.provider === "claudeAgent" || activeSession?.provider === "codex";
|
|
133328
133765
|
const inputWithStructuredQuestionPolicy = fusionInput !== void 0 && !providerHasStructuredQuestionSystemPrompt ? `${NON_SYSTEM_PROVIDER_STRUCTURED_USER_QUESTIONS}\n\n${fusionInput}` : fusionInput;
|
|
133329
|
-
const sessionModelSwitch = activeSession === void 0 ? "in-session" : activeSession.providerInstanceId === void 0 ? yield* new ProviderAdapterRequestError({
|
|
133330
|
-
provider: providerErrorLabel(activeSession.provider),
|
|
133331
|
-
method: "thread.turn.start",
|
|
133332
|
-
detail: `Active provider session '${activeSession.threadId}' is missing a provider instance id.`
|
|
133333
|
-
}) : (yield* providerService.getCapabilities(activeSession.providerInstanceId)).sessionModelSwitch;
|
|
133334
|
-
const requestedModelSelection = input.modelSelection ?? threadModelSelections.get(input.threadId) ?? thread.modelSelection;
|
|
133335
|
-
const modelForTurn = sessionModelSwitch === "unsupported" && input.modelSelection === void 0 ? activeSession?.model !== void 0 ? {
|
|
133336
|
-
...requestedModelSelection,
|
|
133337
|
-
model: activeSession.model
|
|
133338
|
-
} : requestedModelSelection : requestedModelSelection;
|
|
133339
133766
|
const compressMode = thread.compressMode;
|
|
133340
133767
|
const hasSessionLevelRuleset = activeSession?.provider === "claudeAgent" || activeSession?.provider === "codex";
|
|
133341
133768
|
const rebuildsRulesetEachTurn = activeSession?.provider === "codex";
|
|
@@ -133751,8 +134178,7 @@ const make$5 = Effect.gen(function* () {
|
|
|
133751
134178
|
case "thread.runtime-mode-set": {
|
|
133752
134179
|
const thread = yield* resolveThread(event.payload.threadId);
|
|
133753
134180
|
if (!thread?.session || thread.session.status === "stopped") return;
|
|
133754
|
-
|
|
133755
|
-
yield* ensureSessionForThread(event.payload.threadId, event.occurredAt, cachedModelSelection !== void 0 ? { modelSelection: cachedModelSelection } : {});
|
|
134181
|
+
yield* ensureSessionForThread(event.payload.threadId, event.occurredAt);
|
|
133756
134182
|
return;
|
|
133757
134183
|
}
|
|
133758
134184
|
case "thread.turn-start-requested":
|
|
@@ -136015,7 +136441,7 @@ const ObservabilityLive = Layer.unwrap(Effect.gen(function* () {
|
|
|
136015
136441
|
sink,
|
|
136016
136442
|
...delegate ? { delegate } : {}
|
|
136017
136443
|
});
|
|
136018
|
-
return Layer.mergeAll(Layer.succeed(Tracer.Tracer, tracer), layer$
|
|
136444
|
+
return Layer.mergeAll(Layer.succeed(Tracer.Tracer, tracer), layer$61(sink));
|
|
136019
136445
|
})).pipe(Layer.provide(OtlpExporter.layerFlusher), Layer.provideMerge(otlpSerializationLayer));
|
|
136020
136446
|
const metricsLayer = config.otlpMetricsUrl === void 0 ? Layer.empty : OtlpMetrics.layer({
|
|
136021
136447
|
url: config.otlpMetricsUrl,
|
|
@@ -136043,7 +136469,7 @@ const SqliteError = Schema$1.Struct({
|
|
|
136043
136469
|
const isSqliteError = Schema$1.is(SqliteError);
|
|
136044
136470
|
var ServerInstanceAlreadyRunningError = class extends Schema$1.TaggedErrorClass()("ServerInstanceAlreadyRunningError", { stateDir: Schema$1.String }) {
|
|
136045
136471
|
get message() {
|
|
136046
|
-
return `A
|
|
136472
|
+
return `A P4 Code server is already using ${this.stateDir}. Stop it before starting another server with the same P4 home.`;
|
|
136047
136473
|
}
|
|
136048
136474
|
};
|
|
136049
136475
|
var ServerInstanceLockError = class extends Schema$1.TaggedErrorClass()("ServerInstanceLockError", {
|
|
@@ -136052,7 +136478,7 @@ var ServerInstanceLockError = class extends Schema$1.TaggedErrorClass()("ServerI
|
|
|
136052
136478
|
cause: Schema$1.Defect()
|
|
136053
136479
|
}) {
|
|
136054
136480
|
get message() {
|
|
136055
|
-
return `Failed to ${this.operation}
|
|
136481
|
+
return `Failed to ${this.operation} P4 Code server lock at ${this.lockPath}.`;
|
|
136056
136482
|
}
|
|
136057
136483
|
};
|
|
136058
136484
|
const isSqliteBusy = (cause) => {
|
|
@@ -136387,31 +136813,31 @@ const PlatformServicesLive = Layer.unwrap(Effect.gen(function* () {
|
|
|
136387
136813
|
}
|
|
136388
136814
|
}));
|
|
136389
136815
|
const ReactorLayerLive = Layer.empty.pipe(Layer.provideMerge(OrchestrationReactorLive), Layer.provideMerge(ProviderRuntimeIngestionLive), Layer.provideMerge(ProviderCommandReactorLive), Layer.provideMerge(CheckpointReactorLive), Layer.provideMerge(ThreadDeletionReactorLive), Layer.provideMerge(FusionWatcherReactorLive), Layer.provideMerge(ScheduledTaskReactorLive), Layer.provideMerge(ThreadCompletionReactorLive), Layer.provideMerge(PullRequestSyncReactorLive), Layer.provideMerge(RuntimeReceiptBusLive));
|
|
136390
|
-
const ProviderSessionDirectoryLayerLive = ProviderSessionDirectoryLive.pipe(Layer.provide(layer$
|
|
136816
|
+
const ProviderSessionDirectoryLayerLive = ProviderSessionDirectoryLive.pipe(Layer.provide(layer$6));
|
|
136391
136817
|
const ProviderLayerLive = ProviderServiceLive.pipe(Layer.provide(ProviderAdapterRegistryLive), Layer.provideMerge(ProviderSessionDirectoryLayerLive));
|
|
136392
136818
|
const PersistenceLayerLive = Layer.empty.pipe(Layer.provideMerge(layerConfig));
|
|
136393
|
-
const VcsDriverRegistryLayerLive = layer$
|
|
136394
|
-
const SourceControlProviderRegistryLayerLive = layer$
|
|
136395
|
-
const GitManagerLayerLive = layer$
|
|
136396
|
-
const GitLayerLive = Layer.empty.pipe(Layer.provideMerge(GitManagerLayerLive), Layer.provideMerge(layer$
|
|
136397
|
-
const GitWorkflowLayerLive = layer$
|
|
136398
|
-
const SourceControlRepositoryServiceLayerLive = layer$
|
|
136399
|
-
const ReviewLayerLive = layer$
|
|
136400
|
-
const VcsLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$
|
|
136401
|
-
const PullRequestServiceLive = layer$
|
|
136402
|
-
const CheckpointingLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$
|
|
136403
|
-
const PortScannerLayerLive = layer$
|
|
136404
|
-
const TerminalLayerLive = layer$
|
|
136405
|
-
const PreviewLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$
|
|
136406
|
-
const WorkspaceEntriesLayerLive = layer$
|
|
136407
|
-
const WorkspaceFileSystemLayerLive = layer$
|
|
136819
|
+
const VcsDriverRegistryLayerLive = layer$47.pipe(Layer.provide(layer$48));
|
|
136820
|
+
const SourceControlProviderRegistryLayerLive = layer$33.pipe(Layer.provide(Layer.mergeAll(layer$41, layer$39, layer$37, layer$35)), Layer.provideMerge(layer$49), Layer.provideMerge(VcsDriverRegistryLayerLive));
|
|
136821
|
+
const GitManagerLayerLive = layer$32.pipe(Layer.provideMerge(layer$42), Layer.provideMerge(layer$49), Layer.provideMerge(SourceControlProviderRegistryLayerLive), Layer.provideMerge(layer$58));
|
|
136822
|
+
const GitLayerLive = Layer.empty.pipe(Layer.provideMerge(GitManagerLayerLive), Layer.provideMerge(layer$49));
|
|
136823
|
+
const GitWorkflowLayerLive = layer$31.pipe(Layer.provideMerge(VcsDriverRegistryLayerLive), Layer.provideMerge(GitLayerLive));
|
|
136824
|
+
const SourceControlRepositoryServiceLayerLive = layer$7.pipe(Layer.provideMerge(layer$49), Layer.provideMerge(SourceControlProviderRegistryLayerLive));
|
|
136825
|
+
const ReviewLayerLive = layer$12.pipe(Layer.provideMerge(layer$49), Layer.provideMerge(VcsDriverRegistryLayerLive));
|
|
136826
|
+
const VcsLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$48), Layer.provideMerge(VcsDriverRegistryLayerLive), Layer.provideMerge(layer$13.pipe(Layer.provide(VcsDriverRegistryLayerLive))), Layer.provideMerge(GitWorkflowLayerLive), Layer.provideMerge(ReviewLayerLive), Layer.provideMerge(SourceControlRepositoryServiceLayerLive), Layer.provideMerge(layer$14.pipe(Layer.provide(autoPullPolicyLayer), Layer.provide(GitWorkflowLayerLive))));
|
|
136827
|
+
const PullRequestServiceLive = layer$25.pipe(Layer.provide(layer$26), Layer.provide(SourceControlProviderRegistryLayerLive), Layer.provide(layer$50));
|
|
136828
|
+
const CheckpointingLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$45), Layer.provideMerge(layer$46.pipe(Layer.provide(VcsDriverRegistryLayerLive))));
|
|
136829
|
+
const PortScannerLayerLive = layer$44.pipe(Layer.provide(layer$81));
|
|
136830
|
+
const TerminalLayerLive = layer$43.pipe(Layer.provide(PtyAdapterLive), Layer.provide(PortScannerLayerLive));
|
|
136831
|
+
const PreviewLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$18), Layer.provideMerge(PortScannerLayerLive));
|
|
136832
|
+
const WorkspaceEntriesLayerLive = layer$16.pipe(Layer.provide(layer$68));
|
|
136833
|
+
const WorkspaceFileSystemLayerLive = layer$15.pipe(Layer.provide(layer$68), Layer.provide(WorkspaceEntriesLayerLive));
|
|
136408
136834
|
const WorkspaceLayerLive = Layer.mergeAll(layer$68, WorkspaceEntriesLayerLive, WorkspaceFileSystemLayerLive);
|
|
136409
|
-
const ProjectFaviconResolverLayerLive = layer$
|
|
136835
|
+
const ProjectFaviconResolverLayerLive = layer$62.pipe(Layer.provide(layer$68), Layer.provide(layer$63));
|
|
136410
136836
|
const AuthLayerLive = layer$110.pipe(Layer.provideMerge(PersistenceLayerLive), Layer.provide(layer$114));
|
|
136411
136837
|
const ProviderRuntimeLayerLive = ProviderSessionReaperLive.pipe(Layer.provideMerge(ProviderLayerLive), Layer.provideMerge(OrchestrationLayerLive));
|
|
136412
|
-
const RuntimeCoreDependenciesLive = ReactorLayerLive.pipe(Layer.provideMerge(layer$
|
|
136413
|
-
const UsageLayerLive = layer$
|
|
136414
|
-
const RuntimeDependenciesLive = layer$
|
|
136838
|
+
const RuntimeCoreDependenciesLive = ReactorLayerLive.pipe(Layer.provideMerge(layer$24), Layer.provideMerge(Layer.mergeAll(PullRequestServiceLive, CheckpointingLayerLive, SourceControlProviderRegistryLayerLive)), Layer.provideMerge(GitLayerLive), Layer.provideMerge(VcsLayerLive), Layer.provideMerge(ProviderAuthServiceLive), Layer.provideMerge(ProviderRuntimeLayerLive), Layer.provideMerge(Layer.mergeAll(TerminalLayerLive, PreviewLayerLive, RoutedTaskRepositoryLive)), Layer.provideMerge(Layer.mergeAll(PersistenceLayerLive, layer$85)), Layer.provideMerge(layer$79), Layer.provideMerge(ProviderRegistryLive), Layer.provideMerge(layer$57), Layer.provideMerge(Layer.mergeAll(layer$56, layer$70.pipe(Layer.provide(layer$81)), layer$66, layer$67)), Layer.provideMerge(layer$51), Layer.provideMerge(layer$52), Layer.provideMerge(layer$53), Layer.provideMerge(layer$54), Layer.provideMerge(layer$55)).pipe(Layer.provideMerge(ProviderInstanceRegistryHydrationLive), Layer.provideMerge(AntigravityInstallation.layer), Layer.provideMerge(ProviderEventLoggersLive), Layer.provideMerge(OpenCodeRuntimeLive), Layer.provideMerge(layer$59), Layer.provideMerge(layer$89.pipe(Layer.provide(layer$114))), Layer.provideMerge(WorkspaceLayerLive), Layer.provideMerge(ProjectFaviconResolverLayerLive), Layer.provideMerge(layer$80), Layer.provideMerge(layer$65), Layer.provideMerge(remoteComputerUseBindingsLayer.pipe(Layer.provide(layer$85))), Layer.provideMerge(layer$73), Layer.provideMerge(AuthLayerLive), Layer.provideMerge(layer$4.pipe(Layer.provideMerge(LinearClientLive), Layer.provideMerge(Layer.mergeAll(LinearMcpClientLive, TrackerSecretsLive)), Layer.provideMerge(Layer.mergeAll(layer$86, layer$20).pipe(Layer.provideMerge(layer$87), Layer.provideMerge(layer$88))))), Layer.provideMerge(layer$114));
|
|
136839
|
+
const UsageLayerLive = layer$22.pipe(Layer.provide(layer$89.pipe(Layer.provide(layer$114))));
|
|
136840
|
+
const RuntimeDependenciesLive = layer$21.pipe(Layer.provideMerge(RuntimeCoreDependenciesLive)).pipe(Layer.provideMerge(UsageLayerLive), Layer.provideMerge(layer$11), Layer.provideMerge(layer$10), Layer.provideMerge(layer$9), Layer.provideMerge(layer$76), Layer.provideMerge(layer$78), Layer.provideMerge(layer$77), Layer.provide(layer$118));
|
|
136415
136841
|
/**
|
|
136416
136842
|
* Hub asset sync.
|
|
136417
136843
|
*
|
|
@@ -136421,7 +136847,7 @@ const RuntimeDependenciesLive = layer$23.pipe(Layer.provideMerge(RuntimeCoreDepe
|
|
|
136421
136847
|
*/
|
|
136422
136848
|
const AssetSyncLive = layer$83.pipe(Layer.provideMerge(layer$84), Layer.provideMerge(layer$85));
|
|
136423
136849
|
const RuntimeServicesLive = layer$69.pipe(Layer.provideMerge(AssetSyncLive), Layer.provideMerge(RuntimeDependenciesLive));
|
|
136424
|
-
const makeRoutesLayer = Layer.mergeAll(Layer.mergeAll(HttpApiBuilder.layer(EnvironmentHttpApi).pipe(Layer.provide(authHttpApiLayer), Layer.provide(orchestrationHttpApiLayer), Layer.provide(pullRequestHttpApiLayer), Layer.provide(serverEnvironmentHttpApiLayer), Layer.provide(environmentAuthenticatedAuthLayer)), otlpTracesProxyRouteLayer, assetRouteLayer, mcpOAuthCallbackRouteLayer, staticAndDevRouteLayer, websocketRpcRouteLayer), layer$3.pipe(Layer.provide(layer$
|
|
136850
|
+
const makeRoutesLayer = Layer.mergeAll(Layer.mergeAll(HttpApiBuilder.layer(EnvironmentHttpApi).pipe(Layer.provide(authHttpApiLayer), Layer.provide(orchestrationHttpApiLayer), Layer.provide(pullRequestHttpApiLayer), Layer.provide(serverEnvironmentHttpApiLayer), Layer.provide(environmentAuthenticatedAuthLayer)), otlpTracesProxyRouteLayer, assetRouteLayer, mcpOAuthCallbackRouteLayer, staticAndDevRouteLayer, websocketRpcRouteLayer), layer$3.pipe(Layer.provide(layer$5)), layer$64, layer).pipe(Layer.provide(ProjectionProjectRepositoryLive.pipe(Layer.provide(PersistenceLayerLive))), Layer.provide(ProjectionThreadRepositoryLive.pipe(Layer.provide(PersistenceLayerLive))), Layer.provide(layer$63), Layer.provide(layer$24), Layer.provide(PullRequestServiceLive), Layer.provide(layer$19), Layer.provide(layer$74), Layer.provide(browserApiCorsLayer), Layer.provide(httpCompressionLayer));
|
|
136425
136851
|
const makeServerLayer = Layer.unwrap(Effect.gen(function* () {
|
|
136426
136852
|
const config = yield* ServerConfig$1;
|
|
136427
136853
|
yield* fixPath();
|
|
@@ -136464,7 +136890,7 @@ const makeServerLayer = Layer.unwrap(Effect.gen(function* () {
|
|
|
136464
136890
|
cause,
|
|
136465
136891
|
servePort: configured.servePort
|
|
136466
136892
|
}))) : Effect.void)) : Layer.empty;
|
|
136467
|
-
const fullyProvisionedServerLayer = Layer.mergeAll(HttpRouter.serve(makeRoutesLayer, { disableLogger: !config.logWebSocketEvents }), httpListeningLayer, runtimeStateLayer, tailscaleServeLayer, layer$1, layer$2).pipe(Layer.provideMerge(RuntimeServicesLive), Layer.provideMerge(HttpResponseCompressionLive), Layer.provideMerge(HttpServerLive), Layer.provide(ObservabilityLive), Layer.provideMerge(FetchHttpClient.layer), Layer.provideMerge(layer$
|
|
136893
|
+
const fullyProvisionedServerLayer = Layer.mergeAll(HttpRouter.serve(makeRoutesLayer, { disableLogger: !config.logWebSocketEvents }), httpListeningLayer, runtimeStateLayer, tailscaleServeLayer, layer$1, layer$2).pipe(Layer.provideMerge(RuntimeServicesLive), Layer.provideMerge(HttpResponseCompressionLive), Layer.provideMerge(HttpServerLive), Layer.provide(ObservabilityLive), Layer.provideMerge(FetchHttpClient.layer), Layer.provideMerge(layer$50));
|
|
136468
136894
|
return Layer.unwrap(Effect.gen(function* () {
|
|
136469
136895
|
yield* acquireServerInstanceLock(config.stateDir);
|
|
136470
136896
|
return fullyProvisionedServerLayer;
|
|
@@ -136477,8 +136903,8 @@ const runServerCommand = (flags, options) => Effect.gen(function* () {
|
|
|
136477
136903
|
const config = yield* resolveServerConfig(flags, yield* GlobalFlag.LogLevel, options);
|
|
136478
136904
|
return yield* runServer.pipe(Effect.provideService(ServerConfig$1, config));
|
|
136479
136905
|
});
|
|
136480
|
-
const startCommand = Command.make("start", { ...sharedServerCommandFlags }).pipe(Command.withDescription("Run the
|
|
136481
|
-
const serveCommand = Command.make("serve", { ...sharedServerCommandFlags }).pipe(Command.withDescription("Run the
|
|
136906
|
+
const startCommand = Command.make("start", { ...sharedServerCommandFlags }).pipe(Command.withDescription("Run the P4 Code server."), Command.withHandler((flags) => runServerCommand(flags)));
|
|
136907
|
+
const serveCommand = Command.make("serve", { ...sharedServerCommandFlags }).pipe(Command.withDescription("Run the P4 Code server without opening a browser and print headless pairing details."), Command.withHandler((flags) => runServerCommand(flags, {
|
|
136482
136908
|
startupPresentation: "headless",
|
|
136483
136909
|
forceAutoBootstrapProjectFromCwd: false
|
|
136484
136910
|
})));
|
|
@@ -136873,16 +137299,16 @@ const reconcileService = Effect.fn("cli.service.reconcile")(function* () {
|
|
|
136873
137299
|
const LAUNCH_AGENT_LOGIN_NOTE = "This runs as a login item, so it starts when you log in. For an unattended machine, enable automatic login in System Settings › Users & Groups.";
|
|
136874
137300
|
function formatReconcileSuccess(input) {
|
|
136875
137301
|
return [
|
|
136876
|
-
`${input.previouslyInstalled ? "Updated" : "Installed"}
|
|
137302
|
+
`${input.previouslyInstalled ? "Updated" : "Installed"} P4 Code service with @p4code/cli@${input.cliVersion}.`,
|
|
136877
137303
|
`Logs: ${input.plan.logPath}`,
|
|
136878
137304
|
...input.platform === "darwin" && !input.previouslyInstalled ? [LAUNCH_AGENT_LOGIN_NOTE] : []
|
|
136879
137305
|
].join("\n");
|
|
136880
137306
|
}
|
|
136881
137307
|
function formatServiceStatus(status, cliVersion, lastUpdate) {
|
|
136882
|
-
if (!status.supported) return "
|
|
136883
|
-
if (!status.installed) return "
|
|
137308
|
+
if (!status.supported) return "P4 Code service\n Status: unavailable on this machine\n Supported on: Linux with systemd, macOS with launchd";
|
|
137309
|
+
if (!status.installed) return "P4 Code service\n Status: not installed\n Next: Run `p4c service install`.";
|
|
136884
137310
|
return [
|
|
136885
|
-
"
|
|
137311
|
+
"P4 Code service",
|
|
136886
137312
|
` Status: ${status.current ? `installed · @p4code/cli@${cliVersion}` : "needs an update or repair"}`,
|
|
136887
137313
|
` Unit: ${status.unitPath}`,
|
|
136888
137314
|
` Data: ${status.baseDir}`,
|
|
@@ -136935,10 +137361,10 @@ const serviceInstallCommand = Command.make("install", {
|
|
|
136935
137361
|
...projectLocationFlags,
|
|
136936
137362
|
tailscaleServe: tailscaleServeFlag,
|
|
136937
137363
|
tailscaleServePort: tailscaleServePortFlag
|
|
136938
|
-
}).pipe(Command.withDescription("Install
|
|
137364
|
+
}).pipe(Command.withDescription("Install P4 Code as a background service for this user."), Command.withHandler((flags) => runServiceCommand(flags, Effect.gen(function* () {
|
|
136939
137365
|
const result = yield* reconcileService();
|
|
136940
137366
|
if (!result.changed) {
|
|
136941
|
-
yield* Console.log(`
|
|
137367
|
+
yield* Console.log(`P4 Code service is already installed with @p4code/cli@${version$1}.`);
|
|
136942
137368
|
return;
|
|
136943
137369
|
}
|
|
136944
137370
|
yield* Console.log(formatReconcileSuccess({
|
|
@@ -136965,7 +137391,7 @@ const serviceUpdateCommand = Command.make("update", projectLocationFlags).pipe(C
|
|
|
136965
137391
|
});
|
|
136966
137392
|
}
|
|
136967
137393
|
if (!outcome.result.changed) {
|
|
136968
|
-
yield* Console.log(`Restarted the
|
|
137394
|
+
yield* Console.log(`Restarted the P4 Code service on @p4code/cli@${version$1}.`);
|
|
136969
137395
|
return;
|
|
136970
137396
|
}
|
|
136971
137397
|
yield* Console.log(formatReconcileSuccess({
|
|
@@ -136975,9 +137401,9 @@ const serviceUpdateCommand = Command.make("update", projectLocationFlags).pipe(C
|
|
|
136975
137401
|
platform: yield* HostProcessPlatform
|
|
136976
137402
|
}));
|
|
136977
137403
|
}))));
|
|
136978
|
-
const serviceUninstallCommand = Command.make("uninstall", projectLocationFlags).pipe(Command.withDescription("Stop and remove the
|
|
137404
|
+
const serviceUninstallCommand = Command.make("uninstall", projectLocationFlags).pipe(Command.withDescription("Stop and remove the P4 Code background service."), Command.withHandler((flags) => runServiceCommand(flags, Effect.gen(function* () {
|
|
136979
137405
|
const removed = yield* (yield* BootService).uninstall;
|
|
136980
|
-
yield* Console.log(removed ? "Removed the
|
|
137406
|
+
yield* Console.log(removed ? "Removed the P4 Code service." : "P4 Code service is not installed.");
|
|
136981
137407
|
}))));
|
|
136982
137408
|
/**
|
|
136983
137409
|
* Restart without rewriting the unit.
|
|
@@ -136991,11 +137417,11 @@ const serviceUninstallCommand = Command.make("uninstall", projectLocationFlags).
|
|
|
136991
137417
|
const serviceRestartCommand = Command.make("restart", projectLocationFlags).pipe(Command.withDescription("Restart the background service without changing its configuration."), Command.withHandler((flags) => runServiceCommand(flags, Effect.gen(function* () {
|
|
136992
137418
|
const service = yield* BootService;
|
|
136993
137419
|
if (!(yield* service.status).installed) {
|
|
136994
|
-
yield* Console.error("
|
|
137420
|
+
yield* Console.error("P4 Code service is not installed. Install it with: p4c service install");
|
|
136995
137421
|
return;
|
|
136996
137422
|
}
|
|
136997
137423
|
yield* service.restart;
|
|
136998
|
-
yield* Console.log("Restarted the
|
|
137424
|
+
yield* Console.log("Restarted the P4 Code service.");
|
|
136999
137425
|
}))));
|
|
137000
137426
|
/**
|
|
137001
137427
|
* Install a newer CLI, then point the service at it.
|
|
@@ -137030,7 +137456,7 @@ const serviceSelfUpdateCommand = Command.make("self-update", {
|
|
|
137030
137456
|
});
|
|
137031
137457
|
yield* Console.log(`Service now runs @p4code/cli@${installed}.`);
|
|
137032
137458
|
}))));
|
|
137033
|
-
const serviceStatusCommand = Command.make("status", projectLocationFlags).pipe(Command.withDescription("Show whether the
|
|
137459
|
+
const serviceStatusCommand = Command.make("status", projectLocationFlags).pipe(Command.withDescription("Show whether the P4 Code background service is installed."), Command.withHandler((flags) => runServiceCommand(flags, Effect.gen(function* () {
|
|
137034
137460
|
const status = yield* (yield* BootService).status;
|
|
137035
137461
|
const recorded = yield* readServiceUpdateState(status.baseDir);
|
|
137036
137462
|
yield* Console.log(formatServiceStatus(status, version$1, Option.match(recorded, {
|
|
@@ -137042,18 +137468,18 @@ Effect.gen(function* () {
|
|
|
137042
137468
|
const { supported, installed, current } = yield* (yield* BootService).status;
|
|
137043
137469
|
if (!supported) return false;
|
|
137044
137470
|
if (installed && current) {
|
|
137045
|
-
yield* Console.log("
|
|
137471
|
+
yield* Console.log("P4 Code is already set up to run in the background on this machine.");
|
|
137046
137472
|
return true;
|
|
137047
137473
|
}
|
|
137048
137474
|
if (!(yield* Prompt.run(Prompt.confirm({
|
|
137049
|
-
message: installed ? "The installed
|
|
137475
|
+
message: installed ? "The installed P4 Code service needs an update or repair. Update it now?" : "Run P4 Code in the background whenever this machine boots? It stays reachable to your other devices over the network.",
|
|
137050
137476
|
initial: true
|
|
137051
137477
|
})))) return false;
|
|
137052
137478
|
const result = yield* reconcileService();
|
|
137053
137479
|
if (result.changed) yield* Console.log(`Background service ${result.previouslyInstalled ? "updated" : "installed"}. Logs: ${result.plan.logPath}`);
|
|
137054
137480
|
return true;
|
|
137055
137481
|
});
|
|
137056
|
-
const serviceCommand = Command.make("service").pipe(Command.withDescription("Manage the
|
|
137482
|
+
const serviceCommand = Command.make("service").pipe(Command.withDescription("Manage the P4 Code background service."), Command.withSubcommands([
|
|
137057
137483
|
serviceInstallCommand,
|
|
137058
137484
|
serviceUninstallCommand,
|
|
137059
137485
|
serviceUpdateCommand,
|
|
@@ -137090,7 +137516,7 @@ const reportUpdateAvailable = Effect.gen(function* () {
|
|
|
137090
137516
|
* conflict we chose. Taking a name nothing else claims deletes the problem
|
|
137091
137517
|
* rather than managing it.
|
|
137092
137518
|
*/
|
|
137093
|
-
const makeCli = () => Command.make("p4c", { ...sharedServerCommandFlags }).pipe(Command.withDescription("Run the
|
|
137519
|
+
const makeCli = () => Command.make("p4c", { ...sharedServerCommandFlags }).pipe(Command.withDescription("Run the P4 Code server."), Command.withHandler((flags) => runServerCommand(flags)), Command.withSubcommands([
|
|
137094
137520
|
startCommand,
|
|
137095
137521
|
serveCommand,
|
|
137096
137522
|
agentsCommand,
|