@mrrlin-dev/mcp 0.4.108 → 0.4.110
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 +118 -26
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -37432,6 +37432,7 @@ var openApiOperationIds = {
|
|
|
37432
37432
|
listOperatorTranscriptMessages: "listOperatorTranscriptMessages",
|
|
37433
37433
|
createIntentProposal: "createIntentProposal",
|
|
37434
37434
|
getIntentProposal: "getIntentProposal",
|
|
37435
|
+
listIntentProposals: "listIntentProposals",
|
|
37435
37436
|
recordIntentClarification: "recordIntentClarification",
|
|
37436
37437
|
answerIntentClarification: "answerIntentClarification",
|
|
37437
37438
|
confirmIntentProposal: "confirmIntentProposal",
|
|
@@ -38171,13 +38172,13 @@ var mrrlinIntentProposalSchema = external_exports.object({
|
|
|
38171
38172
|
updatedAt: external_exports.string()
|
|
38172
38173
|
});
|
|
38173
38174
|
var mrrlinIntentProposalCreateSchema = external_exports.object({
|
|
38174
|
-
proposalId: external_exports.string().uuid(),
|
|
38175
|
-
version: external_exports.number().int().min(1),
|
|
38175
|
+
proposalId: external_exports.string().uuid().optional(),
|
|
38176
|
+
version: external_exports.number().int().min(1).optional(),
|
|
38176
38177
|
resolvedIntent: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
38177
|
-
digest: external_exports.string().min(1),
|
|
38178
|
+
digest: external_exports.string().min(1).optional(),
|
|
38178
38179
|
transcriptRevision: external_exports.string().optional(),
|
|
38179
|
-
expectedTranscriptRevisionNumber: external_exports.number().int().nonnegative(),
|
|
38180
|
-
messageIds: external_exports.array(external_exports.string().uuid())
|
|
38180
|
+
expectedTranscriptRevisionNumber: external_exports.number().int().nonnegative().optional(),
|
|
38181
|
+
messageIds: external_exports.array(external_exports.string().uuid()).min(1).optional()
|
|
38181
38182
|
}).strict();
|
|
38182
38183
|
var intentProposalResponseSchema = external_exports.object({
|
|
38183
38184
|
data: mrrlinIntentProposalSchema
|
|
@@ -38221,7 +38222,8 @@ var mrrlinIntentConfirmRequestSchema = external_exports.object({
|
|
|
38221
38222
|
actor: external_exports.string().min(1).optional(),
|
|
38222
38223
|
materializeParams: external_exports.object({
|
|
38223
38224
|
task: external_exports.object({
|
|
38224
|
-
id
|
|
38225
|
+
// Omitted ⇒ the API allocates the next per-project GT-N id before confirming.
|
|
38226
|
+
id: external_exports.string().min(1).optional(),
|
|
38225
38227
|
title: external_exports.string().min(1).optional(),
|
|
38226
38228
|
category: external_exports.string().optional(),
|
|
38227
38229
|
subcategory: external_exports.string().optional(),
|
|
@@ -38268,11 +38270,16 @@ var mrrlinIntentConfirmationSchema = external_exports.object({
|
|
|
38268
38270
|
digest: external_exports.string().min(1),
|
|
38269
38271
|
transcriptRevision: external_exports.string(),
|
|
38270
38272
|
transcriptRevisionNumber: external_exports.number().int().nonnegative().optional(),
|
|
38273
|
+
// The task the confirmation materialized, when it materialized one.
|
|
38274
|
+
materializedTaskId: external_exports.string().nullable().optional(),
|
|
38271
38275
|
createdAt: external_exports.string()
|
|
38272
38276
|
});
|
|
38273
38277
|
var intentConfirmationMaybeResponseSchema = external_exports.object({
|
|
38274
38278
|
data: mrrlinIntentConfirmationSchema.nullable()
|
|
38275
38279
|
});
|
|
38280
|
+
var intentProposalListResponseSchema = external_exports.object({
|
|
38281
|
+
data: external_exports.array(mrrlinIntentProposalSchema)
|
|
38282
|
+
});
|
|
38276
38283
|
|
|
38277
38284
|
// ../../packages/schemas/dist/appsumo.js
|
|
38278
38285
|
var APPSUMO_CODE_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
@@ -41647,6 +41654,10 @@ function createMrrlinClient(config2) {
|
|
|
41647
41654
|
});
|
|
41648
41655
|
return intentProposalResponseSchema.parse(body).data;
|
|
41649
41656
|
},
|
|
41657
|
+
async listIntentProposals(projectSlug) {
|
|
41658
|
+
const body = await request(`${projectPath(projectSlug)}/intent/proposals`);
|
|
41659
|
+
return intentProposalListResponseSchema.parse(body).data;
|
|
41660
|
+
},
|
|
41650
41661
|
async getIntentProposal(projectSlug, proposalId, version2) {
|
|
41651
41662
|
try {
|
|
41652
41663
|
const body = await request(`${projectPath(projectSlug)}/intent/proposals/${encodeURIComponent(proposalId)}/${encodeURIComponent(String(version2))}`);
|
|
@@ -41685,7 +41696,7 @@ function createMrrlinClient(config2) {
|
|
|
41685
41696
|
if (error51 instanceof MrrlinApiError && (error51.status === 409 || error51.status === 422)) {
|
|
41686
41697
|
try {
|
|
41687
41698
|
const parsed = JSON.parse(error51.responseBody);
|
|
41688
|
-
const maybeResult = mrrlinIntentConfirmResponseSchema.safeParse(parsed);
|
|
41699
|
+
const maybeResult = mrrlinIntentConfirmResponseSchema.safeParse(parsed?.data ?? parsed);
|
|
41689
41700
|
if (maybeResult.success)
|
|
41690
41701
|
return maybeResult.data;
|
|
41691
41702
|
} catch {
|
|
@@ -44170,6 +44181,24 @@ var CodexAgentHandle = class {
|
|
|
44170
44181
|
}
|
|
44171
44182
|
};
|
|
44172
44183
|
|
|
44184
|
+
// ../../packages/agent-client/dist/providers/thread-env.js
|
|
44185
|
+
function threadProcessEnv(childEnv, additions) {
|
|
44186
|
+
if (!additions || Object.keys(additions).length === 0)
|
|
44187
|
+
return childEnv;
|
|
44188
|
+
const env = { ...childEnv ?? process.env };
|
|
44189
|
+
for (const [key, value] of Object.entries(additions)) {
|
|
44190
|
+
if (value === null) {
|
|
44191
|
+
Reflect.deleteProperty(env, key);
|
|
44192
|
+
} else {
|
|
44193
|
+
env[key] = value;
|
|
44194
|
+
}
|
|
44195
|
+
}
|
|
44196
|
+
return env;
|
|
44197
|
+
}
|
|
44198
|
+
function envOption(env) {
|
|
44199
|
+
return env === void 0 ? {} : { env };
|
|
44200
|
+
}
|
|
44201
|
+
|
|
44173
44202
|
// ../../packages/agent-client/dist/providers/claude/process.js
|
|
44174
44203
|
var import_node_child_process3 = require("node:child_process");
|
|
44175
44204
|
var import_node_crypto = require("node:crypto");
|
|
@@ -44550,7 +44579,7 @@ var ClaudeAgentHandle = class {
|
|
|
44550
44579
|
appendSystemPrompt: params.baseInstructions,
|
|
44551
44580
|
wrapCommand: this.wrapCommand,
|
|
44552
44581
|
brokerSocket: this.brokerSocket,
|
|
44553
|
-
...this.childEnv
|
|
44582
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
44554
44583
|
});
|
|
44555
44584
|
this.processes.set(child.sessionId, child);
|
|
44556
44585
|
this.mappers.set(child.sessionId, new ClaudeBridgeEventMapper());
|
|
@@ -44572,7 +44601,7 @@ var ClaudeAgentHandle = class {
|
|
|
44572
44601
|
appendSystemPrompt: params.baseInstructions,
|
|
44573
44602
|
wrapCommand: this.wrapCommand,
|
|
44574
44603
|
brokerSocket: this.brokerSocket,
|
|
44575
|
-
...this.childEnv
|
|
44604
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
44576
44605
|
});
|
|
44577
44606
|
this.processes.set(threadId, child);
|
|
44578
44607
|
this.mappers.set(threadId, new ClaudeBridgeEventMapper());
|
|
@@ -45086,7 +45115,7 @@ var AgyAgentHandle = class {
|
|
|
45086
45115
|
wrapCommand: this.wrapCommand,
|
|
45087
45116
|
brokerSocket: this.brokerSocket,
|
|
45088
45117
|
disabledTools: this.disabledTools,
|
|
45089
|
-
...this.childEnv
|
|
45118
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
45090
45119
|
});
|
|
45091
45120
|
this.processes.set(child.sessionId, child);
|
|
45092
45121
|
this.mappers.set(child.sessionId, new AgyBridgeEventMapper());
|
|
@@ -45110,7 +45139,7 @@ var AgyAgentHandle = class {
|
|
|
45110
45139
|
wrapCommand: this.wrapCommand,
|
|
45111
45140
|
brokerSocket: this.brokerSocket,
|
|
45112
45141
|
disabledTools: this.disabledTools,
|
|
45113
|
-
...this.childEnv
|
|
45142
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
45114
45143
|
});
|
|
45115
45144
|
this.processes.set(threadId, child);
|
|
45116
45145
|
this.mappers.set(threadId, new AgyBridgeEventMapper());
|
|
@@ -57016,6 +57045,9 @@ var READ_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
57016
57045
|
"search_knowledge",
|
|
57017
57046
|
"search_wiki_pages",
|
|
57018
57047
|
"create_task",
|
|
57048
|
+
// propose_task only records a pending intent proposal; nothing happens until the operator
|
|
57049
|
+
// confirms it in the web UI, so it is as in-product as create_task.
|
|
57050
|
+
"propose_task",
|
|
57019
57051
|
"update_task",
|
|
57020
57052
|
"create_wiki_page",
|
|
57021
57053
|
"update_wiki_page",
|
|
@@ -57781,6 +57813,7 @@ var mcpToolNames = {
|
|
|
57781
57813
|
deleteTaskDependency: "delete_task_dependency",
|
|
57782
57814
|
createInboxItem: "create_inbox_item",
|
|
57783
57815
|
createTask: "create_task",
|
|
57816
|
+
proposeTask: "propose_task",
|
|
57784
57817
|
decideInboxItem: "decide_inbox_item",
|
|
57785
57818
|
getExecutionRun: "get_execution_run",
|
|
57786
57819
|
getProjectSchedulerPolicy: "get_project_scheduler_policy",
|
|
@@ -58403,6 +58436,22 @@ var listTasksInputSchema = projectScopedSchema.merge(mrrlinTaskListFiltersSchema
|
|
|
58403
58436
|
var getTaskInputSchema = taskScopedSchema;
|
|
58404
58437
|
var createTaskInputSchema = proposalProvenanceSchema.merge(projectScopedSchema).merge(mrrlinTaskCreateWithoutIdSchema);
|
|
58405
58438
|
var updateTaskInputSchema = taskScopedSchema.merge(mrrlinTaskUpdateSchema);
|
|
58439
|
+
var proposeTaskInputSchema = projectScopedSchema.extend({
|
|
58440
|
+
kind: external_exports.enum(["task", "plan"]).optional().describe("What the operator's confirmation creates. 'task' (default): the task itself. 'plan': nothing yet \u2014 call create_plan with the confirmed proposalId/proposalVersion/proposalDigest."),
|
|
58441
|
+
title: external_exports.string().min(1).max(500),
|
|
58442
|
+
notes: external_exports.string().max(2e4).optional(),
|
|
58443
|
+
type: mrrlinTaskTypeSchema.optional(),
|
|
58444
|
+
category: external_exports.string().min(1).optional(),
|
|
58445
|
+
subcategory: external_exports.string().min(1).optional(),
|
|
58446
|
+
impact: mrrlinTaskImpactSchema.optional(),
|
|
58447
|
+
autonomyLevel: mrrlinAutonomyLevelSchema.optional(),
|
|
58448
|
+
autonomyReason: external_exports.string().min(1).max(240).optional(),
|
|
58449
|
+
autoDeploy: mrrlinAutoDeploySchema.optional(),
|
|
58450
|
+
domains: mrrlinTaskDomainsSchema.optional(),
|
|
58451
|
+
tags: external_exports.array(external_exports.string().min(1)).optional(),
|
|
58452
|
+
planId: mrrlinPlanIdSchema.optional(),
|
|
58453
|
+
specWikiPageId: mrrlinWikiPageIdSchema.optional()
|
|
58454
|
+
});
|
|
58406
58455
|
var resetDirectorThreadInputSchema = taskScopedSchema;
|
|
58407
58456
|
var archiveTaskInputSchema = taskScopedSchema;
|
|
58408
58457
|
var unarchiveTaskInputSchema = taskScopedSchema;
|
|
@@ -58540,6 +58589,7 @@ var mcpToolInputSchemas = {
|
|
|
58540
58589
|
[mcpToolNames.createWikiPage]: createWikiPageInputSchema,
|
|
58541
58590
|
[mcpToolNames.deleteTaskDependency]: deleteTaskDependencyInputSchema,
|
|
58542
58591
|
[mcpToolNames.createTask]: createTaskInputSchema,
|
|
58592
|
+
[mcpToolNames.proposeTask]: proposeTaskInputSchema,
|
|
58543
58593
|
[mcpToolNames.getExecutionRun]: getExecutionRunInputSchema,
|
|
58544
58594
|
[mcpToolNames.getProjectSchedulerPolicy]: getProjectSchedulerPolicyInputSchema,
|
|
58545
58595
|
[mcpToolNames.getSchedulerPendingTasks]: getSchedulerPendingTasksInputSchema,
|
|
@@ -58604,6 +58654,7 @@ var mcpToolOperationIds = {
|
|
|
58604
58654
|
[mcpToolNames.createWikiPage]: openApiOperationIds.createWikiPage,
|
|
58605
58655
|
[mcpToolNames.deleteTaskDependency]: openApiOperationIds.deleteTaskDependency,
|
|
58606
58656
|
[mcpToolNames.createTask]: openApiOperationIds.createTask,
|
|
58657
|
+
[mcpToolNames.proposeTask]: openApiOperationIds.createIntentProposal,
|
|
58607
58658
|
[mcpToolNames.getExecutionRun]: openApiOperationIds.getExecutionRun,
|
|
58608
58659
|
[mcpToolNames.getProjectSchedulerPolicy]: openApiOperationIds.getProjectSchedulerPolicy,
|
|
58609
58660
|
[mcpToolNames.getSchedulerPendingTasks]: openApiOperationIds.getSchedulerPendingTasks,
|
|
@@ -58658,7 +58709,8 @@ var mcpToolDescriptions = {
|
|
|
58658
58709
|
[mcpToolNames.appendTaskEvent]: "Append an operator note to a task's activity timeline. Also use it as the task-linked receipt path for material immediate work that has a parent task; summarize scope, outcome/no-result, evidence or artifacts, blockers, and next action in the note body.",
|
|
58659
58710
|
[mcpToolNames.createWikiPage]: "Create a markdown Wiki page.",
|
|
58660
58711
|
[mcpToolNames.deleteTaskDependency]: "Delete a blocked-by relationship.",
|
|
58661
|
-
[mcpToolNames.
|
|
58712
|
+
[mcpToolNames.proposeTask]: "Propose a task (or plan) for the operator to confirm. This is how work gets created: a proposal does nothing on its own; the operator sees it in the Director chat and confirms it, and that confirmation creates the task. It binds to the operator's latest message in this chat, so call it right after the operator asked for the work, in the same turn. Call it once per task. Then tell the operator, in plain words, that the task is waiting for their confirmation in the chat \u2014 never say it was created. A new operator message makes an unconfirmed proposal stale; propose again if the operator still wants it. Fails with NO_OPERATOR_TRANSCRIPT when the operator has not said anything this proposal could quote.",
|
|
58713
|
+
[mcpToolNames.createTask]: "Only for a proposal the operator already confirmed: pass its proposalId, proposalVersion and proposalDigest. A confirmed task proposal has already created its task, and this returns that task; never call it to create new work \u2014 use propose_task. Create a new task in a project. Defaults to status='todo' to authorize immediate autopilot work; pass status='backlog' only if explicitly parking the task for later. 'backlog' and 'todo' are the only creatable statuses. Pass parentTaskId when spawning a follow-up task to continue work from an existing task \u2014 its operator_seed_request is inherited automatically if you don't supply your own. Domain is required UNLESS parentTaskId is supplied (a follow-up inherits its parent's domain automatically). Domain selects which reviewer roster judges the task's spec. Valid values: code, seo, marketing, content. When creating tasks for work that produces a published web page, author the work as a [code_change] task and a [page] task (with domain: 'content') linked by blocked_by. Set autoDeploy according to the publish policy: 'prod' if only meaningful once live (robots.txt, sitemap), 'dev' to stop at preview (landing page, layout), or 'off' if the repo is not the operator's own.",
|
|
58662
58714
|
[mcpToolNames.getProject]: "Fetch a single project summary by slug.",
|
|
58663
58715
|
[mcpToolNames.getProjectSnapshot]: "Fetch the full project snapshot: GitHub binding, tasks, plans, and wiki pages.",
|
|
58664
58716
|
[mcpToolNames.getTask]: "Fetch a single task by project slug and task id.",
|
|
@@ -58903,6 +58955,7 @@ async function getAgentProviderForPanel(client, opts = {}) {
|
|
|
58903
58955
|
function createMrrlinTools(options) {
|
|
58904
58956
|
const client = createMrrlinClient(withAuth(options));
|
|
58905
58957
|
async function resolveBoundSlug() {
|
|
58958
|
+
if (process.env.MRRLIN_PROJECT_BINDING === "none") return void 0;
|
|
58906
58959
|
if (options.activeProjectSlug !== void 0) return options.activeProjectSlug;
|
|
58907
58960
|
const envSlug = process.env.MRRLIN_PROJECT_SLUG?.trim();
|
|
58908
58961
|
if (envSlug) return envSlug;
|
|
@@ -59102,10 +59155,35 @@ function createMrrlinTools(options) {
|
|
|
59102
59155
|
`Task materialization digest mismatch for proposal ${proposalId} v${proposalVersion}.`
|
|
59103
59156
|
);
|
|
59104
59157
|
}
|
|
59158
|
+
if (confirmation.materializedTaskId) {
|
|
59159
|
+
return await c.getTask(projectSlug, confirmation.materializedTaskId);
|
|
59160
|
+
}
|
|
59105
59161
|
const status = input.status ?? "todo";
|
|
59106
59162
|
return await c.createTask(projectSlug, { ...input, status });
|
|
59107
59163
|
}
|
|
59108
59164
|
),
|
|
59165
|
+
[mcpToolNames.proposeTask]: makeTool(
|
|
59166
|
+
client,
|
|
59167
|
+
mcpToolNames.proposeTask,
|
|
59168
|
+
"TASK_PROPOSE_FAILED",
|
|
59169
|
+
"Unable to propose task.",
|
|
59170
|
+
async (c, { projectSlug, kind, ...intent }) => {
|
|
59171
|
+
await checkTenantBoundary(projectSlug, "task proposal");
|
|
59172
|
+
const proposal = await c.createIntentProposal(projectSlug, {
|
|
59173
|
+
resolvedIntent: { kind: kind ?? "task", ...intent }
|
|
59174
|
+
});
|
|
59175
|
+
return {
|
|
59176
|
+
proposalId: proposal.proposalId,
|
|
59177
|
+
proposalVersion: proposal.version,
|
|
59178
|
+
proposalDigest: proposal.digest,
|
|
59179
|
+
state: proposal.state,
|
|
59180
|
+
kind: kind ?? "task",
|
|
59181
|
+
title: intent.title,
|
|
59182
|
+
awaitingOperatorConfirmation: true,
|
|
59183
|
+
next: (kind ?? "task") === "task" ? "Tell the operator the task is waiting for their confirmation in the chat. Their confirmation creates it; do not call create_task." : "Tell the operator the plan is waiting for their confirmation in the chat. After they confirm, call create_plan with proposalId, proposalVersion and proposalDigest."
|
|
59184
|
+
};
|
|
59185
|
+
}
|
|
59186
|
+
),
|
|
59109
59187
|
[mcpToolNames.getProject]: makeTool(
|
|
59110
59188
|
client,
|
|
59111
59189
|
mcpToolNames.getProject,
|
|
@@ -61664,7 +61742,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
|
|
|
61664
61742
|
}
|
|
61665
61743
|
|
|
61666
61744
|
// src/_generated/version.ts
|
|
61667
|
-
var PKG_VERSION = "0.4.
|
|
61745
|
+
var PKG_VERSION = "0.4.110";
|
|
61668
61746
|
|
|
61669
61747
|
// src/receipt-signing.ts
|
|
61670
61748
|
var import_node_crypto13 = __toESM(require("node:crypto"), 1);
|
|
@@ -66359,7 +66437,7 @@ ${renderTaskStateSection(taskState)}`;
|
|
|
66359
66437
|
turnCwd = worktreePath;
|
|
66360
66438
|
useExecutor = true;
|
|
66361
66439
|
if (deps.acquireExecutorAgent) {
|
|
66362
|
-
const executorAgent = await deps.acquireExecutorAgent(worktreePath, resolvedProviderId);
|
|
66440
|
+
const executorAgent = await deps.acquireExecutorAgent(worktreePath, resolvedProviderId, projectSlug);
|
|
66363
66441
|
codex = executorAgent.handle;
|
|
66364
66442
|
disposeCodex = executorAgent.dispose;
|
|
66365
66443
|
} else {
|
|
@@ -74276,6 +74354,13 @@ function neutralCheckoutCwd(stateDir) {
|
|
|
74276
74354
|
}
|
|
74277
74355
|
return dir;
|
|
74278
74356
|
}
|
|
74357
|
+
function directorThreadEnv(projectSlug) {
|
|
74358
|
+
const slug = projectSlug ?? "";
|
|
74359
|
+
if (!slug || slug.length > 200 || /[\s\p{Cc}]/u.test(slug)) {
|
|
74360
|
+
return { MRRLIN_PROJECT_SLUG: null, MRRLIN_PROJECT_BINDING: "none" };
|
|
74361
|
+
}
|
|
74362
|
+
return { MRRLIN_PROJECT_SLUG: slug, MRRLIN_PROJECT_BINDING: null };
|
|
74363
|
+
}
|
|
74279
74364
|
function buildThreadStartParams(msg, config2, desiredModel) {
|
|
74280
74365
|
const baseInstructions = [
|
|
74281
74366
|
"You are the Mrrlin Director assistant.",
|
|
@@ -74313,10 +74398,10 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74313
74398
|
"- Every read or write of Mrrlin data \u2014 tasks, plans, wiki pages, inbox items, execution runs,",
|
|
74314
74399
|
" projects \u2014 must go through the corresponding typed MCP tool. Never use `commandExecution`,",
|
|
74315
74400
|
" `curl`, `python`, or any direct HTTP call to the Mrrlin API.",
|
|
74316
|
-
"-
|
|
74317
|
-
" `subcategory`, `impact`, `autonomyLevel`, `planId`,
|
|
74318
|
-
"
|
|
74319
|
-
" for
|
|
74401
|
+
"- New work is created through `propose_task`, one call per task: it accepts `title`, `notes`,",
|
|
74402
|
+
" `category`, `subcategory`, `impact`, `autonomyLevel`, `planId`, and more in one call. The",
|
|
74403
|
+
" operator confirms the proposal in the chat, and that confirmation creates the task \u2014 you do",
|
|
74404
|
+
" not call `create_task` for it. Do not propose then patch.",
|
|
74320
74405
|
"- `commandExecution` is for the operator's own machine and repositories \u2014 running builds, tests,",
|
|
74321
74406
|
" `git`, inspecting local files \u2014 and for public third-party web checks. It is not a transport",
|
|
74322
74407
|
" for this product's API.",
|
|
@@ -74399,11 +74484,12 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74399
74484
|
"NOT add words of your own.",
|
|
74400
74485
|
"",
|
|
74401
74486
|
"Once the operator replies and clarifies or confirms the scope (or if scope was already clear),",
|
|
74402
|
-
"you MUST
|
|
74403
|
-
"
|
|
74404
|
-
"
|
|
74405
|
-
"
|
|
74406
|
-
"
|
|
74487
|
+
"you MUST propose the tasks in the same turn: call `propose_task` once per task (`kind: 'plan'` for",
|
|
74488
|
+
"a plan) so the operator gets a confirmation card for each one immediately. Never leave the",
|
|
74489
|
+
"operator with nothing to confirm after agreeing on scope. Never claim tasks are created, queued,",
|
|
74490
|
+
"or ready before the operator confirmed them: say they are waiting for the operator's confirmation",
|
|
74491
|
+
"in the chat. Proposals bind to the operator's latest message, so propose in the same turn as the",
|
|
74492
|
+
"request \u2014 a later operator message makes an unconfirmed proposal stale.",
|
|
74407
74493
|
"When referring to created tasks or where to view them, use natural, human-friendly language with a markdown link",
|
|
74408
74494
|
"to the Tasks page (e.g. 'on the [Tasks page](/tasks)', '[Tasks board](/tasks)', or in Ukrainian '\u043D\u0430 [\u0441\u0442\u043E\u0440\u0456\u043D\u0446\u0456 \u0437\u0430\u0434\u0430\u0447](/tasks)').",
|
|
74409
74495
|
"Never output raw technical URL fragments like '\u043D\u0430 /tasks' or 'on /tasks', and never use developer database",
|
|
@@ -74690,7 +74776,10 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74690
74776
|
model: desiredModel,
|
|
74691
74777
|
baseInstructions,
|
|
74692
74778
|
developerInstructions: null,
|
|
74693
|
-
ephemeral: null
|
|
74779
|
+
ephemeral: null,
|
|
74780
|
+
// Claude and Agy spawn a process per thread and every Director turn starts or resumes one,
|
|
74781
|
+
// so the turn's own project always reaches the child, including after a project switch.
|
|
74782
|
+
env: directorThreadEnv(msg.context?.projectSlug)
|
|
74694
74783
|
};
|
|
74695
74784
|
}
|
|
74696
74785
|
function readEnvInt(name, fallback) {
|
|
@@ -76778,9 +76867,12 @@ async function startDirectorBridge() {
|
|
|
76778
76867
|
// Task 1.11: providerId is the caller's own pinned/minted seat (execution-consumer.ts's
|
|
76779
76868
|
// resolvedProviderId), not resolved ambiently here — this run-scoped spawn has no business
|
|
76780
76869
|
// re-reading a setting that could have moved since the run's own seat was decided.
|
|
76781
|
-
acquireExecutorAgent: async (worktreePath, providerId) => {
|
|
76870
|
+
acquireExecutorAgent: async (worktreePath, providerId, projectSlug) => {
|
|
76782
76871
|
const executor = await startExecutorServer({
|
|
76783
76872
|
worktree: worktreePath,
|
|
76873
|
+
// The run's provider process carries exactly its own project (or none), so its Mrrlin MCP
|
|
76874
|
+
// server is bound to it and never to whatever the bridge's environment names.
|
|
76875
|
+
env: threadProcessEnv(process.env, directorThreadEnv(projectSlug)),
|
|
76784
76876
|
disabledGitHooksDir: prepareDisabledGitHooksDir(import_node_path40.default.join(config2.stateDir, "locks"), import_node_path40.default.basename(worktreePath)),
|
|
76785
76877
|
provider: providerId
|
|
76786
76878
|
});
|
|
@@ -77711,7 +77803,7 @@ function renderContextPrefix(context) {
|
|
|
77711
77803
|
}
|
|
77712
77804
|
if (context?.activeProposal) {
|
|
77713
77805
|
parts.push(
|
|
77714
|
-
`[ACTIVE PROPOSAL] Proposal ID: ${context.activeProposal.id} (version ${context.activeProposal.version}). Work
|
|
77806
|
+
`[ACTIVE PROPOSAL] Proposal ID: ${context.activeProposal.id} (version ${context.activeProposal.version}). Work is created only by the operator confirming a proposal in the chat; propose new work with propose_task. create_plan, and create_task for an already-confirmed proposal, need its proposalId, proposalVersion, and proposalDigest.`
|
|
77715
77807
|
);
|
|
77716
77808
|
}
|
|
77717
77809
|
if (context?.clarifications?.length) {
|