@p4code/cli 0.1.12 → 0.1.13
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 +201 -32
- package/dist/client/assets/{DiffPanel-DLEF2Os4.js → DiffPanel-Bpvhj9Zk.js} +3 -3
- package/dist/client/assets/{FilePreviewPanel-8D_2Xs92.js → FilePreviewPanel-C2_gi2li.js} +5 -5
- package/dist/client/assets/PreviewPanel-CXrvKPAn.js +2 -0
- package/dist/client/assets/{angular-html-CMBWPyD3.js → angular-html-tWdnCR5u.js} +2 -2
- package/dist/client/assets/{angular-ts-BatZhjLf.js → angular-ts-DHHrhqEn.js} +2 -2
- package/dist/client/assets/{apl-Cx1sW3hC.js → apl-Dttzd1My.js} +2 -2
- package/dist/client/assets/arrow-right-DL8xTI3l.js +2 -0
- package/dist/client/assets/{astro-nMa7HQcv.js → astro-BhhLcbHg.js} +2 -2
- package/dist/client/assets/{blade-JxAt8tFv.js → blade-D1XdhGNZ.js} +2 -2
- package/dist/client/assets/{c-C-yEqtHp.js → c-DU3so7RH.js} +2 -2
- package/dist/client/assets/{cobol-CA3DrkO1.js → cobol-C5SwCVtJ.js} +2 -2
- package/dist/client/assets/{coffee-CNzul851.js → coffee-D8JHirJ4.js} +2 -2
- package/dist/client/assets/{cpp-DYasO6ny.js → cpp-BrxgqiPv.js} +2 -2
- package/dist/client/assets/{crystal-BkYnv3Y5.js → crystal-LnjbHrAj.js} +2 -2
- package/dist/client/assets/{css-GnxXZE-U.js → css-BhvHnfwC.js} +2 -2
- package/dist/client/assets/{edge-DHx6AdO-.js → edge-BIAZ2O1m.js} +2 -2
- package/dist/client/assets/{elixir-XiEvMT4-.js → elixir-C7fzptdf.js} +2 -2
- package/dist/client/assets/{elm-BY4GYI5F.js → elm-24neygAB.js} +2 -2
- package/dist/client/assets/{erb-DDG6lOki.js → erb-DpLDFI3P.js} +2 -2
- package/dist/client/assets/{fileCommentAnnotations-BTZDcAeh.js → fileCommentAnnotations-D9LoOqKz.js} +2 -2
- package/dist/client/assets/{git-rebase-BDUy60An.js → git-rebase-nk76LFrn.js} +2 -2
- package/dist/client/assets/{glimmer-js-Dpr_XG7j.js → glimmer-js-D4faXOGy.js} +2 -2
- package/dist/client/assets/{glimmer-ts-CtZ0ZipS.js → glimmer-ts-CUIVPmuw.js} +2 -2
- package/dist/client/assets/{glsl-DHtQlcKL.js → glsl-CHEysBk5.js} +2 -2
- package/dist/client/assets/{graphql-DtNuYKEb.js → graphql-DxDXWgtu.js} +2 -2
- package/dist/client/assets/{hack-BqNfldCe.js → hack-SE0rPM7F.js} +2 -2
- package/dist/client/assets/{haml-mPiLB45s.js → haml-CZNVJ1t_.js} +2 -2
- package/dist/client/assets/{handlebars-BLxX_l2A.js → handlebars-D3H0z0i1.js} +2 -2
- package/dist/client/assets/{html-DU5G3F4s.js → html-BXh14Kiu.js} +2 -2
- package/dist/client/assets/{html-derivative-BMJPXTuS.js → html-derivative-Dcx75xJi.js} +2 -2
- package/dist/client/assets/{http-6kGF1eof.js → http-CHN_K5kg.js} +2 -2
- package/dist/client/assets/{hurl-CvT1bXUG.js → hurl-DcyaHxXE.js} +2 -2
- package/dist/client/assets/{index-nkPMSYxq.css → index-D7hXE3Wh.css} +1 -1
- package/dist/client/assets/index-DesIBOH0.js +660 -0
- package/dist/client/assets/{java-bBnbDfw8.js → java-CibfJb97.js} +2 -2
- package/dist/client/assets/{javascript-CpOINVUc.js → javascript-CGKYJrgO.js} +2 -2
- package/dist/client/assets/{jinja-CItwptlU.js → jinja-hMi6h2V1.js} +2 -2
- package/dist/client/assets/{jison-BWvHru6a.js → jison-D5hwL1Vj.js} +2 -2
- package/dist/client/assets/{json-ClObSVU5.js → json-DBBzorBt.js} +2 -2
- package/dist/client/assets/{jsx-vHozUqKh.js → jsx-CfjpnlWf.js} +2 -2
- package/dist/client/assets/{julia-CITEF0SC.js → julia-DY-wGzwr.js} +2 -2
- package/dist/client/assets/{just-CAMHq4cU.js → just-Aiaxo0L3.js} +2 -2
- package/dist/client/assets/{latex-BHB-Vy2g.js → latex-Cl7y6v9p.js} +2 -2
- package/dist/client/assets/{liquid-rsijXGco.js → liquid-tjIYQaDR.js} +2 -2
- package/dist/client/assets/{lua-CPA1zmkS.js → lua-DeDHmNSA.js} +2 -2
- package/dist/client/assets/{marko-D9CJEgH2.js → marko-BLEE3RS_.js} +2 -2
- package/dist/client/assets/{mdc-DL5ptUuf.js → mdc-DBLy0ju2.js} +2 -2
- package/dist/client/assets/{nginx-DAAmFPDe.js → nginx-BpS56zJM.js} +2 -2
- package/dist/client/assets/{nim-DmaHLOWa.js → nim-BP_5ZWs4.js} +2 -2
- package/dist/client/assets/{perl-Bw03qQ4D.js → perl-BNoghH8w.js} +2 -2
- package/dist/client/assets/{php-DdSlZ5fF.js → php-fikhFdsH.js} +2 -2
- package/dist/client/assets/{pug-CgQdUdQK.js → pug-BmML_p4L.js} +2 -2
- package/dist/client/assets/{qml-6-Z__KDk.js → qml-WOQTdjfD.js} +2 -2
- package/dist/client/assets/{r-BwsNM1XU.js → r-BuLVFJ9C.js} +2 -2
- package/dist/client/assets/{razor-DRWY5qRs.js → razor-CsZ5mXvp.js} +2 -2
- package/dist/client/assets/{regexp-BGiLplmg.js → regexp-BbB_Z0k0.js} +2 -2
- package/dist/client/assets/{rst-CND1NmX_.js → rst-CGogIoWE.js} +2 -2
- package/dist/client/assets/{ruby-Dlxt-z_r.js → ruby-Drt9dpIY.js} +2 -2
- package/dist/client/assets/{sas-DFeunfku.js → sas-mvidrzzg.js} +2 -2
- package/dist/client/assets/{scss-D_BTo2XD.js → scss-DcqXsy4k.js} +2 -2
- package/dist/client/assets/{shellscript-cEuOjvsv.js → shellscript-C6nla6y6.js} +2 -2
- package/dist/client/assets/{shellsession-CeWrE-Lw.js → shellsession-Dhkmvk-h.js} +2 -2
- package/dist/client/assets/{soy-DdFNKMwD.js → soy-CA1GOdLw.js} +2 -2
- package/dist/client/assets/{sql-3jzdtF3L.js → sql-CaDtCgQd.js} +2 -2
- package/dist/client/assets/{stata-CfftDdbo.js → stata-r5dYDO1a.js} +2 -2
- package/dist/client/assets/{surrealql-BgLa39M_.js → surrealql-CreiDVJS.js} +2 -2
- package/dist/client/assets/{svelte-CJNznzEX.js → svelte-LQf52vP7.js} +2 -2
- package/dist/client/assets/{templ-DiQ0ONH_.js → templ-BAiCCrhW.js} +2 -2
- package/dist/client/assets/{tex-Dj5-ewTi.js → tex-Bi4veNnI.js} +2 -2
- package/dist/client/assets/textarea-8UeQ85tZ.js +46 -0
- package/dist/client/assets/{ts-tags-Rut2YPAl.js → ts-tags-CmONaW11.js} +2 -2
- package/dist/client/assets/{tsx-TxGWIfKc.js → tsx-DEGaq1SP.js} +2 -2
- package/dist/client/assets/{twig-CEDmL9ir.js → twig-DR3myS6w.js} +2 -2
- package/dist/client/assets/{typescript-B1NW_Svr.js → typescript-pTX3WTUF.js} +2 -2
- package/dist/client/assets/{vue-CEjpLlUp.js → vue-_Gh228sM.js} +2 -2
- package/dist/client/assets/{vue-html-BLRayXbW.js → vue-html-DqI2SuCG.js} +2 -2
- package/dist/client/assets/{vue-vine-BaZ_eWYq.js → vue-vine-DJ2u5TuR.js} +2 -2
- package/dist/client/assets/{xml-WjUY_YSL.js → xml-DtWHD1Mk.js} +2 -2
- package/dist/client/assets/{xsl-rMBkkP2N.js → xsl--uIbb82K.js} +2 -2
- package/dist/client/assets/{yaml-BVcdKGq_.js → yaml-BYZt09An.js} +2 -2
- package/dist/client/index.html +3 -3
- package/package.json +1 -1
- package/dist/client/assets/PreviewPanel-DiR-_u2D.js +0 -2
- package/dist/client/assets/arrow-right-D6CCHJEU.js +0 -2
- package/dist/client/assets/index-JvBwT8k1.js +0 -660
- package/dist/client/assets/textarea-CtwXMNmJ.js +0 -46
package/dist/bin.mjs
CHANGED
|
@@ -233,7 +233,7 @@ const make$73 = () => {
|
|
|
233
233
|
const layer$69 = Layer.sync(NetService, make$73);
|
|
234
234
|
//#endregion
|
|
235
235
|
//#region package.json
|
|
236
|
-
var version = "0.1.
|
|
236
|
+
var version = "0.1.13";
|
|
237
237
|
//#endregion
|
|
238
238
|
//#region src/config.ts
|
|
239
239
|
/**
|
|
@@ -1657,6 +1657,7 @@ const CompressMode = Schema$1.Literals([
|
|
|
1657
1657
|
"full",
|
|
1658
1658
|
"ultra"
|
|
1659
1659
|
]);
|
|
1660
|
+
const DEFAULT_COMPRESS_MODE = "full";
|
|
1660
1661
|
const ProviderRequestKind = Schema$1.Literals([
|
|
1661
1662
|
"command",
|
|
1662
1663
|
"file-read",
|
|
@@ -1833,7 +1834,7 @@ const OrchestrationThread = Schema$1.Struct({
|
|
|
1833
1834
|
modelSelection: ModelSelection,
|
|
1834
1835
|
runtimeMode: RuntimeMode,
|
|
1835
1836
|
interactionMode: ProviderInteractionMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE))),
|
|
1836
|
-
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(
|
|
1837
|
+
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_COMPRESS_MODE))),
|
|
1837
1838
|
branch: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
1838
1839
|
worktreePath: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
1839
1840
|
latestTurn: Schema$1.NullOr(OrchestrationLatestTurn),
|
|
@@ -1874,7 +1875,7 @@ const OrchestrationThreadShell = Schema$1.Struct({
|
|
|
1874
1875
|
modelSelection: ModelSelection,
|
|
1875
1876
|
runtimeMode: RuntimeMode,
|
|
1876
1877
|
interactionMode: ProviderInteractionMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE))),
|
|
1877
|
-
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(
|
|
1878
|
+
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_COMPRESS_MODE))),
|
|
1878
1879
|
branch: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
1879
1880
|
worktreePath: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
1880
1881
|
latestTurn: Schema$1.NullOr(OrchestrationLatestTurn),
|
|
@@ -1997,7 +1998,7 @@ const ThreadCreateCommand = Schema$1.Struct({
|
|
|
1997
1998
|
modelSelection: ModelSelection,
|
|
1998
1999
|
runtimeMode: RuntimeMode,
|
|
1999
2000
|
interactionMode: ProviderInteractionMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE))),
|
|
2000
|
-
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(
|
|
2001
|
+
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_COMPRESS_MODE))),
|
|
2001
2002
|
branch: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2002
2003
|
worktreePath: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2003
2004
|
createdAt: IsoDateTime
|
|
@@ -2077,7 +2078,7 @@ const ThreadTurnStartBootstrapCreateThread = Schema$1.Struct({
|
|
|
2077
2078
|
modelSelection: ModelSelection,
|
|
2078
2079
|
runtimeMode: RuntimeMode,
|
|
2079
2080
|
interactionMode: ProviderInteractionMode,
|
|
2080
|
-
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(
|
|
2081
|
+
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_COMPRESS_MODE))),
|
|
2081
2082
|
branch: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2082
2083
|
worktreePath: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2083
2084
|
createdAt: IsoDateTime
|
|
@@ -2107,7 +2108,7 @@ const ThreadTurnStartCommand = Schema$1.Struct({
|
|
|
2107
2108
|
titleSeed: Schema$1.optional(TrimmedNonEmptyString),
|
|
2108
2109
|
runtimeMode: RuntimeMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE$2))),
|
|
2109
2110
|
interactionMode: ProviderInteractionMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE))),
|
|
2110
|
-
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(
|
|
2111
|
+
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_COMPRESS_MODE))),
|
|
2111
2112
|
bootstrap: Schema$1.optional(ThreadTurnStartBootstrap),
|
|
2112
2113
|
sourceProposedPlan: Schema$1.optional(SourceProposedPlanReference),
|
|
2113
2114
|
createdAt: IsoDateTime
|
|
@@ -2126,7 +2127,7 @@ const ClientThreadTurnStartCommand = Schema$1.Struct({
|
|
|
2126
2127
|
titleSeed: Schema$1.optional(TrimmedNonEmptyString),
|
|
2127
2128
|
runtimeMode: RuntimeMode,
|
|
2128
2129
|
interactionMode: ProviderInteractionMode,
|
|
2129
|
-
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(
|
|
2130
|
+
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_COMPRESS_MODE))),
|
|
2130
2131
|
bootstrap: Schema$1.optional(ThreadTurnStartBootstrap),
|
|
2131
2132
|
sourceProposedPlan: Schema$1.optional(SourceProposedPlanReference),
|
|
2132
2133
|
createdAt: IsoDateTime
|
|
@@ -2346,7 +2347,7 @@ const ThreadCreatedPayload$1 = Schema$1.Struct({
|
|
|
2346
2347
|
modelSelection: ModelSelection,
|
|
2347
2348
|
runtimeMode: RuntimeMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE$2))),
|
|
2348
2349
|
interactionMode: ProviderInteractionMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE))),
|
|
2349
|
-
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(
|
|
2350
|
+
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_COMPRESS_MODE))),
|
|
2350
2351
|
branch: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2351
2352
|
worktreePath: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
2352
2353
|
createdAt: IsoDateTime,
|
|
@@ -2406,7 +2407,7 @@ const ThreadInteractionModeSetPayload$1 = Schema$1.Struct({
|
|
|
2406
2407
|
});
|
|
2407
2408
|
const ThreadCompressModeSetPayload$1 = Schema$1.Struct({
|
|
2408
2409
|
threadId: ThreadId,
|
|
2409
|
-
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(
|
|
2410
|
+
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_COMPRESS_MODE))),
|
|
2410
2411
|
updatedAt: IsoDateTime
|
|
2411
2412
|
});
|
|
2412
2413
|
const ThreadMessageSentPayload = Schema$1.Struct({
|
|
@@ -2427,7 +2428,7 @@ const ThreadTurnStartRequestedPayload = Schema$1.Struct({
|
|
|
2427
2428
|
titleSeed: Schema$1.optional(TrimmedNonEmptyString),
|
|
2428
2429
|
runtimeMode: RuntimeMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE$2))),
|
|
2429
2430
|
interactionMode: ProviderInteractionMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE))),
|
|
2430
|
-
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(
|
|
2431
|
+
compressMode: CompressMode.pipe(Schema$1.withDecodingDefault(Effect.succeed(DEFAULT_COMPRESS_MODE))),
|
|
2431
2432
|
sourceProposedPlan: Schema$1.optional(SourceProposedPlanReference),
|
|
2432
2433
|
createdAt: IsoDateTime
|
|
2433
2434
|
});
|
|
@@ -7651,6 +7652,57 @@ const ThreadControlToolError = Schema$1.Union([
|
|
|
7651
7652
|
ThreadRenameRejectedError,
|
|
7652
7653
|
MemoryAppendFailedError
|
|
7653
7654
|
]);
|
|
7655
|
+
const ThreadWatchEventsInput = Schema$1.Struct({
|
|
7656
|
+
threadId: ThreadId.annotate({ description: "The watched thread to read events from. Must be explicitly granted." }),
|
|
7657
|
+
afterSequence: Schema$1.optional(NonNegativeInt.annotate({ description: "Exclusive sequence cursor. Events with a higher sequence are returned. Omit to read from the beginning." })),
|
|
7658
|
+
limit: Schema$1.optional(NonNegativeInt.check(Schema$1.isLessThanOrEqualTo(200)).annotate({ description: `Maximum events to return (default 50, max 200).` }))
|
|
7659
|
+
});
|
|
7660
|
+
const ThreadWatchEventsResult = Schema$1.Struct({
|
|
7661
|
+
threadId: ThreadId,
|
|
7662
|
+
/** Ordered by sequence ascending; resume with the last event's sequence. */
|
|
7663
|
+
events: Schema$1.Array(OrchestrationEvent),
|
|
7664
|
+
/**
|
|
7665
|
+
* The engine's latest persisted sequence at read time. Equal to the last
|
|
7666
|
+
* returned event's sequence when the watcher is caught up.
|
|
7667
|
+
*/
|
|
7668
|
+
headSequence: NonNegativeInt,
|
|
7669
|
+
/** True when more events for this thread exist past the returned page. */
|
|
7670
|
+
hasMore: Schema$1.Boolean
|
|
7671
|
+
});
|
|
7672
|
+
var WatchToolUnavailableError = class extends Schema$1.TaggedErrorClass()("WatchToolUnavailableError", {
|
|
7673
|
+
capability: Schema$1.Literal("watch"),
|
|
7674
|
+
environmentId: EnvironmentId,
|
|
7675
|
+
threadId: ThreadId,
|
|
7676
|
+
providerSessionId: TrimmedNonEmptyString,
|
|
7677
|
+
providerInstanceId: ProviderInstanceId
|
|
7678
|
+
}) {
|
|
7679
|
+
get message() {
|
|
7680
|
+
return `MCP credential does not grant the ${this.capability} capability.`;
|
|
7681
|
+
}
|
|
7682
|
+
};
|
|
7683
|
+
/**
|
|
7684
|
+
* The capability is present but the requested thread is not in the granted
|
|
7685
|
+
* set. Separate from {@link WatchToolUnavailableError} so a watcher can tell
|
|
7686
|
+
* "you cannot watch at all" apart from "not this thread".
|
|
7687
|
+
*/
|
|
7688
|
+
var ThreadWatchNotPermittedError = class extends Schema$1.TaggedErrorClass()("ThreadWatchNotPermittedError", { threadId: ThreadId }) {
|
|
7689
|
+
get message() {
|
|
7690
|
+
return `This session was not granted watch access to thread ${this.threadId}.`;
|
|
7691
|
+
}
|
|
7692
|
+
};
|
|
7693
|
+
var ThreadWatchFailedError = class extends Schema$1.TaggedErrorClass()("ThreadWatchFailedError", {
|
|
7694
|
+
threadId: ThreadId,
|
|
7695
|
+
detail: Schema$1.String
|
|
7696
|
+
}) {
|
|
7697
|
+
get message() {
|
|
7698
|
+
return `Reading events for thread ${this.threadId} failed: ${this.detail}`;
|
|
7699
|
+
}
|
|
7700
|
+
};
|
|
7701
|
+
const ThreadWatchToolError = Schema$1.Union([
|
|
7702
|
+
WatchToolUnavailableError,
|
|
7703
|
+
ThreadWatchNotPermittedError,
|
|
7704
|
+
ThreadWatchFailedError
|
|
7705
|
+
]);
|
|
7654
7706
|
//#endregion
|
|
7655
7707
|
//#region ../../packages/contracts/src/agentAsset.ts
|
|
7656
7708
|
/**
|
|
@@ -23936,11 +23988,66 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
23936
23988
|
});
|
|
23937
23989
|
const OrchestrationProjectionSnapshotQueryLive = Layer.effect(ProjectionSnapshotQuery, makeProjectionSnapshotQuery);
|
|
23938
23990
|
//#endregion
|
|
23991
|
+
//#region src/orchestration/Services/ThreadEventStream.ts
|
|
23992
|
+
var ThreadEventStreamService = class extends Context.Service()("@p4code/cli/orchestration/Services/ThreadEventStream/ThreadEventStreamService") {};
|
|
23993
|
+
//#endregion
|
|
23994
|
+
//#region src/orchestration/Layers/ThreadEventStream.ts
|
|
23995
|
+
const makeThreadEventStream = Effect.gen(function* () {
|
|
23996
|
+
const engine = yield* OrchestrationEngineService;
|
|
23997
|
+
const isThreadEvent = (threadId) => (event) => event.aggregateKind === "thread" && event.aggregateId === threadId;
|
|
23998
|
+
const watch = (input) => Stream.unwrap(Effect.gen(function* () {
|
|
23999
|
+
const matchesThread = isThreadEvent(input.threadId);
|
|
24000
|
+
const liveBuffer = yield* Queue.unbounded();
|
|
24001
|
+
yield* Effect.forkScoped(engine.streamDomainEvents.pipe(Stream.filter(matchesThread), Stream.runForEach((event) => Queue.offer(liveBuffer, event))), { startImmediately: true });
|
|
24002
|
+
const afterSequence = input.afterSequence ?? 0;
|
|
24003
|
+
const headSequence = yield* engine.latestSequence;
|
|
24004
|
+
const replayGap = headSequence - afterSequence;
|
|
24005
|
+
const catchUp = replayGap > 0 ? engine.readEvents(afterSequence, replayGap).pipe(Stream.filter(matchesThread)) : Stream.empty;
|
|
24006
|
+
const caughtUp = Stream.make({
|
|
24007
|
+
kind: "caught-up",
|
|
24008
|
+
headSequence
|
|
24009
|
+
});
|
|
24010
|
+
const live = Stream.fromQueue(liveBuffer).pipe(Stream.filter((event) => event.sequence > headSequence));
|
|
24011
|
+
return Stream.concat(catchUp.pipe(Stream.map((event) => ({
|
|
24012
|
+
kind: "event",
|
|
24013
|
+
event
|
|
24014
|
+
}))), Stream.concat(caughtUp, live.pipe(Stream.map((event) => ({
|
|
24015
|
+
kind: "event",
|
|
24016
|
+
event
|
|
24017
|
+
})))));
|
|
24018
|
+
}));
|
|
24019
|
+
const read = (input) => Effect.gen(function* () {
|
|
24020
|
+
const matchesThread = isThreadEvent(input.threadId);
|
|
24021
|
+
const afterSequence = input.afterSequence ?? 0;
|
|
24022
|
+
const headSequence = yield* engine.latestSequence;
|
|
24023
|
+
const replayGap = headSequence - afterSequence;
|
|
24024
|
+
if (replayGap <= 0) return {
|
|
24025
|
+
events: [],
|
|
24026
|
+
headSequence,
|
|
24027
|
+
hasMore: false
|
|
24028
|
+
};
|
|
24029
|
+
const collected = yield* engine.readEvents(afterSequence, replayGap).pipe(Stream.filter(matchesThread), Stream.take(input.limit + 1), Stream.runCollect);
|
|
24030
|
+
const events = Array.from(collected);
|
|
24031
|
+
const hasMore = events.length > input.limit;
|
|
24032
|
+
return {
|
|
24033
|
+
events: hasMore ? events.slice(0, input.limit) : events,
|
|
24034
|
+
headSequence,
|
|
24035
|
+
hasMore
|
|
24036
|
+
};
|
|
24037
|
+
});
|
|
24038
|
+
return ThreadEventStreamService.of({
|
|
24039
|
+
watch,
|
|
24040
|
+
read
|
|
24041
|
+
});
|
|
24042
|
+
});
|
|
24043
|
+
const ThreadEventStreamLive = Layer.effect(ThreadEventStreamService, makeThreadEventStream);
|
|
24044
|
+
//#endregion
|
|
23939
24045
|
//#region src/orchestration/runtimeLayer.ts
|
|
23940
24046
|
const OrchestrationEventInfrastructureLayerLive = Layer.mergeAll(OrchestrationEventStoreLive, OrchestrationCommandReceiptRepositoryLive);
|
|
23941
24047
|
const OrchestrationProjectionPipelineLayerLive = OrchestrationProjectionPipelineLive.pipe(Layer.provide(OrchestrationEventStoreLive));
|
|
23942
24048
|
const OrchestrationInfrastructureLayerLive = Layer.mergeAll(OrchestrationProjectionSnapshotQueryLive, OrchestrationEventInfrastructureLayerLive, OrchestrationProjectionPipelineLayerLive);
|
|
23943
|
-
const
|
|
24049
|
+
const OrchestrationEngineLayerLive = OrchestrationEngineLive.pipe(Layer.provide(OrchestrationInfrastructureLayerLive));
|
|
24050
|
+
const OrchestrationLayerLive = Layer.mergeAll(OrchestrationInfrastructureLayerLive, OrchestrationEngineLayerLive, ThreadEventStreamLive.pipe(Layer.provide(OrchestrationEngineLayerLive)));
|
|
23944
24051
|
//#endregion
|
|
23945
24052
|
//#region ../../packages/shared/src/keybindings.ts
|
|
23946
24053
|
const DEFAULT_KEYBINDINGS = [
|
|
@@ -27210,7 +27317,7 @@ const resolveAutoBootstrapWelcomeTargets = Effect.gen(function* () {
|
|
|
27210
27317
|
title: "New thread",
|
|
27211
27318
|
modelSelection: nextProjectDefaultModelSelection,
|
|
27212
27319
|
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
|
|
27213
|
-
compressMode:
|
|
27320
|
+
compressMode: DEFAULT_COMPRESS_MODE,
|
|
27214
27321
|
runtimeMode: "full-access",
|
|
27215
27322
|
branch: null,
|
|
27216
27323
|
worktreePath: null,
|
|
@@ -33254,6 +33361,12 @@ const toTaskStoreError = (operation) => (cause) => Effect.logWarning("task store
|
|
|
33254
33361
|
/**
|
|
33255
33362
|
* The `auto` rendering: here is the task, do it.
|
|
33256
33363
|
*
|
|
33364
|
+
* The prompt carries a reference to the task, not a copy of it. Inlining the
|
|
33365
|
+
* body flattened the row into plain text: labels, project and priority were
|
|
33366
|
+
* lost, and an edit made after the thread started was invisible to an agent
|
|
33367
|
+
* still reading its stale snapshot. The row stays the single source of truth
|
|
33368
|
+
* and the agent reads it live over MCP.
|
|
33369
|
+
*
|
|
33257
33370
|
* Two instructions carry their weight. The agent is told its thread is already
|
|
33258
33371
|
* linked to the task, because otherwise its first useful move is to guess which
|
|
33259
33372
|
* board row it is on. And it is told to leave `status` alone: the server moved
|
|
@@ -33262,18 +33375,16 @@ const toTaskStoreError = (operation) => (cause) => Effect.logWarning("task store
|
|
|
33262
33375
|
* the reason the board's columns still mean something.
|
|
33263
33376
|
*/
|
|
33264
33377
|
const buildAutoPrompt = (task) => {
|
|
33265
|
-
const
|
|
33266
|
-
return `You are picking up
|
|
33378
|
+
const reference = task.readableId ?? task.taskId;
|
|
33379
|
+
return `You are picking up task \`${reference}\` from the board: ${task.title}
|
|
33267
33380
|
|
|
33268
|
-
|
|
33381
|
+
Start by reading the task itself with \`task_current\` (or \`task_get\` with \`${reference}\`). The body, labels, project and priority live on the row, not in this message, and the row may have been edited since this thread started — what it says now is the source of truth. Re-read it the same way whenever you need the fields again.
|
|
33269
33382
|
|
|
33270
|
-
|
|
33271
|
-
|
|
33272
|
-
This thread is linked to task \`${task.taskId}\`, which is now In progress. \`task_current\` re-reads it if you need the fields again.
|
|
33383
|
+
This thread is already linked to the task, which is now In progress. Do the work.
|
|
33273
33384
|
|
|
33274
33385
|
Record what you find with \`task_update\` as you go — a decision you made, a constraint you hit, something the task turned out to be wrong about. That is what makes the row worth reading afterwards. Leave \`status\` alone: moving work across the board is the user's call.
|
|
33275
33386
|
|
|
33276
|
-
|
|
33387
|
+
After reading the task, read the code it concerns. If it turns out to be specified too poorly to act on, say so and stop rather than guessing at what was meant.`;
|
|
33277
33388
|
};
|
|
33278
33389
|
/**
|
|
33279
33390
|
* Render a task into the prompt that seeds its thread.
|
|
@@ -36228,6 +36339,24 @@ const requireTaskCapability = Effect.fn("mcp.requireTaskCapability")(function* (
|
|
|
36228
36339
|
});
|
|
36229
36340
|
return invocation;
|
|
36230
36341
|
});
|
|
36342
|
+
/**
|
|
36343
|
+
* The watch capability's guard is two checks, not one: the capability must be
|
|
36344
|
+
* present AND the requested thread must be in the explicit grant set. The two
|
|
36345
|
+
* failures are distinct errors so a watcher can tell "this session cannot
|
|
36346
|
+
* watch at all" apart from "not this thread".
|
|
36347
|
+
*/
|
|
36348
|
+
const requireWatchCapability = Effect.fn("mcp.requireWatchCapability")(function* (watchedThreadId) {
|
|
36349
|
+
const invocation = yield* McpInvocationContext;
|
|
36350
|
+
if (!invocation.capabilities.has("watch")) return yield* new WatchToolUnavailableError({
|
|
36351
|
+
capability: "watch",
|
|
36352
|
+
environmentId: invocation.environmentId,
|
|
36353
|
+
threadId: invocation.threadId,
|
|
36354
|
+
providerSessionId: invocation.providerSessionId,
|
|
36355
|
+
providerInstanceId: invocation.providerInstanceId
|
|
36356
|
+
});
|
|
36357
|
+
if (!invocation.watchThreadIds?.has(watchedThreadId)) return yield* new ThreadWatchNotPermittedError({ threadId: watchedThreadId });
|
|
36358
|
+
return invocation;
|
|
36359
|
+
});
|
|
36231
36360
|
/** Third of the trio, for the same reason the second exists. */
|
|
36232
36361
|
const requireThreadCapability = Effect.fn("mcp.requireThreadCapability")(function* () {
|
|
36233
36362
|
const invocation = yield* McpInvocationContext;
|
|
@@ -43885,8 +44014,8 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker) => WsRpcGroup.t
|
|
|
43885
44014
|
mode: "auto",
|
|
43886
44015
|
task: {
|
|
43887
44016
|
taskId,
|
|
43888
|
-
|
|
43889
|
-
|
|
44017
|
+
readableId: task.readableId,
|
|
44018
|
+
title: task.title
|
|
43890
44019
|
}
|
|
43891
44020
|
}),
|
|
43892
44021
|
attachments: []
|
|
@@ -43895,14 +44024,14 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker) => WsRpcGroup.t
|
|
|
43895
44024
|
titleSeed: threadTitle,
|
|
43896
44025
|
runtimeMode: DEFAULT_RUNTIME_MODE$2,
|
|
43897
44026
|
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
|
|
43898
|
-
compressMode:
|
|
44027
|
+
compressMode: DEFAULT_COMPRESS_MODE,
|
|
43899
44028
|
bootstrap: { createThread: {
|
|
43900
44029
|
projectId: plan.projectId,
|
|
43901
44030
|
title: threadTitle,
|
|
43902
44031
|
modelSelection,
|
|
43903
44032
|
runtimeMode: DEFAULT_RUNTIME_MODE$2,
|
|
43904
44033
|
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
|
|
43905
|
-
compressMode:
|
|
44034
|
+
compressMode: DEFAULT_COMPRESS_MODE,
|
|
43906
44035
|
branch: null,
|
|
43907
44036
|
worktreePath: null,
|
|
43908
44037
|
createdAt
|
|
@@ -45186,16 +45315,20 @@ const makeWithOptions = Effect.fn("McpSessionRegistry.make")(function* (options
|
|
|
45186
45315
|
const providerSessionId = yield* crypto.randomUUIDv4.pipe(Effect.orDie);
|
|
45187
45316
|
const rawToken = yield* crypto.randomBytes(32).pipe(Effect.map(tokenFromBytes), Effect.orDie);
|
|
45188
45317
|
const tokenHash = yield* hashToken(rawToken);
|
|
45318
|
+
const watchThreadIds = new Set((request.watchThreadIds ?? []).map((threadId) => ThreadId.make(threadId)));
|
|
45319
|
+
const capabilities = /* @__PURE__ */ new Set([
|
|
45320
|
+
"preview",
|
|
45321
|
+
"tasks",
|
|
45322
|
+
"threads"
|
|
45323
|
+
]);
|
|
45324
|
+
if (watchThreadIds.size > 0) capabilities.add("watch");
|
|
45189
45325
|
const scope = {
|
|
45190
45326
|
environmentId,
|
|
45191
45327
|
threadId: ThreadId.make(request.threadId),
|
|
45192
45328
|
providerSessionId,
|
|
45193
45329
|
providerInstanceId: ProviderInstanceId.make(request.providerInstanceId),
|
|
45194
|
-
capabilities
|
|
45195
|
-
|
|
45196
|
-
"tasks",
|
|
45197
|
-
"threads"
|
|
45198
|
-
]),
|
|
45330
|
+
capabilities,
|
|
45331
|
+
...watchThreadIds.size > 0 ? { watchThreadIds } : {},
|
|
45199
45332
|
issuedAt
|
|
45200
45333
|
};
|
|
45201
45334
|
yield* SynchronizedRef.update(state, ({ records }) => {
|
|
@@ -82309,7 +82442,7 @@ const invokeTargeted = (operation, input, timeoutMs) => {
|
|
|
82309
82442
|
const { tabId, ...operationInput } = input;
|
|
82310
82443
|
return invoke(operation, operationInput, timeoutMs, tabId);
|
|
82311
82444
|
};
|
|
82312
|
-
const handlers$
|
|
82445
|
+
const handlers$3 = {
|
|
82313
82446
|
preview_status: (input) => invokeTargeted("status", input ?? {}),
|
|
82314
82447
|
preview_open: (input) => invokeTargeted("open", normalizePreviewOpenInput(input)),
|
|
82315
82448
|
preview_navigate: (input) => invokeTargeted("navigate", input, input.timeoutMs),
|
|
@@ -82325,10 +82458,10 @@ const handlers$2 = {
|
|
|
82325
82458
|
preview_recording_start: (input) => invokeTargeted("recordingStart", input ?? {}),
|
|
82326
82459
|
preview_recording_stop: (input) => invokeTargeted("recordingStop", input ?? {})
|
|
82327
82460
|
};
|
|
82328
|
-
const { preview_snapshot, ...standardHandlers } = handlers$
|
|
82461
|
+
const { preview_snapshot, ...standardHandlers } = handlers$3;
|
|
82329
82462
|
const PreviewStandardToolkitHandlersLive = PreviewStandardToolkit.toLayer(standardHandlers);
|
|
82330
82463
|
const PreviewSnapshotToolkitHandlersLive = PreviewSnapshotToolkit.toLayer({ preview_snapshot });
|
|
82331
|
-
PreviewToolkit.toLayer(handlers$
|
|
82464
|
+
PreviewToolkit.toLayer(handlers$3);
|
|
82332
82465
|
//#endregion
|
|
82333
82466
|
//#region src/mcp/toolkits/tasks/tools.ts
|
|
82334
82467
|
const dependencies = [McpInvocationContext, TaskRepository];
|
|
@@ -82561,6 +82694,41 @@ const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
|
|
|
82561
82694
|
})
|
|
82562
82695
|
});
|
|
82563
82696
|
//#endregion
|
|
82697
|
+
//#region src/mcp/toolkits/watch/tools.ts
|
|
82698
|
+
/**
|
|
82699
|
+
* Cross-thread by design, which is exactly why it is the most guarded tool in
|
|
82700
|
+
* the registry: the handler admits only threads in the session's explicit
|
|
82701
|
+
* `watchThreadIds` grant, never the token's whole reach. The read is a cursor
|
|
82702
|
+
* poll because MCP tools are request/response; a watcher advances
|
|
82703
|
+
* `afterSequence` with each page and knows it is caught up when `hasMore` is
|
|
82704
|
+
* false and the last sequence equals `headSequence`.
|
|
82705
|
+
*/
|
|
82706
|
+
const ThreadWatchEventsTool = Tool.make("thread_watch_events", {
|
|
82707
|
+
description: "Read a watched thread's orchestration events after a sequence cursor. Returns an ordered page plus the head sequence; pass the last event's sequence back as afterSequence to poll forward. Only threads this session was explicitly granted are readable.",
|
|
82708
|
+
parameters: ThreadWatchEventsInput,
|
|
82709
|
+
success: ThreadWatchEventsResult,
|
|
82710
|
+
failure: ThreadWatchToolError,
|
|
82711
|
+
dependencies: [McpInvocationContext, ThreadEventStreamService]
|
|
82712
|
+
}).annotate(Tool.Title, "Read watched thread events").annotate(Tool.Readonly, true).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, true);
|
|
82713
|
+
const WatchToolkit = Toolkit.make(ThreadWatchEventsTool);
|
|
82714
|
+
const WatchToolkitHandlersLive = WatchToolkit.toLayer({ thread_watch_events: (input) => Effect.gen(function* () {
|
|
82715
|
+
yield* requireWatchCapability(input.threadId);
|
|
82716
|
+
const page = yield* (yield* ThreadEventStreamService).read({
|
|
82717
|
+
threadId: input.threadId,
|
|
82718
|
+
...input.afterSequence !== void 0 ? { afterSequence: input.afterSequence } : {},
|
|
82719
|
+
limit: input.limit ?? 50
|
|
82720
|
+
}).pipe(Effect.mapError((cause) => new ThreadWatchFailedError({
|
|
82721
|
+
threadId: input.threadId,
|
|
82722
|
+
detail: cause.message
|
|
82723
|
+
})));
|
|
82724
|
+
return {
|
|
82725
|
+
threadId: input.threadId,
|
|
82726
|
+
events: page.events,
|
|
82727
|
+
headSequence: page.headSequence,
|
|
82728
|
+
hasMore: page.hasMore
|
|
82729
|
+
};
|
|
82730
|
+
}) });
|
|
82731
|
+
//#endregion
|
|
82564
82732
|
//#region src/mcp/McpHttpServer.ts
|
|
82565
82733
|
const unauthorized = HttpServerResponse.jsonUnsafe({
|
|
82566
82734
|
error: "invalid_mcp_credential",
|
|
@@ -82665,12 +82833,13 @@ const PreviewSnapshotRegistrationLive = Layer.effectDiscard(registerPreviewSnaps
|
|
|
82665
82833
|
const PreviewToolkitRegistrationLive = Layer.mergeAll(PreviewStandardToolkitRegistrationLive, PreviewSnapshotRegistrationLive);
|
|
82666
82834
|
const TaskToolkitRegistrationLive = McpServer.toolkit(TaskToolkit).pipe(Layer.provide(TaskToolkitHandlersLive));
|
|
82667
82835
|
const ThreadToolkitRegistrationLive = McpServer.toolkit(ThreadToolkit).pipe(Layer.provide(ThreadToolkitHandlersLive));
|
|
82836
|
+
const WatchToolkitRegistrationLive = McpServer.toolkit(WatchToolkit).pipe(Layer.provide(WatchToolkitHandlersLive));
|
|
82668
82837
|
const McpTransportLive = McpServer.layerHttp({
|
|
82669
82838
|
name: "P4Code",
|
|
82670
82839
|
version,
|
|
82671
82840
|
path: "/mcp"
|
|
82672
82841
|
}).pipe(Layer.provide(McpAuthMiddlewareLive));
|
|
82673
|
-
const layer = Layer.mergeAll(PreviewToolkitRegistrationLive, TaskToolkitRegistrationLive, ThreadToolkitRegistrationLive).pipe(Layer.provideMerge(McpTransportLive));
|
|
82842
|
+
const layer = Layer.mergeAll(PreviewToolkitRegistrationLive, TaskToolkitRegistrationLive, ThreadToolkitRegistrationLive, WatchToolkitRegistrationLive).pipe(Layer.provideMerge(McpTransportLive));
|
|
82674
82843
|
//#endregion
|
|
82675
82844
|
//#region src/orchestration/Services/CheckpointReactor.ts
|
|
82676
82845
|
/**
|