@mrrlin-dev/mcp 0.4.85 → 0.4.88
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.cjs +674 -534
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -36673,7 +36673,7 @@ var ARTIFACT_CHECKS = {
|
|
|
36673
36673
|
file_set: null,
|
|
36674
36674
|
code_change: { verifier: "build" },
|
|
36675
36675
|
structured_data: null,
|
|
36676
|
-
message:
|
|
36676
|
+
message: { verifier: "status" }
|
|
36677
36677
|
};
|
|
36678
36678
|
var ARTIFACT_DESTINATIONS = {
|
|
36679
36679
|
document: "wiki",
|
|
@@ -36681,7 +36681,7 @@ var ARTIFACT_DESTINATIONS = {
|
|
|
36681
36681
|
file_set: "artifacts",
|
|
36682
36682
|
code_change: "repo_host",
|
|
36683
36683
|
structured_data: null,
|
|
36684
|
-
message: "
|
|
36684
|
+
message: "send"
|
|
36685
36685
|
};
|
|
36686
36686
|
function resolveKindCapability(kind) {
|
|
36687
36687
|
return ARTIFACT_DESTINATIONS[kind];
|
|
@@ -36737,7 +36737,6 @@ function describeCapabilityRefusal(input) {
|
|
|
36737
36737
|
var openApiOperationIds = {
|
|
36738
36738
|
appendExecutionArtifact: "appendExecutionArtifact",
|
|
36739
36739
|
archivePlan: "archivePlan",
|
|
36740
|
-
bindProjectGithubRepo: "bindProjectGithubRepo",
|
|
36741
36740
|
createExecutionRun: "createExecutionRun",
|
|
36742
36741
|
createExecutionRunHandoff: "createExecutionRunHandoff",
|
|
36743
36742
|
createAsyncJob: "createAsyncJob",
|
|
@@ -36749,10 +36748,6 @@ var openApiOperationIds = {
|
|
|
36749
36748
|
beginAsyncJobAttempt: "beginAsyncJobAttempt",
|
|
36750
36749
|
terminalizeAsyncJob: "terminalizeAsyncJob",
|
|
36751
36750
|
requeueAsyncJob: "requeueAsyncJob",
|
|
36752
|
-
createGithubPullRequest: "createGithubPullRequest",
|
|
36753
|
-
getGithubPullRequest: "getGithubPullRequest",
|
|
36754
|
-
getGithubWorkflowRunLatest: "getGithubWorkflowRunLatest",
|
|
36755
|
-
getGithubLatestDeployment: "getGithubLatestDeployment",
|
|
36756
36751
|
createTaskDependency: "createTaskDependency",
|
|
36757
36752
|
createPlan: "createPlan",
|
|
36758
36753
|
upsertProject: "upsertProject",
|
|
@@ -36775,7 +36770,6 @@ var openApiOperationIds = {
|
|
|
36775
36770
|
getTaskDeployTarget: "getTaskDeployTarget",
|
|
36776
36771
|
getSchedulerPendingTasks: "getSchedulerPendingTasks",
|
|
36777
36772
|
wakeDirector: "wakeDirector",
|
|
36778
|
-
getGithubInstallationRepositories: "getGithubInstallationRepositories",
|
|
36779
36773
|
getProject: "getProject",
|
|
36780
36774
|
getProjectSnapshot: "getProjectSnapshot",
|
|
36781
36775
|
getTask: "getTask",
|
|
@@ -36784,11 +36778,8 @@ var openApiOperationIds = {
|
|
|
36784
36778
|
takeOverTask: "takeOverTask",
|
|
36785
36779
|
closeTaskAsWontDo: "closeTaskAsWontDo",
|
|
36786
36780
|
getWikiPage: "getWikiPage",
|
|
36787
|
-
handleGithubInstallCallback: "handleGithubInstallCallback",
|
|
36788
36781
|
listExecutionArtifacts: "listExecutionArtifacts",
|
|
36789
36782
|
listExecutionRuns: "listExecutionRuns",
|
|
36790
|
-
listGithubInstallations: "listGithubInstallations",
|
|
36791
|
-
listGithubWorkflows: "listGithubWorkflows",
|
|
36792
36783
|
listPlans: "listPlans",
|
|
36793
36784
|
listProjects: "listProjects",
|
|
36794
36785
|
listTaskDependencies: "listTaskDependencies",
|
|
@@ -36797,8 +36788,6 @@ var openApiOperationIds = {
|
|
|
36797
36788
|
listTaxonomy: "listTaxonomy",
|
|
36798
36789
|
listWikiPages: "listWikiPages",
|
|
36799
36790
|
searchWikiPages: "searchWikiPages",
|
|
36800
|
-
dispatchGithubWorkflow: "dispatchGithubWorkflow",
|
|
36801
|
-
dispatchTaskDeploy: "dispatchTaskDeploy",
|
|
36802
36791
|
createInboxItem: "createInboxItem",
|
|
36803
36792
|
listInboxItems: "listInboxItems",
|
|
36804
36793
|
decideInboxItem: "decideInboxItem",
|
|
@@ -37510,16 +37499,12 @@ var mrrlinTaskEventAutonomyLevelSchema = external_exports.enum([
|
|
|
37510
37499
|
"human_review"
|
|
37511
37500
|
]);
|
|
37512
37501
|
var mrrlinAutoDeploySchema = external_exports.enum(["off", "dev", "prod"]);
|
|
37513
|
-
var
|
|
37514
|
-
function normalizeTaskDomain(value) {
|
|
37515
|
-
if (typeof value !== "string")
|
|
37516
|
-
return "code";
|
|
37517
|
-
const v = value.trim().toLowerCase();
|
|
37518
|
-
return mrrlinTaskDomainSchema.options.includes(v) ? v : "code";
|
|
37519
|
-
}
|
|
37502
|
+
var mrrlinTaskDomainsSchema = external_exports.array(external_exports.string()).min(1);
|
|
37520
37503
|
function domainScopedReviewHash(rawHash, domain2) {
|
|
37521
|
-
const d =
|
|
37522
|
-
|
|
37504
|
+
const d = Array.isArray(domain2) ? domain2.map(String) : [String(domain2 || "code")];
|
|
37505
|
+
const normalized = d.map((v) => v.trim().toLowerCase()).filter(Boolean);
|
|
37506
|
+
normalized.sort();
|
|
37507
|
+
return normalized.length === 1 && normalized[0] === "code" ? rawHash : `${rawHash}@${normalized.join(",")}`;
|
|
37523
37508
|
}
|
|
37524
37509
|
var mrrlinDeclaredOutcomeShapeSchema = external_exports.object({
|
|
37525
37510
|
sentence: external_exports.string().trim().min(1),
|
|
@@ -37816,7 +37801,7 @@ var mrrlinTaskSchema = external_exports.object({
|
|
|
37816
37801
|
// ADR 0020. OUTPUT-optional (not defaulted-required) so hardcoded task fixtures/mocks across the
|
|
37817
37802
|
// codebase need no churn; the DB column is NOT NULL default 'code', so real rows always carry it,
|
|
37818
37803
|
// and resolveHeads() treats an absent domain as `code`. Persisted create/update use their own forms.
|
|
37819
|
-
|
|
37804
|
+
domains: mrrlinTaskDomainsSchema.optional(),
|
|
37820
37805
|
autonomyLevel: mrrlinAutonomyLevelSchema,
|
|
37821
37806
|
autonomyReason: external_exports.string().min(1).max(240),
|
|
37822
37807
|
blockedBy: external_exports.array(mrrlinTaskIdSchema),
|
|
@@ -37894,9 +37879,9 @@ var mrrlinTaskSummarySchema = mrrlinTaskSchema.omit({
|
|
|
37894
37879
|
var mrrlinPlanSchema = external_exports.object({
|
|
37895
37880
|
closedTaskCount: external_exports.number().int().nonnegative(),
|
|
37896
37881
|
// ADR 0020 Phase 2 (decision 7): plan-scoped specs resolve their consensus domain through
|
|
37897
|
-
// plan.domain → project.
|
|
37882
|
+
// plan.domain → project.defaultDomains → 'code'. Nullable (null = inherit project default);
|
|
37898
37883
|
// output-optional so existing plan fixtures need no churn.
|
|
37899
|
-
|
|
37884
|
+
domains: mrrlinTaskDomainsSchema.nullable().optional(),
|
|
37900
37885
|
dueDate: external_exports.string().date().nullable(),
|
|
37901
37886
|
goal: external_exports.string().min(1),
|
|
37902
37887
|
id: mrrlinPlanIdSchema,
|
|
@@ -37949,7 +37934,7 @@ var mrrlinCloseTaskAsWontDoRequestSchema = external_exports.object({
|
|
|
37949
37934
|
reason: external_exports.string().min(1)
|
|
37950
37935
|
});
|
|
37951
37936
|
var mrrlinGithubBindingSchema = external_exports.object({
|
|
37952
|
-
appInstallationState: external_exports.enum(["installed", "missing"]),
|
|
37937
|
+
appInstallationState: external_exports.enum(["installed", "missing"]).default("missing"),
|
|
37953
37938
|
installationId: external_exports.number().int().positive().nullable().default(null),
|
|
37954
37939
|
operator: external_exports.string().startsWith("@"),
|
|
37955
37940
|
repo: external_exports.string().regex(/^[^/]+\/[^/]+$/).nullable().default(null)
|
|
@@ -38011,7 +37996,7 @@ var mrrlinProjectSummarySchema = external_exports.object({
|
|
|
38011
37996
|
slug: mrrlinProjectSlugSchema,
|
|
38012
37997
|
// ADR 0020: default consensus domain for this project's plan/project-scoped specs. Output-optional
|
|
38013
37998
|
// (DB column is NOT NULL default 'code') so existing project fixtures/upsert callers need no churn.
|
|
38014
|
-
|
|
37999
|
+
defaultDomains: mrrlinTaskDomainsSchema.optional(),
|
|
38015
38000
|
// model-tier-planning-and-arbiter D9: per-project judge switch. NULL/true means the judge runs
|
|
38016
38001
|
// as today; false means intent-check.ts skips it entirely. Output-optional for the same reason
|
|
38017
38002
|
// defaultDomain is: existing project fixtures/upsert callers need no churn.
|
|
@@ -38065,7 +38050,7 @@ var mrrlinProjectSnapshotSchema = external_exports.object({
|
|
|
38065
38050
|
project: external_exports.object({
|
|
38066
38051
|
// ADR 0020 Phase 2: default consensus domain for plan/project-scoped specs. Output-optional
|
|
38067
38052
|
// (DB column is NOT NULL default 'code') so existing snapshot fixtures need no churn.
|
|
38068
|
-
|
|
38053
|
+
defaultDomains: mrrlinTaskDomainsSchema.optional(),
|
|
38069
38054
|
displayName: external_exports.string().min(1),
|
|
38070
38055
|
emoji: mrrlinProjectEmojiSchema,
|
|
38071
38056
|
slug: mrrlinProjectSlugSchema
|
|
@@ -38082,7 +38067,7 @@ var mrrlinTaskCreateShapeSchema = external_exports.object({
|
|
|
38082
38067
|
// the preview-only constant "dev"; the tasks column itself still defaults to 'off' at the
|
|
38083
38068
|
// SQL level for any direct-insert path that bypasses createTask entirely.
|
|
38084
38069
|
autoDeploy: mrrlinAutoDeploySchema.optional(),
|
|
38085
|
-
|
|
38070
|
+
domains: mrrlinTaskDomainsSchema.optional(),
|
|
38086
38071
|
autonomyLevel: mrrlinAutonomyLevelSchema.default("human_review"),
|
|
38087
38072
|
autonomyReason: external_exports.string().min(1).max(240).default("Needs human review before automation."),
|
|
38088
38073
|
category: taxonomyCategorySchema,
|
|
@@ -38111,11 +38096,11 @@ var mrrlinTaskCreateShapeSchema = external_exports.object({
|
|
|
38111
38096
|
// `apps/api/src/index.ts` for why the refusal cannot live in this schema.
|
|
38112
38097
|
});
|
|
38113
38098
|
function refineTaskCreateDomain(data, ctx) {
|
|
38114
|
-
if (data.
|
|
38099
|
+
if (data.domains === void 0 && data.parentTaskId == null) {
|
|
38115
38100
|
ctx.addIssue({
|
|
38116
38101
|
code: external_exports.ZodIssueCode.custom,
|
|
38117
|
-
path: ["
|
|
38118
|
-
message: "
|
|
38102
|
+
path: ["domains"],
|
|
38103
|
+
message: "domains is required unless parentTaskId is set (a follow-up inherits its parent's domains)"
|
|
38119
38104
|
});
|
|
38120
38105
|
}
|
|
38121
38106
|
}
|
|
@@ -38181,7 +38166,7 @@ var mrrlinTaskUpdateSchema = external_exports.object({
|
|
|
38181
38166
|
actor: external_exports.string().min(1).optional(),
|
|
38182
38167
|
assignee: mrrlinTaskAssigneeSchema.optional(),
|
|
38183
38168
|
autoDeploy: mrrlinAutoDeploySchema.optional(),
|
|
38184
|
-
|
|
38169
|
+
domains: mrrlinTaskDomainsSchema.optional(),
|
|
38185
38170
|
autonomyLevel: mrrlinAutonomyLevelSchema.optional(),
|
|
38186
38171
|
autonomyReason: external_exports.string().min(1).max(240).optional(),
|
|
38187
38172
|
category: taxonomyCategorySchema.optional(),
|
|
@@ -38207,7 +38192,7 @@ var mrrlinTaskUpdateSchema = external_exports.object({
|
|
|
38207
38192
|
// fingerprint moved but the topology still maps the label to the same workflow. Never sent
|
|
38208
38193
|
// by any other caller.
|
|
38209
38194
|
reverifyRequested: external_exports.boolean().optional()
|
|
38210
|
-
}).refine((value) => value.assignee !== void 0 || value.autoDeploy !== void 0 || value.
|
|
38195
|
+
}).refine((value) => value.assignee !== void 0 || value.autoDeploy !== void 0 || value.domains !== void 0 || value.autonomyLevel !== void 0 || value.autonomyReason !== void 0 || value.category !== void 0 || value.directorThreadId !== void 0 || value.directorThreadProvider !== void 0 || value.dueDate !== void 0 || value.followUpAt !== void 0 || value.impact !== void 0 || value.notes !== void 0 || value.planId !== void 0 || value.specApproved !== void 0 || value.specWikiPageId !== void 0 || value.status !== void 0 || value.subcategory !== void 0 || value.tags !== void 0 || value.title !== void 0 || value.type !== void 0 || value.verificationDueAt !== void 0 || value.deployTargets !== void 0 || value.reverifyRequested !== void 0, { message: "TaskUpdate requires at least one field" }).superRefine((value, context) => {
|
|
38211
38196
|
if (value.autonomyLevel !== void 0 && value.autonomyReason === void 0) {
|
|
38212
38197
|
context.addIssue({
|
|
38213
38198
|
code: external_exports.ZodIssueCode.custom,
|
|
@@ -38246,7 +38231,7 @@ var apiViolationsErrorSchema = external_exports.object({
|
|
|
38246
38231
|
violations: external_exports.array(apiViolationSchema).min(1)
|
|
38247
38232
|
});
|
|
38248
38233
|
var mrrlinPlanCreateSchema = external_exports.object({
|
|
38249
|
-
|
|
38234
|
+
domains: mrrlinTaskDomainsSchema.nullable().optional(),
|
|
38250
38235
|
dueDate: external_exports.string().date().nullable().optional(),
|
|
38251
38236
|
goal: external_exports.string().min(1),
|
|
38252
38237
|
id: mrrlinPlanIdSchema,
|
|
@@ -38255,7 +38240,7 @@ var mrrlinPlanCreateSchema = external_exports.object({
|
|
|
38255
38240
|
status: mrrlinPlanStatusSchema.default("active")
|
|
38256
38241
|
});
|
|
38257
38242
|
var mrrlinPlanUpdateSchema = external_exports.object({
|
|
38258
|
-
|
|
38243
|
+
domains: mrrlinTaskDomainsSchema.nullable().optional(),
|
|
38259
38244
|
dueDate: external_exports.string().date().nullable().optional(),
|
|
38260
38245
|
goal: external_exports.string().min(1).optional(),
|
|
38261
38246
|
name: external_exports.string().min(1).optional(),
|
|
@@ -39317,7 +39302,8 @@ var CapabilityRouteSchema = external_exports.object({
|
|
|
39317
39302
|
var CAPABILITY_OPERATIONS = {
|
|
39318
39303
|
wiki: { create: "required", update: "required" },
|
|
39319
39304
|
repo_host: { pull_request: "required", pull_request_state: "required" },
|
|
39320
|
-
publish: { release: "required", observe: "required", preview: "optional", rollback: "optional" }
|
|
39305
|
+
publish: { release: "required", observe: "required", preview: "optional", rollback: "optional" },
|
|
39306
|
+
send: { dispatch: "required", cancel: "optional" }
|
|
39321
39307
|
};
|
|
39322
39308
|
var CapabilityToolClassSchema = external_exports.object({
|
|
39323
39309
|
projectSlug: mrrlinProjectSlugSchema,
|
|
@@ -39564,41 +39550,6 @@ function createMrrlinClient(config2) {
|
|
|
39564
39550
|
return response.text();
|
|
39565
39551
|
}
|
|
39566
39552
|
return {
|
|
39567
|
-
async listGithubInstallations() {
|
|
39568
|
-
const body = await request(`/github/installations`);
|
|
39569
|
-
return githubInstallationListResponseSchema.parse(body).data;
|
|
39570
|
-
},
|
|
39571
|
-
async handleGithubInstallCallback(input) {
|
|
39572
|
-
const setupAction = input.setupAction ?? "install";
|
|
39573
|
-
const url2 = appendQuery(`/github/install/callback`, {
|
|
39574
|
-
installation_id: String(input.installationId),
|
|
39575
|
-
setup_action: setupAction,
|
|
39576
|
-
state: input.state
|
|
39577
|
-
});
|
|
39578
|
-
const body = await request(url2);
|
|
39579
|
-
return githubInstallCallbackResponseSchema.parse(body).data;
|
|
39580
|
-
},
|
|
39581
|
-
async getGithubInstallationRepositories(installationId) {
|
|
39582
|
-
const body = await request(`/github/installations/${encodeURIComponent(String(installationId))}/repositories`);
|
|
39583
|
-
return githubInstallationRepositoriesResponseSchema.parse(body).data;
|
|
39584
|
-
},
|
|
39585
|
-
async bindProjectGithubRepo(projectSlug, input) {
|
|
39586
|
-
const payload = githubBindProjectRepoRequestSchema.parse(input);
|
|
39587
|
-
const body = await request(`${projectPath(projectSlug)}/github/repo`, {
|
|
39588
|
-
body: JSON.stringify(payload),
|
|
39589
|
-
headers: { "content-type": "application/json" },
|
|
39590
|
-
method: "PUT"
|
|
39591
|
-
});
|
|
39592
|
-
return githubBindProjectRepoResponseSchema.parse(body).data;
|
|
39593
|
-
},
|
|
39594
|
-
async createGithubPullRequest(projectSlug, input) {
|
|
39595
|
-
const body = await request(`${projectPath(projectSlug)}/github/pull-requests`, {
|
|
39596
|
-
body: JSON.stringify(input),
|
|
39597
|
-
headers: { "content-type": "application/json" },
|
|
39598
|
-
method: "POST"
|
|
39599
|
-
});
|
|
39600
|
-
return githubCreatePullRequestResponseSchema.parse(body).data;
|
|
39601
|
-
},
|
|
39602
39553
|
async createTask(projectSlug, input) {
|
|
39603
39554
|
const body = await request(`${projectPath(projectSlug)}/tasks`, {
|
|
39604
39555
|
body: JSON.stringify(input),
|
|
@@ -39736,44 +39687,6 @@ function createMrrlinClient(config2) {
|
|
|
39736
39687
|
const body = await request(`${projectPath(projectSlug)}/wiki/${encodeURIComponent(pageId)}`);
|
|
39737
39688
|
return wikiPageResponseSchema.parse(body).data;
|
|
39738
39689
|
},
|
|
39739
|
-
async dispatchGithubWorkflow(projectSlug, workflowId, input) {
|
|
39740
|
-
const body = await request(`${projectPath(projectSlug)}/github/workflows/${encodeURIComponent(workflowId)}/dispatches`, {
|
|
39741
|
-
body: JSON.stringify(input),
|
|
39742
|
-
headers: { "content-type": "application/json" },
|
|
39743
|
-
method: "POST"
|
|
39744
|
-
});
|
|
39745
|
-
return githubWorkflowDispatchResponseSchema.parse(body).data;
|
|
39746
|
-
},
|
|
39747
|
-
async dispatchTaskDeploy(projectSlug, taskId, input) {
|
|
39748
|
-
const body = await request(`${projectPath(projectSlug)}/tasks/${encodeURIComponent(taskId)}/deploy`, {
|
|
39749
|
-
body: JSON.stringify(input),
|
|
39750
|
-
headers: { "content-type": "application/json" },
|
|
39751
|
-
method: "POST"
|
|
39752
|
-
});
|
|
39753
|
-
return githubWorkflowDispatchResponseSchema.parse(body).data;
|
|
39754
|
-
},
|
|
39755
|
-
async getGithubWorkflowRunLatest(projectSlug, query) {
|
|
39756
|
-
const params = new URLSearchParams({
|
|
39757
|
-
workflowId: query.workflowId,
|
|
39758
|
-
branch: query.branch,
|
|
39759
|
-
dispatchedAfter: query.dispatchedAfter
|
|
39760
|
-
});
|
|
39761
|
-
const body = await request(`${projectPath(projectSlug)}/github/workflow-runs/latest?${params.toString()}`);
|
|
39762
|
-
return githubWorkflowRunResponseSchema.parse(body).data;
|
|
39763
|
-
},
|
|
39764
|
-
async getGithubPullRequest(projectSlug, pullNumber) {
|
|
39765
|
-
const body = await request(`${projectPath(projectSlug)}/github/pull-requests/${encodeURIComponent(String(pullNumber))}`);
|
|
39766
|
-
return githubPullRequestResponseSchema.parse(body).data;
|
|
39767
|
-
},
|
|
39768
|
-
async getGithubLatestDeployment(projectSlug, query) {
|
|
39769
|
-
const params = new URLSearchParams({ environment: query.environment });
|
|
39770
|
-
const body = await request(`${projectPath(projectSlug)}/github/deployments/latest?${params.toString()}`);
|
|
39771
|
-
return githubLatestDeploymentResponseSchema.parse(body).data;
|
|
39772
|
-
},
|
|
39773
|
-
async listGithubWorkflows(projectSlug) {
|
|
39774
|
-
const body = await request(`${projectPath(projectSlug)}/github/workflows`);
|
|
39775
|
-
return githubWorkflowListResponseSchema.parse(body).data;
|
|
39776
|
-
},
|
|
39777
39690
|
async listProjects() {
|
|
39778
39691
|
const body = await request("/projects");
|
|
39779
39692
|
return projectSummaryListResponseSchema.parse(body).data;
|
|
@@ -40384,17 +40297,6 @@ function createMrrlinClient(config2) {
|
|
|
40384
40297
|
});
|
|
40385
40298
|
return projectSchedulerPolicyResponseSchema.parse(body).data;
|
|
40386
40299
|
},
|
|
40387
|
-
async getProjectDeployWorkflow(projectSlug, env) {
|
|
40388
|
-
try {
|
|
40389
|
-
const body = await request(`${projectPath(projectSlug)}/deploy-workflows/${env}`);
|
|
40390
|
-
return projectDeployWorkflowResponseSchema.parse(body).data;
|
|
40391
|
-
} catch (error51) {
|
|
40392
|
-
if (error51 instanceof MrrlinApiError && error51.status === 404 && error51.code === "DEPLOY_WORKFLOW_UNSET") {
|
|
40393
|
-
return null;
|
|
40394
|
-
}
|
|
40395
|
-
throw error51;
|
|
40396
|
-
}
|
|
40397
|
-
},
|
|
40398
40300
|
async getDeployTopology(projectSlug) {
|
|
40399
40301
|
const body = await request(`${projectPath(projectSlug)}/deploy-topology`);
|
|
40400
40302
|
return deployTopologyResponseSchema.parse(body).data;
|
|
@@ -40418,14 +40320,6 @@ function createMrrlinClient(config2) {
|
|
|
40418
40320
|
throw error51;
|
|
40419
40321
|
}
|
|
40420
40322
|
},
|
|
40421
|
-
async upsertProjectDeployWorkflow(projectSlug, env, input) {
|
|
40422
|
-
const body = await request(`${projectPath(projectSlug)}/deploy-workflows/${env}`, {
|
|
40423
|
-
body: JSON.stringify(input),
|
|
40424
|
-
headers: { "content-type": "application/json" },
|
|
40425
|
-
method: "PUT"
|
|
40426
|
-
});
|
|
40427
|
-
return projectDeployWorkflowResponseSchema.parse(body).data;
|
|
40428
|
-
},
|
|
40429
40323
|
async getSchedulerPendingTasks(projectSlug) {
|
|
40430
40324
|
const body = await request(`${projectPath(projectSlug)}/scheduler/pending`);
|
|
40431
40325
|
return schedulerPendingTasksResponseSchema.parse(body).data;
|
|
@@ -41207,14 +41101,23 @@ var CODE_HEADS_BY_IMPACT = {
|
|
|
41207
41101
|
medium: ["plan-reviewer", "security-analyst", "scope-analyst"],
|
|
41208
41102
|
low: ["plan-reviewer", "scope-analyst"]
|
|
41209
41103
|
};
|
|
41210
|
-
var MAX_DOMAIN_HEADS =
|
|
41211
|
-
|
|
41212
|
-
|
|
41213
|
-
);
|
|
41104
|
+
var MAX_DOMAIN_HEADS = 7;
|
|
41105
|
+
function normalizeDomains(value) {
|
|
41106
|
+
if (value == null) return [DEFAULT_DOMAIN];
|
|
41107
|
+
const items = Array.isArray(value) ? value : [value];
|
|
41108
|
+
const normalized = [];
|
|
41109
|
+
for (const item of items) {
|
|
41110
|
+
if (typeof item === "string") {
|
|
41111
|
+
const v = item.trim().toLowerCase();
|
|
41112
|
+
if (DOMAINS.includes(v) && !normalized.includes(v)) {
|
|
41113
|
+
normalized.push(v);
|
|
41114
|
+
}
|
|
41115
|
+
}
|
|
41116
|
+
}
|
|
41117
|
+
return normalized.length > 0 ? normalized.sort() : [DEFAULT_DOMAIN];
|
|
41118
|
+
}
|
|
41214
41119
|
function normalizeDomain(value) {
|
|
41215
|
-
|
|
41216
|
-
const v = value.trim().toLowerCase();
|
|
41217
|
-
return DOMAINS.includes(v) ? v : DEFAULT_DOMAIN;
|
|
41120
|
+
return normalizeDomains(value)[0];
|
|
41218
41121
|
}
|
|
41219
41122
|
function normalizeImpact(value) {
|
|
41220
41123
|
if (typeof value !== "string") return null;
|
|
@@ -41222,10 +41125,19 @@ function normalizeImpact(value) {
|
|
|
41222
41125
|
return v === "low" || v === "medium" || v === "high" ? v : null;
|
|
41223
41126
|
}
|
|
41224
41127
|
function resolveHeads(domain2, impact) {
|
|
41225
|
-
const
|
|
41226
|
-
|
|
41227
|
-
const
|
|
41228
|
-
|
|
41128
|
+
const domains = normalizeDomains(domain2);
|
|
41129
|
+
const result = [];
|
|
41130
|
+
const seen = /* @__PURE__ */ new Set();
|
|
41131
|
+
for (const d of domains) {
|
|
41132
|
+
const headsForDomain = d === "code" ? CODE_HEADS_BY_IMPACT[normalizeImpact(impact) ?? "high"] : HEADS_BY_DOMAIN[d];
|
|
41133
|
+
for (const h of headsForDomain) {
|
|
41134
|
+
if (!seen.has(h)) {
|
|
41135
|
+
seen.add(h);
|
|
41136
|
+
result.push(h);
|
|
41137
|
+
}
|
|
41138
|
+
}
|
|
41139
|
+
}
|
|
41140
|
+
return result;
|
|
41229
41141
|
}
|
|
41230
41142
|
var PERSONAS_BY_DOMAIN = {
|
|
41231
41143
|
seo: "seo-writer",
|
|
@@ -41233,9 +41145,13 @@ var PERSONAS_BY_DOMAIN = {
|
|
|
41233
41145
|
marketing: "content-author"
|
|
41234
41146
|
};
|
|
41235
41147
|
function resolveProducerPersona(domain2) {
|
|
41236
|
-
const
|
|
41237
|
-
|
|
41238
|
-
|
|
41148
|
+
const domains = normalizeDomains(domain2);
|
|
41149
|
+
for (const d of domains) {
|
|
41150
|
+
if (d !== "code" && PERSONAS_BY_DOMAIN[d]) {
|
|
41151
|
+
return PERSONAS_BY_DOMAIN[d];
|
|
41152
|
+
}
|
|
41153
|
+
}
|
|
41154
|
+
return null;
|
|
41239
41155
|
}
|
|
41240
41156
|
|
|
41241
41157
|
// src/consensus/acceptance-criteria.ts
|
|
@@ -41358,7 +41274,7 @@ async function runSpecGate(_target, deps, opts) {
|
|
|
41358
41274
|
]
|
|
41359
41275
|
};
|
|
41360
41276
|
}
|
|
41361
|
-
const baseHeads = resolveHeads(intent.
|
|
41277
|
+
const baseHeads = resolveHeads(intent.domains, intent.impact);
|
|
41362
41278
|
const extraHeads = opts?.extraHeads ?? [];
|
|
41363
41279
|
const heads = [...baseHeads, ...extraHeads.filter((h) => !baseHeads.includes(h))];
|
|
41364
41280
|
const spec = await deps.readSpec();
|
|
@@ -42685,7 +42601,8 @@ var ClaudeProcess = class {
|
|
|
42685
42601
|
"stream-json",
|
|
42686
42602
|
"--output-format",
|
|
42687
42603
|
"stream-json",
|
|
42688
|
-
"--include-partial-messages"
|
|
42604
|
+
"--include-partial-messages",
|
|
42605
|
+
"--verbose"
|
|
42689
42606
|
];
|
|
42690
42607
|
if (options.mode.kind === "new") {
|
|
42691
42608
|
args.push("--session-id", this.sessionId);
|
|
@@ -44024,13 +43941,14 @@ async function resolveSpecDomain(client, projectSlug, page) {
|
|
|
44024
43941
|
const taskId = await resolveGatedTaskId(client, projectSlug, page);
|
|
44025
43942
|
if (taskId !== null) {
|
|
44026
43943
|
const task = await client.getTask(projectSlug, taskId);
|
|
44027
|
-
return normalizeDomain(task?.domain);
|
|
43944
|
+
return normalizeDomain(task?.domains ?? task?.domain);
|
|
44028
43945
|
}
|
|
44029
43946
|
const plans = await client.listPlans(projectSlug);
|
|
44030
43947
|
const plan = plans.find((p) => p.specWikiPageId === page.id);
|
|
44031
|
-
|
|
43948
|
+
const planDomains = plan?.domains ?? plan?.domain;
|
|
43949
|
+
if (planDomains != null) return normalizeDomain(planDomains);
|
|
44032
43950
|
const project = await client.getProject(projectSlug);
|
|
44033
|
-
return normalizeDomain(project?.defaultDomain);
|
|
43951
|
+
return normalizeDomain(project?.defaultDomains ?? project?.defaultDomain);
|
|
44034
43952
|
} catch {
|
|
44035
43953
|
return "code";
|
|
44036
43954
|
}
|
|
@@ -44433,7 +44351,7 @@ function buildSpecGateDeps(args) {
|
|
|
44433
44351
|
const taskId = await resolveGatedTaskId(client, projectSlug, { id: page.id, taskId: page.taskId ?? null });
|
|
44434
44352
|
if (taskId === null) {
|
|
44435
44353
|
const project = await client.getProject(projectSlug);
|
|
44436
|
-
return { taskId: null, seed: null, title: null,
|
|
44354
|
+
return { taskId: null, seed: null, title: null, domains: project.defaultDomains, notes: null };
|
|
44437
44355
|
}
|
|
44438
44356
|
const task = await client.getTask(projectSlug, taskId);
|
|
44439
44357
|
if (!task) {
|
|
@@ -44461,7 +44379,7 @@ function buildSpecGateDeps(args) {
|
|
|
44461
44379
|
taskId,
|
|
44462
44380
|
seed: resolvedSeed,
|
|
44463
44381
|
title: task.title ?? "",
|
|
44464
|
-
|
|
44382
|
+
domains: task.domains,
|
|
44465
44383
|
notes,
|
|
44466
44384
|
impact: task.impact,
|
|
44467
44385
|
adjudicated,
|
|
@@ -44620,10 +44538,10 @@ ${artifact}`,
|
|
|
44620
44538
|
timeoutMs,
|
|
44621
44539
|
codexExecutable
|
|
44622
44540
|
});
|
|
44623
|
-
const {
|
|
44541
|
+
const { domains } = await loadIntent();
|
|
44624
44542
|
try {
|
|
44625
44543
|
await client.recordSpecConsensusReview(projectSlug, specPageId, {
|
|
44626
|
-
contentHash: domainScopedReviewHash2(contentHash,
|
|
44544
|
+
contentHash: domainScopedReviewHash2(contentHash, domains),
|
|
44627
44545
|
outcome: String(outcome),
|
|
44628
44546
|
rounds: typeof rounds2 === "number" ? rounds2 : 0,
|
|
44629
44547
|
...history !== void 0 ? { history } : {},
|
|
@@ -44757,7 +44675,7 @@ async function buildDeliverableGateDeps(args) {
|
|
|
44757
44675
|
let criteria = [];
|
|
44758
44676
|
if (taskId) {
|
|
44759
44677
|
const task = await client.getTask(projectSlug, taskId);
|
|
44760
|
-
domain2 = normalizeDomain(task?.domain);
|
|
44678
|
+
domain2 = normalizeDomain(task?.domains ?? task?.domain);
|
|
44761
44679
|
impact = task?.impact;
|
|
44762
44680
|
taskTitle = task?.title ?? "";
|
|
44763
44681
|
if (task?.specWikiPageId) {
|
|
@@ -45306,7 +45224,7 @@ async function maybeRunShadow(input, deps, logger) {
|
|
|
45306
45224
|
const productionVerdict = productionVerdictFromOutcome(input.outcome);
|
|
45307
45225
|
if (productionVerdict === null) return false;
|
|
45308
45226
|
try {
|
|
45309
|
-
const heads = input.heads ?? [...resolveHeads(input.
|
|
45227
|
+
const heads = input.heads ?? [...resolveHeads(input.domains, input.impact), ...input.extraHeads ?? []];
|
|
45310
45228
|
const personaInstructions = {};
|
|
45311
45229
|
for (const name of heads) {
|
|
45312
45230
|
try {
|
|
@@ -45366,7 +45284,7 @@ function applyActivePanel(deps, panel) {
|
|
|
45366
45284
|
async function resolveActivePanel(input, deps) {
|
|
45367
45285
|
if (!multiLlmActive(input.env ?? process.env)) return null;
|
|
45368
45286
|
try {
|
|
45369
|
-
const heads = input.heads ?? [...resolveHeads(input.
|
|
45287
|
+
const heads = input.heads ?? [...resolveHeads(input.domains, input.impact), ...input.extraHeads ?? []];
|
|
45370
45288
|
if (heads.length === 0) return null;
|
|
45371
45289
|
const personaInstructions = {};
|
|
45372
45290
|
for (const name of heads) {
|
|
@@ -50458,6 +50376,12 @@ async function deliverToArtifacts(client, projectSlug, payload, bareFetch) {
|
|
|
50458
50376
|
}
|
|
50459
50377
|
}
|
|
50460
50378
|
|
|
50379
|
+
// src/delivery/send.ts
|
|
50380
|
+
async function deliverToSend(server, toolName, payload) {
|
|
50381
|
+
const { operation: _operation, ...args } = payload;
|
|
50382
|
+
return invokeCapability(server, toolName, args);
|
|
50383
|
+
}
|
|
50384
|
+
|
|
50461
50385
|
// src/delivery/publish.ts
|
|
50462
50386
|
async function deliverToPublish(server, toolName, payload) {
|
|
50463
50387
|
const { operation: _operation, ...args } = payload;
|
|
@@ -50805,6 +50729,14 @@ async function callDestination(client, projectSlug, route, resolvedToolName, pay
|
|
|
50805
50729
|
}
|
|
50806
50730
|
return deliverToArtifacts(client, projectSlug, payload, bareFetch);
|
|
50807
50731
|
}
|
|
50732
|
+
if (route.capability === "send") {
|
|
50733
|
+
if (typeof operation !== "string" || !(operation in CAPABILITY_OPERATIONS.send)) {
|
|
50734
|
+
throw new Error(`callDestination: payload.operation "${String(operation)}" is not valid for send`);
|
|
50735
|
+
}
|
|
50736
|
+
const server = readMcpServerById(mcpConfigPath ?? defaultMcpConfigPath(), route.serverId);
|
|
50737
|
+
if (server === null) throw new NoGrantForServerError(`no local MCP config for server "${route.serverId}"`);
|
|
50738
|
+
return deliverToSend(server, resolvedToolName, payload);
|
|
50739
|
+
}
|
|
50808
50740
|
if (route.capability === "publish") {
|
|
50809
50741
|
if (typeof operation !== "string" || !(operation in CAPABILITY_OPERATIONS.publish)) {
|
|
50810
50742
|
throw new Error(`callDestination: payload.operation "${String(operation)}" is not valid for publish`);
|
|
@@ -51483,7 +51415,7 @@ async function run(ctx, input, builders = defaultNativeSpecGateBuilders) {
|
|
|
51483
51415
|
await maybeRunShadow({
|
|
51484
51416
|
outcome: result.outcome,
|
|
51485
51417
|
artifact: specPage.markdownBody,
|
|
51486
|
-
|
|
51418
|
+
domains: [shadowDomain],
|
|
51487
51419
|
extraHeads: input.extraHeads,
|
|
51488
51420
|
correlationId: `Specs/${input.pageId}`,
|
|
51489
51421
|
// task 1.21: ctx's own minted seat, not an ambient read — ctx already carries it by
|
|
@@ -52011,7 +51943,7 @@ function buildDraftSpecPrompt(task, constitution, deployTarget = null) {
|
|
|
52011
51943
|
`id: ${task.id}`,
|
|
52012
51944
|
`title: ${task.title}`,
|
|
52013
51945
|
`type: ${task.type ?? "task"}`,
|
|
52014
|
-
`
|
|
51946
|
+
`domains: ${(task.domains ?? ["code"]).join(", ")}`,
|
|
52015
51947
|
`impact: ${task.impact ?? ""}`,
|
|
52016
51948
|
`category: ${task.category ?? ""} / ${task.subcategory ?? ""}`,
|
|
52017
51949
|
`tags: ${(task.tags ?? []).join(", ")}`,
|
|
@@ -52715,9 +52647,6 @@ var OUTWARD_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
52715
52647
|
"browser_press_key",
|
|
52716
52648
|
"browser_file_upload",
|
|
52717
52649
|
"browser_select_option",
|
|
52718
|
-
"create_github_pull_request",
|
|
52719
|
-
"dispatch_github_workflow",
|
|
52720
|
-
"dispatch_task_deploy",
|
|
52721
52650
|
"deliver_file",
|
|
52722
52651
|
"record_produced_url"
|
|
52723
52652
|
]);
|
|
@@ -52725,7 +52654,6 @@ var READ_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
52725
52654
|
"browser_navigate",
|
|
52726
52655
|
"browser_snapshot",
|
|
52727
52656
|
"get_execution_run",
|
|
52728
|
-
"get_github_installation_repositories",
|
|
52729
52657
|
"get_project",
|
|
52730
52658
|
"get_project_scheduler_policy",
|
|
52731
52659
|
"get_project_snapshot",
|
|
@@ -52735,8 +52663,6 @@ var READ_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
52735
52663
|
"list_artifact_files",
|
|
52736
52664
|
"list_execution_artifacts",
|
|
52737
52665
|
"list_execution_runs",
|
|
52738
|
-
"list_github_installations",
|
|
52739
|
-
"list_github_workflows",
|
|
52740
52666
|
"list_inbox_items",
|
|
52741
52667
|
"list_plans",
|
|
52742
52668
|
"list_project_members",
|
|
@@ -53497,9 +53423,7 @@ function readOrCreateWorkerToken() {
|
|
|
53497
53423
|
var mcpToolNames = {
|
|
53498
53424
|
appendExecutionArtifact: "append_execution_artifact",
|
|
53499
53425
|
archivePlan: "archive_plan",
|
|
53500
|
-
bindProjectGithubRepo: "bind_project_github_repo",
|
|
53501
53426
|
createExecutionRun: "create_execution_run",
|
|
53502
|
-
createGithubPullRequest: "create_github_pull_request",
|
|
53503
53427
|
createPlan: "create_plan",
|
|
53504
53428
|
createTaskDependency: "create_task_dependency",
|
|
53505
53429
|
createTaxonomyEntry: "create_taxonomy_entry",
|
|
@@ -53522,14 +53446,9 @@ var mcpToolNames = {
|
|
|
53522
53446
|
getProjectSnapshot: "get_project_snapshot",
|
|
53523
53447
|
getTask: "get_task",
|
|
53524
53448
|
getWikiPage: "get_wiki_page",
|
|
53525
|
-
dispatchGithubWorkflow: "dispatch_github_workflow",
|
|
53526
|
-
dispatchTaskDeploy: "dispatch_task_deploy",
|
|
53527
|
-
getGithubInstallationRepositories: "get_github_installation_repositories",
|
|
53528
53449
|
listExecutionArtifacts: "list_execution_artifacts",
|
|
53529
53450
|
listExecutionRuns: "list_execution_runs",
|
|
53530
53451
|
listInboxItems: "list_inbox_items",
|
|
53531
|
-
listGithubInstallations: "list_github_installations",
|
|
53532
|
-
listGithubWorkflows: "list_github_workflows",
|
|
53533
53452
|
listPlans: "list_plans",
|
|
53534
53453
|
listProjects: "list_projects",
|
|
53535
53454
|
listTaskDependencies: "list_task_dependencies",
|
|
@@ -53541,7 +53460,6 @@ var mcpToolNames = {
|
|
|
53541
53460
|
searchKnowledge: "search_knowledge",
|
|
53542
53461
|
updateExecutionRun: "update_execution_run",
|
|
53543
53462
|
upsertProjectSchedulerPolicy: "upsert_project_scheduler_policy",
|
|
53544
|
-
recordDeployWorkflow: "record_deploy_workflow",
|
|
53545
53463
|
updatePlan: "update_plan",
|
|
53546
53464
|
updateTask: "update_task",
|
|
53547
53465
|
resetDirectorThread: "reset_director_thread",
|
|
@@ -54192,17 +54110,6 @@ var runDecisionConsensusInputSchema = external_exports.object({
|
|
|
54192
54110
|
)
|
|
54193
54111
|
});
|
|
54194
54112
|
var searchKnowledgeInputSchema = wikiKnowledgeSearchInputSchema;
|
|
54195
|
-
var createGithubPullRequestInputSchema = projectScopedSchema.merge(githubCreatePullRequestRequestSchema);
|
|
54196
|
-
var listGithubWorkflowsInputSchema = projectScopedSchema;
|
|
54197
|
-
var dispatchGithubWorkflowInputSchema = projectScopedSchema.extend({ workflowId: external_exports.string().min(1) }).merge(githubWorkflowDispatchRequestSchema);
|
|
54198
|
-
var dispatchTaskDeployInputSchema = taskScopedSchema.extend({
|
|
54199
|
-
env: external_exports.enum(["dev", "prod"]),
|
|
54200
|
-
ref: external_exports.string().min(1).default("main"),
|
|
54201
|
-
workflowId: external_exports.string().min(1)
|
|
54202
|
-
});
|
|
54203
|
-
var listGithubInstallationsInputSchema = external_exports.object({});
|
|
54204
|
-
var getGithubInstallationRepositoriesInputSchema = githubInstallationIdParamSchema;
|
|
54205
|
-
var bindProjectGithubRepoInputSchema = projectScopedSchema.merge(githubBindProjectRepoRequestSchema);
|
|
54206
54113
|
var runScopedSchema = projectScopedSchema.merge(executionRunIdParamSchema);
|
|
54207
54114
|
var listExecutionRunsInputSchema = projectScopedSchema.merge(executionRunListFiltersSchema);
|
|
54208
54115
|
var createExecutionRunInputSchema = projectScopedSchema.merge(mrrlinExecutionRunCreateSchema);
|
|
@@ -54214,13 +54121,6 @@ var recordProducedUrlInputSchema = runScopedSchema.merge(mrrlinProducedUrlPayloa
|
|
|
54214
54121
|
var updateTaskStateInputSchema = runScopedSchema.merge(mrrlinTaskStateReportSchema);
|
|
54215
54122
|
var getProjectSchedulerPolicyInputSchema = projectScopedSchema;
|
|
54216
54123
|
var upsertProjectSchedulerPolicyInputSchema = projectScopedSchema.merge(mrrlinProjectSchedulerPolicyUpsertSchema);
|
|
54217
|
-
var recordDeployWorkflowInputSchema = projectScopedSchema.extend({
|
|
54218
|
-
env: mrrlinDeployWorkflowEnvSchema,
|
|
54219
|
-
workflowId: external_exports.number().int().positive().nullable(),
|
|
54220
|
-
workflowPath: external_exports.string().nullable().optional(),
|
|
54221
|
-
reason: external_exports.string().nullable().optional(),
|
|
54222
|
-
state: mrrlinDeployWorkflowStateSchema.optional()
|
|
54223
|
-
});
|
|
54224
54124
|
var getSchedulerPendingTasksInputSchema = projectScopedSchema;
|
|
54225
54125
|
var wakeDirectorInputSchema = projectScopedSchema.merge(wakeDirectorRequestSchema.partial());
|
|
54226
54126
|
var uploadArtifactInputSchema = projectScopedSchema.merge(
|
|
@@ -54278,9 +54178,7 @@ var retrieveContextInputSchema = external_exports.object({
|
|
|
54278
54178
|
var mcpToolInputSchemas = {
|
|
54279
54179
|
[mcpToolNames.appendExecutionArtifact]: appendExecutionArtifactInputSchema,
|
|
54280
54180
|
[mcpToolNames.archivePlan]: archivePlanInputSchema,
|
|
54281
|
-
[mcpToolNames.bindProjectGithubRepo]: bindProjectGithubRepoInputSchema,
|
|
54282
54181
|
[mcpToolNames.createExecutionRun]: createExecutionRunInputSchema,
|
|
54283
|
-
[mcpToolNames.createGithubPullRequest]: createGithubPullRequestInputSchema,
|
|
54284
54182
|
[mcpToolNames.createPlan]: createPlanInputSchema,
|
|
54285
54183
|
[mcpToolNames.createTaskDependency]: createTaskDependencyInputSchema,
|
|
54286
54184
|
[mcpToolNames.createTaxonomyEntry]: createTaxonomyEntryInputSchema,
|
|
@@ -54301,13 +54199,8 @@ var mcpToolInputSchemas = {
|
|
|
54301
54199
|
[mcpToolNames.getProjectSnapshot]: getProjectSnapshotInputSchema,
|
|
54302
54200
|
[mcpToolNames.getTask]: getTaskInputSchema,
|
|
54303
54201
|
[mcpToolNames.getWikiPage]: getWikiPageInputSchema,
|
|
54304
|
-
[mcpToolNames.dispatchGithubWorkflow]: dispatchGithubWorkflowInputSchema,
|
|
54305
|
-
[mcpToolNames.dispatchTaskDeploy]: dispatchTaskDeployInputSchema,
|
|
54306
|
-
[mcpToolNames.getGithubInstallationRepositories]: getGithubInstallationRepositoriesInputSchema,
|
|
54307
54202
|
[mcpToolNames.listExecutionArtifacts]: listExecutionArtifactsInputSchema,
|
|
54308
54203
|
[mcpToolNames.listExecutionRuns]: listExecutionRunsInputSchema,
|
|
54309
|
-
[mcpToolNames.listGithubInstallations]: listGithubInstallationsInputSchema,
|
|
54310
|
-
[mcpToolNames.listGithubWorkflows]: listGithubWorkflowsInputSchema,
|
|
54311
54204
|
[mcpToolNames.listPlans]: listPlansInputSchema,
|
|
54312
54205
|
[mcpToolNames.listProjects]: listProjectsInputSchema,
|
|
54313
54206
|
[mcpToolNames.listTaskDependencies]: listTaskDependenciesInputSchema,
|
|
@@ -54319,7 +54212,6 @@ var mcpToolInputSchemas = {
|
|
|
54319
54212
|
[mcpToolNames.searchKnowledge]: searchKnowledgeInputSchema,
|
|
54320
54213
|
[mcpToolNames.updateExecutionRun]: updateExecutionRunInputSchema,
|
|
54321
54214
|
[mcpToolNames.upsertProjectSchedulerPolicy]: upsertProjectSchedulerPolicyInputSchema,
|
|
54322
|
-
[mcpToolNames.recordDeployWorkflow]: recordDeployWorkflowInputSchema,
|
|
54323
54215
|
[mcpToolNames.updatePlan]: updatePlanInputSchema,
|
|
54324
54216
|
[mcpToolNames.updateTask]: updateTaskInputSchema,
|
|
54325
54217
|
[mcpToolNames.resetDirectorThread]: resetDirectorThreadInputSchema,
|
|
@@ -54350,9 +54242,7 @@ var mcpToolInputSchemas = {
|
|
|
54350
54242
|
var mcpToolOperationIds = {
|
|
54351
54243
|
[mcpToolNames.appendExecutionArtifact]: openApiOperationIds.appendExecutionArtifact,
|
|
54352
54244
|
[mcpToolNames.archivePlan]: openApiOperationIds.archivePlan,
|
|
54353
|
-
[mcpToolNames.bindProjectGithubRepo]: openApiOperationIds.bindProjectGithubRepo,
|
|
54354
54245
|
[mcpToolNames.createExecutionRun]: openApiOperationIds.createExecutionRun,
|
|
54355
|
-
[mcpToolNames.createGithubPullRequest]: openApiOperationIds.createGithubPullRequest,
|
|
54356
54246
|
[mcpToolNames.createPlan]: openApiOperationIds.createPlan,
|
|
54357
54247
|
[mcpToolNames.createTaskDependency]: openApiOperationIds.createTaskDependency,
|
|
54358
54248
|
[mcpToolNames.createTaxonomyEntry]: openApiOperationIds.createTaxonomyEntry,
|
|
@@ -54373,13 +54263,8 @@ var mcpToolOperationIds = {
|
|
|
54373
54263
|
[mcpToolNames.getProjectSnapshot]: openApiOperationIds.getProjectSnapshot,
|
|
54374
54264
|
[mcpToolNames.getTask]: openApiOperationIds.getTask,
|
|
54375
54265
|
[mcpToolNames.getWikiPage]: openApiOperationIds.getWikiPage,
|
|
54376
|
-
[mcpToolNames.dispatchGithubWorkflow]: openApiOperationIds.dispatchGithubWorkflow,
|
|
54377
|
-
[mcpToolNames.dispatchTaskDeploy]: openApiOperationIds.dispatchTaskDeploy,
|
|
54378
|
-
[mcpToolNames.getGithubInstallationRepositories]: openApiOperationIds.getGithubInstallationRepositories,
|
|
54379
54266
|
[mcpToolNames.listExecutionArtifacts]: openApiOperationIds.listExecutionArtifacts,
|
|
54380
54267
|
[mcpToolNames.listExecutionRuns]: openApiOperationIds.listExecutionRuns,
|
|
54381
|
-
[mcpToolNames.listGithubInstallations]: openApiOperationIds.listGithubInstallations,
|
|
54382
|
-
[mcpToolNames.listGithubWorkflows]: openApiOperationIds.listGithubWorkflows,
|
|
54383
54268
|
[mcpToolNames.listPlans]: openApiOperationIds.listPlans,
|
|
54384
54269
|
[mcpToolNames.listProjects]: openApiOperationIds.listProjects,
|
|
54385
54270
|
[mcpToolNames.listTaskDependencies]: openApiOperationIds.listTaskDependencies,
|
|
@@ -54391,7 +54276,6 @@ var mcpToolOperationIds = {
|
|
|
54391
54276
|
[mcpToolNames.searchKnowledge]: openApiOperationIds.searchKnowledge,
|
|
54392
54277
|
[mcpToolNames.updateExecutionRun]: openApiOperationIds.updateExecutionRun,
|
|
54393
54278
|
[mcpToolNames.upsertProjectSchedulerPolicy]: openApiOperationIds.upsertProjectSchedulerPolicy,
|
|
54394
|
-
[mcpToolNames.recordDeployWorkflow]: openApiOperationIds.upsertProjectDeployWorkflow,
|
|
54395
54279
|
[mcpToolNames.updatePlan]: openApiOperationIds.updatePlan,
|
|
54396
54280
|
[mcpToolNames.updateTask]: openApiOperationIds.updateTask,
|
|
54397
54281
|
[mcpToolNames.updateTaskState]: openApiOperationIds.reportTaskState,
|
|
@@ -54414,8 +54298,6 @@ var mcpToolOperationIds = {
|
|
|
54414
54298
|
};
|
|
54415
54299
|
var mcpToolDescriptions = {
|
|
54416
54300
|
[mcpToolNames.archivePlan]: "Archive a plan/epic and clear task plan links.",
|
|
54417
|
-
[mcpToolNames.bindProjectGithubRepo]: "Bind the project to a GitHub repository + installation id.",
|
|
54418
|
-
[mcpToolNames.createGithubPullRequest]: "Create a GitHub pull request for the project's linked repository installation.",
|
|
54419
54301
|
[mcpToolNames.createPlan]: "Create a plan/epic for grouping project tasks.",
|
|
54420
54302
|
[mcpToolNames.createTaskDependency]: "Create a blocked-by relationship between two tasks.",
|
|
54421
54303
|
[mcpToolNames.createTaxonomyEntry]: "Create an allowed category/subcategory pair.",
|
|
@@ -54432,11 +54314,6 @@ var mcpToolDescriptions = {
|
|
|
54432
54314
|
[mcpToolNames.getProjectSnapshot]: "Fetch the full project snapshot: GitHub binding, tasks, plans, and wiki pages.",
|
|
54433
54315
|
[mcpToolNames.getTask]: "Fetch a single task by project slug and task id.",
|
|
54434
54316
|
[mcpToolNames.getWikiPage]: "Fetch a single markdown Wiki page.",
|
|
54435
|
-
[mcpToolNames.dispatchGithubWorkflow]: "Dispatch a GitHub Actions workflow by workflow file/id against a ref visible to the linked installation.",
|
|
54436
|
-
[mcpToolNames.dispatchTaskDeploy]: "Dispatch a task's dev or prod deploy; caller supplies workflowId chosen for this run (ADR 0012). Subject to auto_deploy policy and prod dev-verification gate.",
|
|
54437
|
-
[mcpToolNames.getGithubInstallationRepositories]: "List repositories visible to a GitHub App installation id.",
|
|
54438
|
-
[mcpToolNames.listGithubInstallations]: "List persisted GitHub App installations.",
|
|
54439
|
-
[mcpToolNames.listGithubWorkflows]: "List the bound repository's GitHub Actions workflows live through the linked installation. No Mrrlin-side cache.",
|
|
54440
54317
|
[mcpToolNames.listProjects]: "List every project visible to the operator.",
|
|
54441
54318
|
[mcpToolNames.listPlans]: "List project plans/epics with progress counts.",
|
|
54442
54319
|
[mcpToolNames.listTaskDependencies]: "List task blocked-by dependencies.",
|
|
@@ -54468,7 +54345,6 @@ var mcpToolDescriptions = {
|
|
|
54468
54345
|
[mcpToolNames.updateExecutionRun]: "Update an execution run (status, branch, SHA, PR url, dev/prod workflow ids, checkpoint cursor). Transitioning to handoff_queued requires an approved handoff_judgement artifact.",
|
|
54469
54346
|
[mcpToolNames.getProjectSchedulerPolicy]: "Fetch the project scheduler policy: cadence floor, eligible autonomy levels, and optional wake_floor. Returns defaults if unset.",
|
|
54470
54347
|
[mcpToolNames.upsertProjectSchedulerPolicy]: "Upsert the project scheduler policy. Partial: only provided fields overwrite existing values.",
|
|
54471
|
-
[mcpToolNames.recordDeployWorkflow]: "Record which GitHub Actions workflow deploys this project for one environment (dev or prod), after confirming it via list_github_workflows + reading its file for a workflow_dispatch trigger. Call this AT MOST ONCE per environment per project, only when the deploy gate has parked on a missing/stale workflow id \u2014 this choice becomes durable project state, not a per-run decision. Pass workflowId=null and state='ambiguous' when zero or more than one candidate is confirmed dispatchable; otherwise pass the single confirmed workflowId with state='resolved' (the default). `source` is derived from your identity server-side \u2014 you cannot set it, and this call is always recorded as 'agent'.",
|
|
54472
54348
|
[mcpToolNames.getSchedulerPendingTasks]: "Return tasks the scheduler should wake now: ones with follow_up_at or verification_due_at passed, or the policy wake_floor reached, filtered by eligible autonomy levels.",
|
|
54473
54349
|
[mcpToolNames.wakeDirector]: "Wake Director once for a project: optionally dry-run scheduler evaluation or enqueue execution runs best-effort.",
|
|
54474
54350
|
[mcpToolNames.listInboxItems]: "List operator-inbox items for a project. Optional filters: kind, status.",
|
|
@@ -54682,40 +54558,6 @@ function createMrrlinTools(options) {
|
|
|
54682
54558
|
"Unable to archive plan.",
|
|
54683
54559
|
async (c, { projectSlug, planId }) => await c.updatePlan(projectSlug, planId, { status: "archived" })
|
|
54684
54560
|
),
|
|
54685
|
-
[mcpToolNames.listGithubInstallations]: makeTool(
|
|
54686
|
-
client,
|
|
54687
|
-
mcpToolNames.listGithubInstallations,
|
|
54688
|
-
"GITHUB_INSTALLATION_LIST_FAILED",
|
|
54689
|
-
"Unable to list GitHub installations.",
|
|
54690
|
-
async (c) => await c.listGithubInstallations()
|
|
54691
|
-
),
|
|
54692
|
-
[mcpToolNames.getGithubInstallationRepositories]: makeTool(
|
|
54693
|
-
client,
|
|
54694
|
-
mcpToolNames.getGithubInstallationRepositories,
|
|
54695
|
-
"GITHUB_INSTALLATION_REPOSITORIES_FAILED",
|
|
54696
|
-
"Unable to list installation repositories.",
|
|
54697
|
-
async (c, { installationId }) => await c.getGithubInstallationRepositories(installationId)
|
|
54698
|
-
),
|
|
54699
|
-
[mcpToolNames.bindProjectGithubRepo]: makeTool(
|
|
54700
|
-
client,
|
|
54701
|
-
mcpToolNames.bindProjectGithubRepo,
|
|
54702
|
-
"GITHUB_REPO_BIND_FAILED",
|
|
54703
|
-
"Unable to bind project repository.",
|
|
54704
|
-
async (c, { projectSlug, ...input }) => await c.bindProjectGithubRepo(projectSlug, input)
|
|
54705
|
-
),
|
|
54706
|
-
[mcpToolNames.createGithubPullRequest]: makeTool(
|
|
54707
|
-
client,
|
|
54708
|
-
mcpToolNames.createGithubPullRequest,
|
|
54709
|
-
"GITHUB_PULL_REQUEST_CREATE_FAILED",
|
|
54710
|
-
"Unable to create GitHub pull request.",
|
|
54711
|
-
async (c, { projectSlug, ...input }) => await deliverBuiltIn(
|
|
54712
|
-
c,
|
|
54713
|
-
projectSlug,
|
|
54714
|
-
"code_change",
|
|
54715
|
-
{ operation: "pull_request", ...input },
|
|
54716
|
-
{ mcpConfigPath: options.mcpConfigPath }
|
|
54717
|
-
)
|
|
54718
|
-
),
|
|
54719
54561
|
[mcpToolNames.createPlan]: makeTool(
|
|
54720
54562
|
client,
|
|
54721
54563
|
mcpToolNames.createPlan,
|
|
@@ -54836,27 +54678,6 @@ function createMrrlinTools(options) {
|
|
|
54836
54678
|
"Unable to read wiki page.",
|
|
54837
54679
|
async (c, { projectSlug, pageId }) => await c.getWikiPage(projectSlug, pageId)
|
|
54838
54680
|
),
|
|
54839
|
-
[mcpToolNames.dispatchGithubWorkflow]: makeTool(
|
|
54840
|
-
client,
|
|
54841
|
-
mcpToolNames.dispatchGithubWorkflow,
|
|
54842
|
-
"GITHUB_WORKFLOW_DISPATCH_FAILED",
|
|
54843
|
-
"Unable to dispatch GitHub workflow.",
|
|
54844
|
-
async (c, { projectSlug, workflowId, ...input }) => await c.dispatchGithubWorkflow(projectSlug, workflowId, input)
|
|
54845
|
-
),
|
|
54846
|
-
[mcpToolNames.dispatchTaskDeploy]: makeTool(
|
|
54847
|
-
client,
|
|
54848
|
-
mcpToolNames.dispatchTaskDeploy,
|
|
54849
|
-
"TASK_DEPLOY_DISPATCH_FAILED",
|
|
54850
|
-
"Unable to dispatch the task deploy workflow.",
|
|
54851
|
-
async (c, { projectSlug, taskId, workflowId, ...rest }) => await c.dispatchTaskDeploy(projectSlug, taskId, { ...rest, workflowId })
|
|
54852
|
-
),
|
|
54853
|
-
[mcpToolNames.listGithubWorkflows]: makeTool(
|
|
54854
|
-
client,
|
|
54855
|
-
mcpToolNames.listGithubWorkflows,
|
|
54856
|
-
"GITHUB_WORKFLOW_LIST_FAILED",
|
|
54857
|
-
"Unable to list GitHub workflows.",
|
|
54858
|
-
async (c, { projectSlug }) => await c.listGithubWorkflows(projectSlug)
|
|
54859
|
-
),
|
|
54860
54681
|
[mcpToolNames.listProjects]: makeTool(
|
|
54861
54682
|
client,
|
|
54862
54683
|
mcpToolNames.listProjects,
|
|
@@ -55203,13 +55024,6 @@ function createMrrlinTools(options) {
|
|
|
55203
55024
|
"Unable to upsert project scheduler policy.",
|
|
55204
55025
|
async (c, { projectSlug, ...input }) => await c.upsertProjectSchedulerPolicy(projectSlug, input)
|
|
55205
55026
|
),
|
|
55206
|
-
[mcpToolNames.recordDeployWorkflow]: makeTool(
|
|
55207
|
-
client,
|
|
55208
|
-
mcpToolNames.recordDeployWorkflow,
|
|
55209
|
-
"DEPLOY_WORKFLOW_RECORD_FAILED",
|
|
55210
|
-
"Unable to record the project's deploy workflow choice.",
|
|
55211
|
-
async (c, { projectSlug, env, ...input }) => await c.upsertProjectDeployWorkflow(projectSlug, env, input)
|
|
55212
|
-
),
|
|
55213
55027
|
[mcpToolNames.getSchedulerPendingTasks]: makeTool(
|
|
55214
55028
|
client,
|
|
55215
55029
|
mcpToolNames.getSchedulerPendingTasks,
|
|
@@ -55764,31 +55578,31 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
|
|
|
55764
55578
|
if (cliResult2.status === 0) {
|
|
55765
55579
|
return {
|
|
55766
55580
|
ready: true,
|
|
55767
|
-
checks: { cli: true, version: true, auth: false, mcpReachable: false },
|
|
55581
|
+
checks: { cli: true, version: true, auth: false, mcpReachable: false, smoke: true },
|
|
55768
55582
|
details: []
|
|
55769
55583
|
};
|
|
55770
55584
|
} else if (cliResult2.status === null) {
|
|
55771
55585
|
return {
|
|
55772
55586
|
ready: false,
|
|
55773
|
-
checks: { cli: false, version: false, auth: false, mcpReachable: false },
|
|
55587
|
+
checks: { cli: false, version: false, auth: false, mcpReachable: false, smoke: false },
|
|
55774
55588
|
details: ["cli: `agy` binary not found on PATH"]
|
|
55775
55589
|
};
|
|
55776
55590
|
} else {
|
|
55777
55591
|
return {
|
|
55778
55592
|
ready: false,
|
|
55779
|
-
checks: { cli: true, version: false, auth: false, mcpReachable: false },
|
|
55593
|
+
checks: { cli: true, version: false, auth: false, mcpReachable: false, smoke: false },
|
|
55780
55594
|
details: [`cli: \`agy --version\` exited with code ${cliResult2.status}`]
|
|
55781
55595
|
};
|
|
55782
55596
|
}
|
|
55783
55597
|
} catch (_e) {
|
|
55784
55598
|
return {
|
|
55785
55599
|
ready: false,
|
|
55786
|
-
checks: { cli: false, version: false, auth: false, mcpReachable: false },
|
|
55600
|
+
checks: { cli: false, version: false, auth: false, mcpReachable: false, smoke: false },
|
|
55787
55601
|
details: ["cli: `agy` binary not found on PATH"]
|
|
55788
55602
|
};
|
|
55789
55603
|
}
|
|
55790
55604
|
}
|
|
55791
|
-
const checks = { cli: false, version: false, auth: false, mcpReachable: false };
|
|
55605
|
+
const checks = { cli: false, version: false, auth: false, mcpReachable: false, smoke: false };
|
|
55792
55606
|
const details = [];
|
|
55793
55607
|
let cliResult;
|
|
55794
55608
|
let cliUnreachable = false;
|
|
@@ -55851,7 +55665,34 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
|
|
|
55851
55665
|
}
|
|
55852
55666
|
if (!checks.mcpReachable) details.push("mcpReachable: external-agents server entry missing or invalid");
|
|
55853
55667
|
}
|
|
55854
|
-
|
|
55668
|
+
if (provider === "codex") {
|
|
55669
|
+
checks.smoke = true;
|
|
55670
|
+
} else if (!checks.cli || !checks.version || !checks.auth || !checks.mcpReachable) {
|
|
55671
|
+
checks.smoke = false;
|
|
55672
|
+
} else {
|
|
55673
|
+
try {
|
|
55674
|
+
const result = run3([
|
|
55675
|
+
"--print",
|
|
55676
|
+
"--input-format",
|
|
55677
|
+
"stream-json",
|
|
55678
|
+
"--output-format",
|
|
55679
|
+
"stream-json",
|
|
55680
|
+
"--include-partial-messages",
|
|
55681
|
+
"--verbose",
|
|
55682
|
+
"--permission-mode",
|
|
55683
|
+
"bypassPermissions",
|
|
55684
|
+
"--model",
|
|
55685
|
+
"haiku",
|
|
55686
|
+
"-p",
|
|
55687
|
+
"hi"
|
|
55688
|
+
]);
|
|
55689
|
+
checks.smoke = result.status === 0;
|
|
55690
|
+
} catch {
|
|
55691
|
+
checks.smoke = false;
|
|
55692
|
+
}
|
|
55693
|
+
if (!checks.smoke) details.push("smoke: single-turn `claude --print ... -p hi` failed");
|
|
55694
|
+
}
|
|
55695
|
+
const ready = checks.cli && checks.version && checks.auth && checks.mcpReachable && checks.smoke;
|
|
55855
55696
|
return { ready, checks, details };
|
|
55856
55697
|
}
|
|
55857
55698
|
|
|
@@ -56990,7 +56831,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
|
|
|
56990
56831
|
}
|
|
56991
56832
|
|
|
56992
56833
|
// src/_generated/version.ts
|
|
56993
|
-
var PKG_VERSION = "0.4.
|
|
56834
|
+
var PKG_VERSION = "0.4.88";
|
|
56994
56835
|
|
|
56995
56836
|
// src/api-base-url-migrate.ts
|
|
56996
56837
|
var import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
@@ -57015,28 +56856,45 @@ function resolveServiceCwd(opts) {
|
|
|
57015
56856
|
}
|
|
57016
56857
|
var BRIDGE_APP_NAME = "mrrlin-bridge";
|
|
57017
56858
|
function renderEcosystemConfig(opts) {
|
|
57018
|
-
|
|
57019
|
-
|
|
57020
|
-
|
|
57021
|
-
|
|
57022
|
-
|
|
57023
|
-
|
|
57024
|
-
|
|
57025
|
-
|
|
57026
|
-
|
|
56859
|
+
let envLines;
|
|
56860
|
+
if ("env" in opts && opts.env !== void 0) {
|
|
56861
|
+
const safeEnv = /* @__PURE__ */ Object.create(null);
|
|
56862
|
+
for (const key of Object.keys(opts.env)) {
|
|
56863
|
+
const val = opts.env[key];
|
|
56864
|
+
if (val !== void 0) {
|
|
56865
|
+
safeEnv[key] = val;
|
|
56866
|
+
}
|
|
56867
|
+
}
|
|
56868
|
+
const keys = Object.keys(safeEnv).sort();
|
|
56869
|
+
envLines = keys.map((k) => {
|
|
56870
|
+
const keyProp = k === "__proto__" ? '["__proto__"]' : k;
|
|
56871
|
+
return ` ${keyProp}: ${JSON.stringify(safeEnv[k])},`;
|
|
56872
|
+
}).join("\n");
|
|
56873
|
+
} else {
|
|
56874
|
+
const legacyOpts = opts;
|
|
56875
|
+
const env = {
|
|
56876
|
+
HOME: legacyOpts.home,
|
|
56877
|
+
PATH: legacyOpts.pathEnv,
|
|
56878
|
+
MRRLIN_DIRECTOR_BRIDGE_LOG: "1"
|
|
56879
|
+
};
|
|
56880
|
+
if (legacyOpts.user) {
|
|
56881
|
+
env.USER = legacyOpts.user;
|
|
56882
|
+
if (process.platform === "win32") {
|
|
56883
|
+
env.USERNAME = legacyOpts.user;
|
|
56884
|
+
}
|
|
57027
56885
|
}
|
|
57028
|
-
|
|
57029
|
-
|
|
57030
|
-
|
|
57031
|
-
|
|
57032
|
-
|
|
57033
|
-
|
|
57034
|
-
|
|
57035
|
-
|
|
57036
|
-
|
|
56886
|
+
if (legacyOpts.codexHome) env.CODEX_HOME = legacyOpts.codexHome;
|
|
56887
|
+
const claudeConfigDir = legacyOpts.claudeConfigDir?.trim();
|
|
56888
|
+
if (claudeConfigDir) env.CLAUDE_CONFIG_DIR = claudeConfigDir;
|
|
56889
|
+
const apiBaseUrl = legacyOpts.apiBaseUrl ? retargetRetiredApiBaseUrl(legacyOpts.apiBaseUrl).baseUrl : void 0;
|
|
56890
|
+
if (apiBaseUrl && !isProductionApiBaseUrl(apiBaseUrl)) {
|
|
56891
|
+
env.MRRLIN_API_BASE_URL = apiBaseUrl;
|
|
56892
|
+
if (legacyOpts.apiAllowRemote && !isStagingApiBaseUrl(apiBaseUrl) && !isLoopbackUrl(apiBaseUrl)) {
|
|
56893
|
+
env.MRRLIN_API_ALLOW_REMOTE = "1";
|
|
56894
|
+
}
|
|
57037
56895
|
}
|
|
56896
|
+
envLines = Object.entries(env).map(([k, v]) => ` ${k}: ${JSON.stringify(v)},`).join("\n");
|
|
57038
56897
|
}
|
|
57039
|
-
const envLines = Object.entries(env).map(([k, v]) => ` ${k}: ${JSON.stringify(v)},`).join("\n");
|
|
57040
56898
|
return `module.exports = {
|
|
57041
56899
|
apps: [{
|
|
57042
56900
|
name: ${JSON.stringify(BRIDGE_APP_NAME)},
|
|
@@ -59723,7 +59581,7 @@ async function notifyPinRetirement(info, opts) {
|
|
|
59723
59581
|
type: "bug",
|
|
59724
59582
|
category: "bug",
|
|
59725
59583
|
subcategory: "reported",
|
|
59726
|
-
|
|
59584
|
+
domains: ["code"],
|
|
59727
59585
|
impact: "medium",
|
|
59728
59586
|
notes: `The pinned strong model "${info.pinnedModel}" for provider "${info.providerId}" was not found in the provider's live model list (retired by provider). Falling back to live default model "${info.fallbackModel}". Please update the operator pin in ~/.mrrlin/ecosystem.config.cjs or the corresponding environment variable (MRRLIN_${info.providerId.toUpperCase()}_STRONG_MODEL).`,
|
|
59729
59587
|
operatorSeedRequest: `The pinned strong model "${info.pinnedModel}" for provider "${info.providerId}" has been retired. Fallback in use: "${info.fallbackModel}". Update the strong model pin.`,
|
|
@@ -60038,7 +59896,7 @@ var BASE_INSTRUCTIONS_PREFIX = [
|
|
|
60038
59896
|
"",
|
|
60039
59897
|
"Publish policy and task split:",
|
|
60040
59898
|
"- When creating tasks for work that produces a published web page, author the work as a `[code_change]` task and a `[page]` task linked by `blocked_by` (the `[page]` task is blocked by the `[code_change]` task).",
|
|
60041
|
-
'- The `[page]` task must carry
|
|
59899
|
+
'- The `[page]` task must carry domains: ["content"] so it routes to non-code execution and closes on a live url receipt.',
|
|
60042
59900
|
"- Set autoDeploy on the code change task following the three-way heuristic:",
|
|
60043
59901
|
" - the result is only meaningful once live and there is nothing subjective to look at (`robots.txt`, `llms.txt`, sitemap, metatags) \u2192 release-to-live (`prod`);",
|
|
60044
59902
|
" - the operator would plausibly want to see it rendered first (a landing page, copy, a layout) \u2192 stop at preview (`dev`);",
|
|
@@ -60233,9 +60091,10 @@ async function gatherContext(client, projectSlug, task, openRunId) {
|
|
|
60233
60091
|
async function deployWorkflowReverifyNotice(client, projectSlug) {
|
|
60234
60092
|
const envs = ["dev", "prod"];
|
|
60235
60093
|
const flagged = [];
|
|
60094
|
+
const clientWithDeploy = client;
|
|
60236
60095
|
for (const env of envs) {
|
|
60237
60096
|
try {
|
|
60238
|
-
const row = await
|
|
60097
|
+
const row = await clientWithDeploy.getProjectDeployWorkflow?.(projectSlug, env);
|
|
60239
60098
|
if (row?.reverifyRequested) flagged.push(env);
|
|
60240
60099
|
} catch {
|
|
60241
60100
|
}
|
|
@@ -60558,8 +60417,10 @@ async function driveRun(deps, projectSlug, runId) {
|
|
|
60558
60417
|
}
|
|
60559
60418
|
}
|
|
60560
60419
|
}
|
|
60561
|
-
const
|
|
60562
|
-
|
|
60420
|
+
const runDomains = Array.isArray(task.domains) ? task.domains : [task.domains ?? "code"];
|
|
60421
|
+
const isPureCode = runDomains.length === 1 && runDomains[0] === "code";
|
|
60422
|
+
if (!isPureCode) {
|
|
60423
|
+
const runDomain = runDomains[0] ?? "code";
|
|
60563
60424
|
await driveNonCodeRun(deps, projectSlug, runId, leaseId, task, runDomain);
|
|
60564
60425
|
return;
|
|
60565
60426
|
}
|
|
@@ -61240,7 +61101,7 @@ function buildDeliverableAuthorPrompt(task, specMarkdown) {
|
|
|
61240
61101
|
`--- TASK ---`,
|
|
61241
61102
|
`id: ${task.id}`,
|
|
61242
61103
|
`title: ${task.title}`,
|
|
61243
|
-
`
|
|
61104
|
+
`domains: ${(task.domains ?? ["code"]).join(", ")}`,
|
|
61244
61105
|
``,
|
|
61245
61106
|
`notes:`,
|
|
61246
61107
|
task.notes ?? "(none)",
|
|
@@ -61906,7 +61767,7 @@ async function runBackstopSweep(deps, drive = (slug, id) => driveRun(deps, slug,
|
|
|
61906
61767
|
}
|
|
61907
61768
|
function isRunRecoverableByThisBridge(run3, worktreeRoot) {
|
|
61908
61769
|
if (!worktreeRoot) return true;
|
|
61909
|
-
if (!run3.worktreeId) return
|
|
61770
|
+
if (!run3.worktreeId) return true;
|
|
61910
61771
|
const relative = import_node_path30.default.relative(import_node_path30.default.resolve(worktreeRoot), import_node_path30.default.resolve(run3.worktreeId));
|
|
61911
61772
|
return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path30.default.isAbsolute(relative);
|
|
61912
61773
|
}
|
|
@@ -66417,97 +66278,6 @@ async function startExecutorServer(opts) {
|
|
|
66417
66278
|
}
|
|
66418
66279
|
}
|
|
66419
66280
|
|
|
66420
|
-
// src/verification-turn.ts
|
|
66421
|
-
function buildVerificationPrompt(input) {
|
|
66422
|
-
return [
|
|
66423
|
-
`You are verifying a deployment. The application is live at: ${input.environmentUrl}`,
|
|
66424
|
-
`Run ONLY read-only HTTP checks against that URL to evaluate the verification steps below.`,
|
|
66425
|
-
`Behave as if you had no repository, filesystem, or credential access: do not read or write`,
|
|
66426
|
-
`files, do not use any credentials, do not contact any other host, and do not attempt to`,
|
|
66427
|
-
`mutate anything \u2014 only observe the deployed app over HTTP. (This is a rule you must follow,`,
|
|
66428
|
-
`not something the environment enforces.)`,
|
|
66429
|
-
``,
|
|
66430
|
-
`Verification steps for environment "${input.env}":`,
|
|
66431
|
-
input.verificationSection,
|
|
66432
|
-
``,
|
|
66433
|
-
`When finished, end your final message with EXACTLY one line, nothing after it:`,
|
|
66434
|
-
`VERDICT: PASS - <one-line summary> (if every step passed)`,
|
|
66435
|
-
`VERDICT: FAIL - <one-line summary> (if any step failed or could not be confirmed)`
|
|
66436
|
-
].join("\n");
|
|
66437
|
-
}
|
|
66438
|
-
function parseVerdict2(text) {
|
|
66439
|
-
const re = /^[^\S\n]*VERDICT:\s*(PASS|FAIL)\b[^\S\n]*[-—:]?[^\S\n]*([^\n]*)/gim;
|
|
66440
|
-
let match;
|
|
66441
|
-
let last = null;
|
|
66442
|
-
while ((match = re.exec(text)) !== null) last = match;
|
|
66443
|
-
if (!last) {
|
|
66444
|
-
return {
|
|
66445
|
-
verdict: "fail",
|
|
66446
|
-
summary: "no parseable VERDICT line in verification output",
|
|
66447
|
-
turnRef: null,
|
|
66448
|
-
fullOutput: text
|
|
66449
|
-
};
|
|
66450
|
-
}
|
|
66451
|
-
const verdict = (last[1] ?? "").toLowerCase() === "pass" ? "pass" : "fail";
|
|
66452
|
-
const summary = (last[2] ?? "").trim() || `verification ${verdict}`;
|
|
66453
|
-
return { verdict, summary, turnRef: null, fullOutput: text };
|
|
66454
|
-
}
|
|
66455
|
-
function isBlockedVerificationHost(hostname3) {
|
|
66456
|
-
const h = hostname3.toLowerCase().replace(/^\[|\]$/g, "");
|
|
66457
|
-
if (h === "localhost" || h.endsWith(".localhost") || h.endsWith(".local") || h.endsWith(".internal")) return true;
|
|
66458
|
-
const isIpv6 = h.includes(":");
|
|
66459
|
-
if (isIpv6) {
|
|
66460
|
-
if (h === "::1" || h === "::" || h.startsWith("fe80:") || h.startsWith("fc") || h.startsWith("fd")) return true;
|
|
66461
|
-
if (h.startsWith("::ffff:")) return true;
|
|
66462
|
-
}
|
|
66463
|
-
const m = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(h);
|
|
66464
|
-
if (m) {
|
|
66465
|
-
const a = Number(m[1]);
|
|
66466
|
-
const b = Number(m[2]);
|
|
66467
|
-
if (a === 0 || a === 127 || a === 10) return true;
|
|
66468
|
-
if (a === 169 && b === 254) return true;
|
|
66469
|
-
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
66470
|
-
if (a === 192 && b === 168) return true;
|
|
66471
|
-
}
|
|
66472
|
-
return false;
|
|
66473
|
-
}
|
|
66474
|
-
function createRunVerificationTurn(deps) {
|
|
66475
|
-
return async (input) => {
|
|
66476
|
-
let url2;
|
|
66477
|
-
try {
|
|
66478
|
-
url2 = new URL(input.environmentUrl);
|
|
66479
|
-
} catch {
|
|
66480
|
-
return { verdict: "fail", summary: `invalid environmentUrl: ${input.environmentUrl}`, turnRef: null };
|
|
66481
|
-
}
|
|
66482
|
-
if (url2.protocol !== "http:" && url2.protocol !== "https:") {
|
|
66483
|
-
return { verdict: "fail", summary: `unsupported scheme in environmentUrl: ${url2.protocol}`, turnRef: null };
|
|
66484
|
-
}
|
|
66485
|
-
const hostname3 = url2.hostname;
|
|
66486
|
-
if (!hostname3) {
|
|
66487
|
-
return { verdict: "fail", summary: `environmentUrl has no host: ${input.environmentUrl}`, turnRef: null };
|
|
66488
|
-
}
|
|
66489
|
-
if (isBlockedVerificationHost(hostname3)) {
|
|
66490
|
-
return { verdict: "fail", summary: `refusing to verify against non-public host: ${hostname3}`, turnRef: null };
|
|
66491
|
-
}
|
|
66492
|
-
const providerId = input.run.agentSeat;
|
|
66493
|
-
if (providerId == null) {
|
|
66494
|
-
return { verdict: "fail", summary: "run has no resolved agent_seat", turnRef: null };
|
|
66495
|
-
}
|
|
66496
|
-
const { handle, dispose, cwd } = await deps.startSandbox([hostname3], providerId);
|
|
66497
|
-
try {
|
|
66498
|
-
let text;
|
|
66499
|
-
try {
|
|
66500
|
-
text = await deps.runTurn(handle, buildVerificationPrompt(input), cwd);
|
|
66501
|
-
} catch (error51) {
|
|
66502
|
-
return { verdict: "fail", summary: `verification turn errored: ${String(error51).slice(0, 160)}`, turnRef: null };
|
|
66503
|
-
}
|
|
66504
|
-
return parseVerdict2(text);
|
|
66505
|
-
} finally {
|
|
66506
|
-
dispose();
|
|
66507
|
-
}
|
|
66508
|
-
};
|
|
66509
|
-
}
|
|
66510
|
-
|
|
66511
66281
|
// src/self-review.ts
|
|
66512
66282
|
function buildSelfReviewPrompt(task) {
|
|
66513
66283
|
return [
|
|
@@ -66577,33 +66347,6 @@ function createSelfReviewTurn(deps) {
|
|
|
66577
66347
|
};
|
|
66578
66348
|
}
|
|
66579
66349
|
|
|
66580
|
-
// src/verification-section.ts
|
|
66581
|
-
function extractVerificationSection(markdown) {
|
|
66582
|
-
const lines2 = markdown.split("\n");
|
|
66583
|
-
const headingRe = /^(#{1,6})\s+(.*)$/;
|
|
66584
|
-
let start = -1;
|
|
66585
|
-
let level = 0;
|
|
66586
|
-
for (let i = 0; i < lines2.length; i += 1) {
|
|
66587
|
-
const m = headingRe.exec(lines2[i] ?? "");
|
|
66588
|
-
if (m && /^verification\b/i.test((m[2] ?? "").trim())) {
|
|
66589
|
-
start = i + 1;
|
|
66590
|
-
level = (m[1] ?? "").length;
|
|
66591
|
-
break;
|
|
66592
|
-
}
|
|
66593
|
-
}
|
|
66594
|
-
if (start === -1) return null;
|
|
66595
|
-
let end = lines2.length;
|
|
66596
|
-
for (let i = start; i < lines2.length; i += 1) {
|
|
66597
|
-
const m = headingRe.exec(lines2[i] ?? "");
|
|
66598
|
-
if (m && (m[1] ?? "").length <= level) {
|
|
66599
|
-
end = i;
|
|
66600
|
-
break;
|
|
66601
|
-
}
|
|
66602
|
-
}
|
|
66603
|
-
const body = lines2.slice(start, end).join("\n").trim();
|
|
66604
|
-
return body.length > 0 ? body : null;
|
|
66605
|
-
}
|
|
66606
|
-
|
|
66607
66350
|
// src/director-reseed.ts
|
|
66608
66351
|
var import_node_fs21 = require("node:fs");
|
|
66609
66352
|
var import_node_readline = require("node:readline");
|
|
@@ -66668,6 +66411,23 @@ function extractItems(lines2, sessionIds) {
|
|
|
66668
66411
|
items.sort((a, b) => a.ts < b.ts ? -1 : a.ts > b.ts ? 1 : 0);
|
|
66669
66412
|
return { items, skipped: skipped2 };
|
|
66670
66413
|
}
|
|
66414
|
+
function contextMessagesToReseedItems(contextMessages, currentPromptText) {
|
|
66415
|
+
if (!contextMessages || contextMessages.length === 0) return [];
|
|
66416
|
+
const prior = contextMessages.filter((msg, idx) => {
|
|
66417
|
+
if (idx === 0 && currentPromptText && msg.role === "user" && msg.content.trim() === currentPromptText.trim()) {
|
|
66418
|
+
return false;
|
|
66419
|
+
}
|
|
66420
|
+
return true;
|
|
66421
|
+
});
|
|
66422
|
+
if (prior.length === 0) return [];
|
|
66423
|
+
const chronological = [...prior].reverse();
|
|
66424
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
66425
|
+
return chronological.map((msg, idx) => ({
|
|
66426
|
+
ts: `${nowIso.slice(0, 10)}T00:00:${(idx + 1).toString().padStart(2, "0")}.000Z`,
|
|
66427
|
+
kind: msg.role === "assistant" ? "assistant" : "user",
|
|
66428
|
+
text: msg.content
|
|
66429
|
+
}));
|
|
66430
|
+
}
|
|
66671
66431
|
function renderReseedBlock(items, opts) {
|
|
66672
66432
|
const buildText = (kept2, droppedCount) => {
|
|
66673
66433
|
const header = [
|
|
@@ -69182,7 +68942,9 @@ function createBridgeMessageHandler(deps) {
|
|
|
69182
68942
|
// Client-supplied, so the elements are validated and not just the shape:
|
|
69183
68943
|
// this array selects which sessions' log rows get replayed into a prompt.
|
|
69184
68944
|
priorSessionIds: Array.isArray(msg.priorSessionIds) ? msg.priorSessionIds.filter((id) => typeof id === "string" && id.length > 0) : [],
|
|
69185
|
-
otherBytes
|
|
68945
|
+
otherBytes,
|
|
68946
|
+
contextMessages: msg.context?.contextMessages,
|
|
68947
|
+
currentText: effectiveText
|
|
69186
68948
|
});
|
|
69187
68949
|
} catch {
|
|
69188
68950
|
reseedPrefix = null;
|
|
@@ -69591,48 +69353,6 @@ async function startDirectorBridge() {
|
|
|
69591
69353
|
selfReviewTurn: createSelfReviewTurn({
|
|
69592
69354
|
runTurn: (handle, cwd, prompt) => wrappedTurnLock.run("chat", () => runCollectedAgentTurn(handle, prompt, cwd, SELF_REVIEW_BASE_INSTRUCTIONS))
|
|
69593
69355
|
}),
|
|
69594
|
-
// ADR 0015 deploy gate: after a pushed run reaches dev_deploy/prod_deploy, the backstop sweep
|
|
69595
|
-
// dispatches the deploy + polls + runs a verification turn against the deployed env URL in a
|
|
69596
|
-
// throwaway cwd. Per the owner no-sandbox decision the verification turn runs from the real
|
|
69597
|
-
// operator config like every other executor turn; its observe-only base instructions bound
|
|
69598
|
-
// behaviour, provider-generic since task 4.1.
|
|
69599
|
-
deployGate: {
|
|
69600
|
-
loadVerificationSection: async (projectSlug, task) => {
|
|
69601
|
-
if (!task.specWikiPageId) return null;
|
|
69602
|
-
const page = await client.getWikiPage(projectSlug, task.specWikiPageId).catch(() => null);
|
|
69603
|
-
return page?.markdownBody ? extractVerificationSection(page.markdownBody) : null;
|
|
69604
|
-
},
|
|
69605
|
-
runVerificationTurn: createRunVerificationTurn({
|
|
69606
|
-
// egressDomains is retained in the seam signature (verification-turn.ts still computes the
|
|
69607
|
-
// env host) but no longer constrains anything — the executor is unrestricted.
|
|
69608
|
-
startSandbox: async (_egressDomains, providerId) => {
|
|
69609
|
-
const cwd = import_node_fs23.default.mkdtempSync(import_node_path37.default.join(import_node_os17.default.tmpdir(), "mrrlin-verify-"));
|
|
69610
|
-
let executor;
|
|
69611
|
-
try {
|
|
69612
|
-
executor = await startExecutorServer({ worktree: cwd, provider: providerId });
|
|
69613
|
-
} catch (error51) {
|
|
69614
|
-
try {
|
|
69615
|
-
import_node_fs23.default.rmSync(cwd, { recursive: true, force: true });
|
|
69616
|
-
} catch {
|
|
69617
|
-
}
|
|
69618
|
-
throw error51;
|
|
69619
|
-
}
|
|
69620
|
-
return {
|
|
69621
|
-
handle: executor.handle,
|
|
69622
|
-
cwd,
|
|
69623
|
-
dispose: () => {
|
|
69624
|
-
executor.dispose();
|
|
69625
|
-
try {
|
|
69626
|
-
import_node_fs23.default.rmSync(cwd, { recursive: true, force: true });
|
|
69627
|
-
} catch {
|
|
69628
|
-
}
|
|
69629
|
-
}
|
|
69630
|
-
};
|
|
69631
|
-
},
|
|
69632
|
-
runTurn: (handle, prompt, cwd) => wrappedTurnLock.run("chat", () => runCollectedAgentTurn(handle, prompt, cwd, VERIFICATION_BASE_INSTRUCTIONS))
|
|
69633
|
-
}),
|
|
69634
|
-
budgetSeconds: deployPollBudgetSeconds()
|
|
69635
|
-
},
|
|
69636
69356
|
// ADR 0020 Phase 2: run the deliverable-gate over a non-code run's authored Deliverables page.
|
|
69637
69357
|
// Builds the gate deps (resolving domain/heads/criteria from the page's task + spec) and runs the
|
|
69638
69358
|
// same convergence loop the spec-gate uses. runId is threaded for verdict provenance (decision 10).
|
|
@@ -69818,27 +69538,32 @@ async function startDirectorBridge() {
|
|
|
69818
69538
|
});
|
|
69819
69539
|
return NO_HISTORY_BLOCK;
|
|
69820
69540
|
};
|
|
69821
|
-
|
|
69822
|
-
|
|
69823
|
-
|
|
69824
|
-
|
|
69825
|
-
|
|
69826
|
-
|
|
69827
|
-
|
|
69828
|
-
|
|
69829
|
-
|
|
69830
|
-
|
|
69831
|
-
|
|
69832
|
-
|
|
69833
|
-
|
|
69834
|
-
|
|
69835
|
-
|
|
69541
|
+
let items = [];
|
|
69542
|
+
let filesCount = 0;
|
|
69543
|
+
let missingFilesCount = 0;
|
|
69544
|
+
let skippedCount = 0;
|
|
69545
|
+
const logEnabled = resolveBridgeLogEnabled();
|
|
69546
|
+
const promptsEnabled = resolvePromptsEnabled();
|
|
69547
|
+
if (logEnabled && promptsEnabled) {
|
|
69548
|
+
const retentionWindowMs = readEnvInt("MRRLIN_LOG_RETENTION_AGE_DAYS", 30) * 864e5;
|
|
69549
|
+
const reseedWindowMs = retentionWindowMs;
|
|
69550
|
+
const files = dayFilesInWindow(/* @__PURE__ */ new Date(), reseedWindowMs);
|
|
69551
|
+
filesCount = files.length;
|
|
69552
|
+
const sessionIds = [args.directorSessionId, ...args.priorSessionIds];
|
|
69553
|
+
const { lines: lines2, missingFiles } = await readSessionRows(import_node_path37.default.join(config2.stateDir, "logs"), files, sessionIds);
|
|
69554
|
+
missingFilesCount = missingFiles;
|
|
69555
|
+
const extracted = extractItems(lines2, sessionIds);
|
|
69556
|
+
items = extracted.items;
|
|
69557
|
+
skippedCount = extracted.skipped;
|
|
69558
|
+
}
|
|
69559
|
+
if (items.length === 0 && args.contextMessages && args.contextMessages.length > 0) {
|
|
69560
|
+
items = contextMessagesToReseedItems(args.contextMessages, args.currentText);
|
|
69561
|
+
}
|
|
69562
|
+
if (items.length === 0) {
|
|
69563
|
+
if (!logEnabled) return refuse2("log-disabled");
|
|
69564
|
+
if (!promptsEnabled) return refuse2("prompts-not-logged");
|
|
69565
|
+
return refuse2("no-rows");
|
|
69836
69566
|
}
|
|
69837
|
-
const files = dayFilesInWindow(/* @__PURE__ */ new Date(), reseedWindowMs);
|
|
69838
|
-
const sessionIds = [args.directorSessionId, ...args.priorSessionIds];
|
|
69839
|
-
const { lines: lines2, missingFiles } = await readSessionRows(import_node_path37.default.join(config2.stateDir, "logs"), files, sessionIds);
|
|
69840
|
-
const { items, skipped: skipped2 } = extractItems(lines2, sessionIds);
|
|
69841
|
-
if (items.length === 0) return refuse2("no-rows");
|
|
69842
69567
|
const budget = Math.max(0, Math.min(config2.reseedMaxTokens, config2.turnMaxTokens - args.otherBytes));
|
|
69843
69568
|
const block = renderReseedBlock(items, {
|
|
69844
69569
|
maxTokens: budget,
|
|
@@ -69852,9 +69577,9 @@ async function startDirectorBridge() {
|
|
|
69852
69577
|
payload: {
|
|
69853
69578
|
sessionId: args.directorSessionId,
|
|
69854
69579
|
priorSessionIds: args.priorSessionIds.length,
|
|
69855
|
-
dayFiles:
|
|
69856
|
-
missingFiles,
|
|
69857
|
-
parseSkips:
|
|
69580
|
+
dayFiles: filesCount,
|
|
69581
|
+
missingFiles: missingFilesCount,
|
|
69582
|
+
parseSkips: skippedCount,
|
|
69858
69583
|
itemCount: block.itemCount,
|
|
69859
69584
|
droppedCount: block.droppedCount,
|
|
69860
69585
|
estimatedTokens: Buffer.byteLength(block.text, "utf8"),
|
|
@@ -71321,49 +71046,440 @@ function runSetCredential(args) {
|
|
|
71321
71046
|
var import_node_os18 = __toESM(require("node:os"), 1);
|
|
71322
71047
|
var import_node_fs24 = require("node:fs");
|
|
71323
71048
|
var import_node_path38 = __toESM(require("node:path"), 1);
|
|
71324
|
-
function
|
|
71325
|
-
|
|
71326
|
-
}
|
|
71327
|
-
|
|
71328
|
-
|
|
71329
|
-
|
|
71049
|
+
function parseEnvLine(line, env) {
|
|
71050
|
+
const trimmed = line.trim();
|
|
71051
|
+
if (!trimmed || trimmed === "}" || trimmed === "},") return;
|
|
71052
|
+
const match = /^\s*(?:([a-zA-Z_$][a-zA-Z0-9_$]*)|"((?:[^"\\]|\\.)*)"|(\["__proto__"\]))\s*:\s*("(?:[^"\\]|\\.)*")\s*,?\s*$/.exec(line);
|
|
71053
|
+
if (!match) return;
|
|
71054
|
+
const identKey = match[1];
|
|
71055
|
+
const quotedKey = match[2];
|
|
71056
|
+
const computedProto = match[3];
|
|
71057
|
+
const rawValue = match[4];
|
|
71058
|
+
if (!rawValue) return;
|
|
71059
|
+
let key = null;
|
|
71060
|
+
if (computedProto) {
|
|
71061
|
+
key = "__proto__";
|
|
71062
|
+
} else if (identKey) {
|
|
71063
|
+
if (identKey === "__proto__") {
|
|
71064
|
+
return;
|
|
71065
|
+
}
|
|
71066
|
+
key = identKey;
|
|
71067
|
+
} else if (quotedKey !== void 0) {
|
|
71068
|
+
try {
|
|
71069
|
+
const parsedKey = JSON.parse(`"${quotedKey}"`);
|
|
71070
|
+
if (typeof parsedKey !== "string" || parsedKey === "__proto__") {
|
|
71071
|
+
return;
|
|
71072
|
+
}
|
|
71073
|
+
key = parsedKey;
|
|
71074
|
+
} catch {
|
|
71075
|
+
return;
|
|
71076
|
+
}
|
|
71077
|
+
}
|
|
71078
|
+
if (key === null) return;
|
|
71330
71079
|
try {
|
|
71331
|
-
const
|
|
71332
|
-
|
|
71080
|
+
const parsedValue = JSON.parse(rawValue);
|
|
71081
|
+
if (typeof parsedValue === "string") {
|
|
71082
|
+
env[key] = parsedValue;
|
|
71083
|
+
}
|
|
71333
71084
|
} catch {
|
|
71334
|
-
return
|
|
71085
|
+
return;
|
|
71335
71086
|
}
|
|
71336
71087
|
}
|
|
71337
|
-
function
|
|
71338
|
-
|
|
71339
|
-
|
|
71340
|
-
|
|
71341
|
-
|
|
71342
|
-
|
|
71088
|
+
function parseExistingEcosystemConfig(text) {
|
|
71089
|
+
if (text === null || text === void 0) {
|
|
71090
|
+
return { kind: "missing" };
|
|
71091
|
+
}
|
|
71092
|
+
let mode = "code";
|
|
71093
|
+
const templateCurlyStack = [];
|
|
71094
|
+
let curlyDepth = 0;
|
|
71095
|
+
let squareDepth = 0;
|
|
71096
|
+
let parenDepth = 0;
|
|
71097
|
+
let moduleExportsOpened = false;
|
|
71098
|
+
let moduleExportsClosed = false;
|
|
71099
|
+
let appsArrayOpened = false;
|
|
71100
|
+
let appsArrayClosed = false;
|
|
71101
|
+
let appCandidateActive = false;
|
|
71102
|
+
let candidateHasName = false;
|
|
71103
|
+
let candidateHasScript = false;
|
|
71104
|
+
let candidateHasArgs = false;
|
|
71105
|
+
let candidateHasEnv = false;
|
|
71106
|
+
let candidateEnvOpenedOnLine = false;
|
|
71107
|
+
let candidateEnvClosed = false;
|
|
71108
|
+
let candidateEnv = null;
|
|
71109
|
+
let matchedAppEnv = null;
|
|
71110
|
+
let matchedAppCount = 0;
|
|
71111
|
+
let recentCode = "";
|
|
71112
|
+
let lineCode = "";
|
|
71113
|
+
const len = text.length;
|
|
71114
|
+
let i = 0;
|
|
71115
|
+
while (i < len) {
|
|
71116
|
+
const ch = text[i] ?? "";
|
|
71117
|
+
if (mode === "line_comment") {
|
|
71118
|
+
if (ch === "\n") {
|
|
71119
|
+
mode = "code";
|
|
71120
|
+
lineCode = "";
|
|
71121
|
+
candidateEnvOpenedOnLine = false;
|
|
71122
|
+
}
|
|
71123
|
+
i++;
|
|
71124
|
+
continue;
|
|
71125
|
+
}
|
|
71126
|
+
if (mode === "block_comment") {
|
|
71127
|
+
if (ch === "*" && i + 1 < len && text[i + 1] === "/") {
|
|
71128
|
+
mode = "code";
|
|
71129
|
+
i += 2;
|
|
71130
|
+
continue;
|
|
71131
|
+
}
|
|
71132
|
+
if (ch === "\n") {
|
|
71133
|
+
lineCode = "";
|
|
71134
|
+
candidateEnvOpenedOnLine = false;
|
|
71135
|
+
}
|
|
71136
|
+
i++;
|
|
71137
|
+
continue;
|
|
71138
|
+
}
|
|
71139
|
+
if (mode === "single_quote") {
|
|
71140
|
+
if (ch === "\\") {
|
|
71141
|
+
i += 2;
|
|
71142
|
+
continue;
|
|
71143
|
+
}
|
|
71144
|
+
if (ch === "'") {
|
|
71145
|
+
mode = "code";
|
|
71146
|
+
i++;
|
|
71147
|
+
continue;
|
|
71148
|
+
}
|
|
71149
|
+
if (ch === "\n" || ch === "\r") {
|
|
71150
|
+
return { kind: "rejected", text };
|
|
71151
|
+
}
|
|
71152
|
+
i++;
|
|
71153
|
+
continue;
|
|
71154
|
+
}
|
|
71155
|
+
if (mode === "double_quote") {
|
|
71156
|
+
if (ch === "\\") {
|
|
71157
|
+
lineCode += ch + (text[i + 1] ?? "");
|
|
71158
|
+
i += 2;
|
|
71159
|
+
continue;
|
|
71160
|
+
}
|
|
71161
|
+
lineCode += ch;
|
|
71162
|
+
if (ch === '"') {
|
|
71163
|
+
mode = "code";
|
|
71164
|
+
if (appCandidateActive && curlyDepth === 2 && squareDepth === 1) {
|
|
71165
|
+
if (/name\s*:\s*"mrrlin-bridge"/.test(lineCode)) candidateHasName = true;
|
|
71166
|
+
if (/script\s*:\s*"mrrlin-mcp"/.test(lineCode)) candidateHasScript = true;
|
|
71167
|
+
if (/args\s*:\s*"director-bridge"/.test(lineCode)) candidateHasArgs = true;
|
|
71168
|
+
}
|
|
71169
|
+
i++;
|
|
71170
|
+
continue;
|
|
71171
|
+
}
|
|
71172
|
+
if (ch === "\n" || ch === "\r") {
|
|
71173
|
+
return { kind: "rejected", text };
|
|
71174
|
+
}
|
|
71175
|
+
i++;
|
|
71176
|
+
continue;
|
|
71177
|
+
}
|
|
71178
|
+
if (mode === "template") {
|
|
71179
|
+
if (ch === "\\") {
|
|
71180
|
+
i += 2;
|
|
71181
|
+
continue;
|
|
71182
|
+
}
|
|
71183
|
+
if (ch === "`") {
|
|
71184
|
+
mode = "code";
|
|
71185
|
+
i++;
|
|
71186
|
+
continue;
|
|
71187
|
+
}
|
|
71188
|
+
if (ch === "$" && i + 1 < len && text[i + 1] === "{") {
|
|
71189
|
+
mode = "code";
|
|
71190
|
+
templateCurlyStack.push(curlyDepth);
|
|
71191
|
+
curlyDepth++;
|
|
71192
|
+
i += 2;
|
|
71193
|
+
continue;
|
|
71194
|
+
}
|
|
71195
|
+
i++;
|
|
71196
|
+
continue;
|
|
71197
|
+
}
|
|
71198
|
+
if (ch === "/" && i + 1 < len) {
|
|
71199
|
+
if (text[i + 1] === "/") {
|
|
71200
|
+
mode = "line_comment";
|
|
71201
|
+
i += 2;
|
|
71202
|
+
continue;
|
|
71203
|
+
}
|
|
71204
|
+
if (text[i + 1] === "*") {
|
|
71205
|
+
mode = "block_comment";
|
|
71206
|
+
i += 2;
|
|
71207
|
+
continue;
|
|
71208
|
+
}
|
|
71209
|
+
return { kind: "rejected", text };
|
|
71210
|
+
}
|
|
71211
|
+
if (ch === "/") {
|
|
71212
|
+
return { kind: "rejected", text };
|
|
71213
|
+
}
|
|
71214
|
+
if (ch === "'") {
|
|
71215
|
+
mode = "single_quote";
|
|
71216
|
+
i++;
|
|
71217
|
+
continue;
|
|
71218
|
+
}
|
|
71219
|
+
if (ch === '"') {
|
|
71220
|
+
mode = "double_quote";
|
|
71221
|
+
lineCode += ch;
|
|
71222
|
+
i++;
|
|
71223
|
+
continue;
|
|
71224
|
+
}
|
|
71225
|
+
if (ch === "`") {
|
|
71226
|
+
mode = "template";
|
|
71227
|
+
i++;
|
|
71228
|
+
continue;
|
|
71229
|
+
}
|
|
71230
|
+
if (ch === "\n") {
|
|
71231
|
+
if (appCandidateActive && candidateHasEnv && !candidateEnvClosed && curlyDepth === 3 && candidateEnv) {
|
|
71232
|
+
parseEnvLine(lineCode, candidateEnv);
|
|
71233
|
+
}
|
|
71234
|
+
lineCode = "";
|
|
71235
|
+
candidateEnvOpenedOnLine = false;
|
|
71236
|
+
recentCode += " ";
|
|
71237
|
+
i++;
|
|
71238
|
+
continue;
|
|
71239
|
+
}
|
|
71240
|
+
lineCode += ch;
|
|
71241
|
+
recentCode += ch;
|
|
71242
|
+
if (ch === "{") {
|
|
71243
|
+
if (curlyDepth === 0 && squareDepth === 0) {
|
|
71244
|
+
if (/module\.exports\s*=\s*\{$/.test(recentCode.trim())) {
|
|
71245
|
+
if (moduleExportsOpened) return { kind: "rejected", text };
|
|
71246
|
+
moduleExportsOpened = true;
|
|
71247
|
+
}
|
|
71248
|
+
} else if (moduleExportsOpened && !moduleExportsClosed && appsArrayOpened && !appsArrayClosed && squareDepth === 1 && curlyDepth === 1) {
|
|
71249
|
+
appCandidateActive = true;
|
|
71250
|
+
candidateHasName = false;
|
|
71251
|
+
candidateHasScript = false;
|
|
71252
|
+
candidateHasArgs = false;
|
|
71253
|
+
candidateHasEnv = false;
|
|
71254
|
+
candidateEnvOpenedOnLine = false;
|
|
71255
|
+
candidateEnvClosed = false;
|
|
71256
|
+
candidateEnv = /* @__PURE__ */ Object.create(null);
|
|
71257
|
+
} else if (appCandidateActive && squareDepth === 1 && curlyDepth === 2) {
|
|
71258
|
+
if (/\benv\s*:\s*\{$/.test(recentCode.trim())) {
|
|
71259
|
+
candidateHasEnv = true;
|
|
71260
|
+
candidateEnvOpenedOnLine = true;
|
|
71261
|
+
}
|
|
71262
|
+
}
|
|
71263
|
+
curlyDepth++;
|
|
71264
|
+
recentCode = "";
|
|
71265
|
+
i++;
|
|
71266
|
+
continue;
|
|
71267
|
+
}
|
|
71268
|
+
if (ch === "}") {
|
|
71269
|
+
if (curlyDepth === 0) return { kind: "rejected", text };
|
|
71270
|
+
if (templateCurlyStack.length > 0 && templateCurlyStack[templateCurlyStack.length - 1] === curlyDepth - 1) {
|
|
71271
|
+
templateCurlyStack.pop();
|
|
71272
|
+
mode = "template";
|
|
71273
|
+
curlyDepth--;
|
|
71274
|
+
recentCode = "";
|
|
71275
|
+
i++;
|
|
71276
|
+
continue;
|
|
71277
|
+
}
|
|
71278
|
+
if (appCandidateActive && candidateHasEnv && !candidateEnvClosed && curlyDepth === 3) {
|
|
71279
|
+
if (candidateEnvOpenedOnLine) {
|
|
71280
|
+
candidateHasEnv = false;
|
|
71281
|
+
}
|
|
71282
|
+
const beforeBrace = lineCode.slice(0, -1);
|
|
71283
|
+
if (beforeBrace.trim() && candidateEnv) {
|
|
71284
|
+
parseEnvLine(beforeBrace, candidateEnv);
|
|
71285
|
+
}
|
|
71286
|
+
candidateEnvClosed = true;
|
|
71287
|
+
} else if (appCandidateActive && curlyDepth === 2 && squareDepth === 1) {
|
|
71288
|
+
if (candidateHasName && candidateHasScript && candidateHasArgs && candidateHasEnv && candidateEnvClosed) {
|
|
71289
|
+
matchedAppCount++;
|
|
71290
|
+
if (matchedAppCount > 1) return { kind: "rejected", text };
|
|
71291
|
+
matchedAppEnv = candidateEnv;
|
|
71292
|
+
}
|
|
71293
|
+
appCandidateActive = false;
|
|
71294
|
+
candidateEnv = null;
|
|
71295
|
+
} else if (moduleExportsOpened && !moduleExportsClosed && curlyDepth === 1 && squareDepth === 0) {
|
|
71296
|
+
moduleExportsClosed = true;
|
|
71297
|
+
}
|
|
71298
|
+
curlyDepth--;
|
|
71299
|
+
recentCode = "";
|
|
71300
|
+
i++;
|
|
71301
|
+
continue;
|
|
71302
|
+
}
|
|
71303
|
+
if (ch === "[") {
|
|
71304
|
+
if (moduleExportsOpened && !moduleExportsClosed && curlyDepth === 1 && squareDepth === 0) {
|
|
71305
|
+
if (/\bapps\s*:\s*\[$/.test(recentCode.trim())) {
|
|
71306
|
+
if (appsArrayOpened) return { kind: "rejected", text };
|
|
71307
|
+
appsArrayOpened = true;
|
|
71308
|
+
}
|
|
71309
|
+
}
|
|
71310
|
+
squareDepth++;
|
|
71311
|
+
recentCode = "";
|
|
71312
|
+
i++;
|
|
71313
|
+
continue;
|
|
71314
|
+
}
|
|
71315
|
+
if (ch === "]") {
|
|
71316
|
+
if (squareDepth === 0) return { kind: "rejected", text };
|
|
71317
|
+
if (moduleExportsOpened && !moduleExportsClosed && appsArrayOpened && squareDepth === 1 && curlyDepth === 1) {
|
|
71318
|
+
appsArrayClosed = true;
|
|
71319
|
+
}
|
|
71320
|
+
squareDepth--;
|
|
71321
|
+
recentCode = "";
|
|
71322
|
+
i++;
|
|
71323
|
+
continue;
|
|
71324
|
+
}
|
|
71325
|
+
if (ch === "(") {
|
|
71326
|
+
parenDepth++;
|
|
71327
|
+
i++;
|
|
71328
|
+
continue;
|
|
71329
|
+
}
|
|
71330
|
+
if (ch === ")") {
|
|
71331
|
+
if (parenDepth === 0) return { kind: "rejected", text };
|
|
71332
|
+
parenDepth--;
|
|
71333
|
+
i++;
|
|
71334
|
+
continue;
|
|
71335
|
+
}
|
|
71336
|
+
i++;
|
|
71337
|
+
}
|
|
71338
|
+
if (mode !== "code") return { kind: "rejected", text };
|
|
71339
|
+
if (curlyDepth !== 0 || squareDepth !== 0 || parenDepth !== 0) return { kind: "rejected", text };
|
|
71340
|
+
if (!moduleExportsOpened || !moduleExportsClosed) return { kind: "rejected", text };
|
|
71341
|
+
if (!appsArrayOpened || !appsArrayClosed) return { kind: "rejected", text };
|
|
71342
|
+
if (matchedAppCount !== 1 || !matchedAppEnv) return { kind: "rejected", text };
|
|
71343
|
+
return { kind: "accepted", env: matchedAppEnv, text };
|
|
71344
|
+
}
|
|
71345
|
+
var CURATED_KEYS = [
|
|
71346
|
+
"CODEX_HOME",
|
|
71347
|
+
"CLAUDE_CONFIG_DIR",
|
|
71348
|
+
"MRRLIN_DIRECTOR_BRIDGE_LOG",
|
|
71349
|
+
"MRRLIN_API_BASE_URL",
|
|
71350
|
+
"MRRLIN_API_ALLOW_REMOTE",
|
|
71351
|
+
"MRRLIN_STAGING"
|
|
71352
|
+
];
|
|
71353
|
+
function mergeConfigEnv(depsEnv, carriedEnv) {
|
|
71354
|
+
const isWin = process.platform === "win32";
|
|
71355
|
+
const DENIED_CARRIED_KEYS = new Set(isWin ? ["HOME", "PATH", "USER", "USERNAME"] : ["HOME", "PATH", "USER"]);
|
|
71356
|
+
const mergedEnv = /* @__PURE__ */ Object.create(null);
|
|
71357
|
+
const preservedNames = [];
|
|
71358
|
+
const droppedNames = [];
|
|
71359
|
+
const carriedKeys = Object.keys(carriedEnv);
|
|
71360
|
+
for (const key of carriedKeys) {
|
|
71361
|
+
if (DENIED_CARRIED_KEYS.has(key)) {
|
|
71362
|
+
droppedNames.push(key);
|
|
71363
|
+
continue;
|
|
71364
|
+
}
|
|
71365
|
+
const envVal = depsEnv[key];
|
|
71366
|
+
if (Object.hasOwn(depsEnv, key) && envVal !== void 0) {
|
|
71367
|
+
let installerVal = envVal;
|
|
71368
|
+
if (key === "CODEX_HOME" || key === "CLAUDE_CONFIG_DIR" || key === "MRRLIN_API_BASE_URL") {
|
|
71369
|
+
installerVal = installerVal.trim();
|
|
71370
|
+
}
|
|
71371
|
+
if (installerVal === "") {
|
|
71372
|
+
droppedNames.push(key);
|
|
71373
|
+
} else {
|
|
71374
|
+
preservedNames.push(key);
|
|
71375
|
+
mergedEnv[key] = installerVal;
|
|
71376
|
+
}
|
|
71377
|
+
} else {
|
|
71378
|
+
const carriedVal = carriedEnv[key];
|
|
71379
|
+
if (carriedVal !== void 0) {
|
|
71380
|
+
preservedNames.push(key);
|
|
71381
|
+
mergedEnv[key] = carriedVal;
|
|
71382
|
+
}
|
|
71383
|
+
}
|
|
71384
|
+
}
|
|
71385
|
+
for (const key of CURATED_KEYS) {
|
|
71386
|
+
if (Object.hasOwn(carriedEnv, key)) continue;
|
|
71387
|
+
const envVal = depsEnv[key];
|
|
71388
|
+
if (Object.hasOwn(depsEnv, key) && envVal !== void 0) {
|
|
71389
|
+
let val = envVal;
|
|
71390
|
+
if (key === "CODEX_HOME" || key === "CLAUDE_CONFIG_DIR" || key === "MRRLIN_API_BASE_URL") {
|
|
71391
|
+
val = val.trim();
|
|
71392
|
+
}
|
|
71393
|
+
if (val !== "") {
|
|
71394
|
+
mergedEnv[key] = val;
|
|
71395
|
+
}
|
|
71396
|
+
} else {
|
|
71397
|
+
if (key === "MRRLIN_DIRECTOR_BRIDGE_LOG") {
|
|
71398
|
+
mergedEnv[key] = "1";
|
|
71399
|
+
}
|
|
71400
|
+
}
|
|
71401
|
+
}
|
|
71402
|
+
preservedNames.sort();
|
|
71403
|
+
droppedNames.sort();
|
|
71404
|
+
return { mergedEnv, preservedNames, droppedNames };
|
|
71343
71405
|
}
|
|
71344
|
-
function
|
|
71345
|
-
|
|
71346
|
-
|
|
71347
|
-
|
|
71348
|
-
|
|
71349
|
-
|
|
71350
|
-
return normalizeServiceApiTarget(apiBaseUrl, readEnvString(existing, "MRRLIN_API_ALLOW_REMOTE") === "1");
|
|
71406
|
+
function deriveMergedApiRouting(mergedEnv, invokingBridgeUrl) {
|
|
71407
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
71408
|
+
for (const k of Object.keys(mergedEnv)) {
|
|
71409
|
+
const v = mergedEnv[k];
|
|
71410
|
+
if (v !== void 0) {
|
|
71411
|
+
result[k] = v;
|
|
71351
71412
|
}
|
|
71352
|
-
|
|
71353
|
-
|
|
71413
|
+
}
|
|
71414
|
+
if (Object.hasOwn(result, "MRRLIN_API_BASE_URL")) {
|
|
71415
|
+
const rawApi = result["MRRLIN_API_BASE_URL"];
|
|
71416
|
+
if (rawApi === "") {
|
|
71417
|
+
result["MRRLIN_API_BASE_URL"] = "";
|
|
71418
|
+
} else if (rawApi !== void 0) {
|
|
71419
|
+
const retargeted = retargetRetiredApiBaseUrl(rawApi).baseUrl;
|
|
71420
|
+
result["MRRLIN_API_BASE_URL"] = retargeted;
|
|
71421
|
+
}
|
|
71422
|
+
} else {
|
|
71423
|
+
if (result["MRRLIN_STAGING"] === "1") {
|
|
71424
|
+
result["MRRLIN_API_BASE_URL"] = STAGING_API_BASE_URL;
|
|
71425
|
+
} else if (bridgeUrlImpliesStaging(invokingBridgeUrl)) {
|
|
71426
|
+
result["MRRLIN_API_BASE_URL"] = STAGING_API_BASE_URL;
|
|
71354
71427
|
}
|
|
71355
|
-
return void 0;
|
|
71356
|
-
} catch {
|
|
71357
|
-
return void 0;
|
|
71358
71428
|
}
|
|
71429
|
+
return result;
|
|
71430
|
+
}
|
|
71431
|
+
function escapeRegex2(s) {
|
|
71432
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
71359
71433
|
}
|
|
71360
|
-
function
|
|
71361
|
-
|
|
71362
|
-
|
|
71363
|
-
|
|
71364
|
-
|
|
71434
|
+
function performConfigBackup(deps, ecoPath, existingText) {
|
|
71435
|
+
try {
|
|
71436
|
+
if (!deps.listDir || !deps.writeExclusiveFile) {
|
|
71437
|
+
deps.log("Service config backup failed.");
|
|
71438
|
+
return;
|
|
71439
|
+
}
|
|
71440
|
+
const dir = import_node_path38.default.dirname(ecoPath);
|
|
71441
|
+
let files;
|
|
71442
|
+
try {
|
|
71443
|
+
files = deps.listDir(dir);
|
|
71444
|
+
} catch {
|
|
71445
|
+
deps.log("Service config backup failed.");
|
|
71446
|
+
return;
|
|
71447
|
+
}
|
|
71448
|
+
if (!files || !Array.isArray(files)) {
|
|
71449
|
+
deps.log("Service config backup failed.");
|
|
71450
|
+
return;
|
|
71451
|
+
}
|
|
71452
|
+
const base = import_node_path38.default.basename(ecoPath);
|
|
71453
|
+
const backupRegex = new RegExp(`^${escapeRegex2(base)}\\.bak-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z$`);
|
|
71454
|
+
const existingBackups = files.filter((f) => backupRegex.test(f));
|
|
71455
|
+
if (existingBackups.length >= 10) {
|
|
71456
|
+
deps.log("Service config backup failed.");
|
|
71457
|
+
return;
|
|
71458
|
+
}
|
|
71459
|
+
let now;
|
|
71460
|
+
try {
|
|
71461
|
+
now = deps.clock ? deps.clock() : /* @__PURE__ */ new Date();
|
|
71462
|
+
} catch {
|
|
71463
|
+
deps.log("Service config backup failed.");
|
|
71464
|
+
return;
|
|
71465
|
+
}
|
|
71466
|
+
let iso;
|
|
71467
|
+
try {
|
|
71468
|
+
iso = now.toISOString();
|
|
71469
|
+
} catch {
|
|
71470
|
+
deps.log("Service config backup failed.");
|
|
71471
|
+
return;
|
|
71472
|
+
}
|
|
71473
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(iso)) {
|
|
71474
|
+
deps.log("Service config backup failed.");
|
|
71475
|
+
return;
|
|
71476
|
+
}
|
|
71477
|
+
const ts = iso.replace(/:/g, "-").replace(/\./g, "-");
|
|
71478
|
+
const backupPath = `${ecoPath}.bak-${ts}`;
|
|
71479
|
+
deps.writeExclusiveFile(backupPath, existingText);
|
|
71480
|
+
} catch {
|
|
71481
|
+
deps.log("Service config backup failed.");
|
|
71365
71482
|
}
|
|
71366
|
-
return readExistingServiceApiTarget(deps, ecoPath) ?? {};
|
|
71367
71483
|
}
|
|
71368
71484
|
var SYSTEM_PATH_DIRS = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
71369
71485
|
function defaultHomeOwnerUid(home) {
|
|
@@ -71439,19 +71555,34 @@ function installService(deps) {
|
|
|
71439
71555
|
/* @__PURE__ */ new Set([...resolvedBins.map((b) => import_node_path38.default.dirname(b)), ...systemDirs])
|
|
71440
71556
|
).join(import_node_path38.default.delimiter);
|
|
71441
71557
|
const ecoPath = import_node_path38.default.join(home, ".mrrlin", "ecosystem.config.cjs");
|
|
71442
|
-
const
|
|
71558
|
+
const existingText = deps.readFile ? deps.readFile(ecoPath) : null;
|
|
71559
|
+
const parseResult = parseExistingEcosystemConfig(existingText);
|
|
71560
|
+
if (parseResult.kind === "rejected") {
|
|
71561
|
+
deps.log("Service config env carry skipped.");
|
|
71562
|
+
}
|
|
71563
|
+
if (existingText !== null && existingText !== void 0) {
|
|
71564
|
+
performConfigBackup(deps, ecoPath, existingText);
|
|
71565
|
+
}
|
|
71566
|
+
const carriedEnv = parseResult.kind === "accepted" ? parseResult.env : /* @__PURE__ */ Object.create(null);
|
|
71567
|
+
const { mergedEnv, preservedNames, droppedNames } = mergeConfigEnv(deps.env, carriedEnv);
|
|
71568
|
+
const routedEnv = deriveMergedApiRouting(mergedEnv, deps.env.MRRLIN_BRIDGE_URL);
|
|
71569
|
+
routedEnv.HOME = home;
|
|
71570
|
+
routedEnv.PATH = pathEnv;
|
|
71571
|
+
if (user !== void 0) {
|
|
71572
|
+
routedEnv.USER = user;
|
|
71573
|
+
}
|
|
71574
|
+
if (preservedNames.length > 0) {
|
|
71575
|
+
deps.log(`Service env preserved: ${preservedNames.join(", ")}.`);
|
|
71576
|
+
}
|
|
71577
|
+
if (droppedNames.length > 0) {
|
|
71578
|
+
deps.log(`Service env dropped: ${droppedNames.join(", ")}.`);
|
|
71579
|
+
}
|
|
71443
71580
|
const text = renderEcosystemConfig({
|
|
71444
71581
|
cwd: resolved.cwd,
|
|
71445
|
-
|
|
71446
|
-
user,
|
|
71447
|
-
codexHome: deps.env.CODEX_HOME?.trim() || void 0,
|
|
71448
|
-
claudeConfigDir: deps.env.CLAUDE_CONFIG_DIR?.trim() || void 0,
|
|
71449
|
-
pathEnv,
|
|
71450
|
-
apiBaseUrl: apiTarget.apiBaseUrl,
|
|
71451
|
-
apiAllowRemote: apiTarget.apiAllowRemote
|
|
71582
|
+
env: routedEnv
|
|
71452
71583
|
});
|
|
71453
71584
|
deps.writeFile(ecoPath, text);
|
|
71454
|
-
const start = deps.runPm2(["startOrReload", ecoPath]);
|
|
71585
|
+
const start = deps.runPm2(["startOrReload", ecoPath, "--update-env"]);
|
|
71455
71586
|
if (start.code !== 0) {
|
|
71456
71587
|
deps.log(`pm2 startOrReload failed (exit ${start.code}).`);
|
|
71457
71588
|
return { ok: false };
|
|
@@ -72074,6 +72205,15 @@ async function main() {
|
|
|
72074
72205
|
(0, import_node_fs25.mkdirSync)(import_node_path42.default.dirname(p), { recursive: true, mode: 448 });
|
|
72075
72206
|
(0, import_node_fs25.writeFileSync)(p, c, { mode: 384 });
|
|
72076
72207
|
},
|
|
72208
|
+
writeExclusiveFile: (p, c) => (0, import_node_fs25.writeFileSync)(p, c, { flag: "wx", mode: 384 }),
|
|
72209
|
+
listDir: (p) => {
|
|
72210
|
+
try {
|
|
72211
|
+
return (0, import_node_fs25.readdirSync)(p);
|
|
72212
|
+
} catch {
|
|
72213
|
+
return null;
|
|
72214
|
+
}
|
|
72215
|
+
},
|
|
72216
|
+
clock: () => /* @__PURE__ */ new Date(),
|
|
72077
72217
|
// Swallows every error on purpose — the only caller uses this to recover settings from the
|
|
72078
72218
|
// config it is about to overwrite, and a missing or unreadable file means "no previous
|
|
72079
72219
|
// value", never a failed install. See readExistingTelemetryDefaultProject.
|