@p4code/cli 0.4.8 → 0.4.10
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 +1501 -431
- package/dist/client/assets/DiffPanel-BHGE1G78.js +98 -0
- package/dist/client/assets/{FilePreviewPanel-D983k8TL.js → FilePreviewPanel-Zmw32RkV.js} +12 -12
- package/dist/client/assets/PreviewPanel-RAU_RNvx.js +2 -0
- package/dist/client/assets/PullRequestCodeTab-BbZ7CFZM.js +251 -0
- package/dist/client/assets/{fileCommentAnnotations-YpkRb3SO.js → fileCommentAnnotations-CiKVoVhn.js} +2 -2
- package/dist/client/assets/{index-BCNkRAfG.css → index-CGz5G9YO.css} +1 -1
- package/dist/client/assets/index-DmzzsHSI.js +2770 -0
- package/dist/client/assets/previewAssetResource-DoQeyCSk.js +48 -0
- package/dist/client/assets/{renderFileChildren-DVDSpmWa.js → renderFileChildren-DI1Y1X_Z.js} +2 -2
- package/dist/client/assets/toggle-group-DR0IEjgX.js +2 -0
- package/dist/client/index.html +3 -3
- package/package.json +1 -1
- package/dist/client/assets/DiffPanel-CzluPWKw.js +0 -98
- package/dist/client/assets/PreviewPanel-B4wOy86U.js +0 -2
- package/dist/client/assets/PullRequestCodeTab-CzCmGudy.js +0 -251
- package/dist/client/assets/index-Cru6mBsL.js +0 -2752
- package/dist/client/assets/previewAssetResource-B1FtgzM2.js +0 -48
- package/dist/client/assets/toggle-group-Di8iU1Yz.js +0 -2
package/dist/bin.mjs
CHANGED
|
@@ -52,6 +52,7 @@ import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
|
52
52
|
import * as SqlSchema from "effect/unstable/sql/SqlSchema";
|
|
53
53
|
import * as PlatformError from "effect/PlatformError";
|
|
54
54
|
import * as Migrator from "effect/unstable/sql/Migrator";
|
|
55
|
+
import * as NodeUtil from "node:util";
|
|
55
56
|
import * as Cause from "effect/Cause";
|
|
56
57
|
import * as Exit from "effect/Exit";
|
|
57
58
|
import * as NodeReadline from "node:readline";
|
|
@@ -127,7 +128,7 @@ const closeServer = (server) => {
|
|
|
127
128
|
* NetService - Service tag for startup networking helpers.
|
|
128
129
|
*/
|
|
129
130
|
var NetService = class extends Context.Service()("@p4code/shared/Net/NetService") {};
|
|
130
|
-
const make$
|
|
131
|
+
const make$93 = () => {
|
|
131
132
|
/**
|
|
132
133
|
* Returns true when a TCP server can bind to {host, port}.
|
|
133
134
|
* `EADDRNOTAVAIL` is treated as available so IPv6-absent hosts don't fail
|
|
@@ -236,10 +237,10 @@ const make$92 = () => {
|
|
|
236
237
|
})
|
|
237
238
|
};
|
|
238
239
|
};
|
|
239
|
-
const layer$82 = Layer.sync(NetService, make$
|
|
240
|
+
const layer$82 = Layer.sync(NetService, make$93);
|
|
240
241
|
//#endregion
|
|
241
242
|
//#region package.json
|
|
242
|
-
var version = "0.4.
|
|
243
|
+
var version = "0.4.10";
|
|
243
244
|
//#endregion
|
|
244
245
|
//#region src/config.ts
|
|
245
246
|
/**
|
|
@@ -260,8 +261,8 @@ var ServerConfig$1 = class extends Context.Service()("@p4code/cli/config/ServerC
|
|
|
260
261
|
/** @deprecated Import and use `layerTest` from this module. */
|
|
261
262
|
static layerTest = (cwd, baseDirOrPrefix) => layerTest$3(cwd, baseDirOrPrefix);
|
|
262
263
|
};
|
|
263
|
-
const make$
|
|
264
|
-
const layer$81 = (config) => Layer.succeed(ServerConfig$1, make$
|
|
264
|
+
const make$92 = (config) => ServerConfig$1.of(config);
|
|
265
|
+
const layer$81 = (config) => Layer.succeed(ServerConfig$1, make$92(config));
|
|
265
266
|
const deriveServerPaths = Effect.fn(function* (baseDir, devUrl, options = {}) {
|
|
266
267
|
const { join } = yield* Path.Path;
|
|
267
268
|
const stateDir = join(baseDir, devUrl !== void 0 && !options.baseDirIsExplicit ? "dev" : "userdata");
|
|
@@ -1321,6 +1322,7 @@ const ServerSelfUpdateCapability = Schema$1.Literals([
|
|
|
1321
1322
|
"desktop-managed"
|
|
1322
1323
|
]);
|
|
1323
1324
|
const ExecutionEnvironmentCapabilities = Schema$1.Struct({
|
|
1325
|
+
threadLifecycleV2: Schema$1.optionalKey(Schema$1.Boolean),
|
|
1324
1326
|
repositoryIdentity: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(false))),
|
|
1325
1327
|
connectionProbe: Schema$1.optionalKey(Schema$1.Boolean),
|
|
1326
1328
|
/** Server understands thread.settle / thread.unsettle commands. Absent on
|
|
@@ -2001,7 +2003,31 @@ const ThreadWorkspaceLifecycle = Schema$1.Struct({
|
|
|
2001
2003
|
mergeCommitSha: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2002
2004
|
updatedAt: IsoDateTime
|
|
2003
2005
|
});
|
|
2006
|
+
const ThreadLifecycle = Schema$1.Literals([
|
|
2007
|
+
"active",
|
|
2008
|
+
"done",
|
|
2009
|
+
"archived"
|
|
2010
|
+
]);
|
|
2011
|
+
const ThreadLifecycleReason = Schema$1.Literals([
|
|
2012
|
+
"created",
|
|
2013
|
+
"manual",
|
|
2014
|
+
"inactivity",
|
|
2015
|
+
"pull-request",
|
|
2016
|
+
"user",
|
|
2017
|
+
"activity",
|
|
2018
|
+
"archive",
|
|
2019
|
+
"restore"
|
|
2020
|
+
]);
|
|
2021
|
+
/** Optional during mixed-version support; v2 servers populate every field. */
|
|
2022
|
+
const ThreadCompletionFields = {
|
|
2023
|
+
lifecycle: Schema$1.optional(ThreadLifecycle),
|
|
2024
|
+
lifecycleChangedAt: Schema$1.optional(IsoDateTime),
|
|
2025
|
+
lifecycleReason: Schema$1.optional(ThreadLifecycleReason),
|
|
2026
|
+
doneAt: Schema$1.optional(Schema$1.NullOr(IsoDateTime)),
|
|
2027
|
+
lastEngagedAt: Schema$1.optional(IsoDateTime)
|
|
2028
|
+
};
|
|
2004
2029
|
const OrchestrationThread = Schema$1.Struct({
|
|
2030
|
+
...ThreadCompletionFields,
|
|
2005
2031
|
id: ThreadId,
|
|
2006
2032
|
projectId: ProjectId,
|
|
2007
2033
|
title: TrimmedNonEmptyString,
|
|
@@ -2105,6 +2131,7 @@ const OrchestrationProjectShell = Schema$1.Struct({
|
|
|
2105
2131
|
updatedAt: IsoDateTime
|
|
2106
2132
|
});
|
|
2107
2133
|
const OrchestrationThreadShell = Schema$1.Struct({
|
|
2134
|
+
...ThreadCompletionFields,
|
|
2108
2135
|
id: ThreadId,
|
|
2109
2136
|
projectId: ProjectId,
|
|
2110
2137
|
title: TrimmedNonEmptyString,
|
|
@@ -2362,6 +2389,25 @@ const ThreadUnsettleCommand = Schema$1.Struct({
|
|
|
2362
2389
|
threadId: ThreadId,
|
|
2363
2390
|
reason: Schema$1.Literal("user")
|
|
2364
2391
|
});
|
|
2392
|
+
const ThreadCompleteCommand = Schema$1.Struct({
|
|
2393
|
+
type: Schema$1.Literal("thread.complete"),
|
|
2394
|
+
commandId: CommandId,
|
|
2395
|
+
threadId: ThreadId
|
|
2396
|
+
});
|
|
2397
|
+
const ThreadReopenCommand = Schema$1.Struct({
|
|
2398
|
+
type: Schema$1.Literal("thread.reopen"),
|
|
2399
|
+
commandId: CommandId,
|
|
2400
|
+
threadId: ThreadId
|
|
2401
|
+
});
|
|
2402
|
+
/** Server effects propose completion against the engagement state they inspected. */
|
|
2403
|
+
const ThreadAutoCompleteCommand = Schema$1.Struct({
|
|
2404
|
+
type: Schema$1.Literal("thread.complete.auto"),
|
|
2405
|
+
commandId: CommandId,
|
|
2406
|
+
threadId: ThreadId,
|
|
2407
|
+
reason: Schema$1.Literals(["inactivity", "pull-request"]),
|
|
2408
|
+
expectedLastEngagedAt: IsoDateTime,
|
|
2409
|
+
eligibleAt: IsoDateTime
|
|
2410
|
+
});
|
|
2365
2411
|
const ThreadSnoozeCommand = Schema$1.Struct({
|
|
2366
2412
|
type: Schema$1.Literal("thread.snooze"),
|
|
2367
2413
|
commandId: CommandId,
|
|
@@ -2590,6 +2636,8 @@ const DispatchableClientOrchestrationCommand = Schema$1.Union([
|
|
|
2590
2636
|
ThreadArchiveCommand,
|
|
2591
2637
|
ThreadUnarchiveCommand,
|
|
2592
2638
|
ThreadSettleCommand,
|
|
2639
|
+
ThreadCompleteCommand,
|
|
2640
|
+
ThreadReopenCommand,
|
|
2593
2641
|
ThreadUnsettleCommand,
|
|
2594
2642
|
ThreadSnoozeCommand,
|
|
2595
2643
|
ThreadUnsnoozeCommand,
|
|
@@ -2624,6 +2672,8 @@ const ClientOrchestrationCommand = Schema$1.Union([
|
|
|
2624
2672
|
ThreadArchiveCommand,
|
|
2625
2673
|
ThreadUnarchiveCommand,
|
|
2626
2674
|
ThreadSettleCommand,
|
|
2675
|
+
ThreadCompleteCommand,
|
|
2676
|
+
ThreadReopenCommand,
|
|
2627
2677
|
ThreadUnsettleCommand,
|
|
2628
2678
|
ThreadSnoozeCommand,
|
|
2629
2679
|
ThreadUnsnoozeCommand,
|
|
@@ -2763,6 +2813,7 @@ const ThreadRevertCompleteCommand = Schema$1.Struct({
|
|
|
2763
2813
|
createdAt: IsoDateTime
|
|
2764
2814
|
});
|
|
2765
2815
|
const InternalOrchestrationCommand = Schema$1.Union([
|
|
2816
|
+
ThreadAutoCompleteCommand,
|
|
2766
2817
|
ThreadSessionSetCommand,
|
|
2767
2818
|
ThreadSessionForceStopConvergeCommand,
|
|
2768
2819
|
ThreadTurnCompleteCommand,
|
|
@@ -2856,6 +2907,7 @@ const ProjectDeletedPayload$1 = Schema$1.Struct({
|
|
|
2856
2907
|
deletedAt: IsoDateTime
|
|
2857
2908
|
});
|
|
2858
2909
|
const ThreadCreatedPayload$1 = Schema$1.Struct({
|
|
2910
|
+
...ThreadCompletionFields,
|
|
2859
2911
|
threadId: ThreadId,
|
|
2860
2912
|
projectId: ProjectId,
|
|
2861
2913
|
title: TrimmedNonEmptyString,
|
|
@@ -2879,20 +2931,24 @@ const ThreadDeletedPayload$1 = Schema$1.Struct({
|
|
|
2879
2931
|
deletedAt: IsoDateTime
|
|
2880
2932
|
});
|
|
2881
2933
|
const ThreadArchivedPayload$1 = Schema$1.Struct({
|
|
2934
|
+
...ThreadCompletionFields,
|
|
2882
2935
|
threadId: ThreadId,
|
|
2883
2936
|
archivedAt: IsoDateTime,
|
|
2884
2937
|
updatedAt: IsoDateTime
|
|
2885
2938
|
});
|
|
2886
2939
|
const ThreadUnarchivedPayload$1 = Schema$1.Struct({
|
|
2940
|
+
...ThreadCompletionFields,
|
|
2887
2941
|
threadId: ThreadId,
|
|
2888
2942
|
updatedAt: IsoDateTime
|
|
2889
2943
|
});
|
|
2890
2944
|
const ThreadSettledPayload$1 = Schema$1.Struct({
|
|
2945
|
+
...ThreadCompletionFields,
|
|
2891
2946
|
threadId: ThreadId,
|
|
2892
2947
|
settledAt: IsoDateTime,
|
|
2893
2948
|
updatedAt: IsoDateTime
|
|
2894
2949
|
});
|
|
2895
2950
|
const ThreadUnsettledPayload$1 = Schema$1.Struct({
|
|
2951
|
+
...ThreadCompletionFields,
|
|
2896
2952
|
threadId: ThreadId,
|
|
2897
2953
|
reason: Schema$1.Literals(["user", "activity"]),
|
|
2898
2954
|
updatedAt: IsoDateTime
|
|
@@ -3696,6 +3752,7 @@ Schema$1.Struct({
|
|
|
3696
3752
|
headRefName: TrimmedNonEmptyString,
|
|
3697
3753
|
state: ChangeRequestState,
|
|
3698
3754
|
updatedAt: Schema$1.Option(Schema$1.DateTimeUtc),
|
|
3755
|
+
terminalAt: Schema$1.optional(Schema$1.NullOr(IsoDateTime)),
|
|
3699
3756
|
isCrossRepository: Schema$1.optional(Schema$1.Boolean),
|
|
3700
3757
|
headRepositoryNameWithOwner: Schema$1.optional(Schema$1.NullOr(TrimmedNonEmptyString)),
|
|
3701
3758
|
headRepositoryOwnerLogin: Schema$1.optional(Schema$1.NullOr(TrimmedNonEmptyString))
|
|
@@ -7637,6 +7694,7 @@ const STATIC_KEYBINDING_COMMANDS = [
|
|
|
7637
7694
|
"preview.zoomOut",
|
|
7638
7695
|
"preview.resetZoom",
|
|
7639
7696
|
"commandPalette.toggle",
|
|
7697
|
+
"workspace.searchContents",
|
|
7640
7698
|
"composer.stash",
|
|
7641
7699
|
"chat.new",
|
|
7642
7700
|
"chat.newLocal",
|
|
@@ -8482,6 +8540,7 @@ const SourceControlWritingStyleSettings = Schema$1.Struct({
|
|
|
8482
8540
|
});
|
|
8483
8541
|
const DEFAULT_AUTOMATIC_GIT_FETCH_INTERVAL = Duration.seconds(30);
|
|
8484
8542
|
const ServerSettings = Schema$1.Struct({
|
|
8543
|
+
threadAutoCompleteAfterDays: Schema$1.NullOr(SidebarAutoSettleAfterDays).pipe(Schema$1.withDecodingDefault(Effect.succeed(3))),
|
|
8485
8544
|
enableAssistantStreaming: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(false))),
|
|
8486
8545
|
enableProviderUpdateChecks: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(true))),
|
|
8487
8546
|
/**
|
|
@@ -8699,6 +8758,7 @@ const OpenCodeSettingsPatch = Schema$1.Struct({
|
|
|
8699
8758
|
customModels: Schema$1.optionalKey(Schema$1.Array(Schema$1.String))
|
|
8700
8759
|
});
|
|
8701
8760
|
const ServerSettingsPatch = Schema$1.Struct({
|
|
8761
|
+
threadAutoCompleteAfterDays: Schema$1.optionalKey(Schema$1.NullOr(SidebarAutoSettleAfterDays)),
|
|
8702
8762
|
enableAssistantStreaming: Schema$1.optionalKey(Schema$1.Boolean),
|
|
8703
8763
|
enableProviderUpdateChecks: Schema$1.optionalKey(Schema$1.Boolean),
|
|
8704
8764
|
enableToolCallNarration: Schema$1.optionalKey(Schema$1.Boolean),
|
|
@@ -9611,6 +9671,23 @@ const ProjectSearchEntriesResult = Schema$1.Struct({
|
|
|
9611
9671
|
entries: Schema$1.Array(ProjectEntry),
|
|
9612
9672
|
truncated: Schema$1.Boolean
|
|
9613
9673
|
});
|
|
9674
|
+
const ProjectSearchContentsInput = Schema$1.Struct({
|
|
9675
|
+
cwd: TrimmedNonEmptyString,
|
|
9676
|
+
query: Schema$1.String.check(Schema$1.isNonEmpty(), Schema$1.isMaxLength(256)),
|
|
9677
|
+
limit: PositiveInt.check(Schema$1.isLessThanOrEqualTo(500))
|
|
9678
|
+
});
|
|
9679
|
+
const ProjectSearchContentsResult = Schema$1.Struct({
|
|
9680
|
+
matches: Schema$1.Array(Schema$1.Struct({
|
|
9681
|
+
path: TrimmedNonEmptyString,
|
|
9682
|
+
lineNumber: PositiveInt,
|
|
9683
|
+
lineContent: Schema$1.String,
|
|
9684
|
+
matchRanges: Schema$1.Array(Schema$1.Struct({
|
|
9685
|
+
start: NonNegativeInt,
|
|
9686
|
+
end: NonNegativeInt
|
|
9687
|
+
}))
|
|
9688
|
+
})),
|
|
9689
|
+
truncated: Schema$1.Boolean
|
|
9690
|
+
});
|
|
9614
9691
|
const ProjectListEntriesInput = Schema$1.Struct({ cwd: TrimmedNonEmptyString });
|
|
9615
9692
|
const ProjectListEntriesResult = Schema$1.Struct({
|
|
9616
9693
|
entries: Schema$1.Array(ProjectEntry),
|
|
@@ -10052,13 +10129,16 @@ const ThreadSpawnInput = Schema$1.Struct({
|
|
|
10052
10129
|
interactionMode: Schema$1.optional(ProviderInteractionMode),
|
|
10053
10130
|
compressMode: Schema$1.optional(CompressMode),
|
|
10054
10131
|
unpromptedSubagents: Schema$1.optional(Schema$1.Boolean),
|
|
10055
|
-
|
|
10132
|
+
fusion: Schema$1.optional(Schema$1.Boolean.annotate({ description: "Create two new threads as a separate Fusion pair, then start the builder with prompt. Leaves the caller and its existing pair unchanged. Cannot be combined with fusionWatcher." })),
|
|
10133
|
+
fusionWatcher: Schema$1.optional(Schema$1.Boolean.annotate({ description: "Set true only when creating the watcher to pair with the current thread. Defaults to the saved Fusion supervisor model. No special user command syntax is required." }))
|
|
10056
10134
|
});
|
|
10057
10135
|
const ThreadSpawnResult = Schema$1.Struct({
|
|
10058
10136
|
/** Watchable with `thread_watch_events`, and addressable by every tool here. */
|
|
10059
10137
|
threadId: ThreadId,
|
|
10060
10138
|
projectId: ProjectId,
|
|
10061
|
-
title: TrimmedNonEmptyString
|
|
10139
|
+
title: TrimmedNonEmptyString,
|
|
10140
|
+
pairId: Schema$1.optional(ThreadPairId),
|
|
10141
|
+
watcherThreadId: Schema$1.optional(ThreadId)
|
|
10062
10142
|
});
|
|
10063
10143
|
const ThreadPairCreateInput = Schema$1.Struct({
|
|
10064
10144
|
watcherThreadId: ThreadId.annotate({ description: "The supervisor thread to pair with this session's own builder thread. It must have been created by this session through thread_spawn." }),
|
|
@@ -10230,12 +10310,6 @@ var ThreadSpawnNotPermittedError = class extends Schema$1.TaggedErrorClass()("Th
|
|
|
10230
10310
|
return `Thread ${this.threadId} cannot start another thread: ${this.detail}`;
|
|
10231
10311
|
}
|
|
10232
10312
|
};
|
|
10233
|
-
/** Fusion watcher and pair creation require fresh user authorization from this exact thread. */
|
|
10234
|
-
var ThreadPairApprovalRequiredError = class extends Schema$1.TaggedErrorClass()("ThreadPairApprovalRequiredError", { threadId: ThreadId }) {
|
|
10235
|
-
get message() {
|
|
10236
|
-
return `Thread ${this.threadId} cannot create a Fusion watcher or pair without explicit user approval. The latest user message must invoke /fusion or $fusion on its own line, or affirm the immediately preceding assistant proposal that names Fusion and asks for approval.`;
|
|
10237
|
-
}
|
|
10238
|
-
};
|
|
10239
10313
|
/** The orchestration engine declined or failed a thread control command. */
|
|
10240
10314
|
var ThreadControlRejectedError = class extends Schema$1.TaggedErrorClass()("ThreadControlRejectedError", {
|
|
10241
10315
|
threadId: ThreadId,
|
|
@@ -10250,7 +10324,6 @@ const ThreadControlToolError = Schema$1.Union([
|
|
|
10250
10324
|
ThreadToolUnavailableError,
|
|
10251
10325
|
ThreadControlNotPermittedError,
|
|
10252
10326
|
ThreadSpawnNotPermittedError,
|
|
10253
|
-
ThreadPairApprovalRequiredError,
|
|
10254
10327
|
ThreadControlRejectedError,
|
|
10255
10328
|
ThreadRenameRejectedError,
|
|
10256
10329
|
MemoryAppendFailedError,
|
|
@@ -10274,6 +10347,45 @@ const ThreadWatchEventsResult = Schema$1.Struct({
|
|
|
10274
10347
|
/** True when more events for this thread exist past the returned page. */
|
|
10275
10348
|
hasMore: Schema$1.Boolean
|
|
10276
10349
|
});
|
|
10350
|
+
/** Compact review limits are server-owned, independent of raw event paging. */
|
|
10351
|
+
const THREAD_REVIEW_SCAN_LIMIT = 2e3;
|
|
10352
|
+
const THREAD_REVIEW_ITEM_MAX_BYTES = 8e3;
|
|
10353
|
+
const ThreadWatchReviewInput = Schema$1.Struct({
|
|
10354
|
+
threadId: ThreadId,
|
|
10355
|
+
afterSequence: Schema$1.optional(NonNegativeInt),
|
|
10356
|
+
throughSequence: Schema$1.optional(NonNegativeInt.annotate({ description: "Inclusive fixed review boundary. Omit on the first page to capture the head; reuse the returned boundary on every subsequent page." }))
|
|
10357
|
+
});
|
|
10358
|
+
const ReviewSourceFields = {
|
|
10359
|
+
firstSequence: NonNegativeInt,
|
|
10360
|
+
lastSequence: NonNegativeInt,
|
|
10361
|
+
truncated: Schema$1.Boolean
|
|
10362
|
+
};
|
|
10363
|
+
const ThreadReviewItem = Schema$1.Union([Schema$1.Struct({
|
|
10364
|
+
...ReviewSourceFields,
|
|
10365
|
+
kind: Schema$1.Literal("message"),
|
|
10366
|
+
messageId: Schema$1.String,
|
|
10367
|
+
turnId: Schema$1.NullOr(Schema$1.String),
|
|
10368
|
+
role: Schema$1.String,
|
|
10369
|
+
/** Apply append/replace by message identity across page boundaries. */
|
|
10370
|
+
operation: Schema$1.Literals(["append", "replace"]),
|
|
10371
|
+
complete: Schema$1.Boolean,
|
|
10372
|
+
text: Schema$1.String
|
|
10373
|
+
}), Schema$1.Struct({
|
|
10374
|
+
...ReviewSourceFields,
|
|
10375
|
+
kind: Schema$1.Literal("event"),
|
|
10376
|
+
type: Schema$1.String,
|
|
10377
|
+
/** JSON evidence excerpt. Truncated excerpts require targeted raw recovery. */
|
|
10378
|
+
payload: Schema$1.String
|
|
10379
|
+
})]);
|
|
10380
|
+
const ThreadWatchReviewResult = Schema$1.Struct({
|
|
10381
|
+
threadId: ThreadId,
|
|
10382
|
+
items: Schema$1.Array(ThreadReviewItem),
|
|
10383
|
+
throughSequence: NonNegativeInt,
|
|
10384
|
+
/** Resume from the source scan cursor, even when items is empty. */
|
|
10385
|
+
nextAfterSequence: NonNegativeInt,
|
|
10386
|
+
hasMore: Schema$1.Boolean,
|
|
10387
|
+
scannedEvents: NonNegativeInt
|
|
10388
|
+
});
|
|
10277
10389
|
var WatchToolUnavailableError = class extends Schema$1.TaggedErrorClass()("WatchToolUnavailableError", {
|
|
10278
10390
|
capability: Schema$1.Literal("watch"),
|
|
10279
10391
|
environmentId: EnvironmentId,
|
|
@@ -11539,6 +11651,7 @@ const WS_METHODS = {
|
|
|
11539
11651
|
projectsRemove: "projects.remove",
|
|
11540
11652
|
projectsListEntries: "projects.listEntries",
|
|
11541
11653
|
projectsReadFile: "projects.readFile",
|
|
11654
|
+
projectsSearchContents: "projects.searchContents",
|
|
11542
11655
|
projectsSearchEntries: "projects.searchEntries",
|
|
11543
11656
|
projectsWriteFile: "projects.writeFile",
|
|
11544
11657
|
shellOpenInEditor: "shell.openInEditor",
|
|
@@ -12249,6 +12362,11 @@ const WsSourceControlPublishRepositoryRpc = Rpc.make(WS_METHODS.sourceControlPub
|
|
|
12249
12362
|
success: SourceControlPublishRepositoryResult,
|
|
12250
12363
|
error: Schema$1.Union([SourceControlRepositoryError, EnvironmentAuthorizationError])
|
|
12251
12364
|
});
|
|
12365
|
+
const WsProjectsSearchContentsRpc = Rpc.make(WS_METHODS.projectsSearchContents, {
|
|
12366
|
+
payload: ProjectSearchContentsInput,
|
|
12367
|
+
success: ProjectSearchContentsResult,
|
|
12368
|
+
error: Schema$1.Union([ProjectSearchEntriesError, EnvironmentAuthorizationError])
|
|
12369
|
+
});
|
|
12252
12370
|
const WsProjectsSearchEntriesRpc = Rpc.make(WS_METHODS.projectsSearchEntries, {
|
|
12253
12371
|
payload: ProjectSearchEntriesInput,
|
|
12254
12372
|
success: ProjectSearchEntriesResult,
|
|
@@ -12514,7 +12632,7 @@ const WsSubscribeAuthAccessRpc = Rpc.make(WS_METHODS.subscribeAuthAccess, {
|
|
|
12514
12632
|
error: Schema$1.Union([AuthAccessStreamError, EnvironmentAuthorizationError]),
|
|
12515
12633
|
stream: true
|
|
12516
12634
|
});
|
|
12517
|
-
const WsRpcGroup = RpcGroup.make(WsServerProbeRpc, WsServerGetConfigRpc, WsServerRefreshProvidersRpc, WsServerUpdateProviderRpc, WsServerUpdateServerRpc, WsServerUpsertKeybindingRpc, WsServerRemoveKeybindingRpc, WsServerGetSettingsRpc, WsServerUpdateSettingsRpc, WsServerDiscoverSourceControlRpc, WsServerGetProviderUsageRpc, WsBtwAskRpc, WsBtwCancelRpc, WsServerGetUsageSummaryRpc, WsServerGetTraceDiagnosticsRpc, WsServerGetProcessDiagnosticsRpc, WsServerGetProcessResourceHistoryRpc, WsServerSignalProcessRpc, WsPullRequestsListRpc, WsPullRequestsListStatsRpc, WsPullRequestsDetailRpc, WsPullRequestsActivityRpc, WsPullRequestsDiffFileContentsRpc, WsPullRequestsRunActionRpc, WsPullRequestsUpdateRpc, WsPullRequestsCommentRpc, WsPullRequestsUpdateCommentRpc, WsPullRequestsSubmitReviewRpc, WsPullRequestsReplyToThreadRpc, WsPullRequestsSetThreadResolutionRpc, WsPullRequestsSetReactionRpc, WsPullRequestsInvalidateRpc, WsPullRequestsReviewerCandidatesRpc, WsPullRequestsRequestReviewersRpc, WsSourceControlLookupRepositoryRpc, WsSourceControlCloneRepositoryRpc, WsSourceControlPublishRepositoryRpc, WsProjectsListEntriesRpc, WsProjectsReadFileRpc, WsProjectsSearchEntriesRpc, WsProjectsWriteFileRpc, WsShellOpenInEditorRpc, WsFilesystemBrowseRpc, WsAssetsCreateUrlRpc, WsSubscribeVcsStatusRpc, WsVcsPullRpc, WsVcsRefreshStatusRpc, WsGitRunStackedActionRpc, WsGitResolvePullRequestRpc, WsGitPreparePullRequestThreadRpc, WsVcsListRefsRpc, WsVcsCreateWorktreeRpc, WsVcsRemoveWorktreeRpc, WsVcsCreateRefRpc, WsVcsSwitchRefRpc, WsVcsInitRpc, WsReviewGetDiffPreviewRpc, WsTerminalOpenRpc, WsTerminalAttachRpc, WsTerminalWriteRpc, WsTerminalResizeRpc, WsTerminalClearRpc, WsTerminalRestartRpc, WsTerminalCloseRpc, WsSubscribeTerminalEventsRpc, WsSubscribeTerminalMetadataRpc, WsPreviewOpenRpc, WsPreviewNavigateRpc, WsPreviewResizeRpc, WsPreviewRefreshRpc, WsPreviewCloseRpc, WsPreviewListRpc, WsPreviewReportStatusRpc, WsPreviewAutomationConnectRpc, WsPreviewAutomationRespondRpc, WsPreviewAutomationFocusHostRpc, WsSubscribePreviewEventsRpc, WsSubscribeDiscoveredLocalServersRpc, WsSubscribeServerConfigRpc, WsSubscribeServerLifecycleRpc, WsSubscribeAuthAccessRpc, WsTasksListRpc, WsTasksGetRpc, WsTasksCreateRpc, WsTasksUpdateRpc, WsTasksDeleteRpc, WsTasksStartThreadRpc, WsFeedListRpc, WsFeedRefreshRpc, WsFeedSourcesListRpc, WsFeedSourcesUpsertRpc, WsFeedSourcesDeleteRpc, WsFeedMarkReadRpc, WsFeedCleanupRpc, WsSubscribeTasksRpc, WsHubGetSyncStatusRpc, WsHubConnectRpc, WsHubDisconnectRpc, WsHubSetSyncModeRpc, WsHubSetShareModeRpc, WsHubMintTokenRpc, WsSkillsSyncRpc, WsSkillsPublishRpc, WsSkillsPublishAllRpc, WsSkillsUnpublishRpc, WsAssetsReadRpc, WsAssetsSaveRpc, WsAssetsDeleteRpc, WsAssetsCreateLocalRpc, WsAssetsRemoveLocalRpc, WsSkillRegistrySearchRpc, WsSkillRegistryFetchRpc, WsMcpListRpc, WsMcpSaveRpc, WsMcpRemoveRpc, WsMcpSetSecretRpc, WsMcpOAuthBeginRpc, WsMcpOAuthDisconnectRpc, WsTrackerStatusRpc, WsTrackerSetApiKeyRpc, WsTrackerClearApiKeyRpc, WsOrchestrationDispatchCommandRpc, WsOrchestrationGetTurnDiffRpc, WsOrchestrationGetFullThreadDiffRpc, WsOrchestrationSearchThreadsRpc, WsOrchestrationGetArchivedShellSnapshotRpc, WsOrchestrationSubscribeShellRpc, WsOrchestrationSubscribeThreadRpc);
|
|
12635
|
+
const WsRpcGroup = RpcGroup.make(WsServerProbeRpc, WsServerGetConfigRpc, WsServerRefreshProvidersRpc, WsServerUpdateProviderRpc, WsServerUpdateServerRpc, WsServerUpsertKeybindingRpc, WsServerRemoveKeybindingRpc, WsServerGetSettingsRpc, WsServerUpdateSettingsRpc, WsServerDiscoverSourceControlRpc, WsServerGetProviderUsageRpc, WsBtwAskRpc, WsBtwCancelRpc, WsServerGetUsageSummaryRpc, WsServerGetTraceDiagnosticsRpc, WsServerGetProcessDiagnosticsRpc, WsServerGetProcessResourceHistoryRpc, WsServerSignalProcessRpc, WsPullRequestsListRpc, WsPullRequestsListStatsRpc, WsPullRequestsDetailRpc, WsPullRequestsActivityRpc, WsPullRequestsDiffFileContentsRpc, WsPullRequestsRunActionRpc, WsPullRequestsUpdateRpc, WsPullRequestsCommentRpc, WsPullRequestsUpdateCommentRpc, WsPullRequestsSubmitReviewRpc, WsPullRequestsReplyToThreadRpc, WsPullRequestsSetThreadResolutionRpc, WsPullRequestsSetReactionRpc, WsPullRequestsInvalidateRpc, WsPullRequestsReviewerCandidatesRpc, WsPullRequestsRequestReviewersRpc, WsSourceControlLookupRepositoryRpc, WsSourceControlCloneRepositoryRpc, WsSourceControlPublishRepositoryRpc, WsProjectsListEntriesRpc, WsProjectsReadFileRpc, WsProjectsSearchContentsRpc, WsProjectsSearchEntriesRpc, WsProjectsWriteFileRpc, WsShellOpenInEditorRpc, WsFilesystemBrowseRpc, WsAssetsCreateUrlRpc, WsSubscribeVcsStatusRpc, WsVcsPullRpc, WsVcsRefreshStatusRpc, WsGitRunStackedActionRpc, WsGitResolvePullRequestRpc, WsGitPreparePullRequestThreadRpc, WsVcsListRefsRpc, WsVcsCreateWorktreeRpc, WsVcsRemoveWorktreeRpc, WsVcsCreateRefRpc, WsVcsSwitchRefRpc, WsVcsInitRpc, WsReviewGetDiffPreviewRpc, WsTerminalOpenRpc, WsTerminalAttachRpc, WsTerminalWriteRpc, WsTerminalResizeRpc, WsTerminalClearRpc, WsTerminalRestartRpc, WsTerminalCloseRpc, WsSubscribeTerminalEventsRpc, WsSubscribeTerminalMetadataRpc, WsPreviewOpenRpc, WsPreviewNavigateRpc, WsPreviewResizeRpc, WsPreviewRefreshRpc, WsPreviewCloseRpc, WsPreviewListRpc, WsPreviewReportStatusRpc, WsPreviewAutomationConnectRpc, WsPreviewAutomationRespondRpc, WsPreviewAutomationFocusHostRpc, WsSubscribePreviewEventsRpc, WsSubscribeDiscoveredLocalServersRpc, WsSubscribeServerConfigRpc, WsSubscribeServerLifecycleRpc, WsSubscribeAuthAccessRpc, WsTasksListRpc, WsTasksGetRpc, WsTasksCreateRpc, WsTasksUpdateRpc, WsTasksDeleteRpc, WsTasksStartThreadRpc, WsFeedListRpc, WsFeedRefreshRpc, WsFeedSourcesListRpc, WsFeedSourcesUpsertRpc, WsFeedSourcesDeleteRpc, WsFeedMarkReadRpc, WsFeedCleanupRpc, WsSubscribeTasksRpc, WsHubGetSyncStatusRpc, WsHubConnectRpc, WsHubDisconnectRpc, WsHubSetSyncModeRpc, WsHubSetShareModeRpc, WsHubMintTokenRpc, WsSkillsSyncRpc, WsSkillsPublishRpc, WsSkillsPublishAllRpc, WsSkillsUnpublishRpc, WsAssetsReadRpc, WsAssetsSaveRpc, WsAssetsDeleteRpc, WsAssetsCreateLocalRpc, WsAssetsRemoveLocalRpc, WsSkillRegistrySearchRpc, WsSkillRegistryFetchRpc, WsMcpListRpc, WsMcpSaveRpc, WsMcpRemoveRpc, WsMcpSetSecretRpc, WsMcpOAuthBeginRpc, WsMcpOAuthDisconnectRpc, WsTrackerStatusRpc, WsTrackerSetApiKeyRpc, WsTrackerClearApiKeyRpc, WsOrchestrationDispatchCommandRpc, WsOrchestrationGetTurnDiffRpc, WsOrchestrationGetFullThreadDiffRpc, WsOrchestrationSearchThreadsRpc, WsOrchestrationGetArchivedShellSnapshotRpc, WsOrchestrationSubscribeShellRpc, WsOrchestrationSubscribeThreadRpc);
|
|
12518
12636
|
//#endregion
|
|
12519
12637
|
//#region ../../packages/shared/src/oauthScope.ts
|
|
12520
12638
|
const OAUTH_SCOPE_TOKEN = /^[\u0021\u0023-\u005b\u005d-\u007e]+$/u;
|
|
@@ -12660,7 +12778,7 @@ function deriveAuthClientMetadata(input) {
|
|
|
12660
12778
|
//#endregion
|
|
12661
12779
|
//#region src/auth/EnvironmentAuthPolicy.ts
|
|
12662
12780
|
var EnvironmentAuthPolicy = class extends Context.Service()("@p4code/cli/auth/EnvironmentAuthPolicy") {};
|
|
12663
|
-
const make$
|
|
12781
|
+
const make$91 = Effect.gen(function* () {
|
|
12664
12782
|
const config = yield* ServerConfig$1;
|
|
12665
12783
|
const isRemoteReachable = isRemoteReachableHost(config.host);
|
|
12666
12784
|
const policy = config.mode === "desktop" ? isRemoteReachable ? "remote-reachable" : "desktop-managed-local" : isRemoteReachable ? "remote-reachable" : "loopback-browser";
|
|
@@ -12678,7 +12796,7 @@ const make$90 = Effect.gen(function* () {
|
|
|
12678
12796
|
};
|
|
12679
12797
|
return EnvironmentAuthPolicy.of({ getDescriptor: () => Effect.succeed(descriptor).pipe(Effect.withSpan("EnvironmentAuthPolicy.getDescriptor")) });
|
|
12680
12798
|
});
|
|
12681
|
-
const layer$80 = Layer.effect(EnvironmentAuthPolicy, make$
|
|
12799
|
+
const layer$80 = Layer.effect(EnvironmentAuthPolicy, make$91);
|
|
12682
12800
|
//#endregion
|
|
12683
12801
|
//#region src/persistence/Errors.ts
|
|
12684
12802
|
function summarizeSchemaIssue(issue) {
|
|
@@ -12859,7 +12977,7 @@ function toPersistenceSqlOrDecodeError$6(sqlOperation, decodeOperation, correlat
|
|
|
12859
12977
|
cause
|
|
12860
12978
|
});
|
|
12861
12979
|
}
|
|
12862
|
-
const make$
|
|
12980
|
+
const make$90 = Effect.gen(function* () {
|
|
12863
12981
|
const sql = yield* SqlClient.SqlClient;
|
|
12864
12982
|
const createSessionRow = SqlSchema.void({
|
|
12865
12983
|
Request: CreateAuthSessionInput,
|
|
@@ -12993,7 +13111,7 @@ const make$89 = Effect.gen(function* () {
|
|
|
12993
13111
|
setLastConnectedAt
|
|
12994
13112
|
};
|
|
12995
13113
|
});
|
|
12996
|
-
const layer$79 = Layer.effect(AuthSessionRepository, make$
|
|
13114
|
+
const layer$79 = Layer.effect(AuthSessionRepository, make$90);
|
|
12997
13115
|
//#endregion
|
|
12998
13116
|
//#region src/auth/ServerSecretStore.ts
|
|
12999
13117
|
const secretStoreErrorContext = {
|
|
@@ -13060,7 +13178,7 @@ const isSecretStoreError = Schema$1.is(SecretStoreError);
|
|
|
13060
13178
|
const isPlatformError = (value) => Predicate.isTagged(value, "PlatformError");
|
|
13061
13179
|
const isSecretAlreadyExistsError = (error) => "cause" in error && isPlatformError(error.cause) && error.cause.reason._tag === "AlreadyExists";
|
|
13062
13180
|
var ServerSecretStore = class extends Context.Service()("@p4code/cli/auth/ServerSecretStore") {};
|
|
13063
|
-
const make$
|
|
13181
|
+
const make$89 = Effect.gen(function* () {
|
|
13064
13182
|
const crypto = yield* Crypto.Crypto;
|
|
13065
13183
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
13066
13184
|
const path = yield* Path.Path;
|
|
@@ -13136,7 +13254,7 @@ const make$88 = Effect.gen(function* () {
|
|
|
13136
13254
|
remove
|
|
13137
13255
|
});
|
|
13138
13256
|
});
|
|
13139
|
-
const layer$78 = Layer.effect(ServerSecretStore, make$
|
|
13257
|
+
const layer$78 = Layer.effect(ServerSecretStore, make$89);
|
|
13140
13258
|
//#endregion
|
|
13141
13259
|
//#region src/auth/SessionStore.ts
|
|
13142
13260
|
var MalformedSessionTokenError = class extends Schema$1.TaggedErrorClass()("MalformedSessionTokenError", {}) {
|
|
@@ -13374,7 +13492,7 @@ function toAuthClientSession(input) {
|
|
|
13374
13492
|
current: false
|
|
13375
13493
|
};
|
|
13376
13494
|
}
|
|
13377
|
-
const make$
|
|
13495
|
+
const make$88 = Effect.gen(function* () {
|
|
13378
13496
|
const crypto = yield* Crypto.Crypto;
|
|
13379
13497
|
const serverConfig = yield* ServerConfig$1;
|
|
13380
13498
|
const secretStore = yield* ServerSecretStore;
|
|
@@ -13688,7 +13806,7 @@ const make$87 = Effect.gen(function* () {
|
|
|
13688
13806
|
markDisconnected
|
|
13689
13807
|
});
|
|
13690
13808
|
});
|
|
13691
|
-
const layer$77 = Layer.effect(SessionStore, make$
|
|
13809
|
+
const layer$77 = Layer.effect(SessionStore, make$88).pipe(Layer.provideMerge(layer$79));
|
|
13692
13810
|
//#endregion
|
|
13693
13811
|
//#region src/persistence/AuthPairingLinks.ts
|
|
13694
13812
|
const AuthPairingLinkRecord = Schema$1.Struct({
|
|
@@ -13749,7 +13867,7 @@ function toPersistenceSqlOrDecodeError$5(sqlOperation, decodeOperation, correlat
|
|
|
13749
13867
|
cause
|
|
13750
13868
|
});
|
|
13751
13869
|
}
|
|
13752
|
-
const make$
|
|
13870
|
+
const make$87 = Effect.gen(function* () {
|
|
13753
13871
|
const sql = yield* SqlClient.SqlClient;
|
|
13754
13872
|
const createPairingLinkRow = SqlSchema.void({
|
|
13755
13873
|
Request: CreateAuthPairingLinkInput,
|
|
@@ -13884,7 +14002,7 @@ const make$86 = Effect.gen(function* () {
|
|
|
13884
14002
|
getByCredential
|
|
13885
14003
|
};
|
|
13886
14004
|
});
|
|
13887
|
-
const layer$76 = Layer.effect(AuthPairingLinkRepository, make$
|
|
14005
|
+
const layer$76 = Layer.effect(AuthPairingLinkRepository, make$87);
|
|
13888
14006
|
//#endregion
|
|
13889
14007
|
//#region src/auth/PairingGrantStore.ts
|
|
13890
14008
|
var UnknownBootstrapCredentialError = class extends Schema$1.TaggedErrorClass()("UnknownBootstrapCredentialError", {}) {
|
|
@@ -13979,7 +14097,7 @@ const DEV_STARTUP_TTL_HOURS = Duration.hours(24);
|
|
|
13979
14097
|
const PAIRING_TOKEN_ALPHABET = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
|
|
13980
14098
|
const PAIRING_TOKEN_LENGTH = 12;
|
|
13981
14099
|
const PAIRING_TOKEN_REJECTION_LIMIT = Math.floor(256 / 32) * 32;
|
|
13982
|
-
const make$
|
|
14100
|
+
const make$86 = Effect.gen(function* () {
|
|
13983
14101
|
const crypto = yield* Crypto.Crypto;
|
|
13984
14102
|
const config = yield* ServerConfig$1;
|
|
13985
14103
|
const pairingLinks = yield* AuthPairingLinkRepository;
|
|
@@ -14177,7 +14295,7 @@ const make$85 = Effect.gen(function* () {
|
|
|
14177
14295
|
consume
|
|
14178
14296
|
});
|
|
14179
14297
|
});
|
|
14180
|
-
const layer$75 = Layer.effect(PairingGrantStore, make$
|
|
14298
|
+
const layer$75 = Layer.effect(PairingGrantStore, make$86).pipe(Layer.provideMerge(layer$76));
|
|
14181
14299
|
//#endregion
|
|
14182
14300
|
//#region src/persistence/DatabaseSnapshot.ts
|
|
14183
14301
|
/**
|
|
@@ -16123,6 +16241,31 @@ var _054_ProjectionThreadScheduledTasks_default = Effect.gen(function* () {
|
|
|
16123
16241
|
`;
|
|
16124
16242
|
});
|
|
16125
16243
|
//#endregion
|
|
16244
|
+
//#region src/persistence/Migrations/055_ThreadCompletionLifecycle.ts
|
|
16245
|
+
var _055_ThreadCompletionLifecycle_default = Effect.gen(function* () {
|
|
16246
|
+
const sql = yield* SqlClient.SqlClient;
|
|
16247
|
+
yield* sql`ALTER TABLE projection_threads ADD COLUMN lifecycle TEXT NOT NULL DEFAULT 'active'`;
|
|
16248
|
+
yield* sql`ALTER TABLE projection_threads ADD COLUMN lifecycle_reason TEXT NOT NULL DEFAULT 'created'`;
|
|
16249
|
+
yield* sql`ALTER TABLE projection_threads ADD COLUMN lifecycle_changed_at TEXT`;
|
|
16250
|
+
yield* sql`ALTER TABLE projection_threads ADD COLUMN last_engaged_at TEXT`;
|
|
16251
|
+
yield* sql`
|
|
16252
|
+
UPDATE projection_threads SET
|
|
16253
|
+
lifecycle = CASE WHEN archived_at IS NOT NULL THEN 'archived'
|
|
16254
|
+
WHEN settled_override = 'settled' THEN 'done' ELSE 'active' END,
|
|
16255
|
+
lifecycle_reason = CASE WHEN archived_at IS NOT NULL THEN 'archive'
|
|
16256
|
+
WHEN settled_override = 'settled' THEN 'manual' ELSE 'created' END,
|
|
16257
|
+
lifecycle_changed_at = COALESCE(archived_at, settled_at, created_at),
|
|
16258
|
+
last_engaged_at = MAX(created_at, COALESCE(latest_user_message_at, created_at),
|
|
16259
|
+
COALESCE((SELECT MAX(message.updated_at) FROM projection_thread_messages message
|
|
16260
|
+
WHERE message.thread_id = projection_threads.thread_id AND message.role IN ('user', 'assistant')), created_at)),
|
|
16261
|
+
settled_override = CASE WHEN settled_override = 'settled' THEN 'settled' ELSE 'active' END
|
|
16262
|
+
`;
|
|
16263
|
+
yield* sql`CREATE INDEX idx_projection_threads_lifecycle_sweep
|
|
16264
|
+
ON projection_threads(lifecycle, deleted_at, thread_id)`;
|
|
16265
|
+
yield* sql`CREATE INDEX idx_projection_threads_lifecycle_inactivity
|
|
16266
|
+
ON projection_threads(lifecycle, deleted_at, last_engaged_at, thread_id)`;
|
|
16267
|
+
});
|
|
16268
|
+
//#endregion
|
|
16126
16269
|
//#region src/persistence/Migrations.ts
|
|
16127
16270
|
/**
|
|
16128
16271
|
* MigrationsLive - Migration runner with inline loader
|
|
@@ -16413,6 +16556,11 @@ const migrationEntries = [
|
|
|
16413
16556
|
54,
|
|
16414
16557
|
"ProjectionThreadScheduledTasks",
|
|
16415
16558
|
_054_ProjectionThreadScheduledTasks_default
|
|
16559
|
+
],
|
|
16560
|
+
[
|
|
16561
|
+
55,
|
|
16562
|
+
"ThreadCompletionLifecycle",
|
|
16563
|
+
_055_ThreadCompletionLifecycle_default
|
|
16416
16564
|
]
|
|
16417
16565
|
];
|
|
16418
16566
|
const makeMigrationLoader = (throughId) => Migrator.fromRecord(Object.fromEntries(migrationEntries.filter(([id]) => throughId === void 0 || id <= throughId).map(([id, name, migration]) => [`${id}_${name}`, migration])));
|
|
@@ -17008,12 +17156,42 @@ function dropStaleContextWindowActivities(activities) {
|
|
|
17008
17156
|
return [index === breakdownIndex ? activity : withoutContextWindowBreakdown$1(activity)];
|
|
17009
17157
|
});
|
|
17010
17158
|
}
|
|
17159
|
+
function toolLifecycleIdentity(activity) {
|
|
17160
|
+
return asTrimmedString$2(asRecord$6(asRecord$6(activity.payload)?.data)?.toolCallId);
|
|
17161
|
+
}
|
|
17162
|
+
/** Clients retain fields missing from a completion when folding an update. */
|
|
17163
|
+
function completionPreservesUpdate(update, completion) {
|
|
17164
|
+
const updatePayload = asRecord$6(update.payload);
|
|
17165
|
+
const completionPayload = asRecord$6(completion.payload);
|
|
17166
|
+
if (!updatePayload || !completionPayload) return false;
|
|
17167
|
+
return Object.entries(updatePayload).every(([key, value]) => key === "status" || NodeUtil.isDeepStrictEqual(value, completionPayload[key]));
|
|
17168
|
+
}
|
|
17169
|
+
/** Remove only updates superseded by a later completion in the same turn. */
|
|
17170
|
+
function dropSupersededToolUpdatedActivities(activities) {
|
|
17171
|
+
const lastCompletionIndexByKey = /* @__PURE__ */ new Map();
|
|
17172
|
+
for (let index = 0; index < activities.length; index += 1) {
|
|
17173
|
+
const activity = activities[index];
|
|
17174
|
+
if (activity.kind !== "tool.completed") continue;
|
|
17175
|
+
const identity = toolLifecycleIdentity(activity);
|
|
17176
|
+
if (!identity) continue;
|
|
17177
|
+
const key = `${activity.turnId ?? ""}\u0000${identity}`;
|
|
17178
|
+
lastCompletionIndexByKey.set(key, index);
|
|
17179
|
+
}
|
|
17180
|
+
if (lastCompletionIndexByKey.size === 0) return activities;
|
|
17181
|
+
return activities.filter((activity, index) => {
|
|
17182
|
+
if (activity.kind !== "tool.updated") return true;
|
|
17183
|
+
const identity = toolLifecycleIdentity(activity);
|
|
17184
|
+
if (!identity) return true;
|
|
17185
|
+
const completionIndex = lastCompletionIndexByKey.get(`${activity.turnId ?? ""}\u0000${identity}`);
|
|
17186
|
+
return completionIndex === void 0 || completionIndex <= index || !completionPreservesUpdate(activity, activities[completionIndex]);
|
|
17187
|
+
});
|
|
17188
|
+
}
|
|
17011
17189
|
function projectThreadDetailSnapshot(snapshot) {
|
|
17012
17190
|
return {
|
|
17013
17191
|
...snapshot,
|
|
17014
17192
|
thread: {
|
|
17015
17193
|
...snapshot.thread,
|
|
17016
|
-
activities: dropStaleContextWindowActivities(snapshot.thread.activities).map(projectActivityPayload)
|
|
17194
|
+
activities: dropSupersededToolUpdatedActivities(dropStaleContextWindowActivities(snapshot.thread.activities).map(projectActivityPayload))
|
|
17017
17195
|
}
|
|
17018
17196
|
};
|
|
17019
17197
|
}
|
|
@@ -17411,7 +17589,7 @@ function parseBearerToken(request) {
|
|
|
17411
17589
|
const token = header.slice(7).trim();
|
|
17412
17590
|
return token.length > 0 ? token : null;
|
|
17413
17591
|
}
|
|
17414
|
-
const make$
|
|
17592
|
+
const make$85 = Effect.gen(function* () {
|
|
17415
17593
|
const policy = yield* EnvironmentAuthPolicy;
|
|
17416
17594
|
const bootstrapCredentials = yield* PairingGrantStore;
|
|
17417
17595
|
const sessions = yield* SessionStore;
|
|
@@ -17606,7 +17784,7 @@ const make$84 = Effect.gen(function* () {
|
|
|
17606
17784
|
issueStartupPairingUrl
|
|
17607
17785
|
});
|
|
17608
17786
|
});
|
|
17609
|
-
const layer$74 = Layer.effect(EnvironmentAuth, make$
|
|
17787
|
+
const layer$74 = Layer.effect(EnvironmentAuth, make$85).pipe(Layer.provideMerge(layer$75), Layer.provideMerge(layer$77), Layer.provideMerge(layer$80));
|
|
17610
17788
|
const storageLayer = Layer.mergeAll(layer$78, layerConfig);
|
|
17611
17789
|
const runtimeLayer = layer$74.pipe(Layer.provideMerge(storageLayer));
|
|
17612
17790
|
//#endregion
|
|
@@ -19444,7 +19622,7 @@ const DEFAULT_LIMITS = {
|
|
|
19444
19622
|
windowMillis: FAILURE_WINDOW_MS,
|
|
19445
19623
|
blockMillis: BLOCK_DURATION_MS
|
|
19446
19624
|
};
|
|
19447
|
-
const make$
|
|
19625
|
+
const make$84 = Effect.fn("HubAuthThrottle.make")(function* (limits = DEFAULT_LIMITS) {
|
|
19448
19626
|
const state = yield* Ref.make(initialThrottleState);
|
|
19449
19627
|
return HubAuthThrottle.of({
|
|
19450
19628
|
shouldRefuse: Effect.gen(function* () {
|
|
@@ -19458,7 +19636,7 @@ const make$83 = Effect.fn("HubAuthThrottle.make")(function* (limits = DEFAULT_LI
|
|
|
19458
19636
|
})
|
|
19459
19637
|
});
|
|
19460
19638
|
});
|
|
19461
|
-
const layer$73 = Layer.effect(HubAuthThrottle, make$
|
|
19639
|
+
const layer$73 = Layer.effect(HubAuthThrottle, make$84());
|
|
19462
19640
|
//#endregion
|
|
19463
19641
|
//#region src/hub/HubAuth.ts
|
|
19464
19642
|
/**
|
|
@@ -21178,7 +21356,7 @@ function stripDefaultServerSettings(current, defaults) {
|
|
|
21178
21356
|
}
|
|
21179
21357
|
return Object.is(current, defaults) ? void 0 : current;
|
|
21180
21358
|
}
|
|
21181
|
-
const make$
|
|
21359
|
+
const make$83 = Effect.gen(function* () {
|
|
21182
21360
|
const { settingsPath } = yield* ServerConfig$1;
|
|
21183
21361
|
const fs = yield* FileSystem.FileSystem;
|
|
21184
21362
|
const pathService = yield* Path.Path;
|
|
@@ -21399,7 +21577,7 @@ const make$82 = Effect.gen(function* () {
|
|
|
21399
21577
|
}
|
|
21400
21578
|
};
|
|
21401
21579
|
});
|
|
21402
|
-
const layer$71 = Layer.effect(ServerSettingsService, make$
|
|
21580
|
+
const layer$71 = Layer.effect(ServerSettingsService, make$83);
|
|
21403
21581
|
//#endregion
|
|
21404
21582
|
//#region src/pathExpansion.ts
|
|
21405
21583
|
/**
|
|
@@ -21776,7 +21954,7 @@ function claudeEntryFromRegistration(registration) {
|
|
|
21776
21954
|
};
|
|
21777
21955
|
}
|
|
21778
21956
|
var ClaudeMcpFiles = class extends Context.Service()("@p4code/cli/mcp/ClaudeMcpFiles") {};
|
|
21779
|
-
const make$
|
|
21957
|
+
const make$82 = Effect.gen(function* () {
|
|
21780
21958
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
21781
21959
|
const path = yield* Path.Path;
|
|
21782
21960
|
const services = yield* Effect.context();
|
|
@@ -21843,7 +22021,7 @@ const make$81 = Effect.gen(function* () {
|
|
|
21843
22021
|
removeProject: (projectDir, name) => removeAt(Effect.succeed(projectFile(projectDir)))(name)
|
|
21844
22022
|
};
|
|
21845
22023
|
});
|
|
21846
|
-
const layer$70 = Layer.effect(ClaudeMcpFiles, make$
|
|
22024
|
+
const layer$70 = Layer.effect(ClaudeMcpFiles, make$82);
|
|
21847
22025
|
Layer.succeed(ClaudeMcpFiles, {
|
|
21848
22026
|
readUser: Effect.succeed([]),
|
|
21849
22027
|
readUserAt: () => Effect.succeed([]),
|
|
@@ -21981,7 +22159,7 @@ const decodeClientRegistration = Schema$1.decodeUnknownExit(ClientRegistrationRe
|
|
|
21981
22159
|
const decodeTokenResponse = Schema$1.decodeUnknownExit(TokenResponse);
|
|
21982
22160
|
var McpOAuth = class extends Context.Service()("@p4code/cli/mcp/McpOAuth") {};
|
|
21983
22161
|
const registryError = (detail) => new McpRegistryError({ detail });
|
|
21984
|
-
const make$
|
|
22162
|
+
const make$81 = Effect.gen(function* () {
|
|
21985
22163
|
const config = yield* ServerConfig$1;
|
|
21986
22164
|
const secrets = yield* ServerSecretStore;
|
|
21987
22165
|
const http = yield* HttpClient.HttpClient;
|
|
@@ -22301,7 +22479,7 @@ const make$80 = Effect.gen(function* () {
|
|
|
22301
22479
|
accessTokenFor
|
|
22302
22480
|
};
|
|
22303
22481
|
});
|
|
22304
|
-
const layer$69 = Layer.effect(McpOAuth, make$
|
|
22482
|
+
const layer$69 = Layer.effect(McpOAuth, make$81);
|
|
22305
22483
|
Layer.succeed(McpOAuth, {
|
|
22306
22484
|
statusFor: () => Effect.succeed(Option.none()),
|
|
22307
22485
|
begin: () => Effect.fail(new McpRegistryError({ detail: "OAuth sign-in is not available." })),
|
|
@@ -22319,7 +22497,7 @@ const decodeRegistration$1 = Schema$1.decodeUnknownExit(RegistrationFromJson$1);
|
|
|
22319
22497
|
const encodeRegistration = Schema$1.encodeSync(RegistrationFromJson$1);
|
|
22320
22498
|
var McpRegistry = class extends Context.Service()("@p4code/cli/mcp/McpRegistry") {};
|
|
22321
22499
|
const slotsOf = (registration) => registration.secrets ?? [];
|
|
22322
|
-
const make$
|
|
22500
|
+
const make$80 = Effect.gen(function* () {
|
|
22323
22501
|
const config = yield* ServerConfig$1;
|
|
22324
22502
|
const secrets = yield* ServerSecretStore;
|
|
22325
22503
|
const oauth = yield* McpOAuth;
|
|
@@ -22493,7 +22671,7 @@ const make$79 = Effect.gen(function* () {
|
|
|
22493
22671
|
resolveForSessionAtClaudeUserConfigPath
|
|
22494
22672
|
};
|
|
22495
22673
|
});
|
|
22496
|
-
const layer$68 = Layer.effect(McpRegistry, make$
|
|
22674
|
+
const layer$68 = Layer.effect(McpRegistry, make$80);
|
|
22497
22675
|
//#endregion
|
|
22498
22676
|
//#region src/sync/skillDirectory.ts
|
|
22499
22677
|
/**
|
|
@@ -22872,7 +23050,7 @@ const formatHubLink = (input) => encodeStoredHubLink({
|
|
|
22872
23050
|
shareMode: input.shareMode
|
|
22873
23051
|
});
|
|
22874
23052
|
const fromEnvironment = (environment) => validateHubLink(environment.P4CODE_HUB_URL ?? "", environment.P4CODE_HUB_TOKEN ?? "");
|
|
22875
|
-
const make$
|
|
23053
|
+
const make$79 = Effect.fn("HubLink.make")(function* (environment) {
|
|
22876
23054
|
const secrets = yield* ServerSecretStore;
|
|
22877
23055
|
const env = environment ?? process.env;
|
|
22878
23056
|
const fromEnv = fromEnvironment(env);
|
|
@@ -22938,7 +23116,7 @@ const make$78 = Effect.fn("HubLink.make")(function* (environment) {
|
|
|
22938
23116
|
})
|
|
22939
23117
|
};
|
|
22940
23118
|
});
|
|
22941
|
-
const layer$67 = Layer.effect(HubLink, make$
|
|
23119
|
+
const layer$67 = Layer.effect(HubLink, make$79());
|
|
22942
23120
|
//#endregion
|
|
22943
23121
|
//#region src/sync/HubAssetClient.ts
|
|
22944
23122
|
/**
|
|
@@ -22971,7 +23149,7 @@ const decodeAssetListPage = Schema$1.decodeUnknownEffect(AssetListPage);
|
|
|
22971
23149
|
const decodeConflictBody$1 = Schema$1.decodeUnknownEffect(ConflictBody$1);
|
|
22972
23150
|
const decodeAsset = Schema$1.decodeUnknownEffect(AgentAsset);
|
|
22973
23151
|
var HubAssetClient = class extends Context.Service()("@p4code/cli/sync/HubAssetClient") {};
|
|
22974
|
-
const make$
|
|
23152
|
+
const make$78 = Effect.gen(function* () {
|
|
22975
23153
|
const http = yield* HttpClient.HttpClient;
|
|
22976
23154
|
const link = yield* HubLink;
|
|
22977
23155
|
const requireSettings = Effect.gen(function* () {
|
|
@@ -23053,7 +23231,7 @@ const make$77 = Effect.gen(function* () {
|
|
|
23053
23231
|
remove
|
|
23054
23232
|
};
|
|
23055
23233
|
});
|
|
23056
|
-
const layer$66 = Layer.effect(HubAssetClient, make$
|
|
23234
|
+
const layer$66 = Layer.effect(HubAssetClient, make$78);
|
|
23057
23235
|
//#endregion
|
|
23058
23236
|
//#region src/sync/mcpRegistrationFiles.ts
|
|
23059
23237
|
/**
|
|
@@ -23659,7 +23837,7 @@ const EMPTY_REPORT = {
|
|
|
23659
23837
|
unavailable: null
|
|
23660
23838
|
};
|
|
23661
23839
|
var AssetSync = class extends Context.Service()("@p4code/cli/sync/AssetSync") {};
|
|
23662
|
-
const make$
|
|
23840
|
+
const make$77 = Effect.gen(function* () {
|
|
23663
23841
|
const client = yield* HubAssetClient;
|
|
23664
23842
|
const link = yield* HubLink;
|
|
23665
23843
|
const settingsStore = yield* ServerSettingsService;
|
|
@@ -24369,7 +24547,7 @@ const make$76 = Effect.gen(function* () {
|
|
|
24369
24547
|
removeLocal
|
|
24370
24548
|
};
|
|
24371
24549
|
});
|
|
24372
|
-
const layer$65 = Layer.effect(AssetSync, make$
|
|
24550
|
+
const layer$65 = Layer.effect(AssetSync, make$77);
|
|
24373
24551
|
//#endregion
|
|
24374
24552
|
//#region src/provider/CompressPrompts.ts
|
|
24375
24553
|
/**
|
|
@@ -25446,6 +25624,30 @@ function toPersistenceSqlOrDecodeError$4(sqlOperation, decodeOperation) {
|
|
|
25446
25624
|
}
|
|
25447
25625
|
const makeEventStore = Effect.gen(function* () {
|
|
25448
25626
|
const sql = yield* SqlClient.SqlClient;
|
|
25627
|
+
const readReviewRows = SqlSchema.findAll({
|
|
25628
|
+
Request: Schema$1.Struct({
|
|
25629
|
+
afterSequence: NonNegativeInt,
|
|
25630
|
+
throughSequence: NonNegativeInt,
|
|
25631
|
+
limit: NonNegativeInt
|
|
25632
|
+
}),
|
|
25633
|
+
Result: Schema$1.Struct({
|
|
25634
|
+
sequence: NonNegativeInt,
|
|
25635
|
+
type: Schema$1.String,
|
|
25636
|
+
aggregateKind: Schema$1.String,
|
|
25637
|
+
aggregateId: Schema$1.String,
|
|
25638
|
+
payloadJson: Schema$1.String
|
|
25639
|
+
}),
|
|
25640
|
+
execute: (request) => sql`
|
|
25641
|
+
SELECT sequence, event_type AS "type", aggregate_kind AS "aggregateKind",
|
|
25642
|
+
stream_id AS "aggregateId",
|
|
25643
|
+
substr(payload_json, 1, ${8001}) AS "payloadJson"
|
|
25644
|
+
FROM orchestration_events
|
|
25645
|
+
WHERE sequence > ${request.afterSequence} AND sequence <= ${request.throughSequence}
|
|
25646
|
+
ORDER BY sequence ASC
|
|
25647
|
+
LIMIT ${Math.min(request.limit, THREAD_REVIEW_SCAN_LIMIT)}
|
|
25648
|
+
`
|
|
25649
|
+
});
|
|
25650
|
+
const readReviewPage = (input) => readReviewRows(input).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$4("OrchestrationEventStore.readReviewPage:query", "OrchestrationEventStore.readReviewPage:decode")));
|
|
25449
25651
|
const appendEventRow = SqlSchema.findOne({
|
|
25450
25652
|
Request: AppendEventRequestSchema,
|
|
25451
25653
|
Result: OrchestrationEventPersistedRowSchema,
|
|
@@ -25615,6 +25817,7 @@ const makeEventStore = Effect.gen(function* () {
|
|
|
25615
25817
|
append,
|
|
25616
25818
|
readByCommandId,
|
|
25617
25819
|
readFromSequence,
|
|
25820
|
+
readReviewPage,
|
|
25618
25821
|
readAll: () => readFromSequence(0, Number.MAX_SAFE_INTEGER)
|
|
25619
25822
|
};
|
|
25620
25823
|
});
|
|
@@ -25739,6 +25942,99 @@ function toProjectorDecodeError(eventType) {
|
|
|
25739
25942
|
});
|
|
25740
25943
|
}
|
|
25741
25944
|
//#endregion
|
|
25945
|
+
//#region ../../packages/shared/src/taskAgentKind.ts
|
|
25946
|
+
/** Unknown task types remain agents; only known background types are excluded. */
|
|
25947
|
+
function classifyTaskAgentKind(input) {
|
|
25948
|
+
const taskType = input.taskType ?? input.subagentType;
|
|
25949
|
+
const nonAgent = taskType != null && (INERT_TASK_TYPES.has(taskType) || MONITOR_TASK_TYPES.has(taskType));
|
|
25950
|
+
if (input.agentId?.trim()) return taskType == null || nonAgent ? "background" : "agent";
|
|
25951
|
+
return nonAgent ? "background" : "agent";
|
|
25952
|
+
}
|
|
25953
|
+
//#endregion
|
|
25954
|
+
//#region src/orchestration/ThreadBackgroundLiveness.ts
|
|
25955
|
+
/**
|
|
25956
|
+
* ThreadBackgroundLivenessService - in-memory per-thread background liveness
|
|
25957
|
+
* for the sidebar status pill.
|
|
25958
|
+
*
|
|
25959
|
+
* The turn can settle while native background work runs on (subagent fleets,
|
|
25960
|
+
* workflow runs, Monitor watch loops); the shell previously showed nothing.
|
|
25961
|
+
* Ingestion records task lifecycle transitions and the shell query reads the
|
|
25962
|
+
* derived state at mapping time — no persistence, no migration. After a
|
|
25963
|
+
* server restart the registry is empty until new task events arrive, which
|
|
25964
|
+
* matches reality: orphaned background work is not live.
|
|
25965
|
+
*
|
|
25966
|
+
* "monitoring" is reserved for watch loops (monitor tasks and background
|
|
25967
|
+
* shells) when they are the ONLY live work; any agent work presents as
|
|
25968
|
+
* "working".
|
|
25969
|
+
*
|
|
25970
|
+
* @module ThreadBackgroundLivenessService
|
|
25971
|
+
*/
|
|
25972
|
+
const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
25973
|
+
"completed",
|
|
25974
|
+
"failed",
|
|
25975
|
+
"stopped",
|
|
25976
|
+
"cancelled",
|
|
25977
|
+
"interrupted"
|
|
25978
|
+
]);
|
|
25979
|
+
var ThreadBackgroundLivenessService = class extends Context.Service()("@p4code/cli/orchestration/ThreadBackgroundLiveness/ThreadBackgroundLivenessService") {};
|
|
25980
|
+
function make$76() {
|
|
25981
|
+
const stateByThreadId = /* @__PURE__ */ new Map();
|
|
25982
|
+
const stateFor = (threadId) => {
|
|
25983
|
+
const existing = stateByThreadId.get(threadId);
|
|
25984
|
+
if (existing) return existing;
|
|
25985
|
+
const created = {
|
|
25986
|
+
agents: /* @__PURE__ */ new Set(),
|
|
25987
|
+
monitors: /* @__PURE__ */ new Set(),
|
|
25988
|
+
tasks: /* @__PURE__ */ new Map()
|
|
25989
|
+
};
|
|
25990
|
+
stateByThreadId.set(threadId, created);
|
|
25991
|
+
return created;
|
|
25992
|
+
};
|
|
25993
|
+
const drop = (threadId, taskId) => {
|
|
25994
|
+
const state = stateByThreadId.get(threadId);
|
|
25995
|
+
if (!state) return;
|
|
25996
|
+
state.agents.delete(taskId);
|
|
25997
|
+
state.monitors.delete(taskId);
|
|
25998
|
+
if (state.tasks.size === 0) stateByThreadId.delete(threadId);
|
|
25999
|
+
};
|
|
26000
|
+
return {
|
|
26001
|
+
recordTaskLiveness: (input) => {
|
|
26002
|
+
const state = stateFor(input.threadId);
|
|
26003
|
+
const previous = state.tasks.get(input.taskId);
|
|
26004
|
+
const taskType = input.taskType ?? previous?.taskType;
|
|
26005
|
+
const agentId = input.agentId ?? previous?.agentId;
|
|
26006
|
+
if (input.kind === "completed" || input.status !== void 0 && TERMINAL_STATUSES.has(input.status)) {
|
|
26007
|
+
state.tasks.delete(input.taskId);
|
|
26008
|
+
drop(input.threadId, input.taskId);
|
|
26009
|
+
return;
|
|
26010
|
+
}
|
|
26011
|
+
state.tasks.set(input.taskId, {
|
|
26012
|
+
taskType,
|
|
26013
|
+
agentId
|
|
26014
|
+
});
|
|
26015
|
+
drop(input.threadId, input.taskId);
|
|
26016
|
+
if (input.status === "idle") return;
|
|
26017
|
+
if (taskType !== void 0 && INERT_TASK_TYPES.has(taskType)) return;
|
|
26018
|
+
if (agentId !== void 0 && classifyTaskAgentKind({
|
|
26019
|
+
taskType,
|
|
26020
|
+
agentId
|
|
26021
|
+
}) === "background") return;
|
|
26022
|
+
(taskType !== void 0 && MONITOR_TASK_TYPES.has(taskType) ? state.monitors : state.agents).add(input.taskId);
|
|
26023
|
+
},
|
|
26024
|
+
clearThreadLiveness: (threadId) => {
|
|
26025
|
+
stateByThreadId.delete(threadId);
|
|
26026
|
+
},
|
|
26027
|
+
getThreadBackgroundLiveness: (threadId) => {
|
|
26028
|
+
const state = stateByThreadId.get(threadId);
|
|
26029
|
+
if (!state) return null;
|
|
26030
|
+
if (state.agents.size > 0) return "working";
|
|
26031
|
+
if (state.monitors.size > 0) return "monitoring";
|
|
26032
|
+
return null;
|
|
26033
|
+
}
|
|
26034
|
+
};
|
|
26035
|
+
}
|
|
26036
|
+
const layer$64 = Layer.effect(ThreadBackgroundLivenessService, Effect.sync(make$76));
|
|
26037
|
+
//#endregion
|
|
25742
26038
|
//#region ../../packages/shared/src/path.ts
|
|
25743
26039
|
function isWindowsDrivePath(value) {
|
|
25744
26040
|
return /^[a-zA-Z]:([/\\]|$)/.test(value);
|
|
@@ -25817,6 +26113,74 @@ function requireThreadAbsent(input) {
|
|
|
25817
26113
|
return Effect.fail(invariantError(input.command.type, `Thread '${input.threadId}' already exists and cannot be created twice.`));
|
|
25818
26114
|
}
|
|
25819
26115
|
//#endregion
|
|
26116
|
+
//#region src/orchestration/ThreadCompletion.ts
|
|
26117
|
+
const ENGAGEMENT_ACTIVITY_KINDS = /* @__PURE__ */ new Set([
|
|
26118
|
+
"approval.requested",
|
|
26119
|
+
"user-input.requested",
|
|
26120
|
+
"tool.started",
|
|
26121
|
+
"tool.updated",
|
|
26122
|
+
"tool.completed",
|
|
26123
|
+
"task.started",
|
|
26124
|
+
"task.progress",
|
|
26125
|
+
"task.updated",
|
|
26126
|
+
"task.completed",
|
|
26127
|
+
"turn.plan.updated"
|
|
26128
|
+
]);
|
|
26129
|
+
function isThreadEngagement(event) {
|
|
26130
|
+
switch (event.type) {
|
|
26131
|
+
case "thread.message-sent": return "text" in event.payload && typeof event.payload.text === "string" && event.payload.text.length > 0;
|
|
26132
|
+
case "thread.session-set": return "session" in event.payload && (event.payload.session.status === "starting" || event.payload.session.status === "running");
|
|
26133
|
+
case "thread.activity-appended": return "activity" in event.payload && ENGAGEMENT_ACTIVITY_KINDS.has(event.payload.activity.kind);
|
|
26134
|
+
case "thread.proposed-plan-upserted":
|
|
26135
|
+
case "thread.pinned": return true;
|
|
26136
|
+
default: return false;
|
|
26137
|
+
}
|
|
26138
|
+
}
|
|
26139
|
+
function completionState(thread) {
|
|
26140
|
+
return {
|
|
26141
|
+
lifecycle: thread.lifecycle ?? (thread.archivedAt !== null ? "archived" : thread.settledOverride === "settled" ? "done" : "active"),
|
|
26142
|
+
lifecycleReason: thread.lifecycleReason ?? (thread.settledOverride === "settled" ? "manual" : "created"),
|
|
26143
|
+
lifecycleChangedAt: thread.lifecycleChangedAt ?? thread.archivedAt ?? thread.settledAt ?? thread.createdAt,
|
|
26144
|
+
lastEngagedAt: thread.lastEngagedAt ?? thread.createdAt,
|
|
26145
|
+
doneAt: thread.doneAt ?? thread.settledAt
|
|
26146
|
+
};
|
|
26147
|
+
}
|
|
26148
|
+
/** Transition metadata is shared by in-memory and persisted projections. */
|
|
26149
|
+
function completionAfterEvent(thread, event) {
|
|
26150
|
+
const state = completionState(thread);
|
|
26151
|
+
if (isThreadEngagement(event)) state.lastEngagedAt = state.lastEngagedAt > event.occurredAt ? state.lastEngagedAt : event.occurredAt;
|
|
26152
|
+
switch (event.type) {
|
|
26153
|
+
case "thread.settled": return {
|
|
26154
|
+
...state,
|
|
26155
|
+
lifecycle: "done",
|
|
26156
|
+
doneAt: event.payload.settledAt,
|
|
26157
|
+
lifecycleReason: event.payload.lifecycleReason ?? "manual",
|
|
26158
|
+
lifecycleChangedAt: event.payload.lifecycleChangedAt ?? event.payload.settledAt
|
|
26159
|
+
};
|
|
26160
|
+
case "thread.unsettled": return {
|
|
26161
|
+
...state,
|
|
26162
|
+
lifecycle: "active",
|
|
26163
|
+
doneAt: null,
|
|
26164
|
+
lifecycleReason: event.payload.lifecycleReason ?? event.payload.reason,
|
|
26165
|
+
lifecycleChangedAt: event.payload.lifecycleChangedAt ?? event.payload.updatedAt,
|
|
26166
|
+
lastEngagedAt: event.payload.lastEngagedAt ?? (state.lastEngagedAt > event.payload.updatedAt ? state.lastEngagedAt : event.payload.updatedAt)
|
|
26167
|
+
};
|
|
26168
|
+
case "thread.archived": return {
|
|
26169
|
+
...state,
|
|
26170
|
+
lifecycle: "archived",
|
|
26171
|
+
lifecycleReason: "archive",
|
|
26172
|
+
lifecycleChangedAt: event.payload.lifecycleChangedAt ?? event.payload.archivedAt
|
|
26173
|
+
};
|
|
26174
|
+
case "thread.unarchived": return {
|
|
26175
|
+
...state,
|
|
26176
|
+
lifecycle: state.doneAt !== null ? "done" : "active",
|
|
26177
|
+
lifecycleReason: "restore",
|
|
26178
|
+
lifecycleChangedAt: event.payload.lifecycleChangedAt ?? event.payload.updatedAt
|
|
26179
|
+
};
|
|
26180
|
+
default: return state;
|
|
26181
|
+
}
|
|
26182
|
+
}
|
|
26183
|
+
//#endregion
|
|
25820
26184
|
//#region src/attachmentPaths.ts
|
|
25821
26185
|
function normalizeAttachmentRelativePath(rawRelativePath) {
|
|
25822
26186
|
const normalized = NodePath.normalize(rawRelativePath).replace(/^[/\\]+/, "");
|
|
@@ -26232,6 +26596,10 @@ function createEmptyReadModel(nowIso) {
|
|
|
26232
26596
|
function projectEvent(model, event) {
|
|
26233
26597
|
const nextBase = {
|
|
26234
26598
|
...model,
|
|
26599
|
+
threads: event.aggregateKind !== "thread" ? model.threads : model.threads.map((thread) => thread.id === event.aggregateId ? {
|
|
26600
|
+
...thread,
|
|
26601
|
+
...completionAfterEvent(thread, event)
|
|
26602
|
+
} : thread),
|
|
26235
26603
|
snapshotSequence: event.sequence,
|
|
26236
26604
|
updatedAt: event.occurredAt
|
|
26237
26605
|
};
|
|
@@ -26339,8 +26707,13 @@ function projectEvent(model, event) {
|
|
|
26339
26707
|
latestTurn: null,
|
|
26340
26708
|
createdAt: payload.createdAt,
|
|
26341
26709
|
updatedAt: payload.updatedAt,
|
|
26710
|
+
lifecycle: "active",
|
|
26711
|
+
lifecycleReason: "created",
|
|
26712
|
+
lifecycleChangedAt: payload.createdAt,
|
|
26713
|
+
lastEngagedAt: payload.createdAt,
|
|
26714
|
+
doneAt: null,
|
|
26715
|
+
settledOverride: "active",
|
|
26342
26716
|
archivedAt: null,
|
|
26343
|
-
settledOverride: null,
|
|
26344
26717
|
settledAt: null,
|
|
26345
26718
|
snoozedUntil: null,
|
|
26346
26719
|
snoozedAt: null,
|
|
@@ -26388,7 +26761,7 @@ function projectEvent(model, event) {
|
|
|
26388
26761
|
case "thread.unsettled": return decodeForEvent(ThreadUnsettledPayload, event.payload, event.type, "payload").pipe(Effect.map((payload) => ({
|
|
26389
26762
|
...nextBase,
|
|
26390
26763
|
threads: updateThread(nextBase.threads, payload.threadId, {
|
|
26391
|
-
settledOverride:
|
|
26764
|
+
settledOverride: "active",
|
|
26392
26765
|
settledAt: null,
|
|
26393
26766
|
updatedAt: payload.updatedAt
|
|
26394
26767
|
})
|
|
@@ -26748,7 +27121,7 @@ const decideCommandSequence = Effect.fn("decideCommandSequence")(function* ({ co
|
|
|
26748
27121
|
}
|
|
26749
27122
|
return plannedEvents;
|
|
26750
27123
|
});
|
|
26751
|
-
const
|
|
27124
|
+
const decideCommand = Effect.fn("decideCommand")(function* ({ command, readModel }) {
|
|
26752
27125
|
switch (command.type) {
|
|
26753
27126
|
case "project.create":
|
|
26754
27127
|
yield* requireProjectAbsent({
|
|
@@ -27388,12 +27761,19 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
27388
27761
|
}
|
|
27389
27762
|
return events;
|
|
27390
27763
|
}
|
|
27764
|
+
case "thread.complete":
|
|
27765
|
+
case "thread.complete.auto":
|
|
27391
27766
|
case "thread.settle": {
|
|
27392
27767
|
const thread = yield* requireThreadNotArchived({
|
|
27393
27768
|
readModel,
|
|
27394
27769
|
command,
|
|
27395
27770
|
threadId: command.threadId
|
|
27396
27771
|
});
|
|
27772
|
+
const occurredAt = yield* nowIso$8;
|
|
27773
|
+
if (command.type === "thread.complete.auto" && (completionState(thread).lastEngagedAt !== command.expectedLastEngagedAt || !(Date.parse(command.expectedLastEngagedAt) < Date.parse(command.eligibleAt)) || !(Date.parse(command.eligibleAt) <= Date.parse(occurredAt)) || thread.pinnedAt != null)) return yield* new OrchestrationCommandInvariantError({
|
|
27774
|
+
commandType: command.type,
|
|
27775
|
+
detail: "Thread engagement changed or automatic completion is no longer eligible"
|
|
27776
|
+
});
|
|
27397
27777
|
if (thread.session?.status === "starting" || thread.session?.status === "running") return yield* new OrchestrationCommandInvariantError({
|
|
27398
27778
|
commandType: command.type,
|
|
27399
27779
|
detail: `thread ${command.threadId} has an active session and cannot be settled`
|
|
@@ -27402,7 +27782,6 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
27402
27782
|
commandType: command.type,
|
|
27403
27783
|
detail: `thread ${command.threadId} has a pending approval or user-input request and cannot be settled`
|
|
27404
27784
|
});
|
|
27405
|
-
const occurredAt = yield* nowIso$8;
|
|
27406
27785
|
if (threadHasQueuedTurnStart(thread, occurredAt)) return yield* new OrchestrationCommandInvariantError({
|
|
27407
27786
|
commandType: command.type,
|
|
27408
27787
|
detail: `thread ${command.threadId} has a queued turn start and cannot be settled`
|
|
@@ -27437,6 +27816,7 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
27437
27816
|
}
|
|
27438
27817
|
}];
|
|
27439
27818
|
}
|
|
27819
|
+
case "thread.reopen":
|
|
27440
27820
|
case "thread.unsettle": {
|
|
27441
27821
|
const thread = yield* requireThreadNotArchived({
|
|
27442
27822
|
readModel,
|
|
@@ -27455,7 +27835,7 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
27455
27835
|
type: "thread.unsettled",
|
|
27456
27836
|
payload: {
|
|
27457
27837
|
threadId: command.threadId,
|
|
27458
|
-
reason:
|
|
27838
|
+
reason: "user",
|
|
27459
27839
|
updatedAt: alreadyPinnedActive ? thread.updatedAt : occurredAt
|
|
27460
27840
|
}
|
|
27461
27841
|
};
|
|
@@ -27812,7 +28192,7 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
27812
28192
|
}
|
|
27813
28193
|
};
|
|
27814
28194
|
const lifecycleResetEvents = [];
|
|
27815
|
-
if (targetThread.settledOverride
|
|
28195
|
+
if (targetThread.settledOverride === "settled") lifecycleResetEvents.push({
|
|
27816
28196
|
...yield* withEventBase({
|
|
27817
28197
|
aggregateKind: "thread",
|
|
27818
28198
|
aggregateId: command.threadId,
|
|
@@ -28063,7 +28443,7 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
28063
28443
|
}
|
|
28064
28444
|
};
|
|
28065
28445
|
const isSessionActivity = command.session.status === "starting" || command.session.status === "running";
|
|
28066
|
-
if (thread.settledOverride
|
|
28446
|
+
if (thread.settledOverride !== "settled" || !isSessionActivity) return sessionSetEvent;
|
|
28067
28447
|
return [{
|
|
28068
28448
|
...yield* withEventBase({
|
|
28069
28449
|
aggregateKind: "thread",
|
|
@@ -28214,7 +28594,7 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
28214
28594
|
}
|
|
28215
28595
|
};
|
|
28216
28596
|
const wakesSettledThread = command.activity.kind === "approval.requested" || command.activity.kind === "user-input.requested";
|
|
28217
|
-
if (thread.settledOverride
|
|
28597
|
+
if (thread.settledOverride !== "settled" || !wakesSettledThread) return activityAppendedEvent;
|
|
28218
28598
|
return [{
|
|
28219
28599
|
...yield* withEventBase({
|
|
28220
28600
|
aggregateKind: "thread",
|
|
@@ -28239,6 +28619,74 @@ const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(funct
|
|
|
28239
28619
|
}
|
|
28240
28620
|
}
|
|
28241
28621
|
});
|
|
28622
|
+
const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand")(function* (input) {
|
|
28623
|
+
const { command, readModel } = input;
|
|
28624
|
+
if (input.hasLiveBackgroundWork && (command.type === "thread.settle" || command.type === "thread.complete" || command.type === "thread.complete.auto")) return yield* new OrchestrationCommandInvariantError({
|
|
28625
|
+
commandType: command.type,
|
|
28626
|
+
detail: "Thread has live background work and cannot be completed"
|
|
28627
|
+
});
|
|
28628
|
+
const decided = yield* decideCommand(input);
|
|
28629
|
+
const events = Array.isArray(decided) ? [...decided] : [decided];
|
|
28630
|
+
const target = "threadId" in command ? readModel.threads.find((thread) => thread.id === command.threadId) : void 0;
|
|
28631
|
+
const engagement = events.find(isThreadEngagement);
|
|
28632
|
+
if (target && target.archivedAt === null && completionState(target).lifecycle === "done" && engagement && !events.some((event) => event.type === "thread.unsettled")) events.unshift({
|
|
28633
|
+
...yield* withEventBase({
|
|
28634
|
+
aggregateKind: "thread",
|
|
28635
|
+
aggregateId: target.id,
|
|
28636
|
+
occurredAt: engagement.occurredAt,
|
|
28637
|
+
commandId: command.commandId
|
|
28638
|
+
}),
|
|
28639
|
+
type: "thread.unsettled",
|
|
28640
|
+
payload: {
|
|
28641
|
+
threadId: target.id,
|
|
28642
|
+
reason: "activity",
|
|
28643
|
+
updatedAt: engagement.occurredAt
|
|
28644
|
+
}
|
|
28645
|
+
});
|
|
28646
|
+
return events.map((event) => {
|
|
28647
|
+
if (event.type === "thread.created") return {
|
|
28648
|
+
...event,
|
|
28649
|
+
payload: {
|
|
28650
|
+
...event.payload,
|
|
28651
|
+
lifecycle: "active",
|
|
28652
|
+
lifecycleReason: "created",
|
|
28653
|
+
lifecycleChangedAt: event.payload.createdAt,
|
|
28654
|
+
lastEngagedAt: event.payload.createdAt,
|
|
28655
|
+
doneAt: null
|
|
28656
|
+
}
|
|
28657
|
+
};
|
|
28658
|
+
const eventThread = readModel.threads.find((thread) => thread.id === event.aggregateId);
|
|
28659
|
+
if (!eventThread) return event;
|
|
28660
|
+
switch (event.type) {
|
|
28661
|
+
case "thread.settled":
|
|
28662
|
+
case "thread.unsettled":
|
|
28663
|
+
case "thread.archived":
|
|
28664
|
+
case "thread.unarchived": {
|
|
28665
|
+
const previous = completionState(eventThread);
|
|
28666
|
+
const state = completionAfterEvent(eventThread, {
|
|
28667
|
+
...event,
|
|
28668
|
+
sequence: readModel.snapshotSequence + 1
|
|
28669
|
+
});
|
|
28670
|
+
if (event.type === "thread.settled") state.lifecycleReason = previous.lifecycle === "done" ? previous.lifecycleReason : command.type === "thread.complete.auto" ? command.reason : "manual";
|
|
28671
|
+
if (event.type === "thread.settled" && previous.lifecycle === "done" || event.type === "thread.unsettled" && previous.lifecycle === "active" && (command.type === "thread.reopen" || command.type === "thread.unsettle")) return {
|
|
28672
|
+
...event,
|
|
28673
|
+
payload: {
|
|
28674
|
+
...event.payload,
|
|
28675
|
+
...previous
|
|
28676
|
+
}
|
|
28677
|
+
};
|
|
28678
|
+
return {
|
|
28679
|
+
...event,
|
|
28680
|
+
payload: {
|
|
28681
|
+
...event.payload,
|
|
28682
|
+
...state
|
|
28683
|
+
}
|
|
28684
|
+
};
|
|
28685
|
+
}
|
|
28686
|
+
default: return event;
|
|
28687
|
+
}
|
|
28688
|
+
});
|
|
28689
|
+
});
|
|
28242
28690
|
//#endregion
|
|
28243
28691
|
//#region src/orchestration/Services/ProjectionPipeline.ts
|
|
28244
28692
|
/**
|
|
@@ -28279,6 +28727,7 @@ const makeOrchestrationEngine = Effect.gen(function* () {
|
|
|
28279
28727
|
const projectionPipeline = yield* OrchestrationProjectionPipeline;
|
|
28280
28728
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
28281
28729
|
const crypto = yield* Crypto.Crypto;
|
|
28730
|
+
const backgroundLiveness = yield* ThreadBackgroundLivenessService;
|
|
28282
28731
|
const nowIso = Effect.map(DateTime.now, DateTime.formatIso);
|
|
28283
28732
|
let commandReadModel = createEmptyReadModel(yield* nowIso);
|
|
28284
28733
|
const commandQueue = yield* Queue.unbounded();
|
|
@@ -28326,7 +28775,8 @@ const makeOrchestrationEngine = Effect.gen(function* () {
|
|
|
28326
28775
|
}
|
|
28327
28776
|
const eventBase = yield* decideOrchestrationCommand({
|
|
28328
28777
|
command: envelope.command,
|
|
28329
|
-
readModel: commandReadModel
|
|
28778
|
+
readModel: commandReadModel,
|
|
28779
|
+
hasLiveBackgroundWork: "threadId" in envelope.command && backgroundLiveness.getThreadBackgroundLiveness(envelope.command.threadId) !== null
|
|
28330
28780
|
}).pipe(Effect.provideService(Crypto.Crypto, crypto), Effect.mapError((cause) => isOrchestrationCommandInvariantError(cause) ? cause : new OrchestrationCommandInvariantError({
|
|
28331
28781
|
commandType: envelope.command.type,
|
|
28332
28782
|
detail: "Failed to generate an event identifier.",
|
|
@@ -28428,7 +28878,7 @@ const makeOrchestrationEngine = Effect.gen(function* () {
|
|
|
28428
28878
|
latestSequence: Effect.sync(() => commandReadModel.snapshotSequence)
|
|
28429
28879
|
};
|
|
28430
28880
|
});
|
|
28431
|
-
const OrchestrationEngineLive = Layer.effect(OrchestrationEngineService, makeOrchestrationEngine);
|
|
28881
|
+
const OrchestrationEngineLive = Layer.effect(OrchestrationEngineService, makeOrchestrationEngine).pipe(Layer.provide(layer$64));
|
|
28432
28882
|
//#endregion
|
|
28433
28883
|
//#region src/persistence/Services/ProjectionPendingApprovals.ts
|
|
28434
28884
|
/**
|
|
@@ -28694,6 +29144,7 @@ var ProjectionTurnRepository = class extends Context.Service()("@p4code/cli/pers
|
|
|
28694
29144
|
* @module ProjectionThreadRepository
|
|
28695
29145
|
*/
|
|
28696
29146
|
const ProjectionThread = Schema$1.Struct({
|
|
29147
|
+
...ThreadCompletionFields,
|
|
28697
29148
|
threadId: ThreadId,
|
|
28698
29149
|
projectId: ProjectId,
|
|
28699
29150
|
title: Schema$1.String,
|
|
@@ -29696,6 +30147,10 @@ const makeProjectionThreadRepository = Effect.gen(function* () {
|
|
|
29696
30147
|
archived_at,
|
|
29697
30148
|
settled_override,
|
|
29698
30149
|
settled_at,
|
|
30150
|
+
lifecycle,
|
|
30151
|
+
lifecycle_reason,
|
|
30152
|
+
lifecycle_changed_at,
|
|
30153
|
+
last_engaged_at,
|
|
29699
30154
|
snoozed_until,
|
|
29700
30155
|
snoozed_at,
|
|
29701
30156
|
pinned_at,
|
|
@@ -29726,6 +30181,10 @@ const makeProjectionThreadRepository = Effect.gen(function* () {
|
|
|
29726
30181
|
${row.archivedAt},
|
|
29727
30182
|
${row.settledOverride},
|
|
29728
30183
|
${row.settledAt},
|
|
30184
|
+
${row.lifecycle ?? (row.archivedAt !== null ? "archived" : row.settledOverride === "settled" ? "done" : "active")},
|
|
30185
|
+
${row.lifecycleReason ?? (row.settledOverride === "settled" ? "manual" : "created")},
|
|
30186
|
+
${row.lifecycleChangedAt ?? row.settledAt ?? row.createdAt},
|
|
30187
|
+
${row.lastEngagedAt ?? row.latestUserMessageAt ?? row.createdAt},
|
|
29729
30188
|
${row.snoozedUntil},
|
|
29730
30189
|
${row.snoozedAt},
|
|
29731
30190
|
${row.pinnedAt},
|
|
@@ -29756,6 +30215,10 @@ const makeProjectionThreadRepository = Effect.gen(function* () {
|
|
|
29756
30215
|
archived_at = excluded.archived_at,
|
|
29757
30216
|
settled_override = excluded.settled_override,
|
|
29758
30217
|
settled_at = excluded.settled_at,
|
|
30218
|
+
lifecycle = excluded.lifecycle,
|
|
30219
|
+
lifecycle_reason = excluded.lifecycle_reason,
|
|
30220
|
+
lifecycle_changed_at = excluded.lifecycle_changed_at,
|
|
30221
|
+
last_engaged_at = excluded.last_engaged_at,
|
|
29759
30222
|
snoozed_until = excluded.snoozed_until,
|
|
29760
30223
|
snoozed_at = excluded.snoozed_at,
|
|
29761
30224
|
pinned_at = excluded.pinned_at,
|
|
@@ -29791,6 +30254,10 @@ const makeProjectionThreadRepository = Effect.gen(function* () {
|
|
|
29791
30254
|
archived_at AS "archivedAt",
|
|
29792
30255
|
settled_override AS "settledOverride",
|
|
29793
30256
|
settled_at AS "settledAt",
|
|
30257
|
+
lifecycle AS "lifecycle",
|
|
30258
|
+
lifecycle_reason AS "lifecycleReason",
|
|
30259
|
+
lifecycle_changed_at AS "lifecycleChangedAt",
|
|
30260
|
+
last_engaged_at AS "lastEngagedAt",
|
|
29794
30261
|
snoozed_until AS "snoozedUntil",
|
|
29795
30262
|
snoozed_at AS "snoozedAt",
|
|
29796
30263
|
pinned_at AS "pinnedAt",
|
|
@@ -29828,6 +30295,10 @@ const makeProjectionThreadRepository = Effect.gen(function* () {
|
|
|
29828
30295
|
archived_at AS "archivedAt",
|
|
29829
30296
|
settled_override AS "settledOverride",
|
|
29830
30297
|
settled_at AS "settledAt",
|
|
30298
|
+
lifecycle AS "lifecycle",
|
|
30299
|
+
lifecycle_reason AS "lifecycleReason",
|
|
30300
|
+
lifecycle_changed_at AS "lifecycleChangedAt",
|
|
30301
|
+
last_engaged_at AS "lastEngagedAt",
|
|
29831
30302
|
snoozed_until AS "snoozedUntil",
|
|
29832
30303
|
snoozed_at AS "snoozedAt",
|
|
29833
30304
|
pinned_at AS "pinnedAt",
|
|
@@ -29865,6 +30336,14 @@ const makeProjectionThreadRepository = Effect.gen(function* () {
|
|
|
29865
30336
|
const ProjectionThreadRepositoryLive = Layer.effect(ProjectionThreadRepository, makeProjectionThreadRepository);
|
|
29866
30337
|
//#endregion
|
|
29867
30338
|
//#region src/orchestration/Layers/ProjectionPipeline.ts
|
|
30339
|
+
/**
|
|
30340
|
+
* Tasks the agent started that never reported a terminal status. A task that
|
|
30341
|
+
* outlives its turn is the case worth surfacing: the session goes back to idle
|
|
30342
|
+
* while the task keeps running, so nothing else in the shell shows the work.
|
|
30343
|
+
*
|
|
30344
|
+
* Counted rather than flagged so a lost completion can only strand one task,
|
|
30345
|
+
* and read as a boolean by the shell.
|
|
30346
|
+
*/
|
|
29868
30347
|
const ORCHESTRATION_PROJECTOR_NAMES = {
|
|
29869
30348
|
projects: "projection.projects",
|
|
29870
30349
|
threads: "projection.threads",
|
|
@@ -29910,14 +30389,6 @@ function extractActivityTaskId(payload) {
|
|
|
29910
30389
|
const taskId = payload.taskId;
|
|
29911
30390
|
return typeof taskId === "string" && taskId.length > 0 ? taskId : null;
|
|
29912
30391
|
}
|
|
29913
|
-
/**
|
|
29914
|
-
* Tasks the agent started that never reported a terminal status. A task that
|
|
29915
|
-
* outlives its turn is the case worth surfacing: the session goes back to idle
|
|
29916
|
-
* while the task keeps running, so nothing else in the shell shows the work.
|
|
29917
|
-
*
|
|
29918
|
-
* Counted rather than flagged so a lost completion can only strand one task,
|
|
29919
|
-
* and read as a boolean by the shell.
|
|
29920
|
-
*/
|
|
29921
30392
|
function deriveBackgroundTaskCountFromActivities(activities) {
|
|
29922
30393
|
const openTaskIds = /* @__PURE__ */ new Set();
|
|
29923
30394
|
const ordered = [...activities].toSorted((left, right) => left.createdAt.localeCompare(right.createdAt) || left.activityId.localeCompare(right.activityId));
|
|
@@ -30260,7 +30731,12 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30260
30731
|
createdAt: event.payload.createdAt,
|
|
30261
30732
|
updatedAt: event.payload.updatedAt,
|
|
30262
30733
|
archivedAt: null,
|
|
30263
|
-
|
|
30734
|
+
lifecycle: "active",
|
|
30735
|
+
lifecycleReason: "created",
|
|
30736
|
+
lifecycleChangedAt: event.payload.createdAt,
|
|
30737
|
+
lastEngagedAt: event.payload.createdAt,
|
|
30738
|
+
doneAt: null,
|
|
30739
|
+
settledOverride: "active",
|
|
30264
30740
|
settledAt: null,
|
|
30265
30741
|
snoozedUntil: null,
|
|
30266
30742
|
snoozedAt: null,
|
|
@@ -30280,6 +30756,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30280
30756
|
if (Option.isNone(existingRow)) return;
|
|
30281
30757
|
yield* projectionThreadRepository.upsert({
|
|
30282
30758
|
...existingRow.value,
|
|
30759
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30283
30760
|
archivedAt: event.payload.archivedAt,
|
|
30284
30761
|
updatedAt: event.payload.updatedAt
|
|
30285
30762
|
});
|
|
@@ -30290,6 +30767,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30290
30767
|
if (Option.isNone(existingRow)) return;
|
|
30291
30768
|
yield* projectionThreadRepository.upsert({
|
|
30292
30769
|
...existingRow.value,
|
|
30770
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30293
30771
|
archivedAt: null,
|
|
30294
30772
|
updatedAt: event.payload.updatedAt
|
|
30295
30773
|
});
|
|
@@ -30300,6 +30778,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30300
30778
|
if (Option.isNone(existingRow)) return;
|
|
30301
30779
|
yield* projectionThreadRepository.upsert({
|
|
30302
30780
|
...existingRow.value,
|
|
30781
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30303
30782
|
settledOverride: "settled",
|
|
30304
30783
|
settledAt: event.payload.settledAt,
|
|
30305
30784
|
updatedAt: event.payload.updatedAt
|
|
@@ -30311,7 +30790,8 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30311
30790
|
if (Option.isNone(existingRow)) return;
|
|
30312
30791
|
yield* projectionThreadRepository.upsert({
|
|
30313
30792
|
...existingRow.value,
|
|
30314
|
-
|
|
30793
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30794
|
+
settledOverride: "active",
|
|
30315
30795
|
settledAt: null,
|
|
30316
30796
|
updatedAt: event.payload.updatedAt
|
|
30317
30797
|
});
|
|
@@ -30322,6 +30802,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30322
30802
|
if (Option.isNone(existingRow)) return;
|
|
30323
30803
|
yield* projectionThreadRepository.upsert({
|
|
30324
30804
|
...existingRow.value,
|
|
30805
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30325
30806
|
snoozedUntil: event.payload.snoozedUntil,
|
|
30326
30807
|
snoozedAt: event.payload.snoozedAt,
|
|
30327
30808
|
updatedAt: event.payload.updatedAt
|
|
@@ -30333,6 +30814,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30333
30814
|
if (Option.isNone(existingRow)) return;
|
|
30334
30815
|
yield* projectionThreadRepository.upsert({
|
|
30335
30816
|
...existingRow.value,
|
|
30817
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30336
30818
|
snoozedUntil: null,
|
|
30337
30819
|
snoozedAt: null,
|
|
30338
30820
|
updatedAt: event.payload.updatedAt
|
|
@@ -30344,6 +30826,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30344
30826
|
if (Option.isNone(existingRow)) return;
|
|
30345
30827
|
yield* projectionThreadRepository.upsert({
|
|
30346
30828
|
...existingRow.value,
|
|
30829
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30347
30830
|
pinnedAt: event.payload.pinnedAt,
|
|
30348
30831
|
...event.payload.pinOrderKey === void 0 ? {} : { pinOrderKey: event.payload.pinOrderKey },
|
|
30349
30832
|
updatedAt: event.payload.updatedAt
|
|
@@ -30355,6 +30838,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30355
30838
|
if (Option.isNone(existingRow)) return;
|
|
30356
30839
|
yield* projectionThreadRepository.upsert({
|
|
30357
30840
|
...existingRow.value,
|
|
30841
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30358
30842
|
pinnedAt: null,
|
|
30359
30843
|
pinOrderKey: null,
|
|
30360
30844
|
updatedAt: event.payload.updatedAt
|
|
@@ -30366,6 +30850,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30366
30850
|
if (Option.isNone(existingRow)) return;
|
|
30367
30851
|
yield* projectionThreadRepository.upsert({
|
|
30368
30852
|
...existingRow.value,
|
|
30853
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30369
30854
|
pinOrderKey: event.payload.pinOrderKey,
|
|
30370
30855
|
updatedAt: event.payload.updatedAt
|
|
30371
30856
|
});
|
|
@@ -30376,6 +30861,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30376
30861
|
if (Option.isNone(existingRow)) return;
|
|
30377
30862
|
yield* projectionThreadRepository.upsert({
|
|
30378
30863
|
...existingRow.value,
|
|
30864
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30379
30865
|
...event.payload.title !== void 0 ? { title: event.payload.title } : {},
|
|
30380
30866
|
...event.payload.modelSelection !== void 0 ? { modelSelection: event.payload.modelSelection } : {},
|
|
30381
30867
|
...event.payload.branch !== void 0 ? { branch: event.payload.branch } : {},
|
|
@@ -30390,6 +30876,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30390
30876
|
if (Option.isNone(existingRow)) return;
|
|
30391
30877
|
yield* projectionThreadRepository.upsert({
|
|
30392
30878
|
...existingRow.value,
|
|
30879
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30393
30880
|
runtimeMode: event.payload.runtimeMode,
|
|
30394
30881
|
updatedAt: event.payload.updatedAt
|
|
30395
30882
|
});
|
|
@@ -30400,6 +30887,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30400
30887
|
if (Option.isNone(existingRow)) return;
|
|
30401
30888
|
yield* projectionThreadRepository.upsert({
|
|
30402
30889
|
...existingRow.value,
|
|
30890
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30403
30891
|
interactionMode: event.payload.interactionMode,
|
|
30404
30892
|
updatedAt: event.payload.updatedAt
|
|
30405
30893
|
});
|
|
@@ -30410,6 +30898,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30410
30898
|
if (Option.isNone(existingRow)) return;
|
|
30411
30899
|
yield* projectionThreadRepository.upsert({
|
|
30412
30900
|
...existingRow.value,
|
|
30901
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30413
30902
|
compressMode: event.payload.compressMode,
|
|
30414
30903
|
updatedAt: event.payload.updatedAt
|
|
30415
30904
|
});
|
|
@@ -30420,6 +30909,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30420
30909
|
if (Option.isNone(existingRow)) return;
|
|
30421
30910
|
yield* projectionThreadRepository.upsert({
|
|
30422
30911
|
...existingRow.value,
|
|
30912
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30423
30913
|
unpromptedSubagents: event.payload.unpromptedSubagents ? 1 : 0,
|
|
30424
30914
|
updatedAt: event.payload.updatedAt
|
|
30425
30915
|
});
|
|
@@ -30431,6 +30921,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30431
30921
|
if (Option.isNone(existingRow)) return;
|
|
30432
30922
|
yield* projectionThreadRepository.upsert({
|
|
30433
30923
|
...existingRow.value,
|
|
30924
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30434
30925
|
deletedAt: event.payload.deletedAt,
|
|
30435
30926
|
updatedAt: event.payload.deletedAt
|
|
30436
30927
|
});
|
|
@@ -30445,6 +30936,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30445
30936
|
if (Option.isNone(existingRow)) return;
|
|
30446
30937
|
yield* projectionThreadRepository.upsert({
|
|
30447
30938
|
...existingRow.value,
|
|
30939
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30448
30940
|
updatedAt: event.occurredAt
|
|
30449
30941
|
});
|
|
30450
30942
|
yield* refreshThreadShellSummary(event.payload.threadId);
|
|
@@ -30455,6 +30947,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30455
30947
|
if (Option.isNone(existingRow)) return;
|
|
30456
30948
|
yield* projectionThreadRepository.upsert({
|
|
30457
30949
|
...existingRow.value,
|
|
30950
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30458
30951
|
latestTurnId: event.payload.session.activeTurnId,
|
|
30459
30952
|
updatedAt: event.occurredAt
|
|
30460
30953
|
});
|
|
@@ -30466,6 +30959,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30466
30959
|
if (Option.isNone(existingRow)) return;
|
|
30467
30960
|
yield* projectionThreadRepository.upsert({
|
|
30468
30961
|
...existingRow.value,
|
|
30962
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30469
30963
|
latestTurnId: event.payload.turnId,
|
|
30470
30964
|
updatedAt: event.occurredAt
|
|
30471
30965
|
});
|
|
@@ -30488,6 +30982,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
30488
30982
|
}
|
|
30489
30983
|
yield* projectionThreadRepository.upsert({
|
|
30490
30984
|
...existingRow.value,
|
|
30985
|
+
...completionAfterEvent(existingRow.value, event),
|
|
30491
30986
|
latestTurnId,
|
|
30492
30987
|
updatedAt: event.occurredAt
|
|
30493
30988
|
});
|
|
@@ -31014,84 +31509,6 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
|
|
|
31014
31509
|
});
|
|
31015
31510
|
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));
|
|
31016
31511
|
//#endregion
|
|
31017
|
-
//#region src/orchestration/ThreadBackgroundLiveness.ts
|
|
31018
|
-
/**
|
|
31019
|
-
* ThreadBackgroundLivenessService - in-memory per-thread background liveness
|
|
31020
|
-
* for the sidebar status pill.
|
|
31021
|
-
*
|
|
31022
|
-
* The turn can settle while native background work runs on (subagent fleets,
|
|
31023
|
-
* workflow runs, Monitor watch loops); the shell previously showed nothing.
|
|
31024
|
-
* Ingestion records task lifecycle transitions and the shell query reads the
|
|
31025
|
-
* derived state at mapping time — no persistence, no migration. After a
|
|
31026
|
-
* server restart the registry is empty until new task events arrive, which
|
|
31027
|
-
* matches reality: orphaned background work is not live.
|
|
31028
|
-
*
|
|
31029
|
-
* "monitoring" is reserved for watch loops (monitor tasks and background
|
|
31030
|
-
* shells) when they are the ONLY live work; any agent work presents as
|
|
31031
|
-
* "working".
|
|
31032
|
-
*
|
|
31033
|
-
* @module ThreadBackgroundLivenessService
|
|
31034
|
-
*/
|
|
31035
|
-
const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
31036
|
-
"completed",
|
|
31037
|
-
"failed",
|
|
31038
|
-
"stopped",
|
|
31039
|
-
"cancelled",
|
|
31040
|
-
"interrupted"
|
|
31041
|
-
]);
|
|
31042
|
-
var ThreadBackgroundLivenessService = class extends Context.Service()("@p4code/cli/orchestration/ThreadBackgroundLiveness/ThreadBackgroundLivenessService") {};
|
|
31043
|
-
function make$75() {
|
|
31044
|
-
const stateByThreadId = /* @__PURE__ */ new Map();
|
|
31045
|
-
const stateFor = (threadId) => {
|
|
31046
|
-
const existing = stateByThreadId.get(threadId);
|
|
31047
|
-
if (existing) return existing;
|
|
31048
|
-
const created = {
|
|
31049
|
-
agents: /* @__PURE__ */ new Set(),
|
|
31050
|
-
monitors: /* @__PURE__ */ new Set()
|
|
31051
|
-
};
|
|
31052
|
-
stateByThreadId.set(threadId, created);
|
|
31053
|
-
return created;
|
|
31054
|
-
};
|
|
31055
|
-
const drop = (threadId, taskId) => {
|
|
31056
|
-
const state = stateByThreadId.get(threadId);
|
|
31057
|
-
if (!state) return;
|
|
31058
|
-
state.agents.delete(taskId);
|
|
31059
|
-
state.monitors.delete(taskId);
|
|
31060
|
-
if (state.agents.size === 0 && state.monitors.size === 0) stateByThreadId.delete(threadId);
|
|
31061
|
-
};
|
|
31062
|
-
return {
|
|
31063
|
-
recordTaskLiveness: (input) => {
|
|
31064
|
-
const taskType = input.taskType;
|
|
31065
|
-
if (taskType !== void 0 && INERT_TASK_TYPES.has(taskType)) {
|
|
31066
|
-
drop(input.threadId, input.taskId);
|
|
31067
|
-
return;
|
|
31068
|
-
}
|
|
31069
|
-
if (input.agentId !== void 0 && (taskType === void 0 || MONITOR_TASK_TYPES.has(taskType))) {
|
|
31070
|
-
drop(input.threadId, input.taskId);
|
|
31071
|
-
return;
|
|
31072
|
-
}
|
|
31073
|
-
if (input.kind === "completed" || input.status === "idle" || input.status !== void 0 && TERMINAL_STATUSES.has(input.status)) {
|
|
31074
|
-
drop(input.threadId, input.taskId);
|
|
31075
|
-
return;
|
|
31076
|
-
}
|
|
31077
|
-
drop(input.threadId, input.taskId);
|
|
31078
|
-
const state = stateFor(input.threadId);
|
|
31079
|
-
(taskType !== void 0 && MONITOR_TASK_TYPES.has(taskType) ? state.monitors : state.agents).add(input.taskId);
|
|
31080
|
-
},
|
|
31081
|
-
clearThreadLiveness: (threadId) => {
|
|
31082
|
-
stateByThreadId.delete(threadId);
|
|
31083
|
-
},
|
|
31084
|
-
getThreadBackgroundLiveness: (threadId) => {
|
|
31085
|
-
const state = stateByThreadId.get(threadId);
|
|
31086
|
-
if (!state) return null;
|
|
31087
|
-
if (state.agents.size > 0) return "working";
|
|
31088
|
-
if (state.monitors.size > 0) return "monitoring";
|
|
31089
|
-
return null;
|
|
31090
|
-
}
|
|
31091
|
-
};
|
|
31092
|
-
}
|
|
31093
|
-
const layer$64 = Layer.effect(ThreadBackgroundLivenessService, Effect.sync(make$75));
|
|
31094
|
-
//#endregion
|
|
31095
31512
|
//#region src/persistence/Services/ProjectionCheckpoints.ts
|
|
31096
31513
|
/**
|
|
31097
31514
|
* ProjectionCheckpointRepository - Projection repository interface for checkpoints.
|
|
@@ -31659,12 +32076,12 @@ const runProcessCore = Effect.fn("processRunner.runProcessCore")(function* (spaw
|
|
|
31659
32076
|
stderrInvalidUtf8: stderr.invalidUtf8
|
|
31660
32077
|
};
|
|
31661
32078
|
});
|
|
31662
|
-
const make$
|
|
32079
|
+
const make$75 = Effect.fn("ProcessRunner.make")(function* () {
|
|
31663
32080
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
31664
32081
|
const run = (input) => finalizeRunProcess(runProcessCore(spawner, input), input);
|
|
31665
32082
|
return ProcessRunner.of({ run });
|
|
31666
32083
|
});
|
|
31667
|
-
const layer$63 = Layer.effect(ProcessRunner, make$
|
|
32084
|
+
const layer$63 = Layer.effect(ProcessRunner, make$75());
|
|
31668
32085
|
//#endregion
|
|
31669
32086
|
//#region src/project/RepositoryIdentityResolver.ts
|
|
31670
32087
|
const DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY = 512;
|
|
@@ -31755,7 +32172,7 @@ const resolveRepositoryIdentityFromCacheKey = Effect.fn("RepositoryIdentityResol
|
|
|
31755
32172
|
rootPath: cacheKey
|
|
31756
32173
|
}) : null;
|
|
31757
32174
|
});
|
|
31758
|
-
const make$
|
|
32175
|
+
const make$74 = Effect.fn("RepositoryIdentityResolver.make")(function* (options = {}) {
|
|
31759
32176
|
const processRunner = yield* ProcessRunner;
|
|
31760
32177
|
const repositoryIdentityCache = yield* Cache.makeWith((cacheKey) => resolveRepositoryIdentityFromCacheKey(cacheKey).pipe(Effect.provideService(ProcessRunner, processRunner)), {
|
|
31761
32178
|
capacity: options.cacheCapacity ?? DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY,
|
|
@@ -31770,7 +32187,7 @@ const make$73 = Effect.fn("RepositoryIdentityResolver.make")(function* (options
|
|
|
31770
32187
|
});
|
|
31771
32188
|
return RepositoryIdentityResolver.of({ resolve });
|
|
31772
32189
|
});
|
|
31773
|
-
const layer$62 = Layer.effect(RepositoryIdentityResolver, make$
|
|
32190
|
+
const layer$62 = Layer.effect(RepositoryIdentityResolver, make$74()).pipe(Layer.provide(layer$63));
|
|
31774
32191
|
//#endregion
|
|
31775
32192
|
//#region src/orchestration/Layers/ProjectionSnapshotQuery.ts
|
|
31776
32193
|
const decodeReadModel = Schema$1.decodeUnknownEffect(OrchestrationReadModel);
|
|
@@ -32126,6 +32543,10 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32126
32543
|
archived_at AS "archivedAt",
|
|
32127
32544
|
settled_override AS "settledOverride",
|
|
32128
32545
|
settled_at AS "settledAt",
|
|
32546
|
+
lifecycle AS "lifecycle",
|
|
32547
|
+
lifecycle_reason AS "lifecycleReason",
|
|
32548
|
+
lifecycle_changed_at AS "lifecycleChangedAt",
|
|
32549
|
+
last_engaged_at AS "lastEngagedAt",
|
|
32129
32550
|
snoozed_until AS "snoozedUntil",
|
|
32130
32551
|
snoozed_at AS "snoozedAt",
|
|
32131
32552
|
pinned_at AS "pinnedAt",
|
|
@@ -32163,6 +32584,10 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32163
32584
|
archived_at AS "archivedAt",
|
|
32164
32585
|
settled_override AS "settledOverride",
|
|
32165
32586
|
settled_at AS "settledAt",
|
|
32587
|
+
lifecycle AS "lifecycle",
|
|
32588
|
+
lifecycle_reason AS "lifecycleReason",
|
|
32589
|
+
lifecycle_changed_at AS "lifecycleChangedAt",
|
|
32590
|
+
last_engaged_at AS "lastEngagedAt",
|
|
32166
32591
|
snoozed_until AS "snoozedUntil",
|
|
32167
32592
|
snoozed_at AS "snoozedAt",
|
|
32168
32593
|
pinned_at AS "pinnedAt",
|
|
@@ -32202,6 +32627,10 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32202
32627
|
archived_at AS "archivedAt",
|
|
32203
32628
|
settled_override AS "settledOverride",
|
|
32204
32629
|
settled_at AS "settledAt",
|
|
32630
|
+
lifecycle AS "lifecycle",
|
|
32631
|
+
lifecycle_reason AS "lifecycleReason",
|
|
32632
|
+
lifecycle_changed_at AS "lifecycleChangedAt",
|
|
32633
|
+
last_engaged_at AS "lastEngagedAt",
|
|
32205
32634
|
snoozed_until AS "snoozedUntil",
|
|
32206
32635
|
snoozed_at AS "snoozedAt",
|
|
32207
32636
|
pinned_at AS "pinnedAt",
|
|
@@ -32666,6 +33095,10 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
32666
33095
|
archived_at AS "archivedAt",
|
|
32667
33096
|
settled_override AS "settledOverride",
|
|
32668
33097
|
settled_at AS "settledAt",
|
|
33098
|
+
lifecycle AS "lifecycle",
|
|
33099
|
+
lifecycle_reason AS "lifecycleReason",
|
|
33100
|
+
lifecycle_changed_at AS "lifecycleChangedAt",
|
|
33101
|
+
last_engaged_at AS "lastEngagedAt",
|
|
32669
33102
|
snoozed_until AS "snoozedUntil",
|
|
32670
33103
|
snoozed_at AS "snoozedAt",
|
|
32671
33104
|
pinned_at AS "pinnedAt",
|
|
@@ -33358,6 +33791,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
33358
33791
|
archivedAt: row.archivedAt,
|
|
33359
33792
|
settledOverride: row.settledOverride,
|
|
33360
33793
|
settledAt: row.settledAt,
|
|
33794
|
+
lifecycle: row.lifecycle,
|
|
33795
|
+
lifecycleReason: row.lifecycleReason,
|
|
33796
|
+
lifecycleChangedAt: row.lifecycleChangedAt,
|
|
33797
|
+
lastEngagedAt: row.lastEngagedAt,
|
|
33798
|
+
doneAt: row.settledAt,
|
|
33361
33799
|
snoozedUntil: row.snoozedUntil,
|
|
33362
33800
|
snoozedAt: row.snoozedAt,
|
|
33363
33801
|
pinnedAt: row.pinnedAt,
|
|
@@ -33501,6 +33939,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
33501
33939
|
archivedAt: row.archivedAt,
|
|
33502
33940
|
settledOverride: row.settledOverride,
|
|
33503
33941
|
settledAt: row.settledAt,
|
|
33942
|
+
lifecycle: row.lifecycle,
|
|
33943
|
+
lifecycleReason: row.lifecycleReason,
|
|
33944
|
+
lifecycleChangedAt: row.lifecycleChangedAt,
|
|
33945
|
+
lastEngagedAt: row.lastEngagedAt,
|
|
33946
|
+
doneAt: row.settledAt,
|
|
33504
33947
|
snoozedUntil: row.snoozedUntil,
|
|
33505
33948
|
snoozedAt: row.snoozedAt,
|
|
33506
33949
|
pinnedAt: row.pinnedAt,
|
|
@@ -33567,6 +34010,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
33567
34010
|
archivedAt: row.archivedAt,
|
|
33568
34011
|
settledOverride: row.settledOverride,
|
|
33569
34012
|
settledAt: row.settledAt,
|
|
34013
|
+
lifecycle: row.lifecycle,
|
|
34014
|
+
lifecycleReason: row.lifecycleReason,
|
|
34015
|
+
lifecycleChangedAt: row.lifecycleChangedAt,
|
|
34016
|
+
lastEngagedAt: row.lastEngagedAt,
|
|
34017
|
+
doneAt: row.settledAt,
|
|
33570
34018
|
snoozedUntil: row.snoozedUntil,
|
|
33571
34019
|
snoozedAt: row.snoozedAt,
|
|
33572
34020
|
pinnedAt: row.pinnedAt,
|
|
@@ -33633,6 +34081,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
33633
34081
|
archivedAt: row.archivedAt,
|
|
33634
34082
|
settledOverride: row.settledOverride,
|
|
33635
34083
|
settledAt: row.settledAt,
|
|
34084
|
+
lifecycle: row.lifecycle,
|
|
34085
|
+
lifecycleReason: row.lifecycleReason,
|
|
34086
|
+
lifecycleChangedAt: row.lifecycleChangedAt,
|
|
34087
|
+
lastEngagedAt: row.lastEngagedAt,
|
|
34088
|
+
doneAt: row.settledAt,
|
|
33636
34089
|
snoozedUntil: row.snoozedUntil,
|
|
33637
34090
|
snoozedAt: row.snoozedAt,
|
|
33638
34091
|
pinnedAt: row.pinnedAt,
|
|
@@ -33747,6 +34200,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
33747
34200
|
archivedAt: threadRow.value.archivedAt,
|
|
33748
34201
|
settledOverride: threadRow.value.settledOverride,
|
|
33749
34202
|
settledAt: threadRow.value.settledAt,
|
|
34203
|
+
lifecycle: threadRow.value.lifecycle,
|
|
34204
|
+
lifecycleReason: threadRow.value.lifecycleReason,
|
|
34205
|
+
lifecycleChangedAt: threadRow.value.lifecycleChangedAt,
|
|
34206
|
+
lastEngagedAt: threadRow.value.lastEngagedAt,
|
|
34207
|
+
doneAt: threadRow.value.settledAt,
|
|
33750
34208
|
snoozedUntil: threadRow.value.snoozedUntil,
|
|
33751
34209
|
snoozedAt: threadRow.value.snoozedAt,
|
|
33752
34210
|
pinnedAt: threadRow.value.pinnedAt,
|
|
@@ -33814,6 +34272,11 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
33814
34272
|
archivedAt: threadRow.value.archivedAt,
|
|
33815
34273
|
settledOverride: threadRow.value.settledOverride,
|
|
33816
34274
|
settledAt: threadRow.value.settledAt,
|
|
34275
|
+
lifecycle: threadRow.value.lifecycle,
|
|
34276
|
+
lifecycleReason: threadRow.value.lifecycleReason,
|
|
34277
|
+
lifecycleChangedAt: threadRow.value.lifecycleChangedAt,
|
|
34278
|
+
lastEngagedAt: threadRow.value.lastEngagedAt,
|
|
34279
|
+
doneAt: threadRow.value.settledAt,
|
|
33817
34280
|
snoozedUntil: threadRow.value.snoozedUntil,
|
|
33818
34281
|
snoozedAt: threadRow.value.snoozedAt,
|
|
33819
34282
|
pinnedAt: threadRow.value.pinnedAt,
|
|
@@ -33939,9 +34402,185 @@ const OrchestrationProjectionSnapshotQueryLive = Layer.effect(ProjectionSnapshot
|
|
|
33939
34402
|
//#region src/orchestration/Services/ThreadEventStream.ts
|
|
33940
34403
|
var ThreadEventStreamService = class extends Context.Service()("@p4code/cli/orchestration/Services/ThreadEventStream/ThreadEventStreamService") {};
|
|
33941
34404
|
//#endregion
|
|
34405
|
+
//#region src/orchestration/ThreadReviewProjection.ts
|
|
34406
|
+
const isMessagePayload = Schema$1.is(ThreadMessageSentPayload);
|
|
34407
|
+
const MAX_MESSAGE_IDENTITY_LENGTH = 1024;
|
|
34408
|
+
const MAX_PREVIEW_DEPTH = 12;
|
|
34409
|
+
const MAX_PREVIEW_NODES = 512;
|
|
34410
|
+
const TRUNCATION_MARKER$1 = "\n[truncated; recover source events]\n";
|
|
34411
|
+
function excerpt(text, length) {
|
|
34412
|
+
if (text.length <= length) return text;
|
|
34413
|
+
const sideLength = Math.max(0, Math.floor((length - 36) / 2));
|
|
34414
|
+
return text.slice(0, sideLength).replace(/[\uD800-\uDBFF]$/, "") + TRUNCATION_MARKER$1 + (sideLength > 0 ? text.slice(-sideLength).replace(/^[\uDC00-\uDFFF]/, "") : "");
|
|
34415
|
+
}
|
|
34416
|
+
/** Serialize only a bounded prefix, without walking or copying an oversized tool result. */
|
|
34417
|
+
function payloadPreview(payload) {
|
|
34418
|
+
let remainingNodes = MAX_PREVIEW_NODES;
|
|
34419
|
+
function* parts(value, depth) {
|
|
34420
|
+
if (--remainingNodes < 0 || depth > MAX_PREVIEW_DEPTH) {
|
|
34421
|
+
yield TRUNCATION_MARKER$1;
|
|
34422
|
+
return;
|
|
34423
|
+
}
|
|
34424
|
+
if (typeof value === "string") yield JSON.stringify(excerpt(value, THREAD_REVIEW_ITEM_MAX_BYTES));
|
|
34425
|
+
else if (value === null || typeof value !== "object") yield JSON.stringify(value) ?? "null";
|
|
34426
|
+
else {
|
|
34427
|
+
const array = Array.isArray(value);
|
|
34428
|
+
yield array ? "[" : "{";
|
|
34429
|
+
let first = true;
|
|
34430
|
+
for (const key in value) {
|
|
34431
|
+
if (!Object.hasOwn(value, key)) continue;
|
|
34432
|
+
if (remainingNodes <= 0) {
|
|
34433
|
+
yield TRUNCATION_MARKER$1;
|
|
34434
|
+
break;
|
|
34435
|
+
}
|
|
34436
|
+
if (!first) yield ",";
|
|
34437
|
+
first = false;
|
|
34438
|
+
if (!array) yield JSON.stringify(excerpt(key, THREAD_REVIEW_ITEM_MAX_BYTES)) + ":";
|
|
34439
|
+
yield* parts(value[key], depth + 1);
|
|
34440
|
+
}
|
|
34441
|
+
yield array ? "]" : "}";
|
|
34442
|
+
}
|
|
34443
|
+
}
|
|
34444
|
+
let text = "";
|
|
34445
|
+
let truncated = false;
|
|
34446
|
+
for (const part of parts(payload, 0)) {
|
|
34447
|
+
if (part.includes(TRUNCATION_MARKER$1) || part.includes(JSON.stringify(TRUNCATION_MARKER$1).slice(1, -1))) truncated = true;
|
|
34448
|
+
const remaining = THREAD_REVIEW_ITEM_MAX_BYTES - text.length;
|
|
34449
|
+
if (part.length > remaining) {
|
|
34450
|
+
text += part.slice(0, remaining);
|
|
34451
|
+
truncated = true;
|
|
34452
|
+
break;
|
|
34453
|
+
}
|
|
34454
|
+
text += part;
|
|
34455
|
+
}
|
|
34456
|
+
return {
|
|
34457
|
+
text,
|
|
34458
|
+
truncated
|
|
34459
|
+
};
|
|
34460
|
+
}
|
|
34461
|
+
function fitItem(item) {
|
|
34462
|
+
let result = item;
|
|
34463
|
+
let bytes = Buffer.byteLength(JSON.stringify(result));
|
|
34464
|
+
while (bytes > THREAD_REVIEW_ITEM_MAX_BYTES) {
|
|
34465
|
+
const text = result.kind === "message" ? result.text : result.payload;
|
|
34466
|
+
const length = Math.max(36, Math.floor(text.length / 2));
|
|
34467
|
+
result = result.kind === "message" ? {
|
|
34468
|
+
...result,
|
|
34469
|
+
text: excerpt(text, length),
|
|
34470
|
+
truncated: true
|
|
34471
|
+
} : {
|
|
34472
|
+
...result,
|
|
34473
|
+
payload: excerpt(text, length),
|
|
34474
|
+
truncated: true
|
|
34475
|
+
};
|
|
34476
|
+
bytes = Buffer.byteLength(JSON.stringify(result));
|
|
34477
|
+
}
|
|
34478
|
+
return result;
|
|
34479
|
+
}
|
|
34480
|
+
/** Page-local folds follow the projector: streaming appends; nonempty completion replaces. */
|
|
34481
|
+
function createThreadReviewPage(input) {
|
|
34482
|
+
const items = [];
|
|
34483
|
+
const messageIndexes = /* @__PURE__ */ new Map();
|
|
34484
|
+
let nextAfterSequence = input.afterSequence;
|
|
34485
|
+
let scannedEvents = 0;
|
|
34486
|
+
let itemBytes = 0;
|
|
34487
|
+
const envelopeBytes = Buffer.byteLength(JSON.stringify({
|
|
34488
|
+
threadId: input.threadId,
|
|
34489
|
+
items: [],
|
|
34490
|
+
throughSequence: input.throughSequence,
|
|
34491
|
+
nextAfterSequence: Number.MAX_SAFE_INTEGER,
|
|
34492
|
+
hasMore: false,
|
|
34493
|
+
scannedEvents: Number.MAX_SAFE_INTEGER
|
|
34494
|
+
}));
|
|
34495
|
+
function offer(event, sourceTruncated = false) {
|
|
34496
|
+
if (event.sequence > input.throughSequence) return false;
|
|
34497
|
+
if (event.aggregateKind !== "thread" || event.aggregateId !== input.threadId) {
|
|
34498
|
+
nextAfterSequence = event.sequence;
|
|
34499
|
+
scannedEvents += 1;
|
|
34500
|
+
return true;
|
|
34501
|
+
}
|
|
34502
|
+
let item;
|
|
34503
|
+
let index;
|
|
34504
|
+
let messageKey;
|
|
34505
|
+
if (event.type === "thread.message-sent" && !sourceTruncated && isMessagePayload(event.payload) && event.payload.role === "assistant" && !event.payload.attachments?.length && event.payload.messageId.length + (event.payload.turnId?.length ?? 0) <= MAX_MESSAGE_IDENTITY_LENGTH) {
|
|
34506
|
+
const payload = event.payload;
|
|
34507
|
+
messageKey = JSON.stringify([payload.turnId, payload.messageId]);
|
|
34508
|
+
index = messageIndexes.get(messageKey);
|
|
34509
|
+
const previous = index === void 0 ? void 0 : items[index];
|
|
34510
|
+
const previousMessage = previous?.kind === "message" ? previous : void 0;
|
|
34511
|
+
const replaces = !payload.streaming && payload.text.length > 0;
|
|
34512
|
+
const part = excerpt(payload.text, THREAD_REVIEW_ITEM_MAX_BYTES);
|
|
34513
|
+
item = fitItem({
|
|
34514
|
+
kind: "message",
|
|
34515
|
+
firstSequence: previousMessage?.firstSequence ?? event.sequence,
|
|
34516
|
+
lastSequence: event.sequence,
|
|
34517
|
+
messageId: payload.messageId,
|
|
34518
|
+
turnId: payload.turnId,
|
|
34519
|
+
role: payload.role,
|
|
34520
|
+
operation: replaces ? "replace" : previousMessage?.operation ?? "append",
|
|
34521
|
+
complete: !payload.streaming,
|
|
34522
|
+
text: replaces ? part : (previousMessage?.text ?? "") + part,
|
|
34523
|
+
truncated: part !== payload.text || !replaces && (previousMessage?.truncated ?? false)
|
|
34524
|
+
});
|
|
34525
|
+
} else {
|
|
34526
|
+
const preview = sourceTruncated && typeof event.payload === "string" ? {
|
|
34527
|
+
text: event.payload,
|
|
34528
|
+
truncated: true
|
|
34529
|
+
} : payloadPreview(event.payload);
|
|
34530
|
+
item = fitItem({
|
|
34531
|
+
kind: "event",
|
|
34532
|
+
type: event.type,
|
|
34533
|
+
firstSequence: event.sequence,
|
|
34534
|
+
lastSequence: event.sequence,
|
|
34535
|
+
payload: preview.text,
|
|
34536
|
+
truncated: preview.truncated
|
|
34537
|
+
});
|
|
34538
|
+
}
|
|
34539
|
+
const previousBytes = index === void 0 ? 0 : Buffer.byteLength(JSON.stringify(items[index]));
|
|
34540
|
+
const nextBytes = itemBytes - previousBytes + Buffer.byteLength(JSON.stringify(item));
|
|
34541
|
+
if (index === void 0 && items.length >= 100 || envelopeBytes + nextBytes + items.length + 1 > 48e3) return false;
|
|
34542
|
+
if (index === void 0) {
|
|
34543
|
+
if (messageKey !== void 0) messageIndexes.set(messageKey, items.length);
|
|
34544
|
+
items.push(item);
|
|
34545
|
+
} else items[index] = item;
|
|
34546
|
+
itemBytes = nextBytes;
|
|
34547
|
+
nextAfterSequence = event.sequence;
|
|
34548
|
+
scannedEvents += 1;
|
|
34549
|
+
return true;
|
|
34550
|
+
}
|
|
34551
|
+
return {
|
|
34552
|
+
offer,
|
|
34553
|
+
offerStored(row) {
|
|
34554
|
+
if (row.payloadJson.length <= 8e3) try {
|
|
34555
|
+
return offer({
|
|
34556
|
+
...row,
|
|
34557
|
+
payload: JSON.parse(row.payloadJson)
|
|
34558
|
+
});
|
|
34559
|
+
} catch {}
|
|
34560
|
+
return offer({
|
|
34561
|
+
...row,
|
|
34562
|
+
payload: row.payloadJson.slice(0, THREAD_REVIEW_ITEM_MAX_BYTES)
|
|
34563
|
+
}, true);
|
|
34564
|
+
},
|
|
34565
|
+
finish(exhausted) {
|
|
34566
|
+
if (exhausted) nextAfterSequence = Math.max(nextAfterSequence, input.throughSequence);
|
|
34567
|
+
return {
|
|
34568
|
+
threadId: input.threadId,
|
|
34569
|
+
items: items.toSorted((a, b) => a.lastSequence - b.lastSequence),
|
|
34570
|
+
throughSequence: input.throughSequence,
|
|
34571
|
+
nextAfterSequence,
|
|
34572
|
+
hasMore: nextAfterSequence < input.throughSequence,
|
|
34573
|
+
scannedEvents
|
|
34574
|
+
};
|
|
34575
|
+
}
|
|
34576
|
+
};
|
|
34577
|
+
}
|
|
34578
|
+
//#endregion
|
|
33942
34579
|
//#region src/orchestration/Layers/ThreadEventStream.ts
|
|
34580
|
+
const REVIEW_SOURCE_PAGE_SIZE = 100;
|
|
33943
34581
|
const makeThreadEventStream = Effect.gen(function* () {
|
|
33944
34582
|
const engine = yield* OrchestrationEngineService;
|
|
34583
|
+
const eventStore = yield* OrchestrationEventStore;
|
|
33945
34584
|
const isThreadEvent = (threadId) => (event) => event.aggregateKind === "thread" && event.aggregateId === threadId;
|
|
33946
34585
|
const watch = (input) => Stream.unwrap(Effect.gen(function* () {
|
|
33947
34586
|
const matchesThread = isThreadEvent(input.threadId);
|
|
@@ -33983,9 +34622,38 @@ const makeThreadEventStream = Effect.gen(function* () {
|
|
|
33983
34622
|
hasMore
|
|
33984
34623
|
};
|
|
33985
34624
|
});
|
|
34625
|
+
const readReview = Effect.fn("ThreadEventStream.readReview")(function* (input) {
|
|
34626
|
+
const headSequence = yield* engine.latestSequence;
|
|
34627
|
+
const throughSequence = Math.min(input.throughSequence ?? headSequence, headSequence);
|
|
34628
|
+
const afterSequence = input.afterSequence ?? 0;
|
|
34629
|
+
const page = createThreadReviewPage({
|
|
34630
|
+
threadId: input.threadId,
|
|
34631
|
+
afterSequence,
|
|
34632
|
+
throughSequence
|
|
34633
|
+
});
|
|
34634
|
+
if (afterSequence >= throughSequence) return page.finish(true);
|
|
34635
|
+
let cursor = afterSequence;
|
|
34636
|
+
let scanned = 0;
|
|
34637
|
+
while (scanned < 2e3 && cursor < throughSequence) {
|
|
34638
|
+
const limit = Math.min(REVIEW_SOURCE_PAGE_SIZE, THREAD_REVIEW_SCAN_LIMIT - scanned);
|
|
34639
|
+
const rows = yield* eventStore.readReviewPage({
|
|
34640
|
+
afterSequence: cursor,
|
|
34641
|
+
throughSequence,
|
|
34642
|
+
limit
|
|
34643
|
+
});
|
|
34644
|
+
for (const row of rows) {
|
|
34645
|
+
if (!page.offerStored(row)) return page.finish(false);
|
|
34646
|
+
cursor = row.sequence;
|
|
34647
|
+
scanned += 1;
|
|
34648
|
+
}
|
|
34649
|
+
if (rows.length < limit) return page.finish(true);
|
|
34650
|
+
}
|
|
34651
|
+
return page.finish(false);
|
|
34652
|
+
});
|
|
33986
34653
|
return ThreadEventStreamService.of({
|
|
33987
34654
|
watch,
|
|
33988
|
-
read
|
|
34655
|
+
read,
|
|
34656
|
+
readReview
|
|
33989
34657
|
});
|
|
33990
34658
|
});
|
|
33991
34659
|
const ThreadEventStreamLive = Layer.effect(ThreadEventStreamService, makeThreadEventStream);
|
|
@@ -34002,7 +34670,7 @@ const OrchestrationProjectionPipelineLayerLive = OrchestrationProjectionPipeline
|
|
|
34002
34670
|
const ThreadBackgroundLivenessLayerLive = layer$64;
|
|
34003
34671
|
const OrchestrationInfrastructureLayerLive = Layer.mergeAll(OrchestrationProjectionSnapshotQueryLive, OrchestrationEventInfrastructureLayerLive, OrchestrationProjectionPipelineLayerLive, ThreadBackgroundLivenessLayerLive);
|
|
34004
34672
|
const OrchestrationEngineLayerLive = OrchestrationEngineLive.pipe(Layer.provide(OrchestrationInfrastructureLayerLive));
|
|
34005
|
-
const OrchestrationLayerLive = Layer.mergeAll(OrchestrationInfrastructureLayerLive, OrchestrationEngineLayerLive, ThreadEventStreamLive.pipe(Layer.provide(OrchestrationEngineLayerLive)));
|
|
34673
|
+
const OrchestrationLayerLive = Layer.mergeAll(OrchestrationInfrastructureLayerLive, OrchestrationEngineLayerLive, ThreadEventStreamLive.pipe(Layer.provide(OrchestrationEngineLayerLive), Layer.provide(OrchestrationEventStoreLive)));
|
|
34006
34674
|
//#endregion
|
|
34007
34675
|
//#region ../../packages/shared/src/keybindings.ts
|
|
34008
34676
|
const DEFAULT_KEYBINDINGS = [
|
|
@@ -34474,7 +35142,7 @@ function mergeWithDefaultKeybindings(custom) {
|
|
|
34474
35142
|
* Keybindings - Service tag for keybinding configuration operations.
|
|
34475
35143
|
*/
|
|
34476
35144
|
var Keybindings = class extends Context.Service()("@p4code/cli/keybindings") {};
|
|
34477
|
-
const make$
|
|
35145
|
+
const make$73 = Effect.gen(function* () {
|
|
34478
35146
|
const { keybindingsConfigPath } = yield* ServerConfig$1;
|
|
34479
35147
|
const fs = yield* FileSystem.FileSystem;
|
|
34480
35148
|
const path = yield* Path.Path;
|
|
@@ -34735,7 +35403,7 @@ const make$72 = Effect.gen(function* () {
|
|
|
34735
35403
|
}))
|
|
34736
35404
|
};
|
|
34737
35405
|
});
|
|
34738
|
-
const layer$61 = Layer.effect(Keybindings, make$
|
|
35406
|
+
const layer$61 = Layer.effect(Keybindings, make$73);
|
|
34739
35407
|
//#endregion
|
|
34740
35408
|
//#region src/process/externalLauncher.ts
|
|
34741
35409
|
/**
|
|
@@ -34962,7 +35630,7 @@ const launchEditorProcess = Effect.fn("externalLauncher.launchEditorProcess")(fu
|
|
|
34962
35630
|
cause
|
|
34963
35631
|
}));
|
|
34964
35632
|
});
|
|
34965
|
-
const make$
|
|
35633
|
+
const make$72 = Effect.gen(function* () {
|
|
34966
35634
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
34967
35635
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
34968
35636
|
const path = yield* Path.Path;
|
|
@@ -34973,7 +35641,7 @@ const make$71 = Effect.gen(function* () {
|
|
|
34973
35641
|
launchEditor: (input) => provideCommandResolutionServices(Effect.flatMap(resolveEditorLaunch(input), (launch) => launchEditorProcess(launch).pipe(Effect.provideService(ChildProcessSpawner$1.ChildProcessSpawner, spawner))))
|
|
34974
35642
|
});
|
|
34975
35643
|
});
|
|
34976
|
-
const layer$60 = Layer.effect(ExternalLauncher, make$
|
|
35644
|
+
const layer$60 = Layer.effect(ExternalLauncher, make$72);
|
|
34977
35645
|
//#endregion
|
|
34978
35646
|
//#region src/orchestration/Services/OrchestrationReactor.ts
|
|
34979
35647
|
/**
|
|
@@ -34991,7 +35659,7 @@ var OrchestrationReactor = class extends Context.Service()("@p4code/cli/orchestr
|
|
|
34991
35659
|
//#endregion
|
|
34992
35660
|
//#region src/serverLifecycleEvents.ts
|
|
34993
35661
|
var ServerLifecycleEvents = class extends Context.Service()("@p4code/cli/serverLifecycleEvents") {};
|
|
34994
|
-
const make$
|
|
35662
|
+
const make$71 = Effect.gen(function* () {
|
|
34995
35663
|
const pubsub = yield* PubSub.unbounded();
|
|
34996
35664
|
const state = yield* Ref.make({
|
|
34997
35665
|
sequence: 0,
|
|
@@ -35015,7 +35683,7 @@ const make$70 = Effect.gen(function* () {
|
|
|
35015
35683
|
}
|
|
35016
35684
|
};
|
|
35017
35685
|
});
|
|
35018
|
-
const layer$59 = Layer.effect(ServerLifecycleEvents, make$
|
|
35686
|
+
const layer$59 = Layer.effect(ServerLifecycleEvents, make$71);
|
|
35019
35687
|
//#endregion
|
|
35020
35688
|
//#region src/telemetry/Identify.ts
|
|
35021
35689
|
const CodexAuthJsonSchema = Schema$1.Struct({ tokens: Schema$1.Struct({ account_id: Schema$1.String }) });
|
|
@@ -35188,7 +35856,7 @@ var AnalyticsService = class AnalyticsService extends Context.Service()("@p4code
|
|
|
35188
35856
|
/** No-op layer for callers that intentionally disable telemetry. */
|
|
35189
35857
|
static layerTest = Layer.succeed(AnalyticsService, inert);
|
|
35190
35858
|
};
|
|
35191
|
-
const make$
|
|
35859
|
+
const make$70 = Effect.gen(function* () {
|
|
35192
35860
|
const telemetryConfig = yield* TelemetryEnvConfig;
|
|
35193
35861
|
const posthogKey = telemetryConfig.posthogKey.trim();
|
|
35194
35862
|
if (!telemetryConfig.enabled || posthogKey === "") return inert;
|
|
@@ -35258,7 +35926,7 @@ const make$69 = Effect.gen(function* () {
|
|
|
35258
35926
|
flush
|
|
35259
35927
|
});
|
|
35260
35928
|
});
|
|
35261
|
-
const layer$58 = Layer.effect(AnalyticsService, make$
|
|
35929
|
+
const layer$58 = Layer.effect(AnalyticsService, make$70);
|
|
35262
35930
|
AnalyticsService.layerTest;
|
|
35263
35931
|
//#endregion
|
|
35264
35932
|
//#region src/service/pinnedRuntime.ts
|
|
@@ -35605,7 +36273,7 @@ var BootServiceInstallError = class extends Schema$1.TaggedErrorClass()("BootSer
|
|
|
35605
36273
|
}
|
|
35606
36274
|
};
|
|
35607
36275
|
var BootService = class extends Context.Service()("@p4code/cli/service/bootService") {};
|
|
35608
|
-
const make$
|
|
36276
|
+
const make$69 = Effect.fn("cloud.boot_service.make")(function* (input) {
|
|
35609
36277
|
const hostExecPath = yield* HostProcessExecutablePath;
|
|
35610
36278
|
const hostArguments = yield* HostProcessArguments;
|
|
35611
36279
|
const host = input.host ?? {
|
|
@@ -35827,7 +36495,7 @@ const make$68 = Effect.fn("cloud.boot_service.make")(function* (input) {
|
|
|
35827
36495
|
logPath
|
|
35828
36496
|
});
|
|
35829
36497
|
});
|
|
35830
|
-
const layer$57 = (input) => Layer.effect(BootService, make$
|
|
36498
|
+
const layer$57 = (input) => Layer.effect(BootService, make$69(input));
|
|
35831
36499
|
//#endregion
|
|
35832
36500
|
//#region src/service/selfUpdate.ts
|
|
35833
36501
|
/**
|
|
@@ -35902,7 +36570,7 @@ const resolveServerSelfUpdateCapability = Effect.fn("cloud.server_self_update.re
|
|
|
35902
36570
|
return null;
|
|
35903
36571
|
});
|
|
35904
36572
|
var ServerSelfUpdate = class extends Context.Service()("@p4code/cli/service/selfUpdate/ServerSelfUpdate") {};
|
|
35905
|
-
const make$
|
|
36573
|
+
const make$68 = Effect.fn("cloud.server_self_update.make")(function* (options) {
|
|
35906
36574
|
const serverConfig = yield* ServerConfig$1;
|
|
35907
36575
|
const fs = yield* FileSystem.FileSystem;
|
|
35908
36576
|
const path = yield* Path.Path;
|
|
@@ -36052,7 +36720,7 @@ const make$67 = Effect.fn("cloud.server_self_update.make")(function* (options) {
|
|
|
36052
36720
|
});
|
|
36053
36721
|
return ServerSelfUpdate.of({ update });
|
|
36054
36722
|
});
|
|
36055
|
-
const layer$56 = Layer.effect(ServerSelfUpdate, make$
|
|
36723
|
+
const layer$56 = Layer.effect(ServerSelfUpdate, make$68()).pipe(Layer.provide(layer$63));
|
|
36056
36724
|
//#endregion
|
|
36057
36725
|
//#region src/environment/ServerEnvironmentLabel.ts
|
|
36058
36726
|
const ServerEnvironmentLabelCommandProbe = Schema$1.Literals(["macos-computer-name", "linux-pretty-hostname"]);
|
|
@@ -36184,7 +36852,7 @@ function platformArch(architecture) {
|
|
|
36184
36852
|
default: return "other";
|
|
36185
36853
|
}
|
|
36186
36854
|
}
|
|
36187
|
-
const make$
|
|
36855
|
+
const make$67 = Effect.gen(function* () {
|
|
36188
36856
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
36189
36857
|
const path = yield* Path.Path;
|
|
36190
36858
|
const serverConfig = yield* ServerConfig$1;
|
|
@@ -36233,6 +36901,7 @@ const make$66 = Effect.gen(function* () {
|
|
|
36233
36901
|
connectionProbe: true,
|
|
36234
36902
|
pullRequests: true,
|
|
36235
36903
|
threadSettlement: true,
|
|
36904
|
+
threadLifecycleV2: true,
|
|
36236
36905
|
threadSnooze: true,
|
|
36237
36906
|
threadPinning: true,
|
|
36238
36907
|
threadFork: true,
|
|
@@ -36251,7 +36920,7 @@ const make$66 = Effect.gen(function* () {
|
|
|
36251
36920
|
* state. It intentionally has no fallback Layer.succeed value: callers must
|
|
36252
36921
|
* provide the external platform services and a ServerConfig.
|
|
36253
36922
|
*/
|
|
36254
|
-
const layer$55 = Layer.effect(ServerEnvironment, make$
|
|
36923
|
+
const layer$55 = Layer.effect(ServerEnvironment, make$67).pipe(Layer.provide(layer$63));
|
|
36255
36924
|
//#endregion
|
|
36256
36925
|
//#region src/provider/Services/ProviderSessionReaper.ts
|
|
36257
36926
|
var ProviderSessionReaper = class extends Context.Service()("@p4code/cli/provider/Services/ProviderSessionReaper") {};
|
|
@@ -36393,7 +37062,7 @@ const maybeOpenBrowser = (target) => Effect.gen(function* () {
|
|
|
36393
37062
|
yield* (yield* ExternalLauncher).launchBrowser(target).pipe(Effect.catch(() => Effect.logInfo("browser auto-open unavailable", { hint: `Open ${target} in your browser.` })));
|
|
36394
37063
|
});
|
|
36395
37064
|
const runStartupPhase = (phase, effect) => effect.pipe(Effect.annotateSpans({ "startup.phase": phase }), Effect.withSpan(`server.startup.${phase}`));
|
|
36396
|
-
const make$
|
|
37065
|
+
const make$66 = Effect.gen(function* () {
|
|
36397
37066
|
const serverConfig = yield* ServerConfig$1;
|
|
36398
37067
|
const keybindings = yield* Keybindings;
|
|
36399
37068
|
const orchestrationReactor = yield* OrchestrationReactor;
|
|
@@ -36534,7 +37203,7 @@ const make$65 = Effect.gen(function* () {
|
|
|
36534
37203
|
enqueueCommand: commandGate.enqueueCommand
|
|
36535
37204
|
};
|
|
36536
37205
|
});
|
|
36537
|
-
const layer$54 = Layer.effect(ServerRuntimeStartup, make$
|
|
37206
|
+
const layer$54 = Layer.effect(ServerRuntimeStartup, make$66);
|
|
36538
37207
|
//#endregion
|
|
36539
37208
|
//#region src/serverRuntimeState.ts
|
|
36540
37209
|
const PersistedServerRuntimeState = Schema$1.Struct({
|
|
@@ -36691,7 +37360,7 @@ function expandHomePath$2(input, path) {
|
|
|
36691
37360
|
if (input.startsWith("~/") || input.startsWith("~\\")) return path.join(NodeOS.homedir(), input.slice(2));
|
|
36692
37361
|
return input;
|
|
36693
37362
|
}
|
|
36694
|
-
const make$
|
|
37363
|
+
const make$65 = Effect.gen(function* () {
|
|
36695
37364
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
36696
37365
|
const path = yield* Path.Path;
|
|
36697
37366
|
const statWorkspaceRoot = Effect.fn("WorkspacePaths.statWorkspaceRoot")(function* (workspaceRoot, normalizedWorkspaceRoot, phase) {
|
|
@@ -36748,7 +37417,7 @@ const make$64 = Effect.gen(function* () {
|
|
|
36748
37417
|
resolveRelativePathWithinRoot
|
|
36749
37418
|
});
|
|
36750
37419
|
});
|
|
36751
|
-
const layer$53 = Layer.effect(WorkspacePaths, make$
|
|
37420
|
+
const layer$53 = Layer.effect(WorkspacePaths, make$65);
|
|
36752
37421
|
//#endregion
|
|
36753
37422
|
//#region src/cli/project.ts
|
|
36754
37423
|
const isEnvironmentHttpCommonError = Schema$1.is(EnvironmentHttpCommonError);
|
|
@@ -36883,7 +37552,7 @@ const findActiveProjectTarget = Effect.fn("findActiveProjectTarget")(function* (
|
|
|
36883
37552
|
operation: "resolveProjectTarget",
|
|
36884
37553
|
identifier: input.identifier
|
|
36885
37554
|
});
|
|
36886
|
-
const activeProjects = input.snapshot.projects.filter((project) => project.deletedAt
|
|
37555
|
+
const activeProjects = input.snapshot.projects.filter((project) => project.deletedAt == null);
|
|
36887
37556
|
const exactIdMatch = activeProjects.find((project) => project.id === trimmedIdentifier);
|
|
36888
37557
|
if (exactIdMatch) return {
|
|
36889
37558
|
id: exactIdMatch.id,
|
|
@@ -36907,7 +37576,7 @@ const findActiveProjectTarget = Effect.fn("findActiveProjectTarget")(function* (
|
|
|
36907
37576
|
};
|
|
36908
37577
|
});
|
|
36909
37578
|
const fetchLiveOrchestrationSnapshot = (origin, bearerToken) => Effect.gen(function* () {
|
|
36910
|
-
return yield* (yield* makeLiveServerClient(origin)).orchestration.
|
|
37579
|
+
return yield* (yield* makeLiveServerClient(origin)).orchestration.shellSnapshot({ headers: { authorization: `Bearer ${bearerToken}` } });
|
|
36911
37580
|
}).pipe(withProjectCliLiveServerTimeout, Effect.mapError(projectCommandErrorFromLiveServerRequest));
|
|
36912
37581
|
const dispatchLiveOrchestrationCommand = (origin, bearerToken, command) => Effect.gen(function* () {
|
|
36913
37582
|
yield* (yield* makeLiveServerClient(origin)).orchestration.dispatch({
|
|
@@ -36916,7 +37585,7 @@ const dispatchLiveOrchestrationCommand = (origin, bearerToken, command) => Effec
|
|
|
36916
37585
|
});
|
|
36917
37586
|
}).pipe(withProjectCliLiveServerTimeout, Effect.mapError(projectCommandErrorFromLiveServerRequest));
|
|
36918
37587
|
const getOfflineSnapshot = Effect.fn("getOfflineSnapshot")(function* () {
|
|
36919
|
-
return yield* (yield* ProjectionSnapshotQuery).
|
|
37588
|
+
return yield* (yield* ProjectionSnapshotQuery).getCommandReadModel();
|
|
36920
37589
|
});
|
|
36921
37590
|
const tryResolveLiveProjectExecutionMode = Effect.fn("tryResolveLiveProjectExecutionMode")(function* (environmentAuth, config) {
|
|
36922
37591
|
const runtimeState = yield* readPersistedServerRuntimeState(config.serverRuntimeStatePath);
|
|
@@ -36964,7 +37633,7 @@ const projectAddCommand = Command.make("add", {
|
|
|
36964
37633
|
title: Flag.string("title").pipe(Flag.withDescription("Optional project title."), Flag.optional)
|
|
36965
37634
|
}).pipe(Command.withDescription("Add a project."), Command.withHandler((flags) => runProjectMutation(flags, Effect.fn("projectAddMutation")(function* ({ snapshot, dispatch }) {
|
|
36966
37635
|
const workspaceRoot = yield* normalizeWorkspaceRootForProjectCommand(flags.workspaceRoot);
|
|
36967
|
-
const existingProject = snapshot.projects.find((project) => project.deletedAt
|
|
37636
|
+
const existingProject = snapshot.projects.find((project) => project.deletedAt == null && project.workspaceRoot === workspaceRoot);
|
|
36968
37637
|
if (existingProject) return yield* new ProjectAlreadyExistsError({
|
|
36969
37638
|
operation: "addProject",
|
|
36970
37639
|
projectId: existingProject.id,
|
|
@@ -37931,7 +38600,7 @@ const logP4ProjectFileLoadError = (error) => Effect.logWarning(error).pipe(Effec
|
|
|
37931
38600
|
filePath: error.filePath,
|
|
37932
38601
|
errorTag: error._tag
|
|
37933
38602
|
}));
|
|
37934
|
-
const make$
|
|
38603
|
+
const make$64 = Effect.gen(function* () {
|
|
37935
38604
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
37936
38605
|
const path = yield* Path.Path;
|
|
37937
38606
|
const load = Effect.fn("P4ProjectFileLoader.load")(function* (workspaceRoot) {
|
|
@@ -37952,7 +38621,7 @@ const make$63 = Effect.gen(function* () {
|
|
|
37952
38621
|
});
|
|
37953
38622
|
return P4ProjectFileLoader.of({ load });
|
|
37954
38623
|
});
|
|
37955
|
-
const layer$52 = Layer.effect(P4ProjectFileLoader, make$
|
|
38624
|
+
const layer$52 = Layer.effect(P4ProjectFileLoader, make$64);
|
|
37956
38625
|
//#endregion
|
|
37957
38626
|
//#region src/project/ProjectFaviconResolver.ts
|
|
37958
38627
|
/**
|
|
@@ -38027,7 +38696,7 @@ function extractIconHref(source) {
|
|
|
38027
38696
|
return null;
|
|
38028
38697
|
}
|
|
38029
38698
|
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) }));
|
|
38030
|
-
const make$
|
|
38699
|
+
const make$63 = Effect.gen(function* () {
|
|
38031
38700
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
38032
38701
|
const path = yield* Path.Path;
|
|
38033
38702
|
const workspacePaths = yield* WorkspacePaths;
|
|
@@ -38096,7 +38765,7 @@ const make$62 = Effect.gen(function* () {
|
|
|
38096
38765
|
});
|
|
38097
38766
|
return ProjectFaviconResolver.of({ resolvePath });
|
|
38098
38767
|
});
|
|
38099
|
-
const layer$51 = Layer.effect(ProjectFaviconResolver, make$
|
|
38768
|
+
const layer$51 = Layer.effect(ProjectFaviconResolver, make$63);
|
|
38100
38769
|
//#endregion
|
|
38101
38770
|
//#region src/assets/AssetAccess.ts
|
|
38102
38771
|
const ASSET_ROUTE_PREFIX = "/api/assets";
|
|
@@ -38507,10 +39176,10 @@ const resolveAsset = Effect.fn("AssetAccess.resolveAsset")(function* (token, rel
|
|
|
38507
39176
|
//#endregion
|
|
38508
39177
|
//#region src/observability/BrowserTraceCollector.ts
|
|
38509
39178
|
var BrowserTraceCollector = class extends Context.Service()("@p4code/cli/observability/BrowserTraceCollector") {};
|
|
38510
|
-
const make$
|
|
39179
|
+
const make$62 = (sink) => BrowserTraceCollector.of({ record: (records) => Effect.sync(() => {
|
|
38511
39180
|
for (const record of records) sink.push(record);
|
|
38512
39181
|
}) });
|
|
38513
|
-
const layer$50 = (sink) => Layer.succeed(BrowserTraceCollector, make$
|
|
39182
|
+
const layer$50 = (sink) => Layer.succeed(BrowserTraceCollector, make$62(sink));
|
|
38514
39183
|
//#endregion
|
|
38515
39184
|
//#region src/auth/http.ts
|
|
38516
39185
|
const CREDENTIAL_RESPONSE_HEADERS = {
|
|
@@ -39832,6 +40501,9 @@ const LIST_REFS_SNAPSHOT_CACHE_CAPACITY = 64;
|
|
|
39832
40501
|
const LIST_REFS_SNAPSHOT_CACHE_TTL = Duration.minutes(2);
|
|
39833
40502
|
const LIST_REFS_REFRESH_COALESCE_TTL = Duration.seconds(5);
|
|
39834
40503
|
const LIST_REFS_REFRESH_FAILURE_COOLDOWN = Duration.seconds(30);
|
|
40504
|
+
const STATUS_STATIC_CACHE_CAPACITY = 2048;
|
|
40505
|
+
const STATUS_DEFAULT_BRANCH_CACHE_TTL = Duration.minutes(5);
|
|
40506
|
+
const STATUS_ORIGIN_EXISTS_CACHE_TTL = Duration.minutes(5);
|
|
39835
40507
|
const STATUS_UPSTREAM_REFRESH_ENV = Object.freeze({
|
|
39836
40508
|
GCM_INTERACTIVE: "never",
|
|
39837
40509
|
GIT_ASKPASS: "",
|
|
@@ -40043,6 +40715,9 @@ function isMissingGitCwdError(error) {
|
|
|
40043
40715
|
function isNonRepositoryGitStderr(stderr) {
|
|
40044
40716
|
return stderr.toLowerCase().includes("not a git repository");
|
|
40045
40717
|
}
|
|
40718
|
+
function isUnbornHeadStderr(stderr) {
|
|
40719
|
+
return stderr.toLowerCase().includes("unknown revision") && stderr.toLowerCase().includes("path not in the working tree");
|
|
40720
|
+
}
|
|
40046
40721
|
const nowUnixNano = DateTime.now.pipe(Effect.map((now) => BigInt(DateTime.toEpochMillis(now)) * 1000000n));
|
|
40047
40722
|
const addCurrentSpanEvent = (name, attributes) => Effect.gen(function* () {
|
|
40048
40723
|
const span = yield* Effect.currentSpan;
|
|
@@ -40436,6 +41111,47 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* () {
|
|
|
40436
41111
|
const cacheKey = normalizeRepositoryPathsCacheKey(cwd);
|
|
40437
41112
|
return Cache.get(refresh ? repositoryPathsRefreshCache : repositoryPathsCache, cacheKey);
|
|
40438
41113
|
};
|
|
41114
|
+
const defaultBranchCache = yield* Cache.makeWith((gitCommonDir) => Effect.gen(function* () {
|
|
41115
|
+
const path = yield* Path.Path;
|
|
41116
|
+
const fetchCwd = path.basename(gitCommonDir) === ".git" ? path.dirname(gitCommonDir) : gitCommonDir;
|
|
41117
|
+
return yield* executeGit("GitVcsDriver.statusDetails.defaultBranch", fetchCwd, [
|
|
41118
|
+
"--git-dir",
|
|
41119
|
+
gitCommonDir,
|
|
41120
|
+
"symbolic-ref",
|
|
41121
|
+
"refs/remotes/origin/HEAD"
|
|
41122
|
+
], { allowNonZeroExit: true }).pipe(Effect.map((result) => {
|
|
41123
|
+
if (result.exitCode !== 0) return null;
|
|
41124
|
+
return parseDefaultBranchFromRemoteHeadRef(result.stdout, "origin");
|
|
41125
|
+
}));
|
|
41126
|
+
}), {
|
|
41127
|
+
capacity: STATUS_STATIC_CACHE_CAPACITY,
|
|
41128
|
+
timeToLive: Exit.match({
|
|
41129
|
+
onSuccess: () => STATUS_DEFAULT_BRANCH_CACHE_TTL,
|
|
41130
|
+
onFailure: () => Duration.zero
|
|
41131
|
+
})
|
|
41132
|
+
});
|
|
41133
|
+
const originExistsCache = yield* Cache.makeWith((gitCommonDir) => Effect.gen(function* () {
|
|
41134
|
+
const path = yield* Path.Path;
|
|
41135
|
+
const fetchCwd = path.basename(gitCommonDir) === ".git" ? path.dirname(gitCommonDir) : gitCommonDir;
|
|
41136
|
+
return yield* executeGit("GitVcsDriver.statusDetails.originExists", fetchCwd, [
|
|
41137
|
+
"--git-dir",
|
|
41138
|
+
gitCommonDir,
|
|
41139
|
+
"remote",
|
|
41140
|
+
"get-url",
|
|
41141
|
+
"origin"
|
|
41142
|
+
], { allowNonZeroExit: true }).pipe(Effect.map((result) => result.exitCode === 0));
|
|
41143
|
+
}), {
|
|
41144
|
+
capacity: STATUS_STATIC_CACHE_CAPACITY,
|
|
41145
|
+
timeToLive: Exit.match({
|
|
41146
|
+
onSuccess: () => STATUS_ORIGIN_EXISTS_CACHE_TTL,
|
|
41147
|
+
onFailure: () => Duration.zero
|
|
41148
|
+
})
|
|
41149
|
+
});
|
|
41150
|
+
const invalidateStatusStaticCaches = Effect.fn("invalidateStatusStaticCaches")(function* (cwd) {
|
|
41151
|
+
const cacheKey = (yield* resolveRepositoryPaths(cwd).pipe(Effect.catchTags({ GitCommandError: () => Effect.succeed(null) })))?.gitCommonDir ?? normalizeRepositoryPathsCacheKey(cwd);
|
|
41152
|
+
yield* Cache.invalidate(defaultBranchCache, cacheKey);
|
|
41153
|
+
yield* Cache.invalidate(originExistsCache, cacheKey);
|
|
41154
|
+
});
|
|
40439
41155
|
const resolveGitCommonDir = Effect.fn("resolveGitCommonDir")(function* (cwd) {
|
|
40440
41156
|
const repositoryPaths = yield* resolveRepositoryPaths(cwd);
|
|
40441
41157
|
if (repositoryPaths !== null) return repositoryPaths.gitCommonDir;
|
|
@@ -40479,10 +41195,16 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* () {
|
|
|
40479
41195
|
remoteName: upstream.remoteName
|
|
40480
41196
|
}));
|
|
40481
41197
|
});
|
|
40482
|
-
const resolveDefaultBranchName = (
|
|
40483
|
-
if (
|
|
40484
|
-
|
|
40485
|
-
|
|
41198
|
+
const resolveDefaultBranchName = Effect.fn("resolveDefaultBranchName")(function* (cwd, remoteName) {
|
|
41199
|
+
if (remoteName === "origin") {
|
|
41200
|
+
const repositoryPaths = yield* resolveRepositoryPaths(cwd);
|
|
41201
|
+
if (repositoryPaths) return yield* Cache.get(defaultBranchCache, repositoryPaths.gitCommonDir);
|
|
41202
|
+
}
|
|
41203
|
+
return yield* executeGit("GitVcsDriver.resolveDefaultBranchName", cwd, ["symbolic-ref", `refs/remotes/${remoteName}/HEAD`], { allowNonZeroExit: true }).pipe(Effect.map((result) => {
|
|
41204
|
+
if (result.exitCode !== 0) return null;
|
|
41205
|
+
return parseDefaultBranchFromRemoteHeadRef(result.stdout, remoteName);
|
|
41206
|
+
}));
|
|
41207
|
+
});
|
|
40486
41208
|
const remoteBranchExists = (cwd, remoteName, refName) => executeGit("GitVcsDriver.remoteBranchExists", cwd, [
|
|
40487
41209
|
"show-ref",
|
|
40488
41210
|
"--verify",
|
|
@@ -40587,9 +41309,10 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* () {
|
|
|
40587
41309
|
"HEAD"
|
|
40588
41310
|
], { allowNonZeroExit: true }).pipe(Effect.catchTags({ GitCommandError: (error) => isMissingGitCwdError(error) ? Effect.succeed(null) : Effect.fail(error) }));
|
|
40589
41311
|
if (branchResult === null) return NON_REPOSITORY_REMOTE_STATUS_DETAILS;
|
|
41312
|
+
let branch;
|
|
40590
41313
|
if (branchResult.exitCode !== 0) {
|
|
40591
41314
|
if (isNonRepositoryGitStderr(branchResult.stderr)) return NON_REPOSITORY_REMOTE_STATUS_DETAILS;
|
|
40592
|
-
return yield* new GitCommandError({
|
|
41315
|
+
if (!isUnbornHeadStderr(branchResult.stderr)) return yield* new GitCommandError({
|
|
40593
41316
|
...gitCommandContext({
|
|
40594
41317
|
operation: "GitVcsDriver.statusDetailsRemote.branch",
|
|
40595
41318
|
cwd,
|
|
@@ -40604,9 +41327,16 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* () {
|
|
|
40604
41327
|
stdoutLength: branchResult.stdout.length,
|
|
40605
41328
|
stderrLength: branchResult.stderr.length
|
|
40606
41329
|
});
|
|
41330
|
+
branch = (yield* runGitStdout("GitVcsDriver.statusDetailsRemote.unbornBranch", cwd, [
|
|
41331
|
+
"symbolic-ref",
|
|
41332
|
+
"--quiet",
|
|
41333
|
+
"--short",
|
|
41334
|
+
"HEAD"
|
|
41335
|
+
])).trim() || null;
|
|
41336
|
+
} else {
|
|
41337
|
+
const branchValue = branchResult.stdout.trim();
|
|
41338
|
+
branch = branchValue.length > 0 && branchValue !== "HEAD" ? branchValue : null;
|
|
40607
41339
|
}
|
|
40608
|
-
const branchValue = branchResult.stdout.trim();
|
|
40609
|
-
const branch = branchValue.length > 0 && branchValue !== "HEAD" ? branchValue : null;
|
|
40610
41340
|
const upstreamRef = (yield* resolveCurrentUpstream(cwd))?.upstreamRef ?? null;
|
|
40611
41341
|
let aheadCount = 0;
|
|
40612
41342
|
let behindCount = 0;
|
|
@@ -40664,18 +41394,53 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* () {
|
|
|
40664
41394
|
stderrLength: statusResult.stderr.length
|
|
40665
41395
|
});
|
|
40666
41396
|
}
|
|
40667
|
-
const
|
|
40668
|
-
|
|
40669
|
-
|
|
41397
|
+
const statusCacheKey = (yield* resolveRepositoryPaths(cwd).pipe(Effect.catchTags({ GitCommandError: () => Effect.succeed(null) })))?.gitCommonDir;
|
|
41398
|
+
const [numstatStdout, defaultBranch, hasPrimaryRemote] = yield* Effect.all([
|
|
41399
|
+
executeGitWithStableDiagnostics("GitVcsDriver.statusDetails.numstat", cwd, [
|
|
40670
41400
|
"diff",
|
|
40671
|
-
"
|
|
41401
|
+
"HEAD",
|
|
40672
41402
|
"--numstat"
|
|
40673
|
-
])
|
|
40674
|
-
|
|
40675
|
-
|
|
41403
|
+
], { allowNonZeroExit: true }).pipe(Effect.flatMap((result) => {
|
|
41404
|
+
if (result.exitCode === 0) return Effect.succeed(result.stdout);
|
|
41405
|
+
if (isUnbornHeadStderr(result.stderr)) return Effect.map(Effect.all([runGitStdout("GitVcsDriver.statusDetails.numstat.unborn", cwd, ["diff", "--numstat"]), runGitStdout("GitVcsDriver.statusDetails.numstat.unborn.staged", cwd, [
|
|
41406
|
+
"diff",
|
|
41407
|
+
"--cached",
|
|
41408
|
+
"--numstat"
|
|
41409
|
+
])]), ([unstagedStdout, stagedStdout]) => {
|
|
41410
|
+
const staged = parseNumstatEntries(stagedStdout);
|
|
41411
|
+
const unstaged = parseNumstatEntries(unstagedStdout);
|
|
41412
|
+
const map = /* @__PURE__ */ new Map();
|
|
41413
|
+
for (const entry of [...staged, ...unstaged]) {
|
|
41414
|
+
const existing = map.get(entry.path) ?? {
|
|
41415
|
+
insertions: 0,
|
|
41416
|
+
deletions: 0
|
|
41417
|
+
};
|
|
41418
|
+
existing.insertions += entry.insertions;
|
|
41419
|
+
existing.deletions += entry.deletions;
|
|
41420
|
+
map.set(entry.path, existing);
|
|
41421
|
+
}
|
|
41422
|
+
return Array.from(map.entries()).map(([p, s]) => `${s.insertions}\t${s.deletions}\t${p}`).join("\n");
|
|
41423
|
+
});
|
|
41424
|
+
return Effect.fail(new GitCommandError({
|
|
41425
|
+
...gitCommandContext({
|
|
41426
|
+
operation: "GitVcsDriver.statusDetails.numstat",
|
|
41427
|
+
cwd,
|
|
41428
|
+
args: [
|
|
41429
|
+
"diff",
|
|
41430
|
+
"HEAD",
|
|
41431
|
+
"--numstat"
|
|
41432
|
+
]
|
|
41433
|
+
}),
|
|
41434
|
+
detail: "git diff HEAD --numstat failed.",
|
|
41435
|
+
exitCode: result.exitCode,
|
|
41436
|
+
stdoutLength: result.stdout.length,
|
|
41437
|
+
stderrLength: result.stderr.length
|
|
41438
|
+
}));
|
|
41439
|
+
})),
|
|
41440
|
+
statusCacheKey ? Cache.get(defaultBranchCache, statusCacheKey).pipe(Effect.orElseSucceed(() => null)) : resolveDefaultBranchName(cwd, "origin").pipe(Effect.orElseSucceed(() => null)),
|
|
41441
|
+
statusCacheKey ? Cache.get(originExistsCache, statusCacheKey).pipe(Effect.orElseSucceed(() => false)) : originRemoteExists(cwd).pipe(Effect.orElseSucceed(() => false))
|
|
40676
41442
|
], { concurrency: "unbounded" });
|
|
40677
41443
|
const statusStdout = statusResult.stdout;
|
|
40678
|
-
const defaultBranch = defaultRefResult.exitCode === 0 ? defaultRefResult.stdout.trim().replace(/^refs\/remotes\/origin\//, "") : null;
|
|
40679
41444
|
let refName = null;
|
|
40680
41445
|
let upstreamRef = null;
|
|
40681
41446
|
let aheadCount = 0;
|
|
@@ -40713,18 +41478,12 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* () {
|
|
|
40713
41478
|
}
|
|
40714
41479
|
const isDefaultBranch = refName !== null && (refName === defaultBranch || defaultBranch === null && (refName === "main" || refName === "master"));
|
|
40715
41480
|
if (refName && !isDefaultBranch) aheadOfDefaultCount = fallbackAheadCount !== null ? fallbackAheadCount : yield* computeAheadCountAgainstBase(cwd, refName).pipe(Effect.orElseSucceed(() => 0));
|
|
40716
|
-
const
|
|
40717
|
-
const unstagedEntries = parseNumstatEntries(unstagedNumstatStdout);
|
|
41481
|
+
const numstatEntries = parseNumstatEntries(numstatStdout);
|
|
40718
41482
|
const fileStatMap = /* @__PURE__ */ new Map();
|
|
40719
|
-
for (const entry of
|
|
40720
|
-
|
|
40721
|
-
|
|
40722
|
-
|
|
40723
|
-
};
|
|
40724
|
-
existing.insertions += entry.insertions;
|
|
40725
|
-
existing.deletions += entry.deletions;
|
|
40726
|
-
fileStatMap.set(entry.path, existing);
|
|
40727
|
-
}
|
|
41483
|
+
for (const entry of numstatEntries) fileStatMap.set(entry.path, {
|
|
41484
|
+
insertions: entry.insertions,
|
|
41485
|
+
deletions: entry.deletions
|
|
41486
|
+
});
|
|
40728
41487
|
let insertions = 0;
|
|
40729
41488
|
let deletions = 0;
|
|
40730
41489
|
const files = Array.from(fileStatMap.entries()).map(([filePath, stat]) => {
|
|
@@ -41537,7 +42296,7 @@ const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* () {
|
|
|
41537
42296
|
}
|
|
41538
42297
|
return branchNames;
|
|
41539
42298
|
}));
|
|
41540
|
-
const withListRefsInvalidation = (cwd, effect) => effect.pipe(Effect.ensuring(invalidateListRefsSnapshot(cwd).pipe(Effect.ignore)));
|
|
42299
|
+
const withListRefsInvalidation = (cwd, effect) => effect.pipe(Effect.ensuring(Effect.all([invalidateListRefsSnapshot(cwd).pipe(Effect.ignore), invalidateStatusStaticCaches(cwd).pipe(Effect.ignore)])));
|
|
41541
42300
|
const initRepoWithListRefsInvalidation = (input) => initRepo(input).pipe(Effect.ensuring(Effect.gen(function* () {
|
|
41542
42301
|
const cacheKey = normalizeRepositoryPathsCacheKey(input.cwd);
|
|
41543
42302
|
yield* Cache.invalidate(repositoryPathsRefreshCache, cacheKey);
|
|
@@ -41588,7 +42347,7 @@ const classifyNonZeroExit = (command, stderr) => {
|
|
|
41588
42347
|
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";
|
|
41589
42348
|
return "command-failed";
|
|
41590
42349
|
};
|
|
41591
|
-
const make$
|
|
42350
|
+
const make$61 = Effect.gen(function* () {
|
|
41592
42351
|
const processRunner = yield* ProcessRunner;
|
|
41593
42352
|
const run = Effect.fn("VcsProcess.run")(function* (input) {
|
|
41594
42353
|
const baseError = {
|
|
@@ -41647,7 +42406,7 @@ const make$60 = Effect.gen(function* () {
|
|
|
41647
42406
|
});
|
|
41648
42407
|
return VcsProcess.of({ run });
|
|
41649
42408
|
});
|
|
41650
|
-
const layer$49 = Layer.effect(VcsProcess, make$
|
|
42409
|
+
const layer$49 = Layer.effect(VcsProcess, make$61).pipe(Layer.provide(layer$63));
|
|
41651
42410
|
//#endregion
|
|
41652
42411
|
//#region src/vcs/VcsDriver.ts
|
|
41653
42412
|
var VcsDriver = class extends Context.Service()("@p4code/cli/vcs/VcsDriver") {};
|
|
@@ -42098,12 +42857,12 @@ const makeVcsDriver = Effect.gen(function* () {
|
|
|
42098
42857
|
const driver = yield* makeVcsDriverShape();
|
|
42099
42858
|
return VcsDriver.of(driver);
|
|
42100
42859
|
});
|
|
42101
|
-
const make$
|
|
42860
|
+
const make$60 = Effect.gen(function* () {
|
|
42102
42861
|
const git = yield* makeGitVcsDriverCore();
|
|
42103
42862
|
return GitVcsDriver.of(git);
|
|
42104
42863
|
});
|
|
42105
42864
|
Layer.effect(VcsDriver, makeVcsDriver);
|
|
42106
|
-
const layer$48 = Layer.effect(GitVcsDriver, make$
|
|
42865
|
+
const layer$48 = Layer.effect(GitVcsDriver, make$60);
|
|
42107
42866
|
//#endregion
|
|
42108
42867
|
//#region src/vcs/VcsProjectConfig.ts
|
|
42109
42868
|
const ProjectVcsConfigJson = fromLenientJson(Schema$1.Struct({
|
|
@@ -42135,7 +42894,7 @@ const logVcsProjectConfigError = (error) => Effect.logWarning(error).pipe(Effect
|
|
|
42135
42894
|
configPath: error.configPath,
|
|
42136
42895
|
errorTag: error._tag
|
|
42137
42896
|
}));
|
|
42138
|
-
const make$
|
|
42897
|
+
const make$59 = Effect.gen(function* () {
|
|
42139
42898
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
42140
42899
|
const path = yield* Path.Path;
|
|
42141
42900
|
const findConfigPath = Effect.fn("VcsProjectConfig.findConfigPath")(function* (cwd) {
|
|
@@ -42176,7 +42935,7 @@ const make$58 = Effect.gen(function* () {
|
|
|
42176
42935
|
});
|
|
42177
42936
|
return VcsProjectConfig.of({ resolveKind });
|
|
42178
42937
|
});
|
|
42179
|
-
const layer$47 = Layer.effect(VcsProjectConfig, make$
|
|
42938
|
+
const layer$47 = Layer.effect(VcsProjectConfig, make$59);
|
|
42180
42939
|
//#endregion
|
|
42181
42940
|
//#region src/vcs/VcsDriverRegistry.ts
|
|
42182
42941
|
const DETECTION_CACHE_CAPACITY = 2048;
|
|
@@ -42196,7 +42955,7 @@ function parseDetectionCacheKey(key) {
|
|
|
42196
42955
|
cwd: key.slice(separatorIndex + 1)
|
|
42197
42956
|
};
|
|
42198
42957
|
}
|
|
42199
|
-
const make$
|
|
42958
|
+
const make$58 = Effect.gen(function* () {
|
|
42200
42959
|
const projectConfig = yield* VcsProjectConfig;
|
|
42201
42960
|
const git = yield* makeVcsDriver;
|
|
42202
42961
|
const drivers = { git };
|
|
@@ -42253,7 +43012,7 @@ const make$57 = Effect.gen(function* () {
|
|
|
42253
43012
|
resolve
|
|
42254
43013
|
});
|
|
42255
43014
|
});
|
|
42256
|
-
const layer$46 = Layer.effect(VcsDriverRegistry, make$
|
|
43015
|
+
const layer$46 = Layer.effect(VcsDriverRegistry, make$58).pipe(Layer.provide(layer$47));
|
|
42257
43016
|
//#endregion
|
|
42258
43017
|
//#region src/checkpointing/CheckpointStore.ts
|
|
42259
43018
|
/**
|
|
@@ -42273,7 +43032,7 @@ const layer$46 = Layer.effect(VcsDriverRegistry, make$57).pipe(Layer.provide(lay
|
|
|
42273
43032
|
*/
|
|
42274
43033
|
/** Service tag for checkpoint persistence and restore operations. */
|
|
42275
43034
|
var CheckpointStore = class extends Context.Service()("@p4code/cli/checkpointing/CheckpointStore") {};
|
|
42276
|
-
const make$
|
|
43035
|
+
const make$57 = Effect.gen(function* () {
|
|
42277
43036
|
const vcsRegistry = yield* VcsDriverRegistry;
|
|
42278
43037
|
const resolveCheckpoints = Effect.fn("CheckpointStore.resolveCheckpoints")(function* (operation, cwd) {
|
|
42279
43038
|
const handle = yield* vcsRegistry.resolve({ cwd });
|
|
@@ -42312,7 +43071,7 @@ const make$56 = Effect.gen(function* () {
|
|
|
42312
43071
|
deleteCheckpointRefs
|
|
42313
43072
|
});
|
|
42314
43073
|
});
|
|
42315
|
-
const layer$45 = Layer.effect(CheckpointStore, make$
|
|
43074
|
+
const layer$45 = Layer.effect(CheckpointStore, make$57);
|
|
42316
43075
|
//#endregion
|
|
42317
43076
|
//#region src/checkpointing/CheckpointDiffQuery.ts
|
|
42318
43077
|
/**
|
|
@@ -42334,7 +43093,7 @@ function buildTurnDiffResult(input, diff) {
|
|
|
42334
43093
|
diff
|
|
42335
43094
|
};
|
|
42336
43095
|
}
|
|
42337
|
-
const make$
|
|
43096
|
+
const make$56 = Effect.gen(function* () {
|
|
42338
43097
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
42339
43098
|
const checkpointStore = yield* CheckpointStore;
|
|
42340
43099
|
const threadActivities = yield* ProjectionThreadActivityRepository;
|
|
@@ -42505,7 +43264,7 @@ const make$55 = Effect.gen(function* () {
|
|
|
42505
43264
|
getFullThreadDiff
|
|
42506
43265
|
});
|
|
42507
43266
|
});
|
|
42508
|
-
const layer$44 = Layer.effect(CheckpointDiffQuery, make$
|
|
43267
|
+
const layer$44 = Layer.effect(CheckpointDiffQuery, make$56);
|
|
42509
43268
|
//#endregion
|
|
42510
43269
|
//#region src/orchestration/ThreadLiveEventCoalescer.ts
|
|
42511
43270
|
const COALESCE_WINDOW = Duration.millis(50);
|
|
@@ -42740,11 +43499,11 @@ const makeTextGenerationFromRegistry = (registry) => TextGeneration.of({
|
|
|
42740
43499
|
detail: "This provider does not report account usage."
|
|
42741
43500
|
}))))
|
|
42742
43501
|
});
|
|
42743
|
-
const make$
|
|
43502
|
+
const make$55 = Effect.gen(function* () {
|
|
42744
43503
|
const registry = yield* ProviderInstanceRegistry;
|
|
42745
43504
|
return makeTextGenerationFromRegistry(registry);
|
|
42746
43505
|
});
|
|
42747
|
-
const layer$43 = Layer.effect(TextGeneration, make$
|
|
43506
|
+
const layer$43 = Layer.effect(TextGeneration, make$55);
|
|
42748
43507
|
//#endregion
|
|
42749
43508
|
//#region src/textGeneration/TextGenerationPresets.ts
|
|
42750
43509
|
const conventionalCommitsTextGenerationPolicy = {
|
|
@@ -43076,7 +43835,7 @@ const serversEqual = (left, right) => {
|
|
|
43076
43835
|
}
|
|
43077
43836
|
return true;
|
|
43078
43837
|
};
|
|
43079
|
-
const make$
|
|
43838
|
+
const make$54 = Effect.gen(function* PortDiscoveryMake() {
|
|
43080
43839
|
const net = yield* NetService;
|
|
43081
43840
|
const processRunner = yield* ProcessRunner;
|
|
43082
43841
|
const hostPlatform = yield* HostProcessPlatform;
|
|
@@ -43227,7 +43986,7 @@ const make$53 = Effect.gen(function* PortDiscoveryMake() {
|
|
|
43227
43986
|
unregisterTerminal
|
|
43228
43987
|
});
|
|
43229
43988
|
}).pipe(Effect.withSpan("PortDiscovery.make"));
|
|
43230
|
-
const layer$42 = Layer.effect(PortDiscovery, make$
|
|
43989
|
+
const layer$42 = Layer.effect(PortDiscovery, make$54);
|
|
43231
43990
|
//#endregion
|
|
43232
43991
|
//#region src/terminal/Manager.ts
|
|
43233
43992
|
/**
|
|
@@ -43905,7 +44664,7 @@ function normalizedRuntimeEnv(env) {
|
|
|
43905
44664
|
if (entries.length === 0) return null;
|
|
43906
44665
|
return Object.fromEntries(entries.toSorted(([left], [right]) => left.localeCompare(right)));
|
|
43907
44666
|
}
|
|
43908
|
-
const make$
|
|
44667
|
+
const make$53 = Effect.fn("TerminalManager.make")(function* () {
|
|
43909
44668
|
const { terminalLogsDir } = yield* ServerConfig$1;
|
|
43910
44669
|
const ptyAdapter = yield* PtyAdapter;
|
|
43911
44670
|
const portDiscovery = yield* PortDiscovery;
|
|
@@ -44867,7 +45626,7 @@ const makeWithOptions$1 = Effect.fn("TerminalManager.makeWithOptions")(function*
|
|
|
44867
45626
|
subscribeMetadata
|
|
44868
45627
|
});
|
|
44869
45628
|
});
|
|
44870
|
-
const layer$41 = Layer.effect(TerminalManager, make$
|
|
45629
|
+
const layer$41 = Layer.effect(TerminalManager, make$53()).pipe(Layer.provide(layer$63));
|
|
44871
45630
|
//#endregion
|
|
44872
45631
|
//#region src/project/ProjectSetupScriptRunner.ts
|
|
44873
45632
|
var ProjectSetupScriptOperationError = class extends Schema$1.TaggedErrorClass()("ProjectSetupScriptOperationError", {
|
|
@@ -44898,7 +45657,7 @@ var ProjectSetupScriptProjectNotFoundError = class extends Schema$1.TaggedErrorC
|
|
|
44898
45657
|
};
|
|
44899
45658
|
Schema$1.Union([ProjectSetupScriptOperationError, ProjectSetupScriptProjectNotFoundError]);
|
|
44900
45659
|
var ProjectSetupScriptRunner = class extends Context.Service()("@p4code/cli/project/ProjectSetupScriptRunner") {};
|
|
44901
|
-
const make$
|
|
45660
|
+
const make$52 = Effect.gen(function* () {
|
|
44902
45661
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
44903
45662
|
const terminalManager = yield* TerminalManager;
|
|
44904
45663
|
const runForThread = Effect.fn("ProjectSetupScriptRunner.runForThread")(function* (input) {
|
|
@@ -44956,7 +45715,7 @@ const make$51 = Effect.gen(function* () {
|
|
|
44956
45715
|
});
|
|
44957
45716
|
return ProjectSetupScriptRunner.of({ runForThread });
|
|
44958
45717
|
});
|
|
44959
|
-
const layer$40 = Layer.effect(ProjectSetupScriptRunner, make$
|
|
45718
|
+
const layer$40 = Layer.effect(ProjectSetupScriptRunner, make$52);
|
|
44960
45719
|
//#endregion
|
|
44961
45720
|
//#region src/provider/Services/ProviderRegistry.ts
|
|
44962
45721
|
var ProviderRegistry = class extends Context.Service()("@p4code/cli/provider/Services/ProviderRegistry") {};
|
|
@@ -45053,19 +45812,23 @@ function normalizeAzureDevOpsPullRequestRecord(raw) {
|
|
|
45053
45812
|
baseRefName: normalizeRefName$1(raw.targetRefName),
|
|
45054
45813
|
headRefName: normalizeRefName$1(raw.sourceRefName),
|
|
45055
45814
|
state: normalizeAzureDevOpsPullRequestState(raw.status),
|
|
45815
|
+
...Option.isSome(raw.closedDate ?? Option.none()) ? { terminalAt: DateTime.formatIso(Option.getOrThrow(raw.closedDate ?? Option.none())) } : {},
|
|
45056
45816
|
updatedAt: (raw.closedDate ?? Option.none()).pipe(Option.orElse(() => raw.creationDate ?? Option.none()))
|
|
45057
45817
|
};
|
|
45058
45818
|
}
|
|
45059
45819
|
const decodeAzureDevOpsPullRequestList = decodeJsonResult(Schema$1.Array(Schema$1.Unknown));
|
|
45060
45820
|
const decodeAzureDevOpsPullRequest = decodeJsonResult(AzureDevOpsPullRequestSchema);
|
|
45061
45821
|
const decodeAzureDevOpsPullRequestEntry = Schema$1.decodeUnknownExit(AzureDevOpsPullRequestSchema);
|
|
45062
|
-
function decodeAzureDevOpsPullRequestListJson(raw) {
|
|
45822
|
+
function decodeAzureDevOpsPullRequestListJson(raw, strict = false) {
|
|
45063
45823
|
const result = decodeAzureDevOpsPullRequestList(raw);
|
|
45064
45824
|
if (Result.isSuccess(result)) {
|
|
45065
45825
|
const pullRequests = [];
|
|
45066
45826
|
for (const entry of result.success) {
|
|
45067
45827
|
const decodedEntry = decodeAzureDevOpsPullRequestEntry(entry);
|
|
45068
|
-
if (Exit.isFailure(decodedEntry))
|
|
45828
|
+
if (Exit.isFailure(decodedEntry)) {
|
|
45829
|
+
if (strict) return Result.fail(decodedEntry.cause);
|
|
45830
|
+
continue;
|
|
45831
|
+
}
|
|
45069
45832
|
pullRequests.push(normalizeAzureDevOpsPullRequestRecord(decodedEntry.value));
|
|
45070
45833
|
}
|
|
45071
45834
|
return Result.succeed(pullRequests);
|
|
@@ -45283,7 +46046,7 @@ function decodeAzureDevOpsJson(raw, schema, operation, cwd) {
|
|
|
45283
46046
|
cause
|
|
45284
46047
|
})));
|
|
45285
46048
|
}
|
|
45286
|
-
const make$
|
|
46049
|
+
const make$51 = Effect.gen(function* () {
|
|
45287
46050
|
const process = yield* VcsProcess;
|
|
45288
46051
|
const execute = (input) => process.run({
|
|
45289
46052
|
operation: "AzureDevOpsCli.execute",
|
|
@@ -45323,7 +46086,7 @@ const make$50 = Effect.gen(function* () {
|
|
|
45323
46086
|
"--top",
|
|
45324
46087
|
String(input.limit ?? 20)
|
|
45325
46088
|
]
|
|
45326
|
-
}).pipe(Effect.map((result) => result.stdout.trim()), Effect.flatMap((raw) => raw.length === 0 ? Effect.succeed([]) : Effect.sync(() => decodeAzureDevOpsPullRequestListJson(raw)).pipe(Effect.flatMap((decoded) => {
|
|
46089
|
+
}).pipe(Effect.map((result) => result.stdout.trim()), Effect.flatMap((raw) => raw.length === 0 && !input.strict ? Effect.succeed([]) : Effect.sync(() => decodeAzureDevOpsPullRequestListJson(raw, input.strict)).pipe(Effect.flatMap((decoded) => {
|
|
45327
46090
|
if (!Result.isSuccess(decoded)) return Effect.fail(new AzureDevOpsPullRequestListDecodeError({
|
|
45328
46091
|
operation: "listPullRequests",
|
|
45329
46092
|
command: "az",
|
|
@@ -45425,7 +46188,7 @@ const make$50 = Effect.gen(function* () {
|
|
|
45425
46188
|
}).pipe(Effect.asVoid)
|
|
45426
46189
|
});
|
|
45427
46190
|
});
|
|
45428
|
-
const layer$39 = Layer.effect(AzureDevOpsCli, make$
|
|
46191
|
+
const layer$39 = Layer.effect(AzureDevOpsCli, make$51);
|
|
45429
46192
|
//#endregion
|
|
45430
46193
|
//#region src/sourceControl/SourceControlProviderDiscovery.ts
|
|
45431
46194
|
function firstNonEmptyLine(text) {
|
|
@@ -45625,10 +46388,11 @@ function toChangeRequest$5(summary) {
|
|
|
45625
46388
|
headRefName: summary.headRefName,
|
|
45626
46389
|
state: summary.state,
|
|
45627
46390
|
updatedAt: summary.updatedAt,
|
|
46391
|
+
...summary.terminalAt == null ? {} : { terminalAt: summary.terminalAt },
|
|
45628
46392
|
isCrossRepository: false
|
|
45629
46393
|
};
|
|
45630
46394
|
}
|
|
45631
|
-
const make$
|
|
46395
|
+
const make$50 = Effect.gen(function* () {
|
|
45632
46396
|
const azure = yield* AzureDevOpsCli;
|
|
45633
46397
|
return SourceControlProvider.of({
|
|
45634
46398
|
kind: "azure-devops",
|
|
@@ -45639,6 +46403,7 @@ const make$49 = Effect.gen(function* () {
|
|
|
45639
46403
|
headSelector: input.headSelector,
|
|
45640
46404
|
...source !== void 0 ? { source } : {},
|
|
45641
46405
|
state: input.state,
|
|
46406
|
+
...input.strict !== void 0 ? { strict: input.strict } : {},
|
|
45642
46407
|
...input.limit !== void 0 ? { limit: input.limit } : {}
|
|
45643
46408
|
}).pipe(Effect.map((items) => items.map(toChangeRequest$5)), Effect.mapError((error) => new SourceControlProviderError({
|
|
45644
46409
|
provider: "azure-devops",
|
|
@@ -45720,7 +46485,7 @@ const make$49 = Effect.gen(function* () {
|
|
|
45720
46485
|
})))
|
|
45721
46486
|
});
|
|
45722
46487
|
});
|
|
45723
|
-
Layer.effect(SourceControlProvider, make$
|
|
46488
|
+
Layer.effect(SourceControlProvider, make$50);
|
|
45724
46489
|
//#endregion
|
|
45725
46490
|
//#region src/sourceControl/bitbucketPullRequests.ts
|
|
45726
46491
|
const BitbucketRepositoryRefSchema = Schema$1.Struct({
|
|
@@ -46097,7 +46862,7 @@ function responseError(operation, response) {
|
|
|
46097
46862
|
responseBodyLength: collected.text.length
|
|
46098
46863
|
}))));
|
|
46099
46864
|
}
|
|
46100
|
-
const make$
|
|
46865
|
+
const make$49 = Effect.gen(function* () {
|
|
46101
46866
|
const config = yield* BitbucketApiEnvConfig;
|
|
46102
46867
|
const httpClient = yield* HttpClient.HttpClient;
|
|
46103
46868
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
@@ -46313,7 +47078,7 @@ const make$48 = Effect.gen(function* () {
|
|
|
46313
47078
|
})))
|
|
46314
47079
|
});
|
|
46315
47080
|
});
|
|
46316
|
-
const layer$37 = Layer.effect(BitbucketApi, make$
|
|
47081
|
+
const layer$37 = Layer.effect(BitbucketApi, make$49);
|
|
46317
47082
|
//#endregion
|
|
46318
47083
|
//#region src/sourceControl/BitbucketSourceControlProvider.ts
|
|
46319
47084
|
function toChangeRequest$4(summary) {
|
|
@@ -46331,7 +47096,7 @@ function toChangeRequest$4(summary) {
|
|
|
46331
47096
|
...summary.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: summary.headRepositoryOwnerLogin } : {}
|
|
46332
47097
|
};
|
|
46333
47098
|
}
|
|
46334
|
-
const make$
|
|
47099
|
+
const make$48 = Effect.gen(function* () {
|
|
46335
47100
|
const bitbucket = yield* BitbucketApi;
|
|
46336
47101
|
return SourceControlProvider.of({
|
|
46337
47102
|
kind: "bitbucket",
|
|
@@ -46422,7 +47187,7 @@ const make$47 = Effect.gen(function* () {
|
|
|
46422
47187
|
})))
|
|
46423
47188
|
});
|
|
46424
47189
|
});
|
|
46425
|
-
Layer.effect(SourceControlProvider, make$
|
|
47190
|
+
Layer.effect(SourceControlProvider, make$48);
|
|
46426
47191
|
const makeDiscovery = Effect.gen(function* () {
|
|
46427
47192
|
return {
|
|
46428
47193
|
type: "api",
|
|
@@ -46442,6 +47207,7 @@ const GitHubPullRequestSchema = Schema$1.Struct({
|
|
|
46442
47207
|
headRefName: TrimmedNonEmptyString,
|
|
46443
47208
|
state: Schema$1.optional(Schema$1.NullOr(Schema$1.String)),
|
|
46444
47209
|
mergedAt: Schema$1.optional(Schema$1.NullOr(Schema$1.String)),
|
|
47210
|
+
closedAt: Schema$1.optional(Schema$1.NullOr(Schema$1.String)),
|
|
46445
47211
|
updatedAt: Schema$1.optional(Schema$1.OptionFromNullOr(Schema$1.DateTimeUtcFromString)),
|
|
46446
47212
|
isCrossRepository: Schema$1.optional(Schema$1.Boolean),
|
|
46447
47213
|
headRepository: Schema$1.optional(Schema$1.NullOr(Schema$1.Struct({
|
|
@@ -46465,6 +47231,7 @@ function normalizeGitHubPullRequestRecord(raw) {
|
|
|
46465
47231
|
const headRepositoryName = trimOptionalString$1(raw.headRepository?.name);
|
|
46466
47232
|
const headRepositoryOwnerLogin = trimOptionalString$1(raw.headRepositoryOwner?.login) ?? (explicitNameWithOwner?.includes("/") ? explicitNameWithOwner.split("/")[0] ?? null : null);
|
|
46467
47233
|
const headRepositoryNameWithOwner = explicitNameWithOwner ?? (headRepositoryOwnerLogin && headRepositoryName ? `${headRepositoryOwnerLogin}/${headRepositoryName}` : null);
|
|
47234
|
+
const terminalAt = normalizeGitHubPullRequestState(raw) === "merged" ? raw.mergedAt ?? null : normalizeGitHubPullRequestState(raw) === "closed" ? raw.closedAt ?? null : null;
|
|
46468
47235
|
return {
|
|
46469
47236
|
number: raw.number,
|
|
46470
47237
|
title: raw.title,
|
|
@@ -46473,6 +47240,7 @@ function normalizeGitHubPullRequestRecord(raw) {
|
|
|
46473
47240
|
headRefName: raw.headRefName,
|
|
46474
47241
|
state: normalizeGitHubPullRequestState(raw),
|
|
46475
47242
|
updatedAt: raw.updatedAt ?? Option.none(),
|
|
47243
|
+
...terminalAt == null ? {} : { terminalAt },
|
|
46476
47244
|
...typeof raw.isCrossRepository === "boolean" ? { isCrossRepository: raw.isCrossRepository } : {},
|
|
46477
47245
|
...headRepositoryNameWithOwner ? { headRepositoryNameWithOwner } : {},
|
|
46478
47246
|
...headRepositoryOwnerLogin ? { headRepositoryOwnerLogin } : {}
|
|
@@ -46481,13 +47249,16 @@ function normalizeGitHubPullRequestRecord(raw) {
|
|
|
46481
47249
|
const decodeGitHubPullRequestList = decodeJsonResult(Schema$1.Array(Schema$1.Unknown));
|
|
46482
47250
|
const decodeGitHubPullRequest = decodeJsonResult(GitHubPullRequestSchema);
|
|
46483
47251
|
const decodeGitHubPullRequestEntry = Schema$1.decodeUnknownExit(GitHubPullRequestSchema);
|
|
46484
|
-
function decodeGitHubPullRequestListJson(raw) {
|
|
47252
|
+
function decodeGitHubPullRequestListJson(raw, strict = false) {
|
|
46485
47253
|
const result = decodeGitHubPullRequestList(raw);
|
|
46486
47254
|
if (Result.isSuccess(result)) {
|
|
46487
47255
|
const pullRequests = [];
|
|
46488
47256
|
for (const entry of result.success) {
|
|
46489
47257
|
const decodedEntry = decodeGitHubPullRequestEntry(entry);
|
|
46490
|
-
if (Exit.isFailure(decodedEntry))
|
|
47258
|
+
if (Exit.isFailure(decodedEntry)) {
|
|
47259
|
+
if (strict) return Result.fail(decodedEntry.cause);
|
|
47260
|
+
continue;
|
|
47261
|
+
}
|
|
46491
47262
|
pullRequests.push(normalizeGitHubPullRequestRecord(decodedEntry.value));
|
|
46492
47263
|
}
|
|
46493
47264
|
return Result.succeed(pullRequests);
|
|
@@ -46664,7 +47435,7 @@ function deriveRepositoryCloneUrlsFromCreateOutput(stdout, repository) {
|
|
|
46664
47435
|
sshUrl: `git@${fallbackHost}:${repository}.git`
|
|
46665
47436
|
};
|
|
46666
47437
|
}
|
|
46667
|
-
const make$
|
|
47438
|
+
const make$47 = Effect.gen(function* () {
|
|
46668
47439
|
const process = yield* VcsProcess;
|
|
46669
47440
|
const execute = (input) => process.run({
|
|
46670
47441
|
operation: "GitHubCli.execute",
|
|
@@ -46692,7 +47463,7 @@ const make$46 = Effect.gen(function* () {
|
|
|
46692
47463
|
"--limit",
|
|
46693
47464
|
String(input.limit ?? 1),
|
|
46694
47465
|
"--json",
|
|
46695
|
-
"number,title,url,baseRefName,headRefName,state,mergedAt,isCrossRepository,headRepository,headRepositoryOwner"
|
|
47466
|
+
"number,title,url,baseRefName,headRefName,state,mergedAt,closedAt,isCrossRepository,headRepository,headRepositoryOwner"
|
|
46696
47467
|
]
|
|
46697
47468
|
}).pipe(Effect.map((result) => result.stdout.trim()), Effect.flatMap((raw) => raw.length === 0 ? Effect.succeed([]) : Effect.sync(() => decodeGitHubPullRequestListJson(raw)).pipe(Effect.flatMap((decoded) => {
|
|
46698
47469
|
if (!Result.isSuccess(decoded)) return Effect.fail(new GitHubPullRequestListDecodeError({
|
|
@@ -46709,7 +47480,7 @@ const make$46 = Effect.gen(function* () {
|
|
|
46709
47480
|
"view",
|
|
46710
47481
|
input.reference,
|
|
46711
47482
|
"--json",
|
|
46712
|
-
"number,title,url,baseRefName,headRefName,state,mergedAt,isCrossRepository,headRepository,headRepositoryOwner"
|
|
47483
|
+
"number,title,url,baseRefName,headRefName,state,mergedAt,closedAt,isCrossRepository,headRepository,headRepositoryOwner"
|
|
46713
47484
|
]
|
|
46714
47485
|
}).pipe(Effect.map((result) => result.stdout.trim()), Effect.flatMap((raw) => Effect.sync(() => decodeGitHubPullRequestJson(raw)).pipe(Effect.flatMap((decoded) => {
|
|
46715
47486
|
if (!Result.isSuccess(decoded)) return Effect.fail(new GitHubPullRequestDecodeError({
|
|
@@ -46782,7 +47553,7 @@ const make$46 = Effect.gen(function* () {
|
|
|
46782
47553
|
}).pipe(Effect.asVoid)
|
|
46783
47554
|
});
|
|
46784
47555
|
});
|
|
46785
|
-
const layer$35 = Layer.effect(GitHubCli, make$
|
|
47556
|
+
const layer$35 = Layer.effect(GitHubCli, make$47);
|
|
46786
47557
|
//#endregion
|
|
46787
47558
|
//#region src/sourceControl/gitHubAuthStatus.ts
|
|
46788
47559
|
const GitHubAuthStatusAccountSchema = Schema$1.Struct({
|
|
@@ -46836,6 +47607,7 @@ function toChangeRequest$3(summary) {
|
|
|
46836
47607
|
headRefName: summary.headRefName,
|
|
46837
47608
|
state: summary.state ?? "open",
|
|
46838
47609
|
updatedAt: Option.none(),
|
|
47610
|
+
...summary.terminalAt == null ? {} : { terminalAt: summary.terminalAt },
|
|
46839
47611
|
...summary.isCrossRepository !== void 0 ? { isCrossRepository: summary.isCrossRepository } : {},
|
|
46840
47612
|
...summary.headRepositoryNameWithOwner !== void 0 ? { headRepositoryNameWithOwner: summary.headRepositoryNameWithOwner } : {},
|
|
46841
47613
|
...summary.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: summary.headRepositoryOwnerLogin } : {}
|
|
@@ -46883,7 +47655,7 @@ const discovery$1 = {
|
|
|
46883
47655
|
parseAuth: parseGitHubAuth,
|
|
46884
47656
|
installHint: "Install the GitHub command-line tool (`gh`) via https://cli.github.com/ or your package manager (for example `brew install gh`)."
|
|
46885
47657
|
};
|
|
46886
|
-
const make$
|
|
47658
|
+
const make$46 = Effect.gen(function* () {
|
|
46887
47659
|
const github = yield* GitHubCli;
|
|
46888
47660
|
const listChangeRequests = (input) => {
|
|
46889
47661
|
if (input.state === "open") return github.listOpenPullRequests({
|
|
@@ -46912,12 +47684,12 @@ const make$45 = Effect.gen(function* () {
|
|
|
46912
47684
|
"--limit",
|
|
46913
47685
|
String(input.limit ?? 20),
|
|
46914
47686
|
"--json",
|
|
46915
|
-
"number,title,url,baseRefName,headRefName,state,mergedAt,updatedAt,isCrossRepository,headRepository,headRepositoryOwner"
|
|
47687
|
+
"number,title,url,baseRefName,headRefName,state,mergedAt,closedAt,updatedAt,isCrossRepository,headRepository,headRepositoryOwner"
|
|
46916
47688
|
]
|
|
46917
47689
|
}).pipe(Effect.flatMap((result) => {
|
|
46918
47690
|
const raw = result.stdout.trim();
|
|
46919
|
-
if (raw.length === 0) return Effect.succeed([]);
|
|
46920
|
-
return Effect.sync(() => decodeGitHubPullRequestListJson(raw)).pipe(Effect.flatMap((decoded) => Result.isSuccess(decoded) ? Effect.succeed(decoded.success.map((item) => ({
|
|
47691
|
+
if (raw.length === 0 && !input.strict) return Effect.succeed([]);
|
|
47692
|
+
return Effect.sync(() => decodeGitHubPullRequestListJson(raw, input.strict)).pipe(Effect.flatMap((decoded) => Result.isSuccess(decoded) ? Effect.succeed(decoded.success.map((item) => ({
|
|
46921
47693
|
...toChangeRequest$3(item),
|
|
46922
47694
|
updatedAt: item.updatedAt
|
|
46923
47695
|
}))) : Effect.fail(new GitHubChangeRequestListDecodeError({
|
|
@@ -46999,7 +47771,7 @@ const make$45 = Effect.gen(function* () {
|
|
|
46999
47771
|
})))
|
|
47000
47772
|
});
|
|
47001
47773
|
});
|
|
47002
|
-
Layer.effect(SourceControlProvider, make$
|
|
47774
|
+
Layer.effect(SourceControlProvider, make$46);
|
|
47003
47775
|
//#endregion
|
|
47004
47776
|
//#region src/sourceControl/gitLabMergeRequests.ts
|
|
47005
47777
|
const GitLabProjectReferenceSchema = Schema$1.Struct({
|
|
@@ -47018,6 +47790,8 @@ const GitLabMergeRequestSchema = Schema$1.Struct({
|
|
|
47018
47790
|
source_branch: TrimmedNonEmptyString,
|
|
47019
47791
|
target_branch: TrimmedNonEmptyString,
|
|
47020
47792
|
state: Schema$1.optional(Schema$1.NullOr(Schema$1.String)),
|
|
47793
|
+
merged_at: Schema$1.optional(Schema$1.NullOr(Schema$1.String)),
|
|
47794
|
+
closed_at: Schema$1.optional(Schema$1.NullOr(Schema$1.String)),
|
|
47021
47795
|
updated_at: Schema$1.optional(Schema$1.OptionFromNullOr(Schema$1.DateTimeUtcFromString)),
|
|
47022
47796
|
source_project_id: Schema$1.optional(Schema$1.NullOr(Schema$1.Number)),
|
|
47023
47797
|
target_project_id: Schema$1.optional(Schema$1.NullOr(Schema$1.Number)),
|
|
@@ -47048,6 +47822,7 @@ function normalizeGitLabMergeRequestRecord(raw) {
|
|
|
47048
47822
|
const targetProjectPath = projectPathWithNamespace(raw.target_project);
|
|
47049
47823
|
const isCrossRepository = typeof raw.source_project_id === "number" && typeof raw.target_project_id === "number" ? raw.source_project_id !== raw.target_project_id : sourceProjectPath !== null && targetProjectPath !== null ? sourceProjectPath.toLowerCase() !== targetProjectPath.toLowerCase() : void 0;
|
|
47050
47824
|
const headRepositoryOwnerLogin = ownerLoginFromPathWithNamespace(sourceProjectPath);
|
|
47825
|
+
const terminalAt = normalizeGitLabMergeRequestState(raw.state) === "merged" ? raw.merged_at ?? null : normalizeGitLabMergeRequestState(raw.state) === "closed" ? raw.closed_at ?? null : null;
|
|
47051
47826
|
return {
|
|
47052
47827
|
number: raw.iid,
|
|
47053
47828
|
title: raw.title,
|
|
@@ -47056,6 +47831,7 @@ function normalizeGitLabMergeRequestRecord(raw) {
|
|
|
47056
47831
|
headRefName: raw.source_branch,
|
|
47057
47832
|
state: normalizeGitLabMergeRequestState(raw.state),
|
|
47058
47833
|
updatedAt: raw.updated_at ?? Option.none(),
|
|
47834
|
+
...terminalAt == null ? {} : { terminalAt },
|
|
47059
47835
|
...typeof isCrossRepository === "boolean" ? { isCrossRepository } : {},
|
|
47060
47836
|
...sourceProjectPath ? { headRepositoryNameWithOwner: sourceProjectPath } : {},
|
|
47061
47837
|
...headRepositoryOwnerLogin ? { headRepositoryOwnerLogin } : {}
|
|
@@ -47064,13 +47840,16 @@ function normalizeGitLabMergeRequestRecord(raw) {
|
|
|
47064
47840
|
const decodeGitLabMergeRequestList = decodeJsonResult(Schema$1.Array(Schema$1.Unknown));
|
|
47065
47841
|
const decodeGitLabMergeRequest = decodeJsonResult(GitLabMergeRequestSchema);
|
|
47066
47842
|
const decodeGitLabMergeRequestEntry = Schema$1.decodeUnknownExit(GitLabMergeRequestSchema);
|
|
47067
|
-
function decodeGitLabMergeRequestListJson(raw) {
|
|
47843
|
+
function decodeGitLabMergeRequestListJson(raw, strict = false) {
|
|
47068
47844
|
const result = decodeGitLabMergeRequestList(raw);
|
|
47069
47845
|
if (Result.isSuccess(result)) {
|
|
47070
47846
|
const mergeRequests = [];
|
|
47071
47847
|
for (const entry of result.success) {
|
|
47072
47848
|
const decodedEntry = decodeGitLabMergeRequestEntry(entry);
|
|
47073
|
-
if (Exit.isFailure(decodedEntry))
|
|
47849
|
+
if (Exit.isFailure(decodedEntry)) {
|
|
47850
|
+
if (strict) return Result.fail(decodedEntry.cause);
|
|
47851
|
+
continue;
|
|
47852
|
+
}
|
|
47074
47853
|
mergeRequests.push(normalizeGitLabMergeRequestRecord(decodedEntry.value));
|
|
47075
47854
|
}
|
|
47076
47855
|
return Result.succeed(mergeRequests);
|
|
@@ -47311,7 +48090,7 @@ function parseRepositoryPath(repository) {
|
|
|
47311
48090
|
projectPath
|
|
47312
48091
|
};
|
|
47313
48092
|
}
|
|
47314
|
-
const make$
|
|
48093
|
+
const make$45 = Effect.gen(function* () {
|
|
47315
48094
|
const process = yield* VcsProcess;
|
|
47316
48095
|
const run = (input, mapError) => process.run({
|
|
47317
48096
|
operation: "GitLabCli.execute",
|
|
@@ -47348,7 +48127,7 @@ const make$44 = Effect.gen(function* () {
|
|
|
47348
48127
|
"--output",
|
|
47349
48128
|
"json"
|
|
47350
48129
|
]
|
|
47351
|
-
}).pipe(Effect.map((result) => result.stdout.trim()), Effect.flatMap((raw) => raw.length === 0 ? Effect.succeed([]) : Effect.sync(() => decodeGitLabMergeRequestListJson(raw)).pipe(Effect.flatMap((decoded) => {
|
|
48130
|
+
}).pipe(Effect.map((result) => result.stdout.trim()), Effect.flatMap((raw) => raw.length === 0 && !input.strict ? Effect.succeed([]) : Effect.sync(() => decodeGitLabMergeRequestListJson(raw, input.strict)).pipe(Effect.flatMap((decoded) => {
|
|
47352
48131
|
if (!Result.isSuccess(decoded)) return Effect.fail(new GitLabMergeRequestListDecodeError({
|
|
47353
48132
|
operation: "listMergeRequests",
|
|
47354
48133
|
command: "glab",
|
|
@@ -47462,7 +48241,7 @@ const make$44 = Effect.gen(function* () {
|
|
|
47462
48241
|
}).pipe(Effect.asVoid)
|
|
47463
48242
|
});
|
|
47464
48243
|
});
|
|
47465
|
-
const layer$33 = Layer.effect(GitLabCli, make$
|
|
48244
|
+
const layer$33 = Layer.effect(GitLabCli, make$45);
|
|
47466
48245
|
//#endregion
|
|
47467
48246
|
//#region src/sourceControl/gitLabAuthStatus.ts
|
|
47468
48247
|
const HOST_LINE_PATTERN = /^(?:[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?|\[[a-f0-9:.]+\])(?::\d+)?$/iu;
|
|
@@ -47509,6 +48288,7 @@ function toChangeRequest$2(summary) {
|
|
|
47509
48288
|
headRefName: summary.headRefName,
|
|
47510
48289
|
state: summary.state ?? "open",
|
|
47511
48290
|
updatedAt: summary.updatedAt ?? Option.none(),
|
|
48291
|
+
...summary.terminalAt == null ? {} : { terminalAt: summary.terminalAt },
|
|
47512
48292
|
...summary.isCrossRepository !== void 0 ? { isCrossRepository: summary.isCrossRepository } : {},
|
|
47513
48293
|
...summary.headRepositoryNameWithOwner !== void 0 ? { headRepositoryNameWithOwner: summary.headRepositoryNameWithOwner } : {},
|
|
47514
48294
|
...summary.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: summary.headRepositoryOwnerLogin } : {}
|
|
@@ -47559,7 +48339,7 @@ const discovery = {
|
|
|
47559
48339
|
refineUnknownRemote: refineUnknownGitLabRemote,
|
|
47560
48340
|
installHint: "Install the GitLab command-line tool (`glab`) from https://gitlab.com/gitlab-org/cli or your package manager (for example `brew install glab`)."
|
|
47561
48341
|
};
|
|
47562
|
-
const make$
|
|
48342
|
+
const make$44 = Effect.gen(function* () {
|
|
47563
48343
|
const gitlab = yield* GitLabCli;
|
|
47564
48344
|
return SourceControlProvider.of({
|
|
47565
48345
|
kind: "gitlab",
|
|
@@ -47570,6 +48350,7 @@ const make$43 = Effect.gen(function* () {
|
|
|
47570
48350
|
headSelector: input.headSelector,
|
|
47571
48351
|
...source ? { source } : {},
|
|
47572
48352
|
state: input.state,
|
|
48353
|
+
...input.strict !== void 0 ? { strict: input.strict } : {},
|
|
47573
48354
|
...input.limit !== void 0 ? { limit: input.limit } : {}
|
|
47574
48355
|
}).pipe(Effect.map((items) => items.map(toChangeRequest$2)), Effect.mapError((error) => new SourceControlProviderError({
|
|
47575
48356
|
provider: "gitlab",
|
|
@@ -47647,7 +48428,7 @@ const make$43 = Effect.gen(function* () {
|
|
|
47647
48428
|
})))
|
|
47648
48429
|
});
|
|
47649
48430
|
});
|
|
47650
|
-
Layer.effect(SourceControlProvider, make$
|
|
48431
|
+
Layer.effect(SourceControlProvider, make$44);
|
|
47651
48432
|
//#endregion
|
|
47652
48433
|
//#region src/sourceControl/SourceControlProviderRegistry.ts
|
|
47653
48434
|
const PROVIDER_DETECTION_CACHE_CAPACITY = 2048;
|
|
@@ -47803,12 +48584,12 @@ const makeWithProviders = Effect.fn("makeSourceControlProviderRegistryWithProvid
|
|
|
47803
48584
|
})), { concurrency: "unbounded" })
|
|
47804
48585
|
});
|
|
47805
48586
|
});
|
|
47806
|
-
const make$
|
|
47807
|
-
const github = yield* make$
|
|
47808
|
-
const gitlab = yield* make$
|
|
47809
|
-
const bitbucket = yield* make$
|
|
48587
|
+
const make$43 = Effect.gen(function* () {
|
|
48588
|
+
const github = yield* make$46;
|
|
48589
|
+
const gitlab = yield* make$44;
|
|
48590
|
+
const bitbucket = yield* make$48;
|
|
47810
48591
|
const bitbucketDiscovery = yield* makeDiscovery;
|
|
47811
|
-
const azureDevOps = yield* make$
|
|
48592
|
+
const azureDevOps = yield* make$50;
|
|
47812
48593
|
return yield* makeWithProviders([
|
|
47813
48594
|
{
|
|
47814
48595
|
kind: "github",
|
|
@@ -47832,7 +48613,7 @@ const make$42 = Effect.gen(function* () {
|
|
|
47832
48613
|
}
|
|
47833
48614
|
]);
|
|
47834
48615
|
});
|
|
47835
|
-
const layer$31 = Layer.effect(SourceControlProviderRegistry, make$
|
|
48616
|
+
const layer$31 = Layer.effect(SourceControlProviderRegistry, make$43);
|
|
47836
48617
|
//#endregion
|
|
47837
48618
|
//#region src/sourceControl/PrTemplateDetection.ts
|
|
47838
48619
|
const TEMPLATE_MAX_BYTES = 8e3;
|
|
@@ -47954,6 +48735,7 @@ const detectPrTemplate = Effect.fn("detectPrTemplate")(function* (cwd, treeish,
|
|
|
47954
48735
|
});
|
|
47955
48736
|
//#endregion
|
|
47956
48737
|
//#region src/git/GitManager.ts
|
|
48738
|
+
const COMPLETION_PR_LIST_LIMIT = 100;
|
|
47957
48739
|
var GitManager = class extends Context.Service()("@p4code/cli/git/GitManager") {};
|
|
47958
48740
|
const COMMIT_TIMEOUT_MS = 10 * 6e4;
|
|
47959
48741
|
const MAX_PROGRESS_TEXT_LENGTH = 500;
|
|
@@ -48202,7 +48984,7 @@ function toPullRequestHeadRemoteInfo(pr) {
|
|
|
48202
48984
|
...pr.headRepositoryOwnerLogin !== void 0 ? { headRepositoryOwnerLogin: pr.headRepositoryOwnerLogin } : {}
|
|
48203
48985
|
};
|
|
48204
48986
|
}
|
|
48205
|
-
const make$
|
|
48987
|
+
const make$42 = Effect.gen(function* () {
|
|
48206
48988
|
const gitCore = yield* GitVcsDriver;
|
|
48207
48989
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
48208
48990
|
const textGeneration = yield* TextGeneration;
|
|
@@ -48580,6 +49362,57 @@ const make$41 = Effect.gen(function* () {
|
|
|
48580
49362
|
if (latestOpenPr) return latestOpenPr;
|
|
48581
49363
|
return parsed[0] ?? null;
|
|
48582
49364
|
});
|
|
49365
|
+
const threadCompletionPrState = Effect.fn("GitManager.threadCompletionPrState")(function* (input) {
|
|
49366
|
+
const details = yield* gitCore.statusDetails(input.cwd);
|
|
49367
|
+
if (!details.isRepo) return { state: "none" };
|
|
49368
|
+
if (!details.hasOriginRemote) {
|
|
49369
|
+
const remotes = yield* gitCore.execute({
|
|
49370
|
+
operation: "GitManager.threadCompletionPrState.remotes",
|
|
49371
|
+
cwd: input.cwd,
|
|
49372
|
+
args: ["remote"]
|
|
49373
|
+
});
|
|
49374
|
+
if (remotes.stdoutTruncated) return { state: "unknown" };
|
|
49375
|
+
if (remotes.stdout.trim().length === 0) return { state: "none" };
|
|
49376
|
+
}
|
|
49377
|
+
if (details.branch === null || input.branch !== null && details.branch !== input.branch) return { state: "unknown" };
|
|
49378
|
+
const context = yield* resolveBranchHeadContext(input.cwd, {
|
|
49379
|
+
branch: details.branch,
|
|
49380
|
+
upstreamRef: details.upstreamRef
|
|
49381
|
+
});
|
|
49382
|
+
const provider = yield* sourceControlProvider(input.cwd);
|
|
49383
|
+
if (context.headSelectors.length === 0) return { state: "unknown" };
|
|
49384
|
+
const terminalTimes = [];
|
|
49385
|
+
for (const headSelector of context.headSelectors) {
|
|
49386
|
+
const open = yield* provider.listChangeRequests({
|
|
49387
|
+
cwd: input.cwd,
|
|
49388
|
+
headSelector,
|
|
49389
|
+
state: "open",
|
|
49390
|
+
limit: COMPLETION_PR_LIST_LIMIT,
|
|
49391
|
+
strict: true
|
|
49392
|
+
});
|
|
49393
|
+
if (open.some((pr) => matchesBranchHeadContext(toPullRequestInfo(pr), context))) return { state: "open" };
|
|
49394
|
+
if (open.length > 0) return { state: "unknown" };
|
|
49395
|
+
const history = yield* provider.listChangeRequests({
|
|
49396
|
+
cwd: input.cwd,
|
|
49397
|
+
headSelector,
|
|
49398
|
+
state: "all",
|
|
49399
|
+
limit: COMPLETION_PR_LIST_LIMIT,
|
|
49400
|
+
strict: true
|
|
49401
|
+
});
|
|
49402
|
+
if (history.length >= COMPLETION_PR_LIST_LIMIT) return { state: "unknown" };
|
|
49403
|
+
for (const pr of history) {
|
|
49404
|
+
if (!matchesBranchHeadContext(toPullRequestInfo(pr), context)) return { state: "unknown" };
|
|
49405
|
+
if (pr.state === "open") return { state: "open" };
|
|
49406
|
+
if (pr.terminalAt == null || !Number.isFinite(Date.parse(pr.terminalAt))) return { state: "unknown" };
|
|
49407
|
+
terminalTimes.push(DateTime.formatIso(DateTime.makeUnsafe(pr.terminalAt)));
|
|
49408
|
+
}
|
|
49409
|
+
}
|
|
49410
|
+
const terminalAt = terminalTimes.toSorted().at(-1);
|
|
49411
|
+
return terminalAt === void 0 ? { state: "none" } : {
|
|
49412
|
+
state: "terminal",
|
|
49413
|
+
terminalAt
|
|
49414
|
+
};
|
|
49415
|
+
});
|
|
48583
49416
|
const buildCompletionToast = Effect.fn("buildCompletionToast")(function* (cwd, result) {
|
|
48584
49417
|
const terms = yield* sourceControlProvider(cwd).pipe(Effect.map((provider) => getChangeRequestTerminologyForKind(provider.kind)), Effect.orElseSucceed(() => getChangeRequestTerminologyForKind("unknown")));
|
|
48585
49418
|
const summary = summarizeGitActionResult(result, terms);
|
|
@@ -49113,6 +49946,7 @@ const make$41 = Effect.gen(function* () {
|
|
|
49113
49946
|
}))));
|
|
49114
49947
|
});
|
|
49115
49948
|
return GitManager.of({
|
|
49949
|
+
threadCompletionPrState,
|
|
49116
49950
|
localStatus,
|
|
49117
49951
|
remoteStatus,
|
|
49118
49952
|
status,
|
|
@@ -49124,7 +49958,7 @@ const make$41 = Effect.gen(function* () {
|
|
|
49124
49958
|
runStackedAction
|
|
49125
49959
|
});
|
|
49126
49960
|
});
|
|
49127
|
-
const layer$30 = Layer.effect(GitManager, make$
|
|
49961
|
+
const layer$30 = Layer.effect(GitManager, make$42);
|
|
49128
49962
|
//#endregion
|
|
49129
49963
|
//#region src/git/GitWorkflowService.ts
|
|
49130
49964
|
var GitWorkflowService = class extends Context.Service()("@p4code/cli/git/GitWorkflowService") {};
|
|
@@ -49161,7 +49995,7 @@ function nonRepositoryListRefs() {
|
|
|
49161
49995
|
totalCount: 0
|
|
49162
49996
|
};
|
|
49163
49997
|
}
|
|
49164
|
-
const make$
|
|
49998
|
+
const make$41 = Effect.gen(function* () {
|
|
49165
49999
|
const registry = yield* VcsDriverRegistry;
|
|
49166
50000
|
const git = yield* GitVcsDriver;
|
|
49167
50001
|
const gitManager = yield* GitManager;
|
|
@@ -49247,7 +50081,7 @@ const make$40 = Effect.gen(function* () {
|
|
|
49247
50081
|
renameBranch: (input) => ensureGit("GitWorkflowService.renameBranch", input.cwd).pipe(Effect.andThen(git.renameBranch(input)))
|
|
49248
50082
|
});
|
|
49249
50083
|
});
|
|
49250
|
-
const layer$29 = Layer.effect(GitWorkflowService, make$
|
|
50084
|
+
const layer$29 = Layer.effect(GitWorkflowService, make$41);
|
|
49251
50085
|
//#endregion
|
|
49252
50086
|
//#region src/pullRequest/PullRequestProvider.ts
|
|
49253
50087
|
/**
|
|
@@ -49608,7 +50442,7 @@ function isReviewerName(value) {
|
|
|
49608
50442
|
const name = value.trim();
|
|
49609
50443
|
return name.length > 0 && !name.startsWith("-");
|
|
49610
50444
|
}
|
|
49611
|
-
const make$
|
|
50445
|
+
const make$40 = Effect.gen(function* () {
|
|
49612
50446
|
const azure = yield* AzureDevOpsCli;
|
|
49613
50447
|
const detectArgs = ["--detect", "true"];
|
|
49614
50448
|
const executeJson = (input) => azure.execute({
|
|
@@ -49808,7 +50642,7 @@ const make$39 = Effect.gen(function* () {
|
|
|
49808
50642
|
}).pipe(Effect.asVoid)
|
|
49809
50643
|
});
|
|
49810
50644
|
});
|
|
49811
|
-
const layer$28 = Layer.effect(AzureDevOpsPullRequestCli, make$
|
|
50645
|
+
const layer$28 = Layer.effect(AzureDevOpsPullRequestCli, make$40);
|
|
49812
50646
|
//#endregion
|
|
49813
50647
|
//#region src/pullRequest/AzureDevOpsPullRequestProvider.ts
|
|
49814
50648
|
const CAPABILITIES$3 = {
|
|
@@ -49883,7 +50717,7 @@ function toChangeRequest$1(pullRequest) {
|
|
|
49883
50717
|
labels: []
|
|
49884
50718
|
};
|
|
49885
50719
|
}
|
|
49886
|
-
const make$
|
|
50720
|
+
const make$39 = Effect.gen(function* () {
|
|
49887
50721
|
const cli = yield* AzureDevOpsPullRequestCli;
|
|
49888
50722
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
49889
50723
|
provider: "azure-devops",
|
|
@@ -50623,7 +51457,7 @@ function mergeStrategy(method) {
|
|
|
50623
51457
|
default: return "merge_commit";
|
|
50624
51458
|
}
|
|
50625
51459
|
}
|
|
50626
|
-
const make$
|
|
51460
|
+
const make$38 = Effect.gen(function* () {
|
|
50627
51461
|
const bitbucket = yield* BitbucketApi;
|
|
50628
51462
|
/**
|
|
50629
51463
|
* The repository's own path, and the workspace above it — which the people who may review are
|
|
@@ -50903,7 +51737,7 @@ const make$37 = Effect.gen(function* () {
|
|
|
50903
51737
|
}).pipe(Effect.asVoid))
|
|
50904
51738
|
});
|
|
50905
51739
|
});
|
|
50906
|
-
const layer$27 = Layer.effect(BitbucketPullRequestApi, make$
|
|
51740
|
+
const layer$27 = Layer.effect(BitbucketPullRequestApi, make$38);
|
|
50907
51741
|
//#endregion
|
|
50908
51742
|
//#region src/pullRequest/BitbucketPullRequestProvider.ts
|
|
50909
51743
|
const CAPABILITIES$2 = {
|
|
@@ -50983,7 +51817,7 @@ function toChangeRequest(pullRequest) {
|
|
|
50983
51817
|
labels: []
|
|
50984
51818
|
};
|
|
50985
51819
|
}
|
|
50986
|
-
const make$
|
|
51820
|
+
const make$37 = Effect.gen(function* () {
|
|
50987
51821
|
const api = yield* BitbucketPullRequestApi;
|
|
50988
51822
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
50989
51823
|
provider: "bitbucket",
|
|
@@ -52870,7 +53704,7 @@ function actionArgs$1(action, mergeMethod, updateMethod) {
|
|
|
52870
53704
|
case "reopen": return ["reopen"];
|
|
52871
53705
|
}
|
|
52872
53706
|
}
|
|
52873
|
-
const make$
|
|
53707
|
+
const make$36 = Effect.gen(function* () {
|
|
52874
53708
|
const github = yield* GitHubCli;
|
|
52875
53709
|
/**
|
|
52876
53710
|
* The pull request's own node id, which is what a mutation against the pull request itself is
|
|
@@ -53590,7 +54424,7 @@ const make$35 = Effect.gen(function* () {
|
|
|
53590
54424
|
})))
|
|
53591
54425
|
});
|
|
53592
54426
|
});
|
|
53593
|
-
const layer$26 = Layer.effect(GitHubPullRequestCli, make$
|
|
54427
|
+
const layer$26 = Layer.effect(GitHubPullRequestCli, make$36);
|
|
53594
54428
|
//#endregion
|
|
53595
54429
|
//#region src/pullRequest/GitHubPullRequestProvider.ts
|
|
53596
54430
|
const CAPABILITIES$1 = {
|
|
@@ -53705,7 +54539,7 @@ function loginAvatarUrl(login, host) {
|
|
|
53705
54539
|
}
|
|
53706
54540
|
/** True where markdown would render nothing: whitespace, or only HTML comments. */
|
|
53707
54541
|
const rendersEmpty = (body) => body.replace(/<!--[\s\S]*?-->/g, "").trim().length === 0;
|
|
53708
|
-
const make$
|
|
54542
|
+
const make$35 = Effect.gen(function* () {
|
|
53709
54543
|
const cli = yield* GitHubPullRequestCli;
|
|
53710
54544
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
53711
54545
|
provider: "github",
|
|
@@ -54724,7 +55558,7 @@ function actionArgs(action, mergeMethod) {
|
|
|
54724
55558
|
case "reopen": return ["reopen"];
|
|
54725
55559
|
}
|
|
54726
55560
|
}
|
|
54727
|
-
const make$
|
|
55561
|
+
const make$34 = Effect.gen(function* () {
|
|
54728
55562
|
const gitlab = yield* GitLabCli;
|
|
54729
55563
|
const api = (input) => gitlab.execute({
|
|
54730
55564
|
cwd: input.cwd,
|
|
@@ -55295,7 +56129,7 @@ const make$33 = Effect.gen(function* () {
|
|
|
55295
56129
|
}).pipe(Effect.asVoid)
|
|
55296
56130
|
});
|
|
55297
56131
|
});
|
|
55298
|
-
const layer$25 = Layer.effect(GitLabPullRequestCli, make$
|
|
56132
|
+
const layer$25 = Layer.effect(GitLabPullRequestCli, make$34);
|
|
55299
56133
|
//#endregion
|
|
55300
56134
|
//#region src/pullRequest/GitLabPullRequestProvider.ts
|
|
55301
56135
|
const CAPABILITIES = {
|
|
@@ -55375,7 +56209,7 @@ function reasonFor(error) {
|
|
|
55375
56209
|
if (error._tag === "GitLabCliAuthenticationError") return "unauthenticated";
|
|
55376
56210
|
return "failed";
|
|
55377
56211
|
}
|
|
55378
|
-
const make$
|
|
56212
|
+
const make$33 = Effect.gen(function* () {
|
|
55379
56213
|
const cli = yield* GitLabPullRequestCli;
|
|
55380
56214
|
const fail = (operation) => (error) => new PullRequestProviderError({
|
|
55381
56215
|
provider: "gitlab",
|
|
@@ -55518,13 +56352,13 @@ function fromProviders(providers) {
|
|
|
55518
56352
|
* The hosts this build can read change requests from. A host with no entry here still shows up
|
|
55519
56353
|
* in the provider list as unimplemented, so its projects are explained rather than missing.
|
|
55520
56354
|
*/
|
|
55521
|
-
const make$
|
|
55522
|
-
make$
|
|
55523
|
-
make$
|
|
55524
|
-
make$
|
|
55525
|
-
make$
|
|
56355
|
+
const make$32 = Effect.map(Effect.all([
|
|
56356
|
+
make$35,
|
|
56357
|
+
make$33,
|
|
56358
|
+
make$37,
|
|
56359
|
+
make$39
|
|
55526
56360
|
]), fromProviders);
|
|
55527
|
-
const layer$24 = Layer.effect(PullRequestProviderRegistry, make$
|
|
56361
|
+
const layer$24 = Layer.effect(PullRequestProviderRegistry, make$32).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))));
|
|
55528
56362
|
//#endregion
|
|
55529
56363
|
//#region src/pullRequest/PullRequestService.ts
|
|
55530
56364
|
/**
|
|
@@ -55712,7 +56546,7 @@ function repositoryIdentityOf(project) {
|
|
|
55712
56546
|
if (identity.displayName) return identity.displayName;
|
|
55713
56547
|
return identity.owner && identity.name ? `${identity.owner}/${identity.name}` : null;
|
|
55714
56548
|
}
|
|
55715
|
-
const make$
|
|
56549
|
+
const make$31 = Effect.gen(function* () {
|
|
55716
56550
|
const registry = yield* PullRequestProviderRegistry;
|
|
55717
56551
|
const projections = yield* ProjectionSnapshotQuery;
|
|
55718
56552
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
@@ -56682,7 +57516,7 @@ const make$30 = Effect.gen(function* () {
|
|
|
56682
57516
|
invalidate
|
|
56683
57517
|
});
|
|
56684
57518
|
});
|
|
56685
|
-
const layer$23 = Layer.effect(PullRequestService, make$
|
|
57519
|
+
const layer$23 = Layer.effect(PullRequestService, make$31);
|
|
56686
57520
|
//#endregion
|
|
56687
57521
|
//#region src/orchestration/ThreadWorkspaceLifecycle.ts
|
|
56688
57522
|
var ThreadWorkspaceLifecycleError = class extends Data.TaggedError("ThreadWorkspaceLifecycleError") {};
|
|
@@ -56726,7 +57560,7 @@ const mapLifecycleError = Effect.mapError((cause) => cause instanceof ThreadWork
|
|
|
56726
57560
|
detail: "Thread workspace lifecycle operation failed.",
|
|
56727
57561
|
cause
|
|
56728
57562
|
}));
|
|
56729
|
-
const make$
|
|
57563
|
+
const make$30 = Effect.gen(function* () {
|
|
56730
57564
|
const snapshots = yield* ProjectionSnapshotQuery;
|
|
56731
57565
|
const engine = yield* OrchestrationEngineService;
|
|
56732
57566
|
const gitWorkflow = yield* GitWorkflowService;
|
|
@@ -56980,7 +57814,7 @@ const make$29 = Effect.gen(function* () {
|
|
|
56980
57814
|
record
|
|
56981
57815
|
};
|
|
56982
57816
|
});
|
|
56983
|
-
const layer$22 = Layer.effect(ThreadWorkspaceLifecycleService, make$
|
|
57817
|
+
const layer$22 = Layer.effect(ThreadWorkspaceLifecycleService, make$30);
|
|
56984
57818
|
//#endregion
|
|
56985
57819
|
//#region src/textGeneration/BtwRequestCoordinator.ts
|
|
56986
57820
|
const MAX_PENDING_BTW_CANCELLATIONS = 256;
|
|
@@ -59524,7 +60358,7 @@ function makeUpdateState(input) {
|
|
|
59524
60358
|
output: input.output ?? null
|
|
59525
60359
|
};
|
|
59526
60360
|
}
|
|
59527
|
-
const make$
|
|
60361
|
+
const make$29 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
59528
60362
|
const providerRegistry = yield* ProviderRegistry;
|
|
59529
60363
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
59530
60364
|
const httpClient = yield* HttpClient.HttpClient;
|
|
@@ -59639,7 +60473,7 @@ const make$28 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
|
|
|
59639
60473
|
});
|
|
59640
60474
|
return ProviderMaintenanceRunner.of({ updateProvider });
|
|
59641
60475
|
});
|
|
59642
|
-
const layer$21 = Layer.effect(ProviderMaintenanceRunner, make$
|
|
60476
|
+
const layer$21 = Layer.effect(ProviderMaintenanceRunner, make$29());
|
|
59643
60477
|
//#endregion
|
|
59644
60478
|
//#region src/provider/Drivers/ClaudeHome.ts
|
|
59645
60479
|
const resolveClaudeHomePath = Effect.fn("resolveClaudeHomePath")(function* (config) {
|
|
@@ -60749,7 +61583,7 @@ Layer.succeed(UsageService, UsageService.of({ readSummary: (input) => Effect.suc
|
|
|
60749
61583
|
},
|
|
60750
61584
|
scanDurationMs: 0
|
|
60751
61585
|
}) }));
|
|
60752
|
-
const make$
|
|
61586
|
+
const make$28 = Effect.gen(function* () {
|
|
60753
61587
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
60754
61588
|
const path = yield* Path.Path;
|
|
60755
61589
|
const config = yield* ServerConfig$1;
|
|
@@ -60987,7 +61821,7 @@ const make$27 = Effect.gen(function* () {
|
|
|
60987
61821
|
};
|
|
60988
61822
|
}) };
|
|
60989
61823
|
});
|
|
60990
|
-
const layer$20 = Layer.effect(UsageService, make$
|
|
61824
|
+
const layer$20 = Layer.effect(UsageService, make$28);
|
|
60991
61825
|
//#endregion
|
|
60992
61826
|
//#region src/feed/FeedStore.ts
|
|
60993
61827
|
const storageFailure = (message) => new FeedError({
|
|
@@ -61351,7 +62185,7 @@ const jsonRequest = Effect.fn("FeedService.jsonRequest")(function* (url, token,
|
|
|
61351
62185
|
catch: () => fail("hub_unavailable", "Hub returned invalid JSON.")
|
|
61352
62186
|
});
|
|
61353
62187
|
});
|
|
61354
|
-
const make$
|
|
62188
|
+
const make$27 = Effect.gen(function* () {
|
|
61355
62189
|
const hubLink = yield* HubLink;
|
|
61356
62190
|
const providers = yield* ProviderInstanceRegistry;
|
|
61357
62191
|
const config = yield* ServerConfig$1;
|
|
@@ -61589,7 +62423,7 @@ var FeedService = class extends Context.Reference("@p4code/cli/feed/FeedService"
|
|
|
61589
62423
|
markRead: unavailable,
|
|
61590
62424
|
cleanup: unavailable
|
|
61591
62425
|
}) }) {};
|
|
61592
|
-
const layer$19 = Layer.effect(FeedService, make$
|
|
62426
|
+
const layer$19 = Layer.effect(FeedService, make$27);
|
|
61593
62427
|
const SKILL_MANIFEST_FILENAME = "SKILL.md";
|
|
61594
62428
|
/**
|
|
61595
62429
|
* Split a catalogue id (`owner/repo/skill-name`) into its parts.
|
|
@@ -61735,7 +62569,7 @@ const emptyFetch = (id, unavailable) => ({
|
|
|
61735
62569
|
skipped: [],
|
|
61736
62570
|
unavailable
|
|
61737
62571
|
});
|
|
61738
|
-
const make$
|
|
62572
|
+
const make$26 = Effect.gen(function* () {
|
|
61739
62573
|
const http = yield* HttpClient.HttpClient;
|
|
61740
62574
|
const request = Effect.fn("SkillRegistry.request")(function* (url) {
|
|
61741
62575
|
return yield* http.execute(HttpClientRequest.get(url).pipe(HttpClientRequest.setHeader("accept", "application/json"), HttpClientRequest.setHeader("user-agent", "p4code"))).pipe(Effect.timeout(REQUEST_TIMEOUT_MS));
|
|
@@ -61806,7 +62640,7 @@ const make$25 = Effect.gen(function* () {
|
|
|
61806
62640
|
fetch
|
|
61807
62641
|
};
|
|
61808
62642
|
});
|
|
61809
|
-
const layer$18 = Layer.effect(SkillRegistry, make$
|
|
62643
|
+
const layer$18 = Layer.effect(SkillRegistry, make$26);
|
|
61810
62644
|
//#endregion
|
|
61811
62645
|
//#region src/mcp/McpInvocationContext.ts
|
|
61812
62646
|
var McpInvocationContext = class extends Context.Service()("@p4code/cli/mcp/McpInvocationContext") {};
|
|
@@ -61909,9 +62743,9 @@ const requireThreadControlTarget = Effect.fn("mcp.requireThreadControlTarget")(f
|
|
|
61909
62743
|
* The guard on starting a thread, which is a different question from acting on
|
|
61910
62744
|
* one: it is not "which thread" but "may this session make more of them".
|
|
61911
62745
|
*/
|
|
61912
|
-
const requireThreadSpawn = Effect.fn("mcp.requireThreadSpawn")(function* () {
|
|
62746
|
+
const requireThreadSpawn = Effect.fn("mcp.requireThreadSpawn")(function* (fusion = false) {
|
|
61913
62747
|
const invocation = yield* requireThreadCapability();
|
|
61914
|
-
if (invocation.mayCreateThreads !== true) return yield* new ThreadSpawnNotPermittedError({
|
|
62748
|
+
if (invocation.mayCreateThreads !== true && !(fusion && invocation.mayCreateFusionPairs === true)) return yield* new ThreadSpawnNotPermittedError({
|
|
61915
62749
|
threadId: invocation.threadId,
|
|
61916
62750
|
detail: "this thread was itself started by an agent, and spawning goes one level deep so a runaway loop has a bound"
|
|
61917
62751
|
});
|
|
@@ -62034,7 +62868,7 @@ const classifyResponseError = (context, error) => {
|
|
|
62034
62868
|
});
|
|
62035
62869
|
}
|
|
62036
62870
|
};
|
|
62037
|
-
const make$
|
|
62871
|
+
const make$25 = Effect.gen(function* PreviewAutomationBrokerMake() {
|
|
62038
62872
|
const crypto = yield* Crypto.Crypto;
|
|
62039
62873
|
const state = yield* SynchronizedRef.make({
|
|
62040
62874
|
clients: /* @__PURE__ */ new Map(),
|
|
@@ -62268,7 +63102,7 @@ const make$24 = Effect.gen(function* PreviewAutomationBrokerMake() {
|
|
|
62268
63102
|
invoke
|
|
62269
63103
|
});
|
|
62270
63104
|
}).pipe(Effect.withSpan("PreviewAutomationBroker.make"));
|
|
62271
|
-
const layer$17 = Layer.effect(PreviewAutomationBroker, make$
|
|
63105
|
+
const layer$17 = Layer.effect(PreviewAutomationBroker, make$25);
|
|
62272
63106
|
//#endregion
|
|
62273
63107
|
//#region src/preview/Manager.ts
|
|
62274
63108
|
/**
|
|
@@ -62332,7 +63166,7 @@ const buildIdleSnapshot = (input) => ({
|
|
|
62332
63166
|
viewport: FILL_PREVIEW_VIEWPORT,
|
|
62333
63167
|
updatedAt: input.updatedAt
|
|
62334
63168
|
});
|
|
62335
|
-
const make$
|
|
63169
|
+
const make$24 = Effect.gen(function* PreviewManagerMake() {
|
|
62336
63170
|
const serverEpoch = NodeCrypto.randomUUID();
|
|
62337
63171
|
const stateRef = yield* SynchronizedRef.make(initialState);
|
|
62338
63172
|
const eventsPubSub = yield* PubSub.unbounded();
|
|
@@ -62563,12 +63397,15 @@ const make$23 = Effect.gen(function* PreviewManagerMake() {
|
|
|
62563
63397
|
subscribeEvents: PubSub.subscribe(eventsPubSub)
|
|
62564
63398
|
});
|
|
62565
63399
|
}).pipe(Effect.withSpan("PreviewManager.make"));
|
|
62566
|
-
const layer$16 = Layer.effect(PreviewManager, make$
|
|
63400
|
+
const layer$16 = Layer.effect(PreviewManager, make$24);
|
|
62567
63401
|
//#endregion
|
|
62568
63402
|
//#region src/workspace/WorkspaceSearchIndex.ts
|
|
62569
63403
|
const WORKSPACE_INDEX_MAX_ENTRIES = 25e3;
|
|
62570
63404
|
const WORKSPACE_INDEX_PAGE_SIZE = 25002;
|
|
62571
63405
|
const WORKSPACE_INDEX_SCAN_TIMEOUT = "15 seconds";
|
|
63406
|
+
const CONTENT_SEARCH_TIME_BUDGET_MS = 250;
|
|
63407
|
+
const CONTENT_SEARCH_MAX_MATCHES_PER_FILE = 100;
|
|
63408
|
+
const CONTENT_INDEX_READY_TIMEOUT_MS = 15e3;
|
|
62572
63409
|
const WORKSPACE_INDEX_IDLE_TTL = "15 minutes";
|
|
62573
63410
|
const WORKSPACE_INDEX_SCAN_POLL_INTERVAL = "50 millis";
|
|
62574
63411
|
var WorkspaceSearchIndexCreateFailed = class extends Schema$1.TaggedErrorClass()("WorkspaceSearchIndexCreateFailed", {
|
|
@@ -62662,12 +63499,12 @@ function withDirectoryAncestors(entries) {
|
|
|
62662
63499
|
}
|
|
62663
63500
|
return [...entryByPath.values()];
|
|
62664
63501
|
}
|
|
62665
|
-
const createFinder = Effect.fn("WorkspaceSearchIndex.createFinder")(function* (cwd) {
|
|
63502
|
+
const createFinder = Effect.fn("WorkspaceSearchIndex.createFinder")(function* (cwd, contentSearch) {
|
|
62666
63503
|
const result = yield* Effect.try({
|
|
62667
63504
|
try: () => FileFinder.create({
|
|
62668
63505
|
basePath: cwd,
|
|
62669
63506
|
disableMmapCache: true,
|
|
62670
|
-
disableContentIndexing:
|
|
63507
|
+
disableContentIndexing: !contentSearch,
|
|
62671
63508
|
aiMode: false,
|
|
62672
63509
|
enableFsRootScanning: true,
|
|
62673
63510
|
enableHomeDirScanning: true
|
|
@@ -62697,8 +63534,8 @@ const waitForScan = (cwd, finder, onFailure) => Effect.try({
|
|
|
62697
63534
|
timeout: WORKSPACE_INDEX_SCAN_TIMEOUT
|
|
62698
63535
|
})
|
|
62699
63536
|
}), Effect.withSpan("WorkspaceSearchIndex.waitForScan"));
|
|
62700
|
-
const make$
|
|
62701
|
-
const finder = yield* Effect.acquireRelease(createFinder(cwd), (finder) => Effect.try({
|
|
63537
|
+
const make$23 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd, contentSearch = false) {
|
|
63538
|
+
const finder = yield* Effect.acquireRelease(createFinder(cwd, contentSearch), (finder) => Effect.try({
|
|
62702
63539
|
try: () => finder.destroy(),
|
|
62703
63540
|
catch: (cause) => new WorkspaceSearchIndexDestroyFailed({
|
|
62704
63541
|
cwd,
|
|
@@ -62710,6 +63547,24 @@ const make$22 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd) {
|
|
|
62710
63547
|
reason: "FileFinder.isScanning threw while creating the index.",
|
|
62711
63548
|
cause
|
|
62712
63549
|
}));
|
|
63550
|
+
if (contentSearch) {
|
|
63551
|
+
const ready = yield* Effect.tryPromise({
|
|
63552
|
+
try: () => finder.waitForIndexReady(CONTENT_INDEX_READY_TIMEOUT_MS),
|
|
63553
|
+
catch: (cause) => new WorkspaceSearchIndexCreateFailed({
|
|
63554
|
+
cwd,
|
|
63555
|
+
reason: "Content index initialization failed.",
|
|
63556
|
+
cause
|
|
63557
|
+
})
|
|
63558
|
+
});
|
|
63559
|
+
if (!ready.ok) return yield* new WorkspaceSearchIndexCreateFailed({
|
|
63560
|
+
cwd,
|
|
63561
|
+
reason: ready.error
|
|
63562
|
+
});
|
|
63563
|
+
if (!ready.value) return yield* new WorkspaceSearchIndexScanTimedOut({
|
|
63564
|
+
cwd,
|
|
63565
|
+
timeout: WORKSPACE_INDEX_SCAN_TIMEOUT
|
|
63566
|
+
});
|
|
63567
|
+
}
|
|
62713
63568
|
const runMixedSearch = Effect.fn("WorkspaceSearchIndex.runMixedSearch")(function* (query, pageSize) {
|
|
62714
63569
|
const result = yield* Effect.try({
|
|
62715
63570
|
try: () => finder.mixedSearch(query, { pageSize }),
|
|
@@ -62760,10 +63615,58 @@ const make$22 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd) {
|
|
|
62760
63615
|
const search = Effect.fn("WorkspaceSearchIndex.search")(function* (query, limit) {
|
|
62761
63616
|
return mapMixedSearchResult(yield* runMixedSearch(query, Math.max(1, limit + 1)), limit);
|
|
62762
63617
|
});
|
|
63618
|
+
const searchContents = Effect.fn("WorkspaceSearchIndex.searchContents")(function* (input) {
|
|
63619
|
+
const deadline = performance.now() + CONTENT_SEARCH_TIME_BUDGET_MS;
|
|
63620
|
+
const matches = [];
|
|
63621
|
+
let cursor = null;
|
|
63622
|
+
do {
|
|
63623
|
+
const result = yield* Effect.try({
|
|
63624
|
+
try: () => finder.grep(input.query, {
|
|
63625
|
+
mode: "plain",
|
|
63626
|
+
smartCase: true,
|
|
63627
|
+
maxMatchesPerFile: Math.min(CONTENT_SEARCH_MAX_MATCHES_PER_FILE, input.limit),
|
|
63628
|
+
pageSize: input.limit - matches.length,
|
|
63629
|
+
timeBudgetMs: Math.max(1, Math.ceil(deadline - performance.now())),
|
|
63630
|
+
cursor
|
|
63631
|
+
}),
|
|
63632
|
+
catch: (cause) => new WorkspaceSearchIndexSearchFailed({
|
|
63633
|
+
cwd,
|
|
63634
|
+
queryLength: input.query.length,
|
|
63635
|
+
pageSize: input.limit,
|
|
63636
|
+
reason: "Content search failed.",
|
|
63637
|
+
cause
|
|
63638
|
+
})
|
|
63639
|
+
});
|
|
63640
|
+
if (!result.ok) return yield* new WorkspaceSearchIndexSearchFailed({
|
|
63641
|
+
cwd,
|
|
63642
|
+
queryLength: input.query.length,
|
|
63643
|
+
pageSize: input.limit,
|
|
63644
|
+
reason: result.error
|
|
63645
|
+
});
|
|
63646
|
+
for (const match of result.value.items) {
|
|
63647
|
+
const bytes = Buffer.from(match.lineContent);
|
|
63648
|
+
matches.push({
|
|
63649
|
+
path: toPosixPath(match.relativePath),
|
|
63650
|
+
lineNumber: match.lineNumber,
|
|
63651
|
+
lineContent: match.lineContent,
|
|
63652
|
+
matchRanges: match.matchRanges.map(([start, end]) => ({
|
|
63653
|
+
start: bytes.subarray(0, start).toString().length,
|
|
63654
|
+
end: bytes.subarray(0, end).toString().length
|
|
63655
|
+
}))
|
|
63656
|
+
});
|
|
63657
|
+
}
|
|
63658
|
+
cursor = result.value.nextCursor;
|
|
63659
|
+
} while (matches.length < input.limit && cursor !== null && performance.now() < deadline);
|
|
63660
|
+
return {
|
|
63661
|
+
matches: matches.slice(0, input.limit),
|
|
63662
|
+
truncated: matches.length > input.limit || cursor !== null
|
|
63663
|
+
};
|
|
63664
|
+
});
|
|
62763
63665
|
return WorkspaceSearchIndex.of({
|
|
62764
63666
|
list,
|
|
62765
63667
|
refresh,
|
|
62766
|
-
search
|
|
63668
|
+
search,
|
|
63669
|
+
searchContents
|
|
62767
63670
|
});
|
|
62768
63671
|
});
|
|
62769
63672
|
/**
|
|
@@ -62771,11 +63674,16 @@ const make$22 = Effect.fn("WorkspaceSearchIndex.make")(function* (cwd) {
|
|
|
62771
63674
|
* workspace root. WorkspaceSearchIndexMap owns memoization and idle cleanup;
|
|
62772
63675
|
* using a default cwd here would mix resources from different workspaces.
|
|
62773
63676
|
*/
|
|
62774
|
-
const layer$15 = (cwd) => Layer.effect(WorkspaceSearchIndex, make$
|
|
63677
|
+
const layer$15 = (cwd) => Layer.effect(WorkspaceSearchIndex, make$23(cwd));
|
|
62775
63678
|
var WorkspaceSearchIndexMap = class extends LayerMap.Service()("@p4code/cli/workspace/WorkspaceSearchIndexMap", {
|
|
62776
63679
|
lookup: layer$15,
|
|
62777
63680
|
idleTimeToLive: WORKSPACE_INDEX_IDLE_TTL
|
|
62778
63681
|
}) {};
|
|
63682
|
+
/** Content indexing is allocated only when workspace content search is used. */
|
|
63683
|
+
var WorkspaceContentSearchIndexMap = class extends LayerMap.Service()("@p4code/cli/workspace/WorkspaceContentSearchIndexMap", {
|
|
63684
|
+
lookup: (cwd) => Layer.effect(WorkspaceSearchIndex, make$23(cwd, true)),
|
|
63685
|
+
idleTimeToLive: WORKSPACE_INDEX_IDLE_TTL
|
|
63686
|
+
}) {};
|
|
62779
63687
|
//#endregion
|
|
62780
63688
|
//#region src/workspace/WorkspaceEntries.ts
|
|
62781
63689
|
var WorkspaceEntriesWindowsPathUnsupportedError = class extends Schema$1.TaggedErrorClass()("WorkspaceEntriesWindowsPathUnsupportedError", {
|
|
@@ -62835,9 +63743,10 @@ const resolveBrowseTarget = Effect.fn("WorkspaceEntries.resolveBrowseTarget")(fu
|
|
|
62835
63743
|
if (!input.cwd) return yield* new WorkspaceEntriesCurrentProjectRequiredError({ partialPath: input.partialPath });
|
|
62836
63744
|
return path.resolve(expandHomePath$1(input.cwd, path), input.partialPath);
|
|
62837
63745
|
});
|
|
62838
|
-
const make$
|
|
63746
|
+
const make$22 = Effect.gen(function* () {
|
|
62839
63747
|
const path = yield* Path.Path;
|
|
62840
63748
|
const workspacePaths = yield* WorkspacePaths;
|
|
63749
|
+
const contentSearchIndexes = yield* WorkspaceContentSearchIndexMap;
|
|
62841
63750
|
const workspaceSearchIndexes = yield* WorkspaceSearchIndexMap;
|
|
62842
63751
|
const normalizeWorkspaceRoot = Effect.fn("WorkspaceEntries.normalizeWorkspaceRoot")(function* (cwd) {
|
|
62843
63752
|
return yield* workspacePaths.normalizeWorkspaceRoot(cwd);
|
|
@@ -62902,14 +63811,21 @@ const make$21 = Effect.gen(function* () {
|
|
|
62902
63811
|
return yield* (yield* WorkspaceSearchIndex).list();
|
|
62903
63812
|
}).pipe(Effect.provide(workspaceSearchIndexes.get(normalizedCwd)));
|
|
62904
63813
|
});
|
|
63814
|
+
const searchContents = Effect.fn("WorkspaceEntries.searchContents")(function* (input) {
|
|
63815
|
+
const cwd = yield* normalizeWorkspaceRoot(input.cwd);
|
|
63816
|
+
return yield* Effect.gen(function* () {
|
|
63817
|
+
return yield* (yield* WorkspaceSearchIndex).searchContents(input);
|
|
63818
|
+
}).pipe(Effect.provide(contentSearchIndexes.get(cwd)));
|
|
63819
|
+
});
|
|
62905
63820
|
return WorkspaceEntries.of({
|
|
62906
63821
|
browse,
|
|
62907
63822
|
list,
|
|
62908
63823
|
refresh,
|
|
62909
|
-
search
|
|
63824
|
+
search,
|
|
63825
|
+
searchContents
|
|
62910
63826
|
});
|
|
62911
63827
|
});
|
|
62912
|
-
const layer$14 = Layer.effect(WorkspaceEntries, make$
|
|
63828
|
+
const layer$14 = Layer.effect(WorkspaceEntries, make$22).pipe(Layer.provide(WorkspaceSearchIndexMap.layer), Layer.provide(WorkspaceContentSearchIndexMap.layer));
|
|
62913
63829
|
//#endregion
|
|
62914
63830
|
//#region src/workspace/WorkspaceFileSystem.ts
|
|
62915
63831
|
/**
|
|
@@ -62968,7 +63884,7 @@ Schema$1.Union([
|
|
|
62968
63884
|
]);
|
|
62969
63885
|
/** Service tag for workspace file operations. */
|
|
62970
63886
|
var WorkspaceFileSystem = class extends Context.Service()("@p4code/cli/workspace/WorkspaceFileSystem") {};
|
|
62971
|
-
const make$
|
|
63887
|
+
const make$21 = Effect.gen(function* () {
|
|
62972
63888
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
62973
63889
|
const path = yield* Path.Path;
|
|
62974
63890
|
const workspacePaths = yield* WorkspacePaths;
|
|
@@ -63112,7 +64028,7 @@ const make$20 = Effect.gen(function* () {
|
|
|
63112
64028
|
writeFile
|
|
63113
64029
|
});
|
|
63114
64030
|
});
|
|
63115
|
-
const layer$13 = Layer.effect(WorkspaceFileSystem, make$
|
|
64031
|
+
const layer$13 = Layer.effect(WorkspaceFileSystem, make$21);
|
|
63116
64032
|
//#endregion
|
|
63117
64033
|
//#region src/vcs/VcsStatusBroadcaster.ts
|
|
63118
64034
|
const DEFAULT_VCS_STATUS_REFRESH_INTERVAL = Duration.seconds(30);
|
|
@@ -63184,7 +64100,7 @@ function fingerprintStatusPart(status) {
|
|
|
63184
64100
|
return JSON.stringify(status);
|
|
63185
64101
|
}
|
|
63186
64102
|
const normalizeCwd = (cwd) => Effect.service(FileSystem.FileSystem).pipe(Effect.flatMap((fs) => fs.realPath(cwd)), Effect.orElseSucceed(() => cwd));
|
|
63187
|
-
const make$
|
|
64103
|
+
const make$20 = Effect.gen(function* () {
|
|
63188
64104
|
const workflow = yield* GitWorkflowService;
|
|
63189
64105
|
const fs = yield* FileSystem.FileSystem;
|
|
63190
64106
|
const changesPubSub = yield* Effect.acquireRelease(PubSub.unbounded(), (pubsub) => PubSub.shutdown(pubsub));
|
|
@@ -63408,7 +64324,7 @@ const make$19 = Effect.gen(function* () {
|
|
|
63408
64324
|
streamStatus
|
|
63409
64325
|
});
|
|
63410
64326
|
});
|
|
63411
|
-
const layer$12 = Layer.effect(VcsStatusBroadcaster, make$
|
|
64327
|
+
const layer$12 = Layer.effect(VcsStatusBroadcaster, make$20);
|
|
63412
64328
|
//#endregion
|
|
63413
64329
|
//#region src/vcs/VcsProvisioningService.ts
|
|
63414
64330
|
var VcsProvisioningService = class extends Context.Service()("@p4code/cli/vcs/VcsProvisioningService") {};
|
|
@@ -63421,7 +64337,7 @@ function resolveRequestedKind(kind) {
|
|
|
63421
64337
|
}));
|
|
63422
64338
|
return Effect.succeed(kind);
|
|
63423
64339
|
}
|
|
63424
|
-
const make$
|
|
64340
|
+
const make$19 = Effect.gen(function* () {
|
|
63425
64341
|
const registry = yield* VcsDriverRegistry;
|
|
63426
64342
|
const initRepository = Effect.fn("VcsProvisioningService.initRepository")(function* (input) {
|
|
63427
64343
|
const kind = yield* resolveRequestedKind(input.kind);
|
|
@@ -63429,11 +64345,11 @@ const make$18 = Effect.gen(function* () {
|
|
|
63429
64345
|
});
|
|
63430
64346
|
return VcsProvisioningService.of({ initRepository });
|
|
63431
64347
|
});
|
|
63432
|
-
const layer$11 = Layer.effect(VcsProvisioningService, make$
|
|
64348
|
+
const layer$11 = Layer.effect(VcsProvisioningService, make$19);
|
|
63433
64349
|
//#endregion
|
|
63434
64350
|
//#region src/review/ReviewService.ts
|
|
63435
64351
|
var ReviewService = class extends Context.Service()("@p4code/cli/review/ReviewService") {};
|
|
63436
|
-
const make$
|
|
64352
|
+
const make$18 = Effect.gen(function* () {
|
|
63437
64353
|
const config = yield* ServerConfig$1;
|
|
63438
64354
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
63439
64355
|
const path = yield* Path.Path;
|
|
@@ -63489,7 +64405,7 @@ const make$17 = Effect.gen(function* () {
|
|
|
63489
64405
|
});
|
|
63490
64406
|
return ReviewService.of({ getDiffPreview });
|
|
63491
64407
|
});
|
|
63492
|
-
const layer$10 = Layer.effect(ReviewService, make$
|
|
64408
|
+
const layer$10 = Layer.effect(ReviewService, make$18);
|
|
63493
64409
|
//#endregion
|
|
63494
64410
|
//#region src/diagnostics/ProcessDiagnostics.ts
|
|
63495
64411
|
const PROCESS_QUERY_TIMEOUT_MS = 1e3;
|
|
@@ -63784,7 +64700,7 @@ function assertDescendantPid(pid) {
|
|
|
63784
64700
|
}));
|
|
63785
64701
|
}));
|
|
63786
64702
|
}
|
|
63787
|
-
const make$
|
|
64703
|
+
const make$17 = Effect.gen(function* () {
|
|
63788
64704
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
63789
64705
|
const read = Effect.gen(function* () {
|
|
63790
64706
|
const readAt = yield* DateTime.now;
|
|
@@ -63828,7 +64744,7 @@ const make$16 = Effect.gen(function* () {
|
|
|
63828
64744
|
signal
|
|
63829
64745
|
});
|
|
63830
64746
|
});
|
|
63831
|
-
const layer$9 = Layer.effect(ProcessDiagnostics, make$
|
|
64747
|
+
const layer$9 = Layer.effect(ProcessDiagnostics, make$17);
|
|
63832
64748
|
//#endregion
|
|
63833
64749
|
//#region src/diagnostics/ProcessResourceMonitor.ts
|
|
63834
64750
|
const SAMPLE_INTERVAL_MS = 5e3;
|
|
@@ -63979,7 +64895,7 @@ function aggregateProcessResourceHistory(input) {
|
|
|
63979
64895
|
}) : Option.none()
|
|
63980
64896
|
};
|
|
63981
64897
|
}
|
|
63982
|
-
const make$
|
|
64898
|
+
const make$16 = Effect.gen(function* () {
|
|
63983
64899
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
63984
64900
|
const state = yield* Ref.make({
|
|
63985
64901
|
samples: [],
|
|
@@ -64028,7 +64944,7 @@ const make$15 = Effect.gen(function* () {
|
|
|
64028
64944
|
});
|
|
64029
64945
|
return ProcessResourceMonitor.of({ readHistory });
|
|
64030
64946
|
});
|
|
64031
|
-
const layer$8 = Layer.effect(ProcessResourceMonitor, make$
|
|
64947
|
+
const layer$8 = Layer.effect(ProcessResourceMonitor, make$16);
|
|
64032
64948
|
//#endregion
|
|
64033
64949
|
//#region src/diagnostics/TraceDiagnostics.ts
|
|
64034
64950
|
var TraceFileReadError = class extends Schema$1.TaggedErrorClass()("TraceFileReadError", {
|
|
@@ -64276,7 +65192,7 @@ function readTraceFile(fileSystem, path) {
|
|
|
64276
65192
|
cause
|
|
64277
65193
|
})) }));
|
|
64278
65194
|
}
|
|
64279
|
-
const make$
|
|
65195
|
+
const make$15 = Effect.gen(function* () {
|
|
64280
65196
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
64281
65197
|
const read = Effect.fn("TraceDiagnostics.read")(function* (options) {
|
|
64282
65198
|
const readAt = options.readAt ?? (yield* DateTime.now);
|
|
@@ -64320,7 +65236,7 @@ const make$14 = Effect.gen(function* () {
|
|
|
64320
65236
|
});
|
|
64321
65237
|
return TraceDiagnostics.of({ read });
|
|
64322
65238
|
});
|
|
64323
|
-
const layer$7 = Layer.effect(TraceDiagnostics, make$
|
|
65239
|
+
const layer$7 = Layer.effect(TraceDiagnostics, make$15);
|
|
64324
65240
|
function readTraceDiagnostics(options) {
|
|
64325
65241
|
return Effect.gen(function* () {
|
|
64326
65242
|
return yield* (yield* TraceDiagnostics).read(options);
|
|
@@ -64344,7 +65260,7 @@ const VCS_PROBES = [{
|
|
|
64344
65260
|
installHint: "Install Jujutsu with `brew install jj` or from https://github.com/jj-vcs/jj."
|
|
64345
65261
|
}];
|
|
64346
65262
|
var SourceControlDiscovery = class extends Context.Service()("@p4code/cli/sourceControl/SourceControlDiscovery") {};
|
|
64347
|
-
const make$
|
|
65263
|
+
const make$14 = Effect.gen(function* () {
|
|
64348
65264
|
const config = yield* ServerConfig$1;
|
|
64349
65265
|
const process = yield* VcsProcess;
|
|
64350
65266
|
const sourceControlProviders = yield* SourceControlProviderRegistry;
|
|
@@ -64393,7 +65309,7 @@ const make$13 = Effect.gen(function* () {
|
|
|
64393
65309
|
sourceControlProviders: sourceControlProviders.discover
|
|
64394
65310
|
}) });
|
|
64395
65311
|
});
|
|
64396
|
-
const layer$6 = Layer.effect(SourceControlDiscovery, make$
|
|
65312
|
+
const layer$6 = Layer.effect(SourceControlDiscovery, make$14);
|
|
64397
65313
|
//#endregion
|
|
64398
65314
|
//#region src/sourceControl/SourceControlRepositoryService.ts
|
|
64399
65315
|
const isSourceControlRepositoryError = Schema$1.is(SourceControlRepositoryError);
|
|
@@ -64426,7 +65342,7 @@ function expandHomePath(input, path) {
|
|
|
64426
65342
|
if (input.startsWith("~/") || input.startsWith("~\\")) return path.join(NodeOS.homedir(), input.slice(2));
|
|
64427
65343
|
return input;
|
|
64428
65344
|
}
|
|
64429
|
-
const make$
|
|
65345
|
+
const make$13 = Effect.gen(function* () {
|
|
64430
65346
|
const config = yield* ServerConfig$1;
|
|
64431
65347
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
64432
65348
|
const git = yield* GitVcsDriver;
|
|
@@ -64565,7 +65481,7 @@ const make$12 = Effect.gen(function* () {
|
|
|
64565
65481
|
publishRepository: (input) => publishRepository(input).pipe(mapRepositoryError("publishRepository", input.provider))
|
|
64566
65482
|
});
|
|
64567
65483
|
});
|
|
64568
|
-
const layer$5 = Layer.effect(SourceControlRepositoryService, make$
|
|
65484
|
+
const layer$5 = Layer.effect(SourceControlRepositoryService, make$13);
|
|
64569
65485
|
//#endregion
|
|
64570
65486
|
//#region src/ws.ts
|
|
64571
65487
|
/** Matches `p4c hub token add`, so a token minted here and one minted there are the same thing. */
|
|
@@ -64671,6 +65587,7 @@ function isThreadDetailEvent(event) {
|
|
|
64671
65587
|
}
|
|
64672
65588
|
const PROVIDER_STATUS_DEBOUNCE_MS = 200;
|
|
64673
65589
|
const SHELL_RESUME_MAX_GAP = 1e3;
|
|
65590
|
+
const THREAD_RESUME_MAX_GAP = 1e3;
|
|
64674
65591
|
const RPC_REQUIRED_SCOPE = /* @__PURE__ */ new Map([
|
|
64675
65592
|
[ORCHESTRATION_WS_METHODS.dispatchCommand, AuthOrchestrationOperateScope],
|
|
64676
65593
|
[ORCHESTRATION_WS_METHODS.getTurnDiff, AuthOrchestrationReadScope],
|
|
@@ -64757,6 +65674,7 @@ const RPC_REQUIRED_SCOPE = /* @__PURE__ */ new Map([
|
|
|
64757
65674
|
[WS_METHODS.projectsListEntries, AuthOrchestrationReadScope],
|
|
64758
65675
|
[WS_METHODS.projectsReadFile, AuthOrchestrationReadScope],
|
|
64759
65676
|
[WS_METHODS.projectsSearchEntries, AuthOrchestrationReadScope],
|
|
65677
|
+
[WS_METHODS.projectsSearchContents, AuthOrchestrationReadScope],
|
|
64760
65678
|
[WS_METHODS.projectsWriteFile, AuthOrchestrationOperateScope],
|
|
64761
65679
|
[WS_METHODS.shellOpenInEditor, AuthOrchestrationOperateScope],
|
|
64762
65680
|
[WS_METHODS.filesystemBrowse, AuthOrchestrationReadScope],
|
|
@@ -65373,15 +66291,19 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker) => WsRpcGroup.t
|
|
|
65373
66291
|
const bufferedLiveStream = liveBuffer.stream;
|
|
65374
66292
|
if (input.afterSequence !== void 0) {
|
|
65375
66293
|
const afterSequence = input.afterSequence;
|
|
65376
|
-
const
|
|
65377
|
-
|
|
65378
|
-
|
|
65379
|
-
|
|
65380
|
-
|
|
65381
|
-
|
|
65382
|
-
|
|
65383
|
-
|
|
65384
|
-
|
|
66294
|
+
const headSequence = yield* orchestrationEngine.latestSequence;
|
|
66295
|
+
const replayGap = headSequence - afterSequence;
|
|
66296
|
+
if (replayGap >= 0 && replayGap <= THREAD_RESUME_MAX_GAP) {
|
|
66297
|
+
const catchUpStream = (replayGap === 0 ? Stream.empty : orchestrationEngine.readEvents(afterSequence, replayGap)).pipe(Stream.takeWhile((event) => event.sequence <= headSequence), Stream.filter(isThisThreadDetailEvent), Stream.map((event) => ({
|
|
66298
|
+
kind: "event",
|
|
66299
|
+
event: projectActivityEvent(event)
|
|
66300
|
+
})), Stream.mapError((cause) => new OrchestrationGetSnapshotError({
|
|
66301
|
+
message: `Failed to replay thread ${input.threadId} events`,
|
|
66302
|
+
cause
|
|
66303
|
+
})));
|
|
66304
|
+
const afterCatchUp = input.requestCompletionMarker === true ? Stream.concat(Stream.fromEffect(liveBuffer.offerAndWait({ kind: "synchronized" }).pipe(Effect.andThen(liveBuffer.takeAll))).pipe(Stream.flatMap((items) => Stream.fromIterable(items))), bufferedLiveStream) : bufferedLiveStream;
|
|
66305
|
+
return Stream.concat(catchUpStream, afterCatchUp);
|
|
66306
|
+
}
|
|
65385
66307
|
}
|
|
65386
66308
|
const snapshot = yield* projectionSnapshotQuery.getThreadDetailSnapshot(input.threadId, input.turnLimit === void 0 ? void 0 : { turnLimit: input.turnLimit }).pipe(Effect.mapError((cause) => new OrchestrationGetSnapshotError({
|
|
65387
66309
|
message: `Failed to load thread ${input.threadId}`,
|
|
@@ -65649,6 +66571,13 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker) => WsRpcGroup.t
|
|
|
65649
66571
|
...projectEntriesFailureContext(cause),
|
|
65650
66572
|
cause
|
|
65651
66573
|
}))), { "rpc.aggregate": "workspace" }),
|
|
66574
|
+
[WS_METHODS.projectsSearchContents]: (input) => observeRpcEffect$1(WS_METHODS.projectsSearchContents, workspaceEntries.searchContents(input).pipe(Effect.mapError((cause) => new ProjectSearchEntriesError({
|
|
66575
|
+
cwd: input.cwd,
|
|
66576
|
+
queryLength: input.query.length,
|
|
66577
|
+
limit: input.limit,
|
|
66578
|
+
...projectEntriesFailureContext(cause),
|
|
66579
|
+
cause
|
|
66580
|
+
}))), { "rpc.aggregate": "workspace" }),
|
|
65652
66581
|
[WS_METHODS.projectsListEntries]: (input) => observeRpcEffect$1(WS_METHODS.projectsListEntries, workspaceEntries.list(input).pipe(Effect.mapError((cause) => new ProjectListEntriesError({
|
|
65653
66582
|
...input,
|
|
65654
66583
|
...projectEntriesFailureContext(cause),
|
|
@@ -65869,7 +66798,7 @@ function toPersistenceSqlOrDecodeError(sqlOperation, decodeOperation, correlatio
|
|
|
65869
66798
|
cause
|
|
65870
66799
|
});
|
|
65871
66800
|
}
|
|
65872
|
-
const make$
|
|
66801
|
+
const make$12 = Effect.gen(function* () {
|
|
65873
66802
|
const sql = yield* SqlClient.SqlClient;
|
|
65874
66803
|
const upsertRuntimeRow = SqlSchema.void({
|
|
65875
66804
|
Request: ProviderSessionRuntimeDbRowSchema,
|
|
@@ -65972,7 +66901,7 @@ const make$11 = Effect.gen(function* () {
|
|
|
65972
66901
|
deleteByThreadId
|
|
65973
66902
|
};
|
|
65974
66903
|
});
|
|
65975
|
-
const layer$4 = Layer.effect(ProviderSessionRuntimeRepository, make$
|
|
66904
|
+
const layer$4 = Layer.effect(ProviderSessionRuntimeRepository, make$12);
|
|
65976
66905
|
//#endregion
|
|
65977
66906
|
//#region src/provider/Errors.ts
|
|
65978
66907
|
/**
|
|
@@ -66624,7 +67553,7 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66624
67553
|
const httpServer = yield* HttpServer.HttpServer;
|
|
66625
67554
|
const state = yield* SynchronizedRef.make({
|
|
66626
67555
|
records: /* @__PURE__ */ new Map(),
|
|
66627
|
-
|
|
67556
|
+
spawnedThreads: /* @__PURE__ */ new Map()
|
|
66628
67557
|
});
|
|
66629
67558
|
const currentTimeMillis = options.now ? Effect.sync(options.now) : Clock.currentTimeMillis;
|
|
66630
67559
|
const livenessWindowMs = options.livenessWindowMs ?? DEFAULT_LIVENESS_WINDOW_MS;
|
|
@@ -66649,7 +67578,7 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66649
67578
|
if (watchThreadIds.size > 0) capabilities.add("watch");
|
|
66650
67579
|
if (adviseThreadIds.size > 0) capabilities.add("advise");
|
|
66651
67580
|
const threadId = ThreadId.make(request.threadId);
|
|
66652
|
-
const scopeWith = (mayCreateThreads) => ({
|
|
67581
|
+
const scopeWith = (mayCreateThreads, mayCreateFusionPairs) => ({
|
|
66653
67582
|
environmentId,
|
|
66654
67583
|
threadId,
|
|
66655
67584
|
providerSessionId,
|
|
@@ -66658,19 +67587,20 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66658
67587
|
...watchThreadIds.size > 0 ? { watchThreadIds } : {},
|
|
66659
67588
|
...adviseThreadIds.size > 0 ? { adviseThreadIds } : {},
|
|
66660
67589
|
mayCreateThreads,
|
|
67590
|
+
mayCreateFusionPairs,
|
|
66661
67591
|
issuedAt
|
|
66662
67592
|
});
|
|
66663
|
-
yield* SynchronizedRef.update(state, ({ records,
|
|
67593
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
66664
67594
|
const next = new Map(pruneDead(records, issuedAt));
|
|
66665
67595
|
next.set(tokenHash, {
|
|
66666
67596
|
tokenHash,
|
|
66667
|
-
scope: scopeWith(!
|
|
67597
|
+
scope: scopeWith(!spawnedThreads.has(threadId), spawnedThreads.get(threadId) === true),
|
|
66668
67598
|
controlThreadIds: /* @__PURE__ */ new Set(),
|
|
66669
67599
|
lastAliveAt: issuedAt
|
|
66670
67600
|
});
|
|
66671
67601
|
return {
|
|
66672
67602
|
records: next,
|
|
66673
|
-
|
|
67603
|
+
spawnedThreads
|
|
66674
67604
|
};
|
|
66675
67605
|
});
|
|
66676
67606
|
return { config: {
|
|
@@ -66686,12 +67616,12 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66686
67616
|
if (rawToken.length === 0) return void 0;
|
|
66687
67617
|
const tokenHash = yield* hashToken(rawToken);
|
|
66688
67618
|
const timestamp = yield* currentTimeMillis;
|
|
66689
|
-
return yield* SynchronizedRef.modify(state, ({ records,
|
|
67619
|
+
return yield* SynchronizedRef.modify(state, ({ records, spawnedThreads }) => {
|
|
66690
67620
|
const current = pruneDead(records, timestamp);
|
|
66691
67621
|
const record = current.get(tokenHash);
|
|
66692
67622
|
if (!record) return [void 0, {
|
|
66693
67623
|
records: current,
|
|
66694
|
-
|
|
67624
|
+
spawnedThreads
|
|
66695
67625
|
}];
|
|
66696
67626
|
const next = new Map(current);
|
|
66697
67627
|
next.set(tokenHash, {
|
|
@@ -66705,13 +67635,13 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66705
67635
|
watchThreadIds: /* @__PURE__ */ new Set([...record.scope.watchThreadIds ?? [], ...record.controlThreadIds])
|
|
66706
67636
|
}, {
|
|
66707
67637
|
records: next,
|
|
66708
|
-
|
|
67638
|
+
spawnedThreads
|
|
66709
67639
|
}];
|
|
66710
67640
|
});
|
|
66711
67641
|
});
|
|
66712
67642
|
const touch = Effect.fn("McpSessionRegistry.touch")(function* (threadId) {
|
|
66713
67643
|
const timestamp = yield* currentTimeMillis;
|
|
66714
|
-
yield* SynchronizedRef.update(state, ({ records,
|
|
67644
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
66715
67645
|
const current = pruneDead(records, timestamp);
|
|
66716
67646
|
const next = new Map(current);
|
|
66717
67647
|
for (const [tokenHash, record] of current) if (record.scope.threadId === threadId) next.set(tokenHash, {
|
|
@@ -66720,12 +67650,12 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66720
67650
|
});
|
|
66721
67651
|
return {
|
|
66722
67652
|
records: next,
|
|
66723
|
-
|
|
67653
|
+
spawnedThreads
|
|
66724
67654
|
};
|
|
66725
67655
|
});
|
|
66726
67656
|
});
|
|
66727
67657
|
const grantWatchThread = Effect.fn("McpSessionRegistry.grantWatchThread")(function* ({ watcherThreadId, watchedThreadId }) {
|
|
66728
|
-
yield* SynchronizedRef.update(state, ({ records,
|
|
67658
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
66729
67659
|
const next = new Map(records);
|
|
66730
67660
|
for (const [tokenHash, record] of records) {
|
|
66731
67661
|
if (record.scope.threadId !== watcherThreadId) continue;
|
|
@@ -66740,12 +67670,12 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66740
67670
|
}
|
|
66741
67671
|
return {
|
|
66742
67672
|
records: next,
|
|
66743
|
-
|
|
67673
|
+
spawnedThreads
|
|
66744
67674
|
};
|
|
66745
67675
|
});
|
|
66746
67676
|
});
|
|
66747
67677
|
const revokeWatchThread = Effect.fn("McpSessionRegistry.revokeWatchThread")(function* ({ watcherThreadId, watchedThreadId }) {
|
|
66748
|
-
yield* SynchronizedRef.update(state, ({ records,
|
|
67678
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
66749
67679
|
const next = new Map(records);
|
|
66750
67680
|
for (const [tokenHash, record] of records) {
|
|
66751
67681
|
if (record.scope.threadId !== watcherThreadId) continue;
|
|
@@ -66768,12 +67698,12 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66768
67698
|
}
|
|
66769
67699
|
return {
|
|
66770
67700
|
records: next,
|
|
66771
|
-
|
|
67701
|
+
spawnedThreads
|
|
66772
67702
|
};
|
|
66773
67703
|
});
|
|
66774
67704
|
});
|
|
66775
67705
|
const grantAdviseThread = Effect.fn("McpSessionRegistry.grantAdviseThread")(function* ({ watcherThreadId, advisedThreadId }) {
|
|
66776
|
-
yield* SynchronizedRef.update(state, ({ records,
|
|
67706
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
66777
67707
|
const next = new Map(records);
|
|
66778
67708
|
for (const [tokenHash, record] of records) {
|
|
66779
67709
|
if (record.scope.threadId !== watcherThreadId) continue;
|
|
@@ -66788,12 +67718,12 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66788
67718
|
}
|
|
66789
67719
|
return {
|
|
66790
67720
|
records: next,
|
|
66791
|
-
|
|
67721
|
+
spawnedThreads
|
|
66792
67722
|
};
|
|
66793
67723
|
});
|
|
66794
67724
|
});
|
|
66795
67725
|
const revokeAdviseThread = Effect.fn("McpSessionRegistry.revokeAdviseThread")(function* ({ watcherThreadId, advisedThreadId }) {
|
|
66796
|
-
yield* SynchronizedRef.update(state, ({ records,
|
|
67726
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
66797
67727
|
const next = new Map(records);
|
|
66798
67728
|
for (const [tokenHash, record] of records) {
|
|
66799
67729
|
if (record.scope.threadId !== watcherThreadId) continue;
|
|
@@ -66816,12 +67746,12 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66816
67746
|
}
|
|
66817
67747
|
return {
|
|
66818
67748
|
records: next,
|
|
66819
|
-
|
|
67749
|
+
spawnedThreads
|
|
66820
67750
|
};
|
|
66821
67751
|
});
|
|
66822
67752
|
});
|
|
66823
67753
|
const recordSpawnedThread = Effect.fn("McpSessionRegistry.recordSpawnedThread")(function* (input) {
|
|
66824
|
-
yield* SynchronizedRef.update(state, ({ records,
|
|
67754
|
+
yield* SynchronizedRef.update(state, ({ records, spawnedThreads }) => {
|
|
66825
67755
|
const next = new Map(records);
|
|
66826
67756
|
for (const [tokenHash, record] of records) if (record.scope.providerSessionId === input.providerSessionId) next.set(tokenHash, {
|
|
66827
67757
|
...record,
|
|
@@ -66829,13 +67759,13 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66829
67759
|
});
|
|
66830
67760
|
return {
|
|
66831
67761
|
records: next,
|
|
66832
|
-
|
|
67762
|
+
spawnedThreads: new Map([...spawnedThreads, [input.threadId, input.mayCreateFusionPairs === true]])
|
|
66833
67763
|
};
|
|
66834
67764
|
});
|
|
66835
67765
|
});
|
|
66836
|
-
const revokeWhere = (predicate) => SynchronizedRef.update(state, ({ records,
|
|
67766
|
+
const revokeWhere = (predicate) => SynchronizedRef.update(state, ({ records, spawnedThreads }) => ({
|
|
66837
67767
|
records: new Map(Array.from(records).filter(([, record]) => !predicate(record))),
|
|
66838
|
-
|
|
67768
|
+
spawnedThreads
|
|
66839
67769
|
}));
|
|
66840
67770
|
return McpSessionRegistry.of({
|
|
66841
67771
|
issue,
|
|
@@ -66852,19 +67782,19 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
66852
67782
|
revokeThread: Effect.fn("McpSessionRegistry.revokeThread")(function* (threadId) {
|
|
66853
67783
|
yield* revokeWhere((record) => record.scope.threadId === threadId);
|
|
66854
67784
|
}),
|
|
66855
|
-
revokeAll: SynchronizedRef.update(state, ({
|
|
67785
|
+
revokeAll: SynchronizedRef.update(state, ({ spawnedThreads }) => ({
|
|
66856
67786
|
records: /* @__PURE__ */ new Map(),
|
|
66857
|
-
|
|
67787
|
+
spawnedThreads
|
|
66858
67788
|
}))
|
|
66859
67789
|
});
|
|
66860
67790
|
});
|
|
66861
67791
|
let activeMcpSessionRegistry;
|
|
66862
|
-
const make$
|
|
67792
|
+
const make$11 = Effect.acquireRelease(makeWithOptions().pipe(Effect.tap((registry) => Effect.sync(() => {
|
|
66863
67793
|
activeMcpSessionRegistry = registry;
|
|
66864
67794
|
}))), (registry) => Effect.sync(() => {
|
|
66865
67795
|
if (activeMcpSessionRegistry === registry) activeMcpSessionRegistry = void 0;
|
|
66866
67796
|
}));
|
|
66867
|
-
const layer$3 = Layer.effect(McpSessionRegistry, make$
|
|
67797
|
+
const layer$3 = Layer.effect(McpSessionRegistry, make$11);
|
|
66868
67798
|
const issueActiveMcpCredential = (request) => activeMcpSessionRegistry ? activeMcpSessionRegistry.revokeThread(request.threadId).pipe(Effect.andThen(activeMcpSessionRegistry.issue(request))) : Effect.sync(() => void 0);
|
|
66869
67799
|
/**
|
|
66870
67800
|
* Refreshes the liveness of a thread's MCP credential. Called on every provider
|
|
@@ -67573,6 +68503,13 @@ const makeProviderSessionReaper = (options) => Effect.gen(function* () {
|
|
|
67573
68503
|
});
|
|
67574
68504
|
continue;
|
|
67575
68505
|
}
|
|
68506
|
+
if (thread?.backgroundLiveness != null) {
|
|
68507
|
+
yield* Effect.logDebug("provider.session.reaper.skipped-background-work", {
|
|
68508
|
+
threadId: binding.threadId,
|
|
68509
|
+
backgroundLiveness: thread.backgroundLiveness
|
|
68510
|
+
});
|
|
68511
|
+
continue;
|
|
68512
|
+
}
|
|
67576
68513
|
if (yield* providerService.stopSession({ threadId: binding.threadId }).pipe(Effect.tap(() => Effect.logInfo("provider.session.reaped", {
|
|
67577
68514
|
threadId: binding.threadId,
|
|
67578
68515
|
provider: binding.provider,
|
|
@@ -67590,14 +68527,18 @@ const makeProviderSessionReaper = (options) => Effect.gen(function* () {
|
|
|
67590
68527
|
totalBindings: bindings.length
|
|
67591
68528
|
});
|
|
67592
68529
|
});
|
|
68530
|
+
const sweepSafely = () => sweep.pipe(Effect.catch((error) => Effect.logWarning("provider.session.reaper.sweep-failed", { error })), Effect.catchDefect((defect) => Effect.logWarning("provider.session.reaper.sweep-defect", { defect })));
|
|
67593
68531
|
const start = () => Effect.gen(function* () {
|
|
67594
|
-
yield* Effect.forkScoped(
|
|
68532
|
+
yield* Effect.forkScoped(sweepSafely().pipe(Effect.repeat(Schedule.spaced(Duration.millis(sweepIntervalMs)))));
|
|
67595
68533
|
yield* Effect.logInfo("provider.session.reaper.started", {
|
|
67596
68534
|
inactivityThresholdMs,
|
|
67597
68535
|
sweepIntervalMs
|
|
67598
68536
|
});
|
|
67599
68537
|
});
|
|
67600
|
-
return {
|
|
68538
|
+
return {
|
|
68539
|
+
start,
|
|
68540
|
+
sweep: sweepSafely
|
|
68541
|
+
};
|
|
67601
68542
|
});
|
|
67602
68543
|
const makeProviderSessionReaperLive = (options) => Layer.effect(ProviderSessionReaper, makeProviderSessionReaper(options));
|
|
67603
68544
|
const ProviderSessionReaperLive = makeProviderSessionReaperLive();
|
|
@@ -69779,7 +70720,7 @@ function formatAskUserQuestionAnswers(answers) {
|
|
|
69779
70720
|
* only a one-line reference and the mutable `[fusion-pair]` metadata.
|
|
69780
70721
|
*/
|
|
69781
70722
|
const FUSION_BUILDER_INSTRUCTIONS = `You are Fusion Builder in an already-created native server pair. Server owns pairing and coordination. Do not inspect or invoke the Fusion skill, create/pair/rename threads, or announce/setup Fusion. Start the user's task directly. Before editing, create and maintain the phase list with your provider's step-tracking tool (Claude Code: TaskCreate for each phase, then TaskUpdate for status, or TodoWrite when that is the tool offered; Codex: update_plan), never the MCP task board tools - one entry per phase in order, exactly one in progress at a time, marked completed at each phase end - so phases render in the task banner. That list holds phase entries only for the whole task; keep step-level or per-file todos out of it. Name each phase in 3-6 words by its outcome, never by a command, file path, or flag, because the banner shows the title verbatim. Prose alone leaves the banner empty. Split it into the fewest substantial phases the task genuinely needs plus a final integration/whole-task phase; most tasks need one to three work phases. Each phase is a complete reviewable slice of behavior. Never split per file, per function, or per trivial step: over-splitting spends review turns instead of finishing the job. Add a phase only when a real review boundary, risky decision, or independent behavior separates the work. Complete exactly one phase per turn, and finish the whole phase in that turn rather than stopping early. Do not run tests, typecheck, lint, or builds per phase; write the tests the change needs, then run verification once in the final phase over the whole task. Exception: a phase whose own correctness is unclear may run the single narrowest check that resolves it. End every phase turn with phase completed, todo status, changed behavior/files, and remaining phases; do not start the next phase in the same turn. Server then wakes the paired Supervisor, which resumes you through ${FUSION_ADVICE_PROMPT_PREFIX}; a user message may also revise or resume the work. Final phase verifies the entire task against the original request and labels it ready for whole-task review. Supervisor is unreachable during your turn. Never spawn/use another Supervisor thread/subagent or attribute Supervisor decisions without ${FUSION_ADVICE_PROMPT_PREFIX}. Within the current phase, continue when straightforward or evidence is clear. For a concrete unresolved tradeoff, correctness risk, or design decision materially needing judgment, stop safely before the risky choice; final response states the exact question and why review is needed. Evaluate/follow Supervisor advice unless conflicting with user request or verified repo state.`;
|
|
69782
|
-
const FUSION_WATCHER_INSTRUCTIONS = `You are Fusion Supervisor (watcher) in an already-created native server pair. Server owns pairing and coordination and wakes you with ${FUSION_REVIEW_PROMPT_PREFIX} or ${FUSION_GATE_PROMPT_PREFIX} prompts at builder turn boundaries. A plain message outside such a wake may arrive after your conversational memory of the pair is gone; its [fusion-pair] metadata block is authoritative: the builder thread exists and is the counterpart thread id. Never report that no builder thread exists. To resume supervision, read builder
|
|
70723
|
+
const FUSION_WATCHER_INSTRUCTIONS = `You are Fusion Supervisor (watcher) in an already-created native server pair. Server owns pairing and coordination and wakes you with ${FUSION_REVIEW_PROMPT_PREFIX} or ${FUSION_GATE_PROMPT_PREFIX} prompts at builder turn boundaries. A plain message outside such a wake may arrive after your conversational memory of the pair is gone; its [fusion-pair] metadata block is authoritative: the builder thread exists and is the counterpart thread id. Never report that no builder thread exists. To resume supervision, read builder evidence with thread_watch_review from lastReviewedImplementerSequence, capture its throughSequence on the first page and reuse that fixed bound while paging with nextAfterSequence until hasMore is false (including empty pages). Apply message append/replace operations by identity; recover truncated evidence through targeted raw thread_watch_events source ranges. Retain reviewed requirements and evidence for final review; recover missing context with targeted history reads rather than mandatory raw replay from zero, derive phase from artifacts (git log/status, PR, builder events, including its turn.plan.updated phase list), steer with thread_advise, and answer an open gate with thread_gate_respond. When a review or gate wake prompt specifies an explicit event range, that range wins over this metadata. Never poll or wait for the builder; deliver review or advice, then end the turn. Every thread_advise starts a builder turn whose completion wakes you again, so never advise a builder that is idle on an external wait or has nothing actionable; report the state in your own thread and end without advising.`;
|
|
69783
70724
|
/**
|
|
69784
70725
|
* The one-line stand-in for the full block on a message whose session already
|
|
69785
70726
|
* carries the role instructions.
|
|
@@ -91040,7 +91981,7 @@ const makeTerminationError$1 = (handle) => Effect.match(handle.exitCode, {
|
|
|
91040
91981
|
//#endregion
|
|
91041
91982
|
//#region ../../packages/effect-codex-app-server/src/client.ts
|
|
91042
91983
|
var CodexAppServerClient = class extends Context.Service()("effect-codex-app-server/client/CodexAppServerClient") {};
|
|
91043
|
-
const make$
|
|
91984
|
+
const make$10 = Effect.fn("effect-codex-app-server/CodexAppServerClient.make")(function* (stdio, options = {}, terminationError) {
|
|
91044
91985
|
const requestHandlers = /* @__PURE__ */ new Map();
|
|
91045
91986
|
const notificationHandlers = /* @__PURE__ */ new Map();
|
|
91046
91987
|
let unknownRequestHandler;
|
|
@@ -91107,7 +92048,7 @@ const make$9 = Effect.fn("effect-codex-app-server/CodexAppServerClient.make")(fu
|
|
|
91107
92048
|
const layerChildProcess$1 = (handle, options = {}) => Layer.effect(CodexAppServerClient, makeChildProcessClient(handle, options));
|
|
91108
92049
|
const makeChildProcessClient = Effect.fn("effect-codex-app-server/CodexAppServerClient.makeChildProcessClient")(function* (handle, options) {
|
|
91109
92050
|
yield* Stream.runDrain(handle.stderr).pipe(Effect.ignore, Effect.forkScoped);
|
|
91110
|
-
return yield* make$
|
|
92051
|
+
return yield* make$10(makeChildStdio$1(handle), options, makeTerminationError$1(handle));
|
|
91111
92052
|
});
|
|
91112
92053
|
const resolveCodexLaunchArgs = (launchArgs, environment = process.env) => environment["P4CODE_CODEX_LAUNCH_ARGS"]?.trim() || launchArgs?.trim() || "";
|
|
91113
92054
|
const codexLaunchArgv = (launchArgs) => tokenizeCliArgs(launchArgs);
|
|
@@ -97912,7 +98853,7 @@ const makeTerminationError = (handle) => Effect.match(handle.exitCode, {
|
|
|
97912
98853
|
//#endregion
|
|
97913
98854
|
//#region ../../packages/effect-acp/src/client.ts
|
|
97914
98855
|
var AcpClient = class extends Context.Service()("effect-acp/client/AcpClient") {};
|
|
97915
|
-
const make$
|
|
98856
|
+
const make$9 = Effect.fn("effect-acp/AcpClient.make")(function* (stdio, options = {}, terminationError) {
|
|
97916
98857
|
const coreHandlers = {};
|
|
97917
98858
|
const notificationHandlers = {
|
|
97918
98859
|
sessionUpdate: {
|
|
@@ -98070,7 +99011,7 @@ const make$8 = Effect.fn("effect-acp/AcpClient.make")(function* (stdio, options
|
|
|
98070
99011
|
const layerChildProcess = (handle, options = {}) => {
|
|
98071
99012
|
const stdio = makeChildStdio(handle);
|
|
98072
99013
|
const terminationError = makeTerminationError(handle);
|
|
98073
|
-
return Layer.effect(AcpClient, make$
|
|
99014
|
+
return Layer.effect(AcpClient, make$9(stdio, options, terminationError));
|
|
98074
99015
|
};
|
|
98075
99016
|
//#endregion
|
|
98076
99017
|
//#region ../../packages/shared/src/toolActivity.ts
|
|
@@ -98530,7 +99471,7 @@ function formatConfigOptionValue(value) {
|
|
|
98530
99471
|
const defaultSessionLoadTimeout = Duration.seconds(90);
|
|
98531
99472
|
const defaultSessionLoadReplayIdleGap = Duration.seconds(2);
|
|
98532
99473
|
var AcpSessionRuntime = class extends Context.Service()("@p4code/cli/provider/acp/AcpSessionRuntime") {};
|
|
98533
|
-
const make$
|
|
99474
|
+
const make$8 = (options) => Effect.gen(function* () {
|
|
98534
99475
|
const crypto = yield* Crypto.Crypto;
|
|
98535
99476
|
const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
|
|
98536
99477
|
const runtimeScope = yield* Scope.Scope;
|
|
@@ -98846,7 +99787,7 @@ const make$7 = (options) => Effect.gen(function* () {
|
|
|
98846
99787
|
notify: acp.raw.notify
|
|
98847
99788
|
};
|
|
98848
99789
|
});
|
|
98849
|
-
const layer$2 = (options) => Layer.effect(AcpSessionRuntime, make$
|
|
99790
|
+
const layer$2 = (options) => Layer.effect(AcpSessionRuntime, make$8(options));
|
|
98850
99791
|
function sessionConfigOptionsFromSetup(response) {
|
|
98851
99792
|
return response?.configOptions ?? [];
|
|
98852
99793
|
}
|
|
@@ -106307,7 +107248,7 @@ const stringField = (record, key) => {
|
|
|
106307
107248
|
const value = record[key];
|
|
106308
107249
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
106309
107250
|
};
|
|
106310
|
-
const make$
|
|
107251
|
+
const make$7 = Effect.gen(function* () {
|
|
106311
107252
|
const linear = yield* LinearClient;
|
|
106312
107253
|
return { resolve: Effect.fn("TicketResolver.resolve")(function* (reference) {
|
|
106313
107254
|
const identifier = parseTicketReference(reference);
|
|
@@ -106338,7 +107279,7 @@ const make$6 = Effect.gen(function* () {
|
|
|
106338
107279
|
};
|
|
106339
107280
|
}) };
|
|
106340
107281
|
});
|
|
106341
|
-
const layer$1 = Layer.effect(TicketResolver, make$
|
|
107282
|
+
const layer$1 = Layer.effect(TicketResolver, make$7);
|
|
106342
107283
|
//#endregion
|
|
106343
107284
|
//#region src/mcp/toolkits/tasks/tools.ts
|
|
106344
107285
|
const dependencies = [McpInvocationContext, TaskRepository];
|
|
@@ -106877,7 +107818,7 @@ const AskUserQuestionTool = Tool.make("ask_user_question", {
|
|
|
106877
107818
|
]
|
|
106878
107819
|
}).annotate(Tool.Title, "Ask user question").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
106879
107820
|
const ThreadSpawnTool = Tool.make("thread_spawn", {
|
|
106880
|
-
description: "Start a new agent thread and send it a first message, then return its id. Use it to hand a piece of work to a fresh thread - a subtask you just planned, a job that wants its own transcript. Set fusionWatcher true for a
|
|
107821
|
+
description: "Start a new agent thread and send it a first message, then return its id. Use it to hand a piece of work to a fresh thread - a subtask you just planned, a job that wants its own transcript. Set fusion true to create two new threads as a separate Fusion pair and start its builder with prompt, even when this thread already belongs to a pair. Set fusionWatcher true only for a supervisor to pair with the current thread. Both use saved Fusion role models unless overridden. Act on the user's request; no special command syntax is required. The new thread inherits this one's project, model, permission mode, interaction mode, compression and subagent policy, and every one of those can be set here instead - what you set is already in force for the first turn, so a thread never has to be corrected after it starts. Set modelSelection to run it on another model: give the model id, and leave instanceId out to keep this thread's provider instance. Once started it can be watched with thread_watch_events and changed later with thread_configure. A thread that was itself started this way cannot start another.",
|
|
106881
107822
|
parameters: ThreadSpawnInput,
|
|
106882
107823
|
success: ThreadSpawnResult,
|
|
106883
107824
|
failure: ThreadControlToolError,
|
|
@@ -106885,20 +107826,19 @@ const ThreadSpawnTool = Tool.make("thread_spawn", {
|
|
|
106885
107826
|
McpInvocationContext,
|
|
106886
107827
|
McpSessionRegistry,
|
|
106887
107828
|
OrchestrationEngineService,
|
|
106888
|
-
ProjectionSnapshotQuery,
|
|
106889
107829
|
ProjectionThreadRepository,
|
|
107830
|
+
ServerSettingsService,
|
|
106890
107831
|
Crypto.Crypto
|
|
106891
107832
|
]
|
|
106892
107833
|
}).annotate(Tool.Title, "Start a thread").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
106893
107834
|
const ThreadPairCreateTool = Tool.make("thread_pair_create", {
|
|
106894
|
-
description: "Create a persisted Fusion pair between this agent session's own thread as builder and a supervisor it previously created with thread_spawn.
|
|
107835
|
+
description: "Create a persisted Fusion pair between this agent session's own thread as builder and a supervisor it previously created with thread_spawn. Act on the user's request; no special command syntax is required. The current thread must not already belong to an active Fusion pair. Successful creation automatically continues the builder, so never ask the user to resend the task.",
|
|
106895
107836
|
parameters: ThreadPairCreateInput,
|
|
106896
107837
|
success: ThreadPairCreateResult,
|
|
106897
107838
|
failure: ThreadControlToolError,
|
|
106898
107839
|
dependencies: [
|
|
106899
107840
|
McpInvocationContext,
|
|
106900
107841
|
OrchestrationEngineService,
|
|
106901
|
-
ProjectionSnapshotQuery,
|
|
106902
107842
|
Crypto.Crypto
|
|
106903
107843
|
]
|
|
106904
107844
|
}).annotate(Tool.Title, "Create a Fusion pair").annotate(Tool.Readonly, false).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, false);
|
|
@@ -107073,29 +108013,6 @@ const newCommandId = Effect.gen(function* () {
|
|
|
107073
108013
|
const crypto = yield* Crypto.Crypto;
|
|
107074
108014
|
return CommandId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie));
|
|
107075
108015
|
});
|
|
107076
|
-
const fusionInvocationLine = /^(?:\/fusion|\$fusion)(?:\s+.*)?$/i;
|
|
107077
|
-
const fusionAffirmativeLine = /^(?:approved?|yes(?:,?\s+(?:please|do it))?|ok(?:ay)?|go ahead|do it|proceed)[.!]?$/i;
|
|
107078
|
-
function lastNonEmptyLine(text) {
|
|
107079
|
-
return text.split(/\r?\n/).findLast((line) => line.trim().length > 0)?.trim() ?? "";
|
|
107080
|
-
}
|
|
107081
|
-
function directlyInvokesFusion(text) {
|
|
107082
|
-
return text.split(/\r?\n/).some((line) => fusionInvocationLine.test(line.trim()));
|
|
107083
|
-
}
|
|
107084
|
-
function asksForFusionApproval(message) {
|
|
107085
|
-
if (message?.role !== "assistant") return false;
|
|
107086
|
-
const text = message.text.toLowerCase();
|
|
107087
|
-
return text.includes("fusion") && (text.includes("approve") || text.includes("approval"));
|
|
107088
|
-
}
|
|
107089
|
-
const requireFusionApproval = Effect.fn("mcp.threads.requireFusionApproval")(function* (threadId) {
|
|
107090
|
-
const thread = yield* (yield* ProjectionSnapshotQuery).getThreadDetailById(threadId).pipe(Effect.mapError(() => new ThreadPairApprovalRequiredError({ threadId })));
|
|
107091
|
-
if (Option.isNone(thread)) return yield* new ThreadPairApprovalRequiredError({ threadId });
|
|
107092
|
-
const latestUserIndex = thread.value.messages.findLastIndex((message) => message.role === "user");
|
|
107093
|
-
const latestUser = latestUserIndex >= 0 ? thread.value.messages[latestUserIndex] : void 0;
|
|
107094
|
-
if (latestUser !== void 0 && directlyInvokesFusion(latestUser.text)) return;
|
|
107095
|
-
const precedingAssistant = thread.value.messages.slice(0, latestUserIndex).findLast((message) => message.role === "assistant");
|
|
107096
|
-
if (latestUser !== void 0 && fusionAffirmativeLine.test(lastNonEmptyLine(latestUser.text)) && asksForFusionApproval(precedingAssistant)) return;
|
|
107097
|
-
return yield* new ThreadPairApprovalRequiredError({ threadId });
|
|
107098
|
-
});
|
|
107099
108016
|
/**
|
|
107100
108017
|
* The model a spawned thread starts on.
|
|
107101
108018
|
*
|
|
@@ -107220,8 +108137,11 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
107220
108137
|
}).pipe(Effect.ensuring(Effect.sync(() => forgetPendingMcpUserInput(invocation.threadId, requestId))));
|
|
107221
108138
|
}),
|
|
107222
108139
|
thread_spawn: (input) => Effect.gen(function* () {
|
|
107223
|
-
const invocation = yield* requireThreadSpawn();
|
|
107224
|
-
if (input.fusionWatcher === true) yield*
|
|
108140
|
+
const invocation = yield* requireThreadSpawn(input.fusion === true);
|
|
108141
|
+
if (input.fusion === true && input.fusionWatcher === true) return yield* new ThreadSpawnNotPermittedError({
|
|
108142
|
+
threadId: invocation.threadId,
|
|
108143
|
+
detail: "Choose a new Fusion pair or a standalone watcher, not both."
|
|
108144
|
+
});
|
|
107225
108145
|
const registry = yield* McpSessionRegistry;
|
|
107226
108146
|
const threads = yield* ProjectionThreadRepository;
|
|
107227
108147
|
const crypto = yield* Crypto.Crypto;
|
|
@@ -107235,7 +108155,11 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
107235
108155
|
});
|
|
107236
108156
|
const template = parent.value;
|
|
107237
108157
|
const projectId = input.projectId ?? template.projectId;
|
|
107238
|
-
const
|
|
108158
|
+
const settings = input.fusion === true || input.fusionWatcher === true ? yield* (yield* ServerSettingsService).getSettings.pipe(Effect.mapError((cause) => new ThreadSpawnNotPermittedError({
|
|
108159
|
+
threadId: invocation.threadId,
|
|
108160
|
+
detail: `Fusion settings could not be read: ${cause.message}`
|
|
108161
|
+
}))) : void 0;
|
|
108162
|
+
const modelSelection = resolveSpawnModelSelection(input.modelSelection, (input.fusionWatcher === true ? settings?.fusionWatcherModelSelection : settings?.fusionBuilderModelSelection) ?? template.modelSelection);
|
|
107239
108163
|
const runtimeMode = input.runtimeMode ?? template.runtimeMode;
|
|
107240
108164
|
const interactionMode = input.interactionMode ?? template.interactionMode;
|
|
107241
108165
|
const compressMode = input.compressMode ?? template.compressMode;
|
|
@@ -107259,8 +108183,42 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
107259
108183
|
}, threadId);
|
|
107260
108184
|
yield* registry.recordSpawnedThread({
|
|
107261
108185
|
providerSessionId: invocation.providerSessionId,
|
|
107262
|
-
threadId
|
|
108186
|
+
threadId,
|
|
108187
|
+
...input.fusionWatcher === true ? { mayCreateFusionPairs: true } : {}
|
|
107263
108188
|
});
|
|
108189
|
+
const fusionPair = input.fusion === true ? {
|
|
108190
|
+
pairId: ThreadPairId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie)),
|
|
108191
|
+
watcherThreadId: ThreadId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie))
|
|
108192
|
+
} : void 0;
|
|
108193
|
+
if (fusionPair !== void 0) {
|
|
108194
|
+
yield* dispatchControl({
|
|
108195
|
+
type: "thread.create",
|
|
108196
|
+
commandId: yield* newCommandId,
|
|
108197
|
+
threadId: fusionPair.watcherThreadId,
|
|
108198
|
+
projectId,
|
|
108199
|
+
title: `Review: ${input.title}`,
|
|
108200
|
+
modelSelection: settings?.fusionWatcherModelSelection ?? modelSelection,
|
|
108201
|
+
runtimeMode,
|
|
108202
|
+
interactionMode: "default",
|
|
108203
|
+
compressMode,
|
|
108204
|
+
unpromptedSubagents,
|
|
108205
|
+
branch: null,
|
|
108206
|
+
worktreePath: null,
|
|
108207
|
+
createdAt
|
|
108208
|
+
}, fusionPair.watcherThreadId);
|
|
108209
|
+
yield* registry.recordSpawnedThread({
|
|
108210
|
+
providerSessionId: invocation.providerSessionId,
|
|
108211
|
+
threadId: fusionPair.watcherThreadId
|
|
108212
|
+
});
|
|
108213
|
+
yield* dispatchControl({
|
|
108214
|
+
type: "thread-pair.create",
|
|
108215
|
+
commandId: yield* newCommandId,
|
|
108216
|
+
pairId: fusionPair.pairId,
|
|
108217
|
+
implementerThreadId: threadId,
|
|
108218
|
+
watcherThreadId: fusionPair.watcherThreadId,
|
|
108219
|
+
createdAt
|
|
108220
|
+
}, threadId);
|
|
108221
|
+
}
|
|
107264
108222
|
yield* dispatchControl({
|
|
107265
108223
|
type: "thread.turn.start",
|
|
107266
108224
|
commandId: yield* newCommandId,
|
|
@@ -107282,12 +108240,12 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
107282
108240
|
return {
|
|
107283
108241
|
threadId,
|
|
107284
108242
|
projectId,
|
|
107285
|
-
title: input.title
|
|
108243
|
+
title: input.title,
|
|
108244
|
+
...fusionPair
|
|
107286
108245
|
};
|
|
107287
108246
|
}),
|
|
107288
108247
|
thread_pair_create: (input) => Effect.gen(function* () {
|
|
107289
108248
|
const { invocation, threadId: watcherThreadId } = yield* requireThreadControlTarget(input.watcherThreadId);
|
|
107290
|
-
yield* requireFusionApproval(invocation.threadId);
|
|
107291
108249
|
const crypto = yield* Crypto.Crypto;
|
|
107292
108250
|
const pairId = ThreadPairId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie));
|
|
107293
108251
|
const continuationMessageId = MessageId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie));
|
|
@@ -107825,24 +108783,40 @@ const ThreadWatchEventsTool = Tool.make("thread_watch_events", {
|
|
|
107825
108783
|
failure: ThreadWatchToolError,
|
|
107826
108784
|
dependencies: [McpInvocationContext, ThreadEventStreamService]
|
|
107827
108785
|
}).annotate(Tool.Title, "Read watched thread events").annotate(Tool.Readonly, true).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, true);
|
|
107828
|
-
const
|
|
107829
|
-
|
|
107830
|
-
|
|
107831
|
-
|
|
107832
|
-
|
|
107833
|
-
|
|
107834
|
-
|
|
107835
|
-
|
|
107836
|
-
|
|
107837
|
-
|
|
107838
|
-
|
|
107839
|
-
|
|
107840
|
-
|
|
107841
|
-
|
|
107842
|
-
|
|
107843
|
-
|
|
107844
|
-
|
|
107845
|
-
|
|
108786
|
+
const ThreadWatchReviewTool = Tool.make("thread_watch_review", {
|
|
108787
|
+
description: "Read bounded compact review evidence for an explicitly granted thread. Combines assistant fragments by message identity; preserves user requirements, tool evidence, plans, errors and turn boundaries. Resume with nextAfterSequence and the same throughSequence until hasMore is false, even on empty pages. Message operations append or replace by identity across pages. Truncated evidence includes source sequence ranges for targeted recovery with thread_watch_events; do not treat an excerpt as full proof.",
|
|
108788
|
+
parameters: ThreadWatchReviewInput,
|
|
108789
|
+
success: ThreadWatchReviewResult,
|
|
108790
|
+
failure: ThreadWatchToolError,
|
|
108791
|
+
dependencies: [McpInvocationContext, ThreadEventStreamService]
|
|
108792
|
+
}).annotate(Tool.Title, "Read compact thread review").annotate(Tool.Readonly, true).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, true);
|
|
108793
|
+
const WatchToolkit = Toolkit.make(ThreadWatchEventsTool, ThreadWatchReviewTool);
|
|
108794
|
+
const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
108795
|
+
thread_watch_review: (input) => Effect.gen(function* () {
|
|
108796
|
+
yield* requireWatchCapability(input.threadId);
|
|
108797
|
+
return yield* (yield* ThreadEventStreamService).readReview(input).pipe(Effect.mapError((cause) => new ThreadWatchFailedError({
|
|
108798
|
+
threadId: input.threadId,
|
|
108799
|
+
detail: cause.message
|
|
108800
|
+
})));
|
|
108801
|
+
}),
|
|
108802
|
+
thread_watch_events: (input) => Effect.gen(function* () {
|
|
108803
|
+
yield* requireWatchCapability(input.threadId);
|
|
108804
|
+
const page = yield* (yield* ThreadEventStreamService).read({
|
|
108805
|
+
threadId: input.threadId,
|
|
108806
|
+
...input.afterSequence !== void 0 ? { afterSequence: input.afterSequence } : {},
|
|
108807
|
+
limit: input.limit ?? 50
|
|
108808
|
+
}).pipe(Effect.mapError((cause) => new ThreadWatchFailedError({
|
|
108809
|
+
threadId: input.threadId,
|
|
108810
|
+
detail: cause.message
|
|
108811
|
+
})));
|
|
108812
|
+
return {
|
|
108813
|
+
threadId: input.threadId,
|
|
108814
|
+
events: page.events,
|
|
108815
|
+
headSequence: page.headSequence,
|
|
108816
|
+
hasMore: page.hasMore
|
|
108817
|
+
};
|
|
108818
|
+
})
|
|
108819
|
+
});
|
|
107846
108820
|
//#endregion
|
|
107847
108821
|
//#region src/mcp/McpHttpServer.ts
|
|
107848
108822
|
const unauthorized = HttpServerResponse.jsonUnsafe({
|
|
@@ -108017,6 +108991,100 @@ var ThreadDeletionReactor = class extends Context.Service()("@p4code/cli/orchest
|
|
|
108017
108991
|
//#region src/orchestration/Services/FusionWatcherReactor.ts
|
|
108018
108992
|
var FusionWatcherReactor = class extends Context.Service()("@p4code/cli/orchestration/Services/FusionWatcherReactor") {};
|
|
108019
108993
|
//#endregion
|
|
108994
|
+
//#region src/orchestration/Layers/ThreadCompletionReactor.ts
|
|
108995
|
+
const COMPLETION_SWEEP_BATCH_SIZE = 25;
|
|
108996
|
+
const COMPLETION_SWEEP_INTERVAL = Duration.minutes(1);
|
|
108997
|
+
const COMPLETION_PR_TIMEOUT = Duration.seconds(10);
|
|
108998
|
+
const MILLISECONDS_PER_DAY = 1440 * 60 * 1e3;
|
|
108999
|
+
const make$6 = Effect.gen(function* () {
|
|
109000
|
+
const sql = yield* SqlClient.SqlClient;
|
|
109001
|
+
const settings = yield* ServerSettingsService;
|
|
109002
|
+
const git = yield* GitManager;
|
|
109003
|
+
const engine = yield* OrchestrationEngineService;
|
|
109004
|
+
const crypto = yield* Crypto.Crypto;
|
|
109005
|
+
const mutex = yield* Semaphore.make(1);
|
|
109006
|
+
let cursor = "";
|
|
109007
|
+
const candidates = SqlSchema.findAll({
|
|
109008
|
+
Request: Schema$1.String,
|
|
109009
|
+
Result: Schema$1.Struct({
|
|
109010
|
+
threadId: ThreadId,
|
|
109011
|
+
cwd: Schema$1.String,
|
|
109012
|
+
branch: Schema$1.NullOr(Schema$1.String),
|
|
109013
|
+
lastEngagedAt: IsoDateTime,
|
|
109014
|
+
pinnedAt: Schema$1.NullOr(IsoDateTime),
|
|
109015
|
+
projectDeletedAt: Schema$1.NullOr(IsoDateTime),
|
|
109016
|
+
pendingApprovalCount: Schema$1.Number,
|
|
109017
|
+
pendingUserInputCount: Schema$1.Number,
|
|
109018
|
+
sessionStatus: Schema$1.NullOr(Schema$1.String)
|
|
109019
|
+
}),
|
|
109020
|
+
execute: (afterThreadId) => sql`
|
|
109021
|
+
SELECT t.thread_id AS "threadId", COALESCE(t.worktree_path, p.workspace_root) AS "cwd",
|
|
109022
|
+
t.branch, t.last_engaged_at AS "lastEngagedAt", t.pinned_at AS "pinnedAt",
|
|
109023
|
+
p.deleted_at AS "projectDeletedAt", t.pending_approval_count AS "pendingApprovalCount",
|
|
109024
|
+
t.pending_user_input_count AS "pendingUserInputCount", s.status AS "sessionStatus"
|
|
109025
|
+
FROM projection_threads t
|
|
109026
|
+
JOIN projection_projects p ON p.project_id = t.project_id
|
|
109027
|
+
LEFT JOIN projection_thread_sessions s ON s.thread_id = t.thread_id
|
|
109028
|
+
WHERE t.lifecycle = 'active' AND t.deleted_at IS NULL
|
|
109029
|
+
AND t.thread_id > ${afterThreadId}
|
|
109030
|
+
ORDER BY t.thread_id ASC LIMIT ${COMPLETION_SWEEP_BATCH_SIZE}
|
|
109031
|
+
`
|
|
109032
|
+
});
|
|
109033
|
+
const sweep = Effect.fn("ThreadCompletionReactor.sweep")(function* () {
|
|
109034
|
+
yield* mutex.withPermits(1)(Effect.gen(function* () {
|
|
109035
|
+
const now = yield* Clock.currentTimeMillis;
|
|
109036
|
+
const days = (yield* settings.getSettings).threadAutoCompleteAfterDays;
|
|
109037
|
+
const cutoff = days === null ? null : now - days * MILLISECONDS_PER_DAY;
|
|
109038
|
+
const rows = yield* candidates(cursor);
|
|
109039
|
+
const branchStates = /* @__PURE__ */ new Map();
|
|
109040
|
+
for (const row of rows) {
|
|
109041
|
+
if (row.projectDeletedAt !== null || row.pinnedAt !== null || row.pendingApprovalCount > 0 || row.pendingUserInputCount > 0 || row.sessionStatus === "starting" || row.sessionStatus === "running") continue;
|
|
109042
|
+
const key = `${row.cwd.length}:${row.cwd}${row.branch ?? ""}`;
|
|
109043
|
+
let pr = branchStates.get(key);
|
|
109044
|
+
if (pr === void 0) {
|
|
109045
|
+
pr = yield* git.threadCompletionPrState({
|
|
109046
|
+
cwd: row.cwd,
|
|
109047
|
+
branch: row.branch
|
|
109048
|
+
}).pipe(Effect.timeout(COMPLETION_PR_TIMEOUT), Effect.orElseSucceed(() => ({ state: "unknown" })));
|
|
109049
|
+
branchStates.set(key, pr);
|
|
109050
|
+
}
|
|
109051
|
+
if (pr.state === "unknown" || pr.state === "open") continue;
|
|
109052
|
+
const engagedAt = Date.parse(row.lastEngagedAt);
|
|
109053
|
+
const terminalAt = pr.state === "terminal" ? Date.parse(pr.terminalAt) : null;
|
|
109054
|
+
if (terminalAt !== null && (!Number.isFinite(terminalAt) || terminalAt > now)) continue;
|
|
109055
|
+
const eligible = terminalAt !== null && terminalAt > engagedAt ? {
|
|
109056
|
+
reason: "pull-request",
|
|
109057
|
+
eligibleAt: DateTime.formatIso(DateTime.makeUnsafe(terminalAt))
|
|
109058
|
+
} : cutoff !== null && engagedAt < cutoff ? {
|
|
109059
|
+
reason: "inactivity",
|
|
109060
|
+
eligibleAt: DateTime.formatIso(DateTime.makeUnsafe(cutoff))
|
|
109061
|
+
} : null;
|
|
109062
|
+
if (eligible === null) continue;
|
|
109063
|
+
const commandId = CommandId.make(`server:thread-complete:${yield* crypto.randomUUIDv4}`);
|
|
109064
|
+
yield* engine.dispatch({
|
|
109065
|
+
type: "thread.complete.auto",
|
|
109066
|
+
commandId,
|
|
109067
|
+
threadId: row.threadId,
|
|
109068
|
+
expectedLastEngagedAt: row.lastEngagedAt,
|
|
109069
|
+
...eligible
|
|
109070
|
+
}).pipe(Effect.catch((cause) => Effect.logDebug("Automatic completion did not apply", {
|
|
109071
|
+
threadId: row.threadId,
|
|
109072
|
+
cause
|
|
109073
|
+
})));
|
|
109074
|
+
}
|
|
109075
|
+
cursor = rows.length < COMPLETION_SWEEP_BATCH_SIZE ? "" : rows.at(-1).threadId;
|
|
109076
|
+
}));
|
|
109077
|
+
});
|
|
109078
|
+
return {
|
|
109079
|
+
sweep,
|
|
109080
|
+
start: Effect.fn("ThreadCompletionReactor.start")(function* () {
|
|
109081
|
+
yield* sweep().pipe(Effect.catchCause((cause) => Effect.logWarning("Thread completion sweep failed", { cause })), Effect.repeat(Schedule.spaced(COMPLETION_SWEEP_INTERVAL)), Effect.forkScoped);
|
|
109082
|
+
})
|
|
109083
|
+
};
|
|
109084
|
+
});
|
|
109085
|
+
var ThreadCompletionReactor = class extends Context.Service()("@p4code/cli/orchestration/Layers/ThreadCompletionReactor") {};
|
|
109086
|
+
const ThreadCompletionReactorLive = Layer.effect(ThreadCompletionReactor, make$6);
|
|
109087
|
+
//#endregion
|
|
108020
109088
|
//#region src/orchestration/Services/ScheduledTaskReactor.ts
|
|
108021
109089
|
/**
|
|
108022
109090
|
* ScheduledTaskReactor - fires user-created scheduled tasks.
|
|
@@ -108037,6 +109105,7 @@ const makeOrchestrationReactor = Effect.gen(function* () {
|
|
|
108037
109105
|
const threadDeletionReactor = yield* ThreadDeletionReactor;
|
|
108038
109106
|
const fusionWatcherReactor = yield* FusionWatcherReactor;
|
|
108039
109107
|
const scheduledTaskReactor = yield* ScheduledTaskReactor;
|
|
109108
|
+
const completionReactor = yield* ThreadCompletionReactor;
|
|
108040
109109
|
return { start: Effect.fn("start")(function* () {
|
|
108041
109110
|
yield* providerRuntimeIngestion.start();
|
|
108042
109111
|
yield* providerCommandReactor.start();
|
|
@@ -108044,6 +109113,7 @@ const makeOrchestrationReactor = Effect.gen(function* () {
|
|
|
108044
109113
|
yield* threadDeletionReactor.start();
|
|
108045
109114
|
yield* fusionWatcherReactor.start();
|
|
108046
109115
|
yield* scheduledTaskReactor.start();
|
|
109116
|
+
yield* completionReactor.start();
|
|
108047
109117
|
}) };
|
|
108048
109118
|
});
|
|
108049
109119
|
const OrchestrationReactorLive = Layer.effect(OrchestrationReactor, makeOrchestrationReactor);
|
|
@@ -109437,7 +110507,7 @@ const HANDLED_TURN_START_KEY_TTL = Duration.minutes(30);
|
|
|
109437
110507
|
const DEFAULT_RUNTIME_MODE = "full-access";
|
|
109438
110508
|
const DEFAULT_THREAD_TITLE = "New thread";
|
|
109439
110509
|
const NON_SYSTEM_PROVIDER_STRUCTURED_USER_QUESTIONS = structuredUserQuestionPrompt("your provider's structured user-input question tool");
|
|
109440
|
-
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"
|
|
110510
|
+
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". A direct user request to use or spawn Fusion authorizes Fusion directly without a prior proposal; /fusion and $fusion are optional shortcuts. Do not activate, spawn, or promote until one of those authorizations arrives. UI work, complex logic, task size, unfamiliarity, or duration alone never qualifies.`;
|
|
109441
110511
|
const isFusionWatcherWakeMessageId = (messageId) => messageId.startsWith("fusion-review:") || messageId.startsWith("fusion-gate:");
|
|
109442
110512
|
const findActiveFusionPair = (pairs, threadId) => (pairs ?? []).find((pair) => pair.detachedAt === null && (pair.implementerThreadId === threadId || pair.watcherThreadId === threadId));
|
|
109443
110513
|
const fusionRoleForThread = (pairs, threadId) => {
|
|
@@ -111043,7 +112113,7 @@ After restart/context loss, derive phase from workspace git log/status, PR, rece
|
|
|
111043
112113
|
const watcherPrompt = (input) => `${FUSION_REVIEW_PROMPT_PREFIX}
|
|
111044
112114
|
Review completed builder turn ${input.implementerThreadId}.
|
|
111045
112115
|
|
|
111046
|
-
Call
|
|
112116
|
+
Call thread_watch_review, threadId ${input.implementerThreadId}, afterSequence ${input.afterSequence}, throughSequence ${input.throughSequence}. Continue with nextAfterSequence and the same throughSequence until hasMore is false, including empty pages. Apply message append/replace operations by identity across pages. Recover truncated or uncertain evidence with targeted thread_watch_events reads using its source sequence range. Inspect repo when useful.
|
|
111047
112117
|
|
|
111048
112118
|
Always report concise:
|
|
111049
112119
|
|
|
@@ -111055,7 +112125,7 @@ Determine review boundary from builder's todo status:
|
|
|
111055
112125
|
|
|
111056
112126
|
- Remaining phases, or final status unclear, and the builder has actionable work: intermediate phase review. Call thread_advise for ${input.implementerThreadId}. With objections, send required corrections and next phase. With none, explicitly approve phase and tell builder to continue next todo phase. Never require tests, typecheck, lint, or builds before the final phase.
|
|
111057
112127
|
- Builder waiting on an external process or with nothing actionable: no thread_advise. Report the state here and end.
|
|
111058
|
-
- Final whole-task phase ready:
|
|
112128
|
+
- Final whole-task phase ready: combine previously reviewed evidence with this delta and inspect the full task diff/state. Review original requirements and later corrections, integration across all phases, verification, and delivery. Recover missing requirements or uncertain prior evidence with targeted compact history reads bounded by throughSequence ${input.throughSequence}, and raw source reads when necessary. Do not replay raw history from zero by default. If prior context is unavailable, recover the requirements before concluding. Advise only for concrete objections or unfinished work; otherwise report no objections and end.
|
|
111059
112129
|
|
|
111060
112130
|
${watcherPowers(input.implementerThreadId)}
|
|
111061
112131
|
|
|
@@ -111074,7 +112144,7 @@ const gateKindDescription = (gate) => {
|
|
|
111074
112144
|
const gatePrompt = (input) => `${FUSION_GATE_PROMPT_PREFIX}
|
|
111075
112145
|
Gate ${input.gate.id} is open on builder thread ${input.implementerThreadId}: ${gateKindDescription(input.gate)}. Round ${Math.min(input.gate.round + 1, input.roundCap)} of ${input.roundCap}.
|
|
111076
112146
|
|
|
111077
|
-
First read delta:
|
|
112147
|
+
First read delta: thread_watch_review, threadId ${input.implementerThreadId}, afterSequence ${input.afterSequence}, throughSequence ${input.throughSequence}. Continue with nextAfterSequence and the same throughSequence until hasMore is false, including empty pages. Apply message append/replace operations by identity across pages; recover truncated or uncertain evidence with targeted thread_watch_events reads using its source sequence range. Inspect repo when useful.
|
|
111078
112148
|
|
|
111079
112149
|
Then thread_gate_respond, threadId ${input.implementerThreadId}, gateId ${input.gate.id}:
|
|
111080
112150
|
|
|
@@ -112807,7 +113877,7 @@ const PlatformServicesLive = Layer.unwrap(Effect.gen(function* () {
|
|
|
112807
113877
|
return layer;
|
|
112808
113878
|
}
|
|
112809
113879
|
}));
|
|
112810
|
-
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));
|
|
113880
|
+
const ReactorLayerLive = Layer.empty.pipe(Layer.provideMerge(OrchestrationReactorLive), Layer.provideMerge(ProviderRuntimeIngestionLive), Layer.provideMerge(ProviderCommandReactorLive), Layer.provideMerge(CheckpointReactorLive), Layer.provideMerge(ThreadDeletionReactorLive), Layer.provideMerge(FusionWatcherReactorLive), Layer.provideMerge(ScheduledTaskReactorLive), Layer.provideMerge(ThreadCompletionReactorLive), Layer.provideMerge(RuntimeReceiptBusLive));
|
|
112811
113881
|
const ProviderSessionDirectoryLayerLive = ProviderSessionDirectoryLive.pipe(Layer.provide(layer$4));
|
|
112812
113882
|
const ProviderLayerLive = ProviderServiceLive.pipe(Layer.provide(ProviderAdapterRegistryLive), Layer.provideMerge(ProviderSessionDirectoryLayerLive));
|
|
112813
113883
|
const PersistenceLayerLive = Layer.empty.pipe(Layer.provideMerge(layerConfig));
|