@p4code/cli 0.3.24 → 0.3.26
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 +1701 -626
- package/dist/client/assets/DiffPanel-Cp9ZchPD.js +98 -0
- package/dist/client/assets/{FilePreviewPanel-Bb9aC93M.js → FilePreviewPanel-BSEYlFH_.js} +12 -12
- package/dist/client/assets/PreviewPanel-D9gIr3nZ.js +2 -0
- package/dist/client/assets/PullRequestCodeTab-DREOEFKL.js +251 -0
- package/dist/client/assets/{fileCommentAnnotations-CHfu1OPg.js → fileCommentAnnotations-DktOAoZq.js} +2 -2
- package/dist/client/assets/index-DQk2JhL0.js +2682 -0
- package/dist/client/assets/previewAssetResource-xr2rxKjm.js +48 -0
- package/dist/client/assets/{renderFileChildren-Mulim_7t.js → renderFileChildren-C8xF9yZB.js} +2 -2
- package/dist/client/assets/{toggle-group-BUlsuw8Z.js → toggle-group-oAiXdJRV.js} +2 -2
- package/dist/client/index.html +2 -2
- package/package.json +1 -1
- package/dist/client/assets/DiffPanel-DagtjUZ5.js +0 -98
- package/dist/client/assets/PreviewPanel-DXutrGSC.js +0 -2
- package/dist/client/assets/PullRequestCodeTab-Ds2BAp6r.js +0 -251
- package/dist/client/assets/index-fMAeFrHc.js +0 -2669
- package/dist/client/assets/previewAssetResource-DvTqD816.js +0 -48
package/dist/bin.mjs
CHANGED
|
@@ -127,7 +127,7 @@ const closeServer = (server) => {
|
|
|
127
127
|
* NetService - Service tag for startup networking helpers.
|
|
128
128
|
*/
|
|
129
129
|
var NetService = class extends Context.Service()("@p4code/shared/Net/NetService") {};
|
|
130
|
-
const make$
|
|
130
|
+
const make$92 = () => {
|
|
131
131
|
/**
|
|
132
132
|
* Returns true when a TCP server can bind to {host, port}.
|
|
133
133
|
* `EADDRNOTAVAIL` is treated as available so IPv6-absent hosts don't fail
|
|
@@ -236,10 +236,10 @@ const make$91 = () => {
|
|
|
236
236
|
})
|
|
237
237
|
};
|
|
238
238
|
};
|
|
239
|
-
const layer$82 = Layer.sync(NetService, make$
|
|
239
|
+
const layer$82 = Layer.sync(NetService, make$92);
|
|
240
240
|
//#endregion
|
|
241
241
|
//#region package.json
|
|
242
|
-
var version = "0.3.
|
|
242
|
+
var version = "0.3.26";
|
|
243
243
|
//#endregion
|
|
244
244
|
//#region src/config.ts
|
|
245
245
|
/**
|
|
@@ -260,8 +260,8 @@ var ServerConfig$1 = class extends Context.Service()("@p4code/cli/config/ServerC
|
|
|
260
260
|
/** @deprecated Import and use `layerTest` from this module. */
|
|
261
261
|
static layerTest = (cwd, baseDirOrPrefix) => layerTest$3(cwd, baseDirOrPrefix);
|
|
262
262
|
};
|
|
263
|
-
const make$
|
|
264
|
-
const layer$81 = (config) => Layer.succeed(ServerConfig$1, make$
|
|
263
|
+
const make$91 = (config) => ServerConfig$1.of(config);
|
|
264
|
+
const layer$81 = (config) => Layer.succeed(ServerConfig$1, make$91(config));
|
|
265
265
|
const deriveServerPaths = Effect.fn(function* (baseDir, devUrl, options = {}) {
|
|
266
266
|
const { join } = yield* Path.Path;
|
|
267
267
|
const stateDir = join(baseDir, devUrl !== void 0 && !options.baseDirIsExplicit ? "dev" : "userdata");
|
|
@@ -1333,6 +1333,12 @@ const ExecutionEnvironmentCapabilities = Schema$1.Struct({
|
|
|
1333
1333
|
/** Server understands thread.pin / thread.unpin / thread.pin.reorder
|
|
1334
1334
|
commands. Same version-skew contract as threadSettlement. */
|
|
1335
1335
|
threadPinning: Schema$1.optionalKey(Schema$1.Boolean),
|
|
1336
|
+
/** Server understands the thread.fork command. Same version-skew contract
|
|
1337
|
+
as threadSettlement. */
|
|
1338
|
+
threadFork: Schema$1.optionalKey(Schema$1.Boolean),
|
|
1339
|
+
/** Server understands thread.scheduled-task.create / cancel and fires
|
|
1340
|
+
pending tasks. Same version-skew contract as threadSettlement. */
|
|
1341
|
+
threadScheduledTasks: Schema$1.optionalKey(Schema$1.Boolean),
|
|
1336
1342
|
/** Server exposes the pull-request list, detail, activity, diff, and mutation APIs. Absent on
|
|
1337
1343
|
servers from before the pull-request workspace shipped, so clients must not probe them. */
|
|
1338
1344
|
pullRequests: Schema$1.optionalKey(Schema$1.Boolean),
|
|
@@ -1595,7 +1601,7 @@ const PREFERRED_DEFAULT_CODEX_MODELS = ["gpt-5.6-sol", "gpt-5.6-terra"];
|
|
|
1595
1601
|
const DEFAULT_TEXT_GENERATION_MODEL = "gpt-5.6-luna";
|
|
1596
1602
|
const DEFAULT_MODEL_BY_PROVIDER = {
|
|
1597
1603
|
[CODEX_DRIVER_KIND]: DEFAULT_MODEL,
|
|
1598
|
-
[CLAUDE_DRIVER_KIND]: "claude-
|
|
1604
|
+
[CLAUDE_DRIVER_KIND]: "claude-fable-5-1",
|
|
1599
1605
|
[CURSOR_DRIVER_KIND]: "auto",
|
|
1600
1606
|
[GROK_DRIVER_KIND$1]: "grok-build",
|
|
1601
1607
|
[MUSE_DRIVER_KIND]: "muse-spark-1.2",
|
|
@@ -1877,6 +1883,31 @@ const OrchestrationProposedPlan = Schema$1.Struct({
|
|
|
1877
1883
|
createdAt: IsoDateTime,
|
|
1878
1884
|
updatedAt: IsoDateTime
|
|
1879
1885
|
});
|
|
1886
|
+
const OrchestrationScheduledTaskId = TrimmedNonEmptyString;
|
|
1887
|
+
const OrchestrationScheduledTaskStatus = Schema$1.Literals([
|
|
1888
|
+
"pending",
|
|
1889
|
+
"fired",
|
|
1890
|
+
"failed",
|
|
1891
|
+
"cancelled"
|
|
1892
|
+
]);
|
|
1893
|
+
/**
|
|
1894
|
+
* A prompt the server sends to a thread at a chosen time. Pending tasks are
|
|
1895
|
+
* the live ones: firing starts a turn with `prompt`, cancelling is the way
|
|
1896
|
+
* out before that. A task whose turn could not start after bounded retries
|
|
1897
|
+
* ends `failed` with `failure` explaining why; it can be dismissed or
|
|
1898
|
+
* scheduled again from the client.
|
|
1899
|
+
*/
|
|
1900
|
+
const OrchestrationScheduledTask = Schema$1.Struct({
|
|
1901
|
+
id: OrchestrationScheduledTaskId,
|
|
1902
|
+
prompt: TrimmedNonEmptyString,
|
|
1903
|
+
runAt: IsoDateTime,
|
|
1904
|
+
status: OrchestrationScheduledTaskStatus,
|
|
1905
|
+
createdAt: IsoDateTime,
|
|
1906
|
+
updatedAt: IsoDateTime,
|
|
1907
|
+
firedAt: Schema$1.NullOr(IsoDateTime).pipe(Schema$1.withDecodingDefault(Effect.succeed(null))),
|
|
1908
|
+
cancelledAt: Schema$1.NullOr(IsoDateTime).pipe(Schema$1.withDecodingDefault(Effect.succeed(null))),
|
|
1909
|
+
failure: Schema$1.NullOr(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed(null)))
|
|
1910
|
+
});
|
|
1880
1911
|
const SourceProposedPlanReference = Schema$1.Struct({
|
|
1881
1912
|
threadId: ThreadId,
|
|
1882
1913
|
planId: OrchestrationProposedPlanId
|
|
@@ -1996,6 +2027,7 @@ const OrchestrationThread = Schema$1.Struct({
|
|
|
1996
2027
|
deletedAt: Schema$1.NullOr(IsoDateTime),
|
|
1997
2028
|
messages: Schema$1.Array(OrchestrationMessage),
|
|
1998
2029
|
proposedPlans: Schema$1.Array(OrchestrationProposedPlan).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
2030
|
+
scheduledTasks: Schema$1.optional(Schema$1.Array(OrchestrationScheduledTask)),
|
|
1999
2031
|
activities: Schema$1.Array(OrchestrationThreadActivity),
|
|
2000
2032
|
checkpoints: Schema$1.Array(OrchestrationCheckpointSummary),
|
|
2001
2033
|
session: Schema$1.NullOr(OrchestrationSession)
|
|
@@ -2266,6 +2298,44 @@ const ThreadCreateCommand = Schema$1.Struct({
|
|
|
2266
2298
|
worktreePath: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2267
2299
|
createdAt: IsoDateTime
|
|
2268
2300
|
});
|
|
2301
|
+
/**
|
|
2302
|
+
* Creates a new thread from an existing one. The decider copies the source
|
|
2303
|
+
* thread's configuration and the projections copy its conversation, so the
|
|
2304
|
+
* fork opens with the same context while the source stays untouched.
|
|
2305
|
+
*/
|
|
2306
|
+
const ThreadForkCommand = Schema$1.Struct({
|
|
2307
|
+
type: Schema$1.Literal("thread.fork"),
|
|
2308
|
+
commandId: CommandId,
|
|
2309
|
+
sourceThreadId: ThreadId,
|
|
2310
|
+
threadId: ThreadId,
|
|
2311
|
+
title: Schema$1.optional(TrimmedNonEmptyString),
|
|
2312
|
+
createdAt: IsoDateTime
|
|
2313
|
+
});
|
|
2314
|
+
const ThreadScheduledTaskCreateCommand = Schema$1.Struct({
|
|
2315
|
+
type: Schema$1.Literal("thread.scheduled-task.create"),
|
|
2316
|
+
commandId: CommandId,
|
|
2317
|
+
threadId: ThreadId,
|
|
2318
|
+
taskId: OrchestrationScheduledTaskId,
|
|
2319
|
+
prompt: TrimmedNonEmptyString,
|
|
2320
|
+
runAt: IsoDateTime,
|
|
2321
|
+
createdAt: IsoDateTime
|
|
2322
|
+
});
|
|
2323
|
+
const ThreadScheduledTaskCancelCommand = Schema$1.Struct({
|
|
2324
|
+
type: Schema$1.Literal("thread.scheduled-task.cancel"),
|
|
2325
|
+
commandId: CommandId,
|
|
2326
|
+
threadId: ThreadId,
|
|
2327
|
+
taskId: OrchestrationScheduledTaskId,
|
|
2328
|
+
cancelledAt: IsoDateTime
|
|
2329
|
+
});
|
|
2330
|
+
/** Server-only: records that the scheduler fired (or failed to fire) a task. */
|
|
2331
|
+
const ThreadScheduledTaskFireCommand = Schema$1.Struct({
|
|
2332
|
+
type: Schema$1.Literal("thread.scheduled-task.fire"),
|
|
2333
|
+
commandId: CommandId,
|
|
2334
|
+
threadId: ThreadId,
|
|
2335
|
+
taskId: OrchestrationScheduledTaskId,
|
|
2336
|
+
firedAt: IsoDateTime,
|
|
2337
|
+
failure: Schema$1.optional(Schema$1.String)
|
|
2338
|
+
});
|
|
2269
2339
|
const ThreadDeleteCommand = Schema$1.Struct({
|
|
2270
2340
|
type: Schema$1.Literal("thread.delete"),
|
|
2271
2341
|
commandId: CommandId,
|
|
@@ -2513,6 +2583,9 @@ const DispatchableClientOrchestrationCommand = Schema$1.Union([
|
|
|
2513
2583
|
ProjectMetaUpdateCommand,
|
|
2514
2584
|
ProjectDeleteCommand,
|
|
2515
2585
|
ThreadCreateCommand,
|
|
2586
|
+
ThreadForkCommand,
|
|
2587
|
+
ThreadScheduledTaskCreateCommand,
|
|
2588
|
+
ThreadScheduledTaskCancelCommand,
|
|
2516
2589
|
ThreadDeleteCommand,
|
|
2517
2590
|
ThreadArchiveCommand,
|
|
2518
2591
|
ThreadUnarchiveCommand,
|
|
@@ -2544,6 +2617,9 @@ const ClientOrchestrationCommand = Schema$1.Union([
|
|
|
2544
2617
|
ProjectMetaUpdateCommand,
|
|
2545
2618
|
ProjectDeleteCommand,
|
|
2546
2619
|
ThreadCreateCommand,
|
|
2620
|
+
ThreadForkCommand,
|
|
2621
|
+
ThreadScheduledTaskCreateCommand,
|
|
2622
|
+
ThreadScheduledTaskCancelCommand,
|
|
2547
2623
|
ThreadDeleteCommand,
|
|
2548
2624
|
ThreadArchiveCommand,
|
|
2549
2625
|
ThreadUnarchiveCommand,
|
|
@@ -2698,7 +2774,8 @@ const InternalOrchestrationCommand = Schema$1.Union([
|
|
|
2698
2774
|
ThreadProposedPlanUpsertCommand,
|
|
2699
2775
|
ThreadTurnDiffCompleteCommand,
|
|
2700
2776
|
ThreadActivityAppendCommand,
|
|
2701
|
-
ThreadRevertCompleteCommand
|
|
2777
|
+
ThreadRevertCompleteCommand,
|
|
2778
|
+
ThreadScheduledTaskFireCommand
|
|
2702
2779
|
]);
|
|
2703
2780
|
Schema$1.Union([DispatchableClientOrchestrationCommand, InternalOrchestrationCommand]);
|
|
2704
2781
|
const OrchestrationEventType = Schema$1.Literals([
|
|
@@ -2732,6 +2809,9 @@ const OrchestrationEventType = Schema$1.Literals([
|
|
|
2732
2809
|
"thread.session-force-stop-requested",
|
|
2733
2810
|
"thread.session-set",
|
|
2734
2811
|
"thread.proposed-plan-upserted",
|
|
2812
|
+
"thread.scheduled-task.created",
|
|
2813
|
+
"thread.scheduled-task.cancelled",
|
|
2814
|
+
"thread.scheduled-task.fired",
|
|
2735
2815
|
"thread.turn-diff-completed",
|
|
2736
2816
|
"thread.activity-appended",
|
|
2737
2817
|
"thread.turn-completed",
|
|
@@ -2786,6 +2866,11 @@ const ThreadCreatedPayload$1 = Schema$1.Struct({
|
|
|
2786
2866
|
unpromptedSubagents: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(true))),
|
|
2787
2867
|
branch: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2788
2868
|
worktreePath: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2869
|
+
/**
|
|
2870
|
+
* Set when the thread was forked: projections copy the source thread's
|
|
2871
|
+
* messages into this one. Optional so events from pre-fork servers decode.
|
|
2872
|
+
*/
|
|
2873
|
+
forkedFromThreadId: Schema$1.optional(ThreadId),
|
|
2789
2874
|
createdAt: IsoDateTime,
|
|
2790
2875
|
updatedAt: IsoDateTime
|
|
2791
2876
|
});
|
|
@@ -2998,6 +3083,21 @@ const ThreadProposedPlanUpsertedPayload$1 = Schema$1.Struct({
|
|
|
2998
3083
|
threadId: ThreadId,
|
|
2999
3084
|
proposedPlan: OrchestrationProposedPlan
|
|
3000
3085
|
});
|
|
3086
|
+
const ThreadScheduledTaskCreatedPayload$1 = Schema$1.Struct({
|
|
3087
|
+
threadId: ThreadId,
|
|
3088
|
+
task: OrchestrationScheduledTask
|
|
3089
|
+
});
|
|
3090
|
+
const ThreadScheduledTaskCancelledPayload$1 = Schema$1.Struct({
|
|
3091
|
+
threadId: ThreadId,
|
|
3092
|
+
taskId: OrchestrationScheduledTaskId,
|
|
3093
|
+
cancelledAt: IsoDateTime
|
|
3094
|
+
});
|
|
3095
|
+
const ThreadScheduledTaskFiredPayload$1 = Schema$1.Struct({
|
|
3096
|
+
threadId: ThreadId,
|
|
3097
|
+
taskId: OrchestrationScheduledTaskId,
|
|
3098
|
+
firedAt: IsoDateTime,
|
|
3099
|
+
failure: Schema$1.NullOr(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed(null)))
|
|
3100
|
+
});
|
|
3001
3101
|
const ThreadTurnDiffCompletedPayload$1 = Schema$1.Struct({
|
|
3002
3102
|
threadId: ThreadId,
|
|
3003
3103
|
turnId: TurnId,
|
|
@@ -3185,6 +3285,21 @@ const OrchestrationEvent = Schema$1.Union([
|
|
|
3185
3285
|
type: Schema$1.Literal("thread.proposed-plan-upserted"),
|
|
3186
3286
|
payload: ThreadProposedPlanUpsertedPayload$1
|
|
3187
3287
|
}),
|
|
3288
|
+
Schema$1.Struct({
|
|
3289
|
+
...EventBaseFields,
|
|
3290
|
+
type: Schema$1.Literal("thread.scheduled-task.created"),
|
|
3291
|
+
payload: ThreadScheduledTaskCreatedPayload$1
|
|
3292
|
+
}),
|
|
3293
|
+
Schema$1.Struct({
|
|
3294
|
+
...EventBaseFields,
|
|
3295
|
+
type: Schema$1.Literal("thread.scheduled-task.cancelled"),
|
|
3296
|
+
payload: ThreadScheduledTaskCancelledPayload$1
|
|
3297
|
+
}),
|
|
3298
|
+
Schema$1.Struct({
|
|
3299
|
+
...EventBaseFields,
|
|
3300
|
+
type: Schema$1.Literal("thread.scheduled-task.fired"),
|
|
3301
|
+
payload: ThreadScheduledTaskFiredPayload$1
|
|
3302
|
+
}),
|
|
3188
3303
|
Schema$1.Struct({
|
|
3189
3304
|
...EventBaseFields,
|
|
3190
3305
|
type: Schema$1.Literal("thread.turn-diff-completed"),
|
|
@@ -5163,6 +5278,11 @@ const PREVIEW_AUTOMATION_OPERATIONS = [
|
|
|
5163
5278
|
const PreviewAutomationOperation = Schema.Literals(PREVIEW_AUTOMATION_OPERATIONS);
|
|
5164
5279
|
const PreviewAutomationTabTargetFields = { tabId: Schema.optional(PreviewTabId.annotate({ description: "Exact collaborative browser tab to target. Omit to use this agent session's current tab." })).annotate({ description: "Exact collaborative browser tab to target. Omit to use this agent session's current tab." }) };
|
|
5165
5280
|
const PreviewAutomationTabTargetInput = Schema.Struct(PreviewAutomationTabTargetFields);
|
|
5281
|
+
const INCLUDE_SCREENSHOT_DESCRIPTION = "Attach a PNG screenshot to the result. Omit it for the text-only page state, which already carries locators, visible text, and diagnostics; every attached image stays in the agent's context for the rest of the session.";
|
|
5282
|
+
const PreviewAutomationSnapshotInput = Schema.Struct({
|
|
5283
|
+
...PreviewAutomationTabTargetFields,
|
|
5284
|
+
includeScreenshot: Schema.optional(Schema.Boolean.annotate({ description: INCLUDE_SCREENSHOT_DESCRIPTION })).annotate({ description: INCLUDE_SCREENSHOT_DESCRIPTION })
|
|
5285
|
+
});
|
|
5166
5286
|
const PreviewAutomationStatus = Schema.Struct({
|
|
5167
5287
|
available: Schema.Boolean,
|
|
5168
5288
|
visible: Schema.Boolean,
|
|
@@ -5834,6 +5954,7 @@ const ContextMenuItemSchema = Schema$1.Struct({
|
|
|
5834
5954
|
header: Schema$1.optionalKey(Schema$1.Boolean),
|
|
5835
5955
|
separator: Schema$1.optionalKey(Schema$1.Boolean),
|
|
5836
5956
|
icon: Schema$1.optionalKey(Schema$1.String),
|
|
5957
|
+
shortcut: Schema$1.optionalKey(Schema$1.String),
|
|
5837
5958
|
children: Schema$1.optionalKey(Schema$1.Array(Schema$1.suspend(() => ContextMenuItemSchema)))
|
|
5838
5959
|
});
|
|
5839
5960
|
const DesktopUpdateStatusSchema = Schema$1.Literals([
|
|
@@ -8156,7 +8277,9 @@ const ClientSettingsSchema = Schema$1.Struct({
|
|
|
8156
8277
|
})).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
8157
8278
|
providerModelPreferences: Schema$1.Record(ProviderInstanceId, Schema$1.Struct({
|
|
8158
8279
|
hiddenModels: Schema$1.Array(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
8159
|
-
modelOrder: Schema$1.Array(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed([])))
|
|
8280
|
+
modelOrder: Schema$1.Array(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
8281
|
+
/** Option values a model starts with in this instance until the user picks others. */
|
|
8282
|
+
modelOptionDefaults: Schema$1.Record(TrimmedNonEmptyString, ProviderOptionSelections).pipe(Schema$1.withDecodingDefault(Effect.succeed({})))
|
|
8160
8283
|
})).pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
8161
8284
|
showBuildModeToggle: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(false))),
|
|
8162
8285
|
sidebarAutoSettleAfterDays: Schema$1.NullOr(SidebarAutoSettleAfterDays).pipe(Schema$1.withDecodingDefault(Effect.succeed(3))),
|
|
@@ -8614,7 +8737,8 @@ Schema$1.Struct({
|
|
|
8614
8737
|
}))),
|
|
8615
8738
|
providerModelPreferences: Schema$1.optionalKey(Schema$1.Record(ProviderInstanceId, Schema$1.Struct({
|
|
8616
8739
|
hiddenModels: Schema$1.Array(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
8617
|
-
modelOrder: Schema$1.Array(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed([])))
|
|
8740
|
+
modelOrder: Schema$1.Array(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed([]))),
|
|
8741
|
+
modelOptionDefaults: Schema$1.Record(TrimmedNonEmptyString, ProviderOptionSelections).pipe(Schema$1.withDecodingDefault(Effect.succeed({})))
|
|
8618
8742
|
}))),
|
|
8619
8743
|
showBuildModeToggle: Schema$1.optionalKey(Schema$1.Boolean),
|
|
8620
8744
|
sidebarAutoSettleAfterDays: Schema$1.optionalKey(Schema$1.NullOr(SidebarAutoSettleAfterDays)),
|
|
@@ -12493,7 +12617,7 @@ function deriveAuthClientMetadata(input) {
|
|
|
12493
12617
|
//#endregion
|
|
12494
12618
|
//#region src/auth/EnvironmentAuthPolicy.ts
|
|
12495
12619
|
var EnvironmentAuthPolicy = class extends Context.Service()("@p4code/cli/auth/EnvironmentAuthPolicy") {};
|
|
12496
|
-
const make$
|
|
12620
|
+
const make$90 = Effect.gen(function* () {
|
|
12497
12621
|
const config = yield* ServerConfig$1;
|
|
12498
12622
|
const isRemoteReachable = isRemoteReachableHost(config.host);
|
|
12499
12623
|
const policy = config.mode === "desktop" ? isRemoteReachable ? "remote-reachable" : "desktop-managed-local" : isRemoteReachable ? "remote-reachable" : "loopback-browser";
|
|
@@ -12511,7 +12635,7 @@ const make$89 = Effect.gen(function* () {
|
|
|
12511
12635
|
};
|
|
12512
12636
|
return EnvironmentAuthPolicy.of({ getDescriptor: () => Effect.succeed(descriptor).pipe(Effect.withSpan("EnvironmentAuthPolicy.getDescriptor")) });
|
|
12513
12637
|
});
|
|
12514
|
-
const layer$80 = Layer.effect(EnvironmentAuthPolicy, make$
|
|
12638
|
+
const layer$80 = Layer.effect(EnvironmentAuthPolicy, make$90);
|
|
12515
12639
|
//#endregion
|
|
12516
12640
|
//#region src/persistence/Errors.ts
|
|
12517
12641
|
function summarizeSchemaIssue(issue) {
|
|
@@ -12692,7 +12816,7 @@ function toPersistenceSqlOrDecodeError$6(sqlOperation, decodeOperation, correlat
|
|
|
12692
12816
|
cause
|
|
12693
12817
|
});
|
|
12694
12818
|
}
|
|
12695
|
-
const make$
|
|
12819
|
+
const make$89 = Effect.gen(function* () {
|
|
12696
12820
|
const sql = yield* SqlClient.SqlClient;
|
|
12697
12821
|
const createSessionRow = SqlSchema.void({
|
|
12698
12822
|
Request: CreateAuthSessionInput,
|
|
@@ -12826,7 +12950,7 @@ const make$88 = Effect.gen(function* () {
|
|
|
12826
12950
|
setLastConnectedAt
|
|
12827
12951
|
};
|
|
12828
12952
|
});
|
|
12829
|
-
const layer$79 = Layer.effect(AuthSessionRepository, make$
|
|
12953
|
+
const layer$79 = Layer.effect(AuthSessionRepository, make$89);
|
|
12830
12954
|
//#endregion
|
|
12831
12955
|
//#region src/auth/ServerSecretStore.ts
|
|
12832
12956
|
const secretStoreErrorContext = {
|
|
@@ -12893,7 +13017,7 @@ const isSecretStoreError = Schema$1.is(SecretStoreError);
|
|
|
12893
13017
|
const isPlatformError = (value) => Predicate.isTagged(value, "PlatformError");
|
|
12894
13018
|
const isSecretAlreadyExistsError = (error) => "cause" in error && isPlatformError(error.cause) && error.cause.reason._tag === "AlreadyExists";
|
|
12895
13019
|
var ServerSecretStore = class extends Context.Service()("@p4code/cli/auth/ServerSecretStore") {};
|
|
12896
|
-
const make$
|
|
13020
|
+
const make$88 = Effect.gen(function* () {
|
|
12897
13021
|
const crypto = yield* Crypto.Crypto;
|
|
12898
13022
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
12899
13023
|
const path = yield* Path.Path;
|
|
@@ -12969,7 +13093,7 @@ const make$87 = Effect.gen(function* () {
|
|
|
12969
13093
|
remove
|
|
12970
13094
|
});
|
|
12971
13095
|
});
|
|
12972
|
-
const layer$78 = Layer.effect(ServerSecretStore, make$
|
|
13096
|
+
const layer$78 = Layer.effect(ServerSecretStore, make$88);
|
|
12973
13097
|
//#endregion
|
|
12974
13098
|
//#region src/auth/SessionStore.ts
|
|
12975
13099
|
var MalformedSessionTokenError = class extends Schema$1.TaggedErrorClass()("MalformedSessionTokenError", {}) {
|
|
@@ -13207,7 +13331,7 @@ function toAuthClientSession(input) {
|
|
|
13207
13331
|
current: false
|
|
13208
13332
|
};
|
|
13209
13333
|
}
|
|
13210
|
-
const make$
|
|
13334
|
+
const make$87 = Effect.gen(function* () {
|
|
13211
13335
|
const crypto = yield* Crypto.Crypto;
|
|
13212
13336
|
const serverConfig = yield* ServerConfig$1;
|
|
13213
13337
|
const secretStore = yield* ServerSecretStore;
|
|
@@ -13521,7 +13645,7 @@ const make$86 = Effect.gen(function* () {
|
|
|
13521
13645
|
markDisconnected
|
|
13522
13646
|
});
|
|
13523
13647
|
});
|
|
13524
|
-
const layer$77 = Layer.effect(SessionStore, make$
|
|
13648
|
+
const layer$77 = Layer.effect(SessionStore, make$87).pipe(Layer.provideMerge(layer$79));
|
|
13525
13649
|
//#endregion
|
|
13526
13650
|
//#region src/persistence/AuthPairingLinks.ts
|
|
13527
13651
|
const AuthPairingLinkRecord = Schema$1.Struct({
|
|
@@ -13582,7 +13706,7 @@ function toPersistenceSqlOrDecodeError$5(sqlOperation, decodeOperation, correlat
|
|
|
13582
13706
|
cause
|
|
13583
13707
|
});
|
|
13584
13708
|
}
|
|
13585
|
-
const make$
|
|
13709
|
+
const make$86 = Effect.gen(function* () {
|
|
13586
13710
|
const sql = yield* SqlClient.SqlClient;
|
|
13587
13711
|
const createPairingLinkRow = SqlSchema.void({
|
|
13588
13712
|
Request: CreateAuthPairingLinkInput,
|
|
@@ -13717,7 +13841,7 @@ const make$85 = Effect.gen(function* () {
|
|
|
13717
13841
|
getByCredential
|
|
13718
13842
|
};
|
|
13719
13843
|
});
|
|
13720
|
-
const layer$76 = Layer.effect(AuthPairingLinkRepository, make$
|
|
13844
|
+
const layer$76 = Layer.effect(AuthPairingLinkRepository, make$86);
|
|
13721
13845
|
//#endregion
|
|
13722
13846
|
//#region src/auth/PairingGrantStore.ts
|
|
13723
13847
|
var UnknownBootstrapCredentialError = class extends Schema$1.TaggedErrorClass()("UnknownBootstrapCredentialError", {}) {
|
|
@@ -13812,7 +13936,7 @@ const DEV_STARTUP_TTL_HOURS = Duration.hours(24);
|
|
|
13812
13936
|
const PAIRING_TOKEN_ALPHABET = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
|
|
13813
13937
|
const PAIRING_TOKEN_LENGTH = 12;
|
|
13814
13938
|
const PAIRING_TOKEN_REJECTION_LIMIT = Math.floor(256 / 32) * 32;
|
|
13815
|
-
const make$
|
|
13939
|
+
const make$85 = Effect.gen(function* () {
|
|
13816
13940
|
const crypto = yield* Crypto.Crypto;
|
|
13817
13941
|
const config = yield* ServerConfig$1;
|
|
13818
13942
|
const pairingLinks = yield* AuthPairingLinkRepository;
|
|
@@ -14010,7 +14134,7 @@ const make$84 = Effect.gen(function* () {
|
|
|
14010
14134
|
consume
|
|
14011
14135
|
});
|
|
14012
14136
|
});
|
|
14013
|
-
const layer$75 = Layer.effect(PairingGrantStore, make$
|
|
14137
|
+
const layer$75 = Layer.effect(PairingGrantStore, make$85).pipe(Layer.provideMerge(layer$76));
|
|
14014
14138
|
//#endregion
|
|
14015
14139
|
//#region src/persistence/DatabaseSnapshot.ts
|
|
14016
14140
|
/**
|
|
@@ -15929,6 +16053,33 @@ var _053_ProjectionTurnsKeysetIndex_default = Effect.gen(function* () {
|
|
|
15929
16053
|
`;
|
|
15930
16054
|
});
|
|
15931
16055
|
//#endregion
|
|
16056
|
+
//#region src/persistence/Migrations/054_ProjectionThreadScheduledTasks.ts
|
|
16057
|
+
/**
|
|
16058
|
+
* User-created scheduled tasks: a prompt the server sends to a thread at a
|
|
16059
|
+
* chosen time. Pending rows are what the scheduler re-arms after a restart.
|
|
16060
|
+
*/
|
|
16061
|
+
var _054_ProjectionThreadScheduledTasks_default = Effect.gen(function* () {
|
|
16062
|
+
const sql = yield* SqlClient.SqlClient;
|
|
16063
|
+
yield* sql`
|
|
16064
|
+
CREATE TABLE IF NOT EXISTS projection_thread_scheduled_tasks (
|
|
16065
|
+
task_id TEXT PRIMARY KEY,
|
|
16066
|
+
thread_id TEXT NOT NULL,
|
|
16067
|
+
prompt TEXT NOT NULL,
|
|
16068
|
+
run_at TEXT NOT NULL,
|
|
16069
|
+
status TEXT NOT NULL,
|
|
16070
|
+
created_at TEXT NOT NULL,
|
|
16071
|
+
updated_at TEXT NOT NULL,
|
|
16072
|
+
fired_at TEXT,
|
|
16073
|
+
cancelled_at TEXT,
|
|
16074
|
+
failure TEXT
|
|
16075
|
+
)
|
|
16076
|
+
`;
|
|
16077
|
+
yield* sql`
|
|
16078
|
+
CREATE INDEX IF NOT EXISTS idx_projection_thread_scheduled_tasks_thread_run
|
|
16079
|
+
ON projection_thread_scheduled_tasks(thread_id, run_at)
|
|
16080
|
+
`;
|
|
16081
|
+
});
|
|
16082
|
+
//#endregion
|
|
15932
16083
|
//#region src/persistence/Migrations.ts
|
|
15933
16084
|
/**
|
|
15934
16085
|
* MigrationsLive - Migration runner with inline loader
|
|
@@ -16214,6 +16365,11 @@ const migrationEntries = [
|
|
|
16214
16365
|
53,
|
|
16215
16366
|
"ProjectionTurnsKeysetIndex",
|
|
16216
16367
|
_053_ProjectionTurnsKeysetIndex_default
|
|
16368
|
+
],
|
|
16369
|
+
[
|
|
16370
|
+
54,
|
|
16371
|
+
"ProjectionThreadScheduledTasks",
|
|
16372
|
+
_054_ProjectionThreadScheduledTasks_default
|
|
16217
16373
|
]
|
|
16218
16374
|
];
|
|
16219
16375
|
const makeMigrationLoader = (throughId) => Migrator.fromRecord(Object.fromEntries(migrationEntries.filter(([id]) => throughId === void 0 || id <= throughId).map(([id, name, migration]) => [`${id}_${name}`, migration])));
|
|
@@ -17204,7 +17360,7 @@ function parseBearerToken(request) {
|
|
|
17204
17360
|
const token = header.slice(7).trim();
|
|
17205
17361
|
return token.length > 0 ? token : null;
|
|
17206
17362
|
}
|
|
17207
|
-
const make$
|
|
17363
|
+
const make$84 = Effect.gen(function* () {
|
|
17208
17364
|
const policy = yield* EnvironmentAuthPolicy;
|
|
17209
17365
|
const bootstrapCredentials = yield* PairingGrantStore;
|
|
17210
17366
|
const sessions = yield* SessionStore;
|
|
@@ -17399,7 +17555,7 @@ const make$83 = Effect.gen(function* () {
|
|
|
17399
17555
|
issueStartupPairingUrl
|
|
17400
17556
|
});
|
|
17401
17557
|
});
|
|
17402
|
-
const layer$74 = Layer.effect(EnvironmentAuth, make$
|
|
17558
|
+
const layer$74 = Layer.effect(EnvironmentAuth, make$84).pipe(Layer.provideMerge(layer$75), Layer.provideMerge(layer$77), Layer.provideMerge(layer$80));
|
|
17403
17559
|
const storageLayer = Layer.mergeAll(layer$78, layerConfig);
|
|
17404
17560
|
const runtimeLayer = layer$74.pipe(Layer.provideMerge(storageLayer));
|
|
17405
17561
|
//#endregion
|
|
@@ -19237,7 +19393,7 @@ const DEFAULT_LIMITS = {
|
|
|
19237
19393
|
windowMillis: FAILURE_WINDOW_MS,
|
|
19238
19394
|
blockMillis: BLOCK_DURATION_MS
|
|
19239
19395
|
};
|
|
19240
|
-
const make$
|
|
19396
|
+
const make$83 = Effect.fn("HubAuthThrottle.make")(function* (limits = DEFAULT_LIMITS) {
|
|
19241
19397
|
const state = yield* Ref.make(initialThrottleState);
|
|
19242
19398
|
return HubAuthThrottle.of({
|
|
19243
19399
|
shouldRefuse: Effect.gen(function* () {
|
|
@@ -19251,7 +19407,7 @@ const make$82 = Effect.fn("HubAuthThrottle.make")(function* (limits = DEFAULT_LI
|
|
|
19251
19407
|
})
|
|
19252
19408
|
});
|
|
19253
19409
|
});
|
|
19254
|
-
const layer$73 = Layer.effect(HubAuthThrottle, make$
|
|
19410
|
+
const layer$73 = Layer.effect(HubAuthThrottle, make$83());
|
|
19255
19411
|
//#endregion
|
|
19256
19412
|
//#region src/hub/HubAuth.ts
|
|
19257
19413
|
/**
|
|
@@ -20971,7 +21127,7 @@ function stripDefaultServerSettings(current, defaults) {
|
|
|
20971
21127
|
}
|
|
20972
21128
|
return Object.is(current, defaults) ? void 0 : current;
|
|
20973
21129
|
}
|
|
20974
|
-
const make$
|
|
21130
|
+
const make$82 = Effect.gen(function* () {
|
|
20975
21131
|
const { settingsPath } = yield* ServerConfig$1;
|
|
20976
21132
|
const fs = yield* FileSystem.FileSystem;
|
|
20977
21133
|
const pathService = yield* Path.Path;
|
|
@@ -21192,7 +21348,7 @@ const make$81 = Effect.gen(function* () {
|
|
|
21192
21348
|
}
|
|
21193
21349
|
};
|
|
21194
21350
|
});
|
|
21195
|
-
const layer$71 = Layer.effect(ServerSettingsService, make$
|
|
21351
|
+
const layer$71 = Layer.effect(ServerSettingsService, make$82);
|
|
21196
21352
|
//#endregion
|
|
21197
21353
|
//#region src/pathExpansion.ts
|
|
21198
21354
|
/**
|
|
@@ -21569,7 +21725,7 @@ function claudeEntryFromRegistration(registration) {
|
|
|
21569
21725
|
};
|
|
21570
21726
|
}
|
|
21571
21727
|
var ClaudeMcpFiles = class extends Context.Service()("@p4code/cli/mcp/ClaudeMcpFiles") {};
|
|
21572
|
-
const make$
|
|
21728
|
+
const make$81 = Effect.gen(function* () {
|
|
21573
21729
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
21574
21730
|
const path = yield* Path.Path;
|
|
21575
21731
|
const services = yield* Effect.context();
|
|
@@ -21636,7 +21792,7 @@ const make$80 = Effect.gen(function* () {
|
|
|
21636
21792
|
removeProject: (projectDir, name) => removeAt(Effect.succeed(projectFile(projectDir)))(name)
|
|
21637
21793
|
};
|
|
21638
21794
|
});
|
|
21639
|
-
const layer$70 = Layer.effect(ClaudeMcpFiles, make$
|
|
21795
|
+
const layer$70 = Layer.effect(ClaudeMcpFiles, make$81);
|
|
21640
21796
|
Layer.succeed(ClaudeMcpFiles, {
|
|
21641
21797
|
readUser: Effect.succeed([]),
|
|
21642
21798
|
readUserAt: () => Effect.succeed([]),
|
|
@@ -21774,7 +21930,7 @@ const decodeClientRegistration = Schema$1.decodeUnknownExit(ClientRegistrationRe
|
|
|
21774
21930
|
const decodeTokenResponse = Schema$1.decodeUnknownExit(TokenResponse);
|
|
21775
21931
|
var McpOAuth = class extends Context.Service()("@p4code/cli/mcp/McpOAuth") {};
|
|
21776
21932
|
const registryError = (detail) => new McpRegistryError({ detail });
|
|
21777
|
-
const make$
|
|
21933
|
+
const make$80 = Effect.gen(function* () {
|
|
21778
21934
|
const config = yield* ServerConfig$1;
|
|
21779
21935
|
const secrets = yield* ServerSecretStore;
|
|
21780
21936
|
const http = yield* HttpClient.HttpClient;
|
|
@@ -22094,7 +22250,7 @@ const make$79 = Effect.gen(function* () {
|
|
|
22094
22250
|
accessTokenFor
|
|
22095
22251
|
};
|
|
22096
22252
|
});
|
|
22097
|
-
const layer$69 = Layer.effect(McpOAuth, make$
|
|
22253
|
+
const layer$69 = Layer.effect(McpOAuth, make$80);
|
|
22098
22254
|
Layer.succeed(McpOAuth, {
|
|
22099
22255
|
statusFor: () => Effect.succeed(Option.none()),
|
|
22100
22256
|
begin: () => Effect.fail(new McpRegistryError({ detail: "OAuth sign-in is not available." })),
|
|
@@ -22112,7 +22268,7 @@ const decodeRegistration$1 = Schema$1.decodeUnknownExit(RegistrationFromJson$1);
|
|
|
22112
22268
|
const encodeRegistration = Schema$1.encodeSync(RegistrationFromJson$1);
|
|
22113
22269
|
var McpRegistry = class extends Context.Service()("@p4code/cli/mcp/McpRegistry") {};
|
|
22114
22270
|
const slotsOf = (registration) => registration.secrets ?? [];
|
|
22115
|
-
const make$
|
|
22271
|
+
const make$79 = Effect.gen(function* () {
|
|
22116
22272
|
const config = yield* ServerConfig$1;
|
|
22117
22273
|
const secrets = yield* ServerSecretStore;
|
|
22118
22274
|
const oauth = yield* McpOAuth;
|
|
@@ -22286,7 +22442,7 @@ const make$78 = Effect.gen(function* () {
|
|
|
22286
22442
|
resolveForSessionAtClaudeUserConfigPath
|
|
22287
22443
|
};
|
|
22288
22444
|
});
|
|
22289
|
-
const layer$68 = Layer.effect(McpRegistry, make$
|
|
22445
|
+
const layer$68 = Layer.effect(McpRegistry, make$79);
|
|
22290
22446
|
//#endregion
|
|
22291
22447
|
//#region src/sync/skillDirectory.ts
|
|
22292
22448
|
/**
|
|
@@ -22665,7 +22821,7 @@ const formatHubLink = (input) => encodeStoredHubLink({
|
|
|
22665
22821
|
shareMode: input.shareMode
|
|
22666
22822
|
});
|
|
22667
22823
|
const fromEnvironment = (environment) => validateHubLink(environment.P4CODE_HUB_URL ?? "", environment.P4CODE_HUB_TOKEN ?? "");
|
|
22668
|
-
const make$
|
|
22824
|
+
const make$78 = Effect.fn("HubLink.make")(function* (environment) {
|
|
22669
22825
|
const secrets = yield* ServerSecretStore;
|
|
22670
22826
|
const env = environment ?? process.env;
|
|
22671
22827
|
const fromEnv = fromEnvironment(env);
|
|
@@ -22731,7 +22887,7 @@ const make$77 = Effect.fn("HubLink.make")(function* (environment) {
|
|
|
22731
22887
|
})
|
|
22732
22888
|
};
|
|
22733
22889
|
});
|
|
22734
|
-
const layer$67 = Layer.effect(HubLink, make$
|
|
22890
|
+
const layer$67 = Layer.effect(HubLink, make$78());
|
|
22735
22891
|
//#endregion
|
|
22736
22892
|
//#region src/sync/HubAssetClient.ts
|
|
22737
22893
|
/**
|
|
@@ -22764,7 +22920,7 @@ const decodeAssetListPage = Schema$1.decodeUnknownEffect(AssetListPage);
|
|
|
22764
22920
|
const decodeConflictBody$1 = Schema$1.decodeUnknownEffect(ConflictBody$1);
|
|
22765
22921
|
const decodeAsset = Schema$1.decodeUnknownEffect(AgentAsset);
|
|
22766
22922
|
var HubAssetClient = class extends Context.Service()("@p4code/cli/sync/HubAssetClient") {};
|
|
22767
|
-
const make$
|
|
22923
|
+
const make$77 = Effect.gen(function* () {
|
|
22768
22924
|
const http = yield* HttpClient.HttpClient;
|
|
22769
22925
|
const link = yield* HubLink;
|
|
22770
22926
|
const requireSettings = Effect.gen(function* () {
|
|
@@ -22846,7 +23002,7 @@ const make$76 = Effect.gen(function* () {
|
|
|
22846
23002
|
remove
|
|
22847
23003
|
};
|
|
22848
23004
|
});
|
|
22849
|
-
const layer$66 = Layer.effect(HubAssetClient, make$
|
|
23005
|
+
const layer$66 = Layer.effect(HubAssetClient, make$77);
|
|
22850
23006
|
//#endregion
|
|
22851
23007
|
//#region src/sync/mcpRegistrationFiles.ts
|
|
22852
23008
|
/**
|
|
@@ -23452,7 +23608,7 @@ const EMPTY_REPORT = {
|
|
|
23452
23608
|
unavailable: null
|
|
23453
23609
|
};
|
|
23454
23610
|
var AssetSync = class extends Context.Service()("@p4code/cli/sync/AssetSync") {};
|
|
23455
|
-
const make$
|
|
23611
|
+
const make$76 = Effect.gen(function* () {
|
|
23456
23612
|
const client = yield* HubAssetClient;
|
|
23457
23613
|
const link = yield* HubLink;
|
|
23458
23614
|
const settingsStore = yield* ServerSettingsService;
|
|
@@ -24162,7 +24318,7 @@ const make$75 = Effect.gen(function* () {
|
|
|
24162
24318
|
removeLocal
|
|
24163
24319
|
};
|
|
24164
24320
|
});
|
|
24165
|
-
const layer$65 = Layer.effect(AssetSync, make$
|
|
24321
|
+
const layer$65 = Layer.effect(AssetSync, make$76);
|
|
24166
24322
|
//#endregion
|
|
24167
24323
|
//#region src/provider/CompressPrompts.ts
|
|
24168
24324
|
/**
|
|
@@ -25610,6 +25766,306 @@ function requireThreadAbsent(input) {
|
|
|
25610
25766
|
return Effect.fail(invariantError(input.command.type, `Thread '${input.threadId}' already exists and cannot be created twice.`));
|
|
25611
25767
|
}
|
|
25612
25768
|
//#endregion
|
|
25769
|
+
//#region src/attachmentPaths.ts
|
|
25770
|
+
function normalizeAttachmentRelativePath(rawRelativePath) {
|
|
25771
|
+
const normalized = NodePath.normalize(rawRelativePath).replace(/^[/\\]+/, "");
|
|
25772
|
+
if (normalized.length === 0 || normalized.startsWith("..") || normalized.includes("\0")) return null;
|
|
25773
|
+
return normalized.replace(/\\/g, "/");
|
|
25774
|
+
}
|
|
25775
|
+
function resolveAttachmentRelativePath(input) {
|
|
25776
|
+
const normalizedRelativePath = normalizeAttachmentRelativePath(input.relativePath);
|
|
25777
|
+
if (!normalizedRelativePath) return null;
|
|
25778
|
+
const attachmentsRoot = NodePath.resolve(input.attachmentsDir);
|
|
25779
|
+
const filePath = NodePath.resolve(NodePath.join(attachmentsRoot, normalizedRelativePath));
|
|
25780
|
+
if (!filePath.startsWith(`${attachmentsRoot}${NodePath.sep}`)) return null;
|
|
25781
|
+
return filePath;
|
|
25782
|
+
}
|
|
25783
|
+
//#endregion
|
|
25784
|
+
//#region src/imageMime.ts
|
|
25785
|
+
const IMAGE_EXTENSION_BY_MIME_TYPE = {
|
|
25786
|
+
"image/avif": ".avif",
|
|
25787
|
+
"image/bmp": ".bmp",
|
|
25788
|
+
"image/gif": ".gif",
|
|
25789
|
+
"image/heic": ".heic",
|
|
25790
|
+
"image/heif": ".heif",
|
|
25791
|
+
"image/jpeg": ".jpg",
|
|
25792
|
+
"image/jpg": ".jpg",
|
|
25793
|
+
"image/png": ".png",
|
|
25794
|
+
"image/svg+xml": ".svg",
|
|
25795
|
+
"image/tiff": ".tiff",
|
|
25796
|
+
"image/webp": ".webp"
|
|
25797
|
+
};
|
|
25798
|
+
const SAFE_IMAGE_FILE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
25799
|
+
".avif",
|
|
25800
|
+
".bmp",
|
|
25801
|
+
".gif",
|
|
25802
|
+
".heic",
|
|
25803
|
+
".heif",
|
|
25804
|
+
".ico",
|
|
25805
|
+
".jpeg",
|
|
25806
|
+
".jpg",
|
|
25807
|
+
".png",
|
|
25808
|
+
".svg",
|
|
25809
|
+
".tiff",
|
|
25810
|
+
".webp"
|
|
25811
|
+
]);
|
|
25812
|
+
function isBase64Char(code) {
|
|
25813
|
+
return code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57 || code === 43 || code === 47 || code === 61;
|
|
25814
|
+
}
|
|
25815
|
+
function isBase64Whitespace(code) {
|
|
25816
|
+
return code === 13 || code === 10 || code === 32;
|
|
25817
|
+
}
|
|
25818
|
+
function parseBase64DataUrl(dataUrl) {
|
|
25819
|
+
const trimmed = dataUrl.trim();
|
|
25820
|
+
if (trimmed.slice(0, 5).toLowerCase() !== "data:") return null;
|
|
25821
|
+
const commaIndex = trimmed.indexOf(",");
|
|
25822
|
+
if (commaIndex === -1) return null;
|
|
25823
|
+
const header = trimmed.slice(5, commaIndex);
|
|
25824
|
+
if (header.length === 0) return null;
|
|
25825
|
+
const headerParts = [];
|
|
25826
|
+
for (const part of header.split(";")) {
|
|
25827
|
+
const partTrimmed = part.trim();
|
|
25828
|
+
if (partTrimmed.length > 0) headerParts.push(partTrimmed);
|
|
25829
|
+
}
|
|
25830
|
+
if (headerParts.length < 2) return null;
|
|
25831
|
+
if (headerParts.at(-1)?.toLowerCase() !== "base64") return null;
|
|
25832
|
+
const mimeType = headerParts[0]?.toLowerCase();
|
|
25833
|
+
if (!mimeType) return null;
|
|
25834
|
+
const payload = trimmed.slice(commaIndex + 1);
|
|
25835
|
+
const runs = [];
|
|
25836
|
+
let runStart = -1;
|
|
25837
|
+
for (let index = 0; index < payload.length; index += 1) {
|
|
25838
|
+
const code = payload.charCodeAt(index);
|
|
25839
|
+
if (isBase64Char(code)) {
|
|
25840
|
+
if (runStart === -1) runStart = index;
|
|
25841
|
+
continue;
|
|
25842
|
+
}
|
|
25843
|
+
if (!isBase64Whitespace(code)) return null;
|
|
25844
|
+
if (runStart !== -1) {
|
|
25845
|
+
runs.push(payload.slice(runStart, index));
|
|
25846
|
+
runStart = -1;
|
|
25847
|
+
}
|
|
25848
|
+
}
|
|
25849
|
+
if (runStart !== -1) runs.push(payload.slice(runStart));
|
|
25850
|
+
const base64 = runs.length === 1 ? runs[0] : runs.join("");
|
|
25851
|
+
if (base64.length === 0 || base64.length % 4 !== 0) return null;
|
|
25852
|
+
const firstPad = base64.indexOf("=");
|
|
25853
|
+
if (firstPad !== -1) {
|
|
25854
|
+
if (base64.length - firstPad > 2) return null;
|
|
25855
|
+
for (let index = firstPad; index < base64.length; index += 1) if (base64.charCodeAt(index) !== 61) return null;
|
|
25856
|
+
}
|
|
25857
|
+
return {
|
|
25858
|
+
mimeType,
|
|
25859
|
+
base64
|
|
25860
|
+
};
|
|
25861
|
+
}
|
|
25862
|
+
function inferImageExtension(input) {
|
|
25863
|
+
const key = input.mimeType.toLowerCase();
|
|
25864
|
+
const fromMime = Object.hasOwn(IMAGE_EXTENSION_BY_MIME_TYPE, key) ? IMAGE_EXTENSION_BY_MIME_TYPE[key] : void 0;
|
|
25865
|
+
if (fromMime) return fromMime;
|
|
25866
|
+
const fromMimeExtension = Mime.getExtension(input.mimeType);
|
|
25867
|
+
if (fromMimeExtension && SAFE_IMAGE_FILE_EXTENSIONS.has(fromMimeExtension)) return fromMimeExtension;
|
|
25868
|
+
const fileName = input.fileName?.trim() ?? "";
|
|
25869
|
+
const extensionMatch = /\.([a-z0-9]{1,8})$/i.exec(fileName);
|
|
25870
|
+
const fileNameExtension = extensionMatch ? `.${extensionMatch[1].toLowerCase()}` : "";
|
|
25871
|
+
if (SAFE_IMAGE_FILE_EXTENSIONS.has(fileNameExtension)) return fileNameExtension;
|
|
25872
|
+
return ".bin";
|
|
25873
|
+
}
|
|
25874
|
+
//#endregion
|
|
25875
|
+
//#region src/attachmentStore.ts
|
|
25876
|
+
const ATTACHMENT_FILENAME_EXTENSIONS = [
|
|
25877
|
+
...SAFE_IMAGE_FILE_EXTENSIONS,
|
|
25878
|
+
".pdf",
|
|
25879
|
+
".bin"
|
|
25880
|
+
];
|
|
25881
|
+
const ATTACHMENT_ID_THREAD_SEGMENT_MAX_CHARS = 80;
|
|
25882
|
+
const ATTACHMENT_ID_PATTERN = new RegExp(`^([a-z0-9_]+(?:-[a-z0-9_]+)*)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$`, "i");
|
|
25883
|
+
function toSafeThreadAttachmentSegment(threadId) {
|
|
25884
|
+
const segment = threadId.trim().toLowerCase().replace(/[^a-z0-9_-]+/gi, "-").replace(/-+/g, "-").replace(/^[-_]+|[-_]+$/g, "").slice(0, ATTACHMENT_ID_THREAD_SEGMENT_MAX_CHARS).replace(/[-_]+$/g, "");
|
|
25885
|
+
if (segment.length === 0) return null;
|
|
25886
|
+
return segment;
|
|
25887
|
+
}
|
|
25888
|
+
function createAttachmentId(threadId) {
|
|
25889
|
+
const threadSegment = toSafeThreadAttachmentSegment(threadId);
|
|
25890
|
+
if (!threadSegment) return null;
|
|
25891
|
+
return `${threadSegment}-${NodeCrypto.randomUUID()}`;
|
|
25892
|
+
}
|
|
25893
|
+
function parseThreadSegmentFromAttachmentId(attachmentId) {
|
|
25894
|
+
const normalizedId = normalizeAttachmentRelativePath(attachmentId);
|
|
25895
|
+
if (!normalizedId || normalizedId.includes("/") || normalizedId.includes(".")) return null;
|
|
25896
|
+
const match = normalizedId.match(ATTACHMENT_ID_PATTERN);
|
|
25897
|
+
if (!match) return null;
|
|
25898
|
+
return match[1]?.toLowerCase() ?? null;
|
|
25899
|
+
}
|
|
25900
|
+
function attachmentRelativePath(attachment) {
|
|
25901
|
+
switch (attachment.type) {
|
|
25902
|
+
case "image": {
|
|
25903
|
+
const extension = inferImageExtension({
|
|
25904
|
+
mimeType: attachment.mimeType,
|
|
25905
|
+
fileName: attachment.name
|
|
25906
|
+
});
|
|
25907
|
+
return `${attachment.id}${extension}`;
|
|
25908
|
+
}
|
|
25909
|
+
case "document": return `${attachment.id}.pdf`;
|
|
25910
|
+
}
|
|
25911
|
+
}
|
|
25912
|
+
function resolveAttachmentPath(input) {
|
|
25913
|
+
return resolveAttachmentRelativePath({
|
|
25914
|
+
attachmentsDir: input.attachmentsDir,
|
|
25915
|
+
relativePath: attachmentRelativePath(input.attachment)
|
|
25916
|
+
});
|
|
25917
|
+
}
|
|
25918
|
+
function resolveAttachmentPathById(input) {
|
|
25919
|
+
const normalizedId = normalizeAttachmentRelativePath(input.attachmentId);
|
|
25920
|
+
if (!normalizedId || normalizedId.includes("/") || normalizedId.includes(".")) return null;
|
|
25921
|
+
for (const extension of ATTACHMENT_FILENAME_EXTENSIONS) {
|
|
25922
|
+
const maybePath = resolveAttachmentRelativePath({
|
|
25923
|
+
attachmentsDir: input.attachmentsDir,
|
|
25924
|
+
relativePath: `${normalizedId}${extension}`
|
|
25925
|
+
});
|
|
25926
|
+
if (maybePath && NodeFS.existsSync(maybePath)) return maybePath;
|
|
25927
|
+
}
|
|
25928
|
+
return null;
|
|
25929
|
+
}
|
|
25930
|
+
function parseAttachmentIdFromRelativePath(relativePath) {
|
|
25931
|
+
const normalized = normalizeAttachmentRelativePath(relativePath);
|
|
25932
|
+
if (!normalized || normalized.includes("/")) return null;
|
|
25933
|
+
const extensionIndex = normalized.lastIndexOf(".");
|
|
25934
|
+
if (extensionIndex <= 0) return null;
|
|
25935
|
+
const id = normalized.slice(0, extensionIndex);
|
|
25936
|
+
return id.length > 0 && !id.includes(".") ? id : null;
|
|
25937
|
+
}
|
|
25938
|
+
//#endregion
|
|
25939
|
+
//#region src/orchestration/threadFork.ts
|
|
25940
|
+
/** Providers whose adapter can open a new session on top of a saved one. */
|
|
25941
|
+
const FORKABLE_PROVIDERS = /* @__PURE__ */ new Set(["claudeAgent"]);
|
|
25942
|
+
/**
|
|
25943
|
+
* Message ids are unique across threads, so a copied message needs an id
|
|
25944
|
+
* that ties it to the fork while staying derivable from the original.
|
|
25945
|
+
*/
|
|
25946
|
+
function forkedMessageId(threadId, messageId) {
|
|
25947
|
+
return `${threadId}:fork:${messageId}`;
|
|
25948
|
+
}
|
|
25949
|
+
/**
|
|
25950
|
+
* Attachment ids must look like `<thread-segment>-<uuid>` and the file lives
|
|
25951
|
+
* beside the id, so a copy gets a fresh id under the fork's segment. The uuid
|
|
25952
|
+
* is derived from the source id: the pure read-model projector and the SQLite
|
|
25953
|
+
* projection must agree on it without sharing state.
|
|
25954
|
+
*/
|
|
25955
|
+
function forkedAttachmentId(threadId, attachmentId) {
|
|
25956
|
+
const segment = toSafeThreadAttachmentSegment(threadId);
|
|
25957
|
+
if (!segment) return null;
|
|
25958
|
+
const digest = NodeCrypto.createHash("sha256").update(`${threadId} ${attachmentId}`).digest("hex");
|
|
25959
|
+
return `${segment}-${[
|
|
25960
|
+
digest.slice(0, 8),
|
|
25961
|
+
digest.slice(8, 12),
|
|
25962
|
+
digest.slice(12, 16),
|
|
25963
|
+
digest.slice(16, 20),
|
|
25964
|
+
digest.slice(20, 32)
|
|
25965
|
+
].join("-")}`;
|
|
25966
|
+
}
|
|
25967
|
+
function copyForkedAttachments(threadId, attachments) {
|
|
25968
|
+
if (attachments === void 0) return void 0;
|
|
25969
|
+
const copies = [];
|
|
25970
|
+
for (const attachment of attachments) {
|
|
25971
|
+
const id = forkedAttachmentId(threadId, attachment.id);
|
|
25972
|
+
if (id === null) continue;
|
|
25973
|
+
copies.push({
|
|
25974
|
+
...attachment,
|
|
25975
|
+
id
|
|
25976
|
+
});
|
|
25977
|
+
}
|
|
25978
|
+
return copies;
|
|
25979
|
+
}
|
|
25980
|
+
/**
|
|
25981
|
+
* Copies a source thread's conversation for the fork read model. Turn ids
|
|
25982
|
+
* belong to the source thread's turns, so copies carry none; attachments are
|
|
25983
|
+
* re-keyed to the fork so their files can be copied beside them; a streaming
|
|
25984
|
+
* message is frozen as-is.
|
|
25985
|
+
*/
|
|
25986
|
+
function copyForkedMessages(threadId, messages) {
|
|
25987
|
+
return messages.map((message) => {
|
|
25988
|
+
const attachments = copyForkedAttachments(threadId, message.attachments);
|
|
25989
|
+
return {
|
|
25990
|
+
id: forkedMessageId(threadId, message.id),
|
|
25991
|
+
role: message.role,
|
|
25992
|
+
text: message.text,
|
|
25993
|
+
...attachments !== void 0 ? { attachments } : {},
|
|
25994
|
+
turnId: null,
|
|
25995
|
+
streaming: false,
|
|
25996
|
+
createdAt: message.createdAt,
|
|
25997
|
+
updatedAt: message.updatedAt
|
|
25998
|
+
};
|
|
25999
|
+
});
|
|
26000
|
+
}
|
|
26001
|
+
/** Same copy as {@link copyForkedMessages}, for the SQLite message projection. */
|
|
26002
|
+
function copyForkedProjectionMessages(threadId, rows) {
|
|
26003
|
+
return rows.map((row) => {
|
|
26004
|
+
const attachments = copyForkedAttachments(threadId, row.attachments);
|
|
26005
|
+
return {
|
|
26006
|
+
messageId: forkedMessageId(threadId, row.messageId),
|
|
26007
|
+
threadId,
|
|
26008
|
+
turnId: null,
|
|
26009
|
+
role: row.role,
|
|
26010
|
+
text: row.text,
|
|
26011
|
+
...attachments !== void 0 ? { attachments } : {},
|
|
26012
|
+
isStreaming: false,
|
|
26013
|
+
createdAt: row.createdAt,
|
|
26014
|
+
updatedAt: row.updatedAt
|
|
26015
|
+
};
|
|
26016
|
+
});
|
|
26017
|
+
}
|
|
26018
|
+
/** File copies that make the re-keyed attachment references resolve. */
|
|
26019
|
+
function collectForkedAttachmentCopies(threadId, rows) {
|
|
26020
|
+
const copies = [];
|
|
26021
|
+
for (const row of rows) for (const attachment of row.attachments ?? []) {
|
|
26022
|
+
const id = forkedAttachmentId(threadId, attachment.id);
|
|
26023
|
+
if (id === null) continue;
|
|
26024
|
+
copies.push({
|
|
26025
|
+
fromRelativePath: attachmentRelativePath(attachment),
|
|
26026
|
+
toRelativePath: attachmentRelativePath({
|
|
26027
|
+
...attachment,
|
|
26028
|
+
id
|
|
26029
|
+
})
|
|
26030
|
+
});
|
|
26031
|
+
}
|
|
26032
|
+
return copies;
|
|
26033
|
+
}
|
|
26034
|
+
function isRecord$6(value) {
|
|
26035
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
26036
|
+
}
|
|
26037
|
+
/**
|
|
26038
|
+
* Provider binding for a fork, or the reason there is none. The resume cursor
|
|
26039
|
+
* is re-keyed to the fork and flagged so the adapter opens a new provider
|
|
26040
|
+
* session from the saved one instead of continuing the source's session.
|
|
26041
|
+
*/
|
|
26042
|
+
function buildForkedProviderBinding(threadId, source) {
|
|
26043
|
+
if (source === void 0) return { rejection: "no-binding" };
|
|
26044
|
+
if (!FORKABLE_PROVIDERS.has(source.provider)) return { rejection: "provider-cannot-fork" };
|
|
26045
|
+
if (!isRecord$6(source.resumeCursor) || typeof source.resumeCursor.resume !== "string") return { rejection: "no-resume-cursor" };
|
|
26046
|
+
return { binding: {
|
|
26047
|
+
threadId,
|
|
26048
|
+
provider: source.provider,
|
|
26049
|
+
...source.providerInstanceId ? { providerInstanceId: source.providerInstanceId } : {},
|
|
26050
|
+
...source.adapterKey ? { adapterKey: source.adapterKey } : {},
|
|
26051
|
+
...source.runtimeMode ? { runtimeMode: source.runtimeMode } : {},
|
|
26052
|
+
status: "stopped",
|
|
26053
|
+
resumeCursor: {
|
|
26054
|
+
...source.resumeCursor,
|
|
26055
|
+
threadId,
|
|
26056
|
+
forkSession: true
|
|
26057
|
+
},
|
|
26058
|
+
runtimePayload: source.runtimePayload ?? null
|
|
26059
|
+
} };
|
|
26060
|
+
}
|
|
26061
|
+
function describeThreadForkRejection(rejection) {
|
|
26062
|
+
switch (rejection) {
|
|
26063
|
+
case "no-binding": return "This thread has no provider session to fork yet. Send a message first.";
|
|
26064
|
+
case "provider-cannot-fork": return "This thread's provider cannot fork a session. Fork is available for Claude threads.";
|
|
26065
|
+
case "no-resume-cursor": return "This thread's provider session cannot be resumed, so it cannot be forked.";
|
|
26066
|
+
}
|
|
26067
|
+
}
|
|
26068
|
+
//#endregion
|
|
25613
26069
|
//#region src/orchestration/Schemas.ts
|
|
25614
26070
|
const ProjectCreatedPayload = ProjectCreatedPayload$1;
|
|
25615
26071
|
const ProjectMetaUpdatedPayload = ProjectMetaUpdatedPayload$1;
|
|
@@ -25632,6 +26088,9 @@ const ThreadSnoozedPayload = ThreadSnoozedPayload$1;
|
|
|
25632
26088
|
const ThreadUnsnoozedPayload = ThreadUnsnoozedPayload$1;
|
|
25633
26089
|
const MessageSentPayloadSchema = ThreadMessageSentPayload;
|
|
25634
26090
|
const ThreadProposedPlanUpsertedPayload = ThreadProposedPlanUpsertedPayload$1;
|
|
26091
|
+
const ThreadScheduledTaskCreatedPayload = ThreadScheduledTaskCreatedPayload$1;
|
|
26092
|
+
const ThreadScheduledTaskCancelledPayload = ThreadScheduledTaskCancelledPayload$1;
|
|
26093
|
+
const ThreadScheduledTaskFiredPayload = ThreadScheduledTaskFiredPayload$1;
|
|
25635
26094
|
const ThreadSessionSetPayload = ThreadSessionSetPayload$1;
|
|
25636
26095
|
const ThreadTurnDiffCompletedPayload = ThreadTurnDiffCompletedPayload$1;
|
|
25637
26096
|
const ThreadRevertedPayload = ThreadRevertedPayload$1;
|
|
@@ -25814,6 +26273,7 @@ function projectEvent(model, event) {
|
|
|
25814
26273
|
})));
|
|
25815
26274
|
case "thread.created": return Effect.gen(function* () {
|
|
25816
26275
|
const payload = yield* decodeForEvent(ThreadCreatedPayload, event.payload, event.type, "payload");
|
|
26276
|
+
const forkSource = payload.forkedFromThreadId === void 0 ? void 0 : nextBase.threads.find((entry) => entry.id === payload.forkedFromThreadId);
|
|
25817
26277
|
const thread = yield* decodeForEvent(OrchestrationThread, {
|
|
25818
26278
|
id: payload.threadId,
|
|
25819
26279
|
projectId: payload.projectId,
|
|
@@ -25834,7 +26294,7 @@ function projectEvent(model, event) {
|
|
|
25834
26294
|
snoozedUntil: null,
|
|
25835
26295
|
snoozedAt: null,
|
|
25836
26296
|
deletedAt: null,
|
|
25837
|
-
messages: [],
|
|
26297
|
+
messages: forkSource ? copyForkedMessages(payload.threadId, forkSource.messages) : [],
|
|
25838
26298
|
activities: [],
|
|
25839
26299
|
checkpoints: [],
|
|
25840
26300
|
session: null
|
|
@@ -26016,6 +26476,42 @@ function projectEvent(model, event) {
|
|
|
26016
26476
|
})
|
|
26017
26477
|
};
|
|
26018
26478
|
});
|
|
26479
|
+
case "thread.scheduled-task.created": return Effect.gen(function* () {
|
|
26480
|
+
const payload = yield* decodeForEvent(ThreadScheduledTaskCreatedPayload, event.payload, event.type, "payload");
|
|
26481
|
+
const thread = nextBase.threads.find((entry) => entry.id === payload.threadId);
|
|
26482
|
+
if (!thread) return nextBase;
|
|
26483
|
+
return {
|
|
26484
|
+
...nextBase,
|
|
26485
|
+
threads: updateThread(nextBase.threads, payload.threadId, {
|
|
26486
|
+
scheduledTasks: [...(thread.scheduledTasks ?? []).filter((entry) => entry.id !== payload.task.id), payload.task],
|
|
26487
|
+
updatedAt: event.occurredAt
|
|
26488
|
+
})
|
|
26489
|
+
};
|
|
26490
|
+
});
|
|
26491
|
+
case "thread.scheduled-task.cancelled":
|
|
26492
|
+
case "thread.scheduled-task.fired": return Effect.gen(function* () {
|
|
26493
|
+
const payload = event.type === "thread.scheduled-task.cancelled" ? yield* decodeForEvent(ThreadScheduledTaskCancelledPayload, event.payload, event.type, "payload") : yield* decodeForEvent(ThreadScheduledTaskFiredPayload, event.payload, event.type, "payload");
|
|
26494
|
+
const thread = nextBase.threads.find((entry) => entry.id === payload.threadId);
|
|
26495
|
+
if (!thread) return nextBase;
|
|
26496
|
+
return {
|
|
26497
|
+
...nextBase,
|
|
26498
|
+
threads: updateThread(nextBase.threads, payload.threadId, {
|
|
26499
|
+
scheduledTasks: (thread.scheduledTasks ?? []).map((task) => task.id !== payload.taskId ? task : "cancelledAt" in payload ? {
|
|
26500
|
+
...task,
|
|
26501
|
+
status: "cancelled",
|
|
26502
|
+
cancelledAt: payload.cancelledAt,
|
|
26503
|
+
updatedAt: event.occurredAt
|
|
26504
|
+
} : {
|
|
26505
|
+
...task,
|
|
26506
|
+
status: payload.failure === null ? "fired" : "failed",
|
|
26507
|
+
firedAt: payload.firedAt,
|
|
26508
|
+
failure: payload.failure,
|
|
26509
|
+
updatedAt: event.occurredAt
|
|
26510
|
+
}),
|
|
26511
|
+
updatedAt: event.occurredAt
|
|
26512
|
+
})
|
|
26513
|
+
};
|
|
26514
|
+
});
|
|
26019
26515
|
case "thread.proposed-plan-upserted": return Effect.gen(function* () {
|
|
26020
26516
|
const payload = yield* decodeForEvent(ThreadProposedPlanUpsertedPayload, event.payload, event.type, "payload");
|
|
26021
26517
|
const thread = nextBase.threads.find((entry) => entry.id === payload.threadId);
|
|
@@ -26336,6 +26832,113 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
26336
26832
|
updatedAt: command.createdAt
|
|
26337
26833
|
}
|
|
26338
26834
|
};
|
|
26835
|
+
case "thread.fork": {
|
|
26836
|
+
const source = yield* requireThread({
|
|
26837
|
+
readModel,
|
|
26838
|
+
command,
|
|
26839
|
+
threadId: command.sourceThreadId
|
|
26840
|
+
});
|
|
26841
|
+
yield* requireThreadAbsent({
|
|
26842
|
+
readModel,
|
|
26843
|
+
command,
|
|
26844
|
+
threadId: command.threadId
|
|
26845
|
+
});
|
|
26846
|
+
return {
|
|
26847
|
+
...yield* withEventBase({
|
|
26848
|
+
aggregateKind: "thread",
|
|
26849
|
+
aggregateId: command.threadId,
|
|
26850
|
+
occurredAt: command.createdAt,
|
|
26851
|
+
commandId: command.commandId
|
|
26852
|
+
}),
|
|
26853
|
+
type: "thread.created",
|
|
26854
|
+
payload: {
|
|
26855
|
+
threadId: command.threadId,
|
|
26856
|
+
projectId: source.projectId,
|
|
26857
|
+
title: command.title ?? `${source.title} (fork)`,
|
|
26858
|
+
modelSelection: source.modelSelection,
|
|
26859
|
+
runtimeMode: source.runtimeMode,
|
|
26860
|
+
interactionMode: source.interactionMode,
|
|
26861
|
+
compressMode: source.compressMode,
|
|
26862
|
+
unpromptedSubagents: source.unpromptedSubagents,
|
|
26863
|
+
branch: source.branch,
|
|
26864
|
+
worktreePath: source.worktreePath,
|
|
26865
|
+
forkedFromThreadId: source.id,
|
|
26866
|
+
createdAt: command.createdAt,
|
|
26867
|
+
updatedAt: command.createdAt
|
|
26868
|
+
}
|
|
26869
|
+
};
|
|
26870
|
+
}
|
|
26871
|
+
case "thread.scheduled-task.create":
|
|
26872
|
+
if (((yield* requireThread({
|
|
26873
|
+
readModel,
|
|
26874
|
+
command,
|
|
26875
|
+
threadId: command.threadId
|
|
26876
|
+
})).scheduledTasks ?? []).some((task) => task.id === command.taskId)) return yield* new OrchestrationCommandInvariantError({
|
|
26877
|
+
commandType: command.type,
|
|
26878
|
+
detail: `Scheduled task '${command.taskId}' already exists on thread '${command.threadId}'.`
|
|
26879
|
+
});
|
|
26880
|
+
return {
|
|
26881
|
+
...yield* withEventBase({
|
|
26882
|
+
aggregateKind: "thread",
|
|
26883
|
+
aggregateId: command.threadId,
|
|
26884
|
+
occurredAt: command.createdAt,
|
|
26885
|
+
commandId: command.commandId
|
|
26886
|
+
}),
|
|
26887
|
+
type: "thread.scheduled-task.created",
|
|
26888
|
+
payload: {
|
|
26889
|
+
threadId: command.threadId,
|
|
26890
|
+
task: {
|
|
26891
|
+
id: command.taskId,
|
|
26892
|
+
prompt: command.prompt,
|
|
26893
|
+
runAt: command.runAt,
|
|
26894
|
+
status: "pending",
|
|
26895
|
+
createdAt: command.createdAt,
|
|
26896
|
+
updatedAt: command.createdAt,
|
|
26897
|
+
firedAt: null,
|
|
26898
|
+
cancelledAt: null,
|
|
26899
|
+
failure: null
|
|
26900
|
+
}
|
|
26901
|
+
}
|
|
26902
|
+
};
|
|
26903
|
+
case "thread.scheduled-task.cancel":
|
|
26904
|
+
case "thread.scheduled-task.fire": {
|
|
26905
|
+
const task = ((yield* requireThread({
|
|
26906
|
+
readModel,
|
|
26907
|
+
command,
|
|
26908
|
+
threadId: command.threadId
|
|
26909
|
+
})).scheduledTasks ?? []).find((entry) => entry.id === command.taskId);
|
|
26910
|
+
const cancellable = task?.status === "pending" || task?.status === "failed";
|
|
26911
|
+
if (task === void 0 || (command.type === "thread.scheduled-task.fire" ? task.status !== "pending" : !cancellable)) return yield* new OrchestrationCommandInvariantError({
|
|
26912
|
+
commandType: command.type,
|
|
26913
|
+
detail: `Scheduled task '${command.taskId}' is not ${command.type === "thread.scheduled-task.fire" ? "pending" : "pending or failed"} on thread '${command.threadId}'.`
|
|
26914
|
+
});
|
|
26915
|
+
const occurredAt = command.type === "thread.scheduled-task.cancel" ? command.cancelledAt : command.firedAt;
|
|
26916
|
+
const base = yield* withEventBase({
|
|
26917
|
+
aggregateKind: "thread",
|
|
26918
|
+
aggregateId: command.threadId,
|
|
26919
|
+
occurredAt,
|
|
26920
|
+
commandId: command.commandId
|
|
26921
|
+
});
|
|
26922
|
+
if (command.type === "thread.scheduled-task.cancel") return {
|
|
26923
|
+
...base,
|
|
26924
|
+
type: "thread.scheduled-task.cancelled",
|
|
26925
|
+
payload: {
|
|
26926
|
+
threadId: command.threadId,
|
|
26927
|
+
taskId: command.taskId,
|
|
26928
|
+
cancelledAt: command.cancelledAt
|
|
26929
|
+
}
|
|
26930
|
+
};
|
|
26931
|
+
return {
|
|
26932
|
+
...base,
|
|
26933
|
+
type: "thread.scheduled-task.fired",
|
|
26934
|
+
payload: {
|
|
26935
|
+
threadId: command.threadId,
|
|
26936
|
+
taskId: command.taskId,
|
|
26937
|
+
firedAt: command.firedAt,
|
|
26938
|
+
failure: command.failure ?? null
|
|
26939
|
+
}
|
|
26940
|
+
};
|
|
26941
|
+
}
|
|
26339
26942
|
case "thread.delete": {
|
|
26340
26943
|
yield* requireThread({
|
|
26341
26944
|
readModel,
|
|
@@ -27903,6 +28506,23 @@ const ListProjectionThreadProposedPlansInput = Schema$1.Struct({ threadId: Threa
|
|
|
27903
28506
|
const DeleteProjectionThreadProposedPlansInput = Schema$1.Struct({ threadId: ThreadId });
|
|
27904
28507
|
var ProjectionThreadProposedPlanRepository = class extends Context.Service()("@p4code/cli/persistence/Services/ProjectionThreadProposedPlans/ProjectionThreadProposedPlanRepository") {};
|
|
27905
28508
|
//#endregion
|
|
28509
|
+
//#region src/persistence/Services/ProjectionThreadScheduledTasks.ts
|
|
28510
|
+
const ProjectionThreadScheduledTask = Schema$1.Struct({
|
|
28511
|
+
taskId: OrchestrationScheduledTaskId,
|
|
28512
|
+
threadId: ThreadId,
|
|
28513
|
+
prompt: TrimmedNonEmptyString,
|
|
28514
|
+
runAt: IsoDateTime,
|
|
28515
|
+
status: OrchestrationScheduledTaskStatus,
|
|
28516
|
+
createdAt: IsoDateTime,
|
|
28517
|
+
updatedAt: IsoDateTime,
|
|
28518
|
+
firedAt: Schema$1.NullOr(IsoDateTime),
|
|
28519
|
+
cancelledAt: Schema$1.NullOr(IsoDateTime),
|
|
28520
|
+
failure: Schema$1.NullOr(Schema$1.String)
|
|
28521
|
+
});
|
|
28522
|
+
const GetProjectionThreadScheduledTaskInput = Schema$1.Struct({ taskId: OrchestrationScheduledTaskId });
|
|
28523
|
+
const ListProjectionThreadScheduledTasksInput = Schema$1.Struct({ threadId: ThreadId });
|
|
28524
|
+
var ProjectionThreadScheduledTaskRepository = class extends Context.Service()("@p4code/cli/persistence/Services/ProjectionThreadScheduledTasks/ProjectionThreadScheduledTaskRepository") {};
|
|
28525
|
+
//#endregion
|
|
27906
28526
|
//#region src/persistence/Services/ProjectionThreadSessions.ts
|
|
27907
28527
|
/**
|
|
27908
28528
|
* ProjectionThreadSessionRepository - Repository interface for thread sessions.
|
|
@@ -28598,6 +29218,91 @@ const makeProjectionThreadProposedPlanRepository = Effect.gen(function* () {
|
|
|
28598
29218
|
});
|
|
28599
29219
|
const ProjectionThreadProposedPlanRepositoryLive = Layer.effect(ProjectionThreadProposedPlanRepository, makeProjectionThreadProposedPlanRepository);
|
|
28600
29220
|
//#endregion
|
|
29221
|
+
//#region src/persistence/Layers/ProjectionThreadScheduledTasks.ts
|
|
29222
|
+
const makeProjectionThreadScheduledTaskRepository = Effect.gen(function* () {
|
|
29223
|
+
const sql = yield* SqlClient.SqlClient;
|
|
29224
|
+
const upsertRow = SqlSchema.void({
|
|
29225
|
+
Request: ProjectionThreadScheduledTask,
|
|
29226
|
+
execute: (row) => sql`
|
|
29227
|
+
INSERT INTO projection_thread_scheduled_tasks (
|
|
29228
|
+
task_id,
|
|
29229
|
+
thread_id,
|
|
29230
|
+
prompt,
|
|
29231
|
+
run_at,
|
|
29232
|
+
status,
|
|
29233
|
+
created_at,
|
|
29234
|
+
updated_at,
|
|
29235
|
+
fired_at,
|
|
29236
|
+
cancelled_at,
|
|
29237
|
+
failure
|
|
29238
|
+
)
|
|
29239
|
+
VALUES (
|
|
29240
|
+
${row.taskId},
|
|
29241
|
+
${row.threadId},
|
|
29242
|
+
${row.prompt},
|
|
29243
|
+
${row.runAt},
|
|
29244
|
+
${row.status},
|
|
29245
|
+
${row.createdAt},
|
|
29246
|
+
${row.updatedAt},
|
|
29247
|
+
${row.firedAt},
|
|
29248
|
+
${row.cancelledAt},
|
|
29249
|
+
${row.failure}
|
|
29250
|
+
)
|
|
29251
|
+
ON CONFLICT (task_id)
|
|
29252
|
+
DO UPDATE SET
|
|
29253
|
+
thread_id = excluded.thread_id,
|
|
29254
|
+
prompt = excluded.prompt,
|
|
29255
|
+
run_at = excluded.run_at,
|
|
29256
|
+
status = excluded.status,
|
|
29257
|
+
created_at = excluded.created_at,
|
|
29258
|
+
updated_at = excluded.updated_at,
|
|
29259
|
+
fired_at = excluded.fired_at,
|
|
29260
|
+
cancelled_at = excluded.cancelled_at,
|
|
29261
|
+
failure = excluded.failure
|
|
29262
|
+
`
|
|
29263
|
+
});
|
|
29264
|
+
const selectColumns = sql`
|
|
29265
|
+
task_id AS "taskId",
|
|
29266
|
+
thread_id AS "threadId",
|
|
29267
|
+
prompt,
|
|
29268
|
+
run_at AS "runAt",
|
|
29269
|
+
status,
|
|
29270
|
+
created_at AS "createdAt",
|
|
29271
|
+
updated_at AS "updatedAt",
|
|
29272
|
+
fired_at AS "firedAt",
|
|
29273
|
+
cancelled_at AS "cancelledAt",
|
|
29274
|
+
failure
|
|
29275
|
+
`;
|
|
29276
|
+
const getRow = SqlSchema.findOneOption({
|
|
29277
|
+
Request: GetProjectionThreadScheduledTaskInput,
|
|
29278
|
+
Result: ProjectionThreadScheduledTask,
|
|
29279
|
+
execute: ({ taskId }) => sql`
|
|
29280
|
+
SELECT ${selectColumns}
|
|
29281
|
+
FROM projection_thread_scheduled_tasks
|
|
29282
|
+
WHERE task_id = ${taskId}
|
|
29283
|
+
`
|
|
29284
|
+
});
|
|
29285
|
+
const listRows = SqlSchema.findAll({
|
|
29286
|
+
Request: ListProjectionThreadScheduledTasksInput,
|
|
29287
|
+
Result: ProjectionThreadScheduledTask,
|
|
29288
|
+
execute: ({ threadId }) => sql`
|
|
29289
|
+
SELECT ${selectColumns}
|
|
29290
|
+
FROM projection_thread_scheduled_tasks
|
|
29291
|
+
WHERE thread_id = ${threadId}
|
|
29292
|
+
ORDER BY run_at ASC, task_id ASC
|
|
29293
|
+
`
|
|
29294
|
+
});
|
|
29295
|
+
const upsert = (row) => upsertRow(row).pipe(Effect.mapError(toPersistenceSqlError("ProjectionThreadScheduledTaskRepository.upsert:query")));
|
|
29296
|
+
const getByTaskId = (input) => getRow(input).pipe(Effect.map(Option.getOrNull), Effect.mapError(toPersistenceSqlError("ProjectionThreadScheduledTaskRepository.getByTaskId:query")));
|
|
29297
|
+
const listByThreadId = (input) => listRows(input).pipe(Effect.mapError(toPersistenceSqlError("ProjectionThreadScheduledTaskRepository.listByThreadId:query")));
|
|
29298
|
+
return {
|
|
29299
|
+
upsert,
|
|
29300
|
+
getByTaskId,
|
|
29301
|
+
listByThreadId
|
|
29302
|
+
};
|
|
29303
|
+
});
|
|
29304
|
+
const ProjectionThreadScheduledTaskRepositoryLive = Layer.effect(ProjectionThreadScheduledTaskRepository, makeProjectionThreadScheduledTaskRepository);
|
|
29305
|
+
//#endregion
|
|
28601
29306
|
//#region src/persistence/Layers/ProjectionThreadSessions.ts
|
|
28602
29307
|
const makeProjectionThreadSessionRepository = Effect.gen(function* () {
|
|
28603
29308
|
const sql = yield* SqlClient.SqlClient;
|
|
@@ -29093,182 +29798,13 @@ const makeProjectionThreadRepository = Effect.gen(function* () {
|
|
|
29093
29798
|
});
|
|
29094
29799
|
const ProjectionThreadRepositoryLive = Layer.effect(ProjectionThreadRepository, makeProjectionThreadRepository);
|
|
29095
29800
|
//#endregion
|
|
29096
|
-
//#region src/attachmentPaths.ts
|
|
29097
|
-
function normalizeAttachmentRelativePath(rawRelativePath) {
|
|
29098
|
-
const normalized = NodePath.normalize(rawRelativePath).replace(/^[/\\]+/, "");
|
|
29099
|
-
if (normalized.length === 0 || normalized.startsWith("..") || normalized.includes("\0")) return null;
|
|
29100
|
-
return normalized.replace(/\\/g, "/");
|
|
29101
|
-
}
|
|
29102
|
-
function resolveAttachmentRelativePath(input) {
|
|
29103
|
-
const normalizedRelativePath = normalizeAttachmentRelativePath(input.relativePath);
|
|
29104
|
-
if (!normalizedRelativePath) return null;
|
|
29105
|
-
const attachmentsRoot = NodePath.resolve(input.attachmentsDir);
|
|
29106
|
-
const filePath = NodePath.resolve(NodePath.join(attachmentsRoot, normalizedRelativePath));
|
|
29107
|
-
if (!filePath.startsWith(`${attachmentsRoot}${NodePath.sep}`)) return null;
|
|
29108
|
-
return filePath;
|
|
29109
|
-
}
|
|
29110
|
-
//#endregion
|
|
29111
|
-
//#region src/imageMime.ts
|
|
29112
|
-
const IMAGE_EXTENSION_BY_MIME_TYPE = {
|
|
29113
|
-
"image/avif": ".avif",
|
|
29114
|
-
"image/bmp": ".bmp",
|
|
29115
|
-
"image/gif": ".gif",
|
|
29116
|
-
"image/heic": ".heic",
|
|
29117
|
-
"image/heif": ".heif",
|
|
29118
|
-
"image/jpeg": ".jpg",
|
|
29119
|
-
"image/jpg": ".jpg",
|
|
29120
|
-
"image/png": ".png",
|
|
29121
|
-
"image/svg+xml": ".svg",
|
|
29122
|
-
"image/tiff": ".tiff",
|
|
29123
|
-
"image/webp": ".webp"
|
|
29124
|
-
};
|
|
29125
|
-
const SAFE_IMAGE_FILE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
29126
|
-
".avif",
|
|
29127
|
-
".bmp",
|
|
29128
|
-
".gif",
|
|
29129
|
-
".heic",
|
|
29130
|
-
".heif",
|
|
29131
|
-
".ico",
|
|
29132
|
-
".jpeg",
|
|
29133
|
-
".jpg",
|
|
29134
|
-
".png",
|
|
29135
|
-
".svg",
|
|
29136
|
-
".tiff",
|
|
29137
|
-
".webp"
|
|
29138
|
-
]);
|
|
29139
|
-
function isBase64Char(code) {
|
|
29140
|
-
return code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57 || code === 43 || code === 47 || code === 61;
|
|
29141
|
-
}
|
|
29142
|
-
function isBase64Whitespace(code) {
|
|
29143
|
-
return code === 13 || code === 10 || code === 32;
|
|
29144
|
-
}
|
|
29145
|
-
function parseBase64DataUrl(dataUrl) {
|
|
29146
|
-
const trimmed = dataUrl.trim();
|
|
29147
|
-
if (trimmed.slice(0, 5).toLowerCase() !== "data:") return null;
|
|
29148
|
-
const commaIndex = trimmed.indexOf(",");
|
|
29149
|
-
if (commaIndex === -1) return null;
|
|
29150
|
-
const header = trimmed.slice(5, commaIndex);
|
|
29151
|
-
if (header.length === 0) return null;
|
|
29152
|
-
const headerParts = [];
|
|
29153
|
-
for (const part of header.split(";")) {
|
|
29154
|
-
const partTrimmed = part.trim();
|
|
29155
|
-
if (partTrimmed.length > 0) headerParts.push(partTrimmed);
|
|
29156
|
-
}
|
|
29157
|
-
if (headerParts.length < 2) return null;
|
|
29158
|
-
if (headerParts.at(-1)?.toLowerCase() !== "base64") return null;
|
|
29159
|
-
const mimeType = headerParts[0]?.toLowerCase();
|
|
29160
|
-
if (!mimeType) return null;
|
|
29161
|
-
const payload = trimmed.slice(commaIndex + 1);
|
|
29162
|
-
const runs = [];
|
|
29163
|
-
let runStart = -1;
|
|
29164
|
-
for (let index = 0; index < payload.length; index += 1) {
|
|
29165
|
-
const code = payload.charCodeAt(index);
|
|
29166
|
-
if (isBase64Char(code)) {
|
|
29167
|
-
if (runStart === -1) runStart = index;
|
|
29168
|
-
continue;
|
|
29169
|
-
}
|
|
29170
|
-
if (!isBase64Whitespace(code)) return null;
|
|
29171
|
-
if (runStart !== -1) {
|
|
29172
|
-
runs.push(payload.slice(runStart, index));
|
|
29173
|
-
runStart = -1;
|
|
29174
|
-
}
|
|
29175
|
-
}
|
|
29176
|
-
if (runStart !== -1) runs.push(payload.slice(runStart));
|
|
29177
|
-
const base64 = runs.length === 1 ? runs[0] : runs.join("");
|
|
29178
|
-
if (base64.length === 0 || base64.length % 4 !== 0) return null;
|
|
29179
|
-
const firstPad = base64.indexOf("=");
|
|
29180
|
-
if (firstPad !== -1) {
|
|
29181
|
-
if (base64.length - firstPad > 2) return null;
|
|
29182
|
-
for (let index = firstPad; index < base64.length; index += 1) if (base64.charCodeAt(index) !== 61) return null;
|
|
29183
|
-
}
|
|
29184
|
-
return {
|
|
29185
|
-
mimeType,
|
|
29186
|
-
base64
|
|
29187
|
-
};
|
|
29188
|
-
}
|
|
29189
|
-
function inferImageExtension(input) {
|
|
29190
|
-
const key = input.mimeType.toLowerCase();
|
|
29191
|
-
const fromMime = Object.hasOwn(IMAGE_EXTENSION_BY_MIME_TYPE, key) ? IMAGE_EXTENSION_BY_MIME_TYPE[key] : void 0;
|
|
29192
|
-
if (fromMime) return fromMime;
|
|
29193
|
-
const fromMimeExtension = Mime.getExtension(input.mimeType);
|
|
29194
|
-
if (fromMimeExtension && SAFE_IMAGE_FILE_EXTENSIONS.has(fromMimeExtension)) return fromMimeExtension;
|
|
29195
|
-
const fileName = input.fileName?.trim() ?? "";
|
|
29196
|
-
const extensionMatch = /\.([a-z0-9]{1,8})$/i.exec(fileName);
|
|
29197
|
-
const fileNameExtension = extensionMatch ? `.${extensionMatch[1].toLowerCase()}` : "";
|
|
29198
|
-
if (SAFE_IMAGE_FILE_EXTENSIONS.has(fileNameExtension)) return fileNameExtension;
|
|
29199
|
-
return ".bin";
|
|
29200
|
-
}
|
|
29201
|
-
//#endregion
|
|
29202
|
-
//#region src/attachmentStore.ts
|
|
29203
|
-
const ATTACHMENT_FILENAME_EXTENSIONS = [
|
|
29204
|
-
...SAFE_IMAGE_FILE_EXTENSIONS,
|
|
29205
|
-
".pdf",
|
|
29206
|
-
".bin"
|
|
29207
|
-
];
|
|
29208
|
-
const ATTACHMENT_ID_THREAD_SEGMENT_MAX_CHARS = 80;
|
|
29209
|
-
const ATTACHMENT_ID_PATTERN = new RegExp(`^([a-z0-9_]+(?:-[a-z0-9_]+)*)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$`, "i");
|
|
29210
|
-
function toSafeThreadAttachmentSegment(threadId) {
|
|
29211
|
-
const segment = threadId.trim().toLowerCase().replace(/[^a-z0-9_-]+/gi, "-").replace(/-+/g, "-").replace(/^[-_]+|[-_]+$/g, "").slice(0, ATTACHMENT_ID_THREAD_SEGMENT_MAX_CHARS).replace(/[-_]+$/g, "");
|
|
29212
|
-
if (segment.length === 0) return null;
|
|
29213
|
-
return segment;
|
|
29214
|
-
}
|
|
29215
|
-
function createAttachmentId(threadId) {
|
|
29216
|
-
const threadSegment = toSafeThreadAttachmentSegment(threadId);
|
|
29217
|
-
if (!threadSegment) return null;
|
|
29218
|
-
return `${threadSegment}-${NodeCrypto.randomUUID()}`;
|
|
29219
|
-
}
|
|
29220
|
-
function parseThreadSegmentFromAttachmentId(attachmentId) {
|
|
29221
|
-
const normalizedId = normalizeAttachmentRelativePath(attachmentId);
|
|
29222
|
-
if (!normalizedId || normalizedId.includes("/") || normalizedId.includes(".")) return null;
|
|
29223
|
-
const match = normalizedId.match(ATTACHMENT_ID_PATTERN);
|
|
29224
|
-
if (!match) return null;
|
|
29225
|
-
return match[1]?.toLowerCase() ?? null;
|
|
29226
|
-
}
|
|
29227
|
-
function attachmentRelativePath(attachment) {
|
|
29228
|
-
switch (attachment.type) {
|
|
29229
|
-
case "image": {
|
|
29230
|
-
const extension = inferImageExtension({
|
|
29231
|
-
mimeType: attachment.mimeType,
|
|
29232
|
-
fileName: attachment.name
|
|
29233
|
-
});
|
|
29234
|
-
return `${attachment.id}${extension}`;
|
|
29235
|
-
}
|
|
29236
|
-
case "document": return `${attachment.id}.pdf`;
|
|
29237
|
-
}
|
|
29238
|
-
}
|
|
29239
|
-
function resolveAttachmentPath(input) {
|
|
29240
|
-
return resolveAttachmentRelativePath({
|
|
29241
|
-
attachmentsDir: input.attachmentsDir,
|
|
29242
|
-
relativePath: attachmentRelativePath(input.attachment)
|
|
29243
|
-
});
|
|
29244
|
-
}
|
|
29245
|
-
function resolveAttachmentPathById(input) {
|
|
29246
|
-
const normalizedId = normalizeAttachmentRelativePath(input.attachmentId);
|
|
29247
|
-
if (!normalizedId || normalizedId.includes("/") || normalizedId.includes(".")) return null;
|
|
29248
|
-
for (const extension of ATTACHMENT_FILENAME_EXTENSIONS) {
|
|
29249
|
-
const maybePath = resolveAttachmentRelativePath({
|
|
29250
|
-
attachmentsDir: input.attachmentsDir,
|
|
29251
|
-
relativePath: `${normalizedId}${extension}`
|
|
29252
|
-
});
|
|
29253
|
-
if (maybePath && NodeFS.existsSync(maybePath)) return maybePath;
|
|
29254
|
-
}
|
|
29255
|
-
return null;
|
|
29256
|
-
}
|
|
29257
|
-
function parseAttachmentIdFromRelativePath(relativePath) {
|
|
29258
|
-
const normalized = normalizeAttachmentRelativePath(relativePath);
|
|
29259
|
-
if (!normalized || normalized.includes("/")) return null;
|
|
29260
|
-
const extensionIndex = normalized.lastIndexOf(".");
|
|
29261
|
-
if (extensionIndex <= 0) return null;
|
|
29262
|
-
const id = normalized.slice(0, extensionIndex);
|
|
29263
|
-
return id.length > 0 && !id.includes(".") ? id : null;
|
|
29264
|
-
}
|
|
29265
|
-
//#endregion
|
|
29266
29801
|
//#region src/orchestration/Layers/ProjectionPipeline.ts
|
|
29267
29802
|
const ORCHESTRATION_PROJECTOR_NAMES = {
|
|
29268
29803
|
projects: "projection.projects",
|
|
29269
29804
|
threads: "projection.threads",
|
|
29270
29805
|
threadMessages: "projection.thread-messages",
|
|
29271
29806
|
threadProposedPlans: "projection.thread-proposed-plans",
|
|
29807
|
+
threadScheduledTasks: "projection.thread-scheduled-tasks",
|
|
29272
29808
|
threadActivities: "projection.thread-activities",
|
|
29273
29809
|
threadSessions: "projection.thread-sessions",
|
|
29274
29810
|
threadTurns: "projection.thread-turns",
|
|
@@ -29487,6 +30023,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
29487
30023
|
const projectionThreadRepository = yield* ProjectionThreadRepository;
|
|
29488
30024
|
const projectionThreadMessageRepository = yield* ProjectionThreadMessageRepository;
|
|
29489
30025
|
const projectionThreadProposedPlanRepository = yield* ProjectionThreadProposedPlanRepository;
|
|
30026
|
+
const projectionThreadScheduledTaskRepository = yield* ProjectionThreadScheduledTaskRepository;
|
|
29490
30027
|
const projectionThreadActivityRepository = yield* ProjectionThreadActivityRepository;
|
|
29491
30028
|
const projectionThreadSessionRepository = yield* ProjectionThreadSessionRepository;
|
|
29492
30029
|
const projectionTurnRepository = yield* ProjectionTurnRepository;
|
|
@@ -29494,6 +30031,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
29494
30031
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
29495
30032
|
const path = yield* Path.Path;
|
|
29496
30033
|
const serverConfig = yield* ServerConfig$1;
|
|
30034
|
+
const attachmentsRootDir = serverConfig.attachmentsDir;
|
|
29497
30035
|
const applyProjectsProjection = Effect.fn("applyProjectsProjection")(function* (event, _attachmentSideEffects) {
|
|
29498
30036
|
switch (event.type) {
|
|
29499
30037
|
case "project.created":
|
|
@@ -29893,8 +30431,34 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
29893
30431
|
default: return;
|
|
29894
30432
|
}
|
|
29895
30433
|
});
|
|
30434
|
+
const copyForkedAttachmentFile = Effect.fn("copyForkedAttachmentFile")(function* (copy) {
|
|
30435
|
+
const fromPath = resolveAttachmentRelativePath({
|
|
30436
|
+
attachmentsDir: attachmentsRootDir,
|
|
30437
|
+
relativePath: copy.fromRelativePath
|
|
30438
|
+
});
|
|
30439
|
+
const toPath = resolveAttachmentRelativePath({
|
|
30440
|
+
attachmentsDir: attachmentsRootDir,
|
|
30441
|
+
relativePath: copy.toRelativePath
|
|
30442
|
+
});
|
|
30443
|
+
if (!fromPath || !toPath) return yield* new PersistenceSqlError({
|
|
30444
|
+
operation: "ProjectionPipeline.copyForkedAttachmentFile",
|
|
30445
|
+
detail: `Unsafe attachment path while forking: ${copy.fromRelativePath}`
|
|
30446
|
+
});
|
|
30447
|
+
yield* fileSystem.copyFile(fromPath, toPath).pipe(Effect.catch((error) => error.reason._tag === "NotFound" ? Effect.logWarning("thread fork skipped a missing source attachment", { from: copy.fromRelativePath }) : Effect.fail(new PersistenceSqlError({
|
|
30448
|
+
operation: "ProjectionPipeline.copyForkedAttachmentFile",
|
|
30449
|
+
detail: `Could not copy attachment ${copy.fromRelativePath}: ${error.message}`,
|
|
30450
|
+
cause: error
|
|
30451
|
+
}))));
|
|
30452
|
+
});
|
|
29896
30453
|
const applyThreadMessagesProjection = Effect.fn("applyThreadMessagesProjection")(function* (event, attachmentSideEffects) {
|
|
29897
30454
|
switch (event.type) {
|
|
30455
|
+
case "thread.created": {
|
|
30456
|
+
if (event.payload.forkedFromThreadId === void 0) return;
|
|
30457
|
+
const sourceRows = yield* projectionThreadMessageRepository.listByThreadId({ threadId: event.payload.forkedFromThreadId });
|
|
30458
|
+
yield* Effect.forEach(collectForkedAttachmentCopies(event.payload.threadId, sourceRows), copyForkedAttachmentFile, { concurrency: 1 });
|
|
30459
|
+
yield* Effect.forEach(copyForkedProjectionMessages(event.payload.threadId, sourceRows), projectionThreadMessageRepository.upsert, { concurrency: 1 }).pipe(Effect.asVoid);
|
|
30460
|
+
return;
|
|
30461
|
+
}
|
|
29898
30462
|
case "thread.message-sent": {
|
|
29899
30463
|
const existingMessage = yield* projectionThreadMessageRepository.getByMessageId({ messageId: event.payload.messageId });
|
|
29900
30464
|
const previousMessage = Option.getOrUndefined(existingMessage);
|
|
@@ -29933,6 +30497,43 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
29933
30497
|
default: return;
|
|
29934
30498
|
}
|
|
29935
30499
|
});
|
|
30500
|
+
const applyThreadScheduledTasksProjection = Effect.fn("applyThreadScheduledTasksProjection")(function* (event) {
|
|
30501
|
+
switch (event.type) {
|
|
30502
|
+
case "thread.scheduled-task.created":
|
|
30503
|
+
yield* projectionThreadScheduledTaskRepository.upsert({
|
|
30504
|
+
taskId: event.payload.task.id,
|
|
30505
|
+
threadId: event.payload.threadId,
|
|
30506
|
+
prompt: event.payload.task.prompt,
|
|
30507
|
+
runAt: event.payload.task.runAt,
|
|
30508
|
+
status: event.payload.task.status,
|
|
30509
|
+
createdAt: event.payload.task.createdAt,
|
|
30510
|
+
updatedAt: event.payload.task.updatedAt,
|
|
30511
|
+
firedAt: event.payload.task.firedAt,
|
|
30512
|
+
cancelledAt: event.payload.task.cancelledAt,
|
|
30513
|
+
failure: event.payload.task.failure
|
|
30514
|
+
});
|
|
30515
|
+
return;
|
|
30516
|
+
case "thread.scheduled-task.cancelled":
|
|
30517
|
+
case "thread.scheduled-task.fired": {
|
|
30518
|
+
const existing = yield* projectionThreadScheduledTaskRepository.getByTaskId({ taskId: event.payload.taskId });
|
|
30519
|
+
if (existing === null) return;
|
|
30520
|
+
yield* projectionThreadScheduledTaskRepository.upsert(event.type === "thread.scheduled-task.cancelled" ? {
|
|
30521
|
+
...existing,
|
|
30522
|
+
status: "cancelled",
|
|
30523
|
+
cancelledAt: event.payload.cancelledAt,
|
|
30524
|
+
updatedAt: event.occurredAt
|
|
30525
|
+
} : {
|
|
30526
|
+
...existing,
|
|
30527
|
+
status: event.payload.failure === null ? "fired" : "failed",
|
|
30528
|
+
firedAt: event.payload.firedAt,
|
|
30529
|
+
failure: event.payload.failure,
|
|
30530
|
+
updatedAt: event.occurredAt
|
|
30531
|
+
});
|
|
30532
|
+
return;
|
|
30533
|
+
}
|
|
30534
|
+
default: return;
|
|
30535
|
+
}
|
|
30536
|
+
});
|
|
29936
30537
|
const applyThreadProposedPlansProjection = Effect.fn("applyThreadProposedPlansProjection")(function* (event, _attachmentSideEffects) {
|
|
29937
30538
|
switch (event.type) {
|
|
29938
30539
|
case "thread.proposed-plan-upserted":
|
|
@@ -30292,6 +30893,10 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30292
30893
|
name: ORCHESTRATION_PROJECTOR_NAMES.threadProposedPlans,
|
|
30293
30894
|
apply: applyThreadProposedPlansProjection
|
|
30294
30895
|
},
|
|
30896
|
+
{
|
|
30897
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.threadScheduledTasks,
|
|
30898
|
+
apply: applyThreadScheduledTasksProjection
|
|
30899
|
+
},
|
|
30295
30900
|
{
|
|
30296
30901
|
name: ORCHESTRATION_PROJECTOR_NAMES.threadActivities,
|
|
30297
30902
|
apply: applyThreadActivitiesProjection
|
|
@@ -30341,7 +30946,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30341
30946
|
projectEvent
|
|
30342
30947
|
};
|
|
30343
30948
|
});
|
|
30344
|
-
const OrchestrationProjectionPipelineLive = Layer.effect(OrchestrationProjectionPipeline, makeOrchestrationProjectionPipeline()).pipe(Layer.provideMerge(ProjectionProjectRepositoryLive), Layer.provideMerge(ProjectionThreadRepositoryLive), Layer.provideMerge(ProjectionThreadMessageRepositoryLive), Layer.provideMerge(ProjectionThreadProposedPlanRepositoryLive), Layer.provideMerge(ProjectionThreadActivityRepositoryLive), Layer.provideMerge(ProjectionThreadSessionRepositoryLive), Layer.provideMerge(ProjectionTurnRepositoryLive), Layer.provideMerge(ProjectionPendingApprovalRepositoryLive), Layer.provideMerge(ProjectionStateRepositoryLive));
|
|
30949
|
+
const OrchestrationProjectionPipelineLive = Layer.effect(OrchestrationProjectionPipeline, makeOrchestrationProjectionPipeline()).pipe(Layer.provideMerge(ProjectionProjectRepositoryLive), Layer.provideMerge(ProjectionThreadRepositoryLive), Layer.provideMerge(ProjectionThreadMessageRepositoryLive), Layer.provideMerge(ProjectionThreadProposedPlanRepositoryLive), Layer.provideMerge(ProjectionThreadScheduledTaskRepositoryLive), Layer.provideMerge(ProjectionThreadActivityRepositoryLive), Layer.provideMerge(ProjectionThreadSessionRepositoryLive), Layer.provideMerge(ProjectionTurnRepositoryLive), Layer.provideMerge(ProjectionPendingApprovalRepositoryLive), Layer.provideMerge(ProjectionStateRepositoryLive));
|
|
30345
30950
|
//#endregion
|
|
30346
30951
|
//#region src/orchestration/ThreadBackgroundLiveness.ts
|
|
30347
30952
|
/**
|
|
@@ -30369,7 +30974,7 @@ const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
|
30369
30974
|
"interrupted"
|
|
30370
30975
|
]);
|
|
30371
30976
|
var ThreadBackgroundLivenessService = class extends Context.Service()("@p4code/cli/orchestration/ThreadBackgroundLiveness/ThreadBackgroundLivenessService") {};
|
|
30372
|
-
function make$
|
|
30977
|
+
function make$75() {
|
|
30373
30978
|
const stateByThreadId = /* @__PURE__ */ new Map();
|
|
30374
30979
|
const stateFor = (threadId) => {
|
|
30375
30980
|
const existing = stateByThreadId.get(threadId);
|
|
@@ -30419,7 +31024,7 @@ function make$74() {
|
|
|
30419
31024
|
}
|
|
30420
31025
|
};
|
|
30421
31026
|
}
|
|
30422
|
-
const layer$64 = Layer.effect(ThreadBackgroundLivenessService, Effect.sync(make$
|
|
31027
|
+
const layer$64 = Layer.effect(ThreadBackgroundLivenessService, Effect.sync(make$75));
|
|
30423
31028
|
//#endregion
|
|
30424
31029
|
//#region src/persistence/Services/ProjectionCheckpoints.ts
|
|
30425
31030
|
/**
|
|
@@ -30988,12 +31593,12 @@ const runProcessCore = Effect.fn("processRunner.runProcessCore")(function* (spaw
|
|
|
30988
31593
|
stderrInvalidUtf8: stderr.invalidUtf8
|
|
30989
31594
|
};
|
|
30990
31595
|
});
|
|
30991
|
-
const make$
|
|
31596
|
+
const make$74 = Effect.fn("ProcessRunner.make")(function* () {
|
|
30992
31597
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
30993
31598
|
const run = (input) => finalizeRunProcess(runProcessCore(spawner, input), input);
|
|
30994
31599
|
return ProcessRunner.of({ run });
|
|
30995
31600
|
});
|
|
30996
|
-
const layer$63 = Layer.effect(ProcessRunner, make$
|
|
31601
|
+
const layer$63 = Layer.effect(ProcessRunner, make$74());
|
|
30997
31602
|
//#endregion
|
|
30998
31603
|
//#region src/project/RepositoryIdentityResolver.ts
|
|
30999
31604
|
const DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY = 512;
|
|
@@ -31084,7 +31689,7 @@ const resolveRepositoryIdentityFromCacheKey = Effect.fn("RepositoryIdentityResol
|
|
|
31084
31689
|
rootPath: cacheKey
|
|
31085
31690
|
}) : null;
|
|
31086
31691
|
});
|
|
31087
|
-
const make$
|
|
31692
|
+
const make$73 = Effect.fn("RepositoryIdentityResolver.make")(function* (options = {}) {
|
|
31088
31693
|
const processRunner = yield* ProcessRunner;
|
|
31089
31694
|
const repositoryIdentityCache = yield* Cache.makeWith((cacheKey) => resolveRepositoryIdentityFromCacheKey(cacheKey).pipe(Effect.provideService(ProcessRunner, processRunner)), {
|
|
31090
31695
|
capacity: options.cacheCapacity ?? DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY,
|
|
@@ -31099,7 +31704,7 @@ const make$72 = Effect.fn("RepositoryIdentityResolver.make")(function* (options
|
|
|
31099
31704
|
});
|
|
31100
31705
|
return RepositoryIdentityResolver.of({ resolve });
|
|
31101
31706
|
});
|
|
31102
|
-
const layer$62 = Layer.effect(RepositoryIdentityResolver, make$
|
|
31707
|
+
const layer$62 = Layer.effect(RepositoryIdentityResolver, make$73()).pipe(Layer.provide(layer$63));
|
|
31103
31708
|
//#endregion
|
|
31104
31709
|
//#region src/orchestration/Layers/ProjectionSnapshotQuery.ts
|
|
31105
31710
|
const decodeReadModel = Schema$1.decodeUnknownEffect(OrchestrationReadModel);
|
|
@@ -31114,6 +31719,7 @@ const ProjectionThreadMessageDbRowSchema = ProjectionThreadMessage.mapFields(Str
|
|
|
31114
31719
|
attachments: Schema$1.NullOr(Schema$1.fromJsonString(Schema$1.Array(ChatAttachment)))
|
|
31115
31720
|
}));
|
|
31116
31721
|
const ProjectionThreadProposedPlanDbRowSchema = ProjectionThreadProposedPlan;
|
|
31722
|
+
const ProjectionThreadScheduledTaskDbRowSchema = ProjectionThreadScheduledTask;
|
|
31117
31723
|
const ProjectionThreadDbRowSchema = ProjectionThread.mapFields(Struct.assign({
|
|
31118
31724
|
modelSelection: Schema$1.fromJsonString(ModelSelection),
|
|
31119
31725
|
workspaceLifecycle: Schema$1.NullOr(Schema$1.fromJsonString(ThreadWorkspaceLifecycle))
|
|
@@ -31314,6 +31920,28 @@ function mapProjectShellRow(row, repositoryIdentity) {
|
|
|
31314
31920
|
updatedAt: row.updatedAt
|
|
31315
31921
|
};
|
|
31316
31922
|
}
|
|
31923
|
+
function mapScheduledTaskRow(row) {
|
|
31924
|
+
return {
|
|
31925
|
+
id: row.taskId,
|
|
31926
|
+
prompt: row.prompt,
|
|
31927
|
+
runAt: row.runAt,
|
|
31928
|
+
status: row.status,
|
|
31929
|
+
createdAt: row.createdAt,
|
|
31930
|
+
updatedAt: row.updatedAt,
|
|
31931
|
+
firedAt: row.firedAt,
|
|
31932
|
+
cancelledAt: row.cancelledAt,
|
|
31933
|
+
failure: row.failure
|
|
31934
|
+
};
|
|
31935
|
+
}
|
|
31936
|
+
function groupScheduledTasksByThread(rows) {
|
|
31937
|
+
const byThread = /* @__PURE__ */ new Map();
|
|
31938
|
+
for (const row of rows) {
|
|
31939
|
+
const tasks = byThread.get(row.threadId) ?? [];
|
|
31940
|
+
tasks.push(mapScheduledTaskRow(row));
|
|
31941
|
+
byThread.set(row.threadId, tasks);
|
|
31942
|
+
}
|
|
31943
|
+
return byThread;
|
|
31944
|
+
}
|
|
31317
31945
|
function mapProposedPlanRow(row) {
|
|
31318
31946
|
return {
|
|
31319
31947
|
id: row.planId,
|
|
@@ -31542,6 +32170,45 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
31542
32170
|
updated_at AS "updatedAt"
|
|
31543
32171
|
FROM projection_thread_proposed_plans
|
|
31544
32172
|
ORDER BY thread_id ASC, created_at ASC, plan_id ASC
|
|
32173
|
+
`
|
|
32174
|
+
});
|
|
32175
|
+
const listThreadScheduledTaskRows = SqlSchema.findAll({
|
|
32176
|
+
Request: Schema$1.Void,
|
|
32177
|
+
Result: ProjectionThreadScheduledTaskDbRowSchema,
|
|
32178
|
+
execute: () => sql`
|
|
32179
|
+
SELECT
|
|
32180
|
+
task_id AS "taskId",
|
|
32181
|
+
thread_id AS "threadId",
|
|
32182
|
+
prompt,
|
|
32183
|
+
run_at AS "runAt",
|
|
32184
|
+
status,
|
|
32185
|
+
created_at AS "createdAt",
|
|
32186
|
+
updated_at AS "updatedAt",
|
|
32187
|
+
fired_at AS "firedAt",
|
|
32188
|
+
cancelled_at AS "cancelledAt",
|
|
32189
|
+
failure
|
|
32190
|
+
FROM projection_thread_scheduled_tasks
|
|
32191
|
+
ORDER BY thread_id ASC, run_at ASC, task_id ASC
|
|
32192
|
+
`
|
|
32193
|
+
});
|
|
32194
|
+
const listThreadScheduledTaskRowsByThread = SqlSchema.findAll({
|
|
32195
|
+
Request: ThreadIdLookupInput,
|
|
32196
|
+
Result: ProjectionThreadScheduledTaskDbRowSchema,
|
|
32197
|
+
execute: ({ threadId }) => sql`
|
|
32198
|
+
SELECT
|
|
32199
|
+
task_id AS "taskId",
|
|
32200
|
+
thread_id AS "threadId",
|
|
32201
|
+
prompt,
|
|
32202
|
+
run_at AS "runAt",
|
|
32203
|
+
status,
|
|
32204
|
+
created_at AS "createdAt",
|
|
32205
|
+
updated_at AS "updatedAt",
|
|
32206
|
+
fired_at AS "firedAt",
|
|
32207
|
+
cancelled_at AS "cancelledAt",
|
|
32208
|
+
failure
|
|
32209
|
+
FROM projection_thread_scheduled_tasks
|
|
32210
|
+
WHERE thread_id = ${threadId}
|
|
32211
|
+
ORDER BY run_at ASC, task_id ASC
|
|
31545
32212
|
`
|
|
31546
32213
|
});
|
|
31547
32214
|
const listThreadActivityRows = SqlSchema.findAll({
|
|
@@ -32330,8 +32997,10 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32330
32997
|
listTurnSummaryRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getSnapshot:listTurnSummaries:query", "ProjectionSnapshotQuery.getSnapshot:listTurnSummaries:decodeRows"))),
|
|
32331
32998
|
listLatestTurnRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getSnapshot:listLatestTurns:query", "ProjectionSnapshotQuery.getSnapshot:listLatestTurns:decodeRows"))),
|
|
32332
32999
|
listProjectionStateRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getSnapshot:listProjectionState:query", "ProjectionSnapshotQuery.getSnapshot:listProjectionState:decodeRows"))),
|
|
32333
|
-
listThreadPairRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getSnapshot:listThreadPairs:query", "ProjectionSnapshotQuery.getSnapshot:listThreadPairs:decodeRows")))
|
|
32334
|
-
|
|
33000
|
+
listThreadPairRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getSnapshot:listThreadPairs:query", "ProjectionSnapshotQuery.getSnapshot:listThreadPairs:decodeRows"))),
|
|
33001
|
+
listThreadScheduledTaskRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getSnapshot:listThreadScheduledTasks:query", "ProjectionSnapshotQuery.getSnapshot:listThreadScheduledTasks:decodeRows")))
|
|
33002
|
+
])).pipe(Effect.flatMap(([projectRows, threadRows, messageRows, proposedPlanRows, activityRows, sessionRows, checkpointRows, turnRows, latestTurnRows, stateRows, threadPairRows, scheduledTaskRows]) => Effect.gen(function* () {
|
|
33003
|
+
const scheduledTasksByThread = groupScheduledTasksByThread(scheduledTaskRows);
|
|
32335
33004
|
const messagesByThread = /* @__PURE__ */ new Map();
|
|
32336
33005
|
const proposedPlansByThread = /* @__PURE__ */ new Map();
|
|
32337
33006
|
const activitiesByThread = /* @__PURE__ */ new Map();
|
|
@@ -32465,6 +33134,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32465
33134
|
deletedAt: row.deletedAt,
|
|
32466
33135
|
messages: messagesByThread.get(row.threadId) ?? [],
|
|
32467
33136
|
proposedPlans: proposedPlansByThread.get(row.threadId) ?? [],
|
|
33137
|
+
scheduledTasks: scheduledTasksByThread.get(row.threadId) ?? [],
|
|
32468
33138
|
activities: activitiesByThread.get(row.threadId) ?? [],
|
|
32469
33139
|
checkpoints: checkpointsByThread.get(row.threadId) ?? [],
|
|
32470
33140
|
session: sessionsByThread.get(row.threadId) ?? null
|
|
@@ -32509,8 +33179,10 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32509
33179
|
listThreadSessionRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getCommandReadModel:listThreadSessions:query", "ProjectionSnapshotQuery.getCommandReadModel:listThreadSessions:decodeRows"))),
|
|
32510
33180
|
listLatestTurnRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getCommandReadModel:listLatestTurns:query", "ProjectionSnapshotQuery.getCommandReadModel:listLatestTurns:decodeRows"))),
|
|
32511
33181
|
listProjectionStateRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getCommandReadModel:listProjectionState:query", "ProjectionSnapshotQuery.getCommandReadModel:listProjectionState:decodeRows"))),
|
|
32512
|
-
listThreadPairRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getCommandReadModel:listThreadPairs:query", "ProjectionSnapshotQuery.getCommandReadModel:listThreadPairs:decodeRows")))
|
|
32513
|
-
|
|
33182
|
+
listThreadPairRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getCommandReadModel:listThreadPairs:query", "ProjectionSnapshotQuery.getCommandReadModel:listThreadPairs:decodeRows"))),
|
|
33183
|
+
listThreadScheduledTaskRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getCommandReadModel:listThreadScheduledTasks:query", "ProjectionSnapshotQuery.getCommandReadModel:listThreadScheduledTasks:decodeRows")))
|
|
33184
|
+
])).pipe(Effect.flatMap(([projectRows, threadRows, proposedPlanRows, sessionRows, latestTurnRows, stateRows, threadPairRows, scheduledTaskRows]) => Effect.sync(() => {
|
|
33185
|
+
const scheduledTasksByThread = groupScheduledTasksByThread(scheduledTaskRows);
|
|
32514
33186
|
let updatedAt = null;
|
|
32515
33187
|
const projects = [];
|
|
32516
33188
|
const threads = [];
|
|
@@ -32605,6 +33277,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32605
33277
|
deletedAt: row.deletedAt,
|
|
32606
33278
|
messages: [],
|
|
32607
33279
|
proposedPlans: proposedPlansByThread.get(row.threadId) ?? [],
|
|
33280
|
+
scheduledTasks: scheduledTasksByThread.get(row.threadId) ?? [],
|
|
32608
33281
|
activities: [],
|
|
32609
33282
|
checkpoints: [],
|
|
32610
33283
|
session: sessionByThread.get(row.threadId) ?? null
|
|
@@ -32857,7 +33530,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32857
33530
|
});
|
|
32858
33531
|
});
|
|
32859
33532
|
const getThreadDetailByIdBounded = (threadId, bounds) => Effect.gen(function* () {
|
|
32860
|
-
const [threadRow, messageRows, proposedPlanRows, activityRows, checkpointRows, turnRows, latestTurnRow, sessionRow] = yield* Effect.all([
|
|
33533
|
+
const [threadRow, messageRows, proposedPlanRows, activityRows, checkpointRows, turnRows, latestTurnRow, sessionRow, scheduledTaskRows] = yield* Effect.all([
|
|
32861
33534
|
getActiveThreadRowById({ threadId }).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getThreadDetailById:getThread:query", "ProjectionSnapshotQuery.getThreadDetailById:getThread:decodeRow"))),
|
|
32862
33535
|
(bounds === void 0 ? listThreadMessageRowsByThread({ threadId }) : listThreadMessageRowsByThreadWindow({
|
|
32863
33536
|
threadId,
|
|
@@ -32871,7 +33544,8 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32871
33544
|
listCheckpointRowsByThread({ threadId }).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getThreadDetailById:listCheckpoints:query", "ProjectionSnapshotQuery.getThreadDetailById:listCheckpoints:decodeRows"))),
|
|
32872
33545
|
listTurnSummaryRowsByThread({ threadId }).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getThreadDetailById:listTurnSummaries:query", "ProjectionSnapshotQuery.getThreadDetailById:listTurnSummaries:decodeRows"))),
|
|
32873
33546
|
getLatestTurnRowByThread({ threadId }).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getThreadDetailById:getLatestTurn:query", "ProjectionSnapshotQuery.getThreadDetailById:getLatestTurn:decodeRow"))),
|
|
32874
|
-
getThreadSessionRowByThread({ threadId }).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getThreadDetailById:getSession:query", "ProjectionSnapshotQuery.getThreadDetailById:getSession:decodeRow")))
|
|
33547
|
+
getThreadSessionRowByThread({ threadId }).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getThreadDetailById:getSession:query", "ProjectionSnapshotQuery.getThreadDetailById:getSession:decodeRow"))),
|
|
33548
|
+
listThreadScheduledTaskRowsByThread({ threadId }).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getThreadDetailById:listScheduledTasks:query", "ProjectionSnapshotQuery.getThreadDetailById:listScheduledTasks:decodeRows")))
|
|
32875
33549
|
]);
|
|
32876
33550
|
if (Option.isNone(threadRow)) return Option.none();
|
|
32877
33551
|
const thread = {
|
|
@@ -32912,6 +33586,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32912
33586
|
return message;
|
|
32913
33587
|
}),
|
|
32914
33588
|
proposedPlans: proposedPlanRows.map(mapProposedPlanRow),
|
|
33589
|
+
scheduledTasks: scheduledTaskRows.map(mapScheduledTaskRow),
|
|
32915
33590
|
activities: activityRows.map((row) => {
|
|
32916
33591
|
const activity = {
|
|
32917
33592
|
id: row.activityId,
|
|
@@ -33564,7 +34239,7 @@ function mergeWithDefaultKeybindings(custom) {
|
|
|
33564
34239
|
* Keybindings - Service tag for keybinding configuration operations.
|
|
33565
34240
|
*/
|
|
33566
34241
|
var Keybindings = class extends Context.Service()("@p4code/cli/keybindings") {};
|
|
33567
|
-
const make$
|
|
34242
|
+
const make$72 = Effect.gen(function* () {
|
|
33568
34243
|
const { keybindingsConfigPath } = yield* ServerConfig$1;
|
|
33569
34244
|
const fs = yield* FileSystem.FileSystem;
|
|
33570
34245
|
const path = yield* Path.Path;
|
|
@@ -33825,7 +34500,7 @@ const make$71 = Effect.gen(function* () {
|
|
|
33825
34500
|
}))
|
|
33826
34501
|
};
|
|
33827
34502
|
});
|
|
33828
|
-
const layer$61 = Layer.effect(Keybindings, make$
|
|
34503
|
+
const layer$61 = Layer.effect(Keybindings, make$72);
|
|
33829
34504
|
//#endregion
|
|
33830
34505
|
//#region src/process/externalLauncher.ts
|
|
33831
34506
|
/**
|
|
@@ -34052,7 +34727,7 @@ const launchEditorProcess = Effect.fn("externalLauncher.launchEditorProcess")(fu
|
|
|
34052
34727
|
cause
|
|
34053
34728
|
}));
|
|
34054
34729
|
});
|
|
34055
|
-
const make$
|
|
34730
|
+
const make$71 = Effect.gen(function* () {
|
|
34056
34731
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
34057
34732
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
34058
34733
|
const path = yield* Path.Path;
|
|
@@ -34063,7 +34738,7 @@ const make$70 = Effect.gen(function* () {
|
|
|
34063
34738
|
launchEditor: (input) => provideCommandResolutionServices(Effect.flatMap(resolveEditorLaunch(input), (launch) => launchEditorProcess(launch).pipe(Effect.provideService(ChildProcessSpawner$1.ChildProcessSpawner, spawner))))
|
|
34064
34739
|
});
|
|
34065
34740
|
});
|
|
34066
|
-
const layer$60 = Layer.effect(ExternalLauncher, make$
|
|
34741
|
+
const layer$60 = Layer.effect(ExternalLauncher, make$71);
|
|
34067
34742
|
//#endregion
|
|
34068
34743
|
//#region src/orchestration/Services/OrchestrationReactor.ts
|
|
34069
34744
|
/**
|
|
@@ -34081,7 +34756,7 @@ var OrchestrationReactor = class extends Context.Service()("@p4code/cli/orchestr
|
|
|
34081
34756
|
//#endregion
|
|
34082
34757
|
//#region src/serverLifecycleEvents.ts
|
|
34083
34758
|
var ServerLifecycleEvents = class extends Context.Service()("@p4code/cli/serverLifecycleEvents") {};
|
|
34084
|
-
const make$
|
|
34759
|
+
const make$70 = Effect.gen(function* () {
|
|
34085
34760
|
const pubsub = yield* PubSub.unbounded();
|
|
34086
34761
|
const state = yield* Ref.make({
|
|
34087
34762
|
sequence: 0,
|
|
@@ -34105,7 +34780,7 @@ const make$69 = Effect.gen(function* () {
|
|
|
34105
34780
|
}
|
|
34106
34781
|
};
|
|
34107
34782
|
});
|
|
34108
|
-
const layer$59 = Layer.effect(ServerLifecycleEvents, make$
|
|
34783
|
+
const layer$59 = Layer.effect(ServerLifecycleEvents, make$70);
|
|
34109
34784
|
//#endregion
|
|
34110
34785
|
//#region src/telemetry/Identify.ts
|
|
34111
34786
|
const CodexAuthJsonSchema = Schema$1.Struct({ tokens: Schema$1.Struct({ account_id: Schema$1.String }) });
|
|
@@ -34278,7 +34953,7 @@ var AnalyticsService = class AnalyticsService extends Context.Service()("@p4code
|
|
|
34278
34953
|
/** No-op layer for callers that intentionally disable telemetry. */
|
|
34279
34954
|
static layerTest = Layer.succeed(AnalyticsService, inert);
|
|
34280
34955
|
};
|
|
34281
|
-
const make$
|
|
34956
|
+
const make$69 = Effect.gen(function* () {
|
|
34282
34957
|
const telemetryConfig = yield* TelemetryEnvConfig;
|
|
34283
34958
|
const posthogKey = telemetryConfig.posthogKey.trim();
|
|
34284
34959
|
if (!telemetryConfig.enabled || posthogKey === "") return inert;
|
|
@@ -34348,7 +35023,7 @@ const make$68 = Effect.gen(function* () {
|
|
|
34348
35023
|
flush
|
|
34349
35024
|
});
|
|
34350
35025
|
});
|
|
34351
|
-
const layer$58 = Layer.effect(AnalyticsService, make$
|
|
35026
|
+
const layer$58 = Layer.effect(AnalyticsService, make$69);
|
|
34352
35027
|
AnalyticsService.layerTest;
|
|
34353
35028
|
//#endregion
|
|
34354
35029
|
//#region src/service/pinnedRuntime.ts
|
|
@@ -34695,7 +35370,7 @@ var BootServiceInstallError = class extends Schema$1.TaggedErrorClass()("BootSer
|
|
|
34695
35370
|
}
|
|
34696
35371
|
};
|
|
34697
35372
|
var BootService = class extends Context.Service()("@p4code/cli/service/bootService") {};
|
|
34698
|
-
const make$
|
|
35373
|
+
const make$68 = Effect.fn("cloud.boot_service.make")(function* (input) {
|
|
34699
35374
|
const hostExecPath = yield* HostProcessExecutablePath;
|
|
34700
35375
|
const hostArguments = yield* HostProcessArguments;
|
|
34701
35376
|
const host = input.host ?? {
|
|
@@ -34917,7 +35592,7 @@ const make$67 = Effect.fn("cloud.boot_service.make")(function* (input) {
|
|
|
34917
35592
|
logPath
|
|
34918
35593
|
});
|
|
34919
35594
|
});
|
|
34920
|
-
const layer$57 = (input) => Layer.effect(BootService, make$
|
|
35595
|
+
const layer$57 = (input) => Layer.effect(BootService, make$68(input));
|
|
34921
35596
|
//#endregion
|
|
34922
35597
|
//#region src/service/selfUpdate.ts
|
|
34923
35598
|
/**
|
|
@@ -34992,7 +35667,7 @@ const resolveServerSelfUpdateCapability = Effect.fn("cloud.server_self_update.re
|
|
|
34992
35667
|
return null;
|
|
34993
35668
|
});
|
|
34994
35669
|
var ServerSelfUpdate = class extends Context.Service()("@p4code/cli/service/selfUpdate/ServerSelfUpdate") {};
|
|
34995
|
-
const make$
|
|
35670
|
+
const make$67 = Effect.fn("cloud.server_self_update.make")(function* (options) {
|
|
34996
35671
|
const serverConfig = yield* ServerConfig$1;
|
|
34997
35672
|
const fs = yield* FileSystem.FileSystem;
|
|
34998
35673
|
const path = yield* Path.Path;
|
|
@@ -35142,7 +35817,7 @@ const make$66 = Effect.fn("cloud.server_self_update.make")(function* (options) {
|
|
|
35142
35817
|
});
|
|
35143
35818
|
return ServerSelfUpdate.of({ update });
|
|
35144
35819
|
});
|
|
35145
|
-
const layer$56 = Layer.effect(ServerSelfUpdate, make$
|
|
35820
|
+
const layer$56 = Layer.effect(ServerSelfUpdate, make$67()).pipe(Layer.provide(layer$63));
|
|
35146
35821
|
//#endregion
|
|
35147
35822
|
//#region src/environment/ServerEnvironmentLabel.ts
|
|
35148
35823
|
const ServerEnvironmentLabelCommandProbe = Schema$1.Literals(["macos-computer-name", "linux-pretty-hostname"]);
|
|
@@ -35274,7 +35949,7 @@ function platformArch(architecture) {
|
|
|
35274
35949
|
default: return "other";
|
|
35275
35950
|
}
|
|
35276
35951
|
}
|
|
35277
|
-
const make$
|
|
35952
|
+
const make$66 = Effect.gen(function* () {
|
|
35278
35953
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
35279
35954
|
const path = yield* Path.Path;
|
|
35280
35955
|
const serverConfig = yield* ServerConfig$1;
|
|
@@ -35325,6 +36000,8 @@ const make$65 = Effect.gen(function* () {
|
|
|
35325
36000
|
threadSettlement: true,
|
|
35326
36001
|
threadSnooze: true,
|
|
35327
36002
|
threadPinning: true,
|
|
36003
|
+
threadFork: true,
|
|
36004
|
+
threadScheduledTasks: true,
|
|
35328
36005
|
...serverSelfUpdate === null ? {} : { serverSelfUpdate },
|
|
35329
36006
|
...serverServiceSupervised ? { serverServiceSupervised } : {}
|
|
35330
36007
|
}
|
|
@@ -35339,7 +36016,7 @@ const make$65 = Effect.gen(function* () {
|
|
|
35339
36016
|
* state. It intentionally has no fallback Layer.succeed value: callers must
|
|
35340
36017
|
* provide the external platform services and a ServerConfig.
|
|
35341
36018
|
*/
|
|
35342
|
-
const layer$55 = Layer.effect(ServerEnvironment, make$
|
|
36019
|
+
const layer$55 = Layer.effect(ServerEnvironment, make$66).pipe(Layer.provide(layer$63));
|
|
35343
36020
|
//#endregion
|
|
35344
36021
|
//#region src/provider/Services/ProviderSessionReaper.ts
|
|
35345
36022
|
var ProviderSessionReaper = class extends Context.Service()("@p4code/cli/provider/Services/ProviderSessionReaper") {};
|
|
@@ -35481,7 +36158,7 @@ const maybeOpenBrowser = (target) => Effect.gen(function* () {
|
|
|
35481
36158
|
yield* (yield* ExternalLauncher).launchBrowser(target).pipe(Effect.catch(() => Effect.logInfo("browser auto-open unavailable", { hint: `Open ${target} in your browser.` })));
|
|
35482
36159
|
});
|
|
35483
36160
|
const runStartupPhase = (phase, effect) => effect.pipe(Effect.annotateSpans({ "startup.phase": phase }), Effect.withSpan(`server.startup.${phase}`));
|
|
35484
|
-
const make$
|
|
36161
|
+
const make$65 = Effect.gen(function* () {
|
|
35485
36162
|
const serverConfig = yield* ServerConfig$1;
|
|
35486
36163
|
const keybindings = yield* Keybindings;
|
|
35487
36164
|
const orchestrationReactor = yield* OrchestrationReactor;
|
|
@@ -35622,7 +36299,7 @@ const make$64 = Effect.gen(function* () {
|
|
|
35622
36299
|
enqueueCommand: commandGate.enqueueCommand
|
|
35623
36300
|
};
|
|
35624
36301
|
});
|
|
35625
|
-
const layer$54 = Layer.effect(ServerRuntimeStartup, make$
|
|
36302
|
+
const layer$54 = Layer.effect(ServerRuntimeStartup, make$65);
|
|
35626
36303
|
//#endregion
|
|
35627
36304
|
//#region src/serverRuntimeState.ts
|
|
35628
36305
|
const PersistedServerRuntimeState = Schema$1.Struct({
|
|
@@ -35779,7 +36456,7 @@ function expandHomePath$2(input, path) {
|
|
|
35779
36456
|
if (input.startsWith("~/") || input.startsWith("~\\")) return path.join(NodeOS.homedir(), input.slice(2));
|
|
35780
36457
|
return input;
|
|
35781
36458
|
}
|
|
35782
|
-
const make$
|
|
36459
|
+
const make$64 = Effect.gen(function* () {
|
|
35783
36460
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
35784
36461
|
const path = yield* Path.Path;
|
|
35785
36462
|
const statWorkspaceRoot = Effect.fn("WorkspacePaths.statWorkspaceRoot")(function* (workspaceRoot, normalizedWorkspaceRoot, phase) {
|
|
@@ -35836,7 +36513,7 @@ const make$63 = Effect.gen(function* () {
|
|
|
35836
36513
|
resolveRelativePathWithinRoot
|
|
35837
36514
|
});
|
|
35838
36515
|
});
|
|
35839
|
-
const layer$53 = Layer.effect(WorkspacePaths, make$
|
|
36516
|
+
const layer$53 = Layer.effect(WorkspacePaths, make$64);
|
|
35840
36517
|
//#endregion
|
|
35841
36518
|
//#region src/cli/project.ts
|
|
35842
36519
|
const isEnvironmentHttpCommonError = Schema$1.is(EnvironmentHttpCommonError);
|
|
@@ -37019,7 +37696,7 @@ const logP4ProjectFileLoadError = (error) => Effect.logWarning(error).pipe(Effec
|
|
|
37019
37696
|
filePath: error.filePath,
|
|
37020
37697
|
errorTag: error._tag
|
|
37021
37698
|
}));
|
|
37022
|
-
const make$
|
|
37699
|
+
const make$63 = Effect.gen(function* () {
|
|
37023
37700
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
37024
37701
|
const path = yield* Path.Path;
|
|
37025
37702
|
const load = Effect.fn("P4ProjectFileLoader.load")(function* (workspaceRoot) {
|
|
@@ -37040,7 +37717,7 @@ const make$62 = Effect.gen(function* () {
|
|
|
37040
37717
|
});
|
|
37041
37718
|
return P4ProjectFileLoader.of({ load });
|
|
37042
37719
|
});
|
|
37043
|
-
const layer$52 = Layer.effect(P4ProjectFileLoader, make$
|
|
37720
|
+
const layer$52 = Layer.effect(P4ProjectFileLoader, make$63);
|
|
37044
37721
|
//#endregion
|
|
37045
37722
|
//#region src/project/ProjectFaviconResolver.ts
|
|
37046
37723
|
/**
|
|
@@ -37115,7 +37792,7 @@ function extractIconHref(source) {
|
|
|
37115
37792
|
return null;
|
|
37116
37793
|
}
|
|
37117
37794
|
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) }));
|
|
37118
|
-
const make$
|
|
37795
|
+
const make$62 = Effect.gen(function* () {
|
|
37119
37796
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
37120
37797
|
const path = yield* Path.Path;
|
|
37121
37798
|
const workspacePaths = yield* WorkspacePaths;
|
|
@@ -37184,7 +37861,7 @@ const make$61 = Effect.gen(function* () {
|
|
|
37184
37861
|
});
|
|
37185
37862
|
return ProjectFaviconResolver.of({ resolvePath });
|
|
37186
37863
|
});
|
|
37187
|
-
const layer$51 = Layer.effect(ProjectFaviconResolver, make$
|
|
37864
|
+
const layer$51 = Layer.effect(ProjectFaviconResolver, make$62);
|
|
37188
37865
|
//#endregion
|
|
37189
37866
|
//#region src/assets/AssetAccess.ts
|
|
37190
37867
|
const ASSET_ROUTE_PREFIX = "/api/assets";
|
|
@@ -37595,10 +38272,10 @@ const resolveAsset = Effect.fn("AssetAccess.resolveAsset")(function* (token, rel
|
|
|
37595
38272
|
//#endregion
|
|
37596
38273
|
//#region src/observability/BrowserTraceCollector.ts
|
|
37597
38274
|
var BrowserTraceCollector = class extends Context.Service()("@p4code/cli/observability/BrowserTraceCollector") {};
|
|
37598
|
-
const make$
|
|
38275
|
+
const make$61 = (sink) => BrowserTraceCollector.of({ record: (records) => Effect.sync(() => {
|
|
37599
38276
|
for (const record of records) sink.push(record);
|
|
37600
38277
|
}) });
|
|
37601
|
-
const layer$50 = (sink) => Layer.succeed(BrowserTraceCollector, make$
|
|
38278
|
+
const layer$50 = (sink) => Layer.succeed(BrowserTraceCollector, make$61(sink));
|
|
37602
38279
|
//#endregion
|
|
37603
38280
|
//#region src/auth/http.ts
|
|
37604
38281
|
const CREDENTIAL_RESPONSE_HEADERS = {
|
|
@@ -40651,7 +41328,7 @@ const classifyNonZeroExit = (command, stderr) => {
|
|
|
40651
41328
|
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";
|
|
40652
41329
|
return "command-failed";
|
|
40653
41330
|
};
|
|
40654
|
-
const make$
|
|
41331
|
+
const make$60 = Effect.gen(function* () {
|
|
40655
41332
|
const processRunner = yield* ProcessRunner;
|
|
40656
41333
|
const run = Effect.fn("VcsProcess.run")(function* (input) {
|
|
40657
41334
|
const baseError = {
|
|
@@ -40710,7 +41387,7 @@ const make$59 = Effect.gen(function* () {
|
|
|
40710
41387
|
});
|
|
40711
41388
|
return VcsProcess.of({ run });
|
|
40712
41389
|
});
|
|
40713
|
-
const layer$49 = Layer.effect(VcsProcess, make$
|
|
41390
|
+
const layer$49 = Layer.effect(VcsProcess, make$60).pipe(Layer.provide(layer$63));
|
|
40714
41391
|
//#endregion
|
|
40715
41392
|
//#region src/vcs/VcsDriver.ts
|
|
40716
41393
|
var VcsDriver = class extends Context.Service()("@p4code/cli/vcs/VcsDriver") {};
|
|
@@ -41161,12 +41838,12 @@ const makeVcsDriver = Effect.gen(function* () {
|
|
|
41161
41838
|
const driver = yield* makeVcsDriverShape();
|
|
41162
41839
|
return VcsDriver.of(driver);
|
|
41163
41840
|
});
|
|
41164
|
-
const make$
|
|
41841
|
+
const make$59 = Effect.gen(function* () {
|
|
41165
41842
|
const git = yield* makeGitVcsDriverCore();
|
|
41166
41843
|
return GitVcsDriver.of(git);
|
|
41167
41844
|
});
|
|
41168
41845
|
Layer.effect(VcsDriver, makeVcsDriver);
|
|
41169
|
-
const layer$48 = Layer.effect(GitVcsDriver, make$
|
|
41846
|
+
const layer$48 = Layer.effect(GitVcsDriver, make$59);
|
|
41170
41847
|
//#endregion
|
|
41171
41848
|
//#region src/vcs/VcsProjectConfig.ts
|
|
41172
41849
|
const ProjectVcsConfigJson = fromLenientJson(Schema$1.Struct({
|
|
@@ -41198,7 +41875,7 @@ const logVcsProjectConfigError = (error) => Effect.logWarning(error).pipe(Effect
|
|
|
41198
41875
|
configPath: error.configPath,
|
|
41199
41876
|
errorTag: error._tag
|
|
41200
41877
|
}));
|
|
41201
|
-
const make$
|
|
41878
|
+
const make$58 = Effect.gen(function* () {
|
|
41202
41879
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
41203
41880
|
const path = yield* Path.Path;
|
|
41204
41881
|
const findConfigPath = Effect.fn("VcsProjectConfig.findConfigPath")(function* (cwd) {
|
|
@@ -41239,7 +41916,7 @@ const make$57 = Effect.gen(function* () {
|
|
|
41239
41916
|
});
|
|
41240
41917
|
return VcsProjectConfig.of({ resolveKind });
|
|
41241
41918
|
});
|
|
41242
|
-
const layer$47 = Layer.effect(VcsProjectConfig, make$
|
|
41919
|
+
const layer$47 = Layer.effect(VcsProjectConfig, make$58);
|
|
41243
41920
|
//#endregion
|
|
41244
41921
|
//#region src/vcs/VcsDriverRegistry.ts
|
|
41245
41922
|
const DETECTION_CACHE_CAPACITY = 2048;
|
|
@@ -41259,7 +41936,7 @@ function parseDetectionCacheKey(key) {
|
|
|
41259
41936
|
cwd: key.slice(separatorIndex + 1)
|
|
41260
41937
|
};
|
|
41261
41938
|
}
|
|
41262
|
-
const make$
|
|
41939
|
+
const make$57 = Effect.gen(function* () {
|
|
41263
41940
|
const projectConfig = yield* VcsProjectConfig;
|
|
41264
41941
|
const git = yield* makeVcsDriver;
|
|
41265
41942
|
const drivers = { git };
|
|
@@ -41316,7 +41993,7 @@ const make$56 = Effect.gen(function* () {
|
|
|
41316
41993
|
resolve
|
|
41317
41994
|
});
|
|
41318
41995
|
});
|
|
41319
|
-
const layer$46 = Layer.effect(VcsDriverRegistry, make$
|
|
41996
|
+
const layer$46 = Layer.effect(VcsDriverRegistry, make$57).pipe(Layer.provide(layer$47));
|
|
41320
41997
|
//#endregion
|
|
41321
41998
|
//#region src/checkpointing/CheckpointStore.ts
|
|
41322
41999
|
/**
|
|
@@ -41336,7 +42013,7 @@ const layer$46 = Layer.effect(VcsDriverRegistry, make$56).pipe(Layer.provide(lay
|
|
|
41336
42013
|
*/
|
|
41337
42014
|
/** Service tag for checkpoint persistence and restore operations. */
|
|
41338
42015
|
var CheckpointStore = class extends Context.Service()("@p4code/cli/checkpointing/CheckpointStore") {};
|
|
41339
|
-
const make$
|
|
42016
|
+
const make$56 = Effect.gen(function* () {
|
|
41340
42017
|
const vcsRegistry = yield* VcsDriverRegistry;
|
|
41341
42018
|
const resolveCheckpoints = Effect.fn("CheckpointStore.resolveCheckpoints")(function* (operation, cwd) {
|
|
41342
42019
|
const handle = yield* vcsRegistry.resolve({ cwd });
|
|
@@ -41375,7 +42052,7 @@ const make$55 = Effect.gen(function* () {
|
|
|
41375
42052
|
deleteCheckpointRefs
|
|
41376
42053
|
});
|
|
41377
42054
|
});
|
|
41378
|
-
const layer$45 = Layer.effect(CheckpointStore, make$
|
|
42055
|
+
const layer$45 = Layer.effect(CheckpointStore, make$56);
|
|
41379
42056
|
//#endregion
|
|
41380
42057
|
//#region src/checkpointing/CheckpointDiffQuery.ts
|
|
41381
42058
|
/**
|
|
@@ -41397,7 +42074,7 @@ function buildTurnDiffResult(input, diff) {
|
|
|
41397
42074
|
diff
|
|
41398
42075
|
};
|
|
41399
42076
|
}
|
|
41400
|
-
const make$
|
|
42077
|
+
const make$55 = Effect.gen(function* () {
|
|
41401
42078
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
41402
42079
|
const checkpointStore = yield* CheckpointStore;
|
|
41403
42080
|
const threadActivities = yield* ProjectionThreadActivityRepository;
|
|
@@ -41568,7 +42245,7 @@ const make$54 = Effect.gen(function* () {
|
|
|
41568
42245
|
getFullThreadDiff
|
|
41569
42246
|
});
|
|
41570
42247
|
});
|
|
41571
|
-
const layer$44 = Layer.effect(CheckpointDiffQuery, make$
|
|
42248
|
+
const layer$44 = Layer.effect(CheckpointDiffQuery, make$55);
|
|
41572
42249
|
//#endregion
|
|
41573
42250
|
//#region src/orchestration/Normalizer.ts
|
|
41574
42251
|
const canonicalizeClientCommandTimestamps = (command, receivedAt) => {
|
|
@@ -41683,11 +42360,11 @@ const makeTextGenerationFromRegistry = (registry) => TextGeneration.of({
|
|
|
41683
42360
|
detail: "This provider does not report account usage."
|
|
41684
42361
|
}))))
|
|
41685
42362
|
});
|
|
41686
|
-
const make$
|
|
42363
|
+
const make$54 = Effect.gen(function* () {
|
|
41687
42364
|
const registry = yield* ProviderInstanceRegistry;
|
|
41688
42365
|
return makeTextGenerationFromRegistry(registry);
|
|
41689
42366
|
});
|
|
41690
|
-
const layer$43 = Layer.effect(TextGeneration, make$
|
|
42367
|
+
const layer$43 = Layer.effect(TextGeneration, make$54);
|
|
41691
42368
|
//#endregion
|
|
41692
42369
|
//#region src/textGeneration/TextGenerationPresets.ts
|
|
41693
42370
|
const conventionalCommitsTextGenerationPolicy = {
|
|
@@ -42019,7 +42696,7 @@ const serversEqual = (left, right) => {
|
|
|
42019
42696
|
}
|
|
42020
42697
|
return true;
|
|
42021
42698
|
};
|
|
42022
|
-
const make$
|
|
42699
|
+
const make$53 = Effect.gen(function* PortDiscoveryMake() {
|
|
42023
42700
|
const net = yield* NetService;
|
|
42024
42701
|
const processRunner = yield* ProcessRunner;
|
|
42025
42702
|
const hostPlatform = yield* HostProcessPlatform;
|
|
@@ -42170,7 +42847,7 @@ const make$52 = Effect.gen(function* PortDiscoveryMake() {
|
|
|
42170
42847
|
unregisterTerminal
|
|
42171
42848
|
});
|
|
42172
42849
|
}).pipe(Effect.withSpan("PortDiscovery.make"));
|
|
42173
|
-
const layer$42 = Layer.effect(PortDiscovery, make$
|
|
42850
|
+
const layer$42 = Layer.effect(PortDiscovery, make$53);
|
|
42174
42851
|
//#endregion
|
|
42175
42852
|
//#region src/terminal/Manager.ts
|
|
42176
42853
|
/**
|
|
@@ -42848,7 +43525,7 @@ function normalizedRuntimeEnv(env) {
|
|
|
42848
43525
|
if (entries.length === 0) return null;
|
|
42849
43526
|
return Object.fromEntries(entries.toSorted(([left], [right]) => left.localeCompare(right)));
|
|
42850
43527
|
}
|
|
42851
|
-
const make$
|
|
43528
|
+
const make$52 = Effect.fn("TerminalManager.make")(function* () {
|
|
42852
43529
|
const { terminalLogsDir } = yield* ServerConfig$1;
|
|
42853
43530
|
const ptyAdapter = yield* PtyAdapter;
|
|
42854
43531
|
const portDiscovery = yield* PortDiscovery;
|
|
@@ -43810,7 +44487,7 @@ const makeWithOptions$1 = Effect.fn("TerminalManager.makeWithOptions")(function*
|
|
|
43810
44487
|
subscribeMetadata
|
|
43811
44488
|
});
|
|
43812
44489
|
});
|
|
43813
|
-
const layer$41 = Layer.effect(TerminalManager, make$
|
|
44490
|
+
const layer$41 = Layer.effect(TerminalManager, make$52()).pipe(Layer.provide(layer$63));
|
|
43814
44491
|
//#endregion
|
|
43815
44492
|
//#region src/project/ProjectSetupScriptRunner.ts
|
|
43816
44493
|
var ProjectSetupScriptOperationError = class extends Schema$1.TaggedErrorClass()("ProjectSetupScriptOperationError", {
|
|
@@ -43841,7 +44518,7 @@ var ProjectSetupScriptProjectNotFoundError = class extends Schema$1.TaggedErrorC
|
|
|
43841
44518
|
};
|
|
43842
44519
|
Schema$1.Union([ProjectSetupScriptOperationError, ProjectSetupScriptProjectNotFoundError]);
|
|
43843
44520
|
var ProjectSetupScriptRunner = class extends Context.Service()("@p4code/cli/project/ProjectSetupScriptRunner") {};
|
|
43844
|
-
const make$
|
|
44521
|
+
const make$51 = Effect.gen(function* () {
|
|
43845
44522
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
43846
44523
|
const terminalManager = yield* TerminalManager;
|
|
43847
44524
|
const runForThread = Effect.fn("ProjectSetupScriptRunner.runForThread")(function* (input) {
|
|
@@ -43899,7 +44576,7 @@ const make$50 = Effect.gen(function* () {
|
|
|
43899
44576
|
});
|
|
43900
44577
|
return ProjectSetupScriptRunner.of({ runForThread });
|
|
43901
44578
|
});
|
|
43902
|
-
const layer$40 = Layer.effect(ProjectSetupScriptRunner, make$
|
|
44579
|
+
const layer$40 = Layer.effect(ProjectSetupScriptRunner, make$51);
|
|
43903
44580
|
//#endregion
|
|
43904
44581
|
//#region src/provider/Services/ProviderRegistry.ts
|
|
43905
44582
|
var ProviderRegistry = class extends Context.Service()("@p4code/cli/provider/Services/ProviderRegistry") {};
|
|
@@ -44226,7 +44903,7 @@ function decodeAzureDevOpsJson(raw, schema, operation, cwd) {
|
|
|
44226
44903
|
cause
|
|
44227
44904
|
})));
|
|
44228
44905
|
}
|
|
44229
|
-
const make$
|
|
44906
|
+
const make$50 = Effect.gen(function* () {
|
|
44230
44907
|
const process = yield* VcsProcess;
|
|
44231
44908
|
const execute = (input) => process.run({
|
|
44232
44909
|
operation: "AzureDevOpsCli.execute",
|
|
@@ -44368,7 +45045,7 @@ const make$49 = Effect.gen(function* () {
|
|
|
44368
45045
|
}).pipe(Effect.asVoid)
|
|
44369
45046
|
});
|
|
44370
45047
|
});
|
|
44371
|
-
const layer$39 = Layer.effect(AzureDevOpsCli, make$
|
|
45048
|
+
const layer$39 = Layer.effect(AzureDevOpsCli, make$50);
|
|
44372
45049
|
//#endregion
|
|
44373
45050
|
//#region src/sourceControl/SourceControlProviderDiscovery.ts
|
|
44374
45051
|
function firstNonEmptyLine(text) {
|
|
@@ -44571,7 +45248,7 @@ function toChangeRequest$5(summary) {
|
|
|
44571
45248
|
isCrossRepository: false
|
|
44572
45249
|
};
|
|
44573
45250
|
}
|
|
44574
|
-
const make$
|
|
45251
|
+
const make$49 = Effect.gen(function* () {
|
|
44575
45252
|
const azure = yield* AzureDevOpsCli;
|
|
44576
45253
|
return SourceControlProvider.of({
|
|
44577
45254
|
kind: "azure-devops",
|
|
@@ -44663,7 +45340,7 @@ const make$48 = Effect.gen(function* () {
|
|
|
44663
45340
|
})))
|
|
44664
45341
|
});
|
|
44665
45342
|
});
|
|
44666
|
-
Layer.effect(SourceControlProvider, make$
|
|
45343
|
+
Layer.effect(SourceControlProvider, make$49);
|
|
44667
45344
|
//#endregion
|
|
44668
45345
|
//#region src/sourceControl/bitbucketPullRequests.ts
|
|
44669
45346
|
const BitbucketRepositoryRefSchema = Schema$1.Struct({
|
|
@@ -45040,7 +45717,7 @@ function responseError(operation, response) {
|
|
|
45040
45717
|
responseBodyLength: collected.text.length
|
|
45041
45718
|
}))));
|
|
45042
45719
|
}
|
|
45043
|
-
const make$
|
|
45720
|
+
const make$48 = Effect.gen(function* () {
|
|
45044
45721
|
const config = yield* BitbucketApiEnvConfig;
|
|
45045
45722
|
const httpClient = yield* HttpClient.HttpClient;
|
|
45046
45723
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
@@ -45256,7 +45933,7 @@ const make$47 = Effect.gen(function* () {
|
|
|
45256
45933
|
})))
|
|
45257
45934
|
});
|
|
45258
45935
|
});
|
|
45259
|
-
const layer$37 = Layer.effect(BitbucketApi, make$
|
|
45936
|
+
const layer$37 = Layer.effect(BitbucketApi, make$48);
|
|
45260
45937
|
//#endregion
|
|
45261
45938
|
//#region src/sourceControl/BitbucketSourceControlProvider.ts
|
|
45262
45939
|
function toChangeRequest$4(summary) {
|
|
@@ -45274,7 +45951,7 @@ function toChangeRequest$4(summary) {
|
|
|
45274
45951
|
...summary.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: summary.headRepositoryOwnerLogin } : {}
|
|
45275
45952
|
};
|
|
45276
45953
|
}
|
|
45277
|
-
const make$
|
|
45954
|
+
const make$47 = Effect.gen(function* () {
|
|
45278
45955
|
const bitbucket = yield* BitbucketApi;
|
|
45279
45956
|
return SourceControlProvider.of({
|
|
45280
45957
|
kind: "bitbucket",
|
|
@@ -45365,7 +46042,7 @@ const make$46 = Effect.gen(function* () {
|
|
|
45365
46042
|
})))
|
|
45366
46043
|
});
|
|
45367
46044
|
});
|
|
45368
|
-
Layer.effect(SourceControlProvider, make$
|
|
46045
|
+
Layer.effect(SourceControlProvider, make$47);
|
|
45369
46046
|
const makeDiscovery = Effect.gen(function* () {
|
|
45370
46047
|
return {
|
|
45371
46048
|
type: "api",
|
|
@@ -45607,7 +46284,7 @@ function deriveRepositoryCloneUrlsFromCreateOutput(stdout, repository) {
|
|
|
45607
46284
|
sshUrl: `git@${fallbackHost}:${repository}.git`
|
|
45608
46285
|
};
|
|
45609
46286
|
}
|
|
45610
|
-
const make$
|
|
46287
|
+
const make$46 = Effect.gen(function* () {
|
|
45611
46288
|
const process = yield* VcsProcess;
|
|
45612
46289
|
const execute = (input) => process.run({
|
|
45613
46290
|
operation: "GitHubCli.execute",
|
|
@@ -45725,7 +46402,7 @@ const make$45 = Effect.gen(function* () {
|
|
|
45725
46402
|
}).pipe(Effect.asVoid)
|
|
45726
46403
|
});
|
|
45727
46404
|
});
|
|
45728
|
-
const layer$35 = Layer.effect(GitHubCli, make$
|
|
46405
|
+
const layer$35 = Layer.effect(GitHubCli, make$46);
|
|
45729
46406
|
//#endregion
|
|
45730
46407
|
//#region src/sourceControl/gitHubAuthStatus.ts
|
|
45731
46408
|
const GitHubAuthStatusAccountSchema = Schema$1.Struct({
|
|
@@ -45826,7 +46503,7 @@ const discovery$1 = {
|
|
|
45826
46503
|
parseAuth: parseGitHubAuth,
|
|
45827
46504
|
installHint: "Install the GitHub command-line tool (`gh`) via https://cli.github.com/ or your package manager (for example `brew install gh`)."
|
|
45828
46505
|
};
|
|
45829
|
-
const make$
|
|
46506
|
+
const make$45 = Effect.gen(function* () {
|
|
45830
46507
|
const github = yield* GitHubCli;
|
|
45831
46508
|
const listChangeRequests = (input) => {
|
|
45832
46509
|
if (input.state === "open") return github.listOpenPullRequests({
|
|
@@ -45942,7 +46619,7 @@ const make$44 = Effect.gen(function* () {
|
|
|
45942
46619
|
})))
|
|
45943
46620
|
});
|
|
45944
46621
|
});
|
|
45945
|
-
Layer.effect(SourceControlProvider, make$
|
|
46622
|
+
Layer.effect(SourceControlProvider, make$45);
|
|
45946
46623
|
//#endregion
|
|
45947
46624
|
//#region src/sourceControl/gitLabMergeRequests.ts
|
|
45948
46625
|
const GitLabProjectReferenceSchema = Schema$1.Struct({
|
|
@@ -46254,7 +46931,7 @@ function parseRepositoryPath(repository) {
|
|
|
46254
46931
|
projectPath
|
|
46255
46932
|
};
|
|
46256
46933
|
}
|
|
46257
|
-
const make$
|
|
46934
|
+
const make$44 = Effect.gen(function* () {
|
|
46258
46935
|
const process = yield* VcsProcess;
|
|
46259
46936
|
const run = (input, mapError) => process.run({
|
|
46260
46937
|
operation: "GitLabCli.execute",
|
|
@@ -46405,7 +47082,7 @@ const make$43 = Effect.gen(function* () {
|
|
|
46405
47082
|
}).pipe(Effect.asVoid)
|
|
46406
47083
|
});
|
|
46407
47084
|
});
|
|
46408
|
-
const layer$33 = Layer.effect(GitLabCli, make$
|
|
47085
|
+
const layer$33 = Layer.effect(GitLabCli, make$44);
|
|
46409
47086
|
//#endregion
|
|
46410
47087
|
//#region src/sourceControl/gitLabAuthStatus.ts
|
|
46411
47088
|
const HOST_LINE_PATTERN = /^(?:[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?|\[[a-f0-9:.]+\])(?::\d+)?$/iu;
|
|
@@ -46502,7 +47179,7 @@ const discovery = {
|
|
|
46502
47179
|
refineUnknownRemote: refineUnknownGitLabRemote,
|
|
46503
47180
|
installHint: "Install the GitLab command-line tool (`glab`) from https://gitlab.com/gitlab-org/cli or your package manager (for example `brew install glab`)."
|
|
46504
47181
|
};
|
|
46505
|
-
const make$
|
|
47182
|
+
const make$43 = Effect.gen(function* () {
|
|
46506
47183
|
const gitlab = yield* GitLabCli;
|
|
46507
47184
|
return SourceControlProvider.of({
|
|
46508
47185
|
kind: "gitlab",
|
|
@@ -46590,7 +47267,7 @@ const make$42 = Effect.gen(function* () {
|
|
|
46590
47267
|
})))
|
|
46591
47268
|
});
|
|
46592
47269
|
});
|
|
46593
|
-
Layer.effect(SourceControlProvider, make$
|
|
47270
|
+
Layer.effect(SourceControlProvider, make$43);
|
|
46594
47271
|
//#endregion
|
|
46595
47272
|
//#region src/sourceControl/SourceControlProviderRegistry.ts
|
|
46596
47273
|
const PROVIDER_DETECTION_CACHE_CAPACITY = 2048;
|
|
@@ -46746,12 +47423,12 @@ const makeWithProviders = Effect.fn("makeSourceControlProviderRegistryWithProvid
|
|
|
46746
47423
|
})), { concurrency: "unbounded" })
|
|
46747
47424
|
});
|
|
46748
47425
|
});
|
|
46749
|
-
const make$
|
|
46750
|
-
const github = yield* make$
|
|
46751
|
-
const gitlab = yield* make$
|
|
46752
|
-
const bitbucket = yield* make$
|
|
47426
|
+
const make$42 = Effect.gen(function* () {
|
|
47427
|
+
const github = yield* make$45;
|
|
47428
|
+
const gitlab = yield* make$43;
|
|
47429
|
+
const bitbucket = yield* make$47;
|
|
46753
47430
|
const bitbucketDiscovery = yield* makeDiscovery;
|
|
46754
|
-
const azureDevOps = yield* make$
|
|
47431
|
+
const azureDevOps = yield* make$49;
|
|
46755
47432
|
return yield* makeWithProviders([
|
|
46756
47433
|
{
|
|
46757
47434
|
kind: "github",
|
|
@@ -46775,7 +47452,7 @@ const make$41 = Effect.gen(function* () {
|
|
|
46775
47452
|
}
|
|
46776
47453
|
]);
|
|
46777
47454
|
});
|
|
46778
|
-
const layer$31 = Layer.effect(SourceControlProviderRegistry, make$
|
|
47455
|
+
const layer$31 = Layer.effect(SourceControlProviderRegistry, make$42);
|
|
46779
47456
|
//#endregion
|
|
46780
47457
|
//#region src/sourceControl/PrTemplateDetection.ts
|
|
46781
47458
|
const TEMPLATE_MAX_BYTES = 8e3;
|
|
@@ -47145,7 +47822,7 @@ function toPullRequestHeadRemoteInfo(pr) {
|
|
|
47145
47822
|
...pr.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: pr.headRepositoryOwnerLogin } : {}
|
|
47146
47823
|
};
|
|
47147
47824
|
}
|
|
47148
|
-
const make$
|
|
47825
|
+
const make$41 = Effect.gen(function* () {
|
|
47149
47826
|
const gitCore = yield* GitVcsDriver;
|
|
47150
47827
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
47151
47828
|
const textGeneration = yield* TextGeneration;
|
|
@@ -48067,7 +48744,7 @@ const make$40 = Effect.gen(function* () {
|
|
|
48067
48744
|
runStackedAction
|
|
48068
48745
|
});
|
|
48069
48746
|
});
|
|
48070
|
-
const layer$30 = Layer.effect(GitManager, make$
|
|
48747
|
+
const layer$30 = Layer.effect(GitManager, make$41);
|
|
48071
48748
|
//#endregion
|
|
48072
48749
|
//#region src/git/GitWorkflowService.ts
|
|
48073
48750
|
var GitWorkflowService = class extends Context.Service()("@p4code/cli/git/GitWorkflowService") {};
|
|
@@ -48104,7 +48781,7 @@ function nonRepositoryListRefs() {
|
|
|
48104
48781
|
totalCount: 0
|
|
48105
48782
|
};
|
|
48106
48783
|
}
|
|
48107
|
-
const make$
|
|
48784
|
+
const make$40 = Effect.gen(function* () {
|
|
48108
48785
|
const registry = yield* VcsDriverRegistry;
|
|
48109
48786
|
const git = yield* GitVcsDriver;
|
|
48110
48787
|
const gitManager = yield* GitManager;
|
|
@@ -48190,7 +48867,7 @@ const make$39 = Effect.gen(function* () {
|
|
|
48190
48867
|
renameBranch: (input) => ensureGit("GitWorkflowService.renameBranch", input.cwd).pipe(Effect.andThen(git.renameBranch(input)))
|
|
48191
48868
|
});
|
|
48192
48869
|
});
|
|
48193
|
-
const layer$29 = Layer.effect(GitWorkflowService, make$
|
|
48870
|
+
const layer$29 = Layer.effect(GitWorkflowService, make$40);
|
|
48194
48871
|
//#endregion
|
|
48195
48872
|
//#region src/pullRequest/PullRequestProvider.ts
|
|
48196
48873
|
/**
|
|
@@ -48551,7 +49228,7 @@ function isReviewerName(value) {
|
|
|
48551
49228
|
const name = value.trim();
|
|
48552
49229
|
return name.length > 0 && !name.startsWith("-");
|
|
48553
49230
|
}
|
|
48554
|
-
const make$
|
|
49231
|
+
const make$39 = Effect.gen(function* () {
|
|
48555
49232
|
const azure = yield* AzureDevOpsCli;
|
|
48556
49233
|
const detectArgs = ["--detect", "true"];
|
|
48557
49234
|
const executeJson = (input) => azure.execute({
|
|
@@ -48751,7 +49428,7 @@ const make$38 = Effect.gen(function* () {
|
|
|
48751
49428
|
}).pipe(Effect.asVoid)
|
|
48752
49429
|
});
|
|
48753
49430
|
});
|
|
48754
|
-
const layer$28 = Layer.effect(AzureDevOpsPullRequestCli, make$
|
|
49431
|
+
const layer$28 = Layer.effect(AzureDevOpsPullRequestCli, make$39);
|
|
48755
49432
|
//#endregion
|
|
48756
49433
|
//#region src/pullRequest/AzureDevOpsPullRequestProvider.ts
|
|
48757
49434
|
const CAPABILITIES$3 = {
|
|
@@ -48826,7 +49503,7 @@ function toChangeRequest$1(pullRequest) {
|
|
|
48826
49503
|
labels: []
|
|
48827
49504
|
};
|
|
48828
49505
|
}
|
|
48829
|
-
const make$
|
|
49506
|
+
const make$38 = Effect.gen(function* () {
|
|
48830
49507
|
const cli = yield* AzureDevOpsPullRequestCli;
|
|
48831
49508
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
48832
49509
|
provider: "azure-devops",
|
|
@@ -49566,7 +50243,7 @@ function mergeStrategy(method) {
|
|
|
49566
50243
|
default: return "merge_commit";
|
|
49567
50244
|
}
|
|
49568
50245
|
}
|
|
49569
|
-
const make$
|
|
50246
|
+
const make$37 = Effect.gen(function* () {
|
|
49570
50247
|
const bitbucket = yield* BitbucketApi;
|
|
49571
50248
|
/**
|
|
49572
50249
|
* The repository's own path, and the workspace above it — which the people who may review are
|
|
@@ -49846,7 +50523,7 @@ const make$36 = Effect.gen(function* () {
|
|
|
49846
50523
|
}).pipe(Effect.asVoid))
|
|
49847
50524
|
});
|
|
49848
50525
|
});
|
|
49849
|
-
const layer$27 = Layer.effect(BitbucketPullRequestApi, make$
|
|
50526
|
+
const layer$27 = Layer.effect(BitbucketPullRequestApi, make$37);
|
|
49850
50527
|
//#endregion
|
|
49851
50528
|
//#region src/pullRequest/BitbucketPullRequestProvider.ts
|
|
49852
50529
|
const CAPABILITIES$2 = {
|
|
@@ -49926,7 +50603,7 @@ function toChangeRequest(pullRequest) {
|
|
|
49926
50603
|
labels: []
|
|
49927
50604
|
};
|
|
49928
50605
|
}
|
|
49929
|
-
const make$
|
|
50606
|
+
const make$36 = Effect.gen(function* () {
|
|
49930
50607
|
const api = yield* BitbucketPullRequestApi;
|
|
49931
50608
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
49932
50609
|
provider: "bitbucket",
|
|
@@ -51813,7 +52490,7 @@ function actionArgs$1(action, mergeMethod, updateMethod) {
|
|
|
51813
52490
|
case "reopen": return ["reopen"];
|
|
51814
52491
|
}
|
|
51815
52492
|
}
|
|
51816
|
-
const make$
|
|
52493
|
+
const make$35 = Effect.gen(function* () {
|
|
51817
52494
|
const github = yield* GitHubCli;
|
|
51818
52495
|
/**
|
|
51819
52496
|
* The pull request's own node id, which is what a mutation against the pull request itself is
|
|
@@ -52533,7 +53210,7 @@ const make$34 = Effect.gen(function* () {
|
|
|
52533
53210
|
})))
|
|
52534
53211
|
});
|
|
52535
53212
|
});
|
|
52536
|
-
const layer$26 = Layer.effect(GitHubPullRequestCli, make$
|
|
53213
|
+
const layer$26 = Layer.effect(GitHubPullRequestCli, make$35);
|
|
52537
53214
|
//#endregion
|
|
52538
53215
|
//#region src/pullRequest/GitHubPullRequestProvider.ts
|
|
52539
53216
|
const CAPABILITIES$1 = {
|
|
@@ -52648,7 +53325,7 @@ function loginAvatarUrl(login, host) {
|
|
|
52648
53325
|
}
|
|
52649
53326
|
/** True where markdown would render nothing: whitespace, or only HTML comments. */
|
|
52650
53327
|
const rendersEmpty = (body) => body.replace(/<!--[\s\S]*?-->/g, "").trim().length === 0;
|
|
52651
|
-
const make$
|
|
53328
|
+
const make$34 = Effect.gen(function* () {
|
|
52652
53329
|
const cli = yield* GitHubPullRequestCli;
|
|
52653
53330
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
52654
53331
|
provider: "github",
|
|
@@ -53667,7 +54344,7 @@ function actionArgs(action, mergeMethod) {
|
|
|
53667
54344
|
case "reopen": return ["reopen"];
|
|
53668
54345
|
}
|
|
53669
54346
|
}
|
|
53670
|
-
const make$
|
|
54347
|
+
const make$33 = Effect.gen(function* () {
|
|
53671
54348
|
const gitlab = yield* GitLabCli;
|
|
53672
54349
|
const api = (input) => gitlab.execute({
|
|
53673
54350
|
cwd: input.cwd,
|
|
@@ -54238,7 +54915,7 @@ const make$32 = Effect.gen(function* () {
|
|
|
54238
54915
|
}).pipe(Effect.asVoid)
|
|
54239
54916
|
});
|
|
54240
54917
|
});
|
|
54241
|
-
const layer$25 = Layer.effect(GitLabPullRequestCli, make$
|
|
54918
|
+
const layer$25 = Layer.effect(GitLabPullRequestCli, make$33);
|
|
54242
54919
|
//#endregion
|
|
54243
54920
|
//#region src/pullRequest/GitLabPullRequestProvider.ts
|
|
54244
54921
|
const CAPABILITIES = {
|
|
@@ -54318,7 +54995,7 @@ function reasonFor(error) {
|
|
|
54318
54995
|
if (error._tag === "GitLabCliAuthenticationError") return "unauthenticated";
|
|
54319
54996
|
return "failed";
|
|
54320
54997
|
}
|
|
54321
|
-
const make$
|
|
54998
|
+
const make$32 = Effect.gen(function* () {
|
|
54322
54999
|
const cli = yield* GitLabPullRequestCli;
|
|
54323
55000
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
54324
55001
|
provider: "gitlab",
|
|
@@ -54461,13 +55138,13 @@ function fromProviders(providers) {
|
|
|
54461
55138
|
* The hosts this build can read change requests from. A host with no entry here still shows up
|
|
54462
55139
|
* in the provider list as unimplemented, so its projects are explained rather than missing.
|
|
54463
55140
|
*/
|
|
54464
|
-
const make$
|
|
54465
|
-
make$
|
|
54466
|
-
make$
|
|
54467
|
-
make$
|
|
54468
|
-
make$
|
|
55141
|
+
const make$31 = Effect.map(Effect.all([
|
|
55142
|
+
make$34,
|
|
55143
|
+
make$32,
|
|
55144
|
+
make$36,
|
|
55145
|
+
make$38
|
|
54469
55146
|
]), fromProviders);
|
|
54470
|
-
const layer$24 = Layer.effect(PullRequestProviderRegistry, make$
|
|
55147
|
+
const layer$24 = Layer.effect(PullRequestProviderRegistry, make$31).pipe(Layer.provide(layer$26.pipe(Layer.provide(layer$35))), Layer.provide(layer$25.pipe(Layer.provide(layer$33))), Layer.provide(layer$27.pipe(Layer.provide(layer$37))), Layer.provide(layer$28.pipe(Layer.provide(layer$39))));
|
|
54471
55148
|
//#endregion
|
|
54472
55149
|
//#region src/pullRequest/PullRequestService.ts
|
|
54473
55150
|
/**
|
|
@@ -54655,7 +55332,7 @@ function repositoryIdentityOf(project) {
|
|
|
54655
55332
|
if (identity.displayName) return identity.displayName;
|
|
54656
55333
|
return identity.owner && identity.name ? `${identity.owner}/${identity.name}` : null;
|
|
54657
55334
|
}
|
|
54658
|
-
const make$
|
|
55335
|
+
const make$30 = Effect.gen(function* () {
|
|
54659
55336
|
const registry = yield* PullRequestProviderRegistry;
|
|
54660
55337
|
const projections = yield* ProjectionSnapshotQuery;
|
|
54661
55338
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
@@ -55625,7 +56302,7 @@ const make$29 = Effect.gen(function* () {
|
|
|
55625
56302
|
invalidate
|
|
55626
56303
|
});
|
|
55627
56304
|
});
|
|
55628
|
-
const layer$23 = Layer.effect(PullRequestService, make$
|
|
56305
|
+
const layer$23 = Layer.effect(PullRequestService, make$30);
|
|
55629
56306
|
//#endregion
|
|
55630
56307
|
//#region src/orchestration/ThreadWorkspaceLifecycle.ts
|
|
55631
56308
|
var ThreadWorkspaceLifecycleError = class extends Data.TaggedError("ThreadWorkspaceLifecycleError") {};
|
|
@@ -55635,6 +56312,16 @@ function resolveWorkspaceCleanupRefusal(input) {
|
|
|
55635
56312
|
if (!input.isMerged) return "Cleanup refused because branch is not merged into default branch.";
|
|
55636
56313
|
return null;
|
|
55637
56314
|
}
|
|
56315
|
+
/**
|
|
56316
|
+
* A thread on a detached HEAD has no branch to merge, so its worktree is safe
|
|
56317
|
+
* to drop as soon as nothing in it is unsaved and every commit it points at is
|
|
56318
|
+
* already on the default branch.
|
|
56319
|
+
*/
|
|
56320
|
+
function resolveDetachedWorkspaceCleanupRefusal(input) {
|
|
56321
|
+
if (input.hasUncommittedChanges) return "Cleanup refused because worktree has uncommitted changes.";
|
|
56322
|
+
if (!input.headIsAncestorOfDefault) return "Cleanup refused because the detached worktree has commits that are not on the default branch.";
|
|
56323
|
+
return null;
|
|
56324
|
+
}
|
|
55638
56325
|
function resolveMergedWorkspaceContext(input) {
|
|
55639
56326
|
const pullRequest = input.pullRequest;
|
|
55640
56327
|
if (input.branchIsAncestor && input.branchCommitSha !== null) return {
|
|
@@ -55659,7 +56346,7 @@ const mapLifecycleError = Effect.mapError((cause) => cause instanceof ThreadWork
|
|
|
55659
56346
|
detail: "Thread workspace lifecycle operation failed.",
|
|
55660
56347
|
cause
|
|
55661
56348
|
}));
|
|
55662
|
-
const make$
|
|
56349
|
+
const make$29 = Effect.gen(function* () {
|
|
55663
56350
|
const snapshots = yield* ProjectionSnapshotQuery;
|
|
55664
56351
|
const engine = yield* OrchestrationEngineService;
|
|
55665
56352
|
const gitWorkflow = yield* GitWorkflowService;
|
|
@@ -55675,6 +56362,72 @@ const make$28 = Effect.gen(function* () {
|
|
|
55675
56362
|
}))), { discard: true });
|
|
55676
56363
|
});
|
|
55677
56364
|
const record = (input) => recordRaw(input).pipe(mapLifecycleError);
|
|
56365
|
+
const cleanupDetachedWorktree = Effect.fn("threadWorkspaceLifecycle.cleanupDetached")(function* (input) {
|
|
56366
|
+
const { threadIds, project, worktreePath, refusal, now } = input;
|
|
56367
|
+
if ((yield* git.statusDetailsLocal(worktreePath).pipe(Effect.mapError((cause) => new ThreadWorkspaceLifecycleError({
|
|
56368
|
+
detail: "Could not inspect thread worktree before cleanup.",
|
|
56369
|
+
cause
|
|
56370
|
+
})))).hasWorkingTreeChanges) return yield* refusal(resolveDetachedWorkspaceCleanupRefusal({
|
|
56371
|
+
hasUncommittedChanges: true,
|
|
56372
|
+
headIsAncestorOfDefault: true
|
|
56373
|
+
}));
|
|
56374
|
+
const defaultRef = (yield* gitWorkflow.listRefs({
|
|
56375
|
+
cwd: project.workspaceRoot,
|
|
56376
|
+
includeMatchingRemoteRefs: true,
|
|
56377
|
+
refresh: true
|
|
56378
|
+
})).refs.find((ref) => ref.isRemote === true && ref.isDefault);
|
|
56379
|
+
if (defaultRef === void 0 || defaultRef.remoteName === void 0) return yield* refusal("Cleanup refused because the default remote branch could not be resolved.");
|
|
56380
|
+
yield* gitWorkflow.fetchRemote({
|
|
56381
|
+
cwd: project.workspaceRoot,
|
|
56382
|
+
remoteName: defaultRef.remoteName
|
|
56383
|
+
});
|
|
56384
|
+
const ancestorResult = yield* git.execute({
|
|
56385
|
+
operation: "ThreadWorkspaceLifecycle.detachedMergeBase",
|
|
56386
|
+
cwd: worktreePath,
|
|
56387
|
+
args: [
|
|
56388
|
+
"merge-base",
|
|
56389
|
+
"--is-ancestor",
|
|
56390
|
+
"HEAD",
|
|
56391
|
+
`refs/remotes/${defaultRef.name}`
|
|
56392
|
+
],
|
|
56393
|
+
allowNonZeroExit: true
|
|
56394
|
+
});
|
|
56395
|
+
if (ancestorResult.exitCode !== 0 && ancestorResult.exitCode !== 1) return yield* refusal("Cleanup refused because worktree ancestry could not be verified.");
|
|
56396
|
+
const ancestryRefusal = resolveDetachedWorkspaceCleanupRefusal({
|
|
56397
|
+
hasUncommittedChanges: false,
|
|
56398
|
+
headIsAncestorOfDefault: ancestorResult.exitCode === 0
|
|
56399
|
+
});
|
|
56400
|
+
if (ancestryRefusal !== null) return yield* refusal(ancestryRefusal);
|
|
56401
|
+
yield* record({
|
|
56402
|
+
threadIds,
|
|
56403
|
+
lifecycle: {
|
|
56404
|
+
status: "cleanup-pending",
|
|
56405
|
+
detail: "Detached worktree verified; workspace cleanup is pending.",
|
|
56406
|
+
pullRequestNumber: null,
|
|
56407
|
+
mergeCommitSha: null,
|
|
56408
|
+
updatedAt: now
|
|
56409
|
+
}
|
|
56410
|
+
});
|
|
56411
|
+
yield* gitWorkflow.removeWorktree({
|
|
56412
|
+
cwd: project.workspaceRoot,
|
|
56413
|
+
path: worktreePath
|
|
56414
|
+
});
|
|
56415
|
+
const detail = "Detached worktree removed; thread context preserved.";
|
|
56416
|
+
yield* record({
|
|
56417
|
+
threadIds,
|
|
56418
|
+
lifecycle: {
|
|
56419
|
+
status: "cleaned",
|
|
56420
|
+
detail,
|
|
56421
|
+
pullRequestNumber: null,
|
|
56422
|
+
mergeCommitSha: null,
|
|
56423
|
+
updatedAt: DateTime.formatIso(yield* DateTime.now)
|
|
56424
|
+
}
|
|
56425
|
+
});
|
|
56426
|
+
return {
|
|
56427
|
+
outcome: "cleaned",
|
|
56428
|
+
detail
|
|
56429
|
+
};
|
|
56430
|
+
});
|
|
55678
56431
|
const cleanupRaw = Effect.fn("threadWorkspaceLifecycle.cleanup")(function* (threadId) {
|
|
55679
56432
|
const snapshot = yield* snapshots.getCommandReadModel();
|
|
55680
56433
|
const threadIds = activePairThreadIds(threadId, snapshot.threadPairs ?? []);
|
|
@@ -55710,8 +56463,15 @@ const make$28 = Effect.gen(function* () {
|
|
|
55710
56463
|
if (threads.some((thread) => thread.archivedAt === null)) return yield* refusal("Cleanup refused because thread is not archived.");
|
|
55711
56464
|
const branch = requestedThread.branch;
|
|
55712
56465
|
const worktreePath = requestedThread.worktreePath;
|
|
55713
|
-
if (
|
|
56466
|
+
if (worktreePath === null) return yield* refusal("Cleanup refused because thread has no worktree.");
|
|
55714
56467
|
if (threads.some((thread) => thread.branch !== branch || thread.worktreePath !== worktreePath)) return yield* refusal("Cleanup refused because Fusion threads do not share one workspace.");
|
|
56468
|
+
if (branch === null) return yield* cleanupDetachedWorktree({
|
|
56469
|
+
threadIds,
|
|
56470
|
+
project,
|
|
56471
|
+
worktreePath,
|
|
56472
|
+
refusal,
|
|
56473
|
+
now
|
|
56474
|
+
});
|
|
55715
56475
|
const dirtyRefusal = resolveWorkspaceCleanupRefusal({
|
|
55716
56476
|
hasLiveSession: false,
|
|
55717
56477
|
hasUncommittedChanges: (yield* git.statusDetailsLocal(worktreePath).pipe(Effect.mapError((cause) => new ThreadWorkspaceLifecycleError({
|
|
@@ -55840,7 +56600,7 @@ const make$28 = Effect.gen(function* () {
|
|
|
55840
56600
|
record
|
|
55841
56601
|
};
|
|
55842
56602
|
});
|
|
55843
|
-
const layer$22 = Layer.effect(ThreadWorkspaceLifecycleService, make$
|
|
56603
|
+
const layer$22 = Layer.effect(ThreadWorkspaceLifecycleService, make$29);
|
|
55844
56604
|
//#endregion
|
|
55845
56605
|
//#region src/textGeneration/BtwRequestCoordinator.ts
|
|
55846
56606
|
const MAX_PENDING_BTW_CANCELLATIONS = 256;
|
|
@@ -57994,6 +58754,9 @@ const observeRpcStreamEffect = (method, effect, traceAttributes) => {
|
|
|
57994
58754
|
return withRpcStreamTracing(method, instrumented, traceAttributes);
|
|
57995
58755
|
};
|
|
57996
58756
|
//#endregion
|
|
58757
|
+
//#region src/provider/Services/ProviderSessionDirectory.ts
|
|
58758
|
+
var ProviderSessionDirectory = class extends Context.Service()("@p4code/cli/provider/Services/ProviderSessionDirectory") {};
|
|
58759
|
+
//#endregion
|
|
57997
58760
|
//#region src/provider/providerMaintenanceCommandCoordinator.ts
|
|
57998
58761
|
const makeProviderMaintenanceCommandCoordinator = Effect.fn("makeProviderMaintenanceCommandCoordinator")(function* (input) {
|
|
57999
58762
|
const runningTargetsRef = yield* Ref.make(/* @__PURE__ */ new Set());
|
|
@@ -58381,7 +59144,7 @@ function makeUpdateState(input) {
|
|
|
58381
59144
|
output: input.output ?? null
|
|
58382
59145
|
};
|
|
58383
59146
|
}
|
|
58384
|
-
const make$
|
|
59147
|
+
const make$28 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
58385
59148
|
const providerRegistry = yield* ProviderRegistry;
|
|
58386
59149
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
58387
59150
|
const httpClient = yield* HttpClient.HttpClient;
|
|
@@ -58496,7 +59259,7 @@ const make$27 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
|
58496
59259
|
});
|
|
58497
59260
|
return ProviderMaintenanceRunner.of({ updateProvider });
|
|
58498
59261
|
});
|
|
58499
|
-
const layer$21 = Layer.effect(ProviderMaintenanceRunner, make$
|
|
59262
|
+
const layer$21 = Layer.effect(ProviderMaintenanceRunner, make$28());
|
|
58500
59263
|
//#endregion
|
|
58501
59264
|
//#region src/provider/Drivers/ClaudeHome.ts
|
|
58502
59265
|
const resolveClaudeHomePath = Effect.fn("resolveClaudeHomePath")(function* (config) {
|
|
@@ -59512,7 +60275,7 @@ Layer.succeed(UsageService, UsageService.of({ readSummary: (input) => Effect.suc
|
|
|
59512
60275
|
},
|
|
59513
60276
|
scanDurationMs: 0
|
|
59514
60277
|
}) }));
|
|
59515
|
-
const make$
|
|
60278
|
+
const make$27 = Effect.gen(function* () {
|
|
59516
60279
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
59517
60280
|
const path = yield* Path.Path;
|
|
59518
60281
|
const config = yield* ServerConfig$1;
|
|
@@ -59744,7 +60507,7 @@ const make$26 = Effect.gen(function* () {
|
|
|
59744
60507
|
};
|
|
59745
60508
|
}) };
|
|
59746
60509
|
});
|
|
59747
|
-
const layer$20 = Layer.effect(UsageService, make$
|
|
60510
|
+
const layer$20 = Layer.effect(UsageService, make$27);
|
|
59748
60511
|
//#endregion
|
|
59749
60512
|
//#region src/feed/FeedStore.ts
|
|
59750
60513
|
const storageFailure = (message) => new FeedError({
|
|
@@ -60108,7 +60871,7 @@ const jsonRequest = Effect.fn("FeedService.jsonRequest")(function* (url, token,
|
|
|
60108
60871
|
catch: () => fail("hub_unavailable", "Hub returned invalid JSON.")
|
|
60109
60872
|
});
|
|
60110
60873
|
});
|
|
60111
|
-
const make$
|
|
60874
|
+
const make$26 = Effect.gen(function* () {
|
|
60112
60875
|
const hubLink = yield* HubLink;
|
|
60113
60876
|
const providers = yield* ProviderInstanceRegistry;
|
|
60114
60877
|
const config = yield* ServerConfig$1;
|
|
@@ -60346,7 +61109,7 @@ var FeedService = class extends Context.Reference("@p4code/cli/feed/FeedService"
|
|
|
60346
61109
|
markRead: unavailable,
|
|
60347
61110
|
cleanup: unavailable
|
|
60348
61111
|
}) }) {};
|
|
60349
|
-
const layer$19 = Layer.effect(FeedService, make$
|
|
61112
|
+
const layer$19 = Layer.effect(FeedService, make$26);
|
|
60350
61113
|
const SKILL_MANIFEST_FILENAME = "SKILL.md";
|
|
60351
61114
|
/**
|
|
60352
61115
|
* Split a catalogue id (`owner/repo/skill-name`) into its parts.
|
|
@@ -60492,7 +61255,7 @@ const emptyFetch = (id, unavailable) => ({
|
|
|
60492
61255
|
skipped: [],
|
|
60493
61256
|
unavailable
|
|
60494
61257
|
});
|
|
60495
|
-
const make$
|
|
61258
|
+
const make$25 = Effect.gen(function* () {
|
|
60496
61259
|
const http = yield* HttpClient.HttpClient;
|
|
60497
61260
|
const request = Effect.fn("SkillRegistry.request")(function* (url) {
|
|
60498
61261
|
return yield* http.execute(HttpClientRequest.get(url).pipe(HttpClientRequest.setHeader("accept", "application/json"), HttpClientRequest.setHeader("user-agent", "p4code"))).pipe(Effect.timeout(REQUEST_TIMEOUT_MS));
|
|
@@ -60563,7 +61326,7 @@ const make$24 = Effect.gen(function* () {
|
|
|
60563
61326
|
fetch
|
|
60564
61327
|
};
|
|
60565
61328
|
});
|
|
60566
|
-
const layer$18 = Layer.effect(SkillRegistry, make$
|
|
61329
|
+
const layer$18 = Layer.effect(SkillRegistry, make$25);
|
|
60567
61330
|
//#endregion
|
|
60568
61331
|
//#region src/mcp/McpInvocationContext.ts
|
|
60569
61332
|
var McpInvocationContext = class extends Context.Service()("@p4code/cli/mcp/McpInvocationContext") {};
|
|
@@ -60791,7 +61554,7 @@ const classifyResponseError = (context, error) => {
|
|
|
60791
61554
|
});
|
|
60792
61555
|
}
|
|
60793
61556
|
};
|
|
60794
|
-
const make$
|
|
61557
|
+
const make$24 = Effect.gen(function* PreviewAutomationBrokerMake() {
|
|
60795
61558
|
const crypto = yield* Crypto.Crypto;
|
|
60796
61559
|
const state = yield* SynchronizedRef.make({
|
|
60797
61560
|
clients: /* @__PURE__ */ new Map(),
|
|
@@ -61025,7 +61788,7 @@ const make$23 = Effect.gen(function* PreviewAutomationBrokerMake() {
|
|
|
61025
61788
|
invoke
|
|
61026
61789
|
});
|
|
61027
61790
|
}).pipe(Effect.withSpan("PreviewAutomationBroker.make"));
|
|
61028
|
-
const layer$17 = Layer.effect(PreviewAutomationBroker, make$
|
|
61791
|
+
const layer$17 = Layer.effect(PreviewAutomationBroker, make$24);
|
|
61029
61792
|
//#endregion
|
|
61030
61793
|
//#region src/preview/Manager.ts
|
|
61031
61794
|
/**
|
|
@@ -61089,7 +61852,7 @@ const buildIdleSnapshot = (input) => ({
|
|
|
61089
61852
|
viewport: FILL_PREVIEW_VIEWPORT,
|
|
61090
61853
|
updatedAt: input.updatedAt
|
|
61091
61854
|
});
|
|
61092
|
-
const make$
|
|
61855
|
+
const make$23 = Effect.gen(function* PreviewManagerMake() {
|
|
61093
61856
|
const serverEpoch = NodeCrypto.randomUUID();
|
|
61094
61857
|
const stateRef = yield* SynchronizedRef.make(initialState);
|
|
61095
61858
|
const eventsPubSub = yield* PubSub.unbounded();
|
|
@@ -61320,7 +62083,7 @@ const make$22 = Effect.gen(function* PreviewManagerMake() {
|
|
|
61320
62083
|
subscribeEvents: PubSub.subscribe(eventsPubSub)
|
|
61321
62084
|
});
|
|
61322
62085
|
}).pipe(Effect.withSpan("PreviewManager.make"));
|
|
61323
|
-
const layer$16 = Layer.effect(PreviewManager, make$
|
|
62086
|
+
const layer$16 = Layer.effect(PreviewManager, make$23);
|
|
61324
62087
|
//#endregion
|
|
61325
62088
|
//#region src/workspace/WorkspaceSearchIndex.ts
|
|
61326
62089
|
const WORKSPACE_INDEX_MAX_ENTRIES = 25e3;
|
|
@@ -61454,7 +62217,7 @@ const waitForScan = (cwd, finder, onFailure) => Effect.try({
|
|
|
61454
62217
|
timeout: WORKSPACE_INDEX_SCAN_TIMEOUT
|
|
61455
62218
|
})
|
|
61456
62219
|
}), Effect.withSpan("WorkspaceSearchIndex.waitForScan"));
|
|
61457
|
-
const make$
|
|
62220
|
+
const make$22 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd) {
|
|
61458
62221
|
const finder = yield* Effect.acquireRelease(createFinder(cwd), (finder) => Effect.try({
|
|
61459
62222
|
try: () => finder.destroy(),
|
|
61460
62223
|
catch: (cause) => new WorkspaceSearchIndexDestroyFailed({
|
|
@@ -61528,7 +62291,7 @@ const make$21 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd) {
|
|
|
61528
62291
|
* workspace root. WorkspaceSearchIndexMap owns memoization and idle cleanup;
|
|
61529
62292
|
* using a default cwd here would mix resources from different workspaces.
|
|
61530
62293
|
*/
|
|
61531
|
-
const layer$15 = (cwd) => Layer.effect(WorkspaceSearchIndex, make$
|
|
62294
|
+
const layer$15 = (cwd) => Layer.effect(WorkspaceSearchIndex, make$22(cwd));
|
|
61532
62295
|
var WorkspaceSearchIndexMap = class extends LayerMap.Service()("@p4code/cli/workspace/WorkspaceSearchIndexMap", {
|
|
61533
62296
|
lookup: layer$15,
|
|
61534
62297
|
idleTimeToLive: WORKSPACE_INDEX_IDLE_TTL
|
|
@@ -61592,7 +62355,7 @@ const resolveBrowseTarget = Effect.fn("WorkspaceEntries.resolveBrowseTarget")(fu
|
|
|
61592
62355
|
if (!input.cwd) return yield* new WorkspaceEntriesCurrentProjectRequiredError({ partialPath: input.partialPath });
|
|
61593
62356
|
return path.resolve(expandHomePath$1(input.cwd, path), input.partialPath);
|
|
61594
62357
|
});
|
|
61595
|
-
const make$
|
|
62358
|
+
const make$21 = Effect.gen(function* () {
|
|
61596
62359
|
const path = yield* Path.Path;
|
|
61597
62360
|
const workspacePaths = yield* WorkspacePaths;
|
|
61598
62361
|
const workspaceSearchIndexes = yield* WorkspaceSearchIndexMap;
|
|
@@ -61666,7 +62429,7 @@ const make$20 = Effect.gen(function* () {
|
|
|
61666
62429
|
search
|
|
61667
62430
|
});
|
|
61668
62431
|
});
|
|
61669
|
-
const layer$14 = Layer.effect(WorkspaceEntries, make$
|
|
62432
|
+
const layer$14 = Layer.effect(WorkspaceEntries, make$21).pipe(Layer.provide(WorkspaceSearchIndexMap.layer));
|
|
61670
62433
|
//#endregion
|
|
61671
62434
|
//#region src/workspace/WorkspaceFileSystem.ts
|
|
61672
62435
|
/**
|
|
@@ -61725,7 +62488,7 @@ Schema$1.Union([
|
|
|
61725
62488
|
]);
|
|
61726
62489
|
/** Service tag for workspace file operations. */
|
|
61727
62490
|
var WorkspaceFileSystem = class extends Context.Service()("@p4code/cli/workspace/WorkspaceFileSystem") {};
|
|
61728
|
-
const make$
|
|
62491
|
+
const make$20 = Effect.gen(function* () {
|
|
61729
62492
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
61730
62493
|
const path = yield* Path.Path;
|
|
61731
62494
|
const workspacePaths = yield* WorkspacePaths;
|
|
@@ -61869,7 +62632,7 @@ const make$19 = Effect.gen(function* () {
|
|
|
61869
62632
|
writeFile
|
|
61870
62633
|
});
|
|
61871
62634
|
});
|
|
61872
|
-
const layer$13 = Layer.effect(WorkspaceFileSystem, make$
|
|
62635
|
+
const layer$13 = Layer.effect(WorkspaceFileSystem, make$20);
|
|
61873
62636
|
//#endregion
|
|
61874
62637
|
//#region src/vcs/VcsStatusBroadcaster.ts
|
|
61875
62638
|
const DEFAULT_VCS_STATUS_REFRESH_INTERVAL = Duration.seconds(30);
|
|
@@ -61941,7 +62704,7 @@ function fingerprintStatusPart(status) {
|
|
|
61941
62704
|
return JSON.stringify(status);
|
|
61942
62705
|
}
|
|
61943
62706
|
const normalizeCwd = (cwd) => Effect.service(FileSystem.FileSystem).pipe(Effect.flatMap((fs) => fs.realPath(cwd)), Effect.orElseSucceed(() => cwd));
|
|
61944
|
-
const make$
|
|
62707
|
+
const make$19 = Effect.gen(function* () {
|
|
61945
62708
|
const workflow = yield* GitWorkflowService;
|
|
61946
62709
|
const fs = yield* FileSystem.FileSystem;
|
|
61947
62710
|
const changesPubSub = yield* Effect.acquireRelease(PubSub.unbounded(), (pubsub) => PubSub.shutdown(pubsub));
|
|
@@ -62165,7 +62928,7 @@ const make$18 = Effect.gen(function* () {
|
|
|
62165
62928
|
streamStatus
|
|
62166
62929
|
});
|
|
62167
62930
|
});
|
|
62168
|
-
const layer$12 = Layer.effect(VcsStatusBroadcaster, make$
|
|
62931
|
+
const layer$12 = Layer.effect(VcsStatusBroadcaster, make$19);
|
|
62169
62932
|
//#endregion
|
|
62170
62933
|
//#region src/vcs/VcsProvisioningService.ts
|
|
62171
62934
|
var VcsProvisioningService = class extends Context.Service()("@p4code/cli/vcs/VcsProvisioningService") {};
|
|
@@ -62178,7 +62941,7 @@ function resolveRequestedKind(kind) {
|
|
|
62178
62941
|
}));
|
|
62179
62942
|
return Effect.succeed(kind);
|
|
62180
62943
|
}
|
|
62181
|
-
const make$
|
|
62944
|
+
const make$18 = Effect.gen(function* () {
|
|
62182
62945
|
const registry = yield* VcsDriverRegistry;
|
|
62183
62946
|
const initRepository = Effect.fn("VcsProvisioningService.initRepository")(function* (input) {
|
|
62184
62947
|
const kind = yield* resolveRequestedKind(input.kind);
|
|
@@ -62186,11 +62949,11 @@ const make$17 = Effect.gen(function* () {
|
|
|
62186
62949
|
});
|
|
62187
62950
|
return VcsProvisioningService.of({ initRepository });
|
|
62188
62951
|
});
|
|
62189
|
-
const layer$11 = Layer.effect(VcsProvisioningService, make$
|
|
62952
|
+
const layer$11 = Layer.effect(VcsProvisioningService, make$18);
|
|
62190
62953
|
//#endregion
|
|
62191
62954
|
//#region src/review/ReviewService.ts
|
|
62192
62955
|
var ReviewService = class extends Context.Service()("@p4code/cli/review/ReviewService") {};
|
|
62193
|
-
const make$
|
|
62956
|
+
const make$17 = Effect.gen(function* () {
|
|
62194
62957
|
const config = yield* ServerConfig$1;
|
|
62195
62958
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
62196
62959
|
const path = yield* Path.Path;
|
|
@@ -62246,7 +63009,7 @@ const make$16 = Effect.gen(function* () {
|
|
|
62246
63009
|
});
|
|
62247
63010
|
return ReviewService.of({ getDiffPreview });
|
|
62248
63011
|
});
|
|
62249
|
-
const layer$10 = Layer.effect(ReviewService, make$
|
|
63012
|
+
const layer$10 = Layer.effect(ReviewService, make$17);
|
|
62250
63013
|
//#endregion
|
|
62251
63014
|
//#region src/diagnostics/ProcessDiagnostics.ts
|
|
62252
63015
|
const PROCESS_QUERY_TIMEOUT_MS = 1e3;
|
|
@@ -62541,7 +63304,7 @@ function assertDescendantPid(pid) {
|
|
|
62541
63304
|
}));
|
|
62542
63305
|
}));
|
|
62543
63306
|
}
|
|
62544
|
-
const make$
|
|
63307
|
+
const make$16 = Effect.gen(function* () {
|
|
62545
63308
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
62546
63309
|
const read = Effect.gen(function* () {
|
|
62547
63310
|
const readAt = yield* DateTime.now;
|
|
@@ -62585,7 +63348,7 @@ const make$15 = Effect.gen(function* () {
|
|
|
62585
63348
|
signal
|
|
62586
63349
|
});
|
|
62587
63350
|
});
|
|
62588
|
-
const layer$9 = Layer.effect(ProcessDiagnostics, make$
|
|
63351
|
+
const layer$9 = Layer.effect(ProcessDiagnostics, make$16);
|
|
62589
63352
|
//#endregion
|
|
62590
63353
|
//#region src/diagnostics/ProcessResourceMonitor.ts
|
|
62591
63354
|
const SAMPLE_INTERVAL_MS = 5e3;
|
|
@@ -62736,7 +63499,7 @@ function aggregateProcessResourceHistory(input) {
|
|
|
62736
63499
|
}) : Option.none()
|
|
62737
63500
|
};
|
|
62738
63501
|
}
|
|
62739
|
-
const make$
|
|
63502
|
+
const make$15 = Effect.gen(function* () {
|
|
62740
63503
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
62741
63504
|
const state = yield* Ref.make({
|
|
62742
63505
|
samples: [],
|
|
@@ -62785,7 +63548,7 @@ const make$14 = Effect.gen(function* () {
|
|
|
62785
63548
|
});
|
|
62786
63549
|
return ProcessResourceMonitor.of({ readHistory });
|
|
62787
63550
|
});
|
|
62788
|
-
const layer$8 = Layer.effect(ProcessResourceMonitor, make$
|
|
63551
|
+
const layer$8 = Layer.effect(ProcessResourceMonitor, make$15);
|
|
62789
63552
|
//#endregion
|
|
62790
63553
|
//#region src/diagnostics/TraceDiagnostics.ts
|
|
62791
63554
|
var TraceFileReadError = class extends Schema$1.TaggedErrorClass()("TraceFileReadError", {
|
|
@@ -63033,7 +63796,7 @@ function readTraceFile(fileSystem, path) {
|
|
|
63033
63796
|
cause
|
|
63034
63797
|
})) }));
|
|
63035
63798
|
}
|
|
63036
|
-
const make$
|
|
63799
|
+
const make$14 = Effect.gen(function* () {
|
|
63037
63800
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
63038
63801
|
const read = Effect.fn("TraceDiagnostics.read")(function* (options) {
|
|
63039
63802
|
const readAt = options.readAt ?? (yield* DateTime.now);
|
|
@@ -63077,7 +63840,7 @@ const make$13 = Effect.gen(function* () {
|
|
|
63077
63840
|
});
|
|
63078
63841
|
return TraceDiagnostics.of({ read });
|
|
63079
63842
|
});
|
|
63080
|
-
const layer$7 = Layer.effect(TraceDiagnostics, make$
|
|
63843
|
+
const layer$7 = Layer.effect(TraceDiagnostics, make$14);
|
|
63081
63844
|
function readTraceDiagnostics(options) {
|
|
63082
63845
|
return Effect.gen(function* () {
|
|
63083
63846
|
return yield* (yield* TraceDiagnostics).read(options);
|
|
@@ -63101,7 +63864,7 @@ const VCS_PROBES = [{
|
|
|
63101
63864
|
installHint: "Install Jujutsu with `brew install jj` or from https://github.com/jj-vcs/jj."
|
|
63102
63865
|
}];
|
|
63103
63866
|
var SourceControlDiscovery = class extends Context.Service()("@p4code/cli/sourceControl/SourceControlDiscovery") {};
|
|
63104
|
-
const make$
|
|
63867
|
+
const make$13 = Effect.gen(function* () {
|
|
63105
63868
|
const config = yield* ServerConfig$1;
|
|
63106
63869
|
const process = yield* VcsProcess;
|
|
63107
63870
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
@@ -63150,7 +63913,7 @@ const make$12 = Effect.gen(function* () {
|
|
|
63150
63913
|
sourceControlProviders: sourceControlProviders.discover
|
|
63151
63914
|
}) });
|
|
63152
63915
|
});
|
|
63153
|
-
const layer$6 = Layer.effect(SourceControlDiscovery, make$
|
|
63916
|
+
const layer$6 = Layer.effect(SourceControlDiscovery, make$13);
|
|
63154
63917
|
//#endregion
|
|
63155
63918
|
//#region src/sourceControl/SourceControlRepositoryService.ts
|
|
63156
63919
|
const isSourceControlRepositoryError = Schema$1.is(SourceControlRepositoryError);
|
|
@@ -63183,7 +63946,7 @@ function expandHomePath(input, path) {
|
|
|
63183
63946
|
if (input.startsWith("~/") || input.startsWith("~\\")) return path.join(NodeOS.homedir(), input.slice(2));
|
|
63184
63947
|
return input;
|
|
63185
63948
|
}
|
|
63186
|
-
const make$
|
|
63949
|
+
const make$12 = Effect.gen(function* () {
|
|
63187
63950
|
const config = yield* ServerConfig$1;
|
|
63188
63951
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
63189
63952
|
const git = yield* GitVcsDriver;
|
|
@@ -63322,7 +64085,7 @@ const make$11 = Effect.gen(function* () {
|
|
|
63322
64085
|
publishRepository: (input) => publishRepository(input).pipe(mapRepositoryError("publishRepository", input.provider))
|
|
63323
64086
|
});
|
|
63324
64087
|
});
|
|
63325
|
-
const layer$5 = Layer.effect(SourceControlRepositoryService, make$
|
|
64088
|
+
const layer$5 = Layer.effect(SourceControlRepositoryService, make$12);
|
|
63326
64089
|
//#endregion
|
|
63327
64090
|
//#region src/ws.ts
|
|
63328
64091
|
/** Matches `p4c hub token add`, so a token minted here and one minted there are the same thing. */
|
|
@@ -63424,7 +64187,7 @@ function projectSetupScriptCompatibilityDetail(error) {
|
|
|
63424
64187
|
}
|
|
63425
64188
|
}
|
|
63426
64189
|
function isThreadDetailEvent(event) {
|
|
63427
|
-
return event.type === "thread.message-sent" || event.type === "thread.proposed-plan-upserted" || event.type === "thread.activity-appended" || event.type === "thread.turn-diff-completed" || event.type === "thread.reverted" || event.type === "thread.session-set";
|
|
64190
|
+
return event.type === "thread.message-sent" || event.type === "thread.proposed-plan-upserted" || event.type === "thread.scheduled-task.created" || event.type === "thread.scheduled-task.cancelled" || event.type === "thread.scheduled-task.fired" || event.type === "thread.activity-appended" || event.type === "thread.turn-diff-completed" || event.type === "thread.reverted" || event.type === "thread.session-set";
|
|
63428
64191
|
}
|
|
63429
64192
|
const PROVIDER_STATUS_DEBOUNCE_MS = 200;
|
|
63430
64193
|
const SHELL_RESUME_MAX_GAP = 1e3;
|
|
@@ -63622,6 +64385,7 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker) => WsRpcGroup.t
|
|
|
63622
64385
|
const previewManager = yield* PreviewManager;
|
|
63623
64386
|
const portDiscovery = yield* PortDiscovery;
|
|
63624
64387
|
const providerRegistry = yield* ProviderRegistry;
|
|
64388
|
+
const providerSessionDirectory = yield* ProviderSessionDirectory;
|
|
63625
64389
|
const providerMaintenanceRunner = yield* ProviderMaintenanceRunner;
|
|
63626
64390
|
const serverSelfUpdate = yield* ServerSelfUpdate;
|
|
63627
64391
|
const textGeneration = yield* TextGeneration;
|
|
@@ -64018,7 +64782,22 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker) => WsRpcGroup.t
|
|
|
64018
64782
|
onNone: () => false,
|
|
64019
64783
|
onSome: (thread) => thread.session !== null && thread.session.status !== "stopped"
|
|
64020
64784
|
})), Effect.orElseSucceed(() => false)) : false;
|
|
64021
|
-
const result = yield*
|
|
64785
|
+
const result = normalizedCommand.type === "thread.fork" ? yield* Effect.uninterruptible(Effect.gen(function* () {
|
|
64786
|
+
if (yield* projectionSnapshotQuery.getThreadShellById(normalizedCommand.threadId).pipe(Effect.map(Option.isSome), Effect.orElseSucceed(() => false))) return yield* dispatchNormalizedCommand(normalizedCommand);
|
|
64787
|
+
const forkBinding = yield* providerSessionDirectory.getBinding(normalizedCommand.sourceThreadId).pipe(Effect.map((source) => buildForkedProviderBinding(normalizedCommand.threadId, Option.getOrUndefined(source))), Effect.mapError((error) => new OrchestrationDispatchCommandError({
|
|
64788
|
+
message: `Could not read the source thread's provider session: ${error.message}`,
|
|
64789
|
+
cause: error
|
|
64790
|
+
})));
|
|
64791
|
+
if (forkBinding.rejection !== void 0) return yield* new OrchestrationDispatchCommandError({ message: describeThreadForkRejection(forkBinding.rejection) });
|
|
64792
|
+
yield* providerSessionDirectory.upsert(forkBinding.binding).pipe(Effect.mapError((error) => new OrchestrationDispatchCommandError({
|
|
64793
|
+
message: `Could not save the fork's provider session: ${error.message}`,
|
|
64794
|
+
cause: error
|
|
64795
|
+
})));
|
|
64796
|
+
return yield* dispatchNormalizedCommand(normalizedCommand).pipe(Effect.tapError(() => providerSessionDirectory.remove(normalizedCommand.threadId).pipe(Effect.catchCause((cause) => Effect.logWarning("failed to remove fork binding after dispatch failure", {
|
|
64797
|
+
threadId: normalizedCommand.threadId,
|
|
64798
|
+
cause
|
|
64799
|
+
})))));
|
|
64800
|
+
})) : yield* dispatchNormalizedCommand(normalizedCommand);
|
|
64022
64801
|
if (normalizedCommand.type === "thread.archive") {
|
|
64023
64802
|
const archivedThreadIds = result.events?.filter((event) => event.type === "thread.archived").map((event) => event.payload.threadId);
|
|
64024
64803
|
if (archivedThreadIds === void 0 || archivedThreadIds.length === 0) return yield* new OrchestrationDispatchCommandError({ message: "Archive command completed without authoritative archive events." });
|
|
@@ -64609,7 +65388,7 @@ function toPersistenceSqlOrDecodeError(sqlOperation, decodeOperation, correlatio
|
|
|
64609
65388
|
cause
|
|
64610
65389
|
});
|
|
64611
65390
|
}
|
|
64612
|
-
const make$
|
|
65391
|
+
const make$11 = Effect.gen(function* () {
|
|
64613
65392
|
const sql = yield* SqlClient.SqlClient;
|
|
64614
65393
|
const upsertRuntimeRow = SqlSchema.void({
|
|
64615
65394
|
Request: ProviderSessionRuntimeDbRowSchema,
|
|
@@ -64712,7 +65491,7 @@ const make$10 = Effect.gen(function* () {
|
|
|
64712
65491
|
deleteByThreadId
|
|
64713
65492
|
};
|
|
64714
65493
|
});
|
|
64715
|
-
const layer$4 = Layer.effect(ProviderSessionRuntimeRepository, make$
|
|
65494
|
+
const layer$4 = Layer.effect(ProviderSessionRuntimeRepository, make$11);
|
|
64716
65495
|
//#endregion
|
|
64717
65496
|
//#region src/provider/Errors.ts
|
|
64718
65497
|
/**
|
|
@@ -64837,9 +65616,6 @@ var ProviderSessionDirectoryPersistenceError = class extends Schema$1.TaggedErro
|
|
|
64837
65616
|
}
|
|
64838
65617
|
};
|
|
64839
65618
|
//#endregion
|
|
64840
|
-
//#region src/provider/Services/ProviderSessionDirectory.ts
|
|
64841
|
-
var ProviderSessionDirectory = class extends Context.Service()("@p4code/cli/provider/Services/ProviderSessionDirectory") {};
|
|
64842
|
-
//#endregion
|
|
64843
65619
|
//#region src/provider/Layers/ProviderSessionDirectory.ts
|
|
64844
65620
|
const decodeProviderDriverKindValue = Schema$1.decodeUnknownEffect(ProviderDriverKind);
|
|
64845
65621
|
function toPersistenceError(operation) {
|
|
@@ -64920,12 +65696,14 @@ const makeProviderSessionDirectory = Effect.gen(function* () {
|
|
|
64920
65696
|
detail: `No persisted provider binding found for thread '${threadId}'.`
|
|
64921
65697
|
}))
|
|
64922
65698
|
})));
|
|
65699
|
+
const remove = (threadId) => repository.deleteByThreadId({ threadId }).pipe(Effect.mapError(toPersistenceError("ProviderSessionDirectory.remove:deleteByThreadId")));
|
|
64923
65700
|
const listThreadIds = () => repository.list().pipe(Effect.mapError(toPersistenceError("ProviderSessionDirectory.listThreadIds:list")), Effect.map((rows) => rows.map((row) => row.threadId)));
|
|
64924
65701
|
const listBindings = () => repository.list().pipe(Effect.mapError(toPersistenceError("ProviderSessionDirectory.listBindings:list")), Effect.flatMap((rows) => Effect.forEach(rows, (row) => toRuntimeBinding(row, "ProviderSessionDirectory.listBindings"), { concurrency: "unbounded" })));
|
|
64925
65702
|
return {
|
|
64926
65703
|
upsert,
|
|
64927
65704
|
getProvider,
|
|
64928
65705
|
getBinding,
|
|
65706
|
+
remove,
|
|
64929
65707
|
listThreadIds,
|
|
64930
65708
|
listBindings
|
|
64931
65709
|
};
|
|
@@ -65600,12 +66378,12 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
65600
66378
|
});
|
|
65601
66379
|
});
|
|
65602
66380
|
let activeMcpSessionRegistry;
|
|
65603
|
-
const make$
|
|
66381
|
+
const make$10 = Effect.acquireRelease(makeWithOptions().pipe(Effect.tap((registry) => Effect.sync(() => {
|
|
65604
66382
|
activeMcpSessionRegistry = registry;
|
|
65605
66383
|
}))), (registry) => Effect.sync(() => {
|
|
65606
66384
|
if (activeMcpSessionRegistry === registry) activeMcpSessionRegistry = void 0;
|
|
65607
66385
|
}));
|
|
65608
|
-
const layer$3 = Layer.effect(McpSessionRegistry, make$
|
|
66386
|
+
const layer$3 = Layer.effect(McpSessionRegistry, make$10);
|
|
65609
66387
|
const issueActiveMcpCredential = (request) => activeMcpSessionRegistry ? activeMcpSessionRegistry.revokeThread(request.threadId).pipe(Effect.andThen(activeMcpSessionRegistry.issue(request))) : Effect.sync(() => void 0);
|
|
65610
66388
|
/**
|
|
65611
66389
|
* Refreshes the liveness of a thread's MCP credential. Called on every provider
|
|
@@ -67229,53 +68007,84 @@ const MINIMUM_CLAUDE_OPUS_5_VERSION = "2.1.219";
|
|
|
67229
68007
|
const MINIMUM_CLAUDE_FABLE_5_VERSION = "2.1.169";
|
|
67230
68008
|
const MINIMUM_CLAUDE_OPUS_4_8_VERSION = "2.1.154";
|
|
67231
68009
|
const MINIMUM_CLAUDE_OPUS_4_7_VERSION = "2.1.111";
|
|
67232
|
-
const
|
|
67233
|
-
|
|
67234
|
-
|
|
67235
|
-
|
|
67236
|
-
|
|
67237
|
-
|
|
67238
|
-
|
|
67239
|
-
|
|
67240
|
-
|
|
67241
|
-
|
|
67242
|
-
|
|
67243
|
-
|
|
67244
|
-
|
|
67245
|
-
|
|
67246
|
-
|
|
68010
|
+
const AUTO_COMPACT_WINDOW_OPTION_ID = "autoCompactWindow";
|
|
68011
|
+
const AUTO_COMPACT_WINDOW_AUTO = "auto";
|
|
68012
|
+
/** Token counts behind each explicit auto-compact choice. */
|
|
68013
|
+
const AUTO_COMPACT_WINDOW_TOKENS = {
|
|
68014
|
+
"200k": 2e5,
|
|
68015
|
+
"400k": 4e5,
|
|
68016
|
+
"600k": 6e5
|
|
68017
|
+
};
|
|
68018
|
+
/**
|
|
68019
|
+
* Where Claude Code starts summarising the conversation. "Auto" keeps Claude
|
|
68020
|
+
* Code's own per-model threshold, which on 1M-context models lets a session
|
|
68021
|
+
* grow close to 1M tokens and re-read all of it on every call.
|
|
68022
|
+
*/
|
|
68023
|
+
function buildAutoCompactWindowDescriptor() {
|
|
68024
|
+
return buildSelectOptionDescriptor({
|
|
68025
|
+
id: AUTO_COMPACT_WINDOW_OPTION_ID,
|
|
68026
|
+
label: "Auto-compact At",
|
|
68027
|
+
options: [{
|
|
68028
|
+
value: AUTO_COMPACT_WINDOW_AUTO,
|
|
68029
|
+
label: "Auto",
|
|
67247
68030
|
isDefault: true
|
|
67248
|
-
},
|
|
67249
|
-
|
|
67250
|
-
|
|
67251
|
-
|
|
67252
|
-
|
|
67253
|
-
|
|
67254
|
-
|
|
67255
|
-
|
|
67256
|
-
|
|
67257
|
-
|
|
67258
|
-
|
|
67259
|
-
|
|
67260
|
-
|
|
67261
|
-
|
|
67262
|
-
|
|
67263
|
-
|
|
67264
|
-
|
|
67265
|
-
|
|
67266
|
-
|
|
67267
|
-
|
|
67268
|
-
|
|
67269
|
-
|
|
67270
|
-
|
|
67271
|
-
|
|
67272
|
-
|
|
67273
|
-
|
|
67274
|
-
|
|
67275
|
-
|
|
67276
|
-
|
|
67277
|
-
|
|
67278
|
-
|
|
68031
|
+
}, ...Object.keys(AUTO_COMPACT_WINDOW_TOKENS).map((value) => ({
|
|
68032
|
+
value,
|
|
68033
|
+
label: value
|
|
68034
|
+
}))]
|
|
68035
|
+
});
|
|
68036
|
+
}
|
|
68037
|
+
const CLAUDE_FABLE_CAPABILITIES = createModelCapabilities({ optionDescriptors: [
|
|
68038
|
+
buildSelectOptionDescriptor({
|
|
68039
|
+
id: "effort",
|
|
68040
|
+
label: "Reasoning",
|
|
68041
|
+
options: [
|
|
68042
|
+
{
|
|
68043
|
+
value: "low",
|
|
68044
|
+
label: "Low"
|
|
68045
|
+
},
|
|
68046
|
+
{
|
|
68047
|
+
value: "medium",
|
|
68048
|
+
label: "Medium"
|
|
68049
|
+
},
|
|
68050
|
+
{
|
|
68051
|
+
value: "high",
|
|
68052
|
+
label: "High",
|
|
68053
|
+
isDefault: true
|
|
68054
|
+
},
|
|
68055
|
+
{
|
|
68056
|
+
value: "xhigh",
|
|
68057
|
+
label: "Extra High"
|
|
68058
|
+
},
|
|
68059
|
+
{
|
|
68060
|
+
value: "max",
|
|
68061
|
+
label: "Max"
|
|
68062
|
+
},
|
|
68063
|
+
{
|
|
68064
|
+
value: "ultracode",
|
|
68065
|
+
label: "Ultracode"
|
|
68066
|
+
},
|
|
68067
|
+
{
|
|
68068
|
+
value: "ultrathink",
|
|
68069
|
+
label: "Ultrathink"
|
|
68070
|
+
}
|
|
68071
|
+
],
|
|
68072
|
+
promptInjectedValues: ["ultrathink"]
|
|
68073
|
+
}),
|
|
68074
|
+
buildSelectOptionDescriptor({
|
|
68075
|
+
id: "contextWindow",
|
|
68076
|
+
label: "Context Window",
|
|
68077
|
+
options: [{
|
|
68078
|
+
value: "200k",
|
|
68079
|
+
label: "200k"
|
|
68080
|
+
}, {
|
|
68081
|
+
value: "1m",
|
|
68082
|
+
label: "1M",
|
|
68083
|
+
isDefault: true
|
|
68084
|
+
}]
|
|
68085
|
+
}),
|
|
68086
|
+
buildAutoCompactWindowDescriptor()
|
|
68087
|
+
] });
|
|
67279
68088
|
const BUILT_IN_MODELS = [
|
|
67280
68089
|
{
|
|
67281
68090
|
slug: "claude-fable-5-1",
|
|
@@ -67345,12 +68154,157 @@ const BUILT_IN_MODELS = [
|
|
|
67345
68154
|
label: "1M",
|
|
67346
68155
|
isDefault: true
|
|
67347
68156
|
}]
|
|
67348
|
-
})
|
|
68157
|
+
}),
|
|
68158
|
+
buildAutoCompactWindowDescriptor()
|
|
68159
|
+
] })
|
|
68160
|
+
},
|
|
68161
|
+
{
|
|
68162
|
+
slug: "claude-opus-4-8",
|
|
68163
|
+
name: "Claude Opus 4.8",
|
|
68164
|
+
isCustom: false,
|
|
68165
|
+
capabilities: createModelCapabilities({ optionDescriptors: [
|
|
68166
|
+
buildSelectOptionDescriptor({
|
|
68167
|
+
id: "effort",
|
|
68168
|
+
label: "Reasoning",
|
|
68169
|
+
options: [
|
|
68170
|
+
{
|
|
68171
|
+
value: "low",
|
|
68172
|
+
label: "Low"
|
|
68173
|
+
},
|
|
68174
|
+
{
|
|
68175
|
+
value: "medium",
|
|
68176
|
+
label: "Medium"
|
|
68177
|
+
},
|
|
68178
|
+
{
|
|
68179
|
+
value: "high",
|
|
68180
|
+
label: "High",
|
|
68181
|
+
isDefault: true
|
|
68182
|
+
},
|
|
68183
|
+
{
|
|
68184
|
+
value: "xhigh",
|
|
68185
|
+
label: "Extra High"
|
|
68186
|
+
},
|
|
68187
|
+
{
|
|
68188
|
+
value: "max",
|
|
68189
|
+
label: "Max"
|
|
68190
|
+
},
|
|
68191
|
+
{
|
|
68192
|
+
value: "ultracode",
|
|
68193
|
+
label: "Ultracode"
|
|
68194
|
+
},
|
|
68195
|
+
{
|
|
68196
|
+
value: "ultrathink",
|
|
68197
|
+
label: "Ultrathink"
|
|
68198
|
+
}
|
|
68199
|
+
],
|
|
68200
|
+
promptInjectedValues: ["ultrathink"]
|
|
68201
|
+
}),
|
|
68202
|
+
buildBooleanOptionDescriptor({
|
|
68203
|
+
id: "fastMode",
|
|
68204
|
+
label: "Fast Mode"
|
|
68205
|
+
}),
|
|
68206
|
+
buildAutoCompactWindowDescriptor()
|
|
68207
|
+
] })
|
|
68208
|
+
},
|
|
68209
|
+
{
|
|
68210
|
+
slug: "claude-opus-4-7",
|
|
68211
|
+
name: "Claude Opus 4.7",
|
|
68212
|
+
isCustom: false,
|
|
68213
|
+
capabilities: createModelCapabilities({ optionDescriptors: [
|
|
68214
|
+
buildSelectOptionDescriptor({
|
|
68215
|
+
id: "effort",
|
|
68216
|
+
label: "Reasoning",
|
|
68217
|
+
options: [
|
|
68218
|
+
{
|
|
68219
|
+
value: "low",
|
|
68220
|
+
label: "Low"
|
|
68221
|
+
},
|
|
68222
|
+
{
|
|
68223
|
+
value: "medium",
|
|
68224
|
+
label: "Medium"
|
|
68225
|
+
},
|
|
68226
|
+
{
|
|
68227
|
+
value: "high",
|
|
68228
|
+
label: "High"
|
|
68229
|
+
},
|
|
68230
|
+
{
|
|
68231
|
+
value: "xhigh",
|
|
68232
|
+
label: "Extra High",
|
|
68233
|
+
isDefault: true
|
|
68234
|
+
},
|
|
68235
|
+
{
|
|
68236
|
+
value: "max",
|
|
68237
|
+
label: "Max"
|
|
68238
|
+
},
|
|
68239
|
+
{
|
|
68240
|
+
value: "ultrathink",
|
|
68241
|
+
label: "Ultrathink"
|
|
68242
|
+
}
|
|
68243
|
+
],
|
|
68244
|
+
promptInjectedValues: ["ultrathink"]
|
|
68245
|
+
}),
|
|
68246
|
+
buildBooleanOptionDescriptor({
|
|
68247
|
+
id: "fastMode",
|
|
68248
|
+
label: "Fast Mode"
|
|
68249
|
+
}),
|
|
68250
|
+
buildAutoCompactWindowDescriptor()
|
|
68251
|
+
] })
|
|
68252
|
+
},
|
|
68253
|
+
{
|
|
68254
|
+
slug: "claude-opus-4-6",
|
|
68255
|
+
name: "Claude Opus 4.6",
|
|
68256
|
+
isCustom: false,
|
|
68257
|
+
capabilities: createModelCapabilities({ optionDescriptors: [
|
|
68258
|
+
buildSelectOptionDescriptor({
|
|
68259
|
+
id: "effort",
|
|
68260
|
+
label: "Reasoning",
|
|
68261
|
+
options: [
|
|
68262
|
+
{
|
|
68263
|
+
value: "low",
|
|
68264
|
+
label: "Low"
|
|
68265
|
+
},
|
|
68266
|
+
{
|
|
68267
|
+
value: "medium",
|
|
68268
|
+
label: "Medium"
|
|
68269
|
+
},
|
|
68270
|
+
{
|
|
68271
|
+
value: "high",
|
|
68272
|
+
label: "High",
|
|
68273
|
+
isDefault: true
|
|
68274
|
+
},
|
|
68275
|
+
{
|
|
68276
|
+
value: "max",
|
|
68277
|
+
label: "Max"
|
|
68278
|
+
},
|
|
68279
|
+
{
|
|
68280
|
+
value: "ultrathink",
|
|
68281
|
+
label: "Ultrathink"
|
|
68282
|
+
}
|
|
68283
|
+
],
|
|
68284
|
+
promptInjectedValues: ["ultrathink"]
|
|
68285
|
+
}),
|
|
68286
|
+
buildBooleanOptionDescriptor({
|
|
68287
|
+
id: "fastMode",
|
|
68288
|
+
label: "Fast Mode"
|
|
68289
|
+
}),
|
|
68290
|
+
buildSelectOptionDescriptor({
|
|
68291
|
+
id: "contextWindow",
|
|
68292
|
+
label: "Context Window",
|
|
68293
|
+
options: [{
|
|
68294
|
+
value: "200k",
|
|
68295
|
+
label: "200k"
|
|
68296
|
+
}, {
|
|
68297
|
+
value: "1m",
|
|
68298
|
+
label: "1M",
|
|
68299
|
+
isDefault: true
|
|
68300
|
+
}]
|
|
68301
|
+
}),
|
|
68302
|
+
buildAutoCompactWindowDescriptor()
|
|
67349
68303
|
] })
|
|
67350
68304
|
},
|
|
67351
68305
|
{
|
|
67352
|
-
slug: "claude-opus-4-
|
|
67353
|
-
name: "Claude Opus 4.
|
|
68306
|
+
slug: "claude-opus-4-5",
|
|
68307
|
+
name: "Claude Opus 4.5",
|
|
67354
68308
|
isCustom: false,
|
|
67355
68309
|
capabilities: createModelCapabilities({ optionDescriptors: [buildSelectOptionDescriptor({
|
|
67356
68310
|
id: "effort",
|
|
@@ -67369,72 +68323,19 @@ const BUILT_IN_MODELS = [
|
|
|
67369
68323
|
label: "High",
|
|
67370
68324
|
isDefault: true
|
|
67371
68325
|
},
|
|
67372
|
-
{
|
|
67373
|
-
value: "xhigh",
|
|
67374
|
-
label: "Extra High"
|
|
67375
|
-
},
|
|
67376
|
-
{
|
|
67377
|
-
value: "max",
|
|
67378
|
-
label: "Max"
|
|
67379
|
-
},
|
|
67380
|
-
{
|
|
67381
|
-
value: "ultracode",
|
|
67382
|
-
label: "Ultracode"
|
|
67383
|
-
},
|
|
67384
|
-
{
|
|
67385
|
-
value: "ultrathink",
|
|
67386
|
-
label: "Ultrathink"
|
|
67387
|
-
}
|
|
67388
|
-
],
|
|
67389
|
-
promptInjectedValues: ["ultrathink"]
|
|
67390
|
-
}), buildBooleanOptionDescriptor({
|
|
67391
|
-
id: "fastMode",
|
|
67392
|
-
label: "Fast Mode"
|
|
67393
|
-
})] })
|
|
67394
|
-
},
|
|
67395
|
-
{
|
|
67396
|
-
slug: "claude-opus-4-7",
|
|
67397
|
-
name: "Claude Opus 4.7",
|
|
67398
|
-
isCustom: false,
|
|
67399
|
-
capabilities: createModelCapabilities({ optionDescriptors: [buildSelectOptionDescriptor({
|
|
67400
|
-
id: "effort",
|
|
67401
|
-
label: "Reasoning",
|
|
67402
|
-
options: [
|
|
67403
|
-
{
|
|
67404
|
-
value: "low",
|
|
67405
|
-
label: "Low"
|
|
67406
|
-
},
|
|
67407
|
-
{
|
|
67408
|
-
value: "medium",
|
|
67409
|
-
label: "Medium"
|
|
67410
|
-
},
|
|
67411
|
-
{
|
|
67412
|
-
value: "high",
|
|
67413
|
-
label: "High"
|
|
67414
|
-
},
|
|
67415
|
-
{
|
|
67416
|
-
value: "xhigh",
|
|
67417
|
-
label: "Extra High",
|
|
67418
|
-
isDefault: true
|
|
67419
|
-
},
|
|
67420
68326
|
{
|
|
67421
68327
|
value: "max",
|
|
67422
68328
|
label: "Max"
|
|
67423
|
-
},
|
|
67424
|
-
{
|
|
67425
|
-
value: "ultrathink",
|
|
67426
|
-
label: "Ultrathink"
|
|
67427
68329
|
}
|
|
67428
|
-
]
|
|
67429
|
-
promptInjectedValues: ["ultrathink"]
|
|
68330
|
+
]
|
|
67430
68331
|
}), buildBooleanOptionDescriptor({
|
|
67431
68332
|
id: "fastMode",
|
|
67432
68333
|
label: "Fast Mode"
|
|
67433
68334
|
})] })
|
|
67434
68335
|
},
|
|
67435
68336
|
{
|
|
67436
|
-
slug: "claude-
|
|
67437
|
-
name: "Claude
|
|
68337
|
+
slug: "claude-sonnet-5",
|
|
68338
|
+
name: "Claude Sonnet 5",
|
|
67438
68339
|
isCustom: false,
|
|
67439
68340
|
capabilities: createModelCapabilities({ optionDescriptors: [
|
|
67440
68341
|
buildSelectOptionDescriptor({
|
|
@@ -67454,6 +68355,10 @@ const BUILT_IN_MODELS = [
|
|
|
67454
68355
|
label: "High",
|
|
67455
68356
|
isDefault: true
|
|
67456
68357
|
},
|
|
68358
|
+
{
|
|
68359
|
+
value: "xhigh",
|
|
68360
|
+
label: "Extra High"
|
|
68361
|
+
},
|
|
67457
68362
|
{
|
|
67458
68363
|
value: "max",
|
|
67459
68364
|
label: "Max"
|
|
@@ -67465,146 +68370,68 @@ const BUILT_IN_MODELS = [
|
|
|
67465
68370
|
],
|
|
67466
68371
|
promptInjectedValues: ["ultrathink"]
|
|
67467
68372
|
}),
|
|
67468
|
-
buildBooleanOptionDescriptor({
|
|
67469
|
-
id: "fastMode",
|
|
67470
|
-
label: "Fast Mode"
|
|
67471
|
-
}),
|
|
67472
68373
|
buildSelectOptionDescriptor({
|
|
67473
68374
|
id: "contextWindow",
|
|
67474
68375
|
label: "Context Window",
|
|
67475
68376
|
options: [{
|
|
67476
68377
|
value: "200k",
|
|
67477
|
-
label: "200k"
|
|
68378
|
+
label: "200k",
|
|
68379
|
+
isDefault: true
|
|
67478
68380
|
}, {
|
|
67479
68381
|
value: "1m",
|
|
67480
|
-
label: "1M"
|
|
67481
|
-
isDefault: true
|
|
68382
|
+
label: "1M"
|
|
67482
68383
|
}]
|
|
67483
|
-
})
|
|
68384
|
+
}),
|
|
68385
|
+
buildAutoCompactWindowDescriptor()
|
|
67484
68386
|
] })
|
|
67485
68387
|
},
|
|
67486
|
-
{
|
|
67487
|
-
slug: "claude-opus-4-5",
|
|
67488
|
-
name: "Claude Opus 4.5",
|
|
67489
|
-
isCustom: false,
|
|
67490
|
-
capabilities: createModelCapabilities({ optionDescriptors: [buildSelectOptionDescriptor({
|
|
67491
|
-
id: "effort",
|
|
67492
|
-
label: "Reasoning",
|
|
67493
|
-
options: [
|
|
67494
|
-
{
|
|
67495
|
-
value: "low",
|
|
67496
|
-
label: "Low"
|
|
67497
|
-
},
|
|
67498
|
-
{
|
|
67499
|
-
value: "medium",
|
|
67500
|
-
label: "Medium"
|
|
67501
|
-
},
|
|
67502
|
-
{
|
|
67503
|
-
value: "high",
|
|
67504
|
-
label: "High",
|
|
67505
|
-
isDefault: true
|
|
67506
|
-
},
|
|
67507
|
-
{
|
|
67508
|
-
value: "max",
|
|
67509
|
-
label: "Max"
|
|
67510
|
-
}
|
|
67511
|
-
]
|
|
67512
|
-
}), buildBooleanOptionDescriptor({
|
|
67513
|
-
id: "fastMode",
|
|
67514
|
-
label: "Fast Mode"
|
|
67515
|
-
})] })
|
|
67516
|
-
},
|
|
67517
|
-
{
|
|
67518
|
-
slug: "claude-sonnet-5",
|
|
67519
|
-
name: "Claude Sonnet 5",
|
|
67520
|
-
isCustom: false,
|
|
67521
|
-
capabilities: createModelCapabilities({ optionDescriptors: [buildSelectOptionDescriptor({
|
|
67522
|
-
id: "effort",
|
|
67523
|
-
label: "Reasoning",
|
|
67524
|
-
options: [
|
|
67525
|
-
{
|
|
67526
|
-
value: "low",
|
|
67527
|
-
label: "Low"
|
|
67528
|
-
},
|
|
67529
|
-
{
|
|
67530
|
-
value: "medium",
|
|
67531
|
-
label: "Medium"
|
|
67532
|
-
},
|
|
67533
|
-
{
|
|
67534
|
-
value: "high",
|
|
67535
|
-
label: "High",
|
|
67536
|
-
isDefault: true
|
|
67537
|
-
},
|
|
67538
|
-
{
|
|
67539
|
-
value: "xhigh",
|
|
67540
|
-
label: "Extra High"
|
|
67541
|
-
},
|
|
67542
|
-
{
|
|
67543
|
-
value: "max",
|
|
67544
|
-
label: "Max"
|
|
67545
|
-
},
|
|
67546
|
-
{
|
|
67547
|
-
value: "ultrathink",
|
|
67548
|
-
label: "Ultrathink"
|
|
67549
|
-
}
|
|
67550
|
-
],
|
|
67551
|
-
promptInjectedValues: ["ultrathink"]
|
|
67552
|
-
}), buildSelectOptionDescriptor({
|
|
67553
|
-
id: "contextWindow",
|
|
67554
|
-
label: "Context Window",
|
|
67555
|
-
options: [{
|
|
67556
|
-
value: "200k",
|
|
67557
|
-
label: "200k",
|
|
67558
|
-
isDefault: true
|
|
67559
|
-
}, {
|
|
67560
|
-
value: "1m",
|
|
67561
|
-
label: "1M"
|
|
67562
|
-
}]
|
|
67563
|
-
})] })
|
|
67564
|
-
},
|
|
67565
68388
|
{
|
|
67566
68389
|
slug: "claude-sonnet-4-6",
|
|
67567
68390
|
name: "Claude Sonnet 4.6",
|
|
67568
68391
|
isCustom: false,
|
|
67569
|
-
capabilities: createModelCapabilities({ optionDescriptors: [
|
|
67570
|
-
|
|
67571
|
-
|
|
67572
|
-
|
|
67573
|
-
|
|
67574
|
-
|
|
67575
|
-
|
|
67576
|
-
|
|
67577
|
-
|
|
67578
|
-
|
|
67579
|
-
|
|
67580
|
-
|
|
67581
|
-
|
|
67582
|
-
|
|
67583
|
-
|
|
68392
|
+
capabilities: createModelCapabilities({ optionDescriptors: [
|
|
68393
|
+
buildSelectOptionDescriptor({
|
|
68394
|
+
id: "effort",
|
|
68395
|
+
label: "Reasoning",
|
|
68396
|
+
options: [
|
|
68397
|
+
{
|
|
68398
|
+
value: "low",
|
|
68399
|
+
label: "Low"
|
|
68400
|
+
},
|
|
68401
|
+
{
|
|
68402
|
+
value: "medium",
|
|
68403
|
+
label: "Medium"
|
|
68404
|
+
},
|
|
68405
|
+
{
|
|
68406
|
+
value: "high",
|
|
68407
|
+
label: "High",
|
|
68408
|
+
isDefault: true
|
|
68409
|
+
},
|
|
68410
|
+
{
|
|
68411
|
+
value: "max",
|
|
68412
|
+
label: "Max"
|
|
68413
|
+
},
|
|
68414
|
+
{
|
|
68415
|
+
value: "ultrathink",
|
|
68416
|
+
label: "Ultrathink"
|
|
68417
|
+
}
|
|
68418
|
+
],
|
|
68419
|
+
promptInjectedValues: ["ultrathink"]
|
|
68420
|
+
}),
|
|
68421
|
+
buildSelectOptionDescriptor({
|
|
68422
|
+
id: "contextWindow",
|
|
68423
|
+
label: "Context Window",
|
|
68424
|
+
options: [{
|
|
68425
|
+
value: "200k",
|
|
68426
|
+
label: "200k",
|
|
67584
68427
|
isDefault: true
|
|
67585
|
-
},
|
|
67586
|
-
|
|
67587
|
-
|
|
67588
|
-
|
|
67589
|
-
|
|
67590
|
-
|
|
67591
|
-
|
|
67592
|
-
label: "Ultrathink"
|
|
67593
|
-
}
|
|
67594
|
-
],
|
|
67595
|
-
promptInjectedValues: ["ultrathink"]
|
|
67596
|
-
}), buildSelectOptionDescriptor({
|
|
67597
|
-
id: "contextWindow",
|
|
67598
|
-
label: "Context Window",
|
|
67599
|
-
options: [{
|
|
67600
|
-
value: "200k",
|
|
67601
|
-
label: "200k",
|
|
67602
|
-
isDefault: true
|
|
67603
|
-
}, {
|
|
67604
|
-
value: "1m",
|
|
67605
|
-
label: "1M"
|
|
67606
|
-
}]
|
|
67607
|
-
})] })
|
|
68428
|
+
}, {
|
|
68429
|
+
value: "1m",
|
|
68430
|
+
label: "1M"
|
|
68431
|
+
}]
|
|
68432
|
+
}),
|
|
68433
|
+
buildAutoCompactWindowDescriptor()
|
|
68434
|
+
] })
|
|
67608
68435
|
},
|
|
67609
68436
|
{
|
|
67610
68437
|
slug: "claude-haiku-4-5",
|
|
@@ -67702,6 +68529,11 @@ function resolveClaudeContextWindow(modelSelection) {
|
|
|
67702
68529
|
}).find((candidate) => candidate.id === "contextWindow"));
|
|
67703
68530
|
return typeof value === "string" ? value : void 0;
|
|
67704
68531
|
}
|
|
68532
|
+
/** Tokens at which Claude Code should auto-compact, or undefined for its default. */
|
|
68533
|
+
function resolveClaudeAutoCompactWindow(modelSelection) {
|
|
68534
|
+
const raw = getModelSelectionStringOptionValue(modelSelection, AUTO_COMPACT_WINDOW_OPTION_ID);
|
|
68535
|
+
return raw === void 0 ? void 0 : AUTO_COMPACT_WINDOW_TOKENS[raw];
|
|
68536
|
+
}
|
|
67705
68537
|
function resolveClaudeApiModelId(modelSelection) {
|
|
67706
68538
|
switch (resolveClaudeContextWindow(modelSelection)) {
|
|
67707
68539
|
case "1m": return `${modelSelection.model}[1m]`;
|
|
@@ -68433,7 +69265,7 @@ function formatAskUserQuestionAnswers(answers) {
|
|
|
68433
69265
|
/** Fresh-evidence gate adapted from superpowers' verification skill. */
|
|
68434
69266
|
const VERIFY_BEFORE_COMPLETION_PROMPT = "NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE. Before claiming complete, fixed, or passing: 1) identify proving command; 2) run it fresh and fully; 3) read full output, exit code, failure count; 4) confirm evidence matches claim; 5) state claim with evidence. Missing or failed proof: report actual status.";
|
|
68435
69267
|
/** Visual-proof gate for user-visible frontend work. */
|
|
68436
|
-
const SCREENSHOTS_AFTER_UI_WORK_PROMPT = "AFTER USER-VISIBLE FRONTEND WORK, FRESH VISUAL PROOF IS MANDATORY. Before completing: 1) run the relevant real client; 2) inspect the full changed surface; 3) when P4Code preview is available,
|
|
69268
|
+
const SCREENSHOTS_AFTER_UI_WORK_PROMPT = "AFTER USER-VISIBLE FRONTEND WORK, FRESH VISUAL PROOF IS MANDATORY. Before completing: 1) run the relevant real client; 2) inspect the full changed surface; 3) when P4Code preview is available, inspect with preview_snapshot (text state by default; pass includeScreenshot: true only for the final visual check), then call preview_save_screenshot once after verification passes so P4Code saves the final state under Settings > Screenshots; 4) otherwise capture the verified final state with the relevant approved browser, simulator, or computer tool; 5) verify the screenshot shows the requested result without visible errors; 6) include it in the final response. Keep screenshots out of your own context where possible: delegate repeated visual inspection to a read-only visual review subagent when one is available and only pull the final proof yourself. Ask before launching browser or computer use when approval is required. Skip only work with no user-visible frontend change.";
|
|
68437
69269
|
/** Root-cause gate adapted from superpowers' systematic-debugging skill. */
|
|
68438
69270
|
const ROOT_CAUSE_BEFORE_FIX_PROMPT = "NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST. For bugs or unexpected behavior: 1) read errors, reproduce, inspect recent changes, trace data to source; 2) compare working patterns; 3) state one hypothesis and test smallest change; 4) add failing regression test, implement one fix, verify. After 3 failed fixes, question architecture.";
|
|
68439
69271
|
function guardrailPromptsFor(settings) {
|
|
@@ -68889,7 +69721,8 @@ function readClaudeResumeState(resumeCursor) {
|
|
|
68889
69721
|
...threadId ? { threadId } : {},
|
|
68890
69722
|
...resume ? { resume } : {},
|
|
68891
69723
|
...resumeSessionAt ? { resumeSessionAt } : {},
|
|
68892
|
-
...turnCountValue !== void 0 && Number.isInteger(turnCountValue) && turnCountValue >= 0 ? { turnCount: turnCountValue } : {}
|
|
69724
|
+
...turnCountValue !== void 0 && Number.isInteger(turnCountValue) && turnCountValue >= 0 ? { turnCount: turnCountValue } : {},
|
|
69725
|
+
...cursor.forkSession === true && resume ? { forkSession: true } : {}
|
|
68893
69726
|
};
|
|
68894
69727
|
}
|
|
68895
69728
|
function classifyToolItemType(toolName) {
|
|
@@ -70853,8 +71686,9 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
70853
71686
|
const resumeState = readClaudeResumeState(input.resumeCursor);
|
|
70854
71687
|
const threadId = input.threadId;
|
|
70855
71688
|
const existingResumeSessionId = resumeState?.resume;
|
|
70856
|
-
const
|
|
70857
|
-
const
|
|
71689
|
+
const forkSession = resumeState?.forkSession === true && existingResumeSessionId !== void 0;
|
|
71690
|
+
const newSessionId = existingResumeSessionId === void 0 || forkSession ? yield* randomUUIDv4 : void 0;
|
|
71691
|
+
const sessionId = forkSession ? newSessionId : existingResumeSessionId ?? newSessionId;
|
|
70858
71692
|
const runtimeContext = yield* Effect.context();
|
|
70859
71693
|
const runFork = Effect.runForkWith(runtimeContext);
|
|
70860
71694
|
const runPromise = Effect.runPromiseWith(runtimeContext);
|
|
@@ -71059,6 +71893,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
71059
71893
|
const descriptors = getProviderOptionDescriptors({ caps });
|
|
71060
71894
|
const apiModelId = modelSelection ? resolveClaudeApiModelId(modelSelection) : void 0;
|
|
71061
71895
|
const initialContextWindow = selectedClaudeContextWindow(modelSelection);
|
|
71896
|
+
const autoCompactWindow = resolveClaudeAutoCompactWindow(modelSelection);
|
|
71062
71897
|
const effort = resolveClaudeEffort(caps, getModelSelectionStringOptionValue(modelSelection, "effort")) ?? null;
|
|
71063
71898
|
const fastModeSupported = descriptors.some((descriptor) => descriptor.type === "boolean" && descriptor.id === "fastMode");
|
|
71064
71899
|
const thinkingSupported = descriptors.some((descriptor) => descriptor.type === "boolean" && descriptor.id === "thinking");
|
|
@@ -71118,11 +71953,16 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
71118
71953
|
...permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
|
|
71119
71954
|
...Object.keys(settings).length > 0 ? { settings } : {},
|
|
71120
71955
|
...existingResumeSessionId ? { resume: existingResumeSessionId } : {},
|
|
71956
|
+
...forkSession ? { forkSession: true } : {},
|
|
71121
71957
|
...newSessionId ? { sessionId: newSessionId } : {},
|
|
71122
71958
|
includePartialMessages: true,
|
|
71123
71959
|
canUseTool,
|
|
71124
71960
|
hooks: { SubagentStart: [{ hooks: [compressionSubagentHook] }] },
|
|
71125
|
-
env:
|
|
71961
|
+
env: {
|
|
71962
|
+
...claudeEnvironment,
|
|
71963
|
+
CLAUDE_CODE_ENABLE_TODO_TOOLS: claudeEnvironment.CLAUDE_CODE_ENABLE_TODO_TOOLS ?? "1",
|
|
71964
|
+
...autoCompactWindow === void 0 ? {} : { CLAUDE_CODE_AUTO_COMPACT_WINDOW: String(autoCompactWindow) }
|
|
71965
|
+
},
|
|
71126
71966
|
...input.cwd ? { additionalDirectories: [input.cwd] } : {},
|
|
71127
71967
|
...Object.keys(extraArgs).length > 0 ? { extraArgs } : {},
|
|
71128
71968
|
...mcpSession || Object.keys(externalMcpServers).length > 0 ? { mcpServers: {
|
|
@@ -71138,7 +71978,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
71138
71978
|
"provider.kind": PROVIDER$6,
|
|
71139
71979
|
"provider.thread_id": threadId,
|
|
71140
71980
|
"provider.runtime_mode": input.runtimeMode,
|
|
71141
|
-
"claude.resume.source": existingResumeSessionId !== void 0 ? "resume-session" : "generated-session",
|
|
71981
|
+
"claude.resume.source": forkSession ? "fork-session" : existingResumeSessionId !== void 0 ? "resume-session" : "generated-session",
|
|
71142
71982
|
"claude.resume.thread_id": resumeState?.threadId ?? "",
|
|
71143
71983
|
"claude.resume.session_id": existingResumeSessionId ?? "",
|
|
71144
71984
|
"claude.resume.session_at": resumeState?.resumeSessionAt ?? "",
|
|
@@ -89646,7 +90486,7 @@ const makeTerminationError$1 = (handle) => Effect.match(handle.exitCode, {
|
|
|
89646
90486
|
//#endregion
|
|
89647
90487
|
//#region ../../packages/effect-codex-app-server/src/client.ts
|
|
89648
90488
|
var CodexAppServerClient = class extends Context.Service()("effect-codex-app-server/client/CodexAppServerClient") {};
|
|
89649
|
-
const make$
|
|
90489
|
+
const make$9 = Effect.fn("effect-codex-app-server/CodexAppServerClient.make")(function* (stdio, options = {}, terminationError) {
|
|
89650
90490
|
const requestHandlers = /* @__PURE__ */ new Map();
|
|
89651
90491
|
const notificationHandlers = /* @__PURE__ */ new Map();
|
|
89652
90492
|
let unknownRequestHandler;
|
|
@@ -89713,7 +90553,7 @@ const make$8 = Effect.fn("effect-codex-app-server/CodexAppServerClient.make")(fu
|
|
|
89713
90553
|
const layerChildProcess$1 = (handle, options = {}) => Layer.effect(CodexAppServerClient, makeChildProcessClient(handle, options));
|
|
89714
90554
|
const makeChildProcessClient = Effect.fn("effect-codex-app-server/CodexAppServerClient.makeChildProcessClient")(function* (handle, options) {
|
|
89715
90555
|
yield* Stream.runDrain(handle.stderr).pipe(Effect.ignore, Effect.forkScoped);
|
|
89716
|
-
return yield* make$
|
|
90556
|
+
return yield* make$9(makeChildStdio$1(handle), options, makeTerminationError$1(handle));
|
|
89717
90557
|
});
|
|
89718
90558
|
const resolveCodexLaunchArgs = (launchArgs, environment = process.env) => environment["P4CODE_CODEX_LAUNCH_ARGS"]?.trim() || launchArgs?.trim() || "";
|
|
89719
90559
|
const codexLaunchArgv = (launchArgs) => tokenizeCliArgs(launchArgs);
|
|
@@ -91803,10 +92643,15 @@ function collabTaskEvents(event, canonicalThreadId, item, defaults) {
|
|
|
91803
92643
|
}
|
|
91804
92644
|
return events;
|
|
91805
92645
|
}
|
|
91806
|
-
function itemTitle(itemType, item) {
|
|
92646
|
+
function itemTitle(itemType, item, agentNames) {
|
|
91807
92647
|
if (itemType === "mcp_tool_call" && item?.type === "mcpToolCall") return `${item.server} · ${item.tool}`;
|
|
91808
92648
|
if (item?.type === "collabAgentToolCall") {
|
|
91809
92649
|
const title = COLLAB_TOOL_TITLES[item.tool] ?? "Agent tool call";
|
|
92650
|
+
const names = item.receiverThreadIds.flatMap((threadId) => {
|
|
92651
|
+
const name = agentNames?.get(threadId);
|
|
92652
|
+
return name ? [name] : [];
|
|
92653
|
+
});
|
|
92654
|
+
if (names.length > 0) return `${title} · ${names.join(", ")}`;
|
|
91810
92655
|
const model = trimText$1(item.model);
|
|
91811
92656
|
return model ? `${title} · ${model}` : title;
|
|
91812
92657
|
}
|
|
@@ -91958,12 +92803,13 @@ function runtimeEventBase(event, canonicalThreadId) {
|
|
|
91958
92803
|
}
|
|
91959
92804
|
};
|
|
91960
92805
|
}
|
|
91961
|
-
function mapItemLifecycle(event, canonicalThreadId, lifecycle) {
|
|
92806
|
+
function mapItemLifecycle(event, canonicalThreadId, lifecycle, agentNames) {
|
|
91962
92807
|
const item = (readPayload(V2ItemStartedNotification, event.payload) ?? readPayload(V2ItemCompletedNotification, event.payload))?.item;
|
|
91963
92808
|
if (!item) return;
|
|
91964
92809
|
const itemType = toCanonicalItemType(item.type);
|
|
91965
92810
|
if (itemType === "unknown" && lifecycle !== "item.updated") return;
|
|
91966
92811
|
const detail = itemDetail(itemType, item);
|
|
92812
|
+
const title = itemTitle(itemType, item, agentNames);
|
|
91967
92813
|
const status = lifecycle === "item.started" ? "inProgress" : lifecycle === "item.completed" ? "completed" : void 0;
|
|
91968
92814
|
return {
|
|
91969
92815
|
...runtimeEventBase(event, canonicalThreadId),
|
|
@@ -91971,12 +92817,17 @@ function mapItemLifecycle(event, canonicalThreadId, lifecycle) {
|
|
|
91971
92817
|
payload: {
|
|
91972
92818
|
itemType,
|
|
91973
92819
|
...status ? { status } : {},
|
|
91974
|
-
...
|
|
92820
|
+
...title ? { title } : {},
|
|
91975
92821
|
...detail ? { detail } : {},
|
|
91976
92822
|
...event.payload !== void 0 ? { data: event.payload } : {}
|
|
91977
92823
|
}
|
|
91978
92824
|
};
|
|
91979
92825
|
}
|
|
92826
|
+
function rememberAgentName(item, collabDefaults) {
|
|
92827
|
+
if (item.type !== "subAgentActivity" || collabDefaults === void 0) return;
|
|
92828
|
+
const name = agentNameFromPath(item.agentPath);
|
|
92829
|
+
if (name) collabDefaults.agentNames.set(item.agentThreadId, name);
|
|
92830
|
+
}
|
|
91980
92831
|
function mapToRuntimeEvents(event, canonicalThreadId, collabDefaults) {
|
|
91981
92832
|
if (event.kind === "error") {
|
|
91982
92833
|
if (!event.message) return [];
|
|
@@ -92169,8 +93020,9 @@ function mapToRuntimeEvents(event, canonicalThreadId, collabDefaults) {
|
|
|
92169
93020
|
}];
|
|
92170
93021
|
}
|
|
92171
93022
|
if (event.method === "item/started") {
|
|
92172
|
-
const started = mapItemLifecycle(event, canonicalThreadId, "item.started");
|
|
92173
93023
|
const item = readPayload(V2ItemStartedNotification, event.payload)?.item;
|
|
93024
|
+
if (item) rememberAgentName(item, collabDefaults);
|
|
93025
|
+
const started = mapItemLifecycle(event, canonicalThreadId, "item.started", collabDefaults?.agentNames);
|
|
92174
93026
|
const taskEvents = item ? collabTaskEvents(event, canonicalThreadId, item, collabDefaults) : [];
|
|
92175
93027
|
return started ? [started, ...taskEvents] : taskEvents;
|
|
92176
93028
|
}
|
|
@@ -92187,7 +93039,8 @@ function mapToRuntimeEvents(event, canonicalThreadId, collabDefaults) {
|
|
|
92187
93039
|
payload: { planMarkdown: detail }
|
|
92188
93040
|
}];
|
|
92189
93041
|
}
|
|
92190
|
-
|
|
93042
|
+
rememberAgentName(item, collabDefaults);
|
|
93043
|
+
const completed = mapItemLifecycle(event, canonicalThreadId, "item.completed", collabDefaults?.agentNames);
|
|
92191
93044
|
const taskEvents = collabTaskEvents(event, canonicalThreadId, item, collabDefaults);
|
|
92192
93045
|
return completed ? [completed, ...taskEvents] : taskEvents;
|
|
92193
93046
|
}
|
|
@@ -92561,6 +93414,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
92561
93414
|
cause
|
|
92562
93415
|
})));
|
|
92563
93416
|
const collabDefaults = {
|
|
93417
|
+
agentNames: /* @__PURE__ */ new Map(),
|
|
92564
93418
|
model: input.modelSelection?.instanceId === boundInstanceId ? input.modelSelection.model : void 0,
|
|
92565
93419
|
reasoningEffort: input.modelSelection?.instanceId === boundInstanceId ? getModelSelectionStringOptionValue(input.modelSelection, "reasoningEffort") : void 0
|
|
92566
93420
|
};
|
|
@@ -96499,7 +97353,7 @@ const makeTerminationError = (handle) => Effect.match(handle.exitCode, {
|
|
|
96499
97353
|
//#endregion
|
|
96500
97354
|
//#region ../../packages/effect-acp/src/client.ts
|
|
96501
97355
|
var AcpClient = class extends Context.Service()("effect-acp/client/AcpClient") {};
|
|
96502
|
-
const make$
|
|
97356
|
+
const make$8 = Effect.fn("effect-acp/AcpClient.make")(function* (stdio, options = {}, terminationError) {
|
|
96503
97357
|
const coreHandlers = {};
|
|
96504
97358
|
const notificationHandlers = {
|
|
96505
97359
|
sessionUpdate: {
|
|
@@ -96657,7 +97511,7 @@ const make$7 = Effect.fn("effect-acp/AcpClient.make")(function* (stdio, options
|
|
|
96657
97511
|
const layerChildProcess = (handle, options = {}) => {
|
|
96658
97512
|
const stdio = makeChildStdio(handle);
|
|
96659
97513
|
const terminationError = makeTerminationError(handle);
|
|
96660
|
-
return Layer.effect(AcpClient, make$
|
|
97514
|
+
return Layer.effect(AcpClient, make$8(stdio, options, terminationError));
|
|
96661
97515
|
};
|
|
96662
97516
|
//#endregion
|
|
96663
97517
|
//#region ../../packages/shared/src/toolActivity.ts
|
|
@@ -97117,7 +97971,7 @@ function formatConfigOptionValue(value) {
|
|
|
97117
97971
|
const defaultSessionLoadTimeout = Duration.seconds(90);
|
|
97118
97972
|
const defaultSessionLoadReplayIdleGap = Duration.seconds(2);
|
|
97119
97973
|
var AcpSessionRuntime = class extends Context.Service()("@p4code/cli/provider/acp/AcpSessionRuntime") {};
|
|
97120
|
-
const make$
|
|
97974
|
+
const make$7 = (options) => Effect.gen(function* () {
|
|
97121
97975
|
const crypto = yield* Crypto.Crypto;
|
|
97122
97976
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
97123
97977
|
const runtimeScope = yield* Scope.Scope;
|
|
@@ -97433,7 +98287,7 @@ const make$6 = (options) => Effect.gen(function* () {
|
|
|
97433
98287
|
notify: acp.raw.notify
|
|
97434
98288
|
};
|
|
97435
98289
|
});
|
|
97436
|
-
const layer$2 = (options) => Layer.effect(AcpSessionRuntime, make$
|
|
98290
|
+
const layer$2 = (options) => Layer.effect(AcpSessionRuntime, make$7(options));
|
|
97437
98291
|
function sessionConfigOptionsFromSetup(response) {
|
|
97438
98292
|
return response?.configOptions ?? [];
|
|
97439
98293
|
}
|
|
@@ -104754,8 +105608,8 @@ const PreviewSetAppearanceTool = safeBrowserTool(Tool.make("preview_set_appearan
|
|
|
104754
105608
|
dependencies: dependencies$1
|
|
104755
105609
|
}).annotate(Tool.Title, "Set preview appearance").annotate(Tool.Idempotent, true));
|
|
104756
105610
|
const PreviewSnapshotTool = readonlyBrowserTool(Tool.make("preview_snapshot", {
|
|
104757
|
-
description: "Inspect a page before interacting. Pass tabId to inspect a specific tab; omit it to use this agent session's current tab. Returns page state, semantic elements, diagnostics, action history
|
|
104758
|
-
parameters:
|
|
105611
|
+
description: "Inspect a page before interacting. Pass tabId to inspect a specific tab; omit it to use this agent session's current tab. Returns page state, semantic elements, diagnostics, and action history as text. Pass includeScreenshot: true only when you need to see the rendering; the text state is enough for locators and assertions.",
|
|
105612
|
+
parameters: PreviewAutomationSnapshotInput,
|
|
104759
105613
|
success: PreviewAutomationSnapshot,
|
|
104760
105614
|
failure: PreviewAutomationError,
|
|
104761
105615
|
dependencies: dependencies$1
|
|
@@ -104857,7 +105711,7 @@ const handlers$4 = {
|
|
|
104857
105711
|
preview_navigate: (input) => invokeTargeted("navigate", input, input.timeoutMs),
|
|
104858
105712
|
preview_resize: (input) => invokeTargeted("resize", input, input.timeoutMs),
|
|
104859
105713
|
preview_set_appearance: (input) => invokeTargeted("setColorScheme", input),
|
|
104860
|
-
preview_snapshot: (input) => invokeTargeted("snapshot", input
|
|
105714
|
+
preview_snapshot: (input) => invokeTargeted("snapshot", input?.tabId ? { tabId: input.tabId } : {}),
|
|
104861
105715
|
preview_save_screenshot: (input) => invokeTargeted("saveScreenshot", input ?? {}),
|
|
104862
105716
|
preview_click: (input) => invokeTargeted("click", input, input.timeoutMs).pipe(Effect.as(null)),
|
|
104863
105717
|
preview_type: (input) => invokeTargeted("type", input, input.timeoutMs).pipe(Effect.as(null)),
|
|
@@ -104879,7 +105733,7 @@ const stringField = (record, key) => {
|
|
|
104879
105733
|
const value = record[key];
|
|
104880
105734
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
104881
105735
|
};
|
|
104882
|
-
const make$
|
|
105736
|
+
const make$6 = Effect.gen(function* () {
|
|
104883
105737
|
const linear = yield* LinearClient;
|
|
104884
105738
|
return { resolve: Effect.fn("TicketResolver.resolve")(function* (reference) {
|
|
104885
105739
|
const identifier = parseTicketReference(reference);
|
|
@@ -104910,7 +105764,7 @@ const make$5 = Effect.gen(function* () {
|
|
|
104910
105764
|
};
|
|
104911
105765
|
}) };
|
|
104912
105766
|
});
|
|
104913
|
-
const layer$1 = Layer.effect(TicketResolver, make$
|
|
105767
|
+
const layer$1 = Layer.effect(TicketResolver, make$6);
|
|
104914
105768
|
//#endregion
|
|
104915
105769
|
//#region src/mcp/toolkits/tasks/tools.ts
|
|
104916
105770
|
const dependencies = [McpInvocationContext, TaskRepository];
|
|
@@ -106419,6 +107273,7 @@ const registerPreviewSnapshot = Effect.fn("McpHttpServer.registerPreviewSnapshot
|
|
|
106419
107273
|
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({
|
|
106420
107274
|
onFailure: previewSnapshotFailure,
|
|
106421
107275
|
onSuccess: ({ encodedResult }) => {
|
|
107276
|
+
const includeScreenshot = payload?.includeScreenshot === true;
|
|
106422
107277
|
const { screenshot, ...page } = encodedResult;
|
|
106423
107278
|
const metadata = {
|
|
106424
107279
|
...page,
|
|
@@ -106434,11 +107289,11 @@ const registerPreviewSnapshot = Effect.fn("McpHttpServer.registerPreviewSnapshot
|
|
|
106434
107289
|
content: [{
|
|
106435
107290
|
type: "text",
|
|
106436
107291
|
text: JSON.stringify(metadata)
|
|
106437
|
-
}, {
|
|
107292
|
+
}, ...includeScreenshot ? [{
|
|
106438
107293
|
type: "image",
|
|
106439
107294
|
data: new Uint8Array(Buffer.from(screenshot.data, "base64")),
|
|
106440
107295
|
mimeType: screenshot.mimeType
|
|
106441
|
-
}]
|
|
107296
|
+
}] : []]
|
|
106442
107297
|
}));
|
|
106443
107298
|
}
|
|
106444
107299
|
}));
|
|
@@ -106518,6 +107373,18 @@ var ThreadDeletionReactor = class extends Context.Service()("@p4code/cli/orchest
|
|
|
106518
107373
|
//#region src/orchestration/Services/FusionWatcherReactor.ts
|
|
106519
107374
|
var FusionWatcherReactor = class extends Context.Service()("@p4code/cli/orchestration/Services/FusionWatcherReactor") {};
|
|
106520
107375
|
//#endregion
|
|
107376
|
+
//#region src/orchestration/Services/ScheduledTaskReactor.ts
|
|
107377
|
+
/**
|
|
107378
|
+
* ScheduledTaskReactor - fires user-created scheduled tasks.
|
|
107379
|
+
*
|
|
107380
|
+
* Arms one timer per pending task (from the read model at start and from
|
|
107381
|
+
* `thread.scheduled-task.created` events afterwards), starts the thread turn
|
|
107382
|
+
* when the time comes, and records the outcome on the task.
|
|
107383
|
+
*
|
|
107384
|
+
* @module ScheduledTaskReactor
|
|
107385
|
+
*/
|
|
107386
|
+
var ScheduledTaskReactor = class extends Context.Service()("@p4code/cli/orchestration/Services/ScheduledTaskReactor") {};
|
|
107387
|
+
//#endregion
|
|
106521
107388
|
//#region src/orchestration/Layers/OrchestrationReactor.ts
|
|
106522
107389
|
const makeOrchestrationReactor = Effect.gen(function* () {
|
|
106523
107390
|
const providerRuntimeIngestion = yield* ProviderRuntimeIngestionService;
|
|
@@ -106525,12 +107392,14 @@ const makeOrchestrationReactor = Effect.gen(function* () {
|
|
|
106525
107392
|
const checkpointReactor = yield* CheckpointReactor;
|
|
106526
107393
|
const threadDeletionReactor = yield* ThreadDeletionReactor;
|
|
106527
107394
|
const fusionWatcherReactor = yield* FusionWatcherReactor;
|
|
107395
|
+
const scheduledTaskReactor = yield* ScheduledTaskReactor;
|
|
106528
107396
|
return { start: Effect.fn("start")(function* () {
|
|
106529
107397
|
yield* providerRuntimeIngestion.start();
|
|
106530
107398
|
yield* providerCommandReactor.start();
|
|
106531
107399
|
yield* checkpointReactor.start();
|
|
106532
107400
|
yield* threadDeletionReactor.start();
|
|
106533
107401
|
yield* fusionWatcherReactor.start();
|
|
107402
|
+
yield* scheduledTaskReactor.start();
|
|
106534
107403
|
}) };
|
|
106535
107404
|
});
|
|
106536
107405
|
const OrchestrationReactorLive = Layer.effect(OrchestrationReactor, makeOrchestrationReactor);
|
|
@@ -107116,7 +107985,7 @@ function runtimeEventToActivities(event, taskTitle, compressMode) {
|
|
|
107116
107985
|
}
|
|
107117
107986
|
return [];
|
|
107118
107987
|
}
|
|
107119
|
-
const make$
|
|
107988
|
+
const make$5 = Effect.gen(function* () {
|
|
107120
107989
|
const crypto = yield* Crypto.Crypto;
|
|
107121
107990
|
const orchestrationEngine = yield* OrchestrationEngineService;
|
|
107122
107991
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
@@ -107746,7 +108615,7 @@ const make$4 = Effect.gen(function* () {
|
|
|
107746
108615
|
drain: worker.drain
|
|
107747
108616
|
};
|
|
107748
108617
|
});
|
|
107749
|
-
const ProviderRuntimeIngestionLive = Layer.effect(ProviderRuntimeIngestionService, make$
|
|
108618
|
+
const ProviderRuntimeIngestionLive = Layer.effect(ProviderRuntimeIngestionService, make$5).pipe(Layer.provide(ProjectionTurnRepositoryLive), Layer.provide(layer$64));
|
|
107750
108619
|
//#endregion
|
|
107751
108620
|
//#region src/provider/userInvokedSkills.ts
|
|
107752
108621
|
/**
|
|
@@ -107922,8 +108791,8 @@ const DEFAULT_RUNTIME_MODE = "full-access";
|
|
|
107922
108791
|
const DEFAULT_THREAD_TITLE = "New thread";
|
|
107923
108792
|
const NON_SYSTEM_PROVIDER_STRUCTURED_USER_QUESTIONS = structuredUserQuestionPrompt("your provider's structured user-input question tool");
|
|
107924
108793
|
const FUSION_PROMOTION_INSTRUCTIONS = `Work independently in this normal thread. Fusion is a silent escalation path, not a startup procedure. Do not inspect Fusion tools/skill, mention Fusion status, or announce that Fusion was not invoked. First analyze the task normally. Only if that analysis reveals a concrete unresolved tradeoff, correctness risk, or design decision materially needing a second opinion, stop before implementation, propose Fusion, and ask the user for explicit approval. The user may approve with ordinary affirmative text such as "approved"; /fusion or $fusion also authorizes Fusion directly without a prior proposal. Do not activate, spawn, or promote until one of those authorizations arrives. UI work, complex logic, task size, unfamiliarity, or duration alone never qualifies.`;
|
|
107925
|
-
const FUSION_BUILDER_INSTRUCTIONS = `You are Fusion Builder in an already-created native server pair. Server owns pairing and coordination. Do not inspect or invoke the Fusion skill, create/pair/rename threads, or announce/setup Fusion. Start the user's task directly. Before editing, create and maintain the phase list
|
|
107926
|
-
const FUSION_WATCHER_INSTRUCTIONS = `You are Fusion Supervisor (watcher) in an already-created native server pair. Server owns pairing and coordination and wakes you with ${FUSION_REVIEW_PROMPT_PREFIX} or ${FUSION_GATE_PROMPT_PREFIX} prompts at builder turn boundaries; this message arrived outside such a wake, so your conversational memory of the pair may be gone. The pair metadata below is authoritative: the builder thread exists and is the counterpart thread id. Never report that no builder thread exists. To resume supervision, read builder events with thread_watch_events from lastReviewedImplementerSequence with limit 50, paging forward with the last returned sequence rather than requesting a whole range at once, derive phase from artifacts (git log/status, PR, builder events), 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.`;
|
|
108794
|
+
const FUSION_BUILDER_INSTRUCTIONS = `You are Fusion Builder in an already-created native server pair. Server owns pairing and coordination. Do not inspect or invoke the Fusion skill, create/pair/rename threads, or announce/setup Fusion. Start the user's task directly. Before editing, create and maintain the phase list with your provider's step-tracking tool (Claude Code: TaskCreate for each phase, then TaskUpdate for status, or TodoWrite when that is the tool offered; Codex: update_plan), never the MCP task board tools - one entry per phase in order, exactly one in progress at a time, marked completed at each phase end - so phases render in the task banner. That list holds phase entries only for the whole task; keep step-level or per-file todos out of it. Prose alone leaves the banner empty. Split it into the fewest substantial phases the task genuinely needs plus a final integration/whole-task phase; most tasks need one to three work phases. Each phase is a complete reviewable slice of behavior. Never split per file, per function, or per trivial step: over-splitting spends review turns instead of finishing the job. Add a phase only when a real review boundary, risky decision, or independent behavior separates the work. Complete exactly one phase per turn, and finish the whole phase in that turn rather than stopping early. Do not run tests, typecheck, lint, or builds per phase; write the tests the change needs, then run verification once in the final phase over the whole task. Exception: a phase whose own correctness is unclear may run the single narrowest check that resolves it. End every phase turn with phase completed, todo status, changed behavior/files, and remaining phases; do not start the next phase in the same turn. Server then wakes the paired Supervisor, which resumes you through ${FUSION_ADVICE_PROMPT_PREFIX}; a user message may also revise or resume the work. Final phase verifies the entire task against the original request and labels it ready for whole-task review. Supervisor is unreachable during your turn. Never spawn/use another Supervisor thread/subagent or attribute Supervisor decisions without ${FUSION_ADVICE_PROMPT_PREFIX}. Within the current phase, continue when straightforward or evidence is clear. For a concrete unresolved tradeoff, correctness risk, or design decision materially needing judgment, stop safely before the risky choice; final response states the exact question and why review is needed. Evaluate/follow Supervisor advice unless conflicting with user request or verified repo state.`;
|
|
108795
|
+
const FUSION_WATCHER_INSTRUCTIONS = `You are Fusion Supervisor (watcher) in an already-created native server pair. Server owns pairing and coordination and wakes you with ${FUSION_REVIEW_PROMPT_PREFIX} or ${FUSION_GATE_PROMPT_PREFIX} prompts at builder turn boundaries; this message arrived outside such a wake, so your conversational memory of the pair may be gone. The pair metadata below is authoritative: the builder thread exists and is the counterpart thread id. Never report that no builder thread exists. To resume supervision, read builder events with thread_watch_events from lastReviewedImplementerSequence with limit 50, paging forward with the last returned sequence rather than requesting a whole range at once, 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.`;
|
|
107927
108796
|
const isFusionWatcherWakeMessageId = (messageId) => messageId.startsWith("fusion-review:") || messageId.startsWith("fusion-gate:");
|
|
107928
108797
|
const fusionPairContext = (pair, role) => {
|
|
107929
108798
|
const counterpartThreadId = role === "implementer" ? pair.watcherThreadId : pair.implementerThreadId;
|
|
@@ -108011,7 +108880,7 @@ function resolvePendingWorkspaceCleanupGroups(input) {
|
|
|
108011
108880
|
}
|
|
108012
108881
|
return groups;
|
|
108013
108882
|
}
|
|
108014
|
-
const make$
|
|
108883
|
+
const make$4 = Effect.gen(function* () {
|
|
108015
108884
|
const crypto = yield* Crypto.Crypto;
|
|
108016
108885
|
const orchestrationEngine = yield* OrchestrationEngineService;
|
|
108017
108886
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
@@ -108890,7 +109759,7 @@ const make$3 = Effect.gen(function* () {
|
|
|
108890
109759
|
drain: Effect.all([worker.drain, forceStopDrain], { discard: true }).pipe(Effect.asVoid)
|
|
108891
109760
|
};
|
|
108892
109761
|
});
|
|
108893
|
-
const ProviderCommandReactorLive = Layer.effect(ProviderCommandReactor, make$
|
|
109762
|
+
const ProviderCommandReactorLive = Layer.effect(ProviderCommandReactor, make$4);
|
|
108894
109763
|
//#endregion
|
|
108895
109764
|
//#region src/checkpointing/Diffs.ts
|
|
108896
109765
|
function parseTurnDiffFilesFromUnifiedDiff(diff) {
|
|
@@ -108920,7 +109789,7 @@ function checkpointStatusFromRuntime(status) {
|
|
|
108920
109789
|
default: return "ready";
|
|
108921
109790
|
}
|
|
108922
109791
|
}
|
|
108923
|
-
const make$
|
|
109792
|
+
const make$3 = Effect.gen(function* () {
|
|
108924
109793
|
const randomUUID = (yield* Crypto.Crypto).randomUUIDv4;
|
|
108925
109794
|
const serverEventId = randomUUID.pipe(Effect.map(EventId.make));
|
|
108926
109795
|
const serverCommandId = (tag) => randomUUID.pipe(Effect.map((uuid) => CommandId.make(`server:${tag}:${uuid}`)));
|
|
@@ -109402,7 +110271,7 @@ const make$2 = Effect.gen(function* () {
|
|
|
109402
110271
|
drain: worker.drain
|
|
109403
110272
|
};
|
|
109404
110273
|
});
|
|
109405
|
-
const CheckpointReactorLive = Layer.effect(CheckpointReactor, make$
|
|
110274
|
+
const CheckpointReactorLive = Layer.effect(CheckpointReactor, make$3);
|
|
109406
110275
|
//#endregion
|
|
109407
110276
|
//#region src/orchestration/Layers/FusionWatcherReactor.ts
|
|
109408
110277
|
const GATE_TIMEOUT_SWEEP_INTERVAL = "10 seconds";
|
|
@@ -109492,7 +110361,7 @@ Then thread_gate_respond, threadId ${input.implementerThreadId}, gateId ${input.
|
|
|
109492
110361
|
- "object" plus message: send objection, spend round. After ${input.roundCap} objections, escalate to user.
|
|
109493
110362
|
|
|
109494
110363
|
No answer within ${Math.round(input.gateTimeoutMs / 1e3)} seconds: fail open, record unwatched. Answer, briefly explain to user, end turn; never wait for builder.`;
|
|
109495
|
-
const make$
|
|
110364
|
+
const make$2 = Effect.gen(function* () {
|
|
109496
110365
|
const orchestrationEngine = yield* OrchestrationEngineService;
|
|
109497
110366
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
109498
110367
|
/**
|
|
@@ -110092,7 +110961,7 @@ const make$1 = Effect.gen(function* () {
|
|
|
110092
110961
|
sweepGates: sweepGateTimeouts.pipe(Effect.catchCause((cause) => Effect.logWarning("fusion gate timeout sweep failed", { cause: Cause.pretty(cause) })))
|
|
110093
110962
|
};
|
|
110094
110963
|
});
|
|
110095
|
-
const FusionWatcherReactorLive = Layer.effect(FusionWatcherReactor, make$
|
|
110964
|
+
const FusionWatcherReactorLive = Layer.effect(FusionWatcherReactor, make$2);
|
|
110096
110965
|
//#endregion
|
|
110097
110966
|
//#region src/orchestration/Layers/ThreadDeletionReactor.ts
|
|
110098
110967
|
const logCleanupCauseUnlessInterrupted = ({ effect, message, threadId }) => effect.pipe(Effect.catchCause((cause) => {
|
|
@@ -110102,7 +110971,7 @@ const logCleanupCauseUnlessInterrupted = ({ effect, message, threadId }) => effe
|
|
|
110102
110971
|
cause: Cause.pretty(cause)
|
|
110103
110972
|
});
|
|
110104
110973
|
}));
|
|
110105
|
-
const make = Effect.gen(function* () {
|
|
110974
|
+
const make$1 = Effect.gen(function* () {
|
|
110106
110975
|
const orchestrationEngine = yield* OrchestrationEngineService;
|
|
110107
110976
|
const providerService = yield* ProviderService;
|
|
110108
110977
|
const terminalManager = yield* TerminalManager;
|
|
@@ -110143,7 +111012,213 @@ const make = Effect.gen(function* () {
|
|
|
110143
111012
|
drain: worker.drain
|
|
110144
111013
|
};
|
|
110145
111014
|
});
|
|
110146
|
-
const ThreadDeletionReactorLive = Layer.effect(ThreadDeletionReactor, make);
|
|
111015
|
+
const ThreadDeletionReactorLive = Layer.effect(ThreadDeletionReactor, make$1);
|
|
111016
|
+
//#endregion
|
|
111017
|
+
//#region src/orchestration/scheduledTasks.ts
|
|
111018
|
+
/** Milliseconds until a task is due; 0 for anything already overdue. */
|
|
111019
|
+
function scheduledTaskDelayMs(runAt, nowMs) {
|
|
111020
|
+
const runAtMs = Date.parse(runAt);
|
|
111021
|
+
if (Number.isNaN(runAtMs)) return 0;
|
|
111022
|
+
return Math.max(0, runAtMs - nowMs);
|
|
111023
|
+
}
|
|
111024
|
+
function pendingScheduledTasks(threads) {
|
|
111025
|
+
return threads.flatMap((thread) => thread.deletedAt !== null ? [] : (thread.scheduledTasks ?? []).filter((task) => task.status === "pending").map((task) => ({
|
|
111026
|
+
threadId: thread.id,
|
|
111027
|
+
task
|
|
111028
|
+
})));
|
|
111029
|
+
}
|
|
111030
|
+
/**
|
|
111031
|
+
* Task ids are unique per thread only, so every key derived from a task is
|
|
111032
|
+
* scoped by its thread.
|
|
111033
|
+
*/
|
|
111034
|
+
function scheduledTaskKey(threadId, taskId) {
|
|
111035
|
+
return `${threadId}:${taskId}`;
|
|
111036
|
+
}
|
|
111037
|
+
/**
|
|
111038
|
+
* Every turn-start attempt gets its own command id: the engine keeps a
|
|
111039
|
+
* rejected receipt per command id, so reusing one would replay the first
|
|
111040
|
+
* rejection (a busy thread) on every retry. Crash idempotence comes from the
|
|
111041
|
+
* deterministic message id instead: a turn that already sent
|
|
111042
|
+
* {@link scheduledTaskMessageId} is never started again.
|
|
111043
|
+
*/
|
|
111044
|
+
function scheduledTaskTurnCommandId(threadId, taskId, attemptToken) {
|
|
111045
|
+
return CommandId.make(`scheduled-task:${threadId}:${taskId}:turn:${attemptToken}`);
|
|
111046
|
+
}
|
|
111047
|
+
function scheduledTaskFireCommandId(threadId, taskId) {
|
|
111048
|
+
return CommandId.make(`scheduled-task:${threadId}:${taskId}:fire`);
|
|
111049
|
+
}
|
|
111050
|
+
function scheduledTaskMessageId(threadId, taskId) {
|
|
111051
|
+
return MessageId.make(`scheduled-task:${threadId}:${taskId}`);
|
|
111052
|
+
}
|
|
111053
|
+
//#endregion
|
|
111054
|
+
//#region src/orchestration/Layers/ScheduledTaskReactor.ts
|
|
111055
|
+
/**
|
|
111056
|
+
* A turn that cannot start (thread busy, provider down) is retried on this
|
|
111057
|
+
* cadence before the task is marked failed; the count resets with the process,
|
|
111058
|
+
* and the periodic reconcile re-arms anything still pending.
|
|
111059
|
+
*/
|
|
111060
|
+
const SCHEDULED_TASK_TURN_RETRY_DELAY = Duration.minutes(2);
|
|
111061
|
+
/** Re-arms pending tasks that lost their timer (fire failure, missed event). */
|
|
111062
|
+
const SCHEDULED_TASK_RECONCILE_INTERVAL = Duration.minutes(5);
|
|
111063
|
+
/** Engine-level failures while firing (e.g. persistence) back off briefly and retry. */
|
|
111064
|
+
const FIRE_RETRY = {
|
|
111065
|
+
schedule: Schedule.exponential(Duration.seconds(10)),
|
|
111066
|
+
times: 3
|
|
111067
|
+
};
|
|
111068
|
+
const make = Effect.gen(function* () {
|
|
111069
|
+
const orchestrationEngine = yield* OrchestrationEngineService;
|
|
111070
|
+
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
111071
|
+
const threadMessages = yield* ProjectionThreadMessageRepository;
|
|
111072
|
+
const timers = /* @__PURE__ */ new Map();
|
|
111073
|
+
const turnAttempts = /* @__PURE__ */ new Map();
|
|
111074
|
+
const nowIso = Effect.map(DateTime.now, DateTime.formatIso);
|
|
111075
|
+
const disarm = (threadId, taskId) => Effect.gen(function* () {
|
|
111076
|
+
const key = scheduledTaskKey(threadId, taskId);
|
|
111077
|
+
turnAttempts.delete(key);
|
|
111078
|
+
const fiber = timers.get(key);
|
|
111079
|
+
if (fiber === void 0) return;
|
|
111080
|
+
timers.delete(key);
|
|
111081
|
+
yield* Fiber.interrupt(fiber);
|
|
111082
|
+
});
|
|
111083
|
+
const describeFailure = (failure) => failure instanceof Error ? failure.message : String(failure);
|
|
111084
|
+
/**
|
|
111085
|
+
* Starts the turn, then marks the task fired. The turn's user message has a
|
|
111086
|
+
* deterministic id, so a crash between the two steps re-fires on the next
|
|
111087
|
+
* boot without a second turn: an existing message means the turn already
|
|
111088
|
+
* started. Each attempt uses a fresh command id because the engine replays
|
|
111089
|
+
* a rejected receipt for a reused one. A turn that cannot start re-arms the
|
|
111090
|
+
* task for a bounded number of retries and only then records the failure.
|
|
111091
|
+
*/
|
|
111092
|
+
const fire = Effect.fn("ScheduledTaskReactor.fire")(function* (threadId, task) {
|
|
111093
|
+
const key = scheduledTaskKey(threadId, task.id);
|
|
111094
|
+
timers.delete(key);
|
|
111095
|
+
const thread = (yield* projectionSnapshotQuery.getCommandReadModel()).threads.find((entry) => entry.id === threadId);
|
|
111096
|
+
const current = thread?.scheduledTasks?.find((entry) => entry.id === task.id);
|
|
111097
|
+
if (thread === void 0 || thread.deletedAt !== null || current?.status !== "pending") {
|
|
111098
|
+
turnAttempts.delete(key);
|
|
111099
|
+
return;
|
|
111100
|
+
}
|
|
111101
|
+
const messageId = scheduledTaskMessageId(threadId, task.id);
|
|
111102
|
+
const turnResult = Option.isSome(yield* threadMessages.getByMessageId({ messageId })) ? { _tag: "Success" } : yield* orchestrationEngine.dispatch({
|
|
111103
|
+
type: "thread.turn.start",
|
|
111104
|
+
commandId: scheduledTaskTurnCommandId(threadId, task.id, String(yield* Clock.currentTimeMillis)),
|
|
111105
|
+
threadId,
|
|
111106
|
+
message: {
|
|
111107
|
+
messageId,
|
|
111108
|
+
role: "user",
|
|
111109
|
+
text: task.prompt,
|
|
111110
|
+
attachments: []
|
|
111111
|
+
},
|
|
111112
|
+
runtimeMode: thread.runtimeMode,
|
|
111113
|
+
interactionMode: thread.interactionMode,
|
|
111114
|
+
compressMode: thread.compressMode,
|
|
111115
|
+
unpromptedSubagents: thread.unpromptedSubagents,
|
|
111116
|
+
createdAt: yield* nowIso
|
|
111117
|
+
}).pipe(Effect.result);
|
|
111118
|
+
if (turnResult._tag === "Failure") {
|
|
111119
|
+
const attempts = (turnAttempts.get(key) ?? 0) + 1;
|
|
111120
|
+
if (attempts < 10) {
|
|
111121
|
+
turnAttempts.set(key, attempts);
|
|
111122
|
+
yield* Effect.logInfo("scheduled task turn could not start; retrying", {
|
|
111123
|
+
threadId,
|
|
111124
|
+
taskId: task.id,
|
|
111125
|
+
attempt: attempts,
|
|
111126
|
+
failure: describeFailure(turnResult.failure)
|
|
111127
|
+
});
|
|
111128
|
+
yield* armAfter(threadId, task, SCHEDULED_TASK_TURN_RETRY_DELAY);
|
|
111129
|
+
return;
|
|
111130
|
+
}
|
|
111131
|
+
turnAttempts.delete(key);
|
|
111132
|
+
yield* orchestrationEngine.dispatch({
|
|
111133
|
+
type: "thread.scheduled-task.fire",
|
|
111134
|
+
commandId: scheduledTaskFireCommandId(threadId, task.id),
|
|
111135
|
+
threadId,
|
|
111136
|
+
taskId: task.id,
|
|
111137
|
+
firedAt: yield* nowIso,
|
|
111138
|
+
failure: `Could not start the turn after ${attempts} attempts: ${describeFailure(turnResult.failure)}`
|
|
111139
|
+
});
|
|
111140
|
+
return;
|
|
111141
|
+
}
|
|
111142
|
+
turnAttempts.delete(key);
|
|
111143
|
+
yield* orchestrationEngine.dispatch({
|
|
111144
|
+
type: "thread.scheduled-task.fire",
|
|
111145
|
+
commandId: scheduledTaskFireCommandId(threadId, task.id),
|
|
111146
|
+
threadId,
|
|
111147
|
+
taskId: task.id,
|
|
111148
|
+
firedAt: yield* nowIso
|
|
111149
|
+
});
|
|
111150
|
+
});
|
|
111151
|
+
const armAfter = (threadId, task, delay) => Effect.gen(function* () {
|
|
111152
|
+
const key = scheduledTaskKey(threadId, task.id);
|
|
111153
|
+
const existing = timers.get(key);
|
|
111154
|
+
if (existing !== void 0) {
|
|
111155
|
+
timers.delete(key);
|
|
111156
|
+
yield* Fiber.interrupt(existing);
|
|
111157
|
+
}
|
|
111158
|
+
const fiber = yield* Effect.forkDetach(Effect.sleep(delay).pipe(Effect.flatMap(() => fire(threadId, task).pipe(Effect.retry(FIRE_RETRY))), Effect.catchCause((cause) => Cause.hasInterruptsOnly(cause) ? Effect.void : Effect.logWarning("scheduled task failed to fire; it stays pending until reconcile re-arms it", {
|
|
111159
|
+
threadId,
|
|
111160
|
+
taskId: task.id,
|
|
111161
|
+
cause: Cause.pretty(cause)
|
|
111162
|
+
}))));
|
|
111163
|
+
timers.set(key, fiber);
|
|
111164
|
+
});
|
|
111165
|
+
const arm = (threadId, task) => Effect.gen(function* () {
|
|
111166
|
+
const delayMs = scheduledTaskDelayMs(task.runAt, yield* Clock.currentTimeMillis);
|
|
111167
|
+
yield* armAfter(threadId, task, Duration.millis(delayMs));
|
|
111168
|
+
});
|
|
111169
|
+
/** Arms every pending task that has no live timer; the read model is authoritative. */
|
|
111170
|
+
const reconcile = Effect.fn("ScheduledTaskReactor.reconcile")(function* () {
|
|
111171
|
+
const readModel = yield* projectionSnapshotQuery.getCommandReadModel();
|
|
111172
|
+
for (const pending of pendingScheduledTasks(readModel.threads)) {
|
|
111173
|
+
if (timers.has(scheduledTaskKey(pending.threadId, pending.task.id))) continue;
|
|
111174
|
+
yield* arm(pending.threadId, pending.task);
|
|
111175
|
+
}
|
|
111176
|
+
});
|
|
111177
|
+
const processEvent = Effect.fn("ScheduledTaskReactor.processEvent")(function* (event) {
|
|
111178
|
+
switch (event.type) {
|
|
111179
|
+
case "thread.scheduled-task.created":
|
|
111180
|
+
yield* arm(event.payload.threadId, event.payload.task);
|
|
111181
|
+
return;
|
|
111182
|
+
case "thread.scheduled-task.cancelled":
|
|
111183
|
+
case "thread.scheduled-task.fired":
|
|
111184
|
+
yield* disarm(event.payload.threadId, event.payload.taskId);
|
|
111185
|
+
return;
|
|
111186
|
+
case "thread.deleted":
|
|
111187
|
+
for (const key of Array.from(timers.keys())) {
|
|
111188
|
+
if (!key.startsWith(`${event.payload.threadId}:`)) continue;
|
|
111189
|
+
const fiber = timers.get(key);
|
|
111190
|
+
timers.delete(key);
|
|
111191
|
+
turnAttempts.delete(key);
|
|
111192
|
+
if (fiber !== void 0) yield* Fiber.interrupt(fiber);
|
|
111193
|
+
}
|
|
111194
|
+
return;
|
|
111195
|
+
}
|
|
111196
|
+
});
|
|
111197
|
+
const processEventSafely = (event) => processEvent(event).pipe(Effect.catchCause((cause) => Cause.hasInterruptsOnly(cause) ? Effect.failCause(cause) : Effect.logWarning("scheduled task reactor failed to process event", {
|
|
111198
|
+
eventType: event.type,
|
|
111199
|
+
cause: Cause.pretty(cause)
|
|
111200
|
+
})));
|
|
111201
|
+
const worker = yield* makeDrainableWorker(processEventSafely);
|
|
111202
|
+
const logReconcileFailure = (cause) => Effect.logWarning("scheduled task reconcile failed", { cause: Cause.pretty(cause) });
|
|
111203
|
+
return {
|
|
111204
|
+
start: Effect.fn("start")(function* () {
|
|
111205
|
+
yield* Effect.forkScoped(Stream.runForEach(orchestrationEngine.streamDomainEvents, (event) => {
|
|
111206
|
+
switch (event.type) {
|
|
111207
|
+
case "thread.scheduled-task.created":
|
|
111208
|
+
case "thread.scheduled-task.cancelled":
|
|
111209
|
+
case "thread.scheduled-task.fired":
|
|
111210
|
+
case "thread.deleted": return worker.enqueue(event);
|
|
111211
|
+
default: return Effect.void;
|
|
111212
|
+
}
|
|
111213
|
+
}));
|
|
111214
|
+
yield* reconcile().pipe(Effect.catchCause(logReconcileFailure));
|
|
111215
|
+
yield* Effect.forkScoped(Effect.repeat(reconcile().pipe(Effect.catchCause(logReconcileFailure)), Schedule.spaced(SCHEDULED_TASK_RECONCILE_INTERVAL)).pipe(Effect.delay(SCHEDULED_TASK_RECONCILE_INTERVAL)));
|
|
111216
|
+
yield* Effect.addFinalizer(() => Effect.forEach([...timers.values()], (fiber) => Fiber.interrupt(fiber), { discard: true }).pipe(Effect.tap(() => Effect.sync(() => timers.clear()))));
|
|
111217
|
+
}),
|
|
111218
|
+
drain: worker.drain
|
|
111219
|
+
};
|
|
111220
|
+
});
|
|
111221
|
+
const ScheduledTaskReactorLive = Layer.effect(ScheduledTaskReactor, make);
|
|
110147
111222
|
//#endregion
|
|
110148
111223
|
//#region src/provider/providerStatusCache.ts
|
|
110149
111224
|
const decodeProviderStatusCache = Schema$1.decodeUnknownEffect(Schema$1.fromJsonString(ServerProvider));
|
|
@@ -110924,7 +111999,7 @@ const PlatformServicesLive = Layer.unwrap(Effect.gen(function* () {
|
|
|
110924
111999
|
return layer;
|
|
110925
112000
|
}
|
|
110926
112001
|
}));
|
|
110927
|
-
const ReactorLayerLive = Layer.empty.pipe(Layer.provideMerge(OrchestrationReactorLive), Layer.provideMerge(ProviderRuntimeIngestionLive), Layer.provideMerge(ProviderCommandReactorLive), Layer.provideMerge(CheckpointReactorLive), Layer.provideMerge(ThreadDeletionReactorLive), Layer.provideMerge(FusionWatcherReactorLive), Layer.provideMerge(RuntimeReceiptBusLive));
|
|
112002
|
+
const ReactorLayerLive = Layer.empty.pipe(Layer.provideMerge(OrchestrationReactorLive), Layer.provideMerge(ProviderRuntimeIngestionLive), Layer.provideMerge(ProviderCommandReactorLive), Layer.provideMerge(CheckpointReactorLive), Layer.provideMerge(ThreadDeletionReactorLive), Layer.provideMerge(FusionWatcherReactorLive), Layer.provideMerge(ScheduledTaskReactorLive), Layer.provideMerge(RuntimeReceiptBusLive));
|
|
110928
112003
|
const ProviderSessionDirectoryLayerLive = ProviderSessionDirectoryLive.pipe(Layer.provide(layer$4));
|
|
110929
112004
|
const ProviderLayerLive = ProviderServiceLive.pipe(Layer.provide(ProviderAdapterRegistryLive), Layer.provideMerge(ProviderSessionDirectoryLayerLive));
|
|
110930
112005
|
const PersistenceLayerLive = Layer.empty.pipe(Layer.provideMerge(layerConfig));
|