@myagentroam/node 0.9.115 → 0.9.117

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.
@@ -5,7 +5,7 @@ import { basename, join, resolve } from 'node:path';
5
5
  import { forEachJsonlRecord, listJsonlFiles, mapConcurrent, readJsonlBackwardWindow, readJsonlFileAnchor, readJsonlWindow } from './native-jsonl-reader.js';
6
6
  import { nodeLog } from './operational.js';
7
7
  import { stripClaudePlanTag } from './runner-command-engine.js';
8
- import { stripMissionStartPrompt } from './service/mission-runtime.js';
8
+ import { stripGoalStartPrompt } from './service/goal-runtime.js';
9
9
  import { parseCodexComposerImageMarkers } from './runner/codex/composer-image-markers.js';
10
10
  const DISCOVERY_READ_BYTES = 32 * 1024;
11
11
  const TRANSCRIPT_HEADER_READ_BYTES = 32 * 1024;
@@ -490,7 +490,7 @@ async function readTranscript(path, runner, byteLimit, page, targetLines = Numbe
490
490
  return undefined;
491
491
  const title = items.find((item) => item.kind === 'message' && item.role === 'USER')?.text;
492
492
  // Tagged Plan Mode instruction labels do not form a session title.
493
- const strippedTitle = title === undefined ? undefined : stripClaudePlanTag(stripMissionStartPrompt(title));
493
+ const strippedTitle = title === undefined ? undefined : stripClaudePlanTag(stripGoalStartPrompt(title));
494
494
  return {
495
495
  runner,
496
496
  externalSessionId: id ?? basename(path, '.jsonl'),
@@ -169,7 +169,7 @@ function resolvedMcpServers(raw, secrets) {
169
169
  const record = value;
170
170
  if (typeof record['serverName'] !== 'string' || record['enabled'] !== true)
171
171
  continue;
172
- if (record['__marMission'] === true &&
172
+ if (record['__marGoal'] === true &&
173
173
  typeof record['command'] === 'string' &&
174
174
  Array.isArray(record['args']) &&
175
175
  record['args'].every((value) => typeof value === 'string') &&
@@ -183,8 +183,8 @@ function resolvedMcpServers(raw, secrets) {
183
183
  command: record['command'],
184
184
  args: record['args'],
185
185
  environment: {
186
- MAR_MISSION_MCP_ENDPOINT: record['endpoint'],
187
- MAR_MISSION_MCP_TOKEN: secrets[record['secretName']]
186
+ MAR_GOAL_MCP_ENDPOINT: record['endpoint'],
187
+ MAR_GOAL_MCP_TOKEN: secrets[record['secretName']]
188
188
  }
189
189
  });
190
190
  continue;
@@ -1,6 +1,6 @@
1
1
  import { parseCodexComposerImageMarkers } from './composer-image-markers.js';
2
2
  import { normalizeCodexTool } from './tool-normalizer.js';
3
- import { stripMissionStartPrompt } from '../../service/mission-runtime.js';
3
+ import { stripGoalStartPrompt } from '../../service/goal-runtime.js';
4
4
  const MAX_COMPOSER_ATTACHMENT_BYTES = 5 * 1024 * 1024;
5
5
  const MAX_COMPOSER_ATTACHMENTS_BYTES = 10 * 1024 * 1024;
6
6
  const MAX_ASSISTANT_MESSAGE_CHARACTERS = 64 * 1024;
@@ -355,7 +355,7 @@ export function codexOfficialItem(session, nativeTurnId, value, turnSequence, it
355
355
  completedAt
356
356
  };
357
357
  if (value.type === 'userMessage') {
358
- const text = stripMissionStartPrompt(codexContentText(value.content));
358
+ const text = stripGoalStartPrompt(codexContentText(value.content));
359
359
  return text.length === 0
360
360
  ? undefined
361
361
  : {
@@ -158,8 +158,8 @@ export class CodexManagedRunController {
158
158
  }
159
159
  if (notification.requestId !== undefined &&
160
160
  notification.method === 'mcpServer/elicitation/request' &&
161
- activeRun.missionMcp === true &&
162
- params.serverName === 'myagentroam_mission' &&
161
+ activeRun.goalMcp === true &&
162
+ params.serverName === 'myagentroam_goal' &&
163
163
  isPlainRecord(params._meta) &&
164
164
  params._meta.codex_approval_kind === 'mcp_tool_call') {
165
165
  this.runner.respond(notification.requestId, {
@@ -431,7 +431,7 @@ export class CodexManagedRunController {
431
431
  sessionId,
432
432
  threadId,
433
433
  cwd,
434
- missionMcp: hasMissionMcp(payload.mcpServers)
434
+ goalMcp: hasGoalMcp(payload.mcpServers)
435
435
  });
436
436
  turnResult = await this.runner.startTurn(threadId, input, cwd, turnConfiguration, materializedAttachments);
437
437
  break;
@@ -457,7 +457,7 @@ export class CodexManagedRunController {
457
457
  threadId,
458
458
  turnId,
459
459
  cwd,
460
- missionMcp: hasMissionMcp(payload.mcpServers)
460
+ goalMcp: hasGoalMcp(payload.mcpServers)
461
461
  });
462
462
  this.runner.execution.managedTurns.set(turnId, { sessionId: publicSessionId, runId });
463
463
  if (this.host.runStatus(runId) === 'CANCELLING') {
@@ -489,6 +489,6 @@ export class CodexManagedRunController {
489
489
  });
490
490
  }
491
491
  }
492
- function hasMissionMcp(value) {
493
- return isPlainRecord(value) && isPlainRecord(value.myagentroam_mission);
492
+ function hasGoalMcp(value) {
493
+ return isPlainRecord(value) && isPlainRecord(value.myagentroam_goal);
494
494
  }
@@ -1,5 +1,5 @@
1
1
  import { MarAgentConversationNormalizer } from './conversation-normalizer.js';
2
- import { publicMissionHistoryText } from '../../service/mission-runtime.js';
2
+ import { publicGoalHistoryText } from '../../service/goal-runtime.js';
3
3
  export function projectMarAgentHistory(session, entries, options = {}) {
4
4
  const turns = new Map();
5
5
  const normalizer = new MarAgentConversationNormalizer();
@@ -47,7 +47,7 @@ export function projectMarAgentHistory(session, entries, options = {}) {
47
47
  const registeredImages = images === undefined ? [] : (options.registerInputImages?.(entry) ?? []);
48
48
  replace(turn, historyItem(session, turn, id, 'user_message', 'COMPLETED', {
49
49
  clientMessageId: entry.clientMessageId ?? null,
50
- text: publicMissionHistoryText(entry.text),
50
+ text: publicGoalHistoryText(entry.text),
51
51
  contexts: [],
52
52
  delivery: 'ACCEPTED',
53
53
  ...(images?.length
@@ -130,12 +130,12 @@ export class MarAgentRunner extends AbstractRunner {
130
130
  reasonCode: null
131
131
  },
132
132
  {
133
- id: 'mission',
133
+ id: 'goal',
134
134
  runner: 'mar-agent',
135
- label: '/mission',
136
- stateLabel: 'Mission',
137
- description: 'Enter persistent Mission mode.',
138
- inputHint: '/mission',
135
+ label: '/goal',
136
+ stateLabel: 'Goal',
137
+ description: 'Enter persistent Goal mode.',
138
+ inputHint: '/goal',
139
139
  source: 'MAR_RUNTIME',
140
140
  interaction: 'TOGGLE',
141
141
  available: true,
@@ -1,5 +1,5 @@
1
1
  import { boundedConversationItemId, compactRunnerText } from '../codex/conversation-parser.js';
2
- import { stripMissionStartPrompt } from '../../service/mission-runtime.js';
2
+ import { stripGoalStartPrompt } from '../../service/goal-runtime.js';
3
3
  import { normalizeOpenCodeTool } from './tool-normalizer.js';
4
4
  export function openCodeConversationPage(session, messages, input, managedTurn) {
5
5
  const records = messages.flatMap((value) => {
@@ -49,9 +49,9 @@ function openCodeTurn(session, user, userParts, assistants, sequence, managed) {
49
49
  const localUser = managed?.items.find((item) => item.kind === 'user_message');
50
50
  if (localUser !== undefined)
51
51
  items.push({ ...localUser, turnId: managed.id });
52
- else if (stripMissionStartPrompt(userText).length > 0)
52
+ else if (stripGoalStartPrompt(userText).length > 0)
53
53
  items.push(item(session, nativeTurnId, `user-${nativeTurnId}`, 'user_message', 'COMPLETED', {
54
- text: compactRunnerText(stripMissionStartPrompt(userText), 20_000),
54
+ text: compactRunnerText(stripGoalStartPrompt(userText), 20_000),
55
55
  attachments: []
56
56
  }, startedAt, startedAt, sequence));
57
57
  for (const part of compactionParts) {
@@ -4,6 +4,7 @@ import { declaredRunnerProfiles } from '../runner-profiles.js';
4
4
  import { AbstractRunner } from './abstract-runner.js';
5
5
  import { isWithinWorkspace } from './codex/conversation-parser.js';
6
6
  import { createHash } from 'node:crypto';
7
+ import { homedir } from 'node:os';
7
8
  import { openCodeConversationPage } from './opencode/conversation-parser.js';
8
9
  import { nodeLog } from '../operational.js';
9
10
  const PROFILE_ENTRY_TTL_MS = 30 * 60_000;
@@ -12,9 +13,8 @@ export class OpenCodeRunner extends AbstractRunner {
12
13
  clientFactory;
13
14
  name = 'opencode';
14
15
  discoveryScope = 'WORKSPACE_REQUIRED';
15
- modelsByWorkspace = new Map();
16
- contextLimitsByWorkspace = new Map();
17
- profileTimersByWorkspace = new Map();
16
+ contextLimits = new Map();
17
+ contextLimitsExpiresAt = 0;
18
18
  profileCache = new Map();
19
19
  profileRefreshes = new Map();
20
20
  execution = new Map();
@@ -34,11 +34,11 @@ export class OpenCodeRunner extends AbstractRunner {
34
34
  }).find((profile) => profile.runner === this.name);
35
35
  return { ...base, models: [] };
36
36
  }
37
- async refreshProfile(capabilities, workspace, environment = {}) {
38
- if (capabilities.openCode?.available !== true || workspace === undefined) {
37
+ async refreshProfile(capabilities, _workspace, environment = {}) {
38
+ if (capabilities.openCode?.available !== true) {
39
39
  return this.profile(capabilities);
40
40
  }
41
- const cacheKey = this.profileCacheKey(workspace.path, environment);
41
+ const cacheKey = this.environmentFingerprint(environment);
42
42
  const now = Date.now();
43
43
  for (const [key, entry] of this.profileCache)
44
44
  if (entry.expiresAt <= now)
@@ -46,46 +46,42 @@ export class OpenCodeRunner extends AbstractRunner {
46
46
  const cached = this.profileCache.get(cacheKey);
47
47
  if (cached !== undefined) {
48
48
  nodeLog('runner.opencode.profile.cache-hit', {
49
- workspaceId: workspace.id,
50
49
  models: cached.models.length,
51
50
  remainingTtlMs: cached.expiresAt - now
52
51
  });
53
- this.modelsByWorkspace.set(workspace.path, cached.models);
54
- this.contextLimitsByWorkspace.set(workspace.path, cached.contextLimits);
55
- this.scheduleProfileExpiry(workspace.path);
52
+ this.contextLimits = cached.contextLimits;
53
+ this.contextLimitsExpiresAt = cached.expiresAt;
56
54
  return { ...this.profile(capabilities), models: cached.models };
57
55
  }
58
56
  const current = this.profileRefreshes.get(cacheKey);
59
57
  if (current !== undefined) {
60
- nodeLog('runner.opencode.profile.single-flight-joined', { workspaceId: workspace.id });
58
+ nodeLog('runner.opencode.profile.single-flight-joined', {});
61
59
  return current;
62
60
  }
63
- const refresh = this.fetchProfile(capabilities, workspace, environment, cacheKey).finally(() => {
61
+ const refresh = this.fetchProfile(capabilities, environment, cacheKey).finally(() => {
64
62
  if (this.profileRefreshes.get(cacheKey) === refresh)
65
63
  this.profileRefreshes.delete(cacheKey);
66
64
  });
67
65
  this.profileRefreshes.set(cacheKey, refresh);
68
66
  return refresh;
69
67
  }
70
- async fetchProfile(capabilities, workspace, environment, cacheKey) {
68
+ async fetchProfile(capabilities, environment, cacheKey) {
71
69
  const client = this.managedClient(environment);
72
70
  const startedAt = performance.now();
73
71
  try {
74
- const catalog = await client.providers(workspace.path);
72
+ const catalog = await client.providers(homedir());
75
73
  const models = openCodeProfileModels(catalog);
76
74
  const contextLimits = openCodeContextLimits(catalog);
77
- this.modelsByWorkspace.set(workspace.path, models);
78
- this.contextLimitsByWorkspace.set(workspace.path, contextLimits);
75
+ const expiresAt = Date.now() + PROFILE_ENTRY_TTL_MS;
76
+ this.contextLimits = contextLimits;
77
+ this.contextLimitsExpiresAt = expiresAt;
79
78
  this.profileCache.set(cacheKey, {
80
- expiresAt: Date.now() + PROFILE_ENTRY_TTL_MS,
81
- workspacePath: workspace.path,
82
- environmentFingerprint: this.environmentFingerprint(environment),
79
+ expiresAt,
80
+ environmentFingerprint: cacheKey,
83
81
  models,
84
82
  contextLimits
85
83
  });
86
- this.scheduleProfileExpiry(workspace.path);
87
84
  nodeLog('runner.opencode.profile.providers.completed', {
88
- workspaceId: workspace.id,
89
85
  models: models.length,
90
86
  durationMs: Math.round(performance.now() - startedAt)
91
87
  });
@@ -93,7 +89,6 @@ export class OpenCodeRunner extends AbstractRunner {
93
89
  }
94
90
  catch {
95
91
  nodeLog('runner.opencode.profile.providers.failed', {
96
- workspaceId: workspace.id,
97
92
  durationMs: Math.round(performance.now() - startedAt)
98
93
  });
99
94
  }
@@ -102,11 +97,6 @@ export class OpenCodeRunner extends AbstractRunner {
102
97
  }
103
98
  return this.profile(capabilities);
104
99
  }
105
- profileCacheKey(workspacePath, environment) {
106
- return createHash('sha256')
107
- .update(JSON.stringify({ workspacePath, environment: this.environmentFingerprint(environment) }))
108
- .digest('hex');
109
- }
110
100
  environmentFingerprint(environment) {
111
101
  const entries = Object.entries(environment).sort(([left], [right]) => left.localeCompare(right));
112
102
  return createHash('sha256').update(JSON.stringify(entries)).digest('hex');
@@ -125,18 +115,18 @@ export class OpenCodeRunner extends AbstractRunner {
125
115
  openCode: { available: true }
126
116
  });
127
117
  }
128
- supportsConfiguration(configuration, workspace, environment = {}) {
118
+ supportsConfiguration(configuration, _workspace, environment = {}) {
129
119
  if (configuration.runner !== this.name)
130
120
  return false;
131
- const models = this.cachedModels(workspace, environment);
121
+ const models = this.cachedModels(environment);
132
122
  const model = models.find((candidate) => candidate.id === configuration.model);
133
123
  return (model !== undefined &&
134
124
  (model.supportedEfforts.length === 0 ||
135
125
  model.supportedEfforts.includes(configuration.effort)) &&
136
126
  this.profileForValidation().accessOptions.some((candidate) => candidate.id === configuration.access));
137
127
  }
138
- defaultConfiguration(workspace, environment = {}) {
139
- const model = this.cachedModels(workspace, environment)[0];
128
+ defaultConfiguration(_workspace, environment = {}) {
129
+ const model = this.cachedModels(environment)[0];
140
130
  return {
141
131
  runner: this.name,
142
132
  model: model?.id ?? '',
@@ -144,13 +134,11 @@ export class OpenCodeRunner extends AbstractRunner {
144
134
  access: 'default'
145
135
  };
146
136
  }
147
- cachedModels(workspace, environment) {
137
+ cachedModels(environment) {
148
138
  const fingerprint = this.environmentFingerprint(environment);
149
139
  const now = Date.now();
150
140
  return [...this.profileCache.values()]
151
- .filter((entry) => entry.expiresAt > now &&
152
- entry.environmentFingerprint === fingerprint &&
153
- (workspace === undefined || entry.workspacePath === workspace.path))
141
+ .filter((entry) => entry.expiresAt > now && entry.environmentFingerprint === fingerprint)
154
142
  .flatMap((entry) => entry.models);
155
143
  }
156
144
  mcpConfiguration(raw, secrets) {
@@ -306,24 +294,20 @@ export class OpenCodeRunner extends AbstractRunner {
306
294
  const cache = object(tokens?.cache);
307
295
  const usedTokens = positiveNumber(tokens?.input) + positiveNumber(cache?.read);
308
296
  const modelId = provider !== undefined && model !== undefined ? `${provider}/${model}` : session.model;
309
- const limits = [...this.contextLimitsByWorkspace].find(([workspacePath]) => isWithinWorkspace(session.cwd, workspacePath))?.[1];
310
- const maxTokens = modelId === null ? undefined : limits?.get(modelId);
311
- return maxTokens === undefined || usedTokens <= 0
312
- ? undefined
313
- : { model: modelId, usedTokens, maxTokens };
297
+ if (modelId === null || usedTokens <= 0)
298
+ return undefined;
299
+ const maxTokens = Date.now() >= this.contextLimitsExpiresAt ? undefined : this.contextLimits.get(modelId);
300
+ return maxTokens === undefined ? undefined : { model: modelId, usedTokens, maxTokens };
314
301
  }
315
302
  async stop() {
316
303
  for (const execution of this.execution.values())
317
304
  execution.abort.abort();
318
305
  this.execution.clear();
319
306
  this.managedTurns.clear();
320
- for (const timer of this.profileTimersByWorkspace.values())
321
- clearTimeout(timer);
322
- this.profileTimersByWorkspace.clear();
323
307
  this.profileCache.clear();
324
308
  this.profileRefreshes.clear();
325
- this.modelsByWorkspace.clear();
326
- this.contextLimitsByWorkspace.clear();
309
+ this.contextLimits = new Map();
310
+ this.contextLimitsExpiresAt = 0;
327
311
  const stopping = [
328
312
  this.client.stop(),
329
313
  ...[...this.environmentClients.values()].map(({ client }) => client.stop()),
@@ -333,22 +317,6 @@ export class OpenCodeRunner extends AbstractRunner {
333
317
  await Promise.allSettled(stopping);
334
318
  this.stoppingClients.clear();
335
319
  }
336
- scheduleProfileExpiry(workspacePath) {
337
- this.clearProfileTimer(workspacePath);
338
- const timer = setTimeout(() => {
339
- this.profileTimersByWorkspace.delete(workspacePath);
340
- this.modelsByWorkspace.delete(workspacePath);
341
- this.contextLimitsByWorkspace.delete(workspacePath);
342
- }, PROFILE_ENTRY_TTL_MS);
343
- timer.unref();
344
- this.profileTimersByWorkspace.set(workspacePath, timer);
345
- }
346
- clearProfileTimer(workspacePath) {
347
- const timer = this.profileTimersByWorkspace.get(workspacePath);
348
- if (timer !== undefined)
349
- clearTimeout(timer);
350
- this.profileTimersByWorkspace.delete(workspacePath);
351
- }
352
320
  managedClient(environment, isolationKey) {
353
321
  const entries = Object.entries(environment).sort(([left], [right]) => left.localeCompare(right));
354
322
  if (entries.length === 0 && isolationKey === undefined)
@@ -39,7 +39,7 @@ export function parseCommandInvocation(definition, input) {
39
39
  export class CommandStateStore {
40
40
  states = new Map();
41
41
  list(sessionId) {
42
- return [...(this.states.get(sessionId)?.values() ?? [])].filter((state) => state.active || state.commandId === 'mission');
42
+ return [...(this.states.get(sessionId)?.values() ?? [])].filter((state) => state.active || state.commandId === 'goal');
43
43
  }
44
44
  set(sessionId, state) {
45
45
  const values = this.states.get(sessionId) ?? new Map();
@@ -1,7 +1,7 @@
1
1
  const COMMON_COMMAND_DESCRIPTIONS = {
2
2
  compact: 'Compact the current session context.',
3
3
  plan: 'Toggle collaborative Plan Mode.',
4
- mission: 'Enter persistent Mission mode.'
4
+ goal: 'Enter persistent Goal mode.'
5
5
  };
6
6
  const CLAUDE_MODEL_ENVIRONMENT = {
7
7
  opus: 'ANTHROPIC_DEFAULT_OPUS_MODEL',
@@ -298,13 +298,13 @@ function validModelName(value) {
298
298
  : undefined;
299
299
  }
300
300
  function withCapabilities(profile, available) {
301
- const mission = {
302
- id: 'mission',
301
+ const goal = {
302
+ id: 'goal',
303
303
  runner: profile.runner,
304
- label: '/mission',
305
- stateLabel: 'Mission',
306
- description: COMMON_COMMAND_DESCRIPTIONS.mission,
307
- inputHint: '/mission',
304
+ label: '/goal',
305
+ stateLabel: 'Goal',
306
+ description: COMMON_COMMAND_DESCRIPTIONS.goal,
307
+ inputHint: '/goal',
308
308
  source: 'MAR_RUNTIME',
309
309
  interaction: 'TOGGLE',
310
310
  available,
@@ -314,7 +314,7 @@ function withCapabilities(profile, available) {
314
314
  ...profile,
315
315
  commands: [
316
316
  ...profile.commands.map((command) => available ? command : { ...command, available: false, reasonCode: 'RUNNER_UNAVAILABLE' }),
317
- mission
317
+ goal
318
318
  ],
319
319
  capabilities: available
320
320
  ? ['history.read', 'events.live', 'turn.start', 'turn.queue', 'turn.interrupt']
@@ -1041,7 +1041,7 @@ export class NodeRuntimeState {
1041
1041
  const clientMessageId = isRecord(payload) && typeof payload.clientMessageId === 'string'
1042
1042
  ? payload.clientMessageId
1043
1043
  : undefined;
1044
- const userMessage = clientMessageId?.startsWith('mission:')
1044
+ const userMessage = clientMessageId?.startsWith('goal:')
1045
1045
  ? ''
1046
1046
  : (this.recentUserMessages.get(run.id) ?? this.currentRunMessageText(run.id));
1047
1047
  this.onRunChanged?.(run, session, userMessage.length === 0 ? undefined : userMessage);
@@ -242,7 +242,7 @@ export class ContinuousRunCoordinator {
242
242
  const item = this.options.runtime.getQueueItem(itemId);
243
243
  if (item === undefined)
244
244
  return;
245
- if (!this.missionCurrent(pending)) {
245
+ if (!this.goalCurrent(pending)) {
246
246
  this.deleteQueueItem(item.id);
247
247
  this.schedule(sessionId);
248
248
  return;
@@ -262,8 +262,8 @@ export class ContinuousRunCoordinator {
262
262
  this.options.emitConversation(turn);
263
263
  }
264
264
  else if (executionId === undefined && pending !== undefined) {
265
- if (!this.missionCurrent(pending)) {
266
- this.rejectStaleMission(active.id);
265
+ if (!this.goalCurrent(pending)) {
266
+ this.rejectStaleGoal(active.id);
267
267
  return;
268
268
  }
269
269
  const execution = this.options.runtime.createExecution(active.id);
@@ -277,18 +277,18 @@ export class ContinuousRunCoordinator {
277
277
  return;
278
278
  if (this.dispatchedExecutions.has(executionId))
279
279
  return;
280
- if (!this.missionCurrent(pending)) {
281
- this.rejectStaleMission(executionId);
280
+ if (!this.goalCurrent(pending)) {
281
+ this.rejectStaleGoal(executionId);
282
282
  return;
283
283
  }
284
284
  this.dispatchedExecutions.add(executionId);
285
285
  try {
286
- const missionMcp = pending.mission === undefined
286
+ const goalMcp = pending.goal === undefined
287
287
  ? undefined
288
- : await this.options.missionMcp?.(pending);
289
- if (!this.missionCurrent(pending)) {
288
+ : await this.options.goalMcp?.(pending);
289
+ if (!this.goalCurrent(pending)) {
290
290
  this.dispatchedExecutions.delete(executionId);
291
- this.rejectStaleMission(executionId);
291
+ this.rejectStaleGoal(executionId);
292
292
  return;
293
293
  }
294
294
  this.options.control('run.start', {
@@ -311,7 +311,7 @@ export class ContinuousRunCoordinator {
311
311
  collaborationMode: pending.collaborationMode,
312
312
  ...(pending.serviceTier === undefined ? {} : { serviceTier: pending.serviceTier }),
313
313
  secretEnvironment: pending.secretEnvironment,
314
- ...(missionMcp === undefined ? {} : { mcpSecretEnvironment: missionMcp.secrets }),
314
+ ...(goalMcp === undefined ? {} : { mcpSecretEnvironment: goalMcp.secrets }),
315
315
  ...(pending.personalInstructions === undefined
316
316
  ? {}
317
317
  : { personalInstructions: pending.personalInstructions }),
@@ -323,7 +323,7 @@ export class ContinuousRunCoordinator {
323
323
  ...(pending.computerUse === undefined ? {} : { computerUse: pending.computerUse }),
324
324
  mcpInstallations: [
325
325
  ...this.options.mcps(pending.workspaceId),
326
- ...(missionMcp === undefined ? [] : [missionMcp.installation])
326
+ ...(goalMcp === undefined ? [] : [goalMcp.installation])
327
327
  ]
328
328
  });
329
329
  }
@@ -369,12 +369,11 @@ export class ContinuousRunCoordinator {
369
369
  if (lease !== undefined)
370
370
  this.environmentLeases.set(nextId, lease);
371
371
  }
372
- removeMissionQueue(sessionId, preservedMission) {
372
+ removeGoalQueue(sessionId, preservedGoal) {
373
373
  for (const [id, pending] of this.preparedInputs) {
374
- if (pending.sessionId !== sessionId || pending.mission === undefined)
374
+ if (pending.sessionId !== sessionId || pending.goal === undefined)
375
375
  continue;
376
- if (pending.mission.id === preservedMission?.id &&
377
- pending.mission.revision === preservedMission.revision)
376
+ if (pending.goal.id === preservedGoal?.id && pending.goal.revision === preservedGoal.revision)
378
377
  continue;
379
378
  const item = this.options.runtime.getQueueItem(id);
380
379
  if (item !== undefined)
@@ -414,7 +413,7 @@ export class ContinuousRunCoordinator {
414
413
  const item = this.options.runtime.getQueueItem(itemId);
415
414
  if (item === undefined)
416
415
  throw new Error('QUEUE_ITEM_INVALID');
417
- if (!this.missionCurrent(pending)) {
416
+ if (!this.goalCurrent(pending)) {
418
417
  this.deleteQueueItem(item.id);
419
418
  this.startIdleQueue(sessionId);
420
419
  return;
@@ -434,13 +433,13 @@ export class ContinuousRunCoordinator {
434
433
  throw new Error('QUEUE_INPUT_LOST');
435
434
  return item;
436
435
  }
437
- missionCurrent(pending) {
438
- return (pending.mission === undefined ||
439
- this.options.missionCurrent?.(pending) !== false);
436
+ goalCurrent(pending) {
437
+ return (pending.goal === undefined ||
438
+ this.options.goalCurrent?.(pending) !== false);
440
439
  }
441
- rejectStaleMission(runId) {
440
+ rejectStaleGoal(runId) {
442
441
  this.remove(runId);
443
- this.options.emitRun(runId, 'run.completed', { code: 'MISSION_SUBMISSION_STALE' }, 'INTERRUPTED');
442
+ this.options.emitRun(runId, 'run.completed', { code: 'GOAL_SUBMISSION_STALE' }, 'INTERRUPTED');
444
443
  }
445
444
  isMessageRun(run) {
446
445
  return this.options.runtime.findMessageRun(run.sessionId, run.clientMessageId)?.id === run.id;
@@ -5,16 +5,16 @@ import { tmpdir } from 'node:os';
5
5
  import { join } from 'node:path';
6
6
  import { unlink } from 'node:fs/promises';
7
7
  import { fileURLToPath } from 'node:url';
8
- export class MissionMcpServer {
9
- missions;
8
+ export class GoalMcpServer {
9
+ goals;
10
10
  changed;
11
11
  capabilities = new Map();
12
12
  endpoint = process.platform === 'win32'
13
- ? `\\\\.\\pipe\\mar-mission-${process.pid}-${randomUUID()}`
14
- : join(tmpdir(), `mar-mission-${process.pid}-${randomUUID()}.sock`);
13
+ ? `\\\\.\\pipe\\mar-goal-${process.pid}-${randomUUID()}`
14
+ : join(tmpdir(), `mar-goal-${process.pid}-${randomUUID()}.sock`);
15
15
  listening;
16
- constructor(missions, changed) {
17
- this.missions = missions;
16
+ constructor(goals, changed) {
17
+ this.goals = goals;
18
18
  this.changed = changed;
19
19
  }
20
20
  listen() {
@@ -28,15 +28,15 @@ export class MissionMcpServer {
28
28
  async installation(capability) {
29
29
  await this.listen();
30
30
  const token = randomBytes(32).toString('base64url');
31
- const secretName = `MAR_MISSION_MCP_${randomBytes(16).toString('hex').toUpperCase()}`;
31
+ const secretName = `MAR_GOAL_MCP_${randomBytes(16).toString('hex').toUpperCase()}`;
32
32
  this.capabilities.set(token, capability);
33
33
  return {
34
34
  installation: {
35
- __marMission: true,
36
- serverName: 'myagentroam_mission',
35
+ __marGoal: true,
36
+ serverName: 'myagentroam_goal',
37
37
  enabled: true,
38
38
  command: process.execPath,
39
- args: missionMcpStdioArgs(),
39
+ args: goalMcpStdioArgs(),
40
40
  endpoint: this.endpoint,
41
41
  secretName
42
42
  },
@@ -81,44 +81,44 @@ export class MissionMcpServer {
81
81
  const request = JSON.parse(body);
82
82
  const capability = typeof request.token === 'string' ? this.capabilities.get(request.token) : undefined;
83
83
  if (capability === undefined)
84
- throw new Error('MISSION_CAPABILITY_INVALID');
84
+ throw new Error('GOAL_CAPABILITY_INVALID');
85
85
  const current = this.current(capability);
86
- if (request.tool === 'mar_get_mission') {
86
+ if (request.tool === 'mar_get_goal') {
87
87
  socket.end(`${JSON.stringify({ result: current })}\n`);
88
88
  return;
89
89
  }
90
- if (request.tool !== 'mar_update_mission')
91
- throw new Error('MISSION_TOOL_INVALID');
90
+ if (request.tool !== 'mar_update_goal')
91
+ throw new Error('GOAL_TOOL_INVALID');
92
92
  const status = request.arguments !== null &&
93
93
  typeof request.arguments === 'object' &&
94
94
  'status' in request.arguments
95
95
  ? request.arguments.status
96
96
  : undefined;
97
97
  if (status !== 'completed' && status !== 'blocked')
98
- throw new Error('MISSION_STATUS_INVALID');
99
- const mission = this.missions.update(capability.sessionId, capability.missionId, capability.revision, status);
98
+ throw new Error('GOAL_STATUS_INVALID');
99
+ const goal = this.goals.update(capability.sessionId, capability.goalId, capability.revision, status);
100
100
  this.changed(capability.sessionId);
101
- socket.end(`${JSON.stringify({ result: mission })}\n`);
101
+ socket.end(`${JSON.stringify({ result: goal })}\n`);
102
102
  }
103
103
  catch (error) {
104
- socket.end(`${JSON.stringify({ error: error instanceof Error ? error.message : 'MISSION_IPC_FAILED' })}\n`);
104
+ socket.end(`${JSON.stringify({ error: error instanceof Error ? error.message : 'GOAL_IPC_FAILED' })}\n`);
105
105
  }
106
106
  }
107
107
  current(capability) {
108
- const mission = this.missions.get(capability.sessionId);
109
- if (mission === undefined ||
110
- mission.id !== capability.missionId ||
111
- mission.revision !== capability.revision)
112
- throw new Error('MISSION_CAPABILITY_STALE');
113
- return mission;
108
+ const goal = this.goals.get(capability.sessionId);
109
+ if (goal === undefined ||
110
+ goal.id !== capability.goalId ||
111
+ goal.revision !== capability.revision)
112
+ throw new Error('GOAL_CAPABILITY_STALE');
113
+ return goal;
114
114
  }
115
115
  }
116
- function missionMcpStdioArgs() {
117
- const javascript = fileURLToPath(new URL('./mission-mcp-stdio.js', import.meta.url));
116
+ function goalMcpStdioArgs() {
117
+ const javascript = fileURLToPath(new URL('./goal-mcp-stdio.js', import.meta.url));
118
118
  if (existsSync(javascript))
119
119
  return [javascript];
120
- const typescript = fileURLToPath(new URL('./mission-mcp-stdio.ts', import.meta.url));
120
+ const typescript = fileURLToPath(new URL('./goal-mcp-stdio.ts', import.meta.url));
121
121
  if (!existsSync(typescript))
122
- throw new Error('MISSION_MCP_STDIO_ENTRY_UNAVAILABLE');
122
+ throw new Error('GOAL_MCP_STDIO_ENTRY_UNAVAILABLE');
123
123
  return ['--import', import.meta.resolve('tsx'), typescript];
124
124
  }