@p4code/cli 0.5.16 → 0.5.19
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 +1318 -345
- package/dist/client/assets/DiffPanel-84e5yR38.js +98 -0
- package/dist/client/assets/{FilePreviewPanel-ByLSi1JL.js → FilePreviewPanel-DP6xLZJC.js} +6 -6
- package/dist/client/assets/PreviewPanel-DZ2KnATb.js +2 -0
- package/dist/client/assets/PullRequestCodeTab-C2tGKiR3.js +251 -0
- package/dist/client/assets/{fileCommentAnnotations-T78XG7k8.js → fileCommentAnnotations-BYG5V0WE.js} +2 -2
- package/dist/client/assets/{index-DwVt0vnY.js → index-Mc3jtKyQ.js} +257 -239
- package/dist/client/assets/previewAssetResource-D9vbUdlh.js +48 -0
- package/dist/client/assets/{renderFileChildren-BcefTgOQ.js → renderFileChildren-DxnrMWfd.js} +2 -2
- package/dist/client/assets/{toggle-group-NIaLKwkg.js → toggle-group-CZwEfgZs.js} +2 -2
- package/dist/client/index.html +2 -2
- package/package.json +1 -1
- package/dist/client/assets/DiffPanel-D67u97Q2.js +0 -98
- package/dist/client/assets/PreviewPanel-hzSHtmkO.js +0 -2
- package/dist/client/assets/PullRequestCodeTab-DoXs9qKG.js +0 -251
- package/dist/client/assets/previewAssetResource-CKOao7Zb.js +0 -48
package/dist/bin.mjs
CHANGED
|
@@ -153,7 +153,7 @@ const closeServer = (server) => {
|
|
|
153
153
|
* NetService - Service tag for startup networking helpers.
|
|
154
154
|
*/
|
|
155
155
|
var NetService = class extends Context.Service()("@p4code/shared/Net/NetService") {};
|
|
156
|
-
const make$
|
|
156
|
+
const make$122 = () => {
|
|
157
157
|
/**
|
|
158
158
|
* Returns true when a TCP server can bind to {host, port}.
|
|
159
159
|
* `EADDRNOTAVAIL` is treated as available so IPv6-absent hosts don't fail
|
|
@@ -262,10 +262,10 @@ const make$120 = () => {
|
|
|
262
262
|
})
|
|
263
263
|
};
|
|
264
264
|
};
|
|
265
|
-
const layer$122 = Layer.sync(NetService, make$
|
|
265
|
+
const layer$122 = Layer.sync(NetService, make$122);
|
|
266
266
|
//#endregion
|
|
267
267
|
//#region package.json
|
|
268
|
-
var version$1 = "0.5.
|
|
268
|
+
var version$1 = "0.5.19";
|
|
269
269
|
//#endregion
|
|
270
270
|
//#region src/config.ts
|
|
271
271
|
/**
|
|
@@ -286,8 +286,8 @@ var ServerConfig$1 = class extends Context.Service()("@p4code/cli/config/ServerC
|
|
|
286
286
|
/** @deprecated Import and use `layerTest` from this module. */
|
|
287
287
|
static layerTest = (cwd, baseDirOrPrefix) => layerTest$4(cwd, baseDirOrPrefix);
|
|
288
288
|
};
|
|
289
|
-
const make$
|
|
290
|
-
const layer$121 = (config) => Layer.succeed(ServerConfig$1, make$
|
|
289
|
+
const make$121 = (config) => ServerConfig$1.of(config);
|
|
290
|
+
const layer$121 = (config) => Layer.succeed(ServerConfig$1, make$121(config));
|
|
291
291
|
const deriveServerPaths = Effect.fn(function* (baseDir, devUrl, options = {}) {
|
|
292
292
|
const { join } = yield* Path$1.Path;
|
|
293
293
|
const stateDir = join(baseDir, devUrl !== void 0 && !options.baseDirIsExplicit ? "dev" : "userdata");
|
|
@@ -3521,6 +3521,21 @@ const OrchestrationThreadActivity = Schema$1.Struct({
|
|
|
3521
3521
|
sequence: Schema$1.optional(NonNegativeInt),
|
|
3522
3522
|
createdAt: IsoDateTime
|
|
3523
3523
|
});
|
|
3524
|
+
/**
|
|
3525
|
+
* The activity a turn gets when Jev (TypeSafe System One) answered for it.
|
|
3526
|
+
*
|
|
3527
|
+
* One per consultation, never merged: a turn that took a skill hint and a
|
|
3528
|
+
* workspace choice from Jev carries two, and each names what it decided.
|
|
3529
|
+
* Silence, a timeout or a declined answer append nothing, so the row's
|
|
3530
|
+
* presence is the whole claim.
|
|
3531
|
+
*/
|
|
3532
|
+
const JEV_CONSULTED_ACTIVITY_KIND = "jev.consulted";
|
|
3533
|
+
const JevConsultedFeature = Schema$1.Literals(["capability-hints", "auto-workspace"]);
|
|
3534
|
+
Schema$1.Struct({
|
|
3535
|
+
feature: JevConsultedFeature,
|
|
3536
|
+
/** What Jev decided, in one short clause: "Suggested: design, publish". */
|
|
3537
|
+
summary: TrimmedNonEmptyString
|
|
3538
|
+
});
|
|
3524
3539
|
const OrchestrationLatestTurnState = Schema$1.Literals([
|
|
3525
3540
|
"running",
|
|
3526
3541
|
"interrupted",
|
|
@@ -10400,6 +10415,11 @@ const ClientSettingsSchema = Schema$1.Struct({
|
|
|
10400
10415
|
})).pipe(Schema$1.withDecodingDefault(Effect.succeed(13)))
|
|
10401
10416
|
});
|
|
10402
10417
|
const DEFAULT_CLIENT_SETTINGS = Schema$1.decodeSync(ClientSettingsSchema)({});
|
|
10418
|
+
const DEFAULT_JEV_PREFETCH_TIMEOUT_MS = 2e3;
|
|
10419
|
+
const JevPrefetchTimeoutMs = Schema$1.Int.check(Schema$1.isBetween({
|
|
10420
|
+
minimum: 100,
|
|
10421
|
+
maximum: 3e4
|
|
10422
|
+
}));
|
|
10403
10423
|
const ThreadEnvMode = Schema$1.Literals([
|
|
10404
10424
|
"auto",
|
|
10405
10425
|
"local",
|
|
@@ -10766,6 +10786,32 @@ const ServerSettings = Schema$1.Struct({
|
|
|
10766
10786
|
/** Supervisor wake pre-filter; disabled by default. */
|
|
10767
10787
|
fusionReviewTriage: FusionReviewTriageSettings.pipe(Schema$1.withDecodingDefault(Effect.succeed(Schema$1.decodeUnknownSync(FusionReviewTriageSettings)({})))),
|
|
10768
10788
|
/**
|
|
10789
|
+
* Whether a turn asks Jev which of this environment's capabilities to name
|
|
10790
|
+
* to the model before its first request.
|
|
10791
|
+
*
|
|
10792
|
+
* One environment-wide switch rather than a per-thread control: which skills
|
|
10793
|
+
* and commands exist is a fact about the machine, not about a conversation,
|
|
10794
|
+
* and nobody wants to answer the same question on every new thread. The
|
|
10795
|
+
* ranking is advisory - it adds a few names to the turn and changes nothing
|
|
10796
|
+
* else - so the cost of leaving it on is a short request, which is why it is
|
|
10797
|
+
* on by default.
|
|
10798
|
+
*
|
|
10799
|
+
* Off removes the request entirely. So does a missing Jev key, a timeout or
|
|
10800
|
+
* an unreadable answer: every one of those is the same turn the agent would
|
|
10801
|
+
* have had before this setting existed.
|
|
10802
|
+
*/
|
|
10803
|
+
enableJevPrefetch: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(true))),
|
|
10804
|
+
/** Maximum per-turn wait for capability hints; failures continue without hints. */
|
|
10805
|
+
jevPrefetchTimeoutMs: JevPrefetchTimeoutMs.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_JEV_PREFETCH_TIMEOUT_MS))),
|
|
10806
|
+
/**
|
|
10807
|
+
* Whether Auto checkout mode asks Jev to choose between the current
|
|
10808
|
+
* checkout and a fresh worktree before falling back to the text generation
|
|
10809
|
+
* model. Same shape as `enableJevPrefetch`: environment-wide, on by
|
|
10810
|
+
* default, and every failure path is the decision the turn would have
|
|
10811
|
+
* made without it.
|
|
10812
|
+
*/
|
|
10813
|
+
enableJevAutoWorkspace: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(true))),
|
|
10814
|
+
/**
|
|
10769
10815
|
* Whether the board offers the scoping agent: the Scope action on a task and
|
|
10770
10816
|
* the panel that drafts a new one by interview.
|
|
10771
10817
|
*
|
|
@@ -10995,6 +11041,9 @@ const ServerSettingsPatch = Schema$1.Struct({
|
|
|
10995
11041
|
fusionSummarizerModel: Schema$1.optionalKey(Schema$1.NullOr(ModelSelection)),
|
|
10996
11042
|
fusionPromptOverrides: Schema$1.optionalKey(FusionPromptOverrides),
|
|
10997
11043
|
fusionReviewTriage: Schema$1.optionalKey(FusionReviewTriageSettings),
|
|
11044
|
+
enableJevPrefetch: Schema$1.optionalKey(Schema$1.Boolean),
|
|
11045
|
+
jevPrefetchTimeoutMs: Schema$1.optionalKey(JevPrefetchTimeoutMs),
|
|
11046
|
+
enableJevAutoWorkspace: Schema$1.optionalKey(Schema$1.Boolean),
|
|
10998
11047
|
enableScopingAgent: Schema$1.optionalKey(Schema$1.Boolean),
|
|
10999
11048
|
enablePlanPhase: Schema$1.optionalKey(Schema$1.Boolean),
|
|
11000
11049
|
writeGeneratedSkillsToRepo: Schema$1.optionalKey(Schema$1.Boolean),
|
|
@@ -12575,7 +12624,7 @@ const ThreadSpawnInput = Schema$1.Struct({
|
|
|
12575
12624
|
interactionMode: Schema$1.optional(ProviderInteractionMode),
|
|
12576
12625
|
compressMode: Schema$1.optional(CompressMode),
|
|
12577
12626
|
unpromptedSubagents: Schema$1.optional(Schema$1.Boolean),
|
|
12578
|
-
fusion: Schema$1.optional(Schema$1.Boolean.annotate({ description: "Create two new threads as a separate Fusion pair, then start the
|
|
12627
|
+
fusion: Schema$1.optional(Schema$1.Boolean.annotate({ description: "Create two new threads as a separate Fusion pair, then start the supervisor with prompt. The builder stays empty until advised. Leaves the caller and its existing pair unchanged. Cannot be combined with fusionWatcher." })),
|
|
12579
12628
|
fusionWatcher: Schema$1.optional(Schema$1.Boolean.annotate({ description: "Set true only when creating the watcher to pair with the current thread. Defaults to the saved Fusion supervisor model. No special user command syntax is required." }))
|
|
12580
12629
|
});
|
|
12581
12630
|
const ThreadSpawnResult = Schema$1.Struct({
|
|
@@ -12587,16 +12636,16 @@ const ThreadSpawnResult = Schema$1.Struct({
|
|
|
12587
12636
|
watcherThreadId: Schema$1.optional(ThreadId)
|
|
12588
12637
|
});
|
|
12589
12638
|
const ThreadPairCreateInput = Schema$1.Struct({
|
|
12590
|
-
watcherThreadId: ThreadId.annotate({ description: "
|
|
12639
|
+
watcherThreadId: Schema$1.optional(ThreadId.annotate({ description: "Legacy pairing: use an existing spawned supervisor and keep this chat as builder. Omit to keep this chat and its history as supervisor and create a new empty builder, idle until advised." })),
|
|
12591
12640
|
gateTimeoutMs: Schema$1.optional(NonNegativeInt.annotate({ description: "How long a gate waits on the supervisor before failing open, in milliseconds. Defaults to 120000." }))
|
|
12592
12641
|
});
|
|
12593
12642
|
const ThreadPairCreateResult = Schema$1.Struct({
|
|
12594
12643
|
pairId: ThreadPairId,
|
|
12595
12644
|
implementerThreadId: ThreadId,
|
|
12596
12645
|
watcherThreadId: ThreadId,
|
|
12597
|
-
continuationMessageId: MessageId
|
|
12646
|
+
continuationMessageId: Schema$1.optional(MessageId)
|
|
12598
12647
|
});
|
|
12599
|
-
const ThreadPairDetachInput = Schema$1.Struct({ pairId: ThreadPairId.annotate({ description: "The active Fusion pair to detach. This session must
|
|
12648
|
+
const ThreadPairDetachInput = Schema$1.Struct({ pairId: ThreadPairId.annotate({ description: "The active Fusion pair to detach. This session must belong to the pair and must have created its other thread." }) });
|
|
12600
12649
|
const ThreadPairDetachResult = Schema$1.Struct({
|
|
12601
12650
|
pairId: ThreadPairId,
|
|
12602
12651
|
implementerThreadId: ThreadId,
|
|
@@ -16072,7 +16121,7 @@ function deriveAuthClientMetadata(input) {
|
|
|
16072
16121
|
//#endregion
|
|
16073
16122
|
//#region src/auth/EnvironmentAuthPolicy.ts
|
|
16074
16123
|
var EnvironmentAuthPolicy = class extends Context.Service()("@p4code/cli/auth/EnvironmentAuthPolicy") {};
|
|
16075
|
-
const make$
|
|
16124
|
+
const make$120 = Effect.gen(function* () {
|
|
16076
16125
|
const config = yield* ServerConfig$1;
|
|
16077
16126
|
const isRemoteReachable = isRemoteReachableHost(config.host);
|
|
16078
16127
|
const policy = config.mode === "desktop" ? isRemoteReachable ? "remote-reachable" : "desktop-managed-local" : isRemoteReachable ? "remote-reachable" : "loopback-browser";
|
|
@@ -16090,7 +16139,7 @@ const make$118 = Effect.gen(function* () {
|
|
|
16090
16139
|
};
|
|
16091
16140
|
return EnvironmentAuthPolicy.of({ getDescriptor: () => Effect.succeed(descriptor).pipe(Effect.withSpan("EnvironmentAuthPolicy.getDescriptor")) });
|
|
16092
16141
|
});
|
|
16093
|
-
const layer$120 = Layer.effect(EnvironmentAuthPolicy, make$
|
|
16142
|
+
const layer$120 = Layer.effect(EnvironmentAuthPolicy, make$120);
|
|
16094
16143
|
//#endregion
|
|
16095
16144
|
//#region src/persistence/Errors.ts
|
|
16096
16145
|
function summarizeSchemaIssue(issue) {
|
|
@@ -16271,7 +16320,7 @@ function toPersistenceSqlOrDecodeError$6(sqlOperation, decodeOperation, correlat
|
|
|
16271
16320
|
cause
|
|
16272
16321
|
});
|
|
16273
16322
|
}
|
|
16274
|
-
const make$
|
|
16323
|
+
const make$119 = Effect.gen(function* () {
|
|
16275
16324
|
const sql = yield* SqlClient.SqlClient;
|
|
16276
16325
|
const createSessionRow = SqlSchema.void({
|
|
16277
16326
|
Request: CreateAuthSessionInput,
|
|
@@ -16405,7 +16454,7 @@ const make$117 = Effect.gen(function* () {
|
|
|
16405
16454
|
setLastConnectedAt
|
|
16406
16455
|
};
|
|
16407
16456
|
});
|
|
16408
|
-
const layer$119 = Layer.effect(AuthSessionRepository, make$
|
|
16457
|
+
const layer$119 = Layer.effect(AuthSessionRepository, make$119);
|
|
16409
16458
|
//#endregion
|
|
16410
16459
|
//#region src/auth/ServerSecretStore.ts
|
|
16411
16460
|
const secretStoreErrorContext = {
|
|
@@ -16547,11 +16596,11 @@ const makeForDirectory = Effect.fn("ServerSecretStore.makeForDirectory")(functio
|
|
|
16547
16596
|
remove
|
|
16548
16597
|
});
|
|
16549
16598
|
});
|
|
16550
|
-
const make$
|
|
16599
|
+
const make$118 = Effect.gen(function* () {
|
|
16551
16600
|
const config = yield* ServerConfig$1;
|
|
16552
16601
|
return yield* makeForDirectory(config.secretsDir);
|
|
16553
16602
|
});
|
|
16554
|
-
const layer$118 = Layer.effect(ServerSecretStore, make$
|
|
16603
|
+
const layer$118 = Layer.effect(ServerSecretStore, make$118);
|
|
16555
16604
|
//#endregion
|
|
16556
16605
|
//#region src/auth/SessionStore.ts
|
|
16557
16606
|
var MalformedSessionTokenError = class extends Schema$1.TaggedErrorClass()("MalformedSessionTokenError", {}) {
|
|
@@ -16789,7 +16838,7 @@ function toAuthClientSession(input) {
|
|
|
16789
16838
|
current: false
|
|
16790
16839
|
};
|
|
16791
16840
|
}
|
|
16792
|
-
const make$
|
|
16841
|
+
const make$117 = Effect.gen(function* () {
|
|
16793
16842
|
const crypto = yield* Crypto.Crypto;
|
|
16794
16843
|
const serverConfig = yield* ServerConfig$1;
|
|
16795
16844
|
const secretStore = yield* ServerSecretStore;
|
|
@@ -17104,7 +17153,7 @@ const make$115 = Effect.gen(function* () {
|
|
|
17104
17153
|
markDisconnected
|
|
17105
17154
|
});
|
|
17106
17155
|
});
|
|
17107
|
-
const layer$117 = Layer.effect(SessionStore, make$
|
|
17156
|
+
const layer$117 = Layer.effect(SessionStore, make$117).pipe(Layer.provideMerge(layer$119));
|
|
17108
17157
|
//#endregion
|
|
17109
17158
|
//#region src/persistence/AuthPairingLinks.ts
|
|
17110
17159
|
const AuthPairingLinkRecord = Schema$1.Struct({
|
|
@@ -17165,7 +17214,7 @@ function toPersistenceSqlOrDecodeError$5(sqlOperation, decodeOperation, correlat
|
|
|
17165
17214
|
cause
|
|
17166
17215
|
});
|
|
17167
17216
|
}
|
|
17168
|
-
const make$
|
|
17217
|
+
const make$116 = Effect.gen(function* () {
|
|
17169
17218
|
const sql = yield* SqlClient.SqlClient;
|
|
17170
17219
|
const createPairingLinkRow = SqlSchema.void({
|
|
17171
17220
|
Request: CreateAuthPairingLinkInput,
|
|
@@ -17300,7 +17349,7 @@ const make$114 = Effect.gen(function* () {
|
|
|
17300
17349
|
getByCredential
|
|
17301
17350
|
};
|
|
17302
17351
|
});
|
|
17303
|
-
const layer$116 = Layer.effect(AuthPairingLinkRepository, make$
|
|
17352
|
+
const layer$116 = Layer.effect(AuthPairingLinkRepository, make$116);
|
|
17304
17353
|
//#endregion
|
|
17305
17354
|
//#region src/auth/PairingGrantStore.ts
|
|
17306
17355
|
var UnknownBootstrapCredentialError = class extends Schema$1.TaggedErrorClass()("UnknownBootstrapCredentialError", {}) {
|
|
@@ -17395,7 +17444,7 @@ const DEV_STARTUP_TTL_HOURS = Duration.hours(24);
|
|
|
17395
17444
|
const PAIRING_TOKEN_ALPHABET = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
|
|
17396
17445
|
const PAIRING_TOKEN_LENGTH = 12;
|
|
17397
17446
|
const PAIRING_TOKEN_REJECTION_LIMIT = Math.floor(256 / 32) * 32;
|
|
17398
|
-
const make$
|
|
17447
|
+
const make$115 = Effect.gen(function* () {
|
|
17399
17448
|
const crypto = yield* Crypto.Crypto;
|
|
17400
17449
|
const config = yield* ServerConfig$1;
|
|
17401
17450
|
const pairingLinks = yield* AuthPairingLinkRepository;
|
|
@@ -17593,7 +17642,7 @@ const make$113 = Effect.gen(function* () {
|
|
|
17593
17642
|
consume
|
|
17594
17643
|
});
|
|
17595
17644
|
});
|
|
17596
|
-
const layer$115 = Layer.effect(PairingGrantStore, make$
|
|
17645
|
+
const layer$115 = Layer.effect(PairingGrantStore, make$115).pipe(Layer.provideMerge(layer$116));
|
|
17597
17646
|
//#endregion
|
|
17598
17647
|
//#region src/persistence/DatabaseSnapshot.ts
|
|
17599
17648
|
/**
|
|
@@ -20978,7 +21027,7 @@ function parseBearerToken(request) {
|
|
|
20978
21027
|
const token = header.slice(7).trim();
|
|
20979
21028
|
return token.length > 0 ? token : null;
|
|
20980
21029
|
}
|
|
20981
|
-
const make$
|
|
21030
|
+
const make$114 = Effect.gen(function* () {
|
|
20982
21031
|
const policy = yield* EnvironmentAuthPolicy;
|
|
20983
21032
|
const bootstrapCredentials = yield* PairingGrantStore;
|
|
20984
21033
|
const sessions = yield* SessionStore;
|
|
@@ -21173,7 +21222,7 @@ const make$112 = Effect.gen(function* () {
|
|
|
21173
21222
|
issueStartupPairingUrl
|
|
21174
21223
|
});
|
|
21175
21224
|
});
|
|
21176
|
-
const layer$114 = Layer.effect(EnvironmentAuth, make$
|
|
21225
|
+
const layer$114 = Layer.effect(EnvironmentAuth, make$114).pipe(Layer.provideMerge(layer$115), Layer.provideMerge(layer$117), Layer.provideMerge(layer$120));
|
|
21177
21226
|
const storageLayer = Layer.mergeAll(layer$118, layerConfig);
|
|
21178
21227
|
const runtimeLayer = layer$114.pipe(Layer.provideMerge(storageLayer));
|
|
21179
21228
|
//#endregion
|
|
@@ -23169,7 +23218,7 @@ const DEFAULT_LIMITS = {
|
|
|
23169
23218
|
windowMillis: FAILURE_WINDOW_MS$1,
|
|
23170
23219
|
blockMillis: BLOCK_DURATION_MS
|
|
23171
23220
|
};
|
|
23172
|
-
const make$
|
|
23221
|
+
const make$113 = Effect.fn("HubAuthThrottle.make")(function* (limits = DEFAULT_LIMITS) {
|
|
23173
23222
|
const state = yield* Ref.make(initialThrottleState);
|
|
23174
23223
|
return HubAuthThrottle.of({
|
|
23175
23224
|
shouldRefuse: Effect.gen(function* () {
|
|
@@ -23183,7 +23232,7 @@ const make$111 = Effect.fn("HubAuthThrottle.make")(function* (limits = DEFAULT_L
|
|
|
23183
23232
|
})
|
|
23184
23233
|
});
|
|
23185
23234
|
});
|
|
23186
|
-
const layer$113 = Layer.effect(HubAuthThrottle, make$
|
|
23235
|
+
const layer$113 = Layer.effect(HubAuthThrottle, make$113());
|
|
23187
23236
|
//#endregion
|
|
23188
23237
|
//#region src/hub/HubAuth.ts
|
|
23189
23238
|
/**
|
|
@@ -25165,12 +25214,12 @@ const persistHubAgentActivity = Effect.fn("HubNotificationActivity.persist")(fun
|
|
|
25165
25214
|
var HubSecretStoreUnavailable = class extends Data.TaggedError("HubSecretStoreUnavailable") {};
|
|
25166
25215
|
const HUB_SECRETS_SUFFIX = ".secrets";
|
|
25167
25216
|
/** Dedicated sibling directory per Hub database; no environment configuration is consulted. */
|
|
25168
|
-
const make$
|
|
25217
|
+
const make$112 = Effect.gen(function* () {
|
|
25169
25218
|
const config = yield* HubConfig;
|
|
25170
25219
|
if (!(yield* Path$1.Path).isAbsolute(config.dbPath)) return yield* Effect.fail(new HubSecretStoreUnavailable({ message: "Hub secret storage requires an absolute database path." }));
|
|
25171
25220
|
return yield* makeForDirectory(`${config.dbPath}${HUB_SECRETS_SUFFIX}`);
|
|
25172
25221
|
});
|
|
25173
|
-
const layer$107 = Layer.effect(ServerSecretStore, make$
|
|
25222
|
+
const layer$107 = Layer.effect(ServerSecretStore, make$112);
|
|
25174
25223
|
//#endregion
|
|
25175
25224
|
//#region src/hub/HubNotificationRoutes.ts
|
|
25176
25225
|
const MAX_NOTIFICATION_BODY_BYTES = 16 * 1024;
|
|
@@ -29268,7 +29317,7 @@ function stripDefaultServerSettings(current, defaults) {
|
|
|
29268
29317
|
}
|
|
29269
29318
|
return Object.is(current, defaults) ? void 0 : current;
|
|
29270
29319
|
}
|
|
29271
|
-
const make$
|
|
29320
|
+
const make$111 = Effect.gen(function* () {
|
|
29272
29321
|
const { settingsPath } = yield* ServerConfig$1;
|
|
29273
29322
|
const fs = yield* FileSystem.FileSystem;
|
|
29274
29323
|
const pathService = yield* Path$1.Path;
|
|
@@ -29491,7 +29540,7 @@ const make$109 = Effect.gen(function* () {
|
|
|
29491
29540
|
}
|
|
29492
29541
|
};
|
|
29493
29542
|
});
|
|
29494
|
-
const layer$93 = Layer.effect(ServerSettingsService, make$
|
|
29543
|
+
const layer$93 = Layer.effect(ServerSettingsService, make$111);
|
|
29495
29544
|
//#endregion
|
|
29496
29545
|
//#region src/pathExpansion.ts
|
|
29497
29546
|
/**
|
|
@@ -29731,13 +29780,17 @@ function parseMarkdownFrontmatter(contents) {
|
|
|
29731
29780
|
const name = typeof record.name === "string" ? record.name.trim() : "";
|
|
29732
29781
|
const description = typeof record.description === "string" ? record.description.trim() : "";
|
|
29733
29782
|
const disableModelInvocation = readFrontmatterBoolean(record["disable-model-invocation"]);
|
|
29783
|
+
const tools = Array.isArray(record.tools) ? record.tools.flatMap((tool) => typeof tool === "string" && tool.trim() ? [tool.trim()] : []) : void 0;
|
|
29784
|
+
const model = typeof record.model === "string" ? record.model.trim() : "";
|
|
29734
29785
|
const requiredInteractionMode = record["required-interaction-mode"] === "default" || record["required-interaction-mode"] === "plan" ? record["required-interaction-mode"] : void 0;
|
|
29735
29786
|
return {
|
|
29736
29787
|
kind: "parsed",
|
|
29737
29788
|
...name ? { name } : {},
|
|
29738
29789
|
...description ? { description } : {},
|
|
29739
29790
|
...disableModelInvocation === void 0 ? {} : { disableModelInvocation },
|
|
29740
|
-
...requiredInteractionMode === void 0 ? {} : { requiredInteractionMode }
|
|
29791
|
+
...requiredInteractionMode === void 0 ? {} : { requiredInteractionMode },
|
|
29792
|
+
...tools && tools.length > 0 ? { tools } : {},
|
|
29793
|
+
...model ? { model } : {}
|
|
29741
29794
|
};
|
|
29742
29795
|
}
|
|
29743
29796
|
//#endregion
|
|
@@ -30041,6 +30094,42 @@ const discoverClaudeSkills = Effect.fn("discoverClaudeSkills")(function* (config
|
|
|
30041
30094
|
scope: "project"
|
|
30042
30095
|
}] : []], disabledSkills);
|
|
30043
30096
|
});
|
|
30097
|
+
/**
|
|
30098
|
+
* Load named subagent definitions from the user config dir.
|
|
30099
|
+
*
|
|
30100
|
+
* The CLI finds these itself whenever the `user` setting source is loaded, so
|
|
30101
|
+
* nothing calls this on an ordinary session. It exists for the sessions that
|
|
30102
|
+
* drop that source and still owe the user a specific agent - a Fusion half
|
|
30103
|
+
* under the lean context profile, which must still run the delivery reviewer.
|
|
30104
|
+
* Reading only the names asked for keeps that session from paying for the rest
|
|
30105
|
+
* of the user's agents, which is what dropping the source bought.
|
|
30106
|
+
*
|
|
30107
|
+
* Best-effort like the skill discovery beside it: a missing or malformed
|
|
30108
|
+
* definition is skipped rather than failing the session, because a session
|
|
30109
|
+
* that cannot start is worse than one missing an agent.
|
|
30110
|
+
*/
|
|
30111
|
+
const discoverClaudeUserAgents = Effect.fn("discoverClaudeUserAgents")(function* (config, names, environment, cwd) {
|
|
30112
|
+
if (names.length === 0) return {};
|
|
30113
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
30114
|
+
const path = yield* Path$1.Path;
|
|
30115
|
+
const agentsDir = yield* resolveClaudeUserAgentsDir(config, environment, cwd);
|
|
30116
|
+
const definitions = {};
|
|
30117
|
+
for (const name of names) {
|
|
30118
|
+
const contents = yield* fileSystem.readFileString(path.join(agentsDir, `${name}.md`)).pipe(Effect.orElseSucceed(() => void 0));
|
|
30119
|
+
if (contents === void 0) continue;
|
|
30120
|
+
const frontmatter = parseMarkdownFrontmatter(contents);
|
|
30121
|
+
if (frontmatter.kind !== "parsed") continue;
|
|
30122
|
+
const prompt = stripMarkdownFrontmatter(contents);
|
|
30123
|
+
if (frontmatter.description === void 0 || prompt.length === 0) continue;
|
|
30124
|
+
definitions[name] = {
|
|
30125
|
+
description: frontmatter.description,
|
|
30126
|
+
prompt,
|
|
30127
|
+
...frontmatter.tools ? { tools: frontmatter.tools } : {},
|
|
30128
|
+
...frontmatter.model ? { model: frontmatter.model } : {}
|
|
30129
|
+
};
|
|
30130
|
+
}
|
|
30131
|
+
return definitions;
|
|
30132
|
+
});
|
|
30044
30133
|
//#endregion
|
|
30045
30134
|
//#region src/mcp/ClaudeMcpFiles.ts
|
|
30046
30135
|
/**
|
|
@@ -30153,7 +30242,7 @@ function claudeEntryFromRegistration(registration) {
|
|
|
30153
30242
|
};
|
|
30154
30243
|
}
|
|
30155
30244
|
var ClaudeMcpFiles = class extends Context.Service()("@p4code/cli/mcp/ClaudeMcpFiles") {};
|
|
30156
|
-
const make$
|
|
30245
|
+
const make$110 = Effect.gen(function* () {
|
|
30157
30246
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
30158
30247
|
const path = yield* Path$1.Path;
|
|
30159
30248
|
const services = yield* Effect.context();
|
|
@@ -30220,7 +30309,7 @@ const make$108 = Effect.gen(function* () {
|
|
|
30220
30309
|
removeProject: (projectDir, name) => removeAt(Effect.succeed(projectFile(projectDir)))(name)
|
|
30221
30310
|
};
|
|
30222
30311
|
});
|
|
30223
|
-
const layer$92 = Layer.effect(ClaudeMcpFiles, make$
|
|
30312
|
+
const layer$92 = Layer.effect(ClaudeMcpFiles, make$110);
|
|
30224
30313
|
Layer.succeed(ClaudeMcpFiles, {
|
|
30225
30314
|
readUser: Effect.succeed([]),
|
|
30226
30315
|
readUserAt: () => Effect.succeed([]),
|
|
@@ -30358,7 +30447,7 @@ const decodeClientRegistration = Schema$1.decodeUnknownExit(ClientRegistrationRe
|
|
|
30358
30447
|
const decodeTokenResponse = Schema$1.decodeUnknownExit(TokenResponse);
|
|
30359
30448
|
var McpOAuth = class extends Context.Service()("@p4code/cli/mcp/McpOAuth") {};
|
|
30360
30449
|
const registryError = (detail) => new McpRegistryError({ detail });
|
|
30361
|
-
const make$
|
|
30450
|
+
const make$109 = Effect.gen(function* () {
|
|
30362
30451
|
const config = yield* ServerConfig$1;
|
|
30363
30452
|
const secrets = yield* ServerSecretStore;
|
|
30364
30453
|
const http = yield* HttpClient.HttpClient;
|
|
@@ -30678,7 +30767,7 @@ const make$107 = Effect.gen(function* () {
|
|
|
30678
30767
|
accessTokenFor
|
|
30679
30768
|
};
|
|
30680
30769
|
});
|
|
30681
|
-
const layer$91 = Layer.effect(McpOAuth, make$
|
|
30770
|
+
const layer$91 = Layer.effect(McpOAuth, make$109);
|
|
30682
30771
|
Layer.succeed(McpOAuth, {
|
|
30683
30772
|
statusFor: () => Effect.succeed(Option.none()),
|
|
30684
30773
|
begin: () => Effect.fail(new McpRegistryError({ detail: "OAuth sign-in is not available." })),
|
|
@@ -30696,7 +30785,7 @@ const decodeRegistration$1 = Schema$1.decodeUnknownExit(RegistrationFromJson$1);
|
|
|
30696
30785
|
const encodeRegistration = Schema$1.encodeSync(RegistrationFromJson$1);
|
|
30697
30786
|
var McpRegistry = class extends Context.Service()("@p4code/cli/mcp/McpRegistry") {};
|
|
30698
30787
|
const slotsOf = (registration) => registration.secrets ?? [];
|
|
30699
|
-
const make$
|
|
30788
|
+
const make$108 = Effect.gen(function* () {
|
|
30700
30789
|
const config = yield* ServerConfig$1;
|
|
30701
30790
|
const secrets = yield* ServerSecretStore;
|
|
30702
30791
|
const oauth = yield* McpOAuth;
|
|
@@ -30870,7 +30959,7 @@ const make$106 = Effect.gen(function* () {
|
|
|
30870
30959
|
resolveForSessionAtClaudeUserConfigPath
|
|
30871
30960
|
};
|
|
30872
30961
|
});
|
|
30873
|
-
const layer$90 = Layer.effect(McpRegistry, make$
|
|
30962
|
+
const layer$90 = Layer.effect(McpRegistry, make$108);
|
|
30874
30963
|
//#endregion
|
|
30875
30964
|
//#region src/sync/skillDirectory.ts
|
|
30876
30965
|
/**
|
|
@@ -31249,7 +31338,7 @@ const formatHubLink = (input) => encodeStoredHubLink({
|
|
|
31249
31338
|
shareMode: input.shareMode
|
|
31250
31339
|
});
|
|
31251
31340
|
const fromEnvironment = (environment) => validateHubLink(environment.P4CODE_HUB_URL ?? "", environment.P4CODE_HUB_TOKEN ?? "");
|
|
31252
|
-
const make$
|
|
31341
|
+
const make$107 = Effect.fn("HubLink.make")(function* (environment) {
|
|
31253
31342
|
const secrets = yield* ServerSecretStore;
|
|
31254
31343
|
const env = environment ?? process.env;
|
|
31255
31344
|
const fromEnv = fromEnvironment(env);
|
|
@@ -31322,7 +31411,7 @@ const make$105 = Effect.fn("HubLink.make")(function* (environment) {
|
|
|
31322
31411
|
})
|
|
31323
31412
|
};
|
|
31324
31413
|
});
|
|
31325
|
-
const layer$89 = Layer.effect(HubLink, make$
|
|
31414
|
+
const layer$89 = Layer.effect(HubLink, make$107());
|
|
31326
31415
|
//#endregion
|
|
31327
31416
|
//#region src/sync/HubAssetClient.ts
|
|
31328
31417
|
/**
|
|
@@ -31355,7 +31444,7 @@ const decodeAssetListPage = Schema$1.decodeUnknownEffect(AssetListPage);
|
|
|
31355
31444
|
const decodeConflictBody$1 = Schema$1.decodeUnknownEffect(ConflictBody$1);
|
|
31356
31445
|
const decodeAsset = Schema$1.decodeUnknownEffect(AgentAsset);
|
|
31357
31446
|
var HubAssetClient = class extends Context.Service()("@p4code/cli/sync/HubAssetClient") {};
|
|
31358
|
-
const make$
|
|
31447
|
+
const make$106 = Effect.gen(function* () {
|
|
31359
31448
|
const http = yield* HttpClient.HttpClient;
|
|
31360
31449
|
const link = yield* HubLink;
|
|
31361
31450
|
const requireSettings = Effect.gen(function* () {
|
|
@@ -31437,7 +31526,7 @@ const make$104 = Effect.gen(function* () {
|
|
|
31437
31526
|
remove
|
|
31438
31527
|
};
|
|
31439
31528
|
});
|
|
31440
|
-
const layer$88 = Layer.effect(HubAssetClient, make$
|
|
31529
|
+
const layer$88 = Layer.effect(HubAssetClient, make$106);
|
|
31441
31530
|
//#endregion
|
|
31442
31531
|
//#region src/sync/mcpRegistrationFiles.ts
|
|
31443
31532
|
/**
|
|
@@ -32368,7 +32457,7 @@ const EMPTY_REPORT = {
|
|
|
32368
32457
|
unavailable: null
|
|
32369
32458
|
};
|
|
32370
32459
|
var AssetSync = class extends Context.Service()("@p4code/cli/sync/AssetSync") {};
|
|
32371
|
-
const make$
|
|
32460
|
+
const make$105 = Effect.gen(function* () {
|
|
32372
32461
|
const client = yield* HubAssetClient;
|
|
32373
32462
|
const link = yield* HubLink;
|
|
32374
32463
|
const settingsStore = yield* ServerSettingsService;
|
|
@@ -33232,7 +33321,7 @@ const make$103 = Effect.gen(function* () {
|
|
|
33232
33321
|
removeLocal
|
|
33233
33322
|
};
|
|
33234
33323
|
});
|
|
33235
|
-
const layer$87 = Layer.effect(AssetSync, make$
|
|
33324
|
+
const layer$87 = Layer.effect(AssetSync, make$105);
|
|
33236
33325
|
//#endregion
|
|
33237
33326
|
//#region src/provider/CompressPrompts.ts
|
|
33238
33327
|
/**
|
|
@@ -34621,7 +34710,7 @@ const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
|
34621
34710
|
"interrupted"
|
|
34622
34711
|
]);
|
|
34623
34712
|
var ThreadBackgroundLivenessService = class extends Context.Service()("@p4code/cli/orchestration/ThreadBackgroundLiveness/ThreadBackgroundLivenessService") {};
|
|
34624
|
-
function make$
|
|
34713
|
+
function make$104() {
|
|
34625
34714
|
const stateByThreadId = /* @__PURE__ */ new Map();
|
|
34626
34715
|
const stateFor = (threadId) => {
|
|
34627
34716
|
const existing = stateByThreadId.get(threadId);
|
|
@@ -34677,7 +34766,7 @@ function make$102() {
|
|
|
34677
34766
|
}
|
|
34678
34767
|
};
|
|
34679
34768
|
}
|
|
34680
|
-
const layer$86 = Layer.effect(ThreadBackgroundLivenessService, Effect.sync(make$
|
|
34769
|
+
const layer$86 = Layer.effect(ThreadBackgroundLivenessService, Effect.sync(make$104));
|
|
34681
34770
|
//#endregion
|
|
34682
34771
|
//#region ../../packages/shared/src/sourceControl.ts
|
|
34683
34772
|
const GITHUB_CHANGE_REQUEST_PRESENTATION = {
|
|
@@ -41145,12 +41234,12 @@ const runProcessCore = Effect.fn("processRunner.runProcessCore")(function* (spaw
|
|
|
41145
41234
|
stderrInvalidUtf8: stderr.invalidUtf8
|
|
41146
41235
|
};
|
|
41147
41236
|
});
|
|
41148
|
-
const make$
|
|
41237
|
+
const make$103 = Effect.fn("ProcessRunner.make")(function* () {
|
|
41149
41238
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
41150
41239
|
const run = (input) => finalizeRunProcess(runProcessCore(spawner, input), input);
|
|
41151
41240
|
return ProcessRunner.of({ run });
|
|
41152
41241
|
});
|
|
41153
|
-
const layer$85 = Layer.effect(ProcessRunner, make$
|
|
41242
|
+
const layer$85 = Layer.effect(ProcessRunner, make$103());
|
|
41154
41243
|
//#endregion
|
|
41155
41244
|
//#region src/project/RepositoryIdentityResolver.ts
|
|
41156
41245
|
const DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY = 512;
|
|
@@ -41241,7 +41330,7 @@ const resolveRepositoryIdentityFromCacheKey = Effect.fn("RepositoryIdentityResol
|
|
|
41241
41330
|
rootPath: cacheKey
|
|
41242
41331
|
}) : null;
|
|
41243
41332
|
});
|
|
41244
|
-
const make$
|
|
41333
|
+
const make$102 = Effect.fn("RepositoryIdentityResolver.make")(function* (options = {}) {
|
|
41245
41334
|
const processRunner = yield* ProcessRunner;
|
|
41246
41335
|
const repositoryIdentityCache = yield* Cache.makeWith((cacheKey) => resolveRepositoryIdentityFromCacheKey(cacheKey).pipe(Effect.provideService(ProcessRunner, processRunner)), {
|
|
41247
41336
|
capacity: options.cacheCapacity ?? DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY,
|
|
@@ -41256,7 +41345,7 @@ const make$100 = Effect.fn("RepositoryIdentityResolver.make")(function* (options
|
|
|
41256
41345
|
});
|
|
41257
41346
|
return RepositoryIdentityResolver.of({ resolve });
|
|
41258
41347
|
});
|
|
41259
|
-
const layer$84 = Layer.effect(RepositoryIdentityResolver, make$
|
|
41348
|
+
const layer$84 = Layer.effect(RepositoryIdentityResolver, make$102()).pipe(Layer.provide(layer$85));
|
|
41260
41349
|
//#endregion
|
|
41261
41350
|
//#region src/orchestration/Layers/ProjectionSnapshotQuery.ts
|
|
41262
41351
|
const decodeReadModel = Schema$1.decodeUnknownEffect(OrchestrationReadModel);
|
|
@@ -41620,7 +41709,8 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
41620
41709
|
const EvidenceReadContextRow = Schema$1.Struct({
|
|
41621
41710
|
usedTokensAtRead: Schema$1.NullOr(Schema$1.Number),
|
|
41622
41711
|
readAt: Schema$1.String,
|
|
41623
|
-
afterSequence: Schema$1.NullOr(Schema$1.Number)
|
|
41712
|
+
afterSequence: Schema$1.NullOr(Schema$1.Number),
|
|
41713
|
+
throughSequence: Schema$1.NullOr(Schema$1.Number)
|
|
41624
41714
|
});
|
|
41625
41715
|
const getEvidenceReadContextRow = SqlSchema.findOneOption({
|
|
41626
41716
|
Request: Schema$1.String,
|
|
@@ -41633,7 +41723,8 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
41633
41723
|
ELSE NULL
|
|
41634
41724
|
END AS "usedTokensAtRead",
|
|
41635
41725
|
created_at AS "readAt",
|
|
41636
|
-
json_extract(payload_json, '$.afterSequence') AS "afterSequence"
|
|
41726
|
+
json_extract(payload_json, '$.afterSequence') AS "afterSequence",
|
|
41727
|
+
json_extract(payload_json, '$.throughSequence') AS "throughSequence"
|
|
41637
41728
|
FROM projection_thread_activities
|
|
41638
41729
|
WHERE activity_id = ${activityId}
|
|
41639
41730
|
LIMIT 1
|
|
@@ -41747,6 +41838,10 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
41747
41838
|
WHERE reads.thread_id = ${threadId}
|
|
41748
41839
|
AND reads.kind = 'fusion.evidence.read'
|
|
41749
41840
|
AND json_extract(reads.payload_json, '$.throughSequence') >= 0
|
|
41841
|
+
-- A raw row's bound is wherever paging reached, never the bound a
|
|
41842
|
+
-- wake named, so no report can pair with it and an unpaired one must
|
|
41843
|
+
-- not read as a review nobody answered.
|
|
41844
|
+
AND COALESCE(json_extract(reads.payload_json, '$.raw'), 0) = 0
|
|
41750
41845
|
ORDER BY reads.created_at DESC, reads.rowid DESC
|
|
41751
41846
|
LIMIT 1
|
|
41752
41847
|
`
|
|
@@ -43544,7 +43639,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
43544
43639
|
threadId,
|
|
43545
43640
|
turnId
|
|
43546
43641
|
}).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getTurnStart:query", "ProjectionSnapshotQuery.getTurnStart:decodeRow")));
|
|
43547
|
-
const getActiveTurnId = (threadId) => getActiveTurnIdRow(threadId).pipe(Effect.map(Option.flatMap((row) => Option.
|
|
43642
|
+
const getActiveTurnId = (threadId) => getActiveTurnIdRow(threadId).pipe(Effect.map(Option.flatMap((row) => Option.fromNullishOr(row.activeTurnId))), Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getActiveTurnId:query", "ProjectionSnapshotQuery.getActiveTurnId:decodeRow")));
|
|
43548
43643
|
const getLatestThreadMessageWithIdPrefix = (threadId, idPrefix) => getLatestThreadMessageWithIdPrefixRow({
|
|
43549
43644
|
threadId,
|
|
43550
43645
|
idPrefix
|
|
@@ -44572,7 +44667,7 @@ function mergeWithDefaultKeybindings(custom) {
|
|
|
44572
44667
|
* Keybindings - Service tag for keybinding configuration operations.
|
|
44573
44668
|
*/
|
|
44574
44669
|
var Keybindings = class extends Context.Service()("@p4code/cli/keybindings") {};
|
|
44575
|
-
const make$
|
|
44670
|
+
const make$101 = Effect.gen(function* () {
|
|
44576
44671
|
const { keybindingsConfigPath } = yield* ServerConfig$1;
|
|
44577
44672
|
const fs = yield* FileSystem.FileSystem;
|
|
44578
44673
|
const path = yield* Path$1.Path;
|
|
@@ -44833,7 +44928,7 @@ const make$99 = Effect.gen(function* () {
|
|
|
44833
44928
|
}))
|
|
44834
44929
|
};
|
|
44835
44930
|
});
|
|
44836
|
-
const layer$83 = Layer.effect(Keybindings, make$
|
|
44931
|
+
const layer$83 = Layer.effect(Keybindings, make$101);
|
|
44837
44932
|
//#endregion
|
|
44838
44933
|
//#region src/process/externalLauncher.ts
|
|
44839
44934
|
/**
|
|
@@ -45060,7 +45155,7 @@ const launchEditorProcess = Effect.fn("externalLauncher.launchEditorProcess")(fu
|
|
|
45060
45155
|
cause
|
|
45061
45156
|
}));
|
|
45062
45157
|
});
|
|
45063
|
-
const make$
|
|
45158
|
+
const make$100 = Effect.gen(function* () {
|
|
45064
45159
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
45065
45160
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
45066
45161
|
const path = yield* Path$1.Path;
|
|
@@ -45071,7 +45166,7 @@ const make$98 = Effect.gen(function* () {
|
|
|
45071
45166
|
launchEditor: (input) => provideCommandResolutionServices(Effect.flatMap(resolveEditorLaunch(input), (launch) => launchEditorProcess(launch).pipe(Effect.provideService(ChildProcessSpawner$1.ChildProcessSpawner, spawner))))
|
|
45072
45167
|
});
|
|
45073
45168
|
});
|
|
45074
|
-
const layer$82 = Layer.effect(ExternalLauncher, make$
|
|
45169
|
+
const layer$82 = Layer.effect(ExternalLauncher, make$100);
|
|
45075
45170
|
//#endregion
|
|
45076
45171
|
//#region src/orchestration/Services/OrchestrationReactor.ts
|
|
45077
45172
|
/**
|
|
@@ -45089,7 +45184,7 @@ var OrchestrationReactor = class extends Context.Service()("@p4code/cli/orchestr
|
|
|
45089
45184
|
//#endregion
|
|
45090
45185
|
//#region src/serverLifecycleEvents.ts
|
|
45091
45186
|
var ServerLifecycleEvents = class extends Context.Service()("@p4code/cli/serverLifecycleEvents") {};
|
|
45092
|
-
const make$
|
|
45187
|
+
const make$99 = Effect.gen(function* () {
|
|
45093
45188
|
const pubsub = yield* PubSub.unbounded();
|
|
45094
45189
|
const state = yield* Ref.make({
|
|
45095
45190
|
sequence: 0,
|
|
@@ -45113,7 +45208,7 @@ const make$97 = Effect.gen(function* () {
|
|
|
45113
45208
|
}
|
|
45114
45209
|
};
|
|
45115
45210
|
});
|
|
45116
|
-
const layer$81 = Layer.effect(ServerLifecycleEvents, make$
|
|
45211
|
+
const layer$81 = Layer.effect(ServerLifecycleEvents, make$99);
|
|
45117
45212
|
//#endregion
|
|
45118
45213
|
//#region src/telemetry/Identify.ts
|
|
45119
45214
|
const CodexAuthJsonSchema = Schema$1.Struct({ tokens: Schema$1.Struct({ account_id: Schema$1.String }) });
|
|
@@ -45286,7 +45381,7 @@ var AnalyticsService = class AnalyticsService extends Context.Service()("@p4code
|
|
|
45286
45381
|
/** No-op layer for callers that intentionally disable telemetry. */
|
|
45287
45382
|
static layerTest = Layer.succeed(AnalyticsService, inert);
|
|
45288
45383
|
};
|
|
45289
|
-
const make$
|
|
45384
|
+
const make$98 = Effect.gen(function* () {
|
|
45290
45385
|
const telemetryConfig = yield* TelemetryEnvConfig;
|
|
45291
45386
|
const posthogKey = telemetryConfig.posthogKey.trim();
|
|
45292
45387
|
if (!telemetryConfig.enabled || posthogKey === "") return inert;
|
|
@@ -45356,7 +45451,7 @@ const make$96 = Effect.gen(function* () {
|
|
|
45356
45451
|
flush
|
|
45357
45452
|
});
|
|
45358
45453
|
});
|
|
45359
|
-
const layer$80 = Layer.effect(AnalyticsService, make$
|
|
45454
|
+
const layer$80 = Layer.effect(AnalyticsService, make$98);
|
|
45360
45455
|
AnalyticsService.layerTest;
|
|
45361
45456
|
//#endregion
|
|
45362
45457
|
//#region src/provider/Services/ProviderSessionDirectory.ts
|
|
@@ -45787,7 +45882,7 @@ var BootServiceInstallError = class extends Schema$1.TaggedErrorClass()("BootSer
|
|
|
45787
45882
|
}
|
|
45788
45883
|
};
|
|
45789
45884
|
var BootService = class extends Context.Service()("@p4code/cli/service/bootService") {};
|
|
45790
|
-
const make$
|
|
45885
|
+
const make$97 = Effect.fn("cloud.boot_service.make")(function* (input) {
|
|
45791
45886
|
const hostExecPath = yield* HostProcessExecutablePath;
|
|
45792
45887
|
const hostArguments = yield* HostProcessArguments;
|
|
45793
45888
|
const host = input.host ?? {
|
|
@@ -46009,7 +46104,7 @@ const make$95 = Effect.fn("cloud.boot_service.make")(function* (input) {
|
|
|
46009
46104
|
logPath
|
|
46010
46105
|
});
|
|
46011
46106
|
});
|
|
46012
|
-
const layer$79 = (input) => Layer.effect(BootService, make$
|
|
46107
|
+
const layer$79 = (input) => Layer.effect(BootService, make$97(input));
|
|
46013
46108
|
//#endregion
|
|
46014
46109
|
//#region src/service/selfUpdate.ts
|
|
46015
46110
|
/**
|
|
@@ -46084,7 +46179,7 @@ const resolveServerSelfUpdateCapability = Effect.fn("cloud.server_self_update.re
|
|
|
46084
46179
|
return null;
|
|
46085
46180
|
});
|
|
46086
46181
|
var ServerSelfUpdate = class extends Context.Service()("@p4code/cli/service/selfUpdate/ServerSelfUpdate") {};
|
|
46087
|
-
const make$
|
|
46182
|
+
const make$96 = Effect.fn("cloud.server_self_update.make")(function* (options) {
|
|
46088
46183
|
const serverConfig = yield* ServerConfig$1;
|
|
46089
46184
|
const settings = yield* ServerSettingsService;
|
|
46090
46185
|
const continuationContext = yield* Effect.context();
|
|
@@ -46247,7 +46342,7 @@ const make$94 = Effect.fn("cloud.server_self_update.make")(function* (options) {
|
|
|
46247
46342
|
});
|
|
46248
46343
|
return ServerSelfUpdate.of({ update });
|
|
46249
46344
|
});
|
|
46250
|
-
const layer$78 = Layer.effect(ServerSelfUpdate, make$
|
|
46345
|
+
const layer$78 = Layer.effect(ServerSelfUpdate, make$96()).pipe(Layer.provide(layer$85));
|
|
46251
46346
|
//#endregion
|
|
46252
46347
|
//#region src/environment/ServerEnvironmentLabel.ts
|
|
46253
46348
|
const ServerEnvironmentLabelCommandProbe = Schema$1.Literals(["macos-computer-name", "linux-pretty-hostname"]);
|
|
@@ -46379,7 +46474,7 @@ function platformArch(architecture) {
|
|
|
46379
46474
|
default: return "other";
|
|
46380
46475
|
}
|
|
46381
46476
|
}
|
|
46382
|
-
const make$
|
|
46477
|
+
const make$95 = Effect.gen(function* () {
|
|
46383
46478
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
46384
46479
|
const path = yield* Path$1.Path;
|
|
46385
46480
|
const serverConfig = yield* ServerConfig$1;
|
|
@@ -46457,7 +46552,7 @@ const make$93 = Effect.gen(function* () {
|
|
|
46457
46552
|
* state. It intentionally has no fallback Layer.succeed value: callers must
|
|
46458
46553
|
* provide the external platform services and a ServerConfig.
|
|
46459
46554
|
*/
|
|
46460
|
-
const layer$77 = Layer.effect(ServerEnvironment, make$
|
|
46555
|
+
const layer$77 = Layer.effect(ServerEnvironment, make$95).pipe(Layer.provide(layer$85));
|
|
46461
46556
|
//#endregion
|
|
46462
46557
|
//#region src/sync/SettingsSync.ts
|
|
46463
46558
|
/**
|
|
@@ -46487,7 +46582,9 @@ const IDLE = {
|
|
|
46487
46582
|
sent: []
|
|
46488
46583
|
};
|
|
46489
46584
|
var SettingsSync = class extends Context.Service()("@p4code/cli/sync/SettingsSync") {};
|
|
46490
|
-
const
|
|
46585
|
+
const payloadJson = Schema$1.fromJsonString(SettingsSyncPayload);
|
|
46586
|
+
const decodePayload = Schema$1.decodeUnknownOption(payloadJson);
|
|
46587
|
+
const encodePayload = Schema$1.encodeEffect(payloadJson);
|
|
46491
46588
|
/** The machine's own name, so history can say where a change came from. */
|
|
46492
46589
|
const environmentLabel = () => {
|
|
46493
46590
|
const hostname = NodeOS.hostname().trim();
|
|
@@ -46516,7 +46613,7 @@ const promptOverrideIsRunnable = (value) => {
|
|
|
46516
46613
|
}
|
|
46517
46614
|
return true;
|
|
46518
46615
|
};
|
|
46519
|
-
const make$
|
|
46616
|
+
const make$94 = Effect.gen(function* () {
|
|
46520
46617
|
const settingsService = yield* ServerSettingsService;
|
|
46521
46618
|
const client = yield* HubAssetClient;
|
|
46522
46619
|
const label = environmentLabel();
|
|
@@ -46544,13 +46641,9 @@ const make$92 = Effect.gen(function* () {
|
|
|
46544
46641
|
const incoming = Option.flatMap(fetched.asset, (asset) => {
|
|
46545
46642
|
const file = asset.files.find((candidate) => candidate.path === SETTINGS_SYNC_FILE_PATH);
|
|
46546
46643
|
if (file === void 0) return Option.none();
|
|
46547
|
-
|
|
46548
|
-
return decodePayload(JSON.parse(file.content));
|
|
46549
|
-
} catch {
|
|
46550
|
-
return Option.none();
|
|
46551
|
-
}
|
|
46644
|
+
return decodePayload(file.content);
|
|
46552
46645
|
});
|
|
46553
|
-
const now =
|
|
46646
|
+
const now = DateTime.formatIso(yield* DateTime.now);
|
|
46554
46647
|
const plan = planSettingsSync({
|
|
46555
46648
|
local: filterSyncedSettings(settings),
|
|
46556
46649
|
base: settings.settingsSync.base,
|
|
@@ -46604,12 +46697,13 @@ const make$92 = Effect.gen(function* () {
|
|
|
46604
46697
|
environmentLabel: label,
|
|
46605
46698
|
publishedAt: now
|
|
46606
46699
|
};
|
|
46700
|
+
const content = yield* encodePayload(payload).pipe(Effect.orDie);
|
|
46607
46701
|
const written = yield* client.write({
|
|
46608
46702
|
kind: "settings",
|
|
46609
46703
|
name: ASSET_NAME,
|
|
46610
46704
|
files: [{
|
|
46611
46705
|
path: SETTINGS_SYNC_FILE_PATH,
|
|
46612
|
-
content
|
|
46706
|
+
content
|
|
46613
46707
|
}],
|
|
46614
46708
|
...Option.match(fetched.asset, {
|
|
46615
46709
|
onNone: () => ({}),
|
|
@@ -46661,7 +46755,7 @@ const make$92 = Effect.gen(function* () {
|
|
|
46661
46755
|
unavailable: "settings sync failed"
|
|
46662
46756
|
})))) };
|
|
46663
46757
|
});
|
|
46664
|
-
const layer$76 = Layer.effect(SettingsSync, make$
|
|
46758
|
+
const layer$76 = Layer.effect(SettingsSync, make$94);
|
|
46665
46759
|
//#endregion
|
|
46666
46760
|
//#region src/provider/Services/ProviderHealthRefresher.ts
|
|
46667
46761
|
var ProviderHealthRefresher = class extends Context.Service()("@p4code/cli/provider/Services/ProviderHealthRefresher") {};
|
|
@@ -47019,7 +47113,7 @@ function daemonPortLine(line) {
|
|
|
47019
47113
|
const port = Number(raw);
|
|
47020
47114
|
return Number.isInteger(port) && port > 0 && port <= MAX_PORT$1 ? port : null;
|
|
47021
47115
|
}
|
|
47022
|
-
const make$
|
|
47116
|
+
const make$93 = Effect.fn("AgentDeviceProcess.make")(function* () {
|
|
47023
47117
|
const fs = yield* FileSystem.FileSystem;
|
|
47024
47118
|
const path = yield* Path$1.Path;
|
|
47025
47119
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
@@ -47131,7 +47225,7 @@ const make$91 = Effect.fn("AgentDeviceProcess.make")(function* () {
|
|
|
47131
47225
|
});
|
|
47132
47226
|
return { start };
|
|
47133
47227
|
});
|
|
47134
|
-
const layer$75 = Layer.effect(AgentDeviceProcess, make$
|
|
47228
|
+
const layer$75 = Layer.effect(AgentDeviceProcess, make$93());
|
|
47135
47229
|
//#endregion
|
|
47136
47230
|
//#region src/device/DeviceDiscovery.ts
|
|
47137
47231
|
var DeviceDiscoveryFailure = class extends Data.TaggedError("DeviceDiscoveryFailure") {};
|
|
@@ -47164,7 +47258,7 @@ const decodeDeviceDiscovery = (hostId, body) => Schema$1.decodeUnknownEffect(Sch
|
|
|
47164
47258
|
partial: (value.errors?.length ?? 0) > 0
|
|
47165
47259
|
});
|
|
47166
47260
|
}));
|
|
47167
|
-
const make$
|
|
47261
|
+
const make$92 = Effect.fn("DeviceDiscovery.make")(function* () {
|
|
47168
47262
|
const http = yield* HttpClient.HttpClient;
|
|
47169
47263
|
return Effect.fn("DeviceDiscovery.read")(function* (input) {
|
|
47170
47264
|
const origin = yield* Effect.try(() => new URL(input.ready.hub.origin));
|
|
@@ -47226,7 +47320,7 @@ const Result = Schema$1.Struct({
|
|
|
47226
47320
|
serial: Schema$1.optional(DeviceId),
|
|
47227
47321
|
error: Schema$1.optional(Schema$1.String)
|
|
47228
47322
|
});
|
|
47229
|
-
const make$
|
|
47323
|
+
const make$91 = Effect.fn("DeviceHubActions.make")(function* () {
|
|
47230
47324
|
const http = yield* HttpClient.HttpClient;
|
|
47231
47325
|
const post = Effect.fn("DeviceHubActions.post")(function* (ready, route, payload, timeoutMs) {
|
|
47232
47326
|
return yield* Effect.gen(function* () {
|
|
@@ -47295,7 +47389,7 @@ function sessionsToClose(sessions, input) {
|
|
|
47295
47389
|
//#endregion
|
|
47296
47390
|
//#region src/device/DeviceCommandLeases.ts
|
|
47297
47391
|
/** Owns commands by exact session object, so close/reopen cannot revive an old lease. */
|
|
47298
|
-
const make$
|
|
47392
|
+
const make$90 = Effect.fn("DeviceCommandLeases.make")(function* () {
|
|
47299
47393
|
const lock = yield* Semaphore.make(1);
|
|
47300
47394
|
const entries = /* @__PURE__ */ new Map();
|
|
47301
47395
|
const revoked = /* @__PURE__ */ new WeakSet();
|
|
@@ -47341,7 +47435,7 @@ const make$88 = Effect.fn("DeviceCommandLeases.make")(function* () {
|
|
|
47341
47435
|
//#endregion
|
|
47342
47436
|
//#region src/device/DeviceThreadLeases.ts
|
|
47343
47437
|
/** Thread retirement also cancels opens that have not created a session yet. */
|
|
47344
|
-
const make$
|
|
47438
|
+
const make$89 = Effect.fn("DeviceThreadLeases.make")(function* () {
|
|
47345
47439
|
const lock = yield* Semaphore.make(1);
|
|
47346
47440
|
const scopes = /* @__PURE__ */ new Map();
|
|
47347
47441
|
const blocked = /* @__PURE__ */ new Set();
|
|
@@ -47389,7 +47483,7 @@ const make$87 = Effect.fn("DeviceThreadLeases.make")(function* () {
|
|
|
47389
47483
|
//#region src/device/DeviceHostRegistry.ts
|
|
47390
47484
|
const sameConfig = (a, b) => a === b || a !== null && b !== null && a.id === b.id && a.label === b.label && a.target === b.target && a.port === b.port && a.identityFile === b.identityFile;
|
|
47391
47485
|
/** Owns configuration generations; use() interrupts in-flight work before a host is retired. */
|
|
47392
|
-
const make$
|
|
47486
|
+
const make$88 = Effect.fn("DeviceHostRegistry.make")(function* (factories) {
|
|
47393
47487
|
const factoryContext = yield* Effect.context();
|
|
47394
47488
|
const lock = yield* Semaphore.make(1);
|
|
47395
47489
|
const entries = /* @__PURE__ */ new Map();
|
|
@@ -47557,7 +47651,7 @@ function pngDimensions(png) {
|
|
|
47557
47651
|
height
|
|
47558
47652
|
};
|
|
47559
47653
|
}
|
|
47560
|
-
const make$
|
|
47654
|
+
const make$87 = Effect.fn("DeviceScreenshot.make")(function* () {
|
|
47561
47655
|
const http = yield* HttpClient.HttpClient;
|
|
47562
47656
|
return Effect.fn("DeviceScreenshot.capture")(function* (ready, session) {
|
|
47563
47657
|
const origin = yield* Effect.try(() => new URL(ready.hub.origin));
|
|
@@ -47584,7 +47678,7 @@ const make$85 = Effect.fn("DeviceScreenshot.make")(function* () {
|
|
|
47584
47678
|
})));
|
|
47585
47679
|
});
|
|
47586
47680
|
var DeviceScreenshot = class extends Context.Service()("@p4code/cli/device/DeviceScreenshot") {};
|
|
47587
|
-
const layer$74 = Layer.effect(DeviceScreenshot, make$
|
|
47681
|
+
const layer$74 = Layer.effect(DeviceScreenshot, make$87().pipe(Effect.map((capture) => ({ capture }))));
|
|
47588
47682
|
//#endregion
|
|
47589
47683
|
//#region src/device/XcodeMcpClient.ts
|
|
47590
47684
|
const XCODE_BUILD_MCP_VERSION = "2.7.0";
|
|
@@ -48397,7 +48491,7 @@ const COMMAND_TIMEOUT_MS$1 = 2e4;
|
|
|
48397
48491
|
const COMMAND_OUTPUT_LIMIT = 1024 * 1024;
|
|
48398
48492
|
const COMMAND_FAILURE_CODE = 127;
|
|
48399
48493
|
const APPLE_DEVICE_MCP_MINIMUM_XCODE = 27;
|
|
48400
|
-
const make$
|
|
48494
|
+
const make$86 = Effect.fn("LocalDeviceHost.make")(function* () {
|
|
48401
48495
|
const config = yield* ServerConfig$1;
|
|
48402
48496
|
const fs = yield* FileSystem.FileSystem;
|
|
48403
48497
|
const path = yield* Path$1.Path;
|
|
@@ -48550,7 +48644,7 @@ const make$84 = Effect.fn("LocalDeviceHost.make")(function* () {
|
|
|
48550
48644
|
stop: lock.withPermit(stop)
|
|
48551
48645
|
};
|
|
48552
48646
|
});
|
|
48553
|
-
Layer.effect(DeviceHost, make$
|
|
48647
|
+
Layer.effect(DeviceHost, make$86()).pipe(Layer.provide(layer$75));
|
|
48554
48648
|
Data.TaggedError("SshHostDiscoveryError");
|
|
48555
48649
|
var SshInvalidTargetError = class extends Data.TaggedError("SshInvalidTargetError") {};
|
|
48556
48650
|
var SshCommandError = class extends Data.TaggedError("SshCommandError") {};
|
|
@@ -49409,7 +49503,7 @@ const probeSshDeviceHost = Effect.fn("SshDeviceDiagnostics.probe")(function* (co
|
|
|
49409
49503
|
//#endregion
|
|
49410
49504
|
//#region src/device/SshDeviceHost.ts
|
|
49411
49505
|
const DIAGNOSTICS_CACHE_MS = 1e4;
|
|
49412
|
-
const make$
|
|
49506
|
+
const make$85 = Effect.fn("SshDeviceHost.make")(function* (input) {
|
|
49413
49507
|
const config = yield* Schema$1.decodeUnknownEffect(SshDeviceHostConfig)({ ...input }).pipe(Effect.mapError(() => new DeviceHostError({
|
|
49414
49508
|
hostId: input.id,
|
|
49415
49509
|
step: "configuring SSH device host",
|
|
@@ -49549,8 +49643,8 @@ var DeviceService = class extends Context.Service()("@p4code/cli/device/DeviceSe
|
|
|
49549
49643
|
const makeWithHosts = Effect.fn("DeviceService.makeWithHosts")(function* (input) {
|
|
49550
49644
|
const settings = yield* ServerSettingsService;
|
|
49551
49645
|
const scope = yield* Scope.Scope;
|
|
49552
|
-
const registry = yield* make$
|
|
49553
|
-
const commands = yield* make$
|
|
49646
|
+
const registry = yield* make$88(input);
|
|
49647
|
+
const commands = yield* make$90();
|
|
49554
49648
|
const adapterLeases = /* @__PURE__ */ new Map();
|
|
49555
49649
|
const closeCommands = (sessions) => Effect.sync(() => {
|
|
49556
49650
|
for (const session of sessions) {
|
|
@@ -49559,7 +49653,7 @@ const makeWithHosts = Effect.fn("DeviceService.makeWithHosts")(function* (input)
|
|
|
49559
49653
|
adapterLeases.delete(session.leaseId);
|
|
49560
49654
|
}
|
|
49561
49655
|
}).pipe(Effect.andThen(commands.close(sessions)));
|
|
49562
|
-
const threads = yield* make$
|
|
49656
|
+
const threads = yield* make$89();
|
|
49563
49657
|
const changes = yield* Effect.acquireRelease(PubSub.sliding(STATE_BUFFER_SIZE), PubSub.shutdown);
|
|
49564
49658
|
const stateLock = yield* Semaphore.make(1);
|
|
49565
49659
|
const discoveryLock = yield* Semaphore.make(1);
|
|
@@ -49970,17 +50064,17 @@ const makeWithHosts = Effect.fn("DeviceService.makeWithHosts")(function* (input)
|
|
|
49970
50064
|
}))
|
|
49971
50065
|
};
|
|
49972
50066
|
});
|
|
49973
|
-
const make$
|
|
49974
|
-
const discover = yield* make$
|
|
49975
|
-
const actions = yield* make$
|
|
50067
|
+
const make$84 = Effect.gen(function* () {
|
|
50068
|
+
const discover = yield* make$92();
|
|
50069
|
+
const actions = yield* make$91();
|
|
49976
50070
|
return yield* makeWithHosts({
|
|
49977
|
-
local: make$
|
|
49978
|
-
ssh: make$
|
|
50071
|
+
local: make$86(),
|
|
50072
|
+
ssh: make$85,
|
|
49979
50073
|
discover,
|
|
49980
50074
|
actions
|
|
49981
50075
|
});
|
|
49982
50076
|
}).pipe(Effect.provide(layer$75));
|
|
49983
|
-
const layer$72 = Layer.effect(DeviceService, make$
|
|
50077
|
+
const layer$72 = Layer.effect(DeviceService, make$84);
|
|
49984
50078
|
//#endregion
|
|
49985
50079
|
//#region src/serverRuntimeStartup.ts
|
|
49986
50080
|
var ServerRuntimeStartupError = class extends Schema$1.TaggedErrorClass()("ServerRuntimeStartupError", {
|
|
@@ -50125,7 +50219,7 @@ const startProviderRecovery = Effect.fn("startup.startProviderRecovery")(functio
|
|
|
50125
50219
|
yield* input.recover;
|
|
50126
50220
|
yield* input.startReaper;
|
|
50127
50221
|
});
|
|
50128
|
-
const make$
|
|
50222
|
+
const make$83 = Effect.gen(function* () {
|
|
50129
50223
|
const serverConfig = yield* ServerConfig$1;
|
|
50130
50224
|
const keybindings = yield* Keybindings;
|
|
50131
50225
|
const orchestrationReactor = yield* OrchestrationReactor;
|
|
@@ -50279,7 +50373,7 @@ const make$81 = Effect.gen(function* () {
|
|
|
50279
50373
|
enqueueCommand: commandGate.enqueueCommand
|
|
50280
50374
|
};
|
|
50281
50375
|
});
|
|
50282
|
-
const layer$71 = Layer.effect(ServerRuntimeStartup, make$
|
|
50376
|
+
const layer$71 = Layer.effect(ServerRuntimeStartup, make$83);
|
|
50283
50377
|
//#endregion
|
|
50284
50378
|
//#region src/serverRuntimeState.ts
|
|
50285
50379
|
const PersistedServerRuntimeState = Schema$1.Struct({
|
|
@@ -50436,7 +50530,7 @@ function expandHomePath$2(input, path) {
|
|
|
50436
50530
|
if (input.startsWith("~/") || input.startsWith("~\\")) return path.join(NodeOS.homedir(), input.slice(2));
|
|
50437
50531
|
return input;
|
|
50438
50532
|
}
|
|
50439
|
-
const make$
|
|
50533
|
+
const make$82 = Effect.gen(function* () {
|
|
50440
50534
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
50441
50535
|
const path = yield* Path$1.Path;
|
|
50442
50536
|
const statWorkspaceRoot = Effect.fn("WorkspacePaths.statWorkspaceRoot")(function* (workspaceRoot, normalizedWorkspaceRoot, phase) {
|
|
@@ -50493,7 +50587,7 @@ const make$80 = Effect.gen(function* () {
|
|
|
50493
50587
|
resolveRelativePathWithinRoot
|
|
50494
50588
|
});
|
|
50495
50589
|
});
|
|
50496
|
-
const layer$70 = Layer.effect(WorkspacePaths, make$
|
|
50590
|
+
const layer$70 = Layer.effect(WorkspacePaths, make$82);
|
|
50497
50591
|
//#endregion
|
|
50498
50592
|
//#region src/cli/project.ts
|
|
50499
50593
|
const isEnvironmentHttpCommonError = Schema$1.is(EnvironmentHttpCommonError);
|
|
@@ -54417,7 +54511,7 @@ const makeTerminationError$1 = (handle) => Effect.match(handle.exitCode, {
|
|
|
54417
54511
|
//#region ../../packages/effect-acp/src/client.ts
|
|
54418
54512
|
const MAX_STDERR_CALLBACK_CHARS = 32768;
|
|
54419
54513
|
var AcpClient = class extends Context.Service()("effect-acp/client/AcpClient") {};
|
|
54420
|
-
const make$
|
|
54514
|
+
const make$81 = Effect.fn("effect-acp/AcpClient.make")(function* (stdio, options = {}, terminationError) {
|
|
54421
54515
|
const coreHandlers = {};
|
|
54422
54516
|
const notificationHandlers = {
|
|
54423
54517
|
sessionUpdate: {
|
|
@@ -54584,7 +54678,7 @@ const layerChildProcess$1 = (handle, options = {}) => {
|
|
|
54584
54678
|
})), Stream.drain)) : stdout
|
|
54585
54679
|
};
|
|
54586
54680
|
const terminationError = makeTerminationError$1(handle);
|
|
54587
|
-
return Layer.effect(AcpClient, make$
|
|
54681
|
+
return Layer.effect(AcpClient, make$81(stdio, options, terminationError));
|
|
54588
54682
|
};
|
|
54589
54683
|
//#endregion
|
|
54590
54684
|
//#region src/provider/Drivers/AntigravitySkills.ts
|
|
@@ -55863,7 +55957,7 @@ const Reply = Schema$1.Struct({
|
|
|
55863
55957
|
id: Schema$1.String,
|
|
55864
55958
|
result: Schema$1.Struct({ ok: Schema$1.Boolean })
|
|
55865
55959
|
});
|
|
55866
|
-
const make$
|
|
55960
|
+
const make$80 = Effect.fn("DeviceCommandProxy.make")(function* () {
|
|
55867
55961
|
const http = yield* HttpClient.HttpClient;
|
|
55868
55962
|
const daemonSessions = /* @__PURE__ */ new WeakMap();
|
|
55869
55963
|
return Effect.fn("DeviceCommandProxy.execute")(function* (endpoint, session, payload) {
|
|
@@ -55916,7 +56010,7 @@ const make$78 = Effect.fn("DeviceCommandProxy.make")(function* () {
|
|
|
55916
56010
|
})));
|
|
55917
56011
|
});
|
|
55918
56012
|
var DeviceCommandProxy = class extends Context.Service()("@p4code/cli/device/DeviceCommandProxy") {};
|
|
55919
|
-
const layer$69 = Layer.effect(DeviceCommandProxy, make$
|
|
56013
|
+
const layer$69 = Layer.effect(DeviceCommandProxy, make$80().pipe(Effect.map((execute) => ({ execute }))));
|
|
55920
56014
|
//#endregion
|
|
55921
56015
|
//#region src/device/DeviceHubRoute.ts
|
|
55922
56016
|
const DEVICE_HUB_PROXY_PREFIX = "/api/device-hub";
|
|
@@ -58265,7 +58359,7 @@ const logP4ProjectFileLoadError = (error) => Effect.logWarning(error).pipe(Effec
|
|
|
58265
58359
|
filePath: error.filePath,
|
|
58266
58360
|
errorTag: error._tag
|
|
58267
58361
|
}));
|
|
58268
|
-
const make$
|
|
58362
|
+
const make$79 = Effect.gen(function* () {
|
|
58269
58363
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
58270
58364
|
const path = yield* Path$1.Path;
|
|
58271
58365
|
const load = Effect.fn("P4ProjectFileLoader.load")(function* (workspaceRoot) {
|
|
@@ -58286,7 +58380,7 @@ const make$77 = Effect.gen(function* () {
|
|
|
58286
58380
|
});
|
|
58287
58381
|
return P4ProjectFileLoader.of({ load });
|
|
58288
58382
|
});
|
|
58289
|
-
const layer$66 = Layer.effect(P4ProjectFileLoader, make$
|
|
58383
|
+
const layer$66 = Layer.effect(P4ProjectFileLoader, make$79);
|
|
58290
58384
|
//#endregion
|
|
58291
58385
|
//#region src/project/ProjectFaviconResolver.ts
|
|
58292
58386
|
/**
|
|
@@ -58361,7 +58455,7 @@ function extractIconHref(source) {
|
|
|
58361
58455
|
return null;
|
|
58362
58456
|
}
|
|
58363
58457
|
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) }));
|
|
58364
|
-
const make$
|
|
58458
|
+
const make$78 = Effect.gen(function* () {
|
|
58365
58459
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
58366
58460
|
const path = yield* Path$1.Path;
|
|
58367
58461
|
const workspacePaths = yield* WorkspacePaths;
|
|
@@ -58430,7 +58524,7 @@ const make$76 = Effect.gen(function* () {
|
|
|
58430
58524
|
});
|
|
58431
58525
|
return ProjectFaviconResolver.of({ resolvePath });
|
|
58432
58526
|
});
|
|
58433
|
-
const layer$65 = Layer.effect(ProjectFaviconResolver, make$
|
|
58527
|
+
const layer$65 = Layer.effect(ProjectFaviconResolver, make$78);
|
|
58434
58528
|
//#endregion
|
|
58435
58529
|
//#region src/assets/AssetAccess.ts
|
|
58436
58530
|
const ASSET_ROUTE_PREFIX = "/api/assets";
|
|
@@ -58841,10 +58935,10 @@ const resolveAsset = Effect.fn("AssetAccess.resolveAsset")(function* (token, rel
|
|
|
58841
58935
|
//#endregion
|
|
58842
58936
|
//#region src/observability/BrowserTraceCollector.ts
|
|
58843
58937
|
var BrowserTraceCollector = class extends Context.Service()("@p4code/cli/observability/BrowserTraceCollector") {};
|
|
58844
|
-
const make$
|
|
58938
|
+
const make$77 = (sink) => BrowserTraceCollector.of({ record: (records) => Effect.sync(() => {
|
|
58845
58939
|
for (const record of records) sink.push(record);
|
|
58846
58940
|
}) });
|
|
58847
|
-
const layer$64 = (sink) => Layer.succeed(BrowserTraceCollector, make$
|
|
58941
|
+
const layer$64 = (sink) => Layer.succeed(BrowserTraceCollector, make$77(sink));
|
|
58848
58942
|
//#endregion
|
|
58849
58943
|
//#region src/auth/http.ts
|
|
58850
58944
|
const CREDENTIAL_RESPONSE_HEADERS = {
|
|
@@ -59257,6 +59351,17 @@ function isAutoCheckoutBusy(input) {
|
|
|
59257
59351
|
return thread.latestTurn?.state === "running" || thread.session?.status === "starting" || thread.session?.status === "running";
|
|
59258
59352
|
});
|
|
59259
59353
|
}
|
|
59354
|
+
/** The brief every advisor gets; Jev reads it as instructions, the model as a question. */
|
|
59355
|
+
const AUTO_WORKSPACE_QUESTION_LINES = (hasWorkingTreeChanges) => [
|
|
59356
|
+
"Choose the workspace for this task before its coding agent starts.",
|
|
59357
|
+
"Return exactly local or worktree in the answer field. Do not perform the task.",
|
|
59358
|
+
"No other P4 agent is currently working in this checkout.",
|
|
59359
|
+
`Uncommitted changes are ${hasWorkingTreeChanges ? "present" : "absent"}.`,
|
|
59360
|
+
"Prefer local for questions, investigation, small focused edits, and work that needs current uncommitted changes.",
|
|
59361
|
+
"Prefer worktree for independent implementation, broad changes, risky experiments, or possible interference with someone else's edits.",
|
|
59362
|
+
"A new worktree starts from the selected base branch; uncommitted files are not copied.",
|
|
59363
|
+
"Honor an explicit workspace preference in the task. Preserve unrelated changes. If uncertain, choose worktree."
|
|
59364
|
+
];
|
|
59260
59365
|
const BUSY_CHECKOUT_DECISION = {
|
|
59261
59366
|
mode: "worktree",
|
|
59262
59367
|
reason: "Another agent is working in the current checkout."
|
|
@@ -59265,27 +59370,23 @@ const UNAVAILABLE_DECISION = {
|
|
|
59265
59370
|
mode: "worktree",
|
|
59266
59371
|
reason: "The agent could not choose a workspace; using an isolated worktree."
|
|
59267
59372
|
};
|
|
59268
|
-
const chooseAutoWorkspace = Effect.fn("chooseAutoWorkspace")(function* (input, textGeneration) {
|
|
59373
|
+
const chooseAutoWorkspace = Effect.fn("chooseAutoWorkspace")(function* (input, textGeneration, advisor) {
|
|
59269
59374
|
if (!input.isRepo) return {
|
|
59270
59375
|
mode: "local",
|
|
59271
59376
|
reason: "This project has no Git repository."
|
|
59272
59377
|
};
|
|
59273
59378
|
if (input.busy) return BUSY_CHECKOUT_DECISION;
|
|
59379
|
+
const advised = advisor ? yield* advisor.chooseWorkspace({
|
|
59380
|
+
message: input.message,
|
|
59381
|
+
hasWorkingTreeChanges: input.hasWorkingTreeChanges
|
|
59382
|
+
}) : void 0;
|
|
59383
|
+
if (advised) return advised;
|
|
59274
59384
|
if (!textGeneration.generateBtwAnswer || !input.modelSelection) return UNAVAILABLE_DECISION;
|
|
59275
59385
|
return yield* textGeneration.generateBtwAnswer({
|
|
59276
59386
|
cwd: input.cwd,
|
|
59277
59387
|
modelSelection: input.modelSelection,
|
|
59278
59388
|
context: input.message,
|
|
59279
|
-
question:
|
|
59280
|
-
"Choose the workspace for this task before its coding agent starts.",
|
|
59281
|
-
"Return exactly local or worktree in the answer field. Do not perform the task.",
|
|
59282
|
-
"No other P4 agent is currently working in this checkout.",
|
|
59283
|
-
`Uncommitted changes are ${input.hasWorkingTreeChanges ? "present" : "absent"}.`,
|
|
59284
|
-
"Prefer local for questions, investigation, small focused edits, and work that needs current uncommitted changes.",
|
|
59285
|
-
"Prefer worktree for independent implementation, broad changes, risky experiments, or possible interference with someone else's edits.",
|
|
59286
|
-
"A new worktree starts from the selected base branch; uncommitted files are not copied.",
|
|
59287
|
-
"Honor an explicit workspace preference in the task. Preserve unrelated changes. If uncertain, choose worktree."
|
|
59288
|
-
].join("\n")
|
|
59389
|
+
question: AUTO_WORKSPACE_QUESTION_LINES(input.hasWorkingTreeChanges).join("\n")
|
|
59289
59390
|
}).pipe(Effect.timeout(AUTO_WORKSPACE_DECISION_TIMEOUT), Effect.map(({ answer }) => {
|
|
59290
59391
|
const mode = answer.trim().toLowerCase();
|
|
59291
59392
|
if (mode === "local") return {
|
|
@@ -59449,8 +59550,30 @@ const readWorkflowScript = Effect.fn("orchestration.readWorkflowScript")(functio
|
|
|
59449
59550
|
* written as if the setting applied only to user-facing answers.
|
|
59450
59551
|
*/
|
|
59451
59552
|
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.`;
|
|
59452
|
-
|
|
59453
|
-
|
|
59553
|
+
/**
|
|
59554
|
+
* What a role does when a tool it wants is not its own.
|
|
59555
|
+
*
|
|
59556
|
+
* Both halves get the same words because the failure is the same on both
|
|
59557
|
+
* sides: a denied capability is an answer about what this role may do, and
|
|
59558
|
+
* treating it as an obstacle to route around turns a boundary the server
|
|
59559
|
+
* enforces into one it merely suggests.
|
|
59560
|
+
*/
|
|
59561
|
+
const FUSION_TOOL_BOUNDARY_INSTRUCTIONS = `A tool missing from your role, or a call the server denies for want of a capability or a grant, is a limit to report rather than an obstacle to route around. Never substitute the server's own database, its HTTP API, another MCP server, or any other back channel for a capability you were not granted; say which tool or grant you lacked and what you would have done with it.`;
|
|
59562
|
+
/**
|
|
59563
|
+
* What a role does when the user asks it, in person, for the other half's work.
|
|
59564
|
+
*
|
|
59565
|
+
* Distinct from the tool boundary above: there the role wants a capability and
|
|
59566
|
+
* is told to report the limit, while here the user wants something and the
|
|
59567
|
+
* quiet handover is the failure. A builder that silently parks a tracker
|
|
59568
|
+
* request in its phase report, or a supervisor that silently forwards an
|
|
59569
|
+
* implementation request through thread_advise, answers a question the user
|
|
59570
|
+
* never asked - they may have addressed the wrong half, or may want that half
|
|
59571
|
+
* to say plainly that it cannot. Confirmation costs one turn; a misrouted
|
|
59572
|
+
* instruction costs the work done under it.
|
|
59573
|
+
*/
|
|
59574
|
+
const FUSION_OUT_OF_ROLE_REQUEST_INSTRUCTIONS = `A request the user addresses to you that your role does not own is neither yours to perform nor yours to hand to the other half on your own initiative. Name the capability you lack and the half that owns it, ask the user whether they meant it to go there, and end the turn without acting; carry it across only once they confirm. This governs an instruction aimed at you, not a need your own work turned up - something the task itself raised still travels its normal path. A user who already named the other half, or whose instruction only the other half could have been meant for, has confirmed it; do not ask again.`;
|
|
59575
|
+
const FUSION_BUILDER_INSTRUCTIONS = `You are Fusion Builder in an already-created native server pair. Server owns pairing and coordination. Follow the current turn's [fusion-review-policy] block when present; it overrides the phase-boundary scheduling rules below. Do not inspect or invoke the Fusion skill, create/pair/rename threads, or announce/setup Fusion. Start the user's task directly. The phase plan is not yours: Supervisor authors it, orders it, and moves every phase status, and it renders in your task banner from there. Never create or edit a phase list yourself - not with TaskCreate, TaskUpdate, TodoWrite, update_plan, the MCP task board tools, or thread_plan_update - and never mark your own phase complete. Work the one phase Supervisor put in progress, and report what you did. Step-level notes for your own use are fine as long as they never become a phase list. 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 a report of at most six non-empty lines: the phase you finished, what changed and where, what you verified with its result, and anything unresolved. One line each, every fact once, no restatement of the plan or of advice you were given. Code, exact error text and security warnings are exempt from the cap. 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. The review tools are Supervisor's half of the pair, not yours: thread_watch_review, thread_watch_events and thread_evidence_report are its tools, and a thread outside this pair is not yours to read. Your provider may still list them; that is not a grant, and every call fails. The tracker is Supervisor's too: you neither read nor write tickets, so when the work needs one filed, commented, or moved, say so in your phase report and let Supervisor carry it. ${FUSION_OUT_OF_ROLE_REQUEST_INSTRUCTIONS} ${FUSION_TOOL_BOUNDARY_INSTRUCTIONS} ${FUSION_PAIR_COMMUNICATION_INSTRUCTIONS}`;
|
|
59576
|
+
const FUSION_WATCHER_TOOL_INSTRUCTIONS = `Supervisor tools belong to the p4-code MCP server: thread_watch_review, thread_watch_events, thread_evidence_report, thread_plan_update, thread_advise, thread_gate_respond, and the task board tools task_current, task_get, task_list, task_create and task_update. Read the board whenever planning needs it, and read a named ticket with ticket_resolve together with its comments, treating a later comment as newer intent than the description. Resolve which task that is by calling task_current with the builder's threadId, because a pair started from the board links the row to the builder and not to you; a bare task_current answers for your own thread and reports the task as unlinked. Write only within that task: update it or a subtask you created under it, never an unrelated row, never another project's board, and never any board but this one - task_create files a real ticket on an external tracker when given a source such as 'linear', and that is not yours to file. 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:
|
|
59454
59577
|
## Recommendation
|
|
59455
59578
|
State the decision or correction in one sentence. For a phase review, say whether the phase is approved or needs changes.
|
|
59456
59579
|
## Reason
|
|
@@ -59465,7 +59588,7 @@ Give ordered, concrete actions for the builder, including the next phase and its
|
|
|
59465
59588
|
* which is what it did before this existed.
|
|
59466
59589
|
*/
|
|
59467
59590
|
const FUSION_EVIDENCE_SUMMARY_INSTRUCTIONS = `Read the builder's evidence through a summarizer subagent rather than into your own context: spawn one subagent with the evidence range and have it call thread_watch_review itself, paging with nextAfterSequence against a fixed throughSequence until hasMore is false, and return a summary. Your tool grants reach it, so it can read the paired builder thread exactly as you can. Instruct that subagent that thread_watch_review and thread_watch_events may be absent from its visible tool list and that absence does not establish unavailability: it must first use the available tool search/discovery facility to load those exact tools by name, including provider-prefixed names, and if discovery itself fails it must report that exact error rather than reporting no such tool. Require of that summary: every file path touched with the scale of the change to each, every command run and whether it succeeded or failed, check and test results with their counts, exact error text quoted rather than characterized, the builder's completion claims marked as claims, and anything the builder flagged as uncertain, blocked or unresolved. Over a multi-turn range it must also carry unresolved objections of yours and whether each was answered, phases completed versus reopened, claims never verified, and files touched repeatedly. Every statement cites the sequences behind it so you can check any one of them with a targeted thread_watch_events read. Fail open: if no subagent is available, the spawn errors, it times out, or what comes back is empty or does not cite sequences, read the range yourself and review from the raw evidence. Never skip or shorten a review because a summary was unavailable. Record which fallback you took: a subagent that could not load the watch tools is a misconfiguration worth naming in your report, and it is not the same as a spawn that errored or timed out. Then close the review by calling thread_evidence_report exactly once, after the last page: pass the watched thread id, the same fixed throughSequence the first review page returned - not lastSequence and not the final page's nextAfterSequence, because the server pairs the report to the read by that exact number - the first and last sequence you actually covered, the model you spawned on, and outcome summarized with the subagent's exact returned text, fallback when you read the raw range yourself, or failed when the summarizer could not run or could not report - with the reason in your own words for the last two. Report even when the summary never arrived; a review with no report cannot be told apart from a supervisor that never tried. Never paste builder tool output into it.`;
|
|
59468
|
-
const FUSION_WATCHER_INSTRUCTIONS = `You are Fusion Supervisor (watcher) in an already-created native server pair. Follow the current turn's [fusion-review-policy] block when present; it overrides phase scheduling. 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 write the phase plan and direct its first phase. The plan is yours alone: call thread_plan_update with the builder's threadId, sending the complete ordered list every time, each phase named in 3-6 words by its outcome rather than by a command, file path, or flag, with exactly one in progress. 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 a complete reviewable slice of behavior. Never split per file, per function, or per trivial step. State each phase's completion condition to the builder in the advice, not in the banner title. On every later review, rewrite the same plan: an approved phase becomes completed and the next becomes in progress in the same call, an objection leaves the current phase in progress or reopens a phase you had marked completed, and the final approval completes the last phase. The builder never touches it, so a phase you do not move stays where it is. Then direct the 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}`;
|
|
59591
|
+
const FUSION_WATCHER_INSTRUCTIONS = `You are Fusion Supervisor (watcher) in an already-created native server pair. Follow the current turn's [fusion-review-policy] block when present; it overrides phase scheduling. 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 write the phase plan and direct its first phase. The plan is yours alone: call thread_plan_update with the builder's threadId, sending the complete ordered list every time, each phase named in 3-6 words by its outcome rather than by a command, file path, or flag, with exactly one in progress. 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 a complete reviewable slice of behavior. Never split per file, per function, or per trivial step. State each phase's completion condition to the builder in the advice, not in the banner title. On every later review, rewrite the same plan: an approved phase becomes completed and the next becomes in progress in the same call, an objection leaves the current phase in progress or reopens a phase you had marked completed, and the final approval completes the last phase. The builder never touches it, so a phase you do not move stays where it is. Then direct the 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_OUT_OF_ROLE_REQUEST_INSTRUCTIONS} ${FUSION_TOOL_BOUNDARY_INSTRUCTIONS} ${FUSION_PAIR_COMMUNICATION_INSTRUCTIONS}`;
|
|
59469
59592
|
/**
|
|
59470
59593
|
* The one-line stand-in for the full block on a message whose session already
|
|
59471
59594
|
* carries the role instructions.
|
|
@@ -59625,16 +59748,33 @@ const FUSION_SAFETY_KERNEL = [
|
|
|
59625
59748
|
"- Never commit, push, or open a pull request unless the current turn asked for it, and never commit to main or master directly.",
|
|
59626
59749
|
"- Never add AI attribution to a commit message, pull request, issue, comment, code, or document."
|
|
59627
59750
|
].join("\n");
|
|
59628
|
-
/**
|
|
59751
|
+
/**
|
|
59752
|
+
* Everything the supervisor half needs from the P4 MCP server, and nothing else.
|
|
59753
|
+
*
|
|
59754
|
+
* The task tools are here because planning is the supervisor's job, not an
|
|
59755
|
+
* aside to it: it owns the phase plan, so it has to be able to read the board,
|
|
59756
|
+
* break the work down and keep the authorized task honest. Mutation stays
|
|
59757
|
+
* bounded by the prompt rather than by this set, which can only say whether a
|
|
59758
|
+
* tool exists - the rule is the current task, never someone else's board row.
|
|
59759
|
+
* `task_propose` is deliberately absent: it tells its caller to stop and wait
|
|
59760
|
+
* for the user, and a supervisor that waits is one the builder sits idle
|
|
59761
|
+
* behind. Asking the user is what `ask_user_question` is for.
|
|
59762
|
+
*/
|
|
59629
59763
|
const FUSION_SUPERVISOR_P4_TOOLS = /* @__PURE__ */ new Set([
|
|
59630
59764
|
"thread_watch_review",
|
|
59631
59765
|
"thread_watch_events",
|
|
59632
59766
|
"thread_evidence_report",
|
|
59633
59767
|
"thread_advise",
|
|
59634
59768
|
"thread_gate_respond",
|
|
59769
|
+
"thread_pair_detach",
|
|
59635
59770
|
"thread_plan_update",
|
|
59636
59771
|
"ask_user_question",
|
|
59637
|
-
"task_current"
|
|
59772
|
+
"task_current",
|
|
59773
|
+
"task_get",
|
|
59774
|
+
"task_list",
|
|
59775
|
+
"task_create",
|
|
59776
|
+
"task_update",
|
|
59777
|
+
"ticket_resolve"
|
|
59638
59778
|
]);
|
|
59639
59779
|
/**
|
|
59640
59780
|
* What the builder half must not reach.
|
|
@@ -59642,15 +59782,23 @@ const FUSION_SUPERVISOR_P4_TOOLS = /* @__PURE__ */ new Set([
|
|
|
59642
59782
|
* Framed as a denial rather than an allowance because the builder's job is
|
|
59643
59783
|
* open-ended: it needs coding, verification and preview tools, and a new one of
|
|
59644
59784
|
* those should reach it without an edit here. What it must never have is the
|
|
59645
|
-
* pair's own machinery - spawning threads, creating
|
|
59646
|
-
*
|
|
59647
|
-
*
|
|
59648
|
-
*
|
|
59785
|
+
* pair's own machinery - spawning threads, creating pairs, advising, answering
|
|
59786
|
+
* its own gate - the phase plan, which the supervisor owns outright, plus
|
|
59787
|
+
* task-board mutation and the external services that belong to a person rather
|
|
59788
|
+
* than to an implementation turn. The review tools join that list: they read
|
|
59789
|
+
* the review of the builder's own work, which is the supervisor watching the
|
|
59790
|
+
* builder and never the other way round.
|
|
59791
|
+
*
|
|
59792
|
+
* Both roles retain `thread_pair_detach` as their way out. Its handler limits
|
|
59793
|
+
* detaching to a pair containing the caller whose other thread this session
|
|
59794
|
+
* created. The role policy exposes the action; the handler enforces ownership.
|
|
59649
59795
|
*/
|
|
59650
59796
|
const FUSION_BUILDER_DENIED_P4_TOOLS = /* @__PURE__ */ new Set([
|
|
59651
59797
|
"thread_spawn",
|
|
59798
|
+
"thread_watch_review",
|
|
59799
|
+
"thread_watch_events",
|
|
59800
|
+
"thread_evidence_report",
|
|
59652
59801
|
"thread_pair_create",
|
|
59653
|
-
"thread_pair_detach",
|
|
59654
59802
|
"thread_cleanup",
|
|
59655
59803
|
"thread_rename",
|
|
59656
59804
|
"thread_configure",
|
|
@@ -59695,21 +59843,90 @@ function fusionContextPolicyFor(role, optimizedContext) {
|
|
|
59695
59843
|
optimizedContext
|
|
59696
59844
|
};
|
|
59697
59845
|
}
|
|
59698
|
-
/**
|
|
59846
|
+
/**
|
|
59847
|
+
* Whether a role may call one P4 tool at all, regardless of any setting.
|
|
59848
|
+
*
|
|
59849
|
+
* The hiding functions below are a context measure: they keep a role's tool
|
|
59850
|
+
* list short, they only work on adapters that expose a per-session filter, and
|
|
59851
|
+
* the user can turn them off. This is the authorization question instead, so
|
|
59852
|
+
* it takes no setting and no adapter - a role that cannot act on a tool must
|
|
59853
|
+
* not be able to call it on any provider, whether or not the list it was shown
|
|
59854
|
+
* mentioned it.
|
|
59855
|
+
*
|
|
59856
|
+
* Shaped from the same two sets the hiding uses, so the list a role sees and
|
|
59857
|
+
* the calls it may make cannot drift apart. A thread with no role is not half
|
|
59858
|
+
* of a pair and is not this function's business.
|
|
59859
|
+
*/
|
|
59860
|
+
function fusionRoleMayCallP4Tool(role, toolName) {
|
|
59861
|
+
if (role === void 0) return true;
|
|
59862
|
+
return role === "watcher" ? FUSION_SUPERVISOR_P4_TOOLS.has(toolName) : !FUSION_BUILDER_DENIED_P4_TOOLS.has(toolName);
|
|
59863
|
+
}
|
|
59864
|
+
/**
|
|
59865
|
+
* Whether the context trimming applies. Ordinary threads never reach it.
|
|
59866
|
+
*
|
|
59867
|
+
* Only the measures that exist to save tokens ask this: the P4 tool list and
|
|
59868
|
+
* the setting sources. What a role may do is not a token question and must not
|
|
59869
|
+
* consult a setting the user can turn off - see `fusionRoleApplies`.
|
|
59870
|
+
*/
|
|
59699
59871
|
function fusionLeanContextApplies(input) {
|
|
59700
59872
|
return input.role !== void 0 && input.optimizedContext;
|
|
59701
59873
|
}
|
|
59702
59874
|
/**
|
|
59703
|
-
*
|
|
59875
|
+
* Whether a role's restrictions apply: whenever there is a role.
|
|
59876
|
+
*
|
|
59877
|
+
* Kept apart from the trimming above because the two answer different
|
|
59878
|
+
* questions. Turning context optimization off should cost a pair its token
|
|
59879
|
+
* savings, never hand the builder the tracker and the planning tools back or
|
|
59880
|
+
* give the supervisor an editor.
|
|
59881
|
+
*/
|
|
59882
|
+
function fusionRoleApplies(input) {
|
|
59883
|
+
return input.role !== void 0;
|
|
59884
|
+
}
|
|
59885
|
+
/**
|
|
59886
|
+
* The registered servers the supervisor half keeps, by lowercased name.
|
|
59704
59887
|
*
|
|
59705
|
-
*
|
|
59706
|
-
*
|
|
59707
|
-
*
|
|
59888
|
+
* Only the tracker, and only for the supervisor. It researches the request
|
|
59889
|
+
* before it plans, and `ticket_resolve` answers with a ticket's description
|
|
59890
|
+
* alone - the comments that routinely carry newer intent are reachable only
|
|
59891
|
+
* through the user's own Linear registration. The builder keeps none: it
|
|
59892
|
+
* implements the phase it was given and has no errand on a tracker.
|
|
59893
|
+
*
|
|
59894
|
+
* The name is repeated here rather than imported from `mcp/LinearMcpClient`,
|
|
59895
|
+
* which every adapter would then pull into a provider process. A test pins
|
|
59896
|
+
* the two together, exactly as the P4 tool catalogue is pinned.
|
|
59897
|
+
*/
|
|
59898
|
+
const FUSION_SUPERVISOR_EXTERNAL_MCP_SERVERS = /* @__PURE__ */ new Set(["linear"]);
|
|
59899
|
+
/**
|
|
59900
|
+
* The name a registration was given, with the user-scope prefix taken back off.
|
|
59901
|
+
*
|
|
59902
|
+
* A server the user registered in their own provider config reaches a session
|
|
59903
|
+
* re-keyed as `p4-user-<name>`, so matching the raw key would look for a name
|
|
59904
|
+
* the registry never hands over and would drop the tracker it was written to
|
|
59905
|
+
* keep. The prefix is spelled here for the same reason the name is: importing
|
|
59906
|
+
* the registry would pull it into every provider process.
|
|
59907
|
+
*/
|
|
59908
|
+
const USER_SCOPE_REGISTRATION_PREFIX = "p4-user-";
|
|
59909
|
+
const fusionRegistrationBareName = (name) => {
|
|
59910
|
+
const lowered = name.toLowerCase();
|
|
59911
|
+
return lowered.startsWith(USER_SCOPE_REGISTRATION_PREFIX) ? lowered.slice(8) : lowered;
|
|
59912
|
+
};
|
|
59913
|
+
/**
|
|
59914
|
+
* The external MCP registrations a Fusion session keeps.
|
|
59915
|
+
*
|
|
59916
|
+
* Applies to any pair turn, optimized or not: which servers a role may reach
|
|
59917
|
+
* is authorization, and the setting only governs what is trimmed to save
|
|
59918
|
+
* tokens.
|
|
59919
|
+
*
|
|
59920
|
+
* Everything else a user registered for their own work goes, because neither
|
|
59921
|
+
* role can act on it during a pair turn and every definition is paid for on
|
|
59922
|
+
* every turn of the loop. Computer Use needs no exception here - it is a
|
|
59708
59923
|
* provider-owned endpoint attached only to a session that was granted it, not
|
|
59709
59924
|
* a registration in this map, so a granted session keeps it either way.
|
|
59710
59925
|
*/
|
|
59711
59926
|
function fusionExternalMcpServers(servers, input) {
|
|
59712
|
-
|
|
59927
|
+
if (!fusionRoleApplies(input)) return { ...servers };
|
|
59928
|
+
if (input.role !== "watcher") return {};
|
|
59929
|
+
return Object.fromEntries(Object.entries(servers).filter(([name]) => FUSION_SUPERVISOR_EXTERNAL_MCP_SERVERS.has(fusionRegistrationBareName(name))));
|
|
59713
59930
|
}
|
|
59714
59931
|
/**
|
|
59715
59932
|
* P4 tools this role must not see, given the full catalogue.
|
|
@@ -59723,20 +59940,70 @@ function fusionHiddenP4Tools(catalogue, input) {
|
|
|
59723
59940
|
return input.role === "watcher" ? catalogue.filter((name) => !FUSION_SUPERVISOR_P4_TOOLS.has(name)) : catalogue.filter((name) => FUSION_BUILDER_DENIED_P4_TOOLS.has(name));
|
|
59724
59941
|
}
|
|
59725
59942
|
/**
|
|
59943
|
+
* Provider-native tools the supervisor must not see.
|
|
59944
|
+
*
|
|
59945
|
+
* It reviews and directs; it never edits the tree. Reading tools stay, because
|
|
59946
|
+
* grounding an objection in the code is exactly its job, and a shell stays too
|
|
59947
|
+
* - `git log` and `git status` are how it derives phase from artifacts. What
|
|
59948
|
+
* goes is the means to write the change it is supposed to be reviewing.
|
|
59949
|
+
*
|
|
59950
|
+
* Named per provider, like the builder's list, because the names are the
|
|
59951
|
+
* provider's rather than ours.
|
|
59952
|
+
*/
|
|
59953
|
+
const FUSION_SUPERVISOR_DENIED_NATIVE_TOOLS = [
|
|
59954
|
+
"Edit",
|
|
59955
|
+
"MultiEdit",
|
|
59956
|
+
"Write",
|
|
59957
|
+
"NotebookEdit",
|
|
59958
|
+
"apply_patch"
|
|
59959
|
+
];
|
|
59960
|
+
/**
|
|
59726
59961
|
* Provider-native tools this role must not see.
|
|
59727
59962
|
*
|
|
59728
59963
|
* The supervisor keeps its own planning tool: it is the half that plans, and
|
|
59729
|
-
* for its own thread that tool is the ordinary one.
|
|
59964
|
+
* for its own thread that tool is the ordinary one. It loses the editing tools
|
|
59965
|
+
* instead, which are the builder's half of the same split.
|
|
59966
|
+
*
|
|
59967
|
+
* Applies to any pair turn, optimized or not, for the same reason the external
|
|
59968
|
+
* registrations do: a builder holding the planning tool is a role problem, not
|
|
59969
|
+
* a token one.
|
|
59730
59970
|
*/
|
|
59731
59971
|
function fusionHiddenNativeTools(input) {
|
|
59732
|
-
|
|
59972
|
+
if (!fusionRoleApplies(input)) return [];
|
|
59973
|
+
return input.role === "implementer" ? FUSION_BUILDER_DENIED_NATIVE_TOOLS : FUSION_SUPERVISOR_DENIED_NATIVE_TOOLS;
|
|
59974
|
+
}
|
|
59975
|
+
/**
|
|
59976
|
+
* Global agents a pair still owes its user after the lean profile drops the
|
|
59977
|
+
* user setting source.
|
|
59978
|
+
*
|
|
59979
|
+
* Dropping that source is what makes the profile lean, but it takes the user's
|
|
59980
|
+
* subagent definitions with it, and the delivery loop this pair runs on names
|
|
59981
|
+
* one of them outright: the supervisor will not accept the work until the
|
|
59982
|
+
* global `pr-reviewer` has reviewed the branch. Leaving it unregistered means
|
|
59983
|
+
* the builder either cannot comply or quietly reviews with something else,
|
|
59984
|
+
* which is the failure this list exists to prevent. Named rather than
|
|
59985
|
+
* discovered, so the cost stays one definition instead of every agent the user
|
|
59986
|
+
* happens to have.
|
|
59987
|
+
*/
|
|
59988
|
+
const FUSION_REQUIRED_GLOBAL_AGENTS = ["pr-reviewer"];
|
|
59989
|
+
/**
|
|
59990
|
+
* Which global agents this session has to register for itself.
|
|
59991
|
+
*
|
|
59992
|
+
* Empty unless the lean profile actually dropped the user source: when it is
|
|
59993
|
+
* off the provider loads them the usual way, and registering them again would
|
|
59994
|
+
* be a second definition of the same agent.
|
|
59995
|
+
*/
|
|
59996
|
+
function fusionRequiredGlobalAgents(input) {
|
|
59997
|
+
return fusionLeanContextApplies(input) ? FUSION_REQUIRED_GLOBAL_AGENTS : [];
|
|
59733
59998
|
}
|
|
59734
59999
|
/**
|
|
59735
60000
|
* Setting sources a Fusion session reads.
|
|
59736
60001
|
*
|
|
59737
60002
|
* `user` carries the global memory files and the user-level skills; the
|
|
59738
60003
|
* project's own instructions live in `project` and `local` and stay, because
|
|
59739
|
-
* they are the ones that describe the code being changed.
|
|
60004
|
+
* they are the ones that describe the code being changed. What the drop also
|
|
60005
|
+
* takes, and what `fusionRequiredGlobalAgents` above hands back, is the user's
|
|
60006
|
+
* subagent definitions.
|
|
59740
60007
|
*/
|
|
59741
60008
|
function fusionSettingSources(sources, input) {
|
|
59742
60009
|
if (!fusionLeanContextApplies(input)) return sources;
|
|
@@ -60303,7 +60570,7 @@ const defaultCancelTimeout = Duration.seconds(15);
|
|
|
60303
60570
|
const defaultSessionLoadTimeout = Duration.seconds(90);
|
|
60304
60571
|
const defaultSessionLoadReplayIdleGap = Duration.seconds(2);
|
|
60305
60572
|
var AcpSessionRuntime = class extends Context.Service()("@p4code/cli/provider/acp/AcpSessionRuntime") {};
|
|
60306
|
-
const make$
|
|
60573
|
+
const make$76 = (options) => Effect.gen(function* () {
|
|
60307
60574
|
const crypto = yield* Crypto.Crypto;
|
|
60308
60575
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
60309
60576
|
const runtimeScope = yield* Scope.Scope;
|
|
@@ -60707,7 +60974,7 @@ const make$74 = (options) => Effect.gen(function* () {
|
|
|
60707
60974
|
notify: acp.raw.notify
|
|
60708
60975
|
};
|
|
60709
60976
|
});
|
|
60710
|
-
const layer$63 = (options) => Layer.effect(AcpSessionRuntime, make$
|
|
60977
|
+
const layer$63 = (options) => Layer.effect(AcpSessionRuntime, make$76(options));
|
|
60711
60978
|
function sessionConfigOptionsFromSetup(response) {
|
|
60712
60979
|
return response?.configOptions ?? [];
|
|
60713
60980
|
}
|
|
@@ -65165,7 +65432,7 @@ const BundledOnlyModelManifest = {
|
|
|
65165
65432
|
refreshInBackground: Effect.void
|
|
65166
65433
|
};
|
|
65167
65434
|
Layer.succeed(ModelManifest, BundledOnlyModelManifest);
|
|
65168
|
-
const make$
|
|
65435
|
+
const make$75 = Effect.gen(function* () {
|
|
65169
65436
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
65170
65437
|
const path = yield* Path$1.Path;
|
|
65171
65438
|
const config = yield* ServerConfig$1;
|
|
@@ -65210,7 +65477,7 @@ const make$73 = Effect.gen(function* () {
|
|
|
65210
65477
|
refreshInBackground: Effect.forkIn(guardedRefresh, serviceScope).pipe(Effect.asVoid)
|
|
65211
65478
|
});
|
|
65212
65479
|
});
|
|
65213
|
-
const layer$62 = Layer.effect(ModelManifest, make$
|
|
65480
|
+
const layer$62 = Layer.effect(ModelManifest, make$75);
|
|
65214
65481
|
//#endregion
|
|
65215
65482
|
//#region src/provider/ProviderDriver.ts
|
|
65216
65483
|
function defaultProviderContinuationIdentity(input) {
|
|
@@ -65476,11 +65743,11 @@ const makeTextGenerationFromRegistry = (registry) => TextGeneration.of({
|
|
|
65476
65743
|
detail: "This provider does not report account usage."
|
|
65477
65744
|
}))))
|
|
65478
65745
|
});
|
|
65479
|
-
const make$
|
|
65746
|
+
const make$74 = Effect.gen(function* () {
|
|
65480
65747
|
const registry = yield* ProviderInstanceRegistry;
|
|
65481
65748
|
return makeTextGenerationFromRegistry(registry);
|
|
65482
65749
|
});
|
|
65483
|
-
const layer$61 = Layer.effect(TextGeneration, make$
|
|
65750
|
+
const layer$61 = Layer.effect(TextGeneration, make$74);
|
|
65484
65751
|
//#endregion
|
|
65485
65752
|
//#region src/provider/Layers/claudeUsageLimits.ts
|
|
65486
65753
|
const SESSION_MINS$1 = 300;
|
|
@@ -69927,6 +70194,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
69927
70194
|
optimizedContext: fusionPromptSettings?.optimizedContext ?? DEFAULT_FUSION_PROMPT_SETTINGS.optimizedContext
|
|
69928
70195
|
};
|
|
69929
70196
|
const externalMcpServers = fusionExternalMcpServers(registeredMcpServers, fusionContextPolicy);
|
|
70197
|
+
const requiredGlobalAgents = yield* discoverClaudeUserAgents(claudeSettings, fusionRequiredGlobalAgents(fusionContextPolicy), claudeEnvironment, input.cwd).pipe(Effect.provideService(FileSystem.FileSystem, fileSystem), Effect.provideService(Path$1.Path, path));
|
|
69930
70198
|
const hiddenTools = [...fusionHiddenP4Tools(providerMcpToolNames(), fusionContextPolicy).map((name) => `mcp__${P4CODE_MCP_SERVER_NAME}__${name}`), ...fusionHiddenNativeTools(fusionContextPolicy)];
|
|
69931
70199
|
const unpromptedSubagents = input.unpromptedSubagents !== void 0 ? input.unpromptedSubagents : options?.resolveUnpromptedSubagents === void 0 ? DEFAULT_SERVER_SETTINGS.enableUnpromptedSubagents : yield* options.resolveUnpromptedSubagents;
|
|
69932
70200
|
const compressRuleset = compressRulesetFor(input.compressMode ?? "off");
|
|
@@ -69958,6 +70226,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
69958
70226
|
...systemPromptAppend.length > 0 ? { append: systemPromptAppend } : {}
|
|
69959
70227
|
},
|
|
69960
70228
|
settingSources: [...fusionSettingSources(CLAUDE_SETTING_SOURCES, fusionContextPolicy)],
|
|
70229
|
+
...Object.keys(requiredGlobalAgents).length > 0 ? { agents: requiredGlobalAgents } : {},
|
|
69961
70230
|
...hiddenTools.length > 0 ? { disallowedTools: hiddenTools } : {},
|
|
69962
70231
|
...effectiveEffort ? { effort: effectiveEffort } : {},
|
|
69963
70232
|
...permissionMode ? { permissionMode } : {},
|
|
@@ -88447,7 +88716,7 @@ const makeTerminationError = (handle) => Effect.match(handle.exitCode, {
|
|
|
88447
88716
|
//#endregion
|
|
88448
88717
|
//#region ../../packages/effect-codex-app-server/src/client.ts
|
|
88449
88718
|
var CodexAppServerClient = class extends Context.Service()("effect-codex-app-server/client/CodexAppServerClient") {};
|
|
88450
|
-
const make$
|
|
88719
|
+
const make$73 = Effect.fn("effect-codex-app-server/CodexAppServerClient.make")(function* (stdio, options = {}, terminationError) {
|
|
88451
88720
|
const requestHandlers = /* @__PURE__ */ new Map();
|
|
88452
88721
|
const notificationHandlers = /* @__PURE__ */ new Map();
|
|
88453
88722
|
let unknownRequestHandler;
|
|
@@ -88514,7 +88783,7 @@ const make$71 = Effect.fn("effect-codex-app-server/CodexAppServerClient.make")(f
|
|
|
88514
88783
|
const layerChildProcess = (handle, options = {}) => Layer.effect(CodexAppServerClient, makeChildProcessClient(handle, options));
|
|
88515
88784
|
const makeChildProcessClient = Effect.fn("effect-codex-app-server/CodexAppServerClient.makeChildProcessClient")(function* (handle, options) {
|
|
88516
88785
|
yield* Stream.runDrain(handle.stderr).pipe(Effect.ignore, Effect.forkScoped);
|
|
88517
|
-
return yield* make$
|
|
88786
|
+
return yield* make$73(makeChildStdio(handle), options, makeTerminationError(handle));
|
|
88518
88787
|
});
|
|
88519
88788
|
const resolveCodexLaunchArgs = (launchArgs, environment = process.env) => environment["P4CODE_CODEX_LAUNCH_ARGS"]?.trim() || launchArgs?.trim() || "";
|
|
88520
88789
|
const codexLaunchArgv = (launchArgs) => tokenizeCliArgs(launchArgs);
|
|
@@ -95673,7 +95942,7 @@ function mapMuseExecRecord(input) {
|
|
|
95673
95942
|
const toolName = state.toolNameByTaskId.get(taskId);
|
|
95674
95943
|
state.settledToolTaskIds.add(taskId);
|
|
95675
95944
|
const failed = stringField$1(recordField(payload, "correlation_facts"), "outcome") === "error";
|
|
95676
|
-
const detail = truncate(stringField$1(payload, "text"), MAX_TOOL_DETAIL_CHARS);
|
|
95945
|
+
const detail = truncate$1(stringField$1(payload, "text"), MAX_TOOL_DETAIL_CHARS);
|
|
95677
95946
|
const editFacts = recordField(payload, "edit_facts");
|
|
95678
95947
|
return [(stamp) => ({
|
|
95679
95948
|
type: "item.completed",
|
|
@@ -95697,7 +95966,7 @@ function mapMuseExecRecord(input) {
|
|
|
95697
95966
|
const toolName = state.toolNameByTaskId.get(taskId);
|
|
95698
95967
|
if (!toolName || state.settledToolTaskIds.has(taskId)) return [];
|
|
95699
95968
|
state.settledToolTaskIds.add(taskId);
|
|
95700
|
-
const detail = truncate(stringField$1(event, "reason"), MAX_TOOL_DETAIL_CHARS);
|
|
95969
|
+
const detail = truncate$1(stringField$1(event, "reason"), MAX_TOOL_DETAIL_CHARS);
|
|
95701
95970
|
return [(stamp) => ({
|
|
95702
95971
|
type: "item.completed",
|
|
95703
95972
|
...stamp,
|
|
@@ -95874,7 +96143,7 @@ function recordField(source, key) {
|
|
|
95874
96143
|
function eventField(payload) {
|
|
95875
96144
|
return recordField(payload, "event");
|
|
95876
96145
|
}
|
|
95877
|
-
function truncate(value, max) {
|
|
96146
|
+
function truncate$1(value, max) {
|
|
95878
96147
|
if (value === void 0) return void 0;
|
|
95879
96148
|
const trimmed = value.trim();
|
|
95880
96149
|
if (trimmed.length === 0) return void 0;
|
|
@@ -100275,8 +100544,8 @@ const makeWithReader = (api) => Effect.gen(function* () {
|
|
|
100275
100544
|
}))
|
|
100276
100545
|
};
|
|
100277
100546
|
});
|
|
100278
|
-
const make$
|
|
100279
|
-
const layer$60 = Layer.effect(UsageLimitSources, make$
|
|
100547
|
+
const make$72 = makeCliproxyApi.pipe(Effect.flatMap(makeWithReader));
|
|
100548
|
+
const layer$60 = Layer.effect(UsageLimitSources, make$72);
|
|
100280
100549
|
//#endregion
|
|
100281
100550
|
//#region src/resourceTelemetry/HostResources.ts
|
|
100282
100551
|
const CPU_SAMPLE_INTERVAL = "200 millis";
|
|
@@ -100311,7 +100580,7 @@ function darwinAvailableMemory(output) {
|
|
|
100311
100580
|
const available = (Number(free) + Number(inactive) + Number(speculative)) * Number(pageSize);
|
|
100312
100581
|
return Number.isSafeInteger(available) && Number(pageSize) > 0 ? available : null;
|
|
100313
100582
|
}
|
|
100314
|
-
const make$
|
|
100583
|
+
const make$71 = Effect.fn("makeHostResources")(function* () {
|
|
100315
100584
|
const fs = yield* FileSystem.FileSystem;
|
|
100316
100585
|
const platform = yield* HostProcessPlatform;
|
|
100317
100586
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
@@ -100345,7 +100614,7 @@ const make$69 = Effect.fn("makeHostResources")(function* () {
|
|
|
100345
100614
|
});
|
|
100346
100615
|
return HostResources.of({ read: Cache.get(cache, "host") });
|
|
100347
100616
|
});
|
|
100348
|
-
const layer$59 = Layer.effect(HostResources, make$
|
|
100617
|
+
const layer$59 = Layer.effect(HostResources, make$71());
|
|
100349
100618
|
//#endregion
|
|
100350
100619
|
//#region src/resourceTelemetry/DesktopTelemetryReceiver.ts
|
|
100351
100620
|
const INITIAL_SAMPLE_DEADLINE_MS = 9e4;
|
|
@@ -100480,7 +100749,7 @@ function requireDesktopTelemetryWriteProgress(fd, remainingBytes, written) {
|
|
|
100480
100749
|
}));
|
|
100481
100750
|
}
|
|
100482
100751
|
/** @public Service construction is part of the canonical Effect module API. */
|
|
100483
|
-
const make$
|
|
100752
|
+
const make$70 = Effect.fn("resourceTelemetry.desktopTelemetryReceiver.make")(function* () {
|
|
100484
100753
|
const serverConfig = yield* ServerConfig$1;
|
|
100485
100754
|
const hasDescriptors = serverConfig.mode === "desktop" && serverConfig.desktopTelemetryFd === 4 && serverConfig.desktopTelemetryControlFd === 5;
|
|
100486
100755
|
const config = {
|
|
@@ -100637,7 +100906,7 @@ const make$68 = Effect.fn("resourceTelemetry.desktopTelemetryReceiver.make")(fun
|
|
|
100637
100906
|
setDiagnosticsDemand
|
|
100638
100907
|
});
|
|
100639
100908
|
});
|
|
100640
|
-
const layer$58 = Layer.effect(DesktopTelemetryReceiver, make$
|
|
100909
|
+
const layer$58 = Layer.effect(DesktopTelemetryReceiver, make$70());
|
|
100641
100910
|
//#endregion
|
|
100642
100911
|
//#region src/resourceTelemetry/Model.ts
|
|
100643
100912
|
const MAX_DELTA_INTERVAL_MS = 3e4;
|
|
@@ -101062,7 +101331,7 @@ function resourceMonitorRustTarget(platform, architecture, linuxLibc) {
|
|
|
101062
101331
|
}
|
|
101063
101332
|
if (platform === "win32") return architecture === "arm64" ? "aarch64-pc-windows-msvc" : architecture === "x64" ? "x86_64-pc-windows-msvc" : void 0;
|
|
101064
101333
|
}
|
|
101065
|
-
const make$
|
|
101334
|
+
const make$69 = Effect.fn("resourceTelemetry.resourceMonitorBinary.make")(function* () {
|
|
101066
101335
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
101067
101336
|
const path = yield* Path$1.Path;
|
|
101068
101337
|
const platform = yield* HostProcessPlatform;
|
|
@@ -101108,7 +101377,7 @@ const make$67 = Effect.fn("resourceTelemetry.resourceMonitorBinary.make")(functi
|
|
|
101108
101377
|
});
|
|
101109
101378
|
return ResourceMonitorBinary.of({ resolve });
|
|
101110
101379
|
});
|
|
101111
|
-
const layer$57 = Layer.effect(ResourceMonitorBinary, make$
|
|
101380
|
+
const layer$57 = Layer.effect(ResourceMonitorBinary, make$69());
|
|
101112
101381
|
//#endregion
|
|
101113
101382
|
//#region src/resourceTelemetry/NativeTelemetryClient.ts
|
|
101114
101383
|
const SAMPLE_INTERVAL_MS$1 = 1e3;
|
|
@@ -101258,7 +101527,7 @@ function canCommandNativeTelemetrySidecar(status, hasHandle) {
|
|
|
101258
101527
|
return hasHandle && (status === "healthy" || status === "degraded");
|
|
101259
101528
|
}
|
|
101260
101529
|
/** @public Service construction is part of the canonical Effect module API. */
|
|
101261
|
-
const make$
|
|
101530
|
+
const make$68 = Effect.fn("resourceTelemetry.nativeTelemetryClient.make")(function* () {
|
|
101262
101531
|
const binary = yield* ResourceMonitorBinary;
|
|
101263
101532
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
101264
101533
|
const crypto = yield* Crypto.Crypto;
|
|
@@ -101669,7 +101938,7 @@ const make$66 = Effect.fn("resourceTelemetry.nativeTelemetryClient.make")(functi
|
|
|
101669
101938
|
})
|
|
101670
101939
|
});
|
|
101671
101940
|
});
|
|
101672
|
-
const layer$56 = Layer.effect(NativeTelemetryClient, make$
|
|
101941
|
+
const layer$56 = Layer.effect(NativeTelemetryClient, make$68());
|
|
101673
101942
|
//#endregion
|
|
101674
101943
|
//#region src/resourceTelemetry/ResourceAttribution.ts
|
|
101675
101944
|
var ResourceAttribution = class extends Context.Service()("@p4code/cli/resourceTelemetry/ResourceAttribution") {};
|
|
@@ -101681,7 +101950,7 @@ function nonNegativeInteger(value, fallback) {
|
|
|
101681
101950
|
if (!Number.isFinite(value)) return 0;
|
|
101682
101951
|
return Math.max(0, Math.round(value));
|
|
101683
101952
|
}
|
|
101684
|
-
const make$
|
|
101953
|
+
const make$67 = Effect.fn("resourceTelemetry.resourceAttribution.make")(function* () {
|
|
101685
101954
|
const entries = yield* Ref.make(/* @__PURE__ */ new Map());
|
|
101686
101955
|
const record = (input) => Ref.update(entries, (current) => {
|
|
101687
101956
|
const next = new Map(current);
|
|
@@ -101707,7 +101976,7 @@ const make$65 = Effect.fn("resourceTelemetry.resourceAttribution.make")(function
|
|
|
101707
101976
|
})
|
|
101708
101977
|
});
|
|
101709
101978
|
});
|
|
101710
|
-
const layer$55 = Layer.effect(ResourceAttribution, make$
|
|
101979
|
+
const layer$55 = Layer.effect(ResourceAttribution, make$67());
|
|
101711
101980
|
//#endregion
|
|
101712
101981
|
//#region src/resourceTelemetry/ResourceTelemetryHistory.ts
|
|
101713
101982
|
const MAX_HISTORY_WINDOW_MS = 60 * 6e4;
|
|
@@ -101930,7 +102199,7 @@ function buildHealth(input) {
|
|
|
101930
102199
|
};
|
|
101931
102200
|
}
|
|
101932
102201
|
/** @public Service construction is part of the canonical Effect module API. */
|
|
101933
|
-
const make$
|
|
102202
|
+
const make$66 = Effect.fn("resourceTelemetry.resourceTelemetry.make")(function* () {
|
|
101934
102203
|
const nativeClient = yield* NativeTelemetryClient;
|
|
101935
102204
|
const desktopReceiver = yield* DesktopTelemetryReceiver;
|
|
101936
102205
|
const attribution = yield* ResourceAttribution;
|
|
@@ -102182,7 +102451,7 @@ const make$64 = Effect.fn("resourceTelemetry.resourceTelemetry.make")(function*
|
|
|
102182
102451
|
})))
|
|
102183
102452
|
});
|
|
102184
102453
|
});
|
|
102185
|
-
const layer$54 = Layer.effect(ResourceTelemetry, make$
|
|
102454
|
+
const layer$54 = Layer.effect(ResourceTelemetry, make$66());
|
|
102186
102455
|
//#endregion
|
|
102187
102456
|
//#region src/device/DeviceInspection.ts
|
|
102188
102457
|
const READ_TIMEOUT_MS = 1e4;
|
|
@@ -105337,7 +105606,7 @@ const classifyNonZeroExit = (command, stderr) => {
|
|
|
105337
105606
|
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";
|
|
105338
105607
|
return "command-failed";
|
|
105339
105608
|
};
|
|
105340
|
-
const make$
|
|
105609
|
+
const make$65 = Effect.gen(function* () {
|
|
105341
105610
|
const processRunner = yield* ProcessRunner;
|
|
105342
105611
|
const run = Effect.fn("VcsProcess.run")(function* (input) {
|
|
105343
105612
|
const baseError = {
|
|
@@ -105396,7 +105665,7 @@ const make$63 = Effect.gen(function* () {
|
|
|
105396
105665
|
});
|
|
105397
105666
|
return VcsProcess.of({ run });
|
|
105398
105667
|
});
|
|
105399
|
-
const layer$53 = Layer.effect(VcsProcess, make$
|
|
105668
|
+
const layer$53 = Layer.effect(VcsProcess, make$65).pipe(Layer.provide(layer$85));
|
|
105400
105669
|
//#endregion
|
|
105401
105670
|
//#region src/vcs/VcsDriver.ts
|
|
105402
105671
|
var VcsDriver = class extends Context.Service()("@p4code/cli/vcs/VcsDriver") {};
|
|
@@ -105847,12 +106116,12 @@ const makeVcsDriver = Effect.gen(function* () {
|
|
|
105847
106116
|
const driver = yield* makeVcsDriverShape();
|
|
105848
106117
|
return VcsDriver.of(driver);
|
|
105849
106118
|
});
|
|
105850
|
-
const make$
|
|
106119
|
+
const make$64 = Effect.gen(function* () {
|
|
105851
106120
|
const git = yield* makeGitVcsDriverCore();
|
|
105852
106121
|
return GitVcsDriver.of(git);
|
|
105853
106122
|
});
|
|
105854
106123
|
Layer.effect(VcsDriver, makeVcsDriver);
|
|
105855
|
-
const layer$52 = Layer.effect(GitVcsDriver, make$
|
|
106124
|
+
const layer$52 = Layer.effect(GitVcsDriver, make$64);
|
|
105856
106125
|
//#endregion
|
|
105857
106126
|
//#region src/vcs/VcsProjectConfig.ts
|
|
105858
106127
|
const ProjectVcsConfigJson = fromLenientJson(Schema$1.Struct({
|
|
@@ -105884,7 +106153,7 @@ const logVcsProjectConfigError = (error) => Effect.logWarning(error).pipe(Effect
|
|
|
105884
106153
|
configPath: error.configPath,
|
|
105885
106154
|
errorTag: error._tag
|
|
105886
106155
|
}));
|
|
105887
|
-
const make$
|
|
106156
|
+
const make$63 = Effect.gen(function* () {
|
|
105888
106157
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
105889
106158
|
const path = yield* Path$1.Path;
|
|
105890
106159
|
const findConfigPath = Effect.fn("VcsProjectConfig.findConfigPath")(function* (cwd) {
|
|
@@ -105925,7 +106194,7 @@ const make$61 = Effect.gen(function* () {
|
|
|
105925
106194
|
});
|
|
105926
106195
|
return VcsProjectConfig.of({ resolveKind });
|
|
105927
106196
|
});
|
|
105928
|
-
const layer$51 = Layer.effect(VcsProjectConfig, make$
|
|
106197
|
+
const layer$51 = Layer.effect(VcsProjectConfig, make$63);
|
|
105929
106198
|
//#endregion
|
|
105930
106199
|
//#region src/vcs/VcsDriverRegistry.ts
|
|
105931
106200
|
const DETECTION_CACHE_CAPACITY = 2048;
|
|
@@ -105945,7 +106214,7 @@ function parseDetectionCacheKey(key) {
|
|
|
105945
106214
|
cwd: key.slice(separatorIndex + 1)
|
|
105946
106215
|
};
|
|
105947
106216
|
}
|
|
105948
|
-
const make$
|
|
106217
|
+
const make$62 = Effect.gen(function* () {
|
|
105949
106218
|
const projectConfig = yield* VcsProjectConfig;
|
|
105950
106219
|
const git = yield* makeVcsDriver;
|
|
105951
106220
|
const drivers = { git };
|
|
@@ -106002,7 +106271,7 @@ const make$60 = Effect.gen(function* () {
|
|
|
106002
106271
|
resolve
|
|
106003
106272
|
});
|
|
106004
106273
|
});
|
|
106005
|
-
const layer$50 = Layer.effect(VcsDriverRegistry, make$
|
|
106274
|
+
const layer$50 = Layer.effect(VcsDriverRegistry, make$62).pipe(Layer.provide(layer$51));
|
|
106006
106275
|
//#endregion
|
|
106007
106276
|
//#region src/checkpointing/CheckpointStore.ts
|
|
106008
106277
|
/**
|
|
@@ -106022,7 +106291,7 @@ const layer$50 = Layer.effect(VcsDriverRegistry, make$60).pipe(Layer.provide(lay
|
|
|
106022
106291
|
*/
|
|
106023
106292
|
/** Service tag for checkpoint persistence and restore operations. */
|
|
106024
106293
|
var CheckpointStore = class extends Context.Service()("@p4code/cli/checkpointing/CheckpointStore") {};
|
|
106025
|
-
const make$
|
|
106294
|
+
const make$61 = Effect.gen(function* () {
|
|
106026
106295
|
const vcsRegistry = yield* VcsDriverRegistry;
|
|
106027
106296
|
const resolveCheckpoints = Effect.fn("CheckpointStore.resolveCheckpoints")(function* (operation, cwd) {
|
|
106028
106297
|
const handle = yield* vcsRegistry.resolve({ cwd });
|
|
@@ -106061,7 +106330,7 @@ const make$59 = Effect.gen(function* () {
|
|
|
106061
106330
|
deleteCheckpointRefs
|
|
106062
106331
|
});
|
|
106063
106332
|
});
|
|
106064
|
-
const layer$49 = Layer.effect(CheckpointStore, make$
|
|
106333
|
+
const layer$49 = Layer.effect(CheckpointStore, make$61);
|
|
106065
106334
|
//#endregion
|
|
106066
106335
|
//#region src/checkpointing/CheckpointDiffQuery.ts
|
|
106067
106336
|
/**
|
|
@@ -106083,7 +106352,7 @@ function buildTurnDiffResult(input, diff) {
|
|
|
106083
106352
|
diff
|
|
106084
106353
|
};
|
|
106085
106354
|
}
|
|
106086
|
-
const make$
|
|
106355
|
+
const make$60 = Effect.gen(function* () {
|
|
106087
106356
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
106088
106357
|
const checkpointStore = yield* CheckpointStore;
|
|
106089
106358
|
const threadActivities = yield* ProjectionThreadActivityRepository;
|
|
@@ -106254,7 +106523,7 @@ const make$58 = Effect.gen(function* () {
|
|
|
106254
106523
|
getFullThreadDiff
|
|
106255
106524
|
});
|
|
106256
106525
|
});
|
|
106257
|
-
const layer$48 = Layer.effect(CheckpointDiffQuery, make$
|
|
106526
|
+
const layer$48 = Layer.effect(CheckpointDiffQuery, make$60);
|
|
106258
106527
|
//#endregion
|
|
106259
106528
|
//#region src/orchestration/ThreadLiveEventCoalescer.ts
|
|
106260
106529
|
const COALESCE_WINDOW = Duration.millis(50);
|
|
@@ -106799,7 +107068,7 @@ const serversEqual = (left, right) => {
|
|
|
106799
107068
|
}
|
|
106800
107069
|
return true;
|
|
106801
107070
|
};
|
|
106802
|
-
const make$
|
|
107071
|
+
const make$59 = Effect.gen(function* PortDiscoveryMake() {
|
|
106803
107072
|
const net = yield* NetService;
|
|
106804
107073
|
const processRunner = yield* ProcessRunner;
|
|
106805
107074
|
const hostPlatform = yield* HostProcessPlatform;
|
|
@@ -106950,7 +107219,7 @@ const make$57 = Effect.gen(function* PortDiscoveryMake() {
|
|
|
106950
107219
|
unregisterTerminal
|
|
106951
107220
|
});
|
|
106952
107221
|
}).pipe(Effect.withSpan("PortDiscovery.make"));
|
|
106953
|
-
const layer$47 = Layer.effect(PortDiscovery, make$
|
|
107222
|
+
const layer$47 = Layer.effect(PortDiscovery, make$59);
|
|
106954
107223
|
//#endregion
|
|
106955
107224
|
//#region src/terminal/Manager.ts
|
|
106956
107225
|
/**
|
|
@@ -107628,7 +107897,7 @@ function normalizedRuntimeEnv(env) {
|
|
|
107628
107897
|
if (entries.length === 0) return null;
|
|
107629
107898
|
return Object.fromEntries(entries.toSorted(([left], [right]) => left.localeCompare(right)));
|
|
107630
107899
|
}
|
|
107631
|
-
const make$
|
|
107900
|
+
const make$58 = Effect.fn("TerminalManager.make")(function* () {
|
|
107632
107901
|
const { terminalLogsDir } = yield* ServerConfig$1;
|
|
107633
107902
|
const ptyAdapter = yield* PtyAdapter;
|
|
107634
107903
|
const portDiscovery = yield* PortDiscovery;
|
|
@@ -108590,7 +108859,7 @@ const makeWithOptions$1 = Effect.fn("TerminalManager.makeWithOptions")(function*
|
|
|
108590
108859
|
subscribeMetadata
|
|
108591
108860
|
});
|
|
108592
108861
|
});
|
|
108593
|
-
const layer$46 = Layer.effect(TerminalManager, make$
|
|
108862
|
+
const layer$46 = Layer.effect(TerminalManager, make$58()).pipe(Layer.provide(layer$85));
|
|
108594
108863
|
//#endregion
|
|
108595
108864
|
//#region src/project/ProjectSetupScriptRunner.ts
|
|
108596
108865
|
var ProjectSetupScriptOperationError = class extends Schema$1.TaggedErrorClass()("ProjectSetupScriptOperationError", {
|
|
@@ -108622,7 +108891,7 @@ var ProjectSetupScriptProjectNotFoundError = class extends Schema$1.TaggedErrorC
|
|
|
108622
108891
|
};
|
|
108623
108892
|
Schema$1.Union([ProjectSetupScriptOperationError, ProjectSetupScriptProjectNotFoundError]);
|
|
108624
108893
|
var ProjectSetupScriptRunner = class extends Context.Service()("@p4code/cli/project/ProjectSetupScriptRunner") {};
|
|
108625
|
-
const make$
|
|
108894
|
+
const make$57 = Effect.gen(function* () {
|
|
108626
108895
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
108627
108896
|
const terminalManager = yield* TerminalManager;
|
|
108628
108897
|
const settingsService = yield* Effect.serviceOption(ServerSettingsService);
|
|
@@ -108685,7 +108954,7 @@ const make$55 = Effect.gen(function* () {
|
|
|
108685
108954
|
});
|
|
108686
108955
|
return ProjectSetupScriptRunner.of({ runForThread });
|
|
108687
108956
|
});
|
|
108688
|
-
const layer$45 = Layer.effect(ProjectSetupScriptRunner, make$
|
|
108957
|
+
const layer$45 = Layer.effect(ProjectSetupScriptRunner, make$57);
|
|
108689
108958
|
//#endregion
|
|
108690
108959
|
//#region src/sourceControl/azureDevOpsPullRequests.ts
|
|
108691
108960
|
const AzureDevOpsPullRequestSchema = Schema$1.Struct({
|
|
@@ -109013,7 +109282,7 @@ function decodeAzureDevOpsJson(raw, schema, operation, cwd) {
|
|
|
109013
109282
|
cause
|
|
109014
109283
|
})));
|
|
109015
109284
|
}
|
|
109016
|
-
const make$
|
|
109285
|
+
const make$56 = Effect.gen(function* () {
|
|
109017
109286
|
const process = yield* VcsProcess;
|
|
109018
109287
|
const execute = (input) => process.run({
|
|
109019
109288
|
operation: "AzureDevOpsCli.execute",
|
|
@@ -109155,7 +109424,7 @@ const make$54 = Effect.gen(function* () {
|
|
|
109155
109424
|
}).pipe(Effect.asVoid)
|
|
109156
109425
|
});
|
|
109157
109426
|
});
|
|
109158
|
-
const layer$44 = Layer.effect(AzureDevOpsCli, make$
|
|
109427
|
+
const layer$44 = Layer.effect(AzureDevOpsCli, make$56);
|
|
109159
109428
|
//#endregion
|
|
109160
109429
|
//#region src/sourceControl/SourceControlProviderDiscovery.ts
|
|
109161
109430
|
function firstNonEmptyLine(text) {
|
|
@@ -109359,7 +109628,7 @@ function toChangeRequest$5(summary) {
|
|
|
109359
109628
|
isCrossRepository: false
|
|
109360
109629
|
};
|
|
109361
109630
|
}
|
|
109362
|
-
const make$
|
|
109631
|
+
const make$55 = Effect.gen(function* () {
|
|
109363
109632
|
const azure = yield* AzureDevOpsCli;
|
|
109364
109633
|
return SourceControlProvider.of({
|
|
109365
109634
|
kind: "azure-devops",
|
|
@@ -109452,7 +109721,7 @@ const make$53 = Effect.gen(function* () {
|
|
|
109452
109721
|
})))
|
|
109453
109722
|
});
|
|
109454
109723
|
});
|
|
109455
|
-
Layer.effect(SourceControlProvider, make$
|
|
109724
|
+
Layer.effect(SourceControlProvider, make$55);
|
|
109456
109725
|
//#endregion
|
|
109457
109726
|
//#region src/sourceControl/bitbucketPullRequests.ts
|
|
109458
109727
|
const BitbucketRepositoryRefSchema = Schema$1.Struct({
|
|
@@ -109829,7 +110098,7 @@ function responseError(operation, response) {
|
|
|
109829
110098
|
responseBodyLength: collected.text.length
|
|
109830
110099
|
}))));
|
|
109831
110100
|
}
|
|
109832
|
-
const make$
|
|
110101
|
+
const make$54 = Effect.gen(function* () {
|
|
109833
110102
|
const config = yield* BitbucketApiEnvConfig;
|
|
109834
110103
|
const httpClient = yield* HttpClient.HttpClient;
|
|
109835
110104
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
@@ -110045,7 +110314,7 @@ const make$52 = Effect.gen(function* () {
|
|
|
110045
110314
|
})))
|
|
110046
110315
|
});
|
|
110047
110316
|
});
|
|
110048
|
-
const layer$42 = Layer.effect(BitbucketApi, make$
|
|
110317
|
+
const layer$42 = Layer.effect(BitbucketApi, make$54);
|
|
110049
110318
|
//#endregion
|
|
110050
110319
|
//#region src/sourceControl/BitbucketSourceControlProvider.ts
|
|
110051
110320
|
function toChangeRequest$4(summary) {
|
|
@@ -110063,7 +110332,7 @@ function toChangeRequest$4(summary) {
|
|
|
110063
110332
|
...summary.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: summary.headRepositoryOwnerLogin } : {}
|
|
110064
110333
|
};
|
|
110065
110334
|
}
|
|
110066
|
-
const make$
|
|
110335
|
+
const make$53 = Effect.gen(function* () {
|
|
110067
110336
|
const bitbucket = yield* BitbucketApi;
|
|
110068
110337
|
return SourceControlProvider.of({
|
|
110069
110338
|
kind: "bitbucket",
|
|
@@ -110154,7 +110423,7 @@ const make$51 = Effect.gen(function* () {
|
|
|
110154
110423
|
})))
|
|
110155
110424
|
});
|
|
110156
110425
|
});
|
|
110157
|
-
Layer.effect(SourceControlProvider, make$
|
|
110426
|
+
Layer.effect(SourceControlProvider, make$53);
|
|
110158
110427
|
const makeDiscovery = Effect.gen(function* () {
|
|
110159
110428
|
return {
|
|
110160
110429
|
type: "api",
|
|
@@ -110402,7 +110671,7 @@ function deriveRepositoryCloneUrlsFromCreateOutput(stdout, repository) {
|
|
|
110402
110671
|
sshUrl: `git@${fallbackHost}:${repository}.git`
|
|
110403
110672
|
};
|
|
110404
110673
|
}
|
|
110405
|
-
const make$
|
|
110674
|
+
const make$52 = Effect.gen(function* () {
|
|
110406
110675
|
const process = yield* VcsProcess;
|
|
110407
110676
|
const execute = (input) => process.run({
|
|
110408
110677
|
operation: "GitHubCli.execute",
|
|
@@ -110520,7 +110789,7 @@ const make$50 = Effect.gen(function* () {
|
|
|
110520
110789
|
}).pipe(Effect.asVoid)
|
|
110521
110790
|
});
|
|
110522
110791
|
});
|
|
110523
|
-
const layer$40 = Layer.effect(GitHubCli, make$
|
|
110792
|
+
const layer$40 = Layer.effect(GitHubCli, make$52);
|
|
110524
110793
|
//#endregion
|
|
110525
110794
|
//#region src/sourceControl/gitHubAuthStatus.ts
|
|
110526
110795
|
const GitHubAuthStatusAccountSchema = Schema$1.Struct({
|
|
@@ -110622,7 +110891,7 @@ const discovery$1 = {
|
|
|
110622
110891
|
parseAuth: parseGitHubAuth,
|
|
110623
110892
|
installHint: "Install the GitHub command-line tool (`gh`) via https://cli.github.com/ or your package manager (for example `brew install gh`)."
|
|
110624
110893
|
};
|
|
110625
|
-
const make$
|
|
110894
|
+
const make$51 = Effect.gen(function* () {
|
|
110626
110895
|
const github = yield* GitHubCli;
|
|
110627
110896
|
const listChangeRequests = (input) => {
|
|
110628
110897
|
if (input.state === "open") return github.listOpenPullRequests({
|
|
@@ -110738,7 +111007,7 @@ const make$49 = Effect.gen(function* () {
|
|
|
110738
111007
|
})))
|
|
110739
111008
|
});
|
|
110740
111009
|
});
|
|
110741
|
-
Layer.effect(SourceControlProvider, make$
|
|
111010
|
+
Layer.effect(SourceControlProvider, make$51);
|
|
110742
111011
|
//#endregion
|
|
110743
111012
|
//#region src/sourceControl/gitLabMergeRequests.ts
|
|
110744
111013
|
const GitLabProjectReferenceSchema = Schema$1.Struct({
|
|
@@ -111057,7 +111326,7 @@ function parseRepositoryPath(repository) {
|
|
|
111057
111326
|
projectPath
|
|
111058
111327
|
};
|
|
111059
111328
|
}
|
|
111060
|
-
const make$
|
|
111329
|
+
const make$50 = Effect.gen(function* () {
|
|
111061
111330
|
const process = yield* VcsProcess;
|
|
111062
111331
|
const run = (input, mapError) => process.run({
|
|
111063
111332
|
operation: "GitLabCli.execute",
|
|
@@ -111208,7 +111477,7 @@ const make$48 = Effect.gen(function* () {
|
|
|
111208
111477
|
}).pipe(Effect.asVoid)
|
|
111209
111478
|
});
|
|
111210
111479
|
});
|
|
111211
|
-
const layer$38 = Layer.effect(GitLabCli, make$
|
|
111480
|
+
const layer$38 = Layer.effect(GitLabCli, make$50);
|
|
111212
111481
|
//#endregion
|
|
111213
111482
|
//#region src/sourceControl/gitLabAuthStatus.ts
|
|
111214
111483
|
const HOST_LINE_PATTERN = /^(?:[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?|\[[a-f0-9:.]+\])(?::\d+)?$/iu;
|
|
@@ -111306,7 +111575,7 @@ const discovery = {
|
|
|
111306
111575
|
refineUnknownRemote: refineUnknownGitLabRemote,
|
|
111307
111576
|
installHint: "Install the GitLab command-line tool (`glab`) from https://gitlab.com/gitlab-org/cli or your package manager (for example `brew install glab`)."
|
|
111308
111577
|
};
|
|
111309
|
-
const make$
|
|
111578
|
+
const make$49 = Effect.gen(function* () {
|
|
111310
111579
|
const gitlab = yield* GitLabCli;
|
|
111311
111580
|
return SourceControlProvider.of({
|
|
111312
111581
|
kind: "gitlab",
|
|
@@ -111395,7 +111664,7 @@ const make$47 = Effect.gen(function* () {
|
|
|
111395
111664
|
})))
|
|
111396
111665
|
});
|
|
111397
111666
|
});
|
|
111398
|
-
Layer.effect(SourceControlProvider, make$
|
|
111667
|
+
Layer.effect(SourceControlProvider, make$49);
|
|
111399
111668
|
//#endregion
|
|
111400
111669
|
//#region src/sourceControl/SourceControlProviderRegistry.ts
|
|
111401
111670
|
const PROVIDER_DETECTION_CACHE_CAPACITY = 2048;
|
|
@@ -111551,12 +111820,12 @@ const makeWithProviders = Effect.fn("makeSourceControlProviderRegistryWithProvid
|
|
|
111551
111820
|
})), { concurrency: "unbounded" })
|
|
111552
111821
|
});
|
|
111553
111822
|
});
|
|
111554
|
-
const make$
|
|
111555
|
-
const github = yield* make$
|
|
111556
|
-
const gitlab = yield* make$
|
|
111557
|
-
const bitbucket = yield* make$
|
|
111823
|
+
const make$48 = Effect.gen(function* () {
|
|
111824
|
+
const github = yield* make$51;
|
|
111825
|
+
const gitlab = yield* make$49;
|
|
111826
|
+
const bitbucket = yield* make$53;
|
|
111558
111827
|
const bitbucketDiscovery = yield* makeDiscovery;
|
|
111559
|
-
const azureDevOps = yield* make$
|
|
111828
|
+
const azureDevOps = yield* make$55;
|
|
111560
111829
|
return yield* makeWithProviders([
|
|
111561
111830
|
{
|
|
111562
111831
|
kind: "github",
|
|
@@ -111580,7 +111849,7 @@ const make$46 = Effect.gen(function* () {
|
|
|
111580
111849
|
}
|
|
111581
111850
|
]);
|
|
111582
111851
|
});
|
|
111583
|
-
const layer$36 = Layer.effect(SourceControlProviderRegistry, make$
|
|
111852
|
+
const layer$36 = Layer.effect(SourceControlProviderRegistry, make$48);
|
|
111584
111853
|
//#endregion
|
|
111585
111854
|
//#region src/sourceControl/PrTemplateDetection.ts
|
|
111586
111855
|
const TEMPLATE_MAX_BYTES = 8e3;
|
|
@@ -111951,7 +112220,7 @@ function toPullRequestHeadRemoteInfo(pr) {
|
|
|
111951
112220
|
...pr.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: pr.headRepositoryOwnerLogin } : {}
|
|
111952
112221
|
};
|
|
111953
112222
|
}
|
|
111954
|
-
const make$
|
|
112223
|
+
const make$47 = Effect.gen(function* () {
|
|
111955
112224
|
const gitCore = yield* GitVcsDriver;
|
|
111956
112225
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
111957
112226
|
const textGeneration = yield* TextGeneration;
|
|
@@ -112925,7 +113194,7 @@ const make$45 = Effect.gen(function* () {
|
|
|
112925
113194
|
runStackedAction
|
|
112926
113195
|
});
|
|
112927
113196
|
});
|
|
112928
|
-
const layer$35 = Layer.effect(GitManager, make$
|
|
113197
|
+
const layer$35 = Layer.effect(GitManager, make$47);
|
|
112929
113198
|
//#endregion
|
|
112930
113199
|
//#region src/git/GitWorkflowService.ts
|
|
112931
113200
|
var GitWorkflowService = class extends Context.Service()("@p4code/cli/git/GitWorkflowService") {};
|
|
@@ -112962,7 +113231,7 @@ function nonRepositoryListRefs() {
|
|
|
112962
113231
|
totalCount: 0
|
|
112963
113232
|
};
|
|
112964
113233
|
}
|
|
112965
|
-
const make$
|
|
113234
|
+
const make$46 = Effect.gen(function* () {
|
|
112966
113235
|
const registry = yield* VcsDriverRegistry;
|
|
112967
113236
|
const git = yield* GitVcsDriver;
|
|
112968
113237
|
const gitManager = yield* GitManager;
|
|
@@ -113048,7 +113317,7 @@ const make$44 = Effect.gen(function* () {
|
|
|
113048
113317
|
renameBranch: (input) => ensureGit("GitWorkflowService.renameBranch", input.cwd).pipe(Effect.andThen(git.renameBranch(input)))
|
|
113049
113318
|
});
|
|
113050
113319
|
});
|
|
113051
|
-
const layer$34 = Layer.effect(GitWorkflowService, make$
|
|
113320
|
+
const layer$34 = Layer.effect(GitWorkflowService, make$46);
|
|
113052
113321
|
//#endregion
|
|
113053
113322
|
//#region src/pullRequest/PullRequestProvider.ts
|
|
113054
113323
|
/**
|
|
@@ -113409,7 +113678,7 @@ function isReviewerName(value) {
|
|
|
113409
113678
|
const name = value.trim();
|
|
113410
113679
|
return name.length > 0 && !name.startsWith("-");
|
|
113411
113680
|
}
|
|
113412
|
-
const make$
|
|
113681
|
+
const make$45 = Effect.gen(function* () {
|
|
113413
113682
|
const azure = yield* AzureDevOpsCli;
|
|
113414
113683
|
const detectArgs = ["--detect", "true"];
|
|
113415
113684
|
const executeJson = (input) => azure.execute({
|
|
@@ -113609,7 +113878,7 @@ const make$43 = Effect.gen(function* () {
|
|
|
113609
113878
|
}).pipe(Effect.asVoid)
|
|
113610
113879
|
});
|
|
113611
113880
|
});
|
|
113612
|
-
const layer$33 = Layer.effect(AzureDevOpsPullRequestCli, make$
|
|
113881
|
+
const layer$33 = Layer.effect(AzureDevOpsPullRequestCli, make$45);
|
|
113613
113882
|
//#endregion
|
|
113614
113883
|
//#region src/pullRequest/AzureDevOpsPullRequestProvider.ts
|
|
113615
113884
|
const CAPABILITIES$3 = {
|
|
@@ -113684,7 +113953,7 @@ function toChangeRequest$1(pullRequest) {
|
|
|
113684
113953
|
labels: []
|
|
113685
113954
|
};
|
|
113686
113955
|
}
|
|
113687
|
-
const make$
|
|
113956
|
+
const make$44 = Effect.gen(function* () {
|
|
113688
113957
|
const cli = yield* AzureDevOpsPullRequestCli;
|
|
113689
113958
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
113690
113959
|
provider: "azure-devops",
|
|
@@ -114424,7 +114693,7 @@ function mergeStrategy(method) {
|
|
|
114424
114693
|
default: return "merge_commit";
|
|
114425
114694
|
}
|
|
114426
114695
|
}
|
|
114427
|
-
const make$
|
|
114696
|
+
const make$43 = Effect.gen(function* () {
|
|
114428
114697
|
const bitbucket = yield* BitbucketApi;
|
|
114429
114698
|
/**
|
|
114430
114699
|
* The repository's own path, and the workspace above it — which the people who may review are
|
|
@@ -114704,7 +114973,7 @@ const make$41 = Effect.gen(function* () {
|
|
|
114704
114973
|
}).pipe(Effect.asVoid))
|
|
114705
114974
|
});
|
|
114706
114975
|
});
|
|
114707
|
-
const layer$32 = Layer.effect(BitbucketPullRequestApi, make$
|
|
114976
|
+
const layer$32 = Layer.effect(BitbucketPullRequestApi, make$43);
|
|
114708
114977
|
//#endregion
|
|
114709
114978
|
//#region src/pullRequest/BitbucketPullRequestProvider.ts
|
|
114710
114979
|
const CAPABILITIES$2 = {
|
|
@@ -114784,7 +115053,7 @@ function toChangeRequest(pullRequest) {
|
|
|
114784
115053
|
labels: []
|
|
114785
115054
|
};
|
|
114786
115055
|
}
|
|
114787
|
-
const make$
|
|
115056
|
+
const make$42 = Effect.gen(function* () {
|
|
114788
115057
|
const api = yield* BitbucketPullRequestApi;
|
|
114789
115058
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
114790
115059
|
provider: "bitbucket",
|
|
@@ -117013,7 +117282,7 @@ function actionArgs$1(action, mergeMethod, updateMethod) {
|
|
|
117013
117282
|
case "reopen": return ["reopen"];
|
|
117014
117283
|
}
|
|
117015
117284
|
}
|
|
117016
|
-
const make$
|
|
117285
|
+
const make$41 = Effect.gen(function* () {
|
|
117017
117286
|
const github = yield* GitHubCli;
|
|
117018
117287
|
/**
|
|
117019
117288
|
* The pull request's own node id, which is what a mutation against the pull request itself is
|
|
@@ -117776,7 +118045,7 @@ const make$39 = Effect.gen(function* () {
|
|
|
117776
118045
|
})))
|
|
117777
118046
|
});
|
|
117778
118047
|
});
|
|
117779
|
-
const layer$31 = Layer.effect(GitHubPullRequestCli, make$
|
|
118048
|
+
const layer$31 = Layer.effect(GitHubPullRequestCli, make$41);
|
|
117780
118049
|
//#endregion
|
|
117781
118050
|
//#region src/pullRequest/GitHubPullRequestProvider.ts
|
|
117782
118051
|
const CAPABILITIES$1 = {
|
|
@@ -117893,7 +118162,7 @@ function loginAvatarUrl(login, host) {
|
|
|
117893
118162
|
}
|
|
117894
118163
|
/** True where markdown would render nothing: whitespace, or only HTML comments. */
|
|
117895
118164
|
const rendersEmpty = (body) => body.replace(/<!--[\s\S]*?-->/g, "").trim().length === 0;
|
|
117896
|
-
const make$
|
|
118165
|
+
const make$40 = Effect.gen(function* () {
|
|
117897
118166
|
const cli = yield* GitHubPullRequestCli;
|
|
117898
118167
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
117899
118168
|
provider: "github",
|
|
@@ -118915,7 +119184,7 @@ function actionArgs(action, mergeMethod) {
|
|
|
118915
119184
|
case "reopen": return ["reopen"];
|
|
118916
119185
|
}
|
|
118917
119186
|
}
|
|
118918
|
-
const make$
|
|
119187
|
+
const make$39 = Effect.gen(function* () {
|
|
118919
119188
|
const gitlab = yield* GitLabCli;
|
|
118920
119189
|
const api = (input) => gitlab.execute({
|
|
118921
119190
|
cwd: input.cwd,
|
|
@@ -119486,7 +119755,7 @@ const make$37 = Effect.gen(function* () {
|
|
|
119486
119755
|
}).pipe(Effect.asVoid)
|
|
119487
119756
|
});
|
|
119488
119757
|
});
|
|
119489
|
-
const layer$30 = Layer.effect(GitLabPullRequestCli, make$
|
|
119758
|
+
const layer$30 = Layer.effect(GitLabPullRequestCli, make$39);
|
|
119490
119759
|
//#endregion
|
|
119491
119760
|
//#region src/pullRequest/GitLabPullRequestProvider.ts
|
|
119492
119761
|
const CAPABILITIES = {
|
|
@@ -119566,7 +119835,7 @@ function reasonFor(error) {
|
|
|
119566
119835
|
if (error._tag === "GitLabCliAuthenticationError") return "unauthenticated";
|
|
119567
119836
|
return "failed";
|
|
119568
119837
|
}
|
|
119569
|
-
const make$
|
|
119838
|
+
const make$38 = Effect.gen(function* () {
|
|
119570
119839
|
const cli = yield* GitLabPullRequestCli;
|
|
119571
119840
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
119572
119841
|
provider: "gitlab",
|
|
@@ -119709,13 +119978,13 @@ function fromProviders(providers) {
|
|
|
119709
119978
|
* The hosts this build can read change requests from. A host with no entry here still shows up
|
|
119710
119979
|
* in the provider list as unimplemented, so its projects are explained rather than missing.
|
|
119711
119980
|
*/
|
|
119712
|
-
const make$
|
|
119713
|
-
make$38,
|
|
119714
|
-
make$36,
|
|
119981
|
+
const make$37 = Effect.map(Effect.all([
|
|
119715
119982
|
make$40,
|
|
119716
|
-
make$
|
|
119983
|
+
make$38,
|
|
119984
|
+
make$42,
|
|
119985
|
+
make$44
|
|
119717
119986
|
]), fromProviders);
|
|
119718
|
-
const layer$29 = Layer.effect(PullRequestProviderRegistry, make$
|
|
119987
|
+
const layer$29 = Layer.effect(PullRequestProviderRegistry, make$37).pipe(Layer.provide(layer$31.pipe(Layer.provide(layer$40))), Layer.provide(layer$30.pipe(Layer.provide(layer$38))), Layer.provide(layer$32.pipe(Layer.provide(layer$42))), Layer.provide(layer$33.pipe(Layer.provide(layer$44))));
|
|
119719
119988
|
//#endregion
|
|
119720
119989
|
//#region src/pullRequest/PullRequestService.ts
|
|
119721
119990
|
/**
|
|
@@ -119903,7 +120172,7 @@ function repositoryIdentityOf(project) {
|
|
|
119903
120172
|
if (identity.displayName) return identity.displayName;
|
|
119904
120173
|
return identity.owner && identity.name ? `${identity.owner}/${identity.name}` : null;
|
|
119905
120174
|
}
|
|
119906
|
-
const make$
|
|
120175
|
+
const make$36 = Effect.gen(function* () {
|
|
119907
120176
|
const registry = yield* PullRequestProviderRegistry;
|
|
119908
120177
|
const projections = yield* ProjectionSnapshotQuery;
|
|
119909
120178
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
@@ -120901,7 +121170,7 @@ const make$34 = Effect.gen(function* () {
|
|
|
120901
121170
|
invalidate
|
|
120902
121171
|
});
|
|
120903
121172
|
});
|
|
120904
|
-
const layer$28 = Layer.effect(PullRequestService, make$
|
|
121173
|
+
const layer$28 = Layer.effect(PullRequestService, make$36);
|
|
120905
121174
|
//#endregion
|
|
120906
121175
|
//#region src/orchestration/ThreadWorkspaceLifecycle.ts
|
|
120907
121176
|
var ThreadWorkspaceLifecycleError = class extends Data.TaggedError("ThreadWorkspaceLifecycleError") {};
|
|
@@ -120945,7 +121214,7 @@ const mapLifecycleError = Effect.mapError((cause) => cause instanceof ThreadWork
|
|
|
120945
121214
|
detail: "Thread workspace lifecycle operation failed.",
|
|
120946
121215
|
cause
|
|
120947
121216
|
}));
|
|
120948
|
-
const make$
|
|
121217
|
+
const make$35 = Effect.gen(function* () {
|
|
120949
121218
|
const snapshots = yield* ProjectionSnapshotQuery;
|
|
120950
121219
|
const engine = yield* OrchestrationEngineService;
|
|
120951
121220
|
const gitWorkflow = yield* GitWorkflowService;
|
|
@@ -121199,7 +121468,7 @@ const make$33 = Effect.gen(function* () {
|
|
|
121199
121468
|
record
|
|
121200
121469
|
};
|
|
121201
121470
|
});
|
|
121202
|
-
const layer$27 = Layer.effect(ThreadWorkspaceLifecycleService, make$
|
|
121471
|
+
const layer$27 = Layer.effect(ThreadWorkspaceLifecycleService, make$35);
|
|
121203
121472
|
//#endregion
|
|
121204
121473
|
//#region src/textGeneration/BtwRequestCoordinator.ts
|
|
121205
121474
|
const MAX_PENDING_BTW_CANCELLATIONS = 256;
|
|
@@ -123472,7 +123741,7 @@ function makeUpdateState(input) {
|
|
|
123472
123741
|
output: input.output ?? null
|
|
123473
123742
|
};
|
|
123474
123743
|
}
|
|
123475
|
-
const make$
|
|
123744
|
+
const make$34 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
123476
123745
|
const providerRegistry = yield* ProviderRegistry;
|
|
123477
123746
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
123478
123747
|
const httpClient = yield* HttpClient.HttpClient;
|
|
@@ -123587,7 +123856,7 @@ const make$32 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
|
123587
123856
|
});
|
|
123588
123857
|
return ProviderMaintenanceRunner.of({ updateProvider });
|
|
123589
123858
|
});
|
|
123590
|
-
const layer$26 = Layer.effect(ProviderMaintenanceRunner, make$
|
|
123859
|
+
const layer$26 = Layer.effect(ProviderMaintenanceRunner, make$34());
|
|
123591
123860
|
//#endregion
|
|
123592
123861
|
//#region src/usage/usageTranscripts.ts
|
|
123593
123862
|
const EMPTY_TOTALS = {
|
|
@@ -124413,7 +124682,7 @@ Layer.succeed(UsageService, UsageService.of({
|
|
|
124413
124682
|
scanDurationMs: 0
|
|
124414
124683
|
})
|
|
124415
124684
|
}));
|
|
124416
|
-
const make$
|
|
124685
|
+
const make$33 = Effect.gen(function* () {
|
|
124417
124686
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
124418
124687
|
const path = yield* Path$1.Path;
|
|
124419
124688
|
const config = yield* ServerConfig$1;
|
|
@@ -124696,7 +124965,7 @@ const make$31 = Effect.gen(function* () {
|
|
|
124696
124965
|
readSessionRecords: (input) => scanLock.withPermits(1)(readSessionRecords(input))
|
|
124697
124966
|
};
|
|
124698
124967
|
});
|
|
124699
|
-
const layer$25 = Layer.effect(UsageService, make$
|
|
124968
|
+
const layer$25 = Layer.effect(UsageService, make$33);
|
|
124700
124969
|
//#endregion
|
|
124701
124970
|
//#region src/feed/FeedStore.ts
|
|
124702
124971
|
const storageFailure = (message) => new FeedError({
|
|
@@ -125060,7 +125329,7 @@ const jsonRequest = Effect.fn("FeedService.jsonRequest")(function* (url, token,
|
|
|
125060
125329
|
catch: () => fail("hub_unavailable", "Hub returned invalid JSON.")
|
|
125061
125330
|
});
|
|
125062
125331
|
});
|
|
125063
|
-
const make$
|
|
125332
|
+
const make$32 = Effect.gen(function* () {
|
|
125064
125333
|
const hubLink = yield* HubLink;
|
|
125065
125334
|
const providers = yield* ProviderInstanceRegistry;
|
|
125066
125335
|
const config = yield* ServerConfig$1;
|
|
@@ -125298,7 +125567,7 @@ var FeedService = class extends Context.Reference("@p4code/cli/feed/FeedService"
|
|
|
125298
125567
|
markRead: unavailable,
|
|
125299
125568
|
cleanup: unavailable
|
|
125300
125569
|
}) }) {};
|
|
125301
|
-
const layer$24 = Layer.effect(FeedService, make$
|
|
125570
|
+
const layer$24 = Layer.effect(FeedService, make$32);
|
|
125302
125571
|
//#endregion
|
|
125303
125572
|
//#region src/storageCleanup.ts
|
|
125304
125573
|
const DAY_MS$1 = 864e5;
|
|
@@ -125315,7 +125584,7 @@ function isExpired(modifiedAtMs, days, nowMs) {
|
|
|
125315
125584
|
return modifiedAtMs < nowMs - days * DAY_MS$1;
|
|
125316
125585
|
}
|
|
125317
125586
|
var StorageCleanup = class extends Context.Service()("@p4code/cli/storageCleanup") {};
|
|
125318
|
-
const make$
|
|
125587
|
+
const make$31 = Effect.gen(function* () {
|
|
125319
125588
|
const fs = yield* FileSystem.FileSystem;
|
|
125320
125589
|
const path = yield* Path$1.Path;
|
|
125321
125590
|
const config = yield* ServerConfig$1;
|
|
@@ -125404,7 +125673,7 @@ const make$29 = Effect.gen(function* () {
|
|
|
125404
125673
|
})
|
|
125405
125674
|
};
|
|
125406
125675
|
});
|
|
125407
|
-
const layer$23 = Layer.effect(StorageCleanup, make$
|
|
125676
|
+
const layer$23 = Layer.effect(StorageCleanup, make$31);
|
|
125408
125677
|
//#endregion
|
|
125409
125678
|
//#region src/worktreeCleanupRules.ts
|
|
125410
125679
|
/**
|
|
@@ -125504,7 +125773,7 @@ function planWorktreeCleanup(facts, settings, nowMs) {
|
|
|
125504
125773
|
* @module worktreeCleanup
|
|
125505
125774
|
*/
|
|
125506
125775
|
var WorktreeCleanup = class extends Context.Service()("@p4code/cli/worktreeCleanup") {};
|
|
125507
|
-
const make$
|
|
125776
|
+
const make$30 = Effect.gen(function* () {
|
|
125508
125777
|
const threads = yield* ProjectionThreadRepository;
|
|
125509
125778
|
const projects = yield* ProjectionProjectRepository;
|
|
125510
125779
|
const sessions = yield* ProviderSessionDirectory;
|
|
@@ -125599,7 +125868,7 @@ const make$28 = Effect.gen(function* () {
|
|
|
125599
125868
|
})
|
|
125600
125869
|
};
|
|
125601
125870
|
});
|
|
125602
|
-
const layer$22 = Layer.effect(WorktreeCleanup, make$
|
|
125871
|
+
const layer$22 = Layer.effect(WorktreeCleanup, make$30);
|
|
125603
125872
|
const SKILL_MANIFEST_FILENAME = "SKILL.md";
|
|
125604
125873
|
/**
|
|
125605
125874
|
* Split a catalogue id (`owner/repo/skill-name`) into its parts.
|
|
@@ -125745,7 +126014,7 @@ const emptyFetch = (id, unavailable) => ({
|
|
|
125745
126014
|
skipped: [],
|
|
125746
126015
|
unavailable
|
|
125747
126016
|
});
|
|
125748
|
-
const make$
|
|
126017
|
+
const make$29 = Effect.gen(function* () {
|
|
125749
126018
|
const http = yield* HttpClient.HttpClient;
|
|
125750
126019
|
const request = Effect.fn("SkillRegistry.request")(function* (url) {
|
|
125751
126020
|
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));
|
|
@@ -125816,7 +126085,7 @@ const make$27 = Effect.gen(function* () {
|
|
|
125816
126085
|
fetch
|
|
125817
126086
|
};
|
|
125818
126087
|
});
|
|
125819
|
-
const layer$21 = Layer.effect(SkillRegistry, make$
|
|
126088
|
+
const layer$21 = Layer.effect(SkillRegistry, make$29);
|
|
125820
126089
|
//#endregion
|
|
125821
126090
|
//#region src/orchestration/SupervisorSecrets.ts
|
|
125822
126091
|
/**
|
|
@@ -125892,6 +126161,9 @@ const makeSupervisorSecrets = Effect.gen(function* () {
|
|
|
125892
126161
|
});
|
|
125893
126162
|
const SupervisorSecretsLive = Layer.effect(SupervisorSecrets, makeSupervisorSecrets);
|
|
125894
126163
|
//#endregion
|
|
126164
|
+
//#region src/orchestration/Services/JevWorkspaceAdvisor.ts
|
|
126165
|
+
var JevWorkspaceAdvisor = class extends Context.Service()("@p4code/cli/orchestration/Services/JevWorkspaceAdvisor") {};
|
|
126166
|
+
//#endregion
|
|
125895
126167
|
//#region src/mcp/PreviewAutomationBroker.ts
|
|
125896
126168
|
var PreviewAutomationBroker = class extends Context.Service()("@p4code/cli/mcp/PreviewAutomationBroker") {};
|
|
125897
126169
|
const removeConnectionFromState = (current, clientId, queue) => {
|
|
@@ -126008,7 +126280,7 @@ const classifyResponseError = (context, error) => {
|
|
|
126008
126280
|
});
|
|
126009
126281
|
}
|
|
126010
126282
|
};
|
|
126011
|
-
const make$
|
|
126283
|
+
const make$28 = Effect.gen(function* PreviewAutomationBrokerMake() {
|
|
126012
126284
|
const crypto = yield* Crypto.Crypto;
|
|
126013
126285
|
const state = yield* SynchronizedRef.make({
|
|
126014
126286
|
clients: /* @__PURE__ */ new Map(),
|
|
@@ -126242,7 +126514,7 @@ const make$26 = Effect.gen(function* PreviewAutomationBrokerMake() {
|
|
|
126242
126514
|
invoke
|
|
126243
126515
|
});
|
|
126244
126516
|
}).pipe(Effect.withSpan("PreviewAutomationBroker.make"));
|
|
126245
|
-
const layer$20 = Layer.effect(PreviewAutomationBroker, make$
|
|
126517
|
+
const layer$20 = Layer.effect(PreviewAutomationBroker, make$28);
|
|
126246
126518
|
//#endregion
|
|
126247
126519
|
//#region src/preview/Manager.ts
|
|
126248
126520
|
/**
|
|
@@ -126306,7 +126578,7 @@ const buildIdleSnapshot = (input) => ({
|
|
|
126306
126578
|
viewport: FILL_PREVIEW_VIEWPORT,
|
|
126307
126579
|
updatedAt: input.updatedAt
|
|
126308
126580
|
});
|
|
126309
|
-
const make$
|
|
126581
|
+
const make$27 = Effect.gen(function* PreviewManagerMake() {
|
|
126310
126582
|
const serverEpoch = NodeCrypto.randomUUID();
|
|
126311
126583
|
const stateRef = yield* SynchronizedRef.make(initialState);
|
|
126312
126584
|
const eventsPubSub = yield* PubSub.unbounded();
|
|
@@ -126537,7 +126809,7 @@ const make$25 = Effect.gen(function* PreviewManagerMake() {
|
|
|
126537
126809
|
subscribeEvents: PubSub.subscribe(eventsPubSub)
|
|
126538
126810
|
});
|
|
126539
126811
|
}).pipe(Effect.withSpan("PreviewManager.make"));
|
|
126540
|
-
const layer$19 = Layer.effect(PreviewManager, make$
|
|
126812
|
+
const layer$19 = Layer.effect(PreviewManager, make$27);
|
|
126541
126813
|
//#endregion
|
|
126542
126814
|
//#region src/workspace/WorkspaceSearchIndex.ts
|
|
126543
126815
|
const WORKSPACE_INDEX_MAX_ENTRIES = 25e3;
|
|
@@ -126674,7 +126946,7 @@ const waitForScan = (cwd, finder, onFailure) => Effect.try({
|
|
|
126674
126946
|
timeout: WORKSPACE_INDEX_SCAN_TIMEOUT
|
|
126675
126947
|
})
|
|
126676
126948
|
}), Effect.withSpan("WorkspaceSearchIndex.waitForScan"));
|
|
126677
|
-
const make$
|
|
126949
|
+
const make$26 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd, contentSearch = false) {
|
|
126678
126950
|
const finder = yield* Effect.acquireRelease(createFinder(cwd, contentSearch), (finder) => Effect.try({
|
|
126679
126951
|
try: () => finder.destroy(),
|
|
126680
126952
|
catch: (cause) => new WorkspaceSearchIndexDestroyFailed({
|
|
@@ -126814,14 +127086,14 @@ const make$24 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd, contentSe
|
|
|
126814
127086
|
* workspace root. WorkspaceSearchIndexMap owns memoization and idle cleanup;
|
|
126815
127087
|
* using a default cwd here would mix resources from different workspaces.
|
|
126816
127088
|
*/
|
|
126817
|
-
const layer$18 = (cwd) => Layer.effect(WorkspaceSearchIndex, make$
|
|
127089
|
+
const layer$18 = (cwd) => Layer.effect(WorkspaceSearchIndex, make$26(cwd));
|
|
126818
127090
|
var WorkspaceSearchIndexMap = class extends LayerMap.Service()("@p4code/cli/workspace/WorkspaceSearchIndexMap", {
|
|
126819
127091
|
lookup: layer$18,
|
|
126820
127092
|
idleTimeToLive: WORKSPACE_INDEX_IDLE_TTL
|
|
126821
127093
|
}) {};
|
|
126822
127094
|
/** Content indexing is allocated only when workspace content search is used. */
|
|
126823
127095
|
var WorkspaceContentSearchIndexMap = class extends LayerMap.Service()("@p4code/cli/workspace/WorkspaceContentSearchIndexMap", {
|
|
126824
|
-
lookup: (cwd) => Layer.effect(WorkspaceSearchIndex, make$
|
|
127096
|
+
lookup: (cwd) => Layer.effect(WorkspaceSearchIndex, make$26(cwd, true)),
|
|
126825
127097
|
idleTimeToLive: WORKSPACE_INDEX_IDLE_TTL
|
|
126826
127098
|
}) {};
|
|
126827
127099
|
//#endregion
|
|
@@ -126883,7 +127155,7 @@ const resolveBrowseTarget = Effect.fn("WorkspaceEntries.resolveBrowseTarget")(fu
|
|
|
126883
127155
|
if (!input.cwd) return yield* new WorkspaceEntriesCurrentProjectRequiredError({ partialPath: input.partialPath });
|
|
126884
127156
|
return path.resolve(expandHomePath$1(input.cwd, path), input.partialPath);
|
|
126885
127157
|
});
|
|
126886
|
-
const make$
|
|
127158
|
+
const make$25 = Effect.gen(function* () {
|
|
126887
127159
|
const path = yield* Path$1.Path;
|
|
126888
127160
|
const workspacePaths = yield* WorkspacePaths;
|
|
126889
127161
|
const contentSearchIndexes = yield* WorkspaceContentSearchIndexMap;
|
|
@@ -126965,7 +127237,7 @@ const make$23 = Effect.gen(function* () {
|
|
|
126965
127237
|
searchContents
|
|
126966
127238
|
});
|
|
126967
127239
|
});
|
|
126968
|
-
const layer$17 = Layer.effect(WorkspaceEntries, make$
|
|
127240
|
+
const layer$17 = Layer.effect(WorkspaceEntries, make$25).pipe(Layer.provide(WorkspaceSearchIndexMap.layer), Layer.provide(WorkspaceContentSearchIndexMap.layer));
|
|
126969
127241
|
//#endregion
|
|
126970
127242
|
//#region src/workspace/WorkspaceFileSystem.ts
|
|
126971
127243
|
/**
|
|
@@ -127024,7 +127296,7 @@ Schema$1.Union([
|
|
|
127024
127296
|
]);
|
|
127025
127297
|
/** Service tag for workspace file operations. */
|
|
127026
127298
|
var WorkspaceFileSystem = class extends Context.Service()("@p4code/cli/workspace/WorkspaceFileSystem") {};
|
|
127027
|
-
const make$
|
|
127299
|
+
const make$24 = Effect.gen(function* () {
|
|
127028
127300
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
127029
127301
|
const path = yield* Path$1.Path;
|
|
127030
127302
|
const workspacePaths = yield* WorkspacePaths;
|
|
@@ -127168,7 +127440,7 @@ const make$22 = Effect.gen(function* () {
|
|
|
127168
127440
|
writeFile
|
|
127169
127441
|
});
|
|
127170
127442
|
});
|
|
127171
|
-
const layer$16 = Layer.effect(WorkspaceFileSystem, make$
|
|
127443
|
+
const layer$16 = Layer.effect(WorkspaceFileSystem, make$24);
|
|
127172
127444
|
//#endregion
|
|
127173
127445
|
//#region src/vcs/VcsStatusBroadcaster.ts
|
|
127174
127446
|
const DEFAULT_VCS_STATUS_REFRESH_INTERVAL = Duration.seconds(30);
|
|
@@ -127250,7 +127522,7 @@ const autoPullPolicyLayer = Layer.effect(VcsAutoPullPolicy, Effect.gen(function*
|
|
|
127250
127522
|
return resolveProjectAutoPull(yield* settingsService.getSettings, project.value.id);
|
|
127251
127523
|
}, Effect.orElseSucceed(() => false)) };
|
|
127252
127524
|
}));
|
|
127253
|
-
const make$
|
|
127525
|
+
const make$23 = Effect.gen(function* () {
|
|
127254
127526
|
const autoPullPolicy = yield* VcsAutoPullPolicy;
|
|
127255
127527
|
const workflow = yield* GitWorkflowService;
|
|
127256
127528
|
const fs = yield* FileSystem.FileSystem;
|
|
@@ -127509,7 +127781,7 @@ const make$21 = Effect.gen(function* () {
|
|
|
127509
127781
|
streamStatus
|
|
127510
127782
|
});
|
|
127511
127783
|
});
|
|
127512
|
-
const layer$15 = Layer.effect(VcsStatusBroadcaster, make$
|
|
127784
|
+
const layer$15 = Layer.effect(VcsStatusBroadcaster, make$23);
|
|
127513
127785
|
//#endregion
|
|
127514
127786
|
//#region src/vcs/VcsProvisioningService.ts
|
|
127515
127787
|
var VcsProvisioningService = class extends Context.Service()("@p4code/cli/vcs/VcsProvisioningService") {};
|
|
@@ -127522,7 +127794,7 @@ function resolveRequestedKind(kind) {
|
|
|
127522
127794
|
}));
|
|
127523
127795
|
return Effect.succeed(kind);
|
|
127524
127796
|
}
|
|
127525
|
-
const make$
|
|
127797
|
+
const make$22 = Effect.gen(function* () {
|
|
127526
127798
|
const registry = yield* VcsDriverRegistry;
|
|
127527
127799
|
const initRepository = Effect.fn("VcsProvisioningService.initRepository")(function* (input) {
|
|
127528
127800
|
const kind = yield* resolveRequestedKind(input.kind);
|
|
@@ -127530,11 +127802,11 @@ const make$20 = Effect.gen(function* () {
|
|
|
127530
127802
|
});
|
|
127531
127803
|
return VcsProvisioningService.of({ initRepository });
|
|
127532
127804
|
});
|
|
127533
|
-
const layer$14 = Layer.effect(VcsProvisioningService, make$
|
|
127805
|
+
const layer$14 = Layer.effect(VcsProvisioningService, make$22);
|
|
127534
127806
|
//#endregion
|
|
127535
127807
|
//#region src/review/ReviewService.ts
|
|
127536
127808
|
var ReviewService = class extends Context.Service()("@p4code/cli/review/ReviewService") {};
|
|
127537
|
-
const make$
|
|
127809
|
+
const make$21 = Effect.gen(function* () {
|
|
127538
127810
|
const config = yield* ServerConfig$1;
|
|
127539
127811
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
127540
127812
|
const path = yield* Path$1.Path;
|
|
@@ -127590,7 +127862,7 @@ const make$19 = Effect.gen(function* () {
|
|
|
127590
127862
|
});
|
|
127591
127863
|
return ReviewService.of({ getDiffPreview });
|
|
127592
127864
|
});
|
|
127593
|
-
const layer$13 = Layer.effect(ReviewService, make$
|
|
127865
|
+
const layer$13 = Layer.effect(ReviewService, make$21);
|
|
127594
127866
|
//#endregion
|
|
127595
127867
|
//#region src/diagnostics/ProcessDiagnostics.ts
|
|
127596
127868
|
const PROCESS_QUERY_TIMEOUT_MS = 1e3;
|
|
@@ -127885,7 +128157,7 @@ function assertDescendantPid(pid) {
|
|
|
127885
128157
|
}));
|
|
127886
128158
|
}));
|
|
127887
128159
|
}
|
|
127888
|
-
const make$
|
|
128160
|
+
const make$20 = Effect.gen(function* () {
|
|
127889
128161
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
127890
128162
|
const read = Effect.gen(function* () {
|
|
127891
128163
|
const readAt = yield* DateTime.now;
|
|
@@ -127929,7 +128201,7 @@ const make$18 = Effect.gen(function* () {
|
|
|
127929
128201
|
signal
|
|
127930
128202
|
});
|
|
127931
128203
|
});
|
|
127932
|
-
const layer$12 = Layer.effect(ProcessDiagnostics, make$
|
|
128204
|
+
const layer$12 = Layer.effect(ProcessDiagnostics, make$20);
|
|
127933
128205
|
//#endregion
|
|
127934
128206
|
//#region src/diagnostics/ProcessResourceMonitor.ts
|
|
127935
128207
|
const SAMPLE_INTERVAL_MS = 5e3;
|
|
@@ -128080,7 +128352,7 @@ function aggregateProcessResourceHistory(input) {
|
|
|
128080
128352
|
}) : Option.none()
|
|
128081
128353
|
};
|
|
128082
128354
|
}
|
|
128083
|
-
const make$
|
|
128355
|
+
const make$19 = Effect.gen(function* () {
|
|
128084
128356
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
128085
128357
|
const state = yield* Ref.make({
|
|
128086
128358
|
samples: [],
|
|
@@ -128129,7 +128401,7 @@ const make$17 = Effect.gen(function* () {
|
|
|
128129
128401
|
});
|
|
128130
128402
|
return ProcessResourceMonitor.of({ readHistory });
|
|
128131
128403
|
});
|
|
128132
|
-
const layer$11 = Layer.effect(ProcessResourceMonitor, make$
|
|
128404
|
+
const layer$11 = Layer.effect(ProcessResourceMonitor, make$19);
|
|
128133
128405
|
//#endregion
|
|
128134
128406
|
//#region src/diagnostics/TraceDiagnostics.ts
|
|
128135
128407
|
var TraceFileReadError = class extends Schema$1.TaggedErrorClass()("TraceFileReadError", {
|
|
@@ -128377,7 +128649,7 @@ function readTraceFile(fileSystem, path) {
|
|
|
128377
128649
|
cause
|
|
128378
128650
|
})) }));
|
|
128379
128651
|
}
|
|
128380
|
-
const make$
|
|
128652
|
+
const make$18 = Effect.gen(function* () {
|
|
128381
128653
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
128382
128654
|
const read = Effect.fn("TraceDiagnostics.read")(function* (options) {
|
|
128383
128655
|
const readAt = options.readAt ?? (yield* DateTime.now);
|
|
@@ -128421,7 +128693,7 @@ const make$16 = Effect.gen(function* () {
|
|
|
128421
128693
|
});
|
|
128422
128694
|
return TraceDiagnostics.of({ read });
|
|
128423
128695
|
});
|
|
128424
|
-
const layer$10 = Layer.effect(TraceDiagnostics, make$
|
|
128696
|
+
const layer$10 = Layer.effect(TraceDiagnostics, make$18);
|
|
128425
128697
|
function readTraceDiagnostics(options) {
|
|
128426
128698
|
return Effect.gen(function* () {
|
|
128427
128699
|
return yield* (yield* TraceDiagnostics).read(options);
|
|
@@ -128456,7 +128728,7 @@ function snapshotFromDetail(link, detail, syncedAt) {
|
|
|
128456
128728
|
mergeability: detail.mergeability
|
|
128457
128729
|
};
|
|
128458
128730
|
}
|
|
128459
|
-
const make$
|
|
128731
|
+
const make$17 = Effect.gen(function* () {
|
|
128460
128732
|
const engine = yield* OrchestrationEngineService;
|
|
128461
128733
|
const projections = yield* ProjectionSnapshotQuery;
|
|
128462
128734
|
const pullRequests = yield* PullRequestService;
|
|
@@ -128550,7 +128822,7 @@ const make$15 = Effect.gen(function* () {
|
|
|
128550
128822
|
};
|
|
128551
128823
|
});
|
|
128552
128824
|
var PullRequestSyncReactor = class extends Context.Service()("@p4code/cli/orchestration/Layers/PullRequestSyncReactor") {};
|
|
128553
|
-
const PullRequestSyncReactorLive = Layer.effect(PullRequestSyncReactor, make$
|
|
128825
|
+
const PullRequestSyncReactorLive = Layer.effect(PullRequestSyncReactor, make$17);
|
|
128554
128826
|
//#endregion
|
|
128555
128827
|
//#region src/sourceControl/SourceControlDiscovery.ts
|
|
128556
128828
|
const VCS_PROBES = [{
|
|
@@ -128569,7 +128841,7 @@ const VCS_PROBES = [{
|
|
|
128569
128841
|
installHint: "Install Jujutsu with `brew install jj` or from https://github.com/jj-vcs/jj."
|
|
128570
128842
|
}];
|
|
128571
128843
|
var SourceControlDiscovery = class extends Context.Service()("@p4code/cli/sourceControl/SourceControlDiscovery") {};
|
|
128572
|
-
const make$
|
|
128844
|
+
const make$16 = Effect.gen(function* () {
|
|
128573
128845
|
const config = yield* ServerConfig$1;
|
|
128574
128846
|
const process = yield* VcsProcess;
|
|
128575
128847
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
@@ -128618,7 +128890,7 @@ const make$14 = Effect.gen(function* () {
|
|
|
128618
128890
|
sourceControlProviders: sourceControlProviders.discover
|
|
128619
128891
|
}) });
|
|
128620
128892
|
});
|
|
128621
|
-
const layer$9 = Layer.effect(SourceControlDiscovery, make$
|
|
128893
|
+
const layer$9 = Layer.effect(SourceControlDiscovery, make$16);
|
|
128622
128894
|
//#endregion
|
|
128623
128895
|
//#region src/sourceControl/SourceControlRepositoryService.ts
|
|
128624
128896
|
const isSourceControlRepositoryError = Schema$1.is(SourceControlRepositoryError);
|
|
@@ -128651,7 +128923,7 @@ function expandHomePath(input, path) {
|
|
|
128651
128923
|
if (input.startsWith("~/") || input.startsWith("~\\")) return path.join(NodeOS.homedir(), input.slice(2));
|
|
128652
128924
|
return input;
|
|
128653
128925
|
}
|
|
128654
|
-
const make$
|
|
128926
|
+
const make$15 = Effect.gen(function* () {
|
|
128655
128927
|
const config = yield* ServerConfig$1;
|
|
128656
128928
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
128657
128929
|
const git = yield* GitVcsDriver;
|
|
@@ -128790,7 +129062,7 @@ const make$13 = Effect.gen(function* () {
|
|
|
128790
129062
|
publishRepository: (input) => publishRepository(input).pipe(mapRepositoryError("publishRepository", input.provider))
|
|
128791
129063
|
});
|
|
128792
129064
|
});
|
|
128793
|
-
const layer$8 = Layer.effect(SourceControlRepositoryService, make$
|
|
129065
|
+
const layer$8 = Layer.effect(SourceControlRepositoryService, make$15);
|
|
128794
129066
|
//#endregion
|
|
128795
129067
|
//#region src/ws.ts
|
|
128796
129068
|
/** Matches `p4c hub token add`, so a token minted here and one minted there are the same thing. */
|
|
@@ -129163,6 +129435,7 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker, computerUseBrok
|
|
|
129163
129435
|
const mcpOAuth = yield* McpOAuth;
|
|
129164
129436
|
const linearClient = yield* LinearClient;
|
|
129165
129437
|
const supervisorSecrets = yield* SupervisorSecrets;
|
|
129438
|
+
const jevWorkspaceAdvisor = yield* JevWorkspaceAdvisor;
|
|
129166
129439
|
/** Status with the key masked. The unmasked value never leaves the store. */
|
|
129167
129440
|
const supervisorSecretStatuses = supervisorSecrets.status.pipe(Effect.flatMap((entries) => Effect.forEach(entries, (entry) => supervisorSecrets.read(entry.service).pipe(Effect.map((credential) => ({
|
|
129168
129441
|
...entry,
|
|
@@ -129501,7 +129774,7 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker, computerUseBrok
|
|
|
129501
129774
|
}),
|
|
129502
129775
|
hasWorkingTreeChanges: localStatus.hasWorkingTreeChanges,
|
|
129503
129776
|
modelSelection: command.modelSelection ?? currentThread?.modelSelection
|
|
129504
|
-
}, textGeneration);
|
|
129777
|
+
}, textGeneration, jevWorkspaceAdvisor);
|
|
129505
129778
|
if (decision.mode === "local" && localStatus.isRepo && isAutoCheckoutBusy({
|
|
129506
129779
|
snapshot: yield* projectionSnapshotQuery.getCommandReadModel(),
|
|
129507
129780
|
threadId: command.threadId,
|
|
@@ -129525,6 +129798,24 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker, computerUseBrok
|
|
|
129525
129798
|
},
|
|
129526
129799
|
createdAt: command.createdAt
|
|
129527
129800
|
});
|
|
129801
|
+
if (decision.source === "jev") yield* orchestrationEngine.dispatch({
|
|
129802
|
+
type: "thread.activity.append",
|
|
129803
|
+
commandId: yield* serverCommandId("jev-consulted-workspace"),
|
|
129804
|
+
threadId: command.threadId,
|
|
129805
|
+
activity: {
|
|
129806
|
+
id: yield* serverEventId,
|
|
129807
|
+
tone: "info",
|
|
129808
|
+
kind: JEV_CONSULTED_ACTIVITY_KIND,
|
|
129809
|
+
turnId: null,
|
|
129810
|
+
summary: "Consulted with Jev",
|
|
129811
|
+
payload: {
|
|
129812
|
+
feature: "auto-workspace",
|
|
129813
|
+
summary: decision.mode === "worktree" ? "Chose a new worktree" : "Chose the current checkout"
|
|
129814
|
+
},
|
|
129815
|
+
createdAt: command.createdAt
|
|
129816
|
+
},
|
|
129817
|
+
createdAt: command.createdAt
|
|
129818
|
+
});
|
|
129528
129819
|
if (decision.mode === "local") {
|
|
129529
129820
|
yield* orchestrationEngine.dispatch({
|
|
129530
129821
|
type: "thread.meta.update",
|
|
@@ -130369,7 +130660,7 @@ function toPersistenceSqlOrDecodeError(sqlOperation, decodeOperation, correlatio
|
|
|
130369
130660
|
cause
|
|
130370
130661
|
});
|
|
130371
130662
|
}
|
|
130372
|
-
const make$
|
|
130663
|
+
const make$14 = Effect.gen(function* () {
|
|
130373
130664
|
const sql = yield* SqlClient.SqlClient;
|
|
130374
130665
|
const upsertRuntimeRow = SqlSchema.void({
|
|
130375
130666
|
Request: ProviderSessionRuntimeDbRowSchema,
|
|
@@ -130472,7 +130763,7 @@ const make$12 = Effect.gen(function* () {
|
|
|
130472
130763
|
deleteByThreadId
|
|
130473
130764
|
};
|
|
130474
130765
|
});
|
|
130475
|
-
const layer$7 = Layer.effect(ProviderSessionRuntimeRepository, make$
|
|
130766
|
+
const layer$7 = Layer.effect(ProviderSessionRuntimeRepository, make$14);
|
|
130476
130767
|
//#endregion
|
|
130477
130768
|
//#region src/provider/Layers/ProviderSessionDirectory.ts
|
|
130478
130769
|
const decodeProviderDriverKindValue = Schema$1.decodeUnknownEffect(ProviderDriverKind);
|
|
@@ -130660,14 +130951,15 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130660
130951
|
const httpServer = yield* HttpServer.HttpServer;
|
|
130661
130952
|
const state = yield* SynchronizedRef.make({
|
|
130662
130953
|
records: /* @__PURE__ */ new Map(),
|
|
130663
|
-
spawnedThreads: /* @__PURE__ */ new Map()
|
|
130954
|
+
spawnedThreads: /* @__PURE__ */ new Map(),
|
|
130955
|
+
fusionRoles: /* @__PURE__ */ new Map()
|
|
130664
130956
|
});
|
|
130665
130957
|
const currentTimeMillis = options.now ? Effect.sync(options.now) : Clock.currentTimeMillis;
|
|
130666
130958
|
const livenessWindowMs = options.livenessWindowMs ?? DEFAULT_LIVENESS_WINDOW_MS;
|
|
130667
130959
|
const endpoint = httpServer.address._tag === "TcpAddress" ? `http://${getHttpMcpEndpointHost(httpServer.address.hostname)}:${httpServer.address.port}/mcp` : "http://127.0.0.1/mcp";
|
|
130668
130960
|
const hashToken = (token) => crypto.digest("SHA-256", new TextEncoder().encode(token)).pipe(Effect.map(bytesToHex), Effect.orDie);
|
|
130669
130961
|
const revokeWhere = Effect.fn("McpSessionRegistry.revokeWhere")(function* (predicate) {
|
|
130670
|
-
const removed = yield* SynchronizedRef.modify(state, ({ records, spawnedThreads }) => {
|
|
130962
|
+
const removed = yield* SynchronizedRef.modify(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
130671
130963
|
const next = new Map(records);
|
|
130672
130964
|
const scopes = [];
|
|
130673
130965
|
for (const [hash, record] of records) {
|
|
@@ -130678,7 +130970,8 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130678
130970
|
}
|
|
130679
130971
|
return [scopes, {
|
|
130680
130972
|
records: next,
|
|
130681
|
-
spawnedThreads
|
|
130973
|
+
spawnedThreads,
|
|
130974
|
+
fusionRoles
|
|
130682
130975
|
}];
|
|
130683
130976
|
});
|
|
130684
130977
|
yield* Effect.forEach(removed, (scope) => scope.authorizationLifetime?.revocation ? Deferred.succeed(scope.authorizationLifetime.revocation, void 0) : Effect.void, { discard: true });
|
|
@@ -130706,6 +130999,8 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130706
130999
|
if (watchThreadIds.size > 0) capabilities.add("watch");
|
|
130707
131000
|
if (adviseThreadIds.size > 0) capabilities.add("advise");
|
|
130708
131001
|
const threadId = ThreadId.make(request.threadId);
|
|
131002
|
+
const rememberedRole = yield* SynchronizedRef.get(state).pipe(Effect.map((current) => current.fusionRoles.get(threadId)));
|
|
131003
|
+
const fusionRole = rememberedRole === void 0 ? request.fusionRole : rememberedRole ?? void 0;
|
|
130709
131004
|
const scopeWith = (mayCreateThreads, mayCreateFusionPairs, revocation = mainRevocation) => ({
|
|
130710
131005
|
authorizationLifetime: {
|
|
130711
131006
|
revoked: false,
|
|
@@ -130719,11 +131014,12 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130719
131014
|
capabilities,
|
|
130720
131015
|
...watchThreadIds.size > 0 ? { watchThreadIds } : {},
|
|
130721
131016
|
...adviseThreadIds.size > 0 ? { adviseThreadIds } : {},
|
|
131017
|
+
...fusionRole === void 0 ? {} : { fusionRole },
|
|
130722
131018
|
mayCreateThreads,
|
|
130723
131019
|
mayCreateFusionPairs,
|
|
130724
131020
|
issuedAt
|
|
130725
131021
|
});
|
|
130726
|
-
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
131022
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
130727
131023
|
const next = new Map(records);
|
|
130728
131024
|
next.set(tokenHash, {
|
|
130729
131025
|
tokenHash,
|
|
@@ -130743,7 +131039,8 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130743
131039
|
});
|
|
130744
131040
|
return {
|
|
130745
131041
|
records: next,
|
|
130746
|
-
spawnedThreads
|
|
131042
|
+
spawnedThreads,
|
|
131043
|
+
fusionRoles
|
|
130747
131044
|
};
|
|
130748
131045
|
});
|
|
130749
131046
|
return { config: {
|
|
@@ -130765,12 +131062,13 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130765
131062
|
const tokenHash = yield* hashToken(rawToken);
|
|
130766
131063
|
const timestamp = yield* currentTimeMillis;
|
|
130767
131064
|
yield* pruneDead(timestamp);
|
|
130768
|
-
return yield* SynchronizedRef.modify(state, ({ records, spawnedThreads }) => {
|
|
131065
|
+
return yield* SynchronizedRef.modify(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
130769
131066
|
const current = records;
|
|
130770
131067
|
const record = current.get(tokenHash);
|
|
130771
131068
|
if (!record) return [void 0, {
|
|
130772
131069
|
records: current,
|
|
130773
|
-
spawnedThreads
|
|
131070
|
+
spawnedThreads,
|
|
131071
|
+
fusionRoles
|
|
130774
131072
|
}];
|
|
130775
131073
|
const next = new Map(current);
|
|
130776
131074
|
next.set(tokenHash, {
|
|
@@ -130784,14 +131082,15 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130784
131082
|
watchThreadIds: /* @__PURE__ */ new Set([...record.scope.watchThreadIds ?? [], ...record.controlThreadIds])
|
|
130785
131083
|
}, {
|
|
130786
131084
|
records: next,
|
|
130787
|
-
spawnedThreads
|
|
131085
|
+
spawnedThreads,
|
|
131086
|
+
fusionRoles
|
|
130788
131087
|
}];
|
|
130789
131088
|
});
|
|
130790
131089
|
});
|
|
130791
131090
|
const touch = Effect.fn("McpSessionRegistry.touch")(function* (threadId) {
|
|
130792
131091
|
const timestamp = yield* currentTimeMillis;
|
|
130793
131092
|
yield* pruneDead(timestamp);
|
|
130794
|
-
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
131093
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
130795
131094
|
const current = records;
|
|
130796
131095
|
const next = new Map(current);
|
|
130797
131096
|
for (const [tokenHash, record] of current) if (record.scope.threadId === threadId) next.set(tokenHash, {
|
|
@@ -130800,12 +131099,13 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130800
131099
|
});
|
|
130801
131100
|
return {
|
|
130802
131101
|
records: next,
|
|
130803
|
-
spawnedThreads
|
|
131102
|
+
spawnedThreads,
|
|
131103
|
+
fusionRoles
|
|
130804
131104
|
};
|
|
130805
131105
|
});
|
|
130806
131106
|
});
|
|
130807
131107
|
const grantWatchThread = Effect.fn("McpSessionRegistry.grantWatchThread")(function* ({ watcherThreadId, watchedThreadId }) {
|
|
130808
|
-
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
131108
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
130809
131109
|
const next = new Map(records);
|
|
130810
131110
|
for (const [tokenHash, record] of records) {
|
|
130811
131111
|
if (record.scope.threadId !== watcherThreadId) continue;
|
|
@@ -130820,12 +131120,13 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130820
131120
|
}
|
|
130821
131121
|
return {
|
|
130822
131122
|
records: next,
|
|
130823
|
-
spawnedThreads
|
|
131123
|
+
spawnedThreads,
|
|
131124
|
+
fusionRoles
|
|
130824
131125
|
};
|
|
130825
131126
|
});
|
|
130826
131127
|
});
|
|
130827
131128
|
const revokeWatchThread = Effect.fn("McpSessionRegistry.revokeWatchThread")(function* ({ watcherThreadId, watchedThreadId }) {
|
|
130828
|
-
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
131129
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
130829
131130
|
const next = new Map(records);
|
|
130830
131131
|
for (const [tokenHash, record] of records) {
|
|
130831
131132
|
if (record.scope.threadId !== watcherThreadId) continue;
|
|
@@ -130848,12 +131149,13 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130848
131149
|
}
|
|
130849
131150
|
return {
|
|
130850
131151
|
records: next,
|
|
130851
|
-
spawnedThreads
|
|
131152
|
+
spawnedThreads,
|
|
131153
|
+
fusionRoles
|
|
130852
131154
|
};
|
|
130853
131155
|
});
|
|
130854
131156
|
});
|
|
130855
131157
|
const grantAdviseThread = Effect.fn("McpSessionRegistry.grantAdviseThread")(function* ({ watcherThreadId, advisedThreadId }) {
|
|
130856
|
-
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
131158
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
130857
131159
|
const next = new Map(records);
|
|
130858
131160
|
for (const [tokenHash, record] of records) {
|
|
130859
131161
|
if (record.scope.threadId !== watcherThreadId) continue;
|
|
@@ -130868,12 +131170,13 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130868
131170
|
}
|
|
130869
131171
|
return {
|
|
130870
131172
|
records: next,
|
|
130871
|
-
spawnedThreads
|
|
131173
|
+
spawnedThreads,
|
|
131174
|
+
fusionRoles
|
|
130872
131175
|
};
|
|
130873
131176
|
});
|
|
130874
131177
|
});
|
|
130875
131178
|
const revokeAdviseThread = Effect.fn("McpSessionRegistry.revokeAdviseThread")(function* ({ watcherThreadId, advisedThreadId }) {
|
|
130876
|
-
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
131179
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
130877
131180
|
const next = new Map(records);
|
|
130878
131181
|
for (const [tokenHash, record] of records) {
|
|
130879
131182
|
if (record.scope.threadId !== watcherThreadId) continue;
|
|
@@ -130896,12 +131199,47 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130896
131199
|
}
|
|
130897
131200
|
return {
|
|
130898
131201
|
records: next,
|
|
130899
|
-
spawnedThreads
|
|
131202
|
+
spawnedThreads,
|
|
131203
|
+
fusionRoles
|
|
130900
131204
|
};
|
|
130901
131205
|
});
|
|
130902
131206
|
});
|
|
131207
|
+
/**
|
|
131208
|
+
* Rewrites one thread's half on every credential it holds, and remembers it.
|
|
131209
|
+
*
|
|
131210
|
+
* A pair is routinely made over a thread that is already running, so the
|
|
131211
|
+
* credential it is using was minted before the pair existed and carries no
|
|
131212
|
+
* role. Patching the live record is what closes that session's gate without
|
|
131213
|
+
* restarting it; the remembered value is what answers for a session that has
|
|
131214
|
+
* not started yet, or has not reached its `issue` call.
|
|
131215
|
+
*/
|
|
131216
|
+
const applyFusionRole = (threadId, role) => SynchronizedRef.update(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
131217
|
+
const next = new Map(records);
|
|
131218
|
+
for (const [tokenHash, record] of records) {
|
|
131219
|
+
if (record.scope.threadId !== threadId) continue;
|
|
131220
|
+
const { fusionRole: _previous, ...scopeWithoutRole } = record.scope;
|
|
131221
|
+
next.set(tokenHash, {
|
|
131222
|
+
...record,
|
|
131223
|
+
scope: role === null ? scopeWithoutRole : {
|
|
131224
|
+
...scopeWithoutRole,
|
|
131225
|
+
fusionRole: role
|
|
131226
|
+
}
|
|
131227
|
+
});
|
|
131228
|
+
}
|
|
131229
|
+
return {
|
|
131230
|
+
records: next,
|
|
131231
|
+
spawnedThreads,
|
|
131232
|
+
fusionRoles: new Map(fusionRoles).set(threadId, role)
|
|
131233
|
+
};
|
|
131234
|
+
});
|
|
131235
|
+
const setFusionRole = Effect.fn("McpSessionRegistry.setFusionRole")(function* (input) {
|
|
131236
|
+
yield* applyFusionRole(input.threadId, input.role);
|
|
131237
|
+
});
|
|
131238
|
+
const clearFusionRole = Effect.fn("McpSessionRegistry.clearFusionRole")(function* (input) {
|
|
131239
|
+
yield* applyFusionRole(input.threadId, null);
|
|
131240
|
+
});
|
|
130903
131241
|
const recordSpawnedThread = Effect.fn("McpSessionRegistry.recordSpawnedThread")(function* (input) {
|
|
130904
|
-
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
131242
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads, fusionRoles }) => {
|
|
130905
131243
|
const next = new Map(records);
|
|
130906
131244
|
for (const [tokenHash, record] of records) if (record.scope.providerSessionId === input.providerSessionId) next.set(tokenHash, {
|
|
130907
131245
|
...record,
|
|
@@ -130909,7 +131247,8 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130909
131247
|
});
|
|
130910
131248
|
return {
|
|
130911
131249
|
records: next,
|
|
130912
|
-
spawnedThreads: new Map([...spawnedThreads, [input.threadId, input.mayCreateFusionPairs === true]])
|
|
131250
|
+
spawnedThreads: new Map([...spawnedThreads, [input.threadId, input.mayCreateFusionPairs === true]]),
|
|
131251
|
+
fusionRoles
|
|
130913
131252
|
};
|
|
130914
131253
|
});
|
|
130915
131254
|
});
|
|
@@ -130917,6 +131256,8 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130917
131256
|
issue,
|
|
130918
131257
|
resolve,
|
|
130919
131258
|
touch,
|
|
131259
|
+
setFusionRole,
|
|
131260
|
+
clearFusionRole,
|
|
130920
131261
|
grantWatchThread,
|
|
130921
131262
|
revokeWatchThread,
|
|
130922
131263
|
grantAdviseThread,
|
|
@@ -130932,7 +131273,7 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
130932
131273
|
});
|
|
130933
131274
|
});
|
|
130934
131275
|
let activeMcpSessionRegistry;
|
|
130935
|
-
const make$
|
|
131276
|
+
const make$13 = Effect.acquireRelease(Effect.gen(function* () {
|
|
130936
131277
|
const broker = yield* Effect.serviceOption(ComputerUseBroker);
|
|
130937
131278
|
return yield* makeWithOptions(Option.isSome(broker) ? { onRevoke: broker.value.invalidate } : {});
|
|
130938
131279
|
}).pipe(Effect.tap((registry) => Effect.sync(() => {
|
|
@@ -130940,7 +131281,7 @@ const make$11 = Effect.acquireRelease(Effect.gen(function* () {
|
|
|
130940
131281
|
}))), (registry) => registry.revokeAll.pipe(Effect.andThen(Effect.sync(() => {
|
|
130941
131282
|
if (activeMcpSessionRegistry === registry) activeMcpSessionRegistry = void 0;
|
|
130942
131283
|
}))));
|
|
130943
|
-
const layer$6 = Layer.effect(McpSessionRegistry, make$
|
|
131284
|
+
const layer$6 = Layer.effect(McpSessionRegistry, make$13);
|
|
130944
131285
|
const issueActiveMcpCredential = (request) => activeMcpSessionRegistry ? activeMcpSessionRegistry.revokeThread(request.threadId).pipe(Effect.andThen(activeMcpSessionRegistry.issue(request))) : Effect.sync(() => void 0);
|
|
130945
131286
|
/**
|
|
130946
131287
|
* Refreshes the liveness of a thread's MCP credential. Called on every provider
|
|
@@ -130948,6 +131289,8 @@ const issueActiveMcpCredential = (request) => activeMcpSessionRegistry ? activeM
|
|
|
130948
131289
|
*/
|
|
130949
131290
|
const touchActiveMcpThread = (threadId) => activeMcpSessionRegistry ? activeMcpSessionRegistry.touch(threadId) : Effect.void;
|
|
130950
131291
|
const grantActiveMcpWatchThread = (input) => activeMcpSessionRegistry ? activeMcpSessionRegistry.grantWatchThread(input) : Effect.void;
|
|
131292
|
+
const setActiveMcpFusionRole = (input) => activeMcpSessionRegistry ? activeMcpSessionRegistry.setFusionRole(input) : Effect.void;
|
|
131293
|
+
const clearActiveMcpFusionRole = (input) => activeMcpSessionRegistry ? activeMcpSessionRegistry.clearFusionRole(input) : Effect.void;
|
|
130951
131294
|
const revokeActiveMcpWatchThread = (input) => activeMcpSessionRegistry ? activeMcpSessionRegistry.revokeWatchThread(input) : Effect.void;
|
|
130952
131295
|
const grantActiveMcpAdviseThread = (input) => activeMcpSessionRegistry ? activeMcpSessionRegistry.grantAdviseThread(input) : Effect.void;
|
|
130953
131296
|
const revokeActiveMcpAdviseThread = (input) => activeMcpSessionRegistry ? activeMcpSessionRegistry.revokeAdviseThread(input) : Effect.void;
|
|
@@ -131069,6 +131412,15 @@ const makeProviderService = Effect.fn("makeProviderService")(function* (options)
|
|
|
131069
131412
|
return Option.isSome(thread) ? resolveProjectAgentBrowserAccess(settings, thread.value.projectId) : false;
|
|
131070
131413
|
})), Effect.catch((cause) => Effect.logWarning("Could not read settings; withholding agent browser access.", { cause }).pipe(Effect.as(false))));
|
|
131071
131414
|
const computerUseAccess = yield* registry.getInstanceInfo(providerInstanceId).pipe(Effect.map((info) => info.driverKind !== "codex"), Effect.catch(() => Effect.succeed(false)));
|
|
131415
|
+
const fusionRole = Option.isSome(projectionQuery) ? yield* projectionQuery.value.getActiveThreadPairs().pipe(Effect.map((pairs) => {
|
|
131416
|
+
const pair = pairs.find((entry) => entry.watcherThreadId === threadId || entry.implementerThreadId === threadId);
|
|
131417
|
+
if (pair === void 0) return void 0;
|
|
131418
|
+
return pair.watcherThreadId === threadId ? "watcher" : "implementer";
|
|
131419
|
+
}), Effect.mapError((cause) => new ProviderValidationError({
|
|
131420
|
+
operation: "ProviderService.prepareMcpSession",
|
|
131421
|
+
issue: "Could not read thread pairs, so the session's Fusion role is unknown. Refusing to issue an MCP credential that would carry no role.",
|
|
131422
|
+
cause
|
|
131423
|
+
}))) : yield* Effect.logWarning("No projection service, so an MCP credential is issued with no Fusion role. A pair whose event this process never saw will be ungated.", { threadId }).pipe(Effect.as(void 0));
|
|
131072
131424
|
const threadTitle = Option.isSome(projectionQuery) ? yield* projectionQuery.value.getThreadShellById(threadId).pipe(Effect.map((thread) => Option.isSome(thread) ? thread.value.title : void 0), Effect.catch(() => Effect.succeed(void 0))) : void 0;
|
|
131073
131425
|
const credential = yield* issueActiveMcpCredential({
|
|
131074
131426
|
threadId,
|
|
@@ -131077,7 +131429,8 @@ const makeProviderService = Effect.fn("makeProviderService")(function* (options)
|
|
|
131077
131429
|
browserAccess,
|
|
131078
131430
|
computerUseAccess,
|
|
131079
131431
|
...watchThreadIds !== void 0 ? { watchThreadIds } : {},
|
|
131080
|
-
...adviseThreadIds !== void 0 ? { adviseThreadIds } : {}
|
|
131432
|
+
...adviseThreadIds !== void 0 ? { adviseThreadIds } : {},
|
|
131433
|
+
...fusionRole !== void 0 ? { fusionRole } : {}
|
|
131081
131434
|
});
|
|
131082
131435
|
if (credential) yield* Effect.sync(() => setMcpProviderSession(credential.config));
|
|
131083
131436
|
return credential;
|
|
@@ -131923,6 +132276,47 @@ const mcpInputSchema = (schema) => ({
|
|
|
131923
132276
|
...schema,
|
|
131924
132277
|
type: "object"
|
|
131925
132278
|
});
|
|
132279
|
+
const P4_TOOL_NAMES = new Set(P4CODE_MCP_TOOL_NAMES);
|
|
132280
|
+
/**
|
|
132281
|
+
* The server's own answer to "may this role call this tool", applied to every
|
|
132282
|
+
* registered P4 tool before its handler runs.
|
|
132283
|
+
*
|
|
132284
|
+
* The adapters also hide a role's forbidden tools, but that is a context
|
|
132285
|
+
* measure: it depends on a user setting and on the one adapter that can filter
|
|
132286
|
+
* a session's tool list. A caller that never saw the tool can still name it,
|
|
132287
|
+
* so the rule that matters is enforced here, where every provider's call
|
|
132288
|
+
* arrives and neither a setting nor a prompt can move it.
|
|
132289
|
+
*
|
|
132290
|
+
* Only P4's own tools are governed. A name outside the catalogue belongs to
|
|
132291
|
+
* another server sharing this registration helper - Computer Use is one - and
|
|
132292
|
+
* this policy has nothing to say about it.
|
|
132293
|
+
*/
|
|
132294
|
+
const enforceFusionRole = (toolName) => Effect.serviceOption(McpInvocationContext).pipe(Effect.map((invocation) => {
|
|
132295
|
+
if (!P4_TOOL_NAMES.has(toolName)) return null;
|
|
132296
|
+
const role = invocation._tag === "Some" ? invocation.value.fusionRole : void 0;
|
|
132297
|
+
if (role === void 0 || fusionRoleMayCallP4Tool(role, toolName)) return null;
|
|
132298
|
+
return role;
|
|
132299
|
+
}));
|
|
132300
|
+
/** The half's own word, so the message names the caller rather than a code. */
|
|
132301
|
+
const ROLE_LABEL = {
|
|
132302
|
+
implementer: "builder",
|
|
132303
|
+
watcher: "supervisor"
|
|
132304
|
+
};
|
|
132305
|
+
const deniedResult = (toolName, role) => new McpSchema.CallToolResult({
|
|
132306
|
+
isError: true,
|
|
132307
|
+
content: [{
|
|
132308
|
+
type: "text",
|
|
132309
|
+
text: `${toolName} is not a tool the ${ROLE_LABEL[role]} half of a Fusion pair may call. Report the missing tool rather than working around it.`
|
|
132310
|
+
}]
|
|
132311
|
+
});
|
|
132312
|
+
/**
|
|
132313
|
+
* Wraps one tool handler in the role gate.
|
|
132314
|
+
*
|
|
132315
|
+
* Exported because `addTool` is reachable from two places: this helper, and
|
|
132316
|
+
* the one tool registered by hand. A gate that only covered the helper would
|
|
132317
|
+
* leave that tool open, which is the kind of hole a policy is judged by.
|
|
132318
|
+
*/
|
|
132319
|
+
const withFusionRoleGate = (toolName, handle) => (payload) => enforceFusionRole(toolName).pipe(Effect.flatMap((deniedRole) => deniedRole === null ? handle(payload) : Effect.succeed(deniedResult(toolName, deniedRole))));
|
|
131926
132320
|
const mcpToolkit = (toolkit) => Layer.effectDiscard(Effect.gen(function* () {
|
|
131927
132321
|
const server = yield* McpServer.McpServer;
|
|
131928
132322
|
yield* McpServer.registerToolkit(toolkit).pipe(Effect.provideService(McpServer.McpServer, {
|
|
@@ -131932,7 +132326,8 @@ const mcpToolkit = (toolkit) => Layer.effectDiscard(Effect.gen(function* () {
|
|
|
131932
132326
|
tool: new McpSchema.Tool({
|
|
131933
132327
|
...options.tool,
|
|
131934
132328
|
inputSchema: mcpInputSchema(options.tool.inputSchema)
|
|
131935
|
-
})
|
|
132329
|
+
}),
|
|
132330
|
+
handle: withFusionRoleGate(options.tool.name, options.handle)
|
|
131936
132331
|
})
|
|
131937
132332
|
}));
|
|
131938
132333
|
}));
|
|
@@ -132221,13 +132616,13 @@ const registerScreenshot = Effect.fn("device.registerScreenshot")(function* () {
|
|
|
132221
132616
|
}
|
|
132222
132617
|
}),
|
|
132223
132618
|
annotations: DeviceScreenshotTool.annotations,
|
|
132224
|
-
handle: (payload) => Effect.withFiber((fiber) => built.handle("device_screenshot", payload).pipe(Stream.unwrap, Stream.run(Sink.last()), Effect.flatMap(Effect.fromOption), Effect.provideService(DeviceService, service), Effect.provideService(DeviceScreenshot, screenshots), Effect.provideService(McpInvocationContext, Context.getUnsafe(fiber.context, McpInvocationContext)), Effect.flatMap((result) => screenshotContent(result.encodedResult)), Effect.orElseSucceed(() => new McpSchema.CallToolResult({
|
|
132619
|
+
handle: withFusionRoleGate(DeviceScreenshotTool.name, (payload) => Effect.withFiber((fiber) => built.handle("device_screenshot", payload).pipe(Stream.unwrap, Stream.run(Sink.last()), Effect.flatMap(Effect.fromOption), Effect.provideService(DeviceService, service), Effect.provideService(DeviceScreenshot, screenshots), Effect.provideService(McpInvocationContext, Context.getUnsafe(fiber.context, McpInvocationContext)), Effect.flatMap((result) => screenshotContent(result.encodedResult)), Effect.orElseSucceed(() => new McpSchema.CallToolResult({
|
|
132225
132620
|
isError: true,
|
|
132226
132621
|
content: [{
|
|
132227
132622
|
type: "text",
|
|
132228
132623
|
text: "Device screenshot unavailable. Check the open session and refresh devices."
|
|
132229
132624
|
}]
|
|
132230
|
-
}))))
|
|
132625
|
+
})))))
|
|
132231
132626
|
});
|
|
132232
132627
|
});
|
|
132233
132628
|
const DeviceToolkitRegistrationLive = Layer.mergeAll(mcpToolkit(DeviceStandardToolkit), Layer.effectDiscard(registerScreenshot())).pipe(Layer.provide(DeviceToolkitHandlersLive));
|
|
@@ -132398,7 +132793,7 @@ const stringField = (record, key) => {
|
|
|
132398
132793
|
const value = record[key];
|
|
132399
132794
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
132400
132795
|
};
|
|
132401
|
-
const make$
|
|
132796
|
+
const make$12 = Effect.gen(function* () {
|
|
132402
132797
|
const linear = yield* LinearClient;
|
|
132403
132798
|
return { resolve: Effect.fn("TicketResolver.resolve")(function* (reference) {
|
|
132404
132799
|
const identifier = parseTicketReference(reference);
|
|
@@ -132429,7 +132824,7 @@ const make$10 = Effect.gen(function* () {
|
|
|
132429
132824
|
};
|
|
132430
132825
|
}) };
|
|
132431
132826
|
});
|
|
132432
|
-
const layer$5 = Layer.effect(TicketResolver, make$
|
|
132827
|
+
const layer$5 = Layer.effect(TicketResolver, make$12);
|
|
132433
132828
|
//#endregion
|
|
132434
132829
|
//#region src/mcp/toolkits/tasks/tools.ts
|
|
132435
132830
|
const dependencies = [McpInvocationContext, TaskRepository];
|
|
@@ -132968,7 +133363,7 @@ const AskUserQuestionTool = Tool.make("ask_user_question", {
|
|
|
132968
133363
|
]
|
|
132969
133364
|
}).annotate(Tool.Title, "Ask user question").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
132970
133365
|
const ThreadSpawnTool = Tool.make("thread_spawn", {
|
|
132971
|
-
description: "Start a new agent thread and send it a first message, then return its id. Use it to hand a piece of work to a fresh thread - a subtask you just planned, a job that wants its own transcript. Set fusion true to create two new threads
|
|
133366
|
+
description: "Start a new agent thread and send it a first message, then return its id. Use it to hand a piece of work to a fresh thread - a subtask you just planned, a job that wants its own transcript. For activation here or a new Fusion in this chat, use thread_pair_create with no watcherThreadId so this chat becomes Supervisor and its new Builder starts empty. Set fusion true only for an explicitly separate pair to create two new threads and send prompt to its supervisor, which plans and directs the builder later, even when this thread already belongs to a pair. Set fusionWatcher true only for legacy current-chat-as-builder pairing. Both use saved Fusion role models unless overridden. Act on the user's request; no special command syntax is required. The new thread inherits this one's project, model, permission mode, interaction mode, compression and subagent policy, and every one of those can be set here instead - what you set is already in force for the first turn, so a thread never has to be corrected after it starts. Set modelSelection to run it on another model: give the model id, and leave instanceId out to keep this thread's provider instance. Once started it can be watched with thread_watch_events and changed later with thread_configure. A thread that was itself started this way cannot start another.",
|
|
132972
133367
|
parameters: ThreadSpawnInput,
|
|
132973
133368
|
success: ThreadSpawnResult,
|
|
132974
133369
|
failure: ThreadControlToolError,
|
|
@@ -132982,18 +133377,22 @@ const ThreadSpawnTool = Tool.make("thread_spawn", {
|
|
|
132982
133377
|
]
|
|
132983
133378
|
}).annotate(Tool.Title, "Start a thread").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
132984
133379
|
const ThreadPairCreateTool = Tool.make("thread_pair_create", {
|
|
132985
|
-
description: "
|
|
133380
|
+
description: "Activate Fusion here: call with no watcherThreadId to retain this chat and its history as Supervisor and create a new Builder with no messages or provider context. Builder stays idle until you send thread_advise. Use the returned implementerThreadId for the phase plan and advice. No transcript is copied. Requires explicit user authorization and a standalone current thread. Only an explicitly separate pair should use thread_spawn with fusion true. Supplying watcherThreadId retains legacy current-chat-as-builder pairing.",
|
|
132986
133381
|
parameters: ThreadPairCreateInput,
|
|
132987
133382
|
success: ThreadPairCreateResult,
|
|
132988
133383
|
failure: ThreadControlToolError,
|
|
132989
133384
|
dependencies: [
|
|
132990
133385
|
McpInvocationContext,
|
|
132991
133386
|
OrchestrationEngineService,
|
|
133387
|
+
McpSessionRegistry,
|
|
133388
|
+
ProjectionThreadRepository,
|
|
133389
|
+
ProjectionSnapshotQuery,
|
|
133390
|
+
ServerSettingsService,
|
|
132992
133391
|
Crypto.Crypto
|
|
132993
133392
|
]
|
|
132994
133393
|
}).annotate(Tool.Title, "Create a Fusion pair").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
132995
133394
|
const ThreadPairDetachTool = Tool.make("thread_pair_detach", {
|
|
132996
|
-
description: "Detach this agent session's active Fusion pair, stopping future automatic supervisor reviews while preserving both threads. The session must
|
|
133395
|
+
description: "Detach this agent session's active Fusion pair, stopping future automatic supervisor reviews while preserving both threads. The session must belong to the pair and must have created its other thread.",
|
|
132997
133396
|
parameters: ThreadPairDetachInput,
|
|
132998
133397
|
success: ThreadPairDetachResult,
|
|
132999
133398
|
failure: ThreadControlToolError,
|
|
@@ -133383,6 +133782,14 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
133383
133782
|
watcherThreadId: fusionPair.watcherThreadId,
|
|
133384
133783
|
createdAt
|
|
133385
133784
|
}, threadId);
|
|
133785
|
+
yield* registry.setFusionRole({
|
|
133786
|
+
threadId,
|
|
133787
|
+
role: "implementer"
|
|
133788
|
+
});
|
|
133789
|
+
yield* registry.setFusionRole({
|
|
133790
|
+
threadId: fusionPair.watcherThreadId,
|
|
133791
|
+
role: "watcher"
|
|
133792
|
+
});
|
|
133386
133793
|
}
|
|
133387
133794
|
yield* dispatchControl({
|
|
133388
133795
|
type: "thread.turn.start",
|
|
@@ -133410,6 +133817,74 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
133410
133817
|
};
|
|
133411
133818
|
}),
|
|
133412
133819
|
thread_pair_create: (input) => Effect.gen(function* () {
|
|
133820
|
+
if (input.watcherThreadId === void 0) {
|
|
133821
|
+
const invocation = yield* requireThreadSpawn(true);
|
|
133822
|
+
const reject = (detail) => new ThreadControlRejectedError({
|
|
133823
|
+
threadId: invocation.threadId,
|
|
133824
|
+
commandType: "thread-pair.create",
|
|
133825
|
+
detail
|
|
133826
|
+
});
|
|
133827
|
+
if ((yield* (yield* ProjectionSnapshotQuery).getCommandReadModel().pipe(Effect.mapError((cause) => reject(cause.message)))).threadPairs?.some((pair) => pair.detachedAt === null && (pair.implementerThreadId === invocation.threadId || pair.watcherThreadId === invocation.threadId))) return yield* reject("Current thread already belongs to an active Fusion pair.");
|
|
133828
|
+
const current = yield* (yield* ProjectionThreadRepository).getById({ threadId: invocation.threadId }).pipe(Effect.mapError((cause) => reject(cause.message)));
|
|
133829
|
+
if (Option.isNone(current) || current.value.deletedAt !== null) return yield* reject("Current thread does not exist.");
|
|
133830
|
+
const settings = yield* (yield* ServerSettingsService).getSettings.pipe(Effect.mapError((cause) => reject(cause.message)));
|
|
133831
|
+
const crypto = yield* Crypto.Crypto;
|
|
133832
|
+
const implementerThreadId = ThreadId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie));
|
|
133833
|
+
const pairId = ThreadPairId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie));
|
|
133834
|
+
const createdAt = DateTime.formatIso(yield* DateTime.now);
|
|
133835
|
+
const template = current.value;
|
|
133836
|
+
yield* dispatchControl({
|
|
133837
|
+
type: "thread.create",
|
|
133838
|
+
commandId: yield* newCommandId,
|
|
133839
|
+
threadId: implementerThreadId,
|
|
133840
|
+
projectId: template.projectId,
|
|
133841
|
+
title: `Implement: ${template.title}`,
|
|
133842
|
+
modelSelection: settings.fusionBuilderModelSelection ?? template.modelSelection,
|
|
133843
|
+
runtimeMode: template.runtimeMode,
|
|
133844
|
+
interactionMode: template.interactionMode,
|
|
133845
|
+
compressMode: template.compressMode,
|
|
133846
|
+
unpromptedSubagents: template.unpromptedSubagents === 1,
|
|
133847
|
+
branch: template.branch,
|
|
133848
|
+
worktreePath: template.worktreePath,
|
|
133849
|
+
createdAt
|
|
133850
|
+
}, invocation.threadId);
|
|
133851
|
+
yield* dispatchControl({
|
|
133852
|
+
type: "thread-pair.create",
|
|
133853
|
+
commandId: yield* newCommandId,
|
|
133854
|
+
pairId,
|
|
133855
|
+
implementerThreadId,
|
|
133856
|
+
watcherThreadId: invocation.threadId,
|
|
133857
|
+
...input.gateTimeoutMs === void 0 ? {} : { gateTimeoutMs: input.gateTimeoutMs },
|
|
133858
|
+
createdAt
|
|
133859
|
+
}, invocation.threadId);
|
|
133860
|
+
const registry = yield* McpSessionRegistry;
|
|
133861
|
+
yield* registry.recordSpawnedThread({
|
|
133862
|
+
providerSessionId: invocation.providerSessionId,
|
|
133863
|
+
threadId: implementerThreadId
|
|
133864
|
+
});
|
|
133865
|
+
yield* registry.setFusionRole({
|
|
133866
|
+
threadId: implementerThreadId,
|
|
133867
|
+
role: "implementer"
|
|
133868
|
+
});
|
|
133869
|
+
yield* registry.setFusionRole({
|
|
133870
|
+
threadId: invocation.threadId,
|
|
133871
|
+
role: "watcher"
|
|
133872
|
+
});
|
|
133873
|
+
const grant = {
|
|
133874
|
+
watcherThreadId: invocation.threadId,
|
|
133875
|
+
watchedThreadId: implementerThreadId
|
|
133876
|
+
};
|
|
133877
|
+
yield* registry.grantWatchThread(grant);
|
|
133878
|
+
yield* registry.grantAdviseThread({
|
|
133879
|
+
watcherThreadId: invocation.threadId,
|
|
133880
|
+
advisedThreadId: implementerThreadId
|
|
133881
|
+
});
|
|
133882
|
+
return {
|
|
133883
|
+
pairId,
|
|
133884
|
+
implementerThreadId,
|
|
133885
|
+
watcherThreadId: invocation.threadId
|
|
133886
|
+
};
|
|
133887
|
+
}
|
|
133413
133888
|
const { invocation, threadId: watcherThreadId } = yield* requireThreadControlTarget(input.watcherThreadId);
|
|
133414
133889
|
const crypto = yield* Crypto.Crypto;
|
|
133415
133890
|
const pairId = ThreadPairId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie));
|
|
@@ -133423,6 +133898,15 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
133423
133898
|
continuationMessageId,
|
|
133424
133899
|
createdAt: DateTime.formatIso(yield* DateTime.now)
|
|
133425
133900
|
}, invocation.threadId);
|
|
133901
|
+
const registry = yield* McpSessionRegistry;
|
|
133902
|
+
yield* registry.setFusionRole({
|
|
133903
|
+
threadId: invocation.threadId,
|
|
133904
|
+
role: "implementer"
|
|
133905
|
+
});
|
|
133906
|
+
yield* registry.setFusionRole({
|
|
133907
|
+
threadId: watcherThreadId,
|
|
133908
|
+
role: "watcher"
|
|
133909
|
+
});
|
|
133426
133910
|
return {
|
|
133427
133911
|
pairId,
|
|
133428
133912
|
implementerThreadId: invocation.threadId,
|
|
@@ -133442,15 +133926,16 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
133442
133926
|
commandType: "thread-pair.detach",
|
|
133443
133927
|
detail: `Active Fusion pair '${input.pairId}' was not found.`
|
|
133444
133928
|
});
|
|
133445
|
-
if (pair.implementerThreadId !== invocation.threadId) return yield* new ThreadControlRejectedError({
|
|
133929
|
+
if (pair.implementerThreadId !== invocation.threadId && pair.watcherThreadId !== invocation.threadId) return yield* new ThreadControlRejectedError({
|
|
133446
133930
|
threadId: invocation.threadId,
|
|
133447
133931
|
commandType: "thread-pair.detach",
|
|
133448
|
-
detail: "This session is not the pair
|
|
133932
|
+
detail: "This session is not a member of the pair."
|
|
133449
133933
|
});
|
|
133450
|
-
|
|
133934
|
+
const otherThreadId = pair.implementerThreadId === invocation.threadId ? pair.watcherThreadId : pair.implementerThreadId;
|
|
133935
|
+
if (!invocation.controlThreadIds?.has(otherThreadId)) return yield* new ThreadControlRejectedError({
|
|
133451
133936
|
threadId: invocation.threadId,
|
|
133452
133937
|
commandType: "thread-pair.detach",
|
|
133453
|
-
detail: "This session did not create the
|
|
133938
|
+
detail: "This session did not create the other thread in the pair."
|
|
133454
133939
|
});
|
|
133455
133940
|
const detachedAt = DateTime.formatIso(yield* DateTime.now);
|
|
133456
133941
|
yield* dispatchControl({
|
|
@@ -134067,6 +134552,20 @@ var TypeSafeRequestError = class extends Data.TaggedError("TypeSafeRequestError"
|
|
|
134067
134552
|
var TypeSafeClient = class extends Context.Service()("@p4code/cli/orchestration/triage/TypeSafeClient") {};
|
|
134068
134553
|
const asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
134069
134554
|
/**
|
|
134555
|
+
* The finite numbers out of a probability map, or nothing.
|
|
134556
|
+
*
|
|
134557
|
+
* Non-numeric and non-finite entries are dropped rather than coerced, for the
|
|
134558
|
+
* same reason a missing confidence is never read as zero: a rank built on an
|
|
134559
|
+
* invented number is worse than one built on fewer.
|
|
134560
|
+
*/
|
|
134561
|
+
function readProbabilities(value) {
|
|
134562
|
+
const record = asRecord(value);
|
|
134563
|
+
if (record === void 0) return void 0;
|
|
134564
|
+
const probabilities = {};
|
|
134565
|
+
for (const [key, entry] of Object.entries(record)) if (typeof entry === "number" && Number.isFinite(entry)) probabilities[key] = entry;
|
|
134566
|
+
return Object.keys(probabilities).length === 0 ? void 0 : probabilities;
|
|
134567
|
+
}
|
|
134568
|
+
/**
|
|
134070
134569
|
* Reads one answer, or nothing.
|
|
134071
134570
|
*
|
|
134072
134571
|
* A `choice` or `score` without a numeric `confidence` is rejected rather than
|
|
@@ -134081,10 +134580,16 @@ function parseTypeSafeAnswer(value) {
|
|
|
134081
134580
|
case "choice": {
|
|
134082
134581
|
const choice = record["choice"];
|
|
134083
134582
|
if (typeof choice !== "string" || typeof confidence !== "number") return void 0;
|
|
134084
|
-
|
|
134583
|
+
const probabilities = readProbabilities(record["probabilities"]);
|
|
134584
|
+
return probabilities === void 0 ? {
|
|
134085
134585
|
type: "choice",
|
|
134086
134586
|
choice,
|
|
134087
134587
|
confidence
|
|
134588
|
+
} : {
|
|
134589
|
+
type: "choice",
|
|
134590
|
+
choice,
|
|
134591
|
+
confidence,
|
|
134592
|
+
probabilities
|
|
134088
134593
|
};
|
|
134089
134594
|
}
|
|
134090
134595
|
case "score": {
|
|
@@ -134225,7 +134730,7 @@ const TypeSafeToolkit = Toolkit.make(TypeSafeAskTool);
|
|
|
134225
134730
|
/** Headroom for the envelope and for the estimate's own error. */
|
|
134226
134731
|
const RESERVE_TOKENS = 2e3;
|
|
134227
134732
|
/** One question per call, so the id is fixed rather than invented. */
|
|
134228
|
-
const QUESTION_ID = "question";
|
|
134733
|
+
const QUESTION_ID$1 = "question";
|
|
134229
134734
|
const requestTokens = (input) => estimateTokens(input.data) + estimateTokens(input.instructions) + estimateTokens(JSON.stringify(input.criteria));
|
|
134230
134735
|
const TypeSafeToolkitHandlersLive = TypeSafeToolkit.toLayer({ typesafe_ask: (input) => Effect.gen(function* () {
|
|
134231
134736
|
const tokens = requestTokens(input);
|
|
@@ -134239,7 +134744,7 @@ const TypeSafeToolkitHandlersLive = TypeSafeToolkit.toLayer({ typesafe_ask: (inp
|
|
|
134239
134744
|
model: settings?.fusionReviewTriage.triageModel ?? "jev-latest",
|
|
134240
134745
|
state: input.data,
|
|
134241
134746
|
question: {
|
|
134242
|
-
id: QUESTION_ID,
|
|
134747
|
+
id: QUESTION_ID$1,
|
|
134243
134748
|
type: input.type,
|
|
134244
134749
|
instructions: input.instructions,
|
|
134245
134750
|
criteria: input.criteria
|
|
@@ -134268,6 +134773,16 @@ const TypeSafeToolkitHandlersLive = TypeSafeToolkit.toLayer({ typesafe_ask: (inp
|
|
|
134268
134773
|
* appending beside it.
|
|
134269
134774
|
*/
|
|
134270
134775
|
const evidenceReadActivityId = (watchedThreadId, throughSequence) => EventId.make(`fusion-evidence:${watchedThreadId}:${throughSequence}`);
|
|
134776
|
+
/**
|
|
134777
|
+
* The key a raw read records under, when the supervisor paged the events itself.
|
|
134778
|
+
*
|
|
134779
|
+
* A raw read has no fixed bound to key on: the supervisor discovers where the
|
|
134780
|
+
* window ends by paging to it, so keying on the sequence it happens to have
|
|
134781
|
+
* reached would mint one row per page. The turn is the bound that already
|
|
134782
|
+
* exists, and it collapses the whole raw read into the single row a compact
|
|
134783
|
+
* review would have written.
|
|
134784
|
+
*/
|
|
134785
|
+
const rawEvidenceReadActivityId = (watchedThreadId, readerTurnId) => EventId.make(`fusion-evidence:${watchedThreadId}:turn:${readerTurnId}`);
|
|
134271
134786
|
/** One report per review, keyed like the read it reports on so a retry replaces. */
|
|
134272
134787
|
const evidenceReportActivityId = (watchedThreadId, throughSequence) => EventId.make(`fusion-evidence-summary:${watchedThreadId}:${throughSequence}`);
|
|
134273
134788
|
/**
|
|
@@ -134300,7 +134815,8 @@ const evidenceTiming = (readAt, closedAt) => {
|
|
|
134300
134815
|
const correlateEvidence = Effect.fn("fusionEvidenceReport.correlateEvidence")(function* (input) {
|
|
134301
134816
|
const projections = yield* ProjectionSnapshotQuery;
|
|
134302
134817
|
const latest = yield* projections.getLatestThreadContextWindow(input.readerThreadId).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
134303
|
-
const
|
|
134818
|
+
const readContext = (activityId) => projections.getEvidenceReadContext(activityId).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
134819
|
+
const read = yield* readContext(input.readActivityId).pipe(Effect.flatMap((row) => Option.isSome(row) || input.fallbackReadActivityId === void 0 ? Effect.succeed(row) : readContext(input.fallbackReadActivityId)));
|
|
134304
134820
|
const timing = Option.match(read, {
|
|
134305
134821
|
onNone: () => null,
|
|
134306
134822
|
onSome: (row) => evidenceTiming(row.readAt, input.closedAt)
|
|
@@ -134341,8 +134857,14 @@ const ThreadWatchEventsTool = Tool.make("thread_watch_events", {
|
|
|
134341
134857
|
parameters: ThreadWatchEventsInput,
|
|
134342
134858
|
success: ThreadWatchEventsResult,
|
|
134343
134859
|
failure: ThreadWatchToolError,
|
|
134344
|
-
dependencies: [
|
|
134345
|
-
|
|
134860
|
+
dependencies: [
|
|
134861
|
+
McpInvocationContext,
|
|
134862
|
+
ThreadEventStreamService,
|
|
134863
|
+
OrchestrationEngineService,
|
|
134864
|
+
ProjectionSnapshotQuery,
|
|
134865
|
+
Crypto.Crypto
|
|
134866
|
+
]
|
|
134867
|
+
}).annotate(Tool.Title, "Read watched thread events").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, true);
|
|
134346
134868
|
const ThreadWatchReviewTool = Tool.make("thread_watch_review", {
|
|
134347
134869
|
description: "Read bounded compact review evidence for an explicitly granted thread. Combines assistant fragments by message identity; preserves user requirements, tool evidence, plans, errors and turn boundaries. Resume with nextAfterSequence and the same throughSequence until hasMore is false, even on empty pages. Message operations append or replace by identity across pages. Truncated evidence includes source sequence ranges for targeted recovery with thread_watch_events; do not treat an excerpt as full proof.",
|
|
134348
134870
|
parameters: ThreadWatchReviewInput,
|
|
@@ -134394,20 +134916,24 @@ const REPORT_HEADING = {
|
|
|
134394
134916
|
* for; losing the note that it happened is a smaller loss than losing the page,
|
|
134395
134917
|
* so a rejected dispatch is logged and the page is returned anyway.
|
|
134396
134918
|
*/
|
|
134397
|
-
const recordEvidenceRead = Effect.fn("mcp.watch.recordEvidenceRead")(function* (readerThreadId,
|
|
134919
|
+
const recordEvidenceRead = Effect.fn("mcp.watch.recordEvidenceRead")(function* (readerThreadId, window) {
|
|
134398
134920
|
const engine = yield* OrchestrationEngineService;
|
|
134399
134921
|
const crypto = yield* Crypto.Crypto;
|
|
134400
134922
|
const projections = yield* ProjectionSnapshotQuery;
|
|
134401
134923
|
const createdAt = DateTime.formatIso(yield* DateTime.now);
|
|
134402
|
-
const recorded = yield* projections.getEvidenceReadContext(
|
|
134924
|
+
const recorded = yield* projections.getEvidenceReadContext(window.activityId).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
134403
134925
|
const opened = Option.isSome(recorded);
|
|
134404
134926
|
const readCreatedAt = Option.match(recorded, {
|
|
134405
134927
|
onNone: () => createdAt,
|
|
134406
134928
|
onSome: (row) => row.readAt
|
|
134407
134929
|
});
|
|
134408
134930
|
const readAfterSequence = Option.match(recorded, {
|
|
134409
|
-
onNone: () => afterSequence,
|
|
134410
|
-
onSome: (row) => row.afterSequence ?? afterSequence
|
|
134931
|
+
onNone: () => window.afterSequence,
|
|
134932
|
+
onSome: (row) => row.afterSequence ?? window.afterSequence
|
|
134933
|
+
});
|
|
134934
|
+
const readThroughSequence = Option.match(recorded, {
|
|
134935
|
+
onNone: () => window.throughSequence,
|
|
134936
|
+
onSome: (row) => row.throughSequence === null ? window.throughSequence : Math.max(row.throughSequence, window.throughSequence)
|
|
134411
134937
|
});
|
|
134412
134938
|
const activeTurnId = yield* projections.getActiveTurnId(readerThreadId).pipe(Effect.orElseSucceed(() => Option.none()), Effect.map(Option.getOrNull));
|
|
134413
134939
|
const usedTokensAtRead = opened ? Option.getOrNull(Option.map(recorded, (row) => row.usedTokensAtRead)) : yield* projections.getLatestThreadContextWindow(readerThreadId).pipe(Effect.map(Option.map((row) => row.usedTokens)), Effect.orElseSucceed(() => Option.none()), Effect.map(Option.getOrNull));
|
|
@@ -134417,29 +134943,40 @@ const recordEvidenceRead = Effect.fn("mcp.watch.recordEvidenceRead")(function* (
|
|
|
134417
134943
|
threadId: readerThreadId,
|
|
134418
134944
|
createdAt,
|
|
134419
134945
|
activity: {
|
|
134420
|
-
id:
|
|
134946
|
+
id: window.activityId,
|
|
134421
134947
|
createdAt: readCreatedAt,
|
|
134422
134948
|
tone: "info",
|
|
134423
134949
|
kind: "fusion.evidence.read",
|
|
134424
134950
|
summary: "Read builder evidence",
|
|
134425
134951
|
turnId: null,
|
|
134426
134952
|
payload: {
|
|
134427
|
-
watchedThreadId:
|
|
134953
|
+
watchedThreadId: window.watchedThreadId,
|
|
134428
134954
|
afterSequence: readAfterSequence,
|
|
134429
|
-
throughSequence:
|
|
134430
|
-
nextAfterSequence:
|
|
134431
|
-
hasMore:
|
|
134432
|
-
scannedEvents:
|
|
134955
|
+
throughSequence: readThroughSequence,
|
|
134956
|
+
nextAfterSequence: window.nextAfterSequence,
|
|
134957
|
+
hasMore: window.hasMore,
|
|
134958
|
+
scannedEvents: window.scannedEvents,
|
|
134433
134959
|
...activeTurnId === null ? {} : { turnId: activeTurnId },
|
|
134960
|
+
...window.raw === true ? { raw: true } : {},
|
|
134434
134961
|
...usedTokensAtRead === null ? {} : { usedTokensAtRead }
|
|
134435
134962
|
}
|
|
134436
134963
|
}
|
|
134437
134964
|
}).pipe(Effect.catchCause((cause) => Effect.logWarning("could not record the supervisor's evidence read", {
|
|
134438
134965
|
readerThreadId,
|
|
134439
|
-
watchedThreadId:
|
|
134966
|
+
watchedThreadId: window.watchedThreadId,
|
|
134440
134967
|
cause
|
|
134441
134968
|
})));
|
|
134442
134969
|
});
|
|
134970
|
+
/**
|
|
134971
|
+
* Whether this reader is the watcher half of a live pair over this thread.
|
|
134972
|
+
*
|
|
134973
|
+
* `thread_watch_events` is the generic polling tool, so an orchestrator reading
|
|
134974
|
+
* a thread it spawned goes through it too. Only a Fusion watcher is reading
|
|
134975
|
+
* builder evidence, and only its work log should grow a row saying so.
|
|
134976
|
+
*/
|
|
134977
|
+
const watchesAsFusionSupervisor = Effect.fn("mcp.watch.watchesAsFusionSupervisor")(function* (readerThreadId, watchedThreadId) {
|
|
134978
|
+
return (yield* (yield* ProjectionSnapshotQuery).getActiveThreadPairs().pipe(Effect.orElseSucceed(() => []))).some((pair) => pair.watcherThreadId === readerThreadId && pair.implementerThreadId === watchedThreadId);
|
|
134979
|
+
});
|
|
134443
134980
|
/** Bounded so one report cannot dominate a thread's activity storage. */
|
|
134444
134981
|
const clip = (value, limit) => {
|
|
134445
134982
|
const trimmed = value?.trim();
|
|
@@ -134453,7 +134990,15 @@ const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
|
134453
134990
|
threadId: input.threadId,
|
|
134454
134991
|
detail: cause.message
|
|
134455
134992
|
})));
|
|
134456
|
-
yield* recordEvidenceRead(invocation.threadId,
|
|
134993
|
+
yield* recordEvidenceRead(invocation.threadId, {
|
|
134994
|
+
activityId: evidenceReadActivityId(page.threadId, page.throughSequence),
|
|
134995
|
+
watchedThreadId: page.threadId,
|
|
134996
|
+
afterSequence: input.afterSequence ?? 0,
|
|
134997
|
+
throughSequence: page.throughSequence,
|
|
134998
|
+
nextAfterSequence: page.nextAfterSequence,
|
|
134999
|
+
hasMore: page.hasMore,
|
|
135000
|
+
scannedEvents: page.scannedEvents
|
|
135001
|
+
});
|
|
134457
135002
|
return page;
|
|
134458
135003
|
}),
|
|
134459
135004
|
thread_evidence_report: (input) => Effect.gen(function* () {
|
|
@@ -134461,9 +135006,11 @@ const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
|
134461
135006
|
const engine = yield* OrchestrationEngineService;
|
|
134462
135007
|
const crypto = yield* Crypto.Crypto;
|
|
134463
135008
|
const createdAt = DateTime.formatIso(yield* DateTime.now);
|
|
135009
|
+
const activeTurnId = yield* (yield* ProjectionSnapshotQuery).getActiveTurnId(invocation.threadId).pipe(Effect.orElseSucceed(() => Option.none()), Effect.map(Option.getOrNull));
|
|
134464
135010
|
const { context, timing } = yield* correlateEvidence({
|
|
134465
135011
|
readerThreadId: invocation.threadId,
|
|
134466
135012
|
readActivityId: evidenceReadActivityId(input.threadId, input.throughSequence),
|
|
135013
|
+
...activeTurnId === null ? {} : { fallbackReadActivityId: rawEvidenceReadActivityId(input.threadId, activeTurnId) },
|
|
134467
135014
|
closedAt: createdAt
|
|
134468
135015
|
});
|
|
134469
135016
|
const summary = clip(input.summary, THREAD_EVIDENCE_REPORT_MAX_CHARS);
|
|
@@ -134504,7 +135051,7 @@ const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
|
134504
135051
|
};
|
|
134505
135052
|
}),
|
|
134506
135053
|
thread_watch_events: (input) => Effect.gen(function* () {
|
|
134507
|
-
yield* requireWatchCapability(input.threadId);
|
|
135054
|
+
const invocation = yield* requireWatchCapability(input.threadId);
|
|
134508
135055
|
const page = yield* (yield* ThreadEventStreamService).read({
|
|
134509
135056
|
threadId: input.threadId,
|
|
134510
135057
|
...input.afterSequence !== void 0 ? { afterSequence: input.afterSequence } : {},
|
|
@@ -134513,6 +135060,28 @@ const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
|
134513
135060
|
threadId: input.threadId,
|
|
134514
135061
|
detail: cause.message
|
|
134515
135062
|
})));
|
|
135063
|
+
const lastSequence = page.events.at(-1)?.sequence;
|
|
135064
|
+
if (lastSequence !== void 0 && (yield* watchesAsFusionSupervisor(invocation.threadId, input.threadId))) {
|
|
135065
|
+
const projections = yield* ProjectionSnapshotQuery;
|
|
135066
|
+
const turnId = yield* projections.getActiveTurnId(invocation.threadId).pipe(Effect.orElseSucceed(() => Option.none()), Effect.map(Option.getOrNull));
|
|
135067
|
+
if (turnId !== null) {
|
|
135068
|
+
const activityId = rawEvidenceReadActivityId(input.threadId, turnId);
|
|
135069
|
+
const opened = yield* projections.getLatestEvidenceRead(invocation.threadId).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
135070
|
+
if (!Option.match(opened, {
|
|
135071
|
+
onNone: () => false,
|
|
135072
|
+
onSome: (row) => row.turnId === turnId && row.watchedThreadId === input.threadId
|
|
135073
|
+
})) yield* recordEvidenceRead(invocation.threadId, {
|
|
135074
|
+
activityId,
|
|
135075
|
+
watchedThreadId: input.threadId,
|
|
135076
|
+
afterSequence: input.afterSequence ?? 0,
|
|
135077
|
+
throughSequence: lastSequence,
|
|
135078
|
+
nextAfterSequence: lastSequence,
|
|
135079
|
+
hasMore: page.hasMore,
|
|
135080
|
+
scannedEvents: page.events.length,
|
|
135081
|
+
raw: true
|
|
135082
|
+
});
|
|
135083
|
+
}
|
|
135084
|
+
}
|
|
134516
135085
|
return {
|
|
134517
135086
|
threadId: input.threadId,
|
|
134518
135087
|
events: page.events,
|
|
@@ -134590,7 +135159,7 @@ const registerPreviewSnapshot = Effect.fn("McpHttpServer.registerPreviewSnapshot
|
|
|
134590
135159
|
}
|
|
134591
135160
|
}),
|
|
134592
135161
|
annotations: tool.annotations,
|
|
134593
|
-
handle: (payload) => Effect.withFiber((fiber) => {
|
|
135162
|
+
handle: withFusionRoleGate(tool.name, (payload) => Effect.withFiber((fiber) => {
|
|
134594
135163
|
const invocation = Context.getUnsafe(fiber.context, McpInvocationContext);
|
|
134595
135164
|
return built.handle("preview_snapshot", payload).pipe(Stream.unwrap, Stream.run(Sink.last()), Effect.flatMap(Effect.fromOption), Effect.provideService(PreviewAutomationBroker, broker), Effect.provideService(McpInvocationContext, invocation), Effect.matchCauseEffect({
|
|
134596
135165
|
onFailure: previewSnapshotFailure,
|
|
@@ -134619,7 +135188,7 @@ const registerPreviewSnapshot = Effect.fn("McpHttpServer.registerPreviewSnapshot
|
|
|
134619
135188
|
}));
|
|
134620
135189
|
}
|
|
134621
135190
|
}));
|
|
134622
|
-
})
|
|
135191
|
+
}))
|
|
134623
135192
|
});
|
|
134624
135193
|
});
|
|
134625
135194
|
const PreviewStandardToolkitRegistrationLive = mcpToolkit(PreviewStandardToolkit).pipe(Layer.provide(PreviewStandardToolkitHandlersLive));
|
|
@@ -135840,7 +136409,7 @@ const COMPLETION_SWEEP_BATCH_SIZE = 25;
|
|
|
135840
136409
|
const COMPLETION_SWEEP_INTERVAL = Duration.minutes(1);
|
|
135841
136410
|
const COMPLETION_PR_TIMEOUT = Duration.seconds(10);
|
|
135842
136411
|
const MILLISECONDS_PER_DAY = 1440 * 60 * 1e3;
|
|
135843
|
-
const make$
|
|
136412
|
+
const make$11 = Effect.gen(function* () {
|
|
135844
136413
|
const sql = yield* SqlClient.SqlClient;
|
|
135845
136414
|
const settings = yield* ServerSettingsService;
|
|
135846
136415
|
const git = yield* GitManager;
|
|
@@ -135927,7 +136496,7 @@ const make$9 = Effect.gen(function* () {
|
|
|
135927
136496
|
};
|
|
135928
136497
|
});
|
|
135929
136498
|
var ThreadCompletionReactor = class extends Context.Service()("@p4code/cli/orchestration/Layers/ThreadCompletionReactor") {};
|
|
135930
|
-
const ThreadCompletionReactorLive = Layer.effect(ThreadCompletionReactor, make$
|
|
136499
|
+
const ThreadCompletionReactorLive = Layer.effect(ThreadCompletionReactor, make$11);
|
|
135931
136500
|
//#endregion
|
|
135932
136501
|
//#region src/orchestration/Services/ScheduledTaskReactor.ts
|
|
135933
136502
|
/**
|
|
@@ -136119,7 +136688,7 @@ const decodeReportStamp = Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(R
|
|
|
136119
136688
|
const decodeTurns = Schema$1.decodeUnknownEffect(Schema$1.Array(TurnRow));
|
|
136120
136689
|
const encodeReport = Schema$1.encodeEffect(Schema$1.UnknownFromJsonString);
|
|
136121
136690
|
/** Reads existing projections only; observation never dispatches orchestration commands. */
|
|
136122
|
-
const make$
|
|
136691
|
+
const make$10 = Effect.gen(function* () {
|
|
136123
136692
|
const sql = yield* SqlClient.SqlClient;
|
|
136124
136693
|
const fs = yield* FileSystem.FileSystem;
|
|
136125
136694
|
const path = yield* Path$1.Path;
|
|
@@ -136193,7 +136762,7 @@ const make$8 = Effect.gen(function* () {
|
|
|
136193
136762
|
};
|
|
136194
136763
|
});
|
|
136195
136764
|
const layer$1 = Layer.effectDiscard(Effect.gen(function* () {
|
|
136196
|
-
yield* (yield* make$
|
|
136765
|
+
yield* (yield* make$10).start;
|
|
136197
136766
|
}));
|
|
136198
136767
|
//#endregion
|
|
136199
136768
|
//#region src/orchestration/Services/RuntimeReceiptBus.ts
|
|
@@ -136781,7 +137350,7 @@ function runtimeEventToActivities(event, taskTitle, compressMode) {
|
|
|
136781
137350
|
}
|
|
136782
137351
|
return [];
|
|
136783
137352
|
}
|
|
136784
|
-
const make$
|
|
137353
|
+
const make$9 = Effect.gen(function* () {
|
|
136785
137354
|
const crypto = yield* Crypto.Crypto;
|
|
136786
137355
|
const orchestrationEngine = yield* OrchestrationEngineService;
|
|
136787
137356
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
@@ -137414,7 +137983,7 @@ const make$7 = Effect.gen(function* () {
|
|
|
137414
137983
|
drain: worker.drain
|
|
137415
137984
|
};
|
|
137416
137985
|
});
|
|
137417
|
-
const ProviderRuntimeIngestionLive = Layer.effect(ProviderRuntimeIngestionService, make$
|
|
137986
|
+
const ProviderRuntimeIngestionLive = Layer.effect(ProviderRuntimeIngestionService, make$9).pipe(Layer.provide(ProjectionTurnRepositoryLive), Layer.provide(layer$86));
|
|
137418
137987
|
//#endregion
|
|
137419
137988
|
//#region src/provider/userInvokedSkills.ts
|
|
137420
137989
|
/**
|
|
@@ -137536,6 +138105,9 @@ const expandUserInvokedSkill = Effect.fnUntraced(function* (input) {
|
|
|
137536
138105
|
});
|
|
137537
138106
|
});
|
|
137538
138107
|
//#endregion
|
|
138108
|
+
//#region src/orchestration/Services/JevToolPrefetch.ts
|
|
138109
|
+
var JevToolPrefetch = class extends Context.Service()("@p4code/cli/orchestration/Services/JevToolPrefetch") {};
|
|
138110
|
+
//#endregion
|
|
137539
138111
|
//#region src/orchestration/Layers/ProviderCommandReactor.ts
|
|
137540
138112
|
const isProviderAdapterRequestError = Schema$1.is(ProviderAdapterRequestError);
|
|
137541
138113
|
const isProviderDriverKind = Schema$1.is(ProviderDriverKind);
|
|
@@ -137690,13 +138262,14 @@ function resolvePendingWorkspaceCleanupGroups(input) {
|
|
|
137690
138262
|
}
|
|
137691
138263
|
return groups;
|
|
137692
138264
|
}
|
|
137693
|
-
const make$
|
|
138265
|
+
const make$8 = Effect.gen(function* () {
|
|
137694
138266
|
const compactingThreads = /* @__PURE__ */ new Map();
|
|
137695
138267
|
const crypto = yield* Crypto.Crypto;
|
|
137696
138268
|
const orchestrationEngine = yield* OrchestrationEngineService;
|
|
137697
138269
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
137698
138270
|
const providerService = yield* ProviderService;
|
|
137699
138271
|
const providerRegistry = yield* ProviderRegistry;
|
|
138272
|
+
const jevToolPrefetch = yield* JevToolPrefetch;
|
|
137700
138273
|
const gitWorkflow = yield* GitWorkflowService;
|
|
137701
138274
|
const threadWorkspaceLifecycle = yield* ThreadWorkspaceLifecycleService;
|
|
137702
138275
|
const vcsStatusBroadcaster = yield* VcsStatusBroadcaster;
|
|
@@ -137758,6 +138331,27 @@ const make$6 = Effect.gen(function* () {
|
|
|
137758
138331
|
},
|
|
137759
138332
|
createdAt: input.createdAt
|
|
137760
138333
|
})));
|
|
138334
|
+
const appendJevConsultedActivity = (input) => Effect.all({
|
|
138335
|
+
commandId: serverCommandId("jev-consulted-activity"),
|
|
138336
|
+
eventId: serverEventId()
|
|
138337
|
+
}).pipe(Effect.flatMap(({ commandId, eventId }) => orchestrationEngine.dispatch({
|
|
138338
|
+
type: "thread.activity.append",
|
|
138339
|
+
commandId,
|
|
138340
|
+
threadId: input.threadId,
|
|
138341
|
+
activity: {
|
|
138342
|
+
id: eventId,
|
|
138343
|
+
tone: "info",
|
|
138344
|
+
kind: JEV_CONSULTED_ACTIVITY_KIND,
|
|
138345
|
+
summary: "Consulted with Jev",
|
|
138346
|
+
payload: {
|
|
138347
|
+
feature: input.feature,
|
|
138348
|
+
summary: input.summary
|
|
138349
|
+
},
|
|
138350
|
+
turnId: input.turnId,
|
|
138351
|
+
createdAt: input.createdAt
|
|
138352
|
+
},
|
|
138353
|
+
createdAt: input.createdAt
|
|
138354
|
+
})), Effect.catchCause(() => Effect.void));
|
|
137761
138355
|
/**
|
|
137762
138356
|
* A stop otherwise leaves nothing behind: the only row the
|
|
137763
138357
|
* timeline ever got was the failure case above, and the turn fold's "You
|
|
@@ -138278,10 +138872,47 @@ const make$6 = Effect.gen(function* () {
|
|
|
138278
138872
|
if (levelChangedMidSession) threadSessionRulesetModes.set(input.threadId, compressMode);
|
|
138279
138873
|
const chatInput = isChatProject(thread.projectId) && activeSession?.provider !== "opencode" && activeSession?.provider !== "claudeAgent" && thread.messages.filter((message) => message.role === "user").length === 1 ? [P4_CHAT_SYSTEM_PROMPT, inputWithStructuredQuestionPolicy].filter(Boolean).join("\n\n") : inputWithStructuredQuestionPolicy;
|
|
138280
138874
|
const inputWithCompressSuffix = chatInput !== void 0 && compressSuffix !== void 0 ? `${chatInput}\n\n${compressSuffix}` : chatInput;
|
|
138875
|
+
const prefetchProvider = (yield* providerRegistry.getProviders).find((snapshot) => snapshot.instanceId === modelForTurn.instanceId);
|
|
138876
|
+
yield* Effect.logDebug("jev prefetch evaluated", {
|
|
138877
|
+
threadId: input.threadId,
|
|
138878
|
+
instanceId: modelForTurn.instanceId,
|
|
138879
|
+
providerFound: prefetchProvider !== void 0,
|
|
138880
|
+
catalogSize: (prefetchProvider?.skills.length ?? 0) + (prefetchProvider?.slashCommands.length ?? 0),
|
|
138881
|
+
hasInput: inputWithCompressSuffix !== void 0
|
|
138882
|
+
});
|
|
138883
|
+
if (prefetchProvider === void 0) yield* Effect.logDebug("jev prefetch skipped", {
|
|
138884
|
+
reason: "provider not registered",
|
|
138885
|
+
instanceId: modelForTurn.instanceId
|
|
138886
|
+
});
|
|
138887
|
+
const prefetch = inputWithCompressSuffix === void 0 || prefetchProvider === void 0 ? void 0 : yield* jevToolPrefetch.hintFor({
|
|
138888
|
+
request: input.messageText,
|
|
138889
|
+
skills: prefetchProvider.skills,
|
|
138890
|
+
...activeSession?.cwd ? { cwd: activeSession.cwd } : {},
|
|
138891
|
+
compact: compressMode !== "off",
|
|
138892
|
+
maxChars: Math.max(0, PROVIDER_SEND_TURN_MAX_INPUT_CHARS - inputWithCompressSuffix.length - 2),
|
|
138893
|
+
catalog: [...prefetchProvider.skills.map((skill) => ({
|
|
138894
|
+
kind: "skill",
|
|
138895
|
+
name: skill.name,
|
|
138896
|
+
description: skill.shortDescription ?? skill.description,
|
|
138897
|
+
enabled: skill.enabled
|
|
138898
|
+
})), ...prefetchProvider.slashCommands.map((command) => ({
|
|
138899
|
+
kind: "command",
|
|
138900
|
+
name: command.name,
|
|
138901
|
+
description: command.description
|
|
138902
|
+
}))]
|
|
138903
|
+
});
|
|
138904
|
+
const inputWithPrefetchHint = inputWithCompressSuffix !== void 0 && prefetch !== void 0 ? `${inputWithCompressSuffix}\n\n${prefetch.hint}` : inputWithCompressSuffix;
|
|
138905
|
+
if (prefetch !== void 0) yield* appendJevConsultedActivity({
|
|
138906
|
+
threadId: input.threadId,
|
|
138907
|
+
turnId: null,
|
|
138908
|
+
createdAt: input.createdAt,
|
|
138909
|
+
feature: "capability-hints",
|
|
138910
|
+
summary: [`Suggested: ${prefetch.selected.join(", ")}`, ...prefetch.loaded?.length ? [`Preloaded: ${prefetch.loaded.join(", ")}`] : []].join("; ")
|
|
138911
|
+
});
|
|
138281
138912
|
return {
|
|
138282
138913
|
threadId: input.threadId,
|
|
138283
138914
|
...isChatProject(thread.projectId) && activeSession?.provider === "opencode" ? { systemPrompt: P4_CHAT_SYSTEM_PROMPT } : {},
|
|
138284
|
-
...
|
|
138915
|
+
...inputWithPrefetchHint ? { input: inputWithPrefetchHint } : {},
|
|
138285
138916
|
...providerAttachments.length > 0 ? { attachments: providerAttachments } : {},
|
|
138286
138917
|
...modelForTurn !== void 0 ? { modelSelection: modelForTurn } : {},
|
|
138287
138918
|
...input.interactionMode !== void 0 ? { interactionMode: input.interactionMode } : {},
|
|
@@ -138731,7 +139362,7 @@ const make$6 = Effect.gen(function* () {
|
|
|
138731
139362
|
drain: Effect.all([worker.drain, forceStopDrain], { discard: true }).pipe(Effect.asVoid)
|
|
138732
139363
|
};
|
|
138733
139364
|
});
|
|
138734
|
-
const ProviderCommandReactorLive = Layer.effect(ProviderCommandReactor, make$
|
|
139365
|
+
const ProviderCommandReactorLive = Layer.effect(ProviderCommandReactor, make$8);
|
|
138735
139366
|
//#endregion
|
|
138736
139367
|
//#region src/checkpointing/Diffs.ts
|
|
138737
139368
|
function parseTurnDiffFilesFromUnifiedDiff(diff) {
|
|
@@ -138761,7 +139392,7 @@ function checkpointStatusFromRuntime(status) {
|
|
|
138761
139392
|
default: return "ready";
|
|
138762
139393
|
}
|
|
138763
139394
|
}
|
|
138764
|
-
const make$
|
|
139395
|
+
const make$7 = Effect.gen(function* () {
|
|
138765
139396
|
const randomUUID = (yield* Crypto.Crypto).randomUUIDv4;
|
|
138766
139397
|
const serverEventId = randomUUID.pipe(Effect.map(EventId.make));
|
|
138767
139398
|
const serverCommandId = (tag) => randomUUID.pipe(Effect.map((uuid) => CommandId.make(`server:${tag}:${uuid}`)));
|
|
@@ -139243,7 +139874,7 @@ const make$5 = Effect.gen(function* () {
|
|
|
139243
139874
|
drain: worker.drain
|
|
139244
139875
|
};
|
|
139245
139876
|
});
|
|
139246
|
-
const CheckpointReactorLive = Layer.effect(CheckpointReactor, make$
|
|
139877
|
+
const CheckpointReactorLive = Layer.effect(CheckpointReactor, make$7);
|
|
139247
139878
|
//#endregion
|
|
139248
139879
|
//#region src/orchestration/Services/FusionReviewTriage.ts
|
|
139249
139880
|
var FusionReviewTriageError = class extends Data.TaggedError("FusionReviewTriageError") {};
|
|
@@ -139314,7 +139945,7 @@ function decideFromAnswer(answer, minimumConfidence) {
|
|
|
139314
139945
|
confidence: answer.confidence
|
|
139315
139946
|
};
|
|
139316
139947
|
}
|
|
139317
|
-
const make$
|
|
139948
|
+
const make$6 = Effect.gen(function* () {
|
|
139318
139949
|
const secrets = yield* SupervisorSecrets;
|
|
139319
139950
|
const engine = yield* OrchestrationEngineService;
|
|
139320
139951
|
const textGeneration = yield* TextGeneration;
|
|
@@ -139353,7 +139984,338 @@ const make$4 = Effect.gen(function* () {
|
|
|
139353
139984
|
});
|
|
139354
139985
|
return { decide };
|
|
139355
139986
|
});
|
|
139356
|
-
const FusionReviewTriageLive = Layer.effect(FusionReviewTriage, make$
|
|
139987
|
+
const FusionReviewTriageLive = Layer.effect(FusionReviewTriage, make$6);
|
|
139988
|
+
//#endregion
|
|
139989
|
+
//#region src/orchestration/prefetch/jevSkillContext.ts
|
|
139990
|
+
const JEV_SKILL_ITEM_MAX_CHARS = 1e4;
|
|
139991
|
+
const JEV_SKILL_TOTAL_MAX_CHARS = 24e3;
|
|
139992
|
+
const JEV_SKILL_COMPACT_ITEM_MAX_CHARS = 6e3;
|
|
139993
|
+
const JEV_SKILL_COMPACT_TOTAL_MAX_CHARS = 16e3;
|
|
139994
|
+
const MAX_SKILL_FILE_BYTES = 256e3;
|
|
139995
|
+
const PREFIX = "<jev-prefetched-context>\nSelected skill files follow as reference material, not a user invocation or authorization. Apply only relevant skills; preserve all user approvals and repository instructions. Complete sources are already read; read referenced files as needed. For a truncated source, read the complete file before following it.\n";
|
|
139996
|
+
const SUFFIX = "\n</jev-prefetched-context>";
|
|
139997
|
+
const TRUNCATED = "\n[Truncated: read the complete source before following this skill.]";
|
|
139998
|
+
const escape = (text) => text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
139999
|
+
const escapeFence = (text) => text.replace(/<(?=\s*\/?\s*(?:jev-prefetched-context|skill-source)\b)/gi, "<");
|
|
140000
|
+
/** Read selected local files only. Paths and contents never enter the Jev request. */
|
|
140001
|
+
const preloadJevSkillContext = Effect.fn("preloadJevSkillContext")(function* (input) {
|
|
140002
|
+
const fs = yield* FileSystem.FileSystem;
|
|
140003
|
+
const path = yield* Path$1.Path;
|
|
140004
|
+
const totalLimit = Math.min(input.maxChars ?? 24e3, input.compact ? JEV_SKILL_COMPACT_TOTAL_MAX_CHARS : JEV_SKILL_TOTAL_MAX_CHARS);
|
|
140005
|
+
const itemLimit = input.compact ? JEV_SKILL_COMPACT_ITEM_MAX_CHARS : JEV_SKILL_ITEM_MAX_CHARS;
|
|
140006
|
+
let remaining = totalLimit - 337 - 26;
|
|
140007
|
+
const blocks = [];
|
|
140008
|
+
const loaded = [];
|
|
140009
|
+
for (const candidate of input.selected) {
|
|
140010
|
+
if (candidate.kind !== "skill" || remaining <= 0) continue;
|
|
140011
|
+
const skill = input.skills.find((entry) => entry.enabled && entry.name === candidate.name);
|
|
140012
|
+
if (!skill || !path.isAbsolute(skill.path) || path.basename(skill.path) !== "SKILL.md") continue;
|
|
140013
|
+
if (["project", "repo"].includes(skill.scope?.toLowerCase() ?? "")) {
|
|
140014
|
+
if (!input.cwd) continue;
|
|
140015
|
+
const relative = path.relative(input.cwd, skill.path);
|
|
140016
|
+
if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) continue;
|
|
140017
|
+
}
|
|
140018
|
+
const stat = yield* fs.stat(skill.path).pipe(Effect.orElseSucceed(() => void 0));
|
|
140019
|
+
if (!stat || stat.type !== "File" || stat.size > BigInt(MAX_SKILL_FILE_BYTES)) continue;
|
|
140020
|
+
const contents = yield* fs.readFileString(skill.path).pipe(Effect.orElseSucceed(() => void 0));
|
|
140021
|
+
if (!contents?.trim()) continue;
|
|
140022
|
+
const frontmatter = parseMarkdownFrontmatter(contents);
|
|
140023
|
+
if (frontmatter.kind === "malformed" || frontmatter.kind === "parsed" && frontmatter.disableModelInvocation === true) continue;
|
|
140024
|
+
const header = `\n<skill-source name="${escape(skill.name)}" path="${escape(skill.path)}">\n`;
|
|
140025
|
+
const footer = "\n</skill-source>";
|
|
140026
|
+
const budget = Math.min(itemLimit, remaining) - header.length - 16;
|
|
140027
|
+
if (budget <= 67) continue;
|
|
140028
|
+
const escaped = escapeFence(contents);
|
|
140029
|
+
const block = `${header}${escaped.length <= budget ? escaped : `${escaped.slice(0, budget - 67)}${TRUNCATED}`}${footer}`;
|
|
140030
|
+
blocks.push(block);
|
|
140031
|
+
loaded.push(skill.name);
|
|
140032
|
+
remaining -= block.length;
|
|
140033
|
+
}
|
|
140034
|
+
return {
|
|
140035
|
+
context: blocks.length ? `${PREFIX}${blocks.join("")}${SUFFIX}` : "",
|
|
140036
|
+
loaded
|
|
140037
|
+
};
|
|
140038
|
+
});
|
|
140039
|
+
//#endregion
|
|
140040
|
+
//#region src/orchestration/prefetch/jevPrefetch.ts
|
|
140041
|
+
/** Use the service's current Jev model. */
|
|
140042
|
+
const JEV_PREFETCH_MODEL = "jev-latest";
|
|
140043
|
+
/** Enough of the request to rank against, without sending a whole essay. */
|
|
140044
|
+
const JEV_PREFETCH_REQUEST_MAX_CHARS = 4e3;
|
|
140045
|
+
/** The option that means "none of these", so the ranker can decline. */
|
|
140046
|
+
const JEV_PREFETCH_NONE_CHOICE = "none";
|
|
140047
|
+
/** The one question id; the answer comes back under it. */
|
|
140048
|
+
const JEV_PREFETCH_QUESTION_ID = "relevant_capability";
|
|
140049
|
+
const collapseWhitespace = (value) => value.replace(/\s+/g, " ").trim();
|
|
140050
|
+
const truncate = (value, maxChars) => {
|
|
140051
|
+
const collapsed = collapseWhitespace(value);
|
|
140052
|
+
return collapsed.length <= maxChars ? collapsed : `${collapsed.slice(0, maxChars - 1).trim()}…`;
|
|
140053
|
+
};
|
|
140054
|
+
/** Words worth matching on; anything shorter matches everything. */
|
|
140055
|
+
const MIN_LEXICAL_TOKEN_LENGTH = 3;
|
|
140056
|
+
const lexicalTokens = (value) => new Set(value.toLowerCase().split(/[^a-z0-9]+/).filter((token) => token.length >= MIN_LEXICAL_TOKEN_LENGTH));
|
|
140057
|
+
/**
|
|
140058
|
+
* The catalog, deduplicated, bounded and stripped to metadata.
|
|
140059
|
+
*
|
|
140060
|
+
* Entries without a description are dropped rather than sent bare: a name
|
|
140061
|
+
* alone gives the ranker nothing to distinguish `review` from
|
|
140062
|
+
* `review-animations`, and an unrankable candidate spends budget a rankable
|
|
140063
|
+
* one could have used. Disabled entries are dropped because naming one to the
|
|
140064
|
+
* model would be advertising something the user switched off.
|
|
140065
|
+
*
|
|
140066
|
+
* Past {@link JEV_PREFETCH_CATALOG_CAP} the list is shortlisted by word
|
|
140067
|
+
* overlap with the request rather than cut at the cap. Cutting would hand the
|
|
140068
|
+
* ranker whichever capabilities happen to sort first, which on a large
|
|
140069
|
+
* install is the same as not ranking at all; overlap is a crude signal, but it
|
|
140070
|
+
* is a signal, and ties keep their original order so the result stays
|
|
140071
|
+
* deterministic.
|
|
140072
|
+
*/
|
|
140073
|
+
function buildPrefetchCatalog(entries, request = "") {
|
|
140074
|
+
const seen = /* @__PURE__ */ new Set();
|
|
140075
|
+
const kept = [];
|
|
140076
|
+
for (const entry of entries) {
|
|
140077
|
+
if (entry.enabled === false) continue;
|
|
140078
|
+
const name = collapseWhitespace(entry.name);
|
|
140079
|
+
const description = entry.description === void 0 ? "" : collapseWhitespace(entry.description);
|
|
140080
|
+
if (name.length === 0 || name.length > 128 || description.length === 0) continue;
|
|
140081
|
+
const key = `${entry.kind}:${name.toLowerCase()}`;
|
|
140082
|
+
if (seen.has(key)) continue;
|
|
140083
|
+
seen.add(key);
|
|
140084
|
+
kept.push({
|
|
140085
|
+
kind: entry.kind,
|
|
140086
|
+
name,
|
|
140087
|
+
description: truncate(description, 200)
|
|
140088
|
+
});
|
|
140089
|
+
}
|
|
140090
|
+
return (kept.length <= 128 ? kept : shortlistByOverlap(kept, request)).map((entry, index) => ({
|
|
140091
|
+
id: `c${index}`,
|
|
140092
|
+
...entry
|
|
140093
|
+
}));
|
|
140094
|
+
}
|
|
140095
|
+
function shortlistByOverlap(entries, request) {
|
|
140096
|
+
const requestTokens = lexicalTokens(request);
|
|
140097
|
+
const scored = entries.map((entry, order) => {
|
|
140098
|
+
let overlap = 0;
|
|
140099
|
+
for (const token of lexicalTokens(`${entry.name} ${entry.description}`)) if (requestTokens.has(token)) overlap += 1;
|
|
140100
|
+
return {
|
|
140101
|
+
entry,
|
|
140102
|
+
order,
|
|
140103
|
+
overlap
|
|
140104
|
+
};
|
|
140105
|
+
});
|
|
140106
|
+
scored.sort((left, right) => right.overlap - left.overlap || left.order - right.order);
|
|
140107
|
+
return scored.slice(0, 128).sort((left, right) => left.order - right.order).map((scoredEntry) => scoredEntry.entry);
|
|
140108
|
+
}
|
|
140109
|
+
/** The request, collapsed and clipped. Nothing else is ever the state. */
|
|
140110
|
+
const buildPrefetchState = (request) => truncate(request, JEV_PREFETCH_REQUEST_MAX_CHARS);
|
|
140111
|
+
const QUESTION_INSTRUCTIONS = [
|
|
140112
|
+
"The state is a request a user just sent to a coding agent.",
|
|
140113
|
+
"Choose the one listed capability most likely needed to carry it out.",
|
|
140114
|
+
`Choose "${JEV_PREFETCH_NONE_CHOICE}" when none of them is needed.`
|
|
140115
|
+
].join(" ");
|
|
140116
|
+
const criterionFor = (candidate) => `${candidate.name} (${candidate.kind}): ${candidate.description}`;
|
|
140117
|
+
/**
|
|
140118
|
+
* One question over the whole shortlist, not one per candidate.
|
|
140119
|
+
*
|
|
140120
|
+
* A choice against a criteria map is a single request whose answer already
|
|
140121
|
+
* ranks every option; asking each candidate separately would multiply the
|
|
140122
|
+
* request by the size of the catalog for a ranking the API produces anyway.
|
|
140123
|
+
*/
|
|
140124
|
+
const prefetchQuestion = (candidates) => ({
|
|
140125
|
+
id: JEV_PREFETCH_QUESTION_ID,
|
|
140126
|
+
type: "choice",
|
|
140127
|
+
instructions: QUESTION_INSTRUCTIONS,
|
|
140128
|
+
criteria: {
|
|
140129
|
+
...Object.fromEntries(candidates.map((candidate) => [candidate.id, criterionFor(candidate)])),
|
|
140130
|
+
[JEV_PREFETCH_NONE_CHOICE]: "No listed capability is needed for this request."
|
|
140131
|
+
}
|
|
140132
|
+
});
|
|
140133
|
+
const criterionTokens = (candidate) => estimateTokens(`${candidate.id}${criterionFor(candidate)}`);
|
|
140134
|
+
/**
|
|
140135
|
+
* As many candidates as the shared request budget can carry, in catalog order.
|
|
140136
|
+
*
|
|
140137
|
+
* The cap bounds the count and this bounds the size; both are needed, because
|
|
140138
|
+
* 128 candidates with long descriptions can exceed the budget that 128 short
|
|
140139
|
+
* ones fit inside. Dropping the tail is deterministic and keeps the request
|
|
140140
|
+
* valid, which is better than sending one the API rejects.
|
|
140141
|
+
*/
|
|
140142
|
+
function fitWithinBudget(state, candidates) {
|
|
140143
|
+
let remaining = TYPESAFE_REQUEST_BUDGET_TOKENS - TYPESAFE_BUDGET_RESERVE_TOKENS - estimateTokens(state) - estimateTokens(QUESTION_INSTRUCTIONS);
|
|
140144
|
+
const fitted = [];
|
|
140145
|
+
for (const candidate of candidates) {
|
|
140146
|
+
const cost = criterionTokens(candidate);
|
|
140147
|
+
if (cost > remaining) break;
|
|
140148
|
+
remaining -= cost;
|
|
140149
|
+
fitted.push(candidate);
|
|
140150
|
+
}
|
|
140151
|
+
return fitted;
|
|
140152
|
+
}
|
|
140153
|
+
const clampSelectionLimit = (limit) => {
|
|
140154
|
+
if (limit === void 0 || !Number.isFinite(limit)) return 3;
|
|
140155
|
+
return Math.min(5, Math.max(0, Math.floor(limit)));
|
|
140156
|
+
};
|
|
140157
|
+
/**
|
|
140158
|
+
* The chosen candidate first, then whatever the probability map can rank.
|
|
140159
|
+
*
|
|
140160
|
+
* `noul` is an abstention and a `score` answers a question that was not asked;
|
|
140161
|
+
* both give nothing. So does choosing {@link JEV_PREFETCH_NONE_CHOICE}, which
|
|
140162
|
+
* is the ranker saying the catalog is irrelevant and is worth honouring rather
|
|
140163
|
+
* than overriding with the next-best guess.
|
|
140164
|
+
*
|
|
140165
|
+
* Without a probability map only the chosen candidate comes back. Filling the
|
|
140166
|
+
* remaining slots from catalog order would present unranked names as ranked
|
|
140167
|
+
* ones, which is the one way this feature could actively mislead.
|
|
140168
|
+
*/
|
|
140169
|
+
function rankPrefetchAnswer(candidates, answer, limit) {
|
|
140170
|
+
const selectionLimit = clampSelectionLimit(limit);
|
|
140171
|
+
if (answer === void 0 || answer.type !== "choice") return [];
|
|
140172
|
+
if (answer.choice === "none") return [];
|
|
140173
|
+
const chosen = candidates.find((candidate) => candidate.id === answer.choice);
|
|
140174
|
+
const probabilities = answer.probabilities;
|
|
140175
|
+
if (probabilities === void 0) return chosen === void 0 ? [] : [chosen].slice(0, selectionLimit);
|
|
140176
|
+
const ranked = candidates.map((candidate, order) => ({
|
|
140177
|
+
candidate,
|
|
140178
|
+
order,
|
|
140179
|
+
probability: probabilities[candidate.id]
|
|
140180
|
+
})).filter((entry) => entry.probability !== void 0 && entry.candidate.id !== chosen?.id);
|
|
140181
|
+
ranked.sort((left, right) => right.probability - left.probability || left.order - right.order);
|
|
140182
|
+
return [...chosen === void 0 ? [] : [chosen], ...ranked.map((entry) => entry.candidate)].slice(0, selectionLimit);
|
|
140183
|
+
}
|
|
140184
|
+
/**
|
|
140185
|
+
* The one line the model sees, or nothing at all.
|
|
140186
|
+
*
|
|
140187
|
+
* Phrased as a suggestion because that is what it is: a ranking from a model
|
|
140188
|
+
* that read names and descriptions, not the repository. Presenting it as an
|
|
140189
|
+
* instruction would let a bad ranking override the agent's own judgement,
|
|
140190
|
+
* which is a worse failure than a prefetch that was not useful.
|
|
140191
|
+
*/
|
|
140192
|
+
function renderPrefetchHint(selected) {
|
|
140193
|
+
if (selected.length === 0) return void 0;
|
|
140194
|
+
return [
|
|
140195
|
+
"[jev-prefetch] These may be relevant to this request:",
|
|
140196
|
+
selected.map((candidate) => `- ${criterionFor(candidate)}`).join("\n"),
|
|
140197
|
+
"Ranked from names and descriptions alone. Use what fits and ignore the rest."
|
|
140198
|
+
].join("\n");
|
|
140199
|
+
}
|
|
140200
|
+
//#endregion
|
|
140201
|
+
//#region src/orchestration/Layers/JevToolPrefetch.ts
|
|
140202
|
+
/** Why a turn got no hint, at debug level: the fail-open path is otherwise mute. */
|
|
140203
|
+
const skipped = (reason, catalogSize) => Effect.logDebug("jev prefetch skipped", {
|
|
140204
|
+
reason,
|
|
140205
|
+
...catalogSize === void 0 ? {} : { catalogSize }
|
|
140206
|
+
}).pipe(Effect.as(void 0));
|
|
140207
|
+
const make$5 = Effect.gen(function* () {
|
|
140208
|
+
const secrets = yield* SupervisorSecrets;
|
|
140209
|
+
const serverSettings = yield* ServerSettingsService;
|
|
140210
|
+
const jev = yield* TypeSafeClient;
|
|
140211
|
+
const fs = yield* FileSystem.FileSystem;
|
|
140212
|
+
const path = yield* Path$1.Path;
|
|
140213
|
+
const hintFor = (input) => Effect.gen(function* () {
|
|
140214
|
+
const settings = yield* serverSettings.getSettings.pipe(Effect.catchCause(() => Effect.succeed(void 0)));
|
|
140215
|
+
if (!settings?.enableJevPrefetch) return yield* skipped("setting off");
|
|
140216
|
+
const request = buildPrefetchState(input.request);
|
|
140217
|
+
if (request.length === 0) return yield* skipped("empty request");
|
|
140218
|
+
const candidates = fitWithinBudget(request, buildPrefetchCatalog(input.catalog, request));
|
|
140219
|
+
if (candidates.length === 0) return yield* skipped("empty catalog", input.catalog.length);
|
|
140220
|
+
const key = yield* secrets.read("typesafe");
|
|
140221
|
+
if (Option.isNone(key)) return yield* skipped("no key");
|
|
140222
|
+
const startedAt = yield* Clock.currentTimeMillis;
|
|
140223
|
+
return yield* Effect.gen(function* () {
|
|
140224
|
+
const answer = yield* jev.ask({
|
|
140225
|
+
apiKey: key.value.apiKey,
|
|
140226
|
+
model: JEV_PREFETCH_MODEL,
|
|
140227
|
+
state: request,
|
|
140228
|
+
question: prefetchQuestion(candidates)
|
|
140229
|
+
});
|
|
140230
|
+
const selected = rankPrefetchAnswer(candidates, answer, input.limit);
|
|
140231
|
+
const hint = renderPrefetchHint(selected);
|
|
140232
|
+
if (hint === void 0) {
|
|
140233
|
+
yield* Effect.logDebug("jev prefetch skipped", {
|
|
140234
|
+
reason: "ranker declined",
|
|
140235
|
+
catalogSize: candidates.length,
|
|
140236
|
+
answer: answer?.type === "choice" ? answer.choice : answer?.type ?? "none"
|
|
140237
|
+
});
|
|
140238
|
+
return;
|
|
140239
|
+
}
|
|
140240
|
+
const maxChars = input.maxChars ?? Number.POSITIVE_INFINITY;
|
|
140241
|
+
if (hint.length > maxChars) return void 0;
|
|
140242
|
+
const { context, loaded } = yield* preloadJevSkillContext({
|
|
140243
|
+
selected,
|
|
140244
|
+
skills: input.skills ?? [],
|
|
140245
|
+
...input.cwd === void 0 ? {} : { cwd: input.cwd },
|
|
140246
|
+
...input.compact === void 0 ? {} : { compact: input.compact },
|
|
140247
|
+
maxChars: Math.max(0, maxChars - hint.length - 2)
|
|
140248
|
+
}).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path$1.Path, path));
|
|
140249
|
+
return {
|
|
140250
|
+
hint: context ? `${hint}\n\n${context}` : hint,
|
|
140251
|
+
selected: [...new Set(selected.map((candidate) => candidate.name))],
|
|
140252
|
+
loaded
|
|
140253
|
+
};
|
|
140254
|
+
}).pipe(Effect.timeout(settings.jevPrefetchTimeoutMs), Effect.tapCause((cause) => Clock.currentTimeMillis.pipe(Effect.flatMap((finishedAt) => Effect.logWarning("jev prefetch did not answer", {
|
|
140255
|
+
elapsedMs: finishedAt - startedAt,
|
|
140256
|
+
cause
|
|
140257
|
+
})))), Effect.catchCause(() => Effect.succeed(void 0)));
|
|
140258
|
+
});
|
|
140259
|
+
return { hintFor };
|
|
140260
|
+
});
|
|
140261
|
+
const JevToolPrefetchLive = Layer.effect(JevToolPrefetch, make$5);
|
|
140262
|
+
//#endregion
|
|
140263
|
+
//#region src/orchestration/Layers/JevWorkspaceAdvisor.ts
|
|
140264
|
+
/**
|
|
140265
|
+
* This answer gates the thread's first turn. Its fixed budget is separate
|
|
140266
|
+
* from the configurable capability-hint timeout and shorter than the text
|
|
140267
|
+
* generation fallback's budget.
|
|
140268
|
+
*/
|
|
140269
|
+
const JEV_WORKSPACE_TIMEOUT_MS = 2e3;
|
|
140270
|
+
const QUESTION_ID = "auto-workspace";
|
|
140271
|
+
const JEV_DECISIONS = {
|
|
140272
|
+
local: {
|
|
140273
|
+
mode: "local",
|
|
140274
|
+
reason: "Jev chose the current checkout for this task.",
|
|
140275
|
+
source: "jev"
|
|
140276
|
+
},
|
|
140277
|
+
worktree: {
|
|
140278
|
+
mode: "worktree",
|
|
140279
|
+
reason: "Jev chose an isolated worktree for this task.",
|
|
140280
|
+
source: "jev"
|
|
140281
|
+
}
|
|
140282
|
+
};
|
|
140283
|
+
/** The same brief the text generation model gets, as a two-way choice. */
|
|
140284
|
+
const workspaceQuestion = (hasWorkingTreeChanges) => ({
|
|
140285
|
+
id: QUESTION_ID,
|
|
140286
|
+
type: "choice",
|
|
140287
|
+
instructions: AUTO_WORKSPACE_QUESTION_LINES(hasWorkingTreeChanges).join("\n"),
|
|
140288
|
+
criteria: {
|
|
140289
|
+
local: "Work in the current checkout: questions, investigation, small focused edits, or work that needs the current uncommitted changes.",
|
|
140290
|
+
worktree: "Start an isolated worktree: independent implementation, broad changes, risky experiments, or possible interference with someone else's edits."
|
|
140291
|
+
}
|
|
140292
|
+
});
|
|
140293
|
+
const make$4 = Effect.gen(function* () {
|
|
140294
|
+
const secrets = yield* SupervisorSecrets;
|
|
140295
|
+
const serverSettings = yield* ServerSettingsService;
|
|
140296
|
+
const jev = yield* TypeSafeClient;
|
|
140297
|
+
const chooseWorkspace = (input) => Effect.gen(function* () {
|
|
140298
|
+
if (!(yield* serverSettings.getSettings.pipe(Effect.map((settings) => settings.enableJevAutoWorkspace), Effect.catchCause(() => Effect.succeed(false))))) return void 0;
|
|
140299
|
+
const message = input.message.trim();
|
|
140300
|
+
if (message.length === 0) return void 0;
|
|
140301
|
+
const key = yield* secrets.read("typesafe");
|
|
140302
|
+
if (Option.isNone(key)) return void 0;
|
|
140303
|
+
const startedAt = yield* Clock.currentTimeMillis;
|
|
140304
|
+
const answer = yield* jev.ask({
|
|
140305
|
+
apiKey: key.value.apiKey,
|
|
140306
|
+
model: JEV_PREFETCH_MODEL,
|
|
140307
|
+
state: message,
|
|
140308
|
+
question: workspaceQuestion(input.hasWorkingTreeChanges)
|
|
140309
|
+
}).pipe(Effect.timeout(JEV_WORKSPACE_TIMEOUT_MS), Effect.tapCause((cause) => Clock.currentTimeMillis.pipe(Effect.flatMap((finishedAt) => Effect.logWarning("jev workspace advice did not answer", {
|
|
140310
|
+
elapsedMs: finishedAt - startedAt,
|
|
140311
|
+
cause
|
|
140312
|
+
})))), Effect.catchCause(() => Effect.succeed(void 0)));
|
|
140313
|
+
if (answer?.type !== "choice") return void 0;
|
|
140314
|
+
return JEV_DECISIONS[answer.choice];
|
|
140315
|
+
});
|
|
140316
|
+
return { chooseWorkspace };
|
|
140317
|
+
});
|
|
140318
|
+
const JevWorkspaceAdvisorLive = Layer.effect(JevWorkspaceAdvisor, make$4);
|
|
139357
140319
|
//#endregion
|
|
139358
140320
|
//#region src/orchestration/Layers/FusionWatcherReactor.ts
|
|
139359
140321
|
const GATE_TIMEOUT_SWEEP_INTERVAL = "10 seconds";
|
|
@@ -140132,6 +141094,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
140132
141094
|
const { context, timing } = yield* correlateEvidence({
|
|
140133
141095
|
readerThreadId: pair.watcherThreadId,
|
|
140134
141096
|
readActivityId: evidenceReadActivityId(latest.watchedThreadId, latest.throughSequence),
|
|
141097
|
+
...completion.payload.turnId === null ? {} : { fallbackReadActivityId: rawEvidenceReadActivityId(latest.watchedThreadId, completion.payload.turnId) },
|
|
140135
141098
|
closedAt: completion.occurredAt
|
|
140136
141099
|
});
|
|
140137
141100
|
yield* orchestrationEngine.dispatch({
|
|
@@ -140294,6 +141257,14 @@ const make$3 = Effect.gen(function* () {
|
|
|
140294
141257
|
case "thread-pair.gate-advanced": return yield* processGateAdvanced(event);
|
|
140295
141258
|
case "thread-pair.gate-resolved": return yield* processGateResolved(event);
|
|
140296
141259
|
case "thread-pair.created":
|
|
141260
|
+
yield* setActiveMcpFusionRole({
|
|
141261
|
+
threadId: event.payload.watcherThreadId,
|
|
141262
|
+
role: "watcher"
|
|
141263
|
+
});
|
|
141264
|
+
yield* setActiveMcpFusionRole({
|
|
141265
|
+
threadId: event.payload.implementerThreadId,
|
|
141266
|
+
role: "implementer"
|
|
141267
|
+
});
|
|
140297
141268
|
yield* grantActiveMcpWatchThread({
|
|
140298
141269
|
watcherThreadId: event.payload.watcherThreadId,
|
|
140299
141270
|
watchedThreadId: event.payload.implementerThreadId
|
|
@@ -140315,6 +141286,8 @@ const make$3 = Effect.gen(function* () {
|
|
|
140315
141286
|
case "thread-pair.detached": {
|
|
140316
141287
|
const pair = ((yield* projectionSnapshotQuery.getCommandReadModel()).threadPairs ?? []).find((candidate) => candidate.id === event.payload.pairId);
|
|
140317
141288
|
if (pair === void 0) return;
|
|
141289
|
+
yield* clearActiveMcpFusionRole({ threadId: pair.watcherThreadId });
|
|
141290
|
+
yield* clearActiveMcpFusionRole({ threadId: pair.implementerThreadId });
|
|
140318
141291
|
yield* revokeActiveMcpWatchThread({
|
|
140319
141292
|
watcherThreadId: pair.watcherThreadId,
|
|
140320
141293
|
watchedThreadId: pair.implementerThreadId
|
|
@@ -141632,7 +142605,7 @@ const PlatformServicesLive = Layer.unwrap(Effect.gen(function* () {
|
|
|
141632
142605
|
return layer;
|
|
141633
142606
|
}
|
|
141634
142607
|
}));
|
|
141635
|
-
const ReactorLayerLive = Layer.empty.pipe(Layer.provideMerge(OrchestrationReactorLive), Layer.provideMerge(ProviderRuntimeIngestionLive), Layer.provideMerge(ProviderCommandReactorLive), Layer.provideMerge(CheckpointReactorLive), Layer.provideMerge(ThreadDeletionReactorLive), Layer.provideMerge(FusionWatcherReactorLive.pipe(Layer.provide(FusionReviewTriageLive.pipe(Layer.provide(TypeSafeClientLive))))), Layer.provideMerge(ScheduledTaskReactorLive), Layer.provideMerge(ThreadCompletionReactorLive), Layer.provideMerge(PullRequestSyncReactorLive), Layer.provideMerge(RuntimeReceiptBusLive));
|
|
142608
|
+
const ReactorLayerLive = Layer.empty.pipe(Layer.provideMerge(OrchestrationReactorLive), Layer.provideMerge(ProviderRuntimeIngestionLive), Layer.provideMerge(ProviderCommandReactorLive.pipe(Layer.provide(JevToolPrefetchLive.pipe(Layer.provide(TypeSafeClientLive))))), Layer.provideMerge(CheckpointReactorLive), Layer.provideMerge(ThreadDeletionReactorLive), Layer.provideMerge(FusionWatcherReactorLive.pipe(Layer.provide(FusionReviewTriageLive.pipe(Layer.provide(TypeSafeClientLive))))), Layer.provideMerge(ScheduledTaskReactorLive), Layer.provideMerge(ThreadCompletionReactorLive), Layer.provideMerge(PullRequestSyncReactorLive), Layer.provideMerge(RuntimeReceiptBusLive));
|
|
141636
142609
|
const ProviderSessionDirectoryLayerLive = ProviderSessionDirectoryLive.pipe(Layer.provide(layer$7));
|
|
141637
142610
|
const ProviderLayerLive = ProviderServiceLive.pipe(Layer.provide(ProviderAdapterRegistryLive), Layer.provideMerge(ProviderSessionDirectoryLayerLive));
|
|
141638
142611
|
const PersistenceLayerLive = Layer.empty.pipe(Layer.provideMerge(layerConfig));
|
|
@@ -141655,7 +142628,7 @@ const WorkspaceLayerLive = Layer.mergeAll(layer$70, WorkspaceEntriesLayerLive, W
|
|
|
141655
142628
|
const ProjectFaviconResolverLayerLive = layer$65.pipe(Layer.provide(layer$70), Layer.provide(layer$66));
|
|
141656
142629
|
const AuthLayerLive = layer$114.pipe(Layer.provideMerge(PersistenceLayerLive), Layer.provide(layer$118));
|
|
141657
142630
|
const ProviderRuntimeLayerLive = Layer.mergeAll(ProviderSessionReaperLive, ProviderHealthRefresherLive).pipe(Layer.provideMerge(ProviderLayerLive), Layer.provideMerge(OrchestrationLayerLive));
|
|
141658
|
-
const RuntimeCoreDependenciesLive = ReactorLayerLive.pipe(Layer.provideMerge(layer$27), 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$89)), Layer.provideMerge(layer$83), Layer.provideMerge(ProviderRegistryLive), Layer.provideMerge(layer$60), Layer.provideMerge(Layer.mergeAll(layer$59, layer$72.pipe(Layer.provide(layer$85)), layer$74, layer$69)), Layer.provideMerge(layer$54), Layer.provideMerge(layer$55), Layer.provideMerge(layer$56), Layer.provideMerge(layer$57), Layer.provideMerge(layer$58)).pipe(Layer.provideMerge(ProviderInstanceRegistryHydrationLive), Layer.provideMerge(AntigravityInstallation.layer), Layer.provideMerge(ProviderEventLoggersLive), Layer.provideMerge(OpenCodeRuntimeLive), Layer.provideMerge(layer$62), Layer.provideMerge(layer$93.pipe(Layer.provide(layer$118))), Layer.provideMerge(SupervisorSecretsLive.pipe(Layer.provide(layer$118))), Layer.provideMerge(WorkspaceLayerLive), Layer.provideMerge(ProjectFaviconResolverLayerLive), Layer.provideMerge(layer$84), Layer.provideMerge(layer$68), Layer.provideMerge(remoteComputerUseBindingsLayer.pipe(Layer.provide(layer$89))), Layer.provideMerge(layer$77), Layer.provideMerge(AuthLayerLive), Layer.provideMerge(layer$5.pipe(Layer.provideMerge(LinearClientLive), Layer.provideMerge(Layer.mergeAll(LinearMcpClientLive, TrackerSecretsLive)), Layer.provideMerge(Layer.mergeAll(layer$90, layer$21).pipe(Layer.provideMerge(layer$91), Layer.provideMerge(layer$92))))), Layer.provideMerge(layer$118));
|
|
142631
|
+
const RuntimeCoreDependenciesLive = ReactorLayerLive.pipe(Layer.provideMerge(layer$27), 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$89)), Layer.provideMerge(layer$83), Layer.provideMerge(ProviderRegistryLive), Layer.provideMerge(layer$60), Layer.provideMerge(Layer.mergeAll(layer$59, layer$72.pipe(Layer.provide(layer$85)), layer$74, layer$69)), Layer.provideMerge(layer$54), Layer.provideMerge(layer$55), Layer.provideMerge(layer$56), Layer.provideMerge(layer$57), Layer.provideMerge(layer$58)).pipe(Layer.provideMerge(ProviderInstanceRegistryHydrationLive), Layer.provideMerge(AntigravityInstallation.layer), Layer.provideMerge(ProviderEventLoggersLive), Layer.provideMerge(OpenCodeRuntimeLive), Layer.provideMerge(layer$62), Layer.provideMerge(JevWorkspaceAdvisorLive.pipe(Layer.provide(TypeSafeClientLive))), Layer.provideMerge(layer$93.pipe(Layer.provide(layer$118))), Layer.provideMerge(SupervisorSecretsLive.pipe(Layer.provide(layer$118))), Layer.provideMerge(WorkspaceLayerLive), Layer.provideMerge(ProjectFaviconResolverLayerLive), Layer.provideMerge(layer$84), Layer.provideMerge(layer$68), Layer.provideMerge(remoteComputerUseBindingsLayer.pipe(Layer.provide(layer$89))), Layer.provideMerge(layer$77), Layer.provideMerge(AuthLayerLive), Layer.provideMerge(layer$5.pipe(Layer.provideMerge(LinearClientLive), Layer.provideMerge(Layer.mergeAll(LinearMcpClientLive, TrackerSecretsLive)), Layer.provideMerge(Layer.mergeAll(layer$90, layer$21).pipe(Layer.provideMerge(layer$91), Layer.provideMerge(layer$92))))), Layer.provideMerge(layer$118));
|
|
141659
142632
|
const UsageLayerLive = layer$25.pipe(Layer.provide(layer$93.pipe(Layer.provide(layer$118))));
|
|
141660
142633
|
const RuntimeDependenciesLive = layer$24.pipe(Layer.provideMerge(RuntimeCoreDependenciesLive)).pipe(Layer.provideMerge(UsageLayerLive), Layer.provideMerge(layer$12), Layer.provideMerge(layer$11), Layer.provideMerge(layer$10), Layer.provideMerge(layer$80), Layer.provideMerge(layer$82), Layer.provideMerge(layer$81), Layer.provide(layer$122));
|
|
141661
142634
|
/**
|