@mrrlin-dev/mcp 0.4.108 → 0.4.109
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 +117 -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,23 @@ 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
|
+
delete env[key];
|
|
44192
|
+
else
|
|
44193
|
+
env[key] = value;
|
|
44194
|
+
}
|
|
44195
|
+
return env;
|
|
44196
|
+
}
|
|
44197
|
+
function envOption(env) {
|
|
44198
|
+
return env === void 0 ? {} : { env };
|
|
44199
|
+
}
|
|
44200
|
+
|
|
44173
44201
|
// ../../packages/agent-client/dist/providers/claude/process.js
|
|
44174
44202
|
var import_node_child_process3 = require("node:child_process");
|
|
44175
44203
|
var import_node_crypto = require("node:crypto");
|
|
@@ -44550,7 +44578,7 @@ var ClaudeAgentHandle = class {
|
|
|
44550
44578
|
appendSystemPrompt: params.baseInstructions,
|
|
44551
44579
|
wrapCommand: this.wrapCommand,
|
|
44552
44580
|
brokerSocket: this.brokerSocket,
|
|
44553
|
-
...this.childEnv
|
|
44581
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
44554
44582
|
});
|
|
44555
44583
|
this.processes.set(child.sessionId, child);
|
|
44556
44584
|
this.mappers.set(child.sessionId, new ClaudeBridgeEventMapper());
|
|
@@ -44572,7 +44600,7 @@ var ClaudeAgentHandle = class {
|
|
|
44572
44600
|
appendSystemPrompt: params.baseInstructions,
|
|
44573
44601
|
wrapCommand: this.wrapCommand,
|
|
44574
44602
|
brokerSocket: this.brokerSocket,
|
|
44575
|
-
...this.childEnv
|
|
44603
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
44576
44604
|
});
|
|
44577
44605
|
this.processes.set(threadId, child);
|
|
44578
44606
|
this.mappers.set(threadId, new ClaudeBridgeEventMapper());
|
|
@@ -45086,7 +45114,7 @@ var AgyAgentHandle = class {
|
|
|
45086
45114
|
wrapCommand: this.wrapCommand,
|
|
45087
45115
|
brokerSocket: this.brokerSocket,
|
|
45088
45116
|
disabledTools: this.disabledTools,
|
|
45089
|
-
...this.childEnv
|
|
45117
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
45090
45118
|
});
|
|
45091
45119
|
this.processes.set(child.sessionId, child);
|
|
45092
45120
|
this.mappers.set(child.sessionId, new AgyBridgeEventMapper());
|
|
@@ -45110,7 +45138,7 @@ var AgyAgentHandle = class {
|
|
|
45110
45138
|
wrapCommand: this.wrapCommand,
|
|
45111
45139
|
brokerSocket: this.brokerSocket,
|
|
45112
45140
|
disabledTools: this.disabledTools,
|
|
45113
|
-
...this.childEnv
|
|
45141
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
45114
45142
|
});
|
|
45115
45143
|
this.processes.set(threadId, child);
|
|
45116
45144
|
this.mappers.set(threadId, new AgyBridgeEventMapper());
|
|
@@ -57016,6 +57044,9 @@ var READ_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
57016
57044
|
"search_knowledge",
|
|
57017
57045
|
"search_wiki_pages",
|
|
57018
57046
|
"create_task",
|
|
57047
|
+
// propose_task only records a pending intent proposal; nothing happens until the operator
|
|
57048
|
+
// confirms it in the web UI, so it is as in-product as create_task.
|
|
57049
|
+
"propose_task",
|
|
57019
57050
|
"update_task",
|
|
57020
57051
|
"create_wiki_page",
|
|
57021
57052
|
"update_wiki_page",
|
|
@@ -57781,6 +57812,7 @@ var mcpToolNames = {
|
|
|
57781
57812
|
deleteTaskDependency: "delete_task_dependency",
|
|
57782
57813
|
createInboxItem: "create_inbox_item",
|
|
57783
57814
|
createTask: "create_task",
|
|
57815
|
+
proposeTask: "propose_task",
|
|
57784
57816
|
decideInboxItem: "decide_inbox_item",
|
|
57785
57817
|
getExecutionRun: "get_execution_run",
|
|
57786
57818
|
getProjectSchedulerPolicy: "get_project_scheduler_policy",
|
|
@@ -58403,6 +58435,22 @@ var listTasksInputSchema = projectScopedSchema.merge(mrrlinTaskListFiltersSchema
|
|
|
58403
58435
|
var getTaskInputSchema = taskScopedSchema;
|
|
58404
58436
|
var createTaskInputSchema = proposalProvenanceSchema.merge(projectScopedSchema).merge(mrrlinTaskCreateWithoutIdSchema);
|
|
58405
58437
|
var updateTaskInputSchema = taskScopedSchema.merge(mrrlinTaskUpdateSchema);
|
|
58438
|
+
var proposeTaskInputSchema = projectScopedSchema.extend({
|
|
58439
|
+
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."),
|
|
58440
|
+
title: external_exports.string().min(1).max(500),
|
|
58441
|
+
notes: external_exports.string().max(2e4).optional(),
|
|
58442
|
+
type: mrrlinTaskTypeSchema.optional(),
|
|
58443
|
+
category: external_exports.string().min(1).optional(),
|
|
58444
|
+
subcategory: external_exports.string().min(1).optional(),
|
|
58445
|
+
impact: mrrlinTaskImpactSchema.optional(),
|
|
58446
|
+
autonomyLevel: mrrlinAutonomyLevelSchema.optional(),
|
|
58447
|
+
autonomyReason: external_exports.string().min(1).max(240).optional(),
|
|
58448
|
+
autoDeploy: mrrlinAutoDeploySchema.optional(),
|
|
58449
|
+
domains: mrrlinTaskDomainsSchema.optional(),
|
|
58450
|
+
tags: external_exports.array(external_exports.string().min(1)).optional(),
|
|
58451
|
+
planId: mrrlinPlanIdSchema.optional(),
|
|
58452
|
+
specWikiPageId: mrrlinWikiPageIdSchema.optional()
|
|
58453
|
+
});
|
|
58406
58454
|
var resetDirectorThreadInputSchema = taskScopedSchema;
|
|
58407
58455
|
var archiveTaskInputSchema = taskScopedSchema;
|
|
58408
58456
|
var unarchiveTaskInputSchema = taskScopedSchema;
|
|
@@ -58540,6 +58588,7 @@ var mcpToolInputSchemas = {
|
|
|
58540
58588
|
[mcpToolNames.createWikiPage]: createWikiPageInputSchema,
|
|
58541
58589
|
[mcpToolNames.deleteTaskDependency]: deleteTaskDependencyInputSchema,
|
|
58542
58590
|
[mcpToolNames.createTask]: createTaskInputSchema,
|
|
58591
|
+
[mcpToolNames.proposeTask]: proposeTaskInputSchema,
|
|
58543
58592
|
[mcpToolNames.getExecutionRun]: getExecutionRunInputSchema,
|
|
58544
58593
|
[mcpToolNames.getProjectSchedulerPolicy]: getProjectSchedulerPolicyInputSchema,
|
|
58545
58594
|
[mcpToolNames.getSchedulerPendingTasks]: getSchedulerPendingTasksInputSchema,
|
|
@@ -58604,6 +58653,7 @@ var mcpToolOperationIds = {
|
|
|
58604
58653
|
[mcpToolNames.createWikiPage]: openApiOperationIds.createWikiPage,
|
|
58605
58654
|
[mcpToolNames.deleteTaskDependency]: openApiOperationIds.deleteTaskDependency,
|
|
58606
58655
|
[mcpToolNames.createTask]: openApiOperationIds.createTask,
|
|
58656
|
+
[mcpToolNames.proposeTask]: openApiOperationIds.createIntentProposal,
|
|
58607
58657
|
[mcpToolNames.getExecutionRun]: openApiOperationIds.getExecutionRun,
|
|
58608
58658
|
[mcpToolNames.getProjectSchedulerPolicy]: openApiOperationIds.getProjectSchedulerPolicy,
|
|
58609
58659
|
[mcpToolNames.getSchedulerPendingTasks]: openApiOperationIds.getSchedulerPendingTasks,
|
|
@@ -58658,7 +58708,8 @@ var mcpToolDescriptions = {
|
|
|
58658
58708
|
[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
58709
|
[mcpToolNames.createWikiPage]: "Create a markdown Wiki page.",
|
|
58660
58710
|
[mcpToolNames.deleteTaskDependency]: "Delete a blocked-by relationship.",
|
|
58661
|
-
[mcpToolNames.
|
|
58711
|
+
[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.",
|
|
58712
|
+
[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
58713
|
[mcpToolNames.getProject]: "Fetch a single project summary by slug.",
|
|
58663
58714
|
[mcpToolNames.getProjectSnapshot]: "Fetch the full project snapshot: GitHub binding, tasks, plans, and wiki pages.",
|
|
58664
58715
|
[mcpToolNames.getTask]: "Fetch a single task by project slug and task id.",
|
|
@@ -58903,6 +58954,7 @@ async function getAgentProviderForPanel(client, opts = {}) {
|
|
|
58903
58954
|
function createMrrlinTools(options) {
|
|
58904
58955
|
const client = createMrrlinClient(withAuth(options));
|
|
58905
58956
|
async function resolveBoundSlug() {
|
|
58957
|
+
if (process.env.MRRLIN_PROJECT_BINDING === "none") return void 0;
|
|
58906
58958
|
if (options.activeProjectSlug !== void 0) return options.activeProjectSlug;
|
|
58907
58959
|
const envSlug = process.env.MRRLIN_PROJECT_SLUG?.trim();
|
|
58908
58960
|
if (envSlug) return envSlug;
|
|
@@ -59102,10 +59154,35 @@ function createMrrlinTools(options) {
|
|
|
59102
59154
|
`Task materialization digest mismatch for proposal ${proposalId} v${proposalVersion}.`
|
|
59103
59155
|
);
|
|
59104
59156
|
}
|
|
59157
|
+
if (confirmation.materializedTaskId) {
|
|
59158
|
+
return await c.getTask(projectSlug, confirmation.materializedTaskId);
|
|
59159
|
+
}
|
|
59105
59160
|
const status = input.status ?? "todo";
|
|
59106
59161
|
return await c.createTask(projectSlug, { ...input, status });
|
|
59107
59162
|
}
|
|
59108
59163
|
),
|
|
59164
|
+
[mcpToolNames.proposeTask]: makeTool(
|
|
59165
|
+
client,
|
|
59166
|
+
mcpToolNames.proposeTask,
|
|
59167
|
+
"TASK_PROPOSE_FAILED",
|
|
59168
|
+
"Unable to propose task.",
|
|
59169
|
+
async (c, { projectSlug, kind, ...intent }) => {
|
|
59170
|
+
await checkTenantBoundary(projectSlug, "task proposal");
|
|
59171
|
+
const proposal = await c.createIntentProposal(projectSlug, {
|
|
59172
|
+
resolvedIntent: { kind: kind ?? "task", ...intent }
|
|
59173
|
+
});
|
|
59174
|
+
return {
|
|
59175
|
+
proposalId: proposal.proposalId,
|
|
59176
|
+
proposalVersion: proposal.version,
|
|
59177
|
+
proposalDigest: proposal.digest,
|
|
59178
|
+
state: proposal.state,
|
|
59179
|
+
kind: kind ?? "task",
|
|
59180
|
+
title: intent.title,
|
|
59181
|
+
awaitingOperatorConfirmation: true,
|
|
59182
|
+
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."
|
|
59183
|
+
};
|
|
59184
|
+
}
|
|
59185
|
+
),
|
|
59109
59186
|
[mcpToolNames.getProject]: makeTool(
|
|
59110
59187
|
client,
|
|
59111
59188
|
mcpToolNames.getProject,
|
|
@@ -61664,7 +61741,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
|
|
|
61664
61741
|
}
|
|
61665
61742
|
|
|
61666
61743
|
// src/_generated/version.ts
|
|
61667
|
-
var PKG_VERSION = "0.4.
|
|
61744
|
+
var PKG_VERSION = "0.4.109";
|
|
61668
61745
|
|
|
61669
61746
|
// src/receipt-signing.ts
|
|
61670
61747
|
var import_node_crypto13 = __toESM(require("node:crypto"), 1);
|
|
@@ -66359,7 +66436,7 @@ ${renderTaskStateSection(taskState)}`;
|
|
|
66359
66436
|
turnCwd = worktreePath;
|
|
66360
66437
|
useExecutor = true;
|
|
66361
66438
|
if (deps.acquireExecutorAgent) {
|
|
66362
|
-
const executorAgent = await deps.acquireExecutorAgent(worktreePath, resolvedProviderId);
|
|
66439
|
+
const executorAgent = await deps.acquireExecutorAgent(worktreePath, resolvedProviderId, projectSlug);
|
|
66363
66440
|
codex = executorAgent.handle;
|
|
66364
66441
|
disposeCodex = executorAgent.dispose;
|
|
66365
66442
|
} else {
|
|
@@ -74276,6 +74353,13 @@ function neutralCheckoutCwd(stateDir) {
|
|
|
74276
74353
|
}
|
|
74277
74354
|
return dir;
|
|
74278
74355
|
}
|
|
74356
|
+
function directorThreadEnv(projectSlug) {
|
|
74357
|
+
const slug = projectSlug ?? "";
|
|
74358
|
+
if (!slug || slug.length > 200 || /[\s\p{Cc}]/u.test(slug)) {
|
|
74359
|
+
return { MRRLIN_PROJECT_SLUG: null, MRRLIN_PROJECT_BINDING: "none" };
|
|
74360
|
+
}
|
|
74361
|
+
return { MRRLIN_PROJECT_SLUG: slug, MRRLIN_PROJECT_BINDING: null };
|
|
74362
|
+
}
|
|
74279
74363
|
function buildThreadStartParams(msg, config2, desiredModel) {
|
|
74280
74364
|
const baseInstructions = [
|
|
74281
74365
|
"You are the Mrrlin Director assistant.",
|
|
@@ -74313,10 +74397,10 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74313
74397
|
"- Every read or write of Mrrlin data \u2014 tasks, plans, wiki pages, inbox items, execution runs,",
|
|
74314
74398
|
" projects \u2014 must go through the corresponding typed MCP tool. Never use `commandExecution`,",
|
|
74315
74399
|
" `curl`, `python`, or any direct HTTP call to the Mrrlin API.",
|
|
74316
|
-
"-
|
|
74317
|
-
" `subcategory`, `impact`, `autonomyLevel`, `planId`,
|
|
74318
|
-
"
|
|
74319
|
-
" for
|
|
74400
|
+
"- New work is created through `propose_task`, one call per task: it accepts `title`, `notes`,",
|
|
74401
|
+
" `category`, `subcategory`, `impact`, `autonomyLevel`, `planId`, and more in one call. The",
|
|
74402
|
+
" operator confirms the proposal in the chat, and that confirmation creates the task \u2014 you do",
|
|
74403
|
+
" not call `create_task` for it. Do not propose then patch.",
|
|
74320
74404
|
"- `commandExecution` is for the operator's own machine and repositories \u2014 running builds, tests,",
|
|
74321
74405
|
" `git`, inspecting local files \u2014 and for public third-party web checks. It is not a transport",
|
|
74322
74406
|
" for this product's API.",
|
|
@@ -74399,11 +74483,12 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74399
74483
|
"NOT add words of your own.",
|
|
74400
74484
|
"",
|
|
74401
74485
|
"Once the operator replies and clarifies or confirms the scope (or if scope was already clear),",
|
|
74402
|
-
"you MUST
|
|
74403
|
-
"
|
|
74404
|
-
"
|
|
74405
|
-
"
|
|
74406
|
-
"
|
|
74486
|
+
"you MUST propose the tasks in the same turn: call `propose_task` once per task (`kind: 'plan'` for",
|
|
74487
|
+
"a plan) so the operator gets a confirmation card for each one immediately. Never leave the",
|
|
74488
|
+
"operator with nothing to confirm after agreeing on scope. Never claim tasks are created, queued,",
|
|
74489
|
+
"or ready before the operator confirmed them: say they are waiting for the operator's confirmation",
|
|
74490
|
+
"in the chat. Proposals bind to the operator's latest message, so propose in the same turn as the",
|
|
74491
|
+
"request \u2014 a later operator message makes an unconfirmed proposal stale.",
|
|
74407
74492
|
"When referring to created tasks or where to view them, use natural, human-friendly language with a markdown link",
|
|
74408
74493
|
"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
74494
|
"Never output raw technical URL fragments like '\u043D\u0430 /tasks' or 'on /tasks', and never use developer database",
|
|
@@ -74690,7 +74775,10 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74690
74775
|
model: desiredModel,
|
|
74691
74776
|
baseInstructions,
|
|
74692
74777
|
developerInstructions: null,
|
|
74693
|
-
ephemeral: null
|
|
74778
|
+
ephemeral: null,
|
|
74779
|
+
// Claude and Agy spawn a process per thread and every Director turn starts or resumes one,
|
|
74780
|
+
// so the turn's own project always reaches the child, including after a project switch.
|
|
74781
|
+
env: directorThreadEnv(msg.context?.projectSlug)
|
|
74694
74782
|
};
|
|
74695
74783
|
}
|
|
74696
74784
|
function readEnvInt(name, fallback) {
|
|
@@ -76778,9 +76866,12 @@ async function startDirectorBridge() {
|
|
|
76778
76866
|
// Task 1.11: providerId is the caller's own pinned/minted seat (execution-consumer.ts's
|
|
76779
76867
|
// resolvedProviderId), not resolved ambiently here — this run-scoped spawn has no business
|
|
76780
76868
|
// re-reading a setting that could have moved since the run's own seat was decided.
|
|
76781
|
-
acquireExecutorAgent: async (worktreePath, providerId) => {
|
|
76869
|
+
acquireExecutorAgent: async (worktreePath, providerId, projectSlug) => {
|
|
76782
76870
|
const executor = await startExecutorServer({
|
|
76783
76871
|
worktree: worktreePath,
|
|
76872
|
+
// The run's provider process carries exactly its own project (or none), so its Mrrlin MCP
|
|
76873
|
+
// server is bound to it and never to whatever the bridge's environment names.
|
|
76874
|
+
env: threadProcessEnv(process.env, directorThreadEnv(projectSlug)),
|
|
76784
76875
|
disabledGitHooksDir: prepareDisabledGitHooksDir(import_node_path40.default.join(config2.stateDir, "locks"), import_node_path40.default.basename(worktreePath)),
|
|
76785
76876
|
provider: providerId
|
|
76786
76877
|
});
|
|
@@ -77711,7 +77802,7 @@ function renderContextPrefix(context) {
|
|
|
77711
77802
|
}
|
|
77712
77803
|
if (context?.activeProposal) {
|
|
77713
77804
|
parts.push(
|
|
77714
|
-
`[ACTIVE PROPOSAL] Proposal ID: ${context.activeProposal.id} (version ${context.activeProposal.version}). Work
|
|
77805
|
+
`[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
77806
|
);
|
|
77716
77807
|
}
|
|
77717
77808
|
if (context?.clarifications?.length) {
|