@p4code/cli 0.1.21 → 0.1.22
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 +229 -37
- package/dist/client/assets/{DiffPanel-2Gqo7b0N.js → DiffPanel-Cdf69_RS.js} +2 -2
- package/dist/client/assets/{FilePreviewPanel-Po3D7bHa.js → FilePreviewPanel-CkKXCbcG.js} +2 -2
- package/dist/client/assets/{PreviewPanel-ebSBxbsf.js → PreviewPanel-BtqdQqtN.js} +2 -2
- package/dist/client/assets/{angular-html-BhHAxMde.js → angular-html-BPHFZwgm.js} +2 -2
- package/dist/client/assets/{angular-ts-CxZFyQM4.js → angular-ts-CXoIeuGh.js} +2 -2
- package/dist/client/assets/{apl-D8rOr4fH.js → apl-C6oPUNZZ.js} +2 -2
- package/dist/client/assets/arrow-right-7YX6fLbL.js +2 -0
- package/dist/client/assets/{astro-DYSYdOU9.js → astro-Bq_n5uKv.js} +2 -2
- package/dist/client/assets/{blade-DaHnYPa_.js → blade-DYe65h_C.js} +2 -2
- package/dist/client/assets/{c-oRWOBveW.js → c-BsDji_bt.js} +2 -2
- package/dist/client/assets/{cobol-Djebq6RA.js → cobol-CoC31Rpg.js} +2 -2
- package/dist/client/assets/{coffee-CKhxS88r.js → coffee-DU1_O9cH.js} +2 -2
- package/dist/client/assets/{cpp-BjVgWq1h.js → cpp-D5_eYHZr.js} +2 -2
- package/dist/client/assets/{crystal-DXzIaEKx.js → crystal-3iIyvfhL.js} +2 -2
- package/dist/client/assets/{css-7AulbBAq.js → css-B4bpFXEv.js} +2 -2
- package/dist/client/assets/{edge-B3VgcX6t.js → edge--YoYp8s_.js} +2 -2
- package/dist/client/assets/{elixir-DGUU7Wwf.js → elixir-CZ1wqlQn.js} +2 -2
- package/dist/client/assets/{elm-B9tr8qBJ.js → elm-DKdyYY92.js} +2 -2
- package/dist/client/assets/{erb-BgSl2c_f.js → erb-PeUqy_9N.js} +2 -2
- package/dist/client/assets/{fileCommentAnnotations-C06ZwrTh.js → fileCommentAnnotations-BTb-0nj3.js} +2 -2
- package/dist/client/assets/{git-rebase-CJMhrhmS.js → git-rebase-1Z5OxWid.js} +2 -2
- package/dist/client/assets/{glimmer-js-Dzf5VMSx.js → glimmer-js-Br0y4u5b.js} +2 -2
- package/dist/client/assets/{glimmer-ts-CHD8gl5-.js → glimmer-ts-Oh0AMNJv.js} +2 -2
- package/dist/client/assets/{glsl-CDpKClnF.js → glsl-DI6kM2gF.js} +2 -2
- package/dist/client/assets/{graphql-DX6Ul3G5.js → graphql-VCSJCQkl.js} +2 -2
- package/dist/client/assets/{hack-NU-7p0gC.js → hack-4xJQMtbZ.js} +2 -2
- package/dist/client/assets/{haml-Cf7Y-ZgP.js → haml-Bc0kPVkr.js} +2 -2
- package/dist/client/assets/{handlebars-BOvzNDfr.js → handlebars-Znb8TzWA.js} +2 -2
- package/dist/client/assets/{html-CokKN6Uo.js → html-_Zw71zQT.js} +2 -2
- package/dist/client/assets/{html-derivative-CcTOncd6.js → html-derivative-D6Fn1mLE.js} +2 -2
- package/dist/client/assets/{http-CGr88I6S.js → http-CSdnm1Wh.js} +2 -2
- package/dist/client/assets/{hurl-BfdIF20D.js → hurl-DKOuNoWT.js} +2 -2
- package/dist/client/assets/{index-BwGqPoA8.js → index-CeztlSXj.js} +13 -7
- package/dist/client/assets/{java-DjcrYPKU.js → java-Czo4Dn1f.js} +2 -2
- package/dist/client/assets/{javascript-C1msiELJ.js → javascript-fyReKHSS.js} +2 -2
- package/dist/client/assets/{jinja-BP-z74Sl.js → jinja-CvJhR5Z5.js} +2 -2
- package/dist/client/assets/{jison-DTU_ib6_.js → jison-DSlj1sEU.js} +2 -2
- package/dist/client/assets/{json-n2oR8huX.js → json-fCB7n2pX.js} +2 -2
- package/dist/client/assets/{jsx-DLc8ZGPF.js → jsx-C1OJlXdb.js} +2 -2
- package/dist/client/assets/{julia-BFtTfktg.js → julia-CmLSMgqX.js} +2 -2
- package/dist/client/assets/{just-CBZfmiGm.js → just-D9KdTXpD.js} +2 -2
- package/dist/client/assets/{latex-B9jcgQKp.js → latex-BZoE-Z3X.js} +2 -2
- package/dist/client/assets/{liquid-D-PCb97a.js → liquid-DW5UrT3Q.js} +2 -2
- package/dist/client/assets/{lua-CeAbwjz7.js → lua-DMAjig-8.js} +2 -2
- package/dist/client/assets/{marko-D2oCpzm8.js → marko-EN2dMS-t.js} +2 -2
- package/dist/client/assets/{mdc-BN4ff7dr.js → mdc-DV5R0Zdp.js} +2 -2
- package/dist/client/assets/{nginx-TigpgX3q.js → nginx-BhF2pPjp.js} +2 -2
- package/dist/client/assets/{nim-BbkIxZP5.js → nim-Ck0oR8VY.js} +2 -2
- package/dist/client/assets/{perl-Dq3UNlmA.js → perl-B4V1RSOt.js} +2 -2
- package/dist/client/assets/{php-CDBbIDUr.js → php-BvwSzqRH.js} +2 -2
- package/dist/client/assets/{pug-X1om8_0C.js → pug-DB3guzOM.js} +2 -2
- package/dist/client/assets/{qml-C_aweCjl.js → qml-CohVRZGq.js} +2 -2
- package/dist/client/assets/{r-BH02pZo7.js → r-Doi-hRR2.js} +2 -2
- package/dist/client/assets/{razor-DFd9duVt.js → razor-CtBV-RZa.js} +2 -2
- package/dist/client/assets/{regexp-BYgWQcZZ.js → regexp-DgF6jh6T.js} +2 -2
- package/dist/client/assets/{rst-DS4ajG1_.js → rst-1GlNPFb8.js} +2 -2
- package/dist/client/assets/{ruby-rrP3E-yX.js → ruby-C_Jg-W0j.js} +2 -2
- package/dist/client/assets/{sas-qOp3AbMp.js → sas-IRPqQRQC.js} +2 -2
- package/dist/client/assets/{scss-BePdknOf.js → scss-BPKDbfld.js} +2 -2
- package/dist/client/assets/{shellscript-Di7DOIUv.js → shellscript-D5KbVhsx.js} +2 -2
- package/dist/client/assets/{shellsession-DS-qEJoT.js → shellsession-bEniUyPe.js} +2 -2
- package/dist/client/assets/{soy-CT_pCK5o.js → soy-D0Pcy9LW.js} +2 -2
- package/dist/client/assets/{sql-CVynNG6j.js → sql-DF2TL966.js} +2 -2
- package/dist/client/assets/{stata-B2fKxQHN.js → stata-BLI2BTCU.js} +2 -2
- package/dist/client/assets/{surrealql-BOcosx9e.js → surrealql-BjtO5tmi.js} +2 -2
- package/dist/client/assets/{svelte-BQBQ3ysY.js → svelte-IyvKNOcX.js} +2 -2
- package/dist/client/assets/{templ-cinsfbYE.js → templ-qRJlnfHP.js} +2 -2
- package/dist/client/assets/{tex-PiJ0CI8J.js → tex-CgYv5ALc.js} +2 -2
- package/dist/client/assets/{textarea-DV6gvhvo.js → textarea-B03Qe3NX.js} +2 -2
- package/dist/client/assets/{ts-tags-jRjqE2jk.js → ts-tags-YasuuPCT.js} +2 -2
- package/dist/client/assets/{tsx-DqzTbomV.js → tsx-BF7eypTR.js} +2 -2
- package/dist/client/assets/{twig-5U1Vd9zl.js → twig-BF-FIMTp.js} +2 -2
- package/dist/client/assets/{typescript-DmYNCX8k.js → typescript-CtOBCMI7.js} +2 -2
- package/dist/client/assets/{vue-BOE7yHne.js → vue-BTbCYZab.js} +2 -2
- package/dist/client/assets/{vue-html-roHe5KnN.js → vue-html-1KQNz6IV.js} +2 -2
- package/dist/client/assets/{vue-vine-YC-R0SEx.js → vue-vine-BVHOJ5oI.js} +2 -2
- package/dist/client/assets/{xml-B-QQaugn.js → xml-CftlzqvG.js} +2 -2
- package/dist/client/assets/{xsl-CyPKxPW7.js → xsl-DoQ9dHRM.js} +2 -2
- package/dist/client/assets/{yaml-Bq2pe1E4.js → yaml-DMUX1MAF.js} +2 -2
- package/dist/client/index.html +2 -2
- package/package.json +1 -1
- package/dist/client/assets/arrow-right-Dseaz2v4.js +0 -2
package/dist/bin.mjs
CHANGED
|
@@ -233,7 +233,7 @@ const make$76 = () => {
|
|
|
233
233
|
const layer$72 = Layer.sync(NetService, make$76);
|
|
234
234
|
//#endregion
|
|
235
235
|
//#region package.json
|
|
236
|
-
var version = "0.1.
|
|
236
|
+
var version = "0.1.22";
|
|
237
237
|
//#endregion
|
|
238
238
|
//#region src/config.ts
|
|
239
239
|
/**
|
|
@@ -7858,11 +7858,21 @@ var ProjectWriteFileError = class extends Schema$1.TaggedErrorClass()("ProjectWr
|
|
|
7858
7858
|
* is a URL as often as an id, and which tracker a bare `MOBILE-12262` belongs
|
|
7859
7859
|
* to is a question only the resolver can answer.
|
|
7860
7860
|
*/
|
|
7861
|
-
const TicketResolveInput = Schema$1.Struct({ reference: TrimmedNonEmptyString });
|
|
7861
|
+
const TicketResolveInput = Schema$1.Struct({ reference: TrimmedNonEmptyString.pipe(Schema$1.annotateEncoded({ description: "The ticket as it was written: an identifier like MOBILE-12241, or a tracker URL. Pass it through verbatim rather than reformatting it." })) });
|
|
7862
7862
|
const TicketResolveResult = Schema$1.Struct({
|
|
7863
7863
|
externalRef: TaskExternalRef,
|
|
7864
7864
|
/** The issue title as the tracker reports it, for the task that mirrors it. */
|
|
7865
|
-
title: TrimmedNonEmptyString
|
|
7865
|
+
title: TrimmedNonEmptyString,
|
|
7866
|
+
/**
|
|
7867
|
+
* The issue body, when the tracker reports one.
|
|
7868
|
+
*
|
|
7869
|
+
* Optional because it is the one field here that has a legitimate empty
|
|
7870
|
+
* value - plenty of tickets are a title and nothing else - and because the
|
|
7871
|
+
* composer, which only ever renders a chip, does not read it. It is carried
|
|
7872
|
+
* for the caller that does: an agent handed a ticket id needs the
|
|
7873
|
+
* requirements, and the title alone sends it back to ask for them.
|
|
7874
|
+
*/
|
|
7875
|
+
description: Schema$1.optional(TrimmedNonEmptyString)
|
|
7866
7876
|
});
|
|
7867
7877
|
/**
|
|
7868
7878
|
* Why a reference could not be turned into a ticket.
|
|
@@ -34864,6 +34874,7 @@ const TASK_PLAN_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
34864
34874
|
"task_get",
|
|
34865
34875
|
"task_current",
|
|
34866
34876
|
"task_propose",
|
|
34877
|
+
"ticket_resolve",
|
|
34867
34878
|
"taskcreate",
|
|
34868
34879
|
"taskupdate",
|
|
34869
34880
|
"tasklist",
|
|
@@ -36571,13 +36582,16 @@ const make$36 = Effect.gen(function* () {
|
|
|
36571
36582
|
reason: "not_found",
|
|
36572
36583
|
detail: `Linear returned nothing usable for ${identifier}.`
|
|
36573
36584
|
});
|
|
36585
|
+
const externalRef = {
|
|
36586
|
+
source: "linear",
|
|
36587
|
+
identifier: stringField$1(issue, "identifier") ?? identifier,
|
|
36588
|
+
url
|
|
36589
|
+
};
|
|
36590
|
+
const description = stringField$1(issue, "description");
|
|
36574
36591
|
return {
|
|
36575
|
-
externalRef
|
|
36576
|
-
|
|
36577
|
-
|
|
36578
|
-
url
|
|
36579
|
-
},
|
|
36580
|
-
title
|
|
36592
|
+
externalRef,
|
|
36593
|
+
title,
|
|
36594
|
+
...description === void 0 ? {} : { description }
|
|
36581
36595
|
};
|
|
36582
36596
|
}) };
|
|
36583
36597
|
});
|
|
@@ -47727,6 +47741,18 @@ const ProviderEventLoggersLive = Layer.effect(ProviderEventLoggers, Effect.gen(f
|
|
|
47727
47741
|
var ProviderService = class extends Context.Service()("@p4code/cli/provider/Services/ProviderService") {};
|
|
47728
47742
|
//#endregion
|
|
47729
47743
|
//#region src/mcp/McpProviderSession.ts
|
|
47744
|
+
/**
|
|
47745
|
+
* The name p4code declares its own toolkit under, in every provider.
|
|
47746
|
+
*
|
|
47747
|
+
* One constant because it is one name in the agent's world: prompts, skills and
|
|
47748
|
+
* the tool categories all say `p4-code`, whichever runtime is reading them.
|
|
47749
|
+
* Every adapter also excludes it from the user's registered servers, so a
|
|
47750
|
+
* registration of the same name cannot displace the built-in one and take the
|
|
47751
|
+
* per-thread credential's tools (`task_current`, `thread_*`) with it.
|
|
47752
|
+
*/
|
|
47753
|
+
const P4CODE_MCP_SERVER_NAME = "p4-code";
|
|
47754
|
+
/** The reserved names, as the set the mappers take. */
|
|
47755
|
+
const P4CODE_MCP_SERVER_NAMES = /* @__PURE__ */ new Set([P4CODE_MCP_SERVER_NAME]);
|
|
47730
47756
|
const sessionsByThread = /* @__PURE__ */ new Map();
|
|
47731
47757
|
function setMcpProviderSession(config) {
|
|
47732
47758
|
sessionsByThread.set(config.threadId, config);
|
|
@@ -71563,6 +71589,81 @@ const SERVER_NOTIFICATION_PARAMS = {
|
|
|
71563
71589
|
"account/login/completed": V2AccountLoginCompletedNotification
|
|
71564
71590
|
};
|
|
71565
71591
|
//#endregion
|
|
71592
|
+
//#region src/provider/Layers/codexMcpArgs.ts
|
|
71593
|
+
/** Codex's own name for the token variable of p4code's built-in server. */
|
|
71594
|
+
const CODEX_P4CODE_BEARER_TOKEN_ENV_VAR = "P4_MCP_BEARER_TOKEN";
|
|
71595
|
+
/** Prefix for the per-server variables the registered servers get. */
|
|
71596
|
+
const BEARER_TOKEN_ENV_VAR_PREFIX = "P4_MCP_BEARER_TOKEN_";
|
|
71597
|
+
/** TOML bare keys; anything else has to be quoted inside the dotted path. */
|
|
71598
|
+
const BARE_KEY = /^[A-Za-z0-9_-]+$/;
|
|
71599
|
+
const AUTHORIZATION_HEADER = "authorization";
|
|
71600
|
+
const BEARER_PREFIX = /^Bearer\s+/;
|
|
71601
|
+
const configKey = (name, field) => `mcp_servers.${BARE_KEY.test(name) ? name : JSON.stringify(name)}.${field}`;
|
|
71602
|
+
/**
|
|
71603
|
+
* A variable name derived from the server's, uniquely.
|
|
71604
|
+
*
|
|
71605
|
+
* Uppercased with every character a shell would not accept replaced, which can
|
|
71606
|
+
* collide (`a.b` and `a-b`), so the sanitized name is the prefix and the index
|
|
71607
|
+
* keeps it unique. The index is stable within one call, which is all that is
|
|
71608
|
+
* needed: the variable and the reference to it are emitted together.
|
|
71609
|
+
*/
|
|
71610
|
+
const bearerTokenEnvVar = (name, index) => `${BEARER_TOKEN_ENV_VAR_PREFIX}${name.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_${index}`;
|
|
71611
|
+
/**
|
|
71612
|
+
* @param resolved - Servers keyed by name, as the registry resolved them.
|
|
71613
|
+
* @param exclude - Names p4code declares itself. A registration cannot displace
|
|
71614
|
+
* the built-in `p4-code` server, whose per-thread credential is the only
|
|
71615
|
+
* thing that makes `task_current` and the thread tools work.
|
|
71616
|
+
*/
|
|
71617
|
+
const toCodexMcpConfig = (resolved, exclude = /* @__PURE__ */ new Set()) => {
|
|
71618
|
+
const args = [];
|
|
71619
|
+
const env = {};
|
|
71620
|
+
const skipped = [];
|
|
71621
|
+
const push = (name, field, value) => {
|
|
71622
|
+
args.push("-c", `${configKey(name, field)}=${value}`);
|
|
71623
|
+
};
|
|
71624
|
+
let index = 0;
|
|
71625
|
+
for (const [name, server] of Object.entries(resolved)) {
|
|
71626
|
+
if (exclude.has(name)) continue;
|
|
71627
|
+
if (server.type === "stdio") {
|
|
71628
|
+
push(name, "command", JSON.stringify(server.command));
|
|
71629
|
+
push(name, "args", JSON.stringify(server.args));
|
|
71630
|
+
if (Object.keys(server.env).length > 0) push(name, "env", `{ ${Object.entries(server.env).map(([key, value]) => `${JSON.stringify(key)} = ${JSON.stringify(value)}`).join(", ")} }`);
|
|
71631
|
+
index += 1;
|
|
71632
|
+
continue;
|
|
71633
|
+
}
|
|
71634
|
+
if (server.type === "sse") {
|
|
71635
|
+
skipped.push({
|
|
71636
|
+
name,
|
|
71637
|
+
reason: "Codex speaks streamable HTTP, not SSE."
|
|
71638
|
+
});
|
|
71639
|
+
continue;
|
|
71640
|
+
}
|
|
71641
|
+
const headerNames = Object.keys(server.headers);
|
|
71642
|
+
const authorization = headerNames.find((key) => key.toLowerCase() === AUTHORIZATION_HEADER);
|
|
71643
|
+
const otherHeaders = headerNames.filter((key) => key !== authorization);
|
|
71644
|
+
if (otherHeaders.length > 0) {
|
|
71645
|
+
skipped.push({
|
|
71646
|
+
name,
|
|
71647
|
+
reason: `Codex sends no custom headers, and this server needs ${otherHeaders.join(", ")}.`
|
|
71648
|
+
});
|
|
71649
|
+
continue;
|
|
71650
|
+
}
|
|
71651
|
+
push(name, "url", JSON.stringify(server.url));
|
|
71652
|
+
if (authorization !== void 0) {
|
|
71653
|
+
const token = server.headers[authorization]?.replace(BEARER_PREFIX, "") ?? "";
|
|
71654
|
+
const variable = bearerTokenEnvVar(name, index);
|
|
71655
|
+
env[variable] = token;
|
|
71656
|
+
push(name, "bearer_token_env_var", JSON.stringify(variable));
|
|
71657
|
+
}
|
|
71658
|
+
index += 1;
|
|
71659
|
+
}
|
|
71660
|
+
return {
|
|
71661
|
+
args,
|
|
71662
|
+
env,
|
|
71663
|
+
skipped
|
|
71664
|
+
};
|
|
71665
|
+
};
|
|
71666
|
+
//#endregion
|
|
71566
71667
|
//#region ../../packages/effect-codex-app-server/src/_internal/shared.ts
|
|
71567
71668
|
const JsonRpcId$1 = Schema$1.Union([Schema$1.Number, Schema$1.String]);
|
|
71568
71669
|
const JsonRpcError = Schema$1.Struct({
|
|
@@ -73959,6 +74060,11 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
73959
74060
|
if (existing && !existing.stopped) yield* Effect.suspend(() => stopSessionInternal(existing));
|
|
73960
74061
|
const serviceTier = input.modelSelection?.instanceId === boundInstanceId ? getCodexServiceTierOptionValue(input.modelSelection) : void 0;
|
|
73961
74062
|
const mcpSession = readMcpProviderSession(input.threadId);
|
|
74063
|
+
const externalMcp = toCodexMcpConfig(options?.resolveMcpServers === void 0 ? {} : yield* options.resolveMcpServers, P4CODE_MCP_SERVER_NAMES);
|
|
74064
|
+
for (const dropped of externalMcp.skipped) yield* Effect.logWarning("codex cannot express an mcp registration", {
|
|
74065
|
+
server: dropped.name,
|
|
74066
|
+
reason: dropped.reason
|
|
74067
|
+
});
|
|
73962
74068
|
const runtimeInput = {
|
|
73963
74069
|
threadId: input.threadId,
|
|
73964
74070
|
providerInstanceId: boundInstanceId,
|
|
@@ -73971,17 +74077,18 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
73971
74077
|
runtimeMode: input.runtimeMode,
|
|
73972
74078
|
...input.modelSelection?.instanceId === boundInstanceId ? { model: input.modelSelection.model } : {},
|
|
73973
74079
|
...serviceTier ? { serviceTier } : {},
|
|
73974
|
-
...mcpSession ? {
|
|
74080
|
+
...externalMcp.args.length > 0 || mcpSession ? {
|
|
73975
74081
|
environment: {
|
|
73976
74082
|
...options?.environment ?? process.env,
|
|
73977
|
-
|
|
74083
|
+
...externalMcp.env,
|
|
74084
|
+
...mcpSession ? { [CODEX_P4CODE_BEARER_TOKEN_ENV_VAR]: mcpSession.authorizationHeader.replace(/^Bearer\s+/, "") } : {}
|
|
73978
74085
|
},
|
|
73979
|
-
appServerArgs: [
|
|
74086
|
+
appServerArgs: [...externalMcp.args, ...mcpSession ? [
|
|
73980
74087
|
"-c",
|
|
73981
|
-
`mcp_servers.
|
|
74088
|
+
`mcp_servers.${P4CODE_MCP_SERVER_NAME}.url=${mcpSession.endpoint}`,
|
|
73982
74089
|
"-c",
|
|
73983
|
-
|
|
73984
|
-
]
|
|
74090
|
+
`mcp_servers.${P4CODE_MCP_SERVER_NAME}.bearer_token_env_var="${CODEX_P4CODE_BEARER_TOKEN_ENV_VAR}"`
|
|
74091
|
+
] : []]
|
|
73985
74092
|
} : {}
|
|
73986
74093
|
};
|
|
73987
74094
|
const sessionScope = yield* Scope.make("sequential");
|
|
@@ -74484,6 +74591,7 @@ const CodexDriver = {
|
|
|
74484
74591
|
const adapter = yield* makeCodexAdapter(effectiveConfig, {
|
|
74485
74592
|
instanceId,
|
|
74486
74593
|
environment: processEnv,
|
|
74594
|
+
resolveMcpServers: (yield* McpRegistry).resolveForSession,
|
|
74487
74595
|
...eventLoggers.native ? { nativeEventLogger: eventLoggers.native } : {}
|
|
74488
74596
|
});
|
|
74489
74597
|
const textGeneration = yield* makeCodexTextGeneration(effectiveConfig, processEnv);
|
|
@@ -80076,6 +80184,31 @@ const makeCursorTextGeneration = Effect.fn("makeCursorTextGeneration")(function*
|
|
|
80076
80184
|
};
|
|
80077
80185
|
});
|
|
80078
80186
|
//#endregion
|
|
80187
|
+
//#region src/provider/acp/acpMcpServers.ts
|
|
80188
|
+
const namedPairs = (values) => Object.entries(values).map(([name, value]) => ({
|
|
80189
|
+
name,
|
|
80190
|
+
value
|
|
80191
|
+
}));
|
|
80192
|
+
/**
|
|
80193
|
+
* @param resolved - Servers keyed by name, as the registry resolved them.
|
|
80194
|
+
* @param exclude - Names p4code declares itself, which win over a registration
|
|
80195
|
+
* of the same name. The built-in `p4-code` server carries a per-thread
|
|
80196
|
+
* credential no registration can reproduce, so a same-named registration must
|
|
80197
|
+
* not be able to displace it — it would take `task_current` with it, and the
|
|
80198
|
+
* failure would look like the agent forgetting which task it is on.
|
|
80199
|
+
*/
|
|
80200
|
+
const toAcpMcpServers = (resolved, exclude = /* @__PURE__ */ new Set()) => Object.entries(resolved).filter(([name]) => !exclude.has(name)).map(([name, server]) => server.type === "stdio" ? {
|
|
80201
|
+
name,
|
|
80202
|
+
command: server.command,
|
|
80203
|
+
args: [...server.args],
|
|
80204
|
+
env: namedPairs(server.env)
|
|
80205
|
+
} : {
|
|
80206
|
+
type: server.type,
|
|
80207
|
+
name,
|
|
80208
|
+
url: server.url,
|
|
80209
|
+
headers: namedPairs(server.headers)
|
|
80210
|
+
});
|
|
80211
|
+
//#endregion
|
|
80079
80212
|
//#region src/provider/acp/AcpAdapterSupport.ts
|
|
80080
80213
|
const isAcpProcessExitedError = Schema$1.is(AcpProcessExitedError);
|
|
80081
80214
|
const isAcpRequestError = Schema$1.is(AcpRequestError);
|
|
@@ -80560,6 +80693,15 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
80560
80693
|
});
|
|
80561
80694
|
const effectiveCursorSettings = options?.resolveSettings ? yield* options.resolveSettings : cursorSettings;
|
|
80562
80695
|
const mcpSession = readMcpProviderSession(input.threadId);
|
|
80696
|
+
const mcpServers = [...toAcpMcpServers(options?.resolveMcpServers === void 0 ? {} : yield* options.resolveMcpServers, P4CODE_MCP_SERVER_NAMES), ...mcpSession ? [{
|
|
80697
|
+
type: "http",
|
|
80698
|
+
name: P4CODE_MCP_SERVER_NAME,
|
|
80699
|
+
url: mcpSession.endpoint,
|
|
80700
|
+
headers: [{
|
|
80701
|
+
name: "Authorization",
|
|
80702
|
+
value: mcpSession.authorizationHeader
|
|
80703
|
+
}]
|
|
80704
|
+
}] : []];
|
|
80563
80705
|
const acp = yield* makeCursorAcpRuntime({
|
|
80564
80706
|
cursorSettings: effectiveCursorSettings,
|
|
80565
80707
|
...options?.environment ? { environment: options.environment } : {},
|
|
@@ -80567,18 +80709,10 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
80567
80709
|
cwd,
|
|
80568
80710
|
...resumeSessionId ? { resumeSessionId } : {},
|
|
80569
80711
|
clientInfo: {
|
|
80570
|
-
name:
|
|
80712
|
+
name: P4CODE_MCP_SERVER_NAME,
|
|
80571
80713
|
version: "0.0.0"
|
|
80572
80714
|
},
|
|
80573
|
-
...
|
|
80574
|
-
type: "http",
|
|
80575
|
-
name: "p4-code",
|
|
80576
|
-
url: mcpSession.endpoint,
|
|
80577
|
-
headers: [{
|
|
80578
|
-
name: "Authorization",
|
|
80579
|
-
value: mcpSession.authorizationHeader
|
|
80580
|
-
}]
|
|
80581
|
-
}] } : {},
|
|
80715
|
+
...mcpServers.length > 0 ? { mcpServers } : {},
|
|
80582
80716
|
...acpNativeLoggers
|
|
80583
80717
|
}).pipe(Effect.provideService(Crypto.Crypto, crypto), Effect.provideService(Scope.Scope, sessionScope), Effect.mapError((cause) => new ProviderAdapterProcessError({
|
|
80584
80718
|
provider: PROVIDER$3,
|
|
@@ -81059,6 +81193,7 @@ const CursorDriver = {
|
|
|
81059
81193
|
});
|
|
81060
81194
|
const adapter = yield* makeCursorAdapter(effectiveConfig, {
|
|
81061
81195
|
environment: processEnv,
|
|
81196
|
+
resolveMcpServers: (yield* McpRegistry).resolveForSession,
|
|
81062
81197
|
...eventLoggers.native ? { nativeEventLogger: eventLoggers.native } : {},
|
|
81063
81198
|
instanceId
|
|
81064
81199
|
});
|
|
@@ -81781,6 +81916,15 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
81781
81916
|
threadId: input.threadId
|
|
81782
81917
|
});
|
|
81783
81918
|
const mcpSession = readMcpProviderSession(input.threadId);
|
|
81919
|
+
const mcpServers = [...toAcpMcpServers(options?.resolveMcpServers === void 0 ? {} : yield* options.resolveMcpServers, P4CODE_MCP_SERVER_NAMES), ...mcpSession ? [{
|
|
81920
|
+
type: "http",
|
|
81921
|
+
name: P4CODE_MCP_SERVER_NAME,
|
|
81922
|
+
url: mcpSession.endpoint,
|
|
81923
|
+
headers: [{
|
|
81924
|
+
name: "Authorization",
|
|
81925
|
+
value: mcpSession.authorizationHeader
|
|
81926
|
+
}]
|
|
81927
|
+
}] : []];
|
|
81784
81928
|
const acp = yield* makeGrokAcpRuntime({
|
|
81785
81929
|
grokSettings,
|
|
81786
81930
|
...options?.environment ? { environment: options.environment } : {},
|
|
@@ -81788,18 +81932,10 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
81788
81932
|
cwd,
|
|
81789
81933
|
...resumeSessionId ? { resumeSessionId } : {},
|
|
81790
81934
|
clientInfo: {
|
|
81791
|
-
name:
|
|
81935
|
+
name: P4CODE_MCP_SERVER_NAME,
|
|
81792
81936
|
version: "0.0.0"
|
|
81793
81937
|
},
|
|
81794
|
-
...
|
|
81795
|
-
type: "http",
|
|
81796
|
-
name: "p4-code",
|
|
81797
|
-
url: mcpSession.endpoint,
|
|
81798
|
-
headers: [{
|
|
81799
|
-
name: "Authorization",
|
|
81800
|
-
value: mcpSession.authorizationHeader
|
|
81801
|
-
}]
|
|
81802
|
-
}] } : {},
|
|
81938
|
+
...mcpServers.length > 0 ? { mcpServers } : {},
|
|
81803
81939
|
...acpNativeLoggers
|
|
81804
81940
|
}).pipe(Effect.provideService(Crypto.Crypto, crypto), Effect.provideService(Scope.Scope, sessionScope), Effect.mapError((cause) => new ProviderAdapterProcessError({
|
|
81805
81941
|
provider: PROVIDER$2,
|
|
@@ -82615,6 +82751,7 @@ const GrokDriver = {
|
|
|
82615
82751
|
});
|
|
82616
82752
|
const adapter = yield* makeGrokAdapter(effectiveConfig, {
|
|
82617
82753
|
environment: processEnv,
|
|
82754
|
+
resolveMcpServers: (yield* McpRegistry).resolveForSession,
|
|
82618
82755
|
...eventLoggers.native ? { nativeEventLogger: eventLoggers.native } : {},
|
|
82619
82756
|
instanceId
|
|
82620
82757
|
});
|
|
@@ -84452,6 +84589,27 @@ const makeOpenCodeTextGeneration = Effect.fn("makeOpenCodeTextGeneration")(funct
|
|
|
84452
84589
|
};
|
|
84453
84590
|
});
|
|
84454
84591
|
//#endregion
|
|
84592
|
+
//#region src/provider/Layers/openCodeMcpServers.ts
|
|
84593
|
+
/**
|
|
84594
|
+
* @param resolved - Servers keyed by name, as the registry resolved them.
|
|
84595
|
+
* @param exclude - Names p4code declares itself, which a registration must not
|
|
84596
|
+
* be able to displace: the built-in `p4-code` server carries the per-thread
|
|
84597
|
+
* credential behind `task_current` and the thread tools.
|
|
84598
|
+
*/
|
|
84599
|
+
const toOpenCodeMcpServers = (resolved, exclude = /* @__PURE__ */ new Set()) => Object.entries(resolved).filter(([name]) => !exclude.has(name)).map(([name, server]) => ({
|
|
84600
|
+
name,
|
|
84601
|
+
config: server.type === "stdio" ? {
|
|
84602
|
+
type: "local",
|
|
84603
|
+
command: [server.command, ...server.args],
|
|
84604
|
+
...Object.keys(server.env).length > 0 ? { environment: server.env } : {}
|
|
84605
|
+
} : {
|
|
84606
|
+
type: "remote",
|
|
84607
|
+
url: server.url,
|
|
84608
|
+
...Object.keys(server.headers).length > 0 ? { headers: server.headers } : {},
|
|
84609
|
+
oauth: false
|
|
84610
|
+
}
|
|
84611
|
+
}));
|
|
84612
|
+
//#endregion
|
|
84455
84613
|
//#region src/provider/Layers/OpenCodeAdapter.ts
|
|
84456
84614
|
const PROVIDER = ProviderDriverKind.make("opencode");
|
|
84457
84615
|
/**
|
|
@@ -85128,8 +85286,15 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
85128
85286
|
...server.external && serverPassword ? { serverPassword } : {}
|
|
85129
85287
|
});
|
|
85130
85288
|
const mcpSession = readMcpProviderSession(input.threadId);
|
|
85289
|
+
if (!server.external) {
|
|
85290
|
+
const externalMcpServers = toOpenCodeMcpServers(options?.resolveMcpServers === void 0 ? {} : yield* options.resolveMcpServers, P4CODE_MCP_SERVER_NAMES);
|
|
85291
|
+
for (const entry of externalMcpServers) yield* runOpenCodeSdk("mcp.add", () => client.mcp.add(entry)).pipe(Effect.catchCause((cause) => Effect.logWarning("opencode rejected an mcp registration", {
|
|
85292
|
+
server: entry.name,
|
|
85293
|
+
cause
|
|
85294
|
+
})));
|
|
85295
|
+
}
|
|
85131
85296
|
if (mcpSession && !server.external) yield* runOpenCodeSdk("mcp.add", () => client.mcp.add({
|
|
85132
|
-
name:
|
|
85297
|
+
name: P4CODE_MCP_SERVER_NAME,
|
|
85133
85298
|
config: {
|
|
85134
85299
|
type: "remote",
|
|
85135
85300
|
url: mcpSession.endpoint,
|
|
@@ -85818,6 +85983,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
85818
85983
|
const adapter = yield* makeOpenCodeAdapter(effectiveConfig, {
|
|
85819
85984
|
instanceId,
|
|
85820
85985
|
environment: processEnv,
|
|
85986
|
+
resolveMcpServers: (yield* McpRegistry).resolveForSession,
|
|
85821
85987
|
...eventLoggers.native ? { nativeEventLogger: eventLoggers.native } : {}
|
|
85822
85988
|
});
|
|
85823
85989
|
const textGeneration = yield* makeOpenCodeTextGeneration(effectiveConfig, processEnv);
|
|
@@ -86490,7 +86656,29 @@ const TaskProposeTool = Tool.make("task_propose", {
|
|
|
86490
86656
|
failure: TaskToolError,
|
|
86491
86657
|
dependencies
|
|
86492
86658
|
}).annotate(Tool.Title, "Propose a task").annotate(Tool.Readonly, true).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, true);
|
|
86493
|
-
|
|
86659
|
+
/**
|
|
86660
|
+
* Reading a tracker ticket, for every provider rather than only the ones that
|
|
86661
|
+
* can talk to the tracker themselves.
|
|
86662
|
+
*
|
|
86663
|
+
* p4code resolves this server-side through the Linear server the user
|
|
86664
|
+
* registered once in Settings, so an agent gets the ticket whether or not its
|
|
86665
|
+
* own runtime was handed that registration. Without it, a thread started from
|
|
86666
|
+
* "MOBILE-12241" on a provider with no tracker of its own can only ask the user
|
|
86667
|
+
* to paste the description back in - which is the question they already
|
|
86668
|
+
* answered by quoting the id.
|
|
86669
|
+
*
|
|
86670
|
+
* On the task toolkit rather than a toolkit of its own because it is board
|
|
86671
|
+
* work: a resolved ticket's next step is `task_create` with the `externalRef`
|
|
86672
|
+
* this returns, and the two share the one capability a session is granted.
|
|
86673
|
+
*/
|
|
86674
|
+
const TicketResolveTool = Tool.make("ticket_resolve", {
|
|
86675
|
+
description: "Read a tracker ticket by id or URL (e.g. MOBILE-12241, or a linear.app link), returning its identifier, canonical URL, title and description. Use this whenever the user names a ticket rather than asking them to paste it. Pass the returned externalRef straight to task_create to mirror the ticket onto the board. Fails when no tracker is registered on this machine, which is a thing only the user can fix.",
|
|
86676
|
+
parameters: TicketResolveInput,
|
|
86677
|
+
success: TicketResolveResult,
|
|
86678
|
+
failure: Schema$1.Union([TaskToolUnavailableError, TicketResolveError]),
|
|
86679
|
+
dependencies: [McpInvocationContext, TicketResolver]
|
|
86680
|
+
}).annotate(Tool.Title, "Resolve a ticket").annotate(Tool.Readonly, true).annotate(Tool.Destructive, false).annotate(Tool.Idempotent, true);
|
|
86681
|
+
const TaskToolkit = Toolkit.make(TaskListTool, TaskGetTool, TaskCurrentTool, TaskCreateTool, TaskUpdateTool, TaskProposeTool, TicketResolveTool);
|
|
86494
86682
|
//#endregion
|
|
86495
86683
|
//#region src/mcp/toolkits/tasks/handlers.ts
|
|
86496
86684
|
const nowIso$1 = Effect.map(DateTime.now, DateTime.formatIso);
|
|
@@ -86576,6 +86764,10 @@ const TaskToolkitHandlersLive = TaskToolkit.toLayer({
|
|
|
86576
86764
|
if (Option.isNone(patched)) return yield* new TaskNotFoundError({ taskId: input.taskId });
|
|
86577
86765
|
return patched.value;
|
|
86578
86766
|
}),
|
|
86767
|
+
ticket_resolve: (input) => Effect.gen(function* () {
|
|
86768
|
+
yield* requireTaskCapability();
|
|
86769
|
+
return yield* (yield* TicketResolver).resolve(input.reference);
|
|
86770
|
+
}),
|
|
86579
86771
|
task_propose: () => Effect.gen(function* () {
|
|
86580
86772
|
yield* requireTaskCapability();
|
|
86581
86773
|
return { awaitingConfirmation: true };
|