@adhdev/daemon-core 0.9.82-rc.315 → 0.9.82-rc.317
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/cli-adapter-types.d.ts +23 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +9 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +309 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +308 -52
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-runtime-store.d.ts +6 -0
- package/dist/mesh/mesh-work-queue.d.ts +22 -0
- package/dist/repo-mesh-types.d.ts +68 -0
- package/package.json +2 -2
- package/src/cli-adapter-types.ts +25 -0
- package/src/cli-adapters/provider-cli-adapter.ts +36 -1
- package/src/cli-adapters/provider-cli-shared.ts +19 -2
- package/src/commands/router.ts +42 -1
- package/src/config/mesh-config.ts +72 -1
- package/src/git/git-status.ts +122 -41
- package/src/index.ts +7 -1
- package/src/mesh/mesh-events-coordinator.ts +5 -1
- package/src/mesh/mesh-reconcile-loop.ts +31 -1
- package/src/mesh/mesh-runtime-store.ts +13 -0
- package/src/mesh/mesh-work-queue.ts +89 -11
- package/src/repo-mesh-types.ts +112 -0
|
@@ -34,6 +34,28 @@ export interface AcpAdapterHandle {
|
|
|
34
34
|
setConfigOption?(configId: string, value: string): Promise<void>;
|
|
35
35
|
resolvePermission?(approved: boolean): Promise<void>;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Launch metadata for a CLI session, surfaced by the dashboard Session info panel.
|
|
39
|
+
* Derived from the live adapter's spawn plan — the resolved binary, the full
|
|
40
|
+
* argument vector (provider base args + per-launch extra args), the cwd, and the
|
|
41
|
+
* set of per-launch extra-env KEYS (values are intentionally omitted so secrets in
|
|
42
|
+
* extraEnv are never sent to the dashboard). providerSessionId is the upstream
|
|
43
|
+
* agent's own session id once the CLI reports it.
|
|
44
|
+
*/
|
|
45
|
+
export interface CliLaunchInfo {
|
|
46
|
+
/** Resolved executable path the PTY actually spawns. */
|
|
47
|
+
command?: string;
|
|
48
|
+
/** Full argument vector (provider spawn.args + extraArgs, {{workingDir}} expanded). */
|
|
49
|
+
args: string[];
|
|
50
|
+
/** Per-launch extra args only (subset of args), for attribution. */
|
|
51
|
+
extraArgs: string[];
|
|
52
|
+
/** Working directory the session was spawned in. */
|
|
53
|
+
cwd: string;
|
|
54
|
+
/** KEYS of per-launch extra env (values omitted — may contain secrets). */
|
|
55
|
+
extraEnvKeys: string[];
|
|
56
|
+
/** Upstream agent session id, once the CLI reports one. */
|
|
57
|
+
providerSessionId?: string;
|
|
58
|
+
}
|
|
37
59
|
export interface CliAdapter {
|
|
38
60
|
cliType: string;
|
|
39
61
|
cliName: string;
|
|
@@ -69,6 +91,7 @@ export interface CliAdapter {
|
|
|
69
91
|
setOnPtyData?(callback: (data: string) => void): void;
|
|
70
92
|
writeRaw?(data: string): void;
|
|
71
93
|
resize?(cols: number, rows: number): void;
|
|
94
|
+
getLaunchInfo?(): CliLaunchInfo;
|
|
72
95
|
getRuntimeMetadata?(): unknown;
|
|
73
96
|
updateRuntimeMeta?(meta: Record<string, unknown>): void;
|
|
74
97
|
refreshProviderDefinition?(provider: unknown): void;
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* type, name, category: 'cli', binary, spawn, approvalKeys
|
|
14
14
|
* compatibility: [{ ideVersion, scriptDir }] ← versioned scripts
|
|
15
15
|
*/
|
|
16
|
-
import type { CliAdapter } from '../cli-adapter-types.js';
|
|
16
|
+
import type { CliAdapter, CliLaunchInfo } from '../cli-adapter-types.js';
|
|
17
17
|
import type { InteractivePromptResponse } from '../providers/types/interactive-prompt.js';
|
|
18
18
|
import { type PtyRuntimeMetadata, type PtyTransportFactory } from './pty-transport.js';
|
|
19
19
|
import { type CliProviderModule, type CliScripts, type CliSessionStatus, type CliTraceEntry, type ParsedSession } from './provider-cli-shared.js';
|
|
@@ -190,6 +190,14 @@ export declare class ProviderCliAdapter implements CliAdapter {
|
|
|
190
190
|
getPartialResponse(): string;
|
|
191
191
|
getDebugSnapshot(): Record<string, unknown>;
|
|
192
192
|
getRuntimeMetadata(): PtyRuntimeMetadata | null;
|
|
193
|
+
/**
|
|
194
|
+
* Launch metadata for the dashboard Session info panel. Re-derives the spawn plan
|
|
195
|
+
* (pure — same inputs the live PTY was spawned with) so the dashboard sees the
|
|
196
|
+
* resolved binary, full arg vector, and cwd without us having to persist it.
|
|
197
|
+
* extraEnv values are intentionally dropped (keys only) so secrets passed at
|
|
198
|
+
* launch time never reach the dashboard.
|
|
199
|
+
*/
|
|
200
|
+
getLaunchInfo(): CliLaunchInfo;
|
|
193
201
|
updateRuntimeMeta(meta: Record<string, unknown>, replace?: boolean): void;
|
|
194
202
|
cancel(): void;
|
|
195
203
|
saveAndStop(): Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ export type { ChatBubbleState, ChatMessage, ExtensionInfo, CommandResult as Core
|
|
|
7
7
|
export type { SessionEntry, CompactSessionEntry, CompactDaemonEntry, CloudDaemonSummaryEntry, DashboardBootstrapDaemonEntry, VersionUpdateReason, CloudStatusReportPayload, DaemonStatusEventPayload, DashboardStatusEventPayload, SessionTransport, SessionKind, SessionCapability, AgentSessionStream, ReadChatCursor, ReadChatSyncResult, TransportTopic, SessionChatTailSubscriptionParams, SessionRuntimeOutputSubscriptionParams, MachineRuntimeSubscriptionParams, SessionHostDiagnosticsSubscriptionParams, SessionModalSubscriptionParams, DaemonMetadataSubscriptionParams, WorkspaceGitSubscriptionParams, SessionChatTailUpdate, MachineRuntimeUpdate, SessionHostDiagnosticsUpdate, SessionModalUpdate, DaemonMetadataUpdate, TopicUpdateEnvelope, SubscribeRequest, UnsubscribeRequest, StandaloneWsStatusPayload, AvailableProviderInfo, AcpConfigOption, AcpMode, ProviderControlSchema, StatusReportPayload, MachineInfo, SessionHostDiagnosticsSnapshot, SessionHostRecord, SessionHostWriteOwner, SessionHostAttachedClient, SessionHostLogEntry, SessionHostRequestTrace, SessionHostRuntimeTransition, DetectedIdeInfo, WorkspaceEntry, ProviderSummaryItem, ProviderSummaryMetadata, ProviderState, ProviderStatus, ProviderErrorReason, SessionActiveChatData, ActiveChatData, IdeProviderState, CliProviderState, AcpProviderState, ExtensionProviderState, MessageInputSupport, InputMediaStrategyDescriptor, InputAttachmentStrategy, InputMediaType, } from './shared-types.js';
|
|
8
8
|
export type { InteractivePrompt, InteractiveQuestion, InteractiveOption, InteractivePromptResponse, InteractiveAnswer, } from './providers/types/interactive-prompt.js';
|
|
9
9
|
export { normalizeInteractivePrompt, normalizeInteractivePromptResponse, buildClaudeInteractiveToolResult, interactivePromptFromClaudeAskUserQuestion, detectClaudeAskUserQuestionPromptFromJson, } from './providers/types/interactive-prompt.js';
|
|
10
|
-
export type { RepoMesh, RepoMeshDaemonRole, RepoMeshHostMetadata, RepoMeshHostPairingMetadata, RepoMeshHostStatus, RepoMeshNode, RepoMeshNodeHealth, RepoMeshPolicy, RepoMeshNodePolicy, RepoMeshRelatedRepo, RepoMeshNodeCapabilities, DetectedCommand, ProjectContextSnapshot, ProjectContextSource, RepoMeshCoordinatorConfig, LocalMeshConfig, LocalMeshEntry, LocalMeshNodeEntry, RepoMeshStatus, RepoMeshNodeStatus, RepoMeshPeerConnectionStatus, RepoMeshPeerConnectionState, RepoMeshPeerConnectionTransport, RepoMeshSessionStatus, RepoMeshQueueTask, RepoMeshQueueTaskStatus, RepoMeshQueueSummary, RepoMeshQueueStatus, RepoMeshLedgerEntryStatus, RepoMeshLedgerSummaryStatus, RepoMeshLedgerStatus, MeshAsyncJobLifecycle, RepoMeshSchedulingStrategy, } from './repo-mesh-types.js';
|
|
11
|
-
export { DEFAULT_MESH_POLICY, resolveDelegatedWorkerAutoApprove, MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, normalizeMeshSchedulingStrategy, resolveNodeSchedulingPriority, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, resolveAutoConvergeCodeChange, } from './repo-mesh-types.js';
|
|
10
|
+
export type { RepoMesh, RepoMeshDaemonRole, RepoMeshHostMetadata, RepoMeshHostPairingMetadata, RepoMeshHostStatus, RepoMeshNode, RepoMeshNodeHealth, RepoMeshPolicy, RepoMeshNodePolicy, RepoMeshRelatedRepo, RepoMeshNodeCapabilities, DetectedCommand, ProjectContextSnapshot, ProjectContextSource, RepoMeshCoordinatorConfig, LocalMeshConfig, LocalMeshEntry, LocalMeshNodeEntry, RepoMeshStatus, RepoMeshNodeStatus, RepoMeshPeerConnectionStatus, RepoMeshPeerConnectionState, RepoMeshPeerConnectionTransport, RepoMeshSessionStatus, RepoMeshQueueTask, RepoMeshQueueTaskStatus, RepoMeshQueueSummary, RepoMeshQueueStatus, RepoMeshLedgerEntryStatus, RepoMeshLedgerSummaryStatus, RepoMeshLedgerStatus, MeshAsyncJobLifecycle, RepoMeshSchedulingStrategy, RepoMeshTaskAffinityPolicy, StandardMeshRole, } from './repo-mesh-types.js';
|
|
11
|
+
export { DEFAULT_MESH_POLICY, resolveDelegatedWorkerAutoApprove, MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, normalizeMeshSchedulingStrategy, resolveNodeSchedulingPriority, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, resolveAutoConvergeCodeChange, STANDARD_MESH_ROLES, DEFAULT_TASKMODE_ROLE_MAP, resolveTaskAffinityRole, resolveMeshRoleOptions, } from './repo-mesh-types.js';
|
|
12
12
|
export * from './git/index.js';
|
|
13
13
|
import type { RuntimeWriteOwner as _RuntimeWriteOwner } from './shared-types-extra.js';
|
|
14
14
|
import type { RuntimeAttachedClient as _RuntimeAttachedClient } from './shared-types-extra.js';
|
|
@@ -49,7 +49,7 @@ export { fastForwardMeshNode } from './mesh/mesh-fast-forward.js';
|
|
|
49
49
|
export type { MeshFastForwardNodeArgs, MeshFastForwardPlannedStep, MeshFastForwardResult } from './mesh/mesh-fast-forward.js';
|
|
50
50
|
export { buildMeshLedgerReconciliationEvidence, buildMeshLedgerReplicaEvidence } from './mesh/mesh-ledger-reconciliation.js';
|
|
51
51
|
export type { AnyLedgerSlice, MeshLedgerReconciliationEvidence, MeshLedgerReplicaEvidence, MeshLedgerReplicaStatus } from './mesh/mesh-ledger-reconciliation.js';
|
|
52
|
-
export { enqueueTask, recordDirectDispatchTask, getQueue, claimNextTask, updateTaskStatus, updateSessionTaskStatus, cancelTask, requeueTask, getMeshQueueStats, getMeshQueueRevision, normalizeMeshTaskMode, validateMeshTaskModeRequest, buildMeshNodeCapabilityTags, nodeSatisfiesRequiredTags, normalizeMeshCapabilityTags, resolveConvergeRequiredTags, insertDirectDispatch, getActiveDirectDispatches, updateDirectDispatchStatus, cleanupTerminalDirectDispatches, markStaleDirectDispatches, deleteDirectDispatchesByTaskId, recordMeshToolCall, assertNoDependencyCycle, hasPendingDependents, describeTaskDependencyState } from './mesh/mesh-work-queue.js';
|
|
52
|
+
export { enqueueTask, recordDirectDispatchTask, getQueue, claimNextTask, updateTaskStatus, updateSessionTaskStatus, cancelTask, requeueTask, getMeshQueueStats, getMeshQueueRevision, normalizeMeshTaskMode, validateMeshTaskModeRequest, buildMeshNodeCapabilityTags, nodeSatisfiesRequiredTags, normalizeMeshCapabilityTags, resolveConvergeRequiredTags, resolveTaskAffinityRequiredTags, insertDirectDispatch, getActiveDirectDispatches, updateDirectDispatchStatus, cleanupTerminalDirectDispatches, markStaleDirectDispatches, deleteDirectDispatchesByTaskId, recordMeshToolCall, assertNoDependencyCycle, hasPendingDependents, describeTaskDependencyState } from './mesh/mesh-work-queue.js';
|
|
53
53
|
export type { MeshWorkQueueEntry, MeshTaskStatus, MeshTaskMode, MeshWorkQueueStats, MeshQueueMutationOptions, MeshTaskModeValidationResult, DirectDispatchRecord, MeshToolCallRateResult } from './mesh/mesh-work-queue.js';
|
|
54
54
|
export { buildCompactStaleDirectWorkSummary, buildMeshActiveWork, buildMeshActiveWorkSummary, classifyStaleDirectForPrune, PRUNABLE_ORPHAN_STALE_REASONS } from './mesh/mesh-active-work.js';
|
|
55
55
|
export type { StaleDirectPruneClassification } from './mesh/mesh-active-work.js';
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,35 @@ function resolveNodeSchedulingPriority(nodePolicy) {
|
|
|
40
40
|
const raw = Number(nodePolicy?.schedulingPriority);
|
|
41
41
|
return Number.isFinite(raw) ? raw : 0;
|
|
42
42
|
}
|
|
43
|
+
function resolveTaskAffinityRole(taskMode, policy) {
|
|
44
|
+
if (!taskMode) return null;
|
|
45
|
+
if (policy?.enabled === false) return null;
|
|
46
|
+
const override = policy?.byTaskMode && Object.prototype.hasOwnProperty.call(policy.byTaskMode, taskMode) ? policy.byTaskMode[taskMode] : void 0;
|
|
47
|
+
if (typeof override === "string") {
|
|
48
|
+
const trimmed = override.trim().toLowerCase();
|
|
49
|
+
return trimmed ? trimmed : null;
|
|
50
|
+
}
|
|
51
|
+
const fallback = DEFAULT_TASKMODE_ROLE_MAP[taskMode];
|
|
52
|
+
return fallback ?? null;
|
|
53
|
+
}
|
|
54
|
+
function resolveMeshRoleOptions(policy) {
|
|
55
|
+
const out = [...STANDARD_MESH_ROLES];
|
|
56
|
+
const seen = new Set(out);
|
|
57
|
+
const add = (raw) => {
|
|
58
|
+
if (typeof raw !== "string") return;
|
|
59
|
+
const role = raw.trim().toLowerCase();
|
|
60
|
+
if (!role || seen.has(role)) return;
|
|
61
|
+
seen.add(role);
|
|
62
|
+
out.push(role);
|
|
63
|
+
};
|
|
64
|
+
if (policy?.byTaskMode) {
|
|
65
|
+
for (const value of Object.values(policy.byTaskMode)) add(value);
|
|
66
|
+
}
|
|
67
|
+
if (Array.isArray(policy?.customRoles)) {
|
|
68
|
+
for (const value of policy.customRoles) add(value);
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
43
72
|
function resolveAutoConvergeCodeChange(policy) {
|
|
44
73
|
return policy?.autoConvergeCodeChange === true;
|
|
45
74
|
}
|
|
@@ -70,7 +99,7 @@ function resolveProviderMaxParallel(nodePolicy, providerType) {
|
|
|
70
99
|
if (!Number.isFinite(raw) || raw < 0) return void 0;
|
|
71
100
|
return Math.floor(raw);
|
|
72
101
|
}
|
|
73
|
-
var MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, DEFAULT_MESH_POLICY;
|
|
102
|
+
var MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, STANDARD_MESH_ROLES, DEFAULT_TASKMODE_ROLE_MAP, DEFAULT_MESH_POLICY;
|
|
74
103
|
var init_repo_mesh_types = __esm({
|
|
75
104
|
"src/repo-mesh-types.ts"() {
|
|
76
105
|
"use strict";
|
|
@@ -83,6 +112,14 @@ var init_repo_mesh_types = __esm({
|
|
|
83
112
|
DEFAULT_MESH_SCHEDULING_STRATEGY = "first_eligible";
|
|
84
113
|
MESH_CONVERGE_REFINE_TAG = "converge=refine";
|
|
85
114
|
MESH_CONVERGE_FAST_FORWARD_TAG = "converge=fast_forward";
|
|
115
|
+
STANDARD_MESH_ROLES = ["investigator", "coder", "validator", "converger"];
|
|
116
|
+
DEFAULT_TASKMODE_ROLE_MAP = {
|
|
117
|
+
live_debug_readonly: "investigator",
|
|
118
|
+
code_change: "coder",
|
|
119
|
+
launch_app: "coder",
|
|
120
|
+
validation: "validator",
|
|
121
|
+
convergence: "converger"
|
|
122
|
+
};
|
|
86
123
|
DEFAULT_MESH_POLICY = {
|
|
87
124
|
requirePreTaskCheckpoint: false,
|
|
88
125
|
requirePostTaskCheckpoint: true,
|
|
@@ -316,10 +353,10 @@ function readInjected(value) {
|
|
|
316
353
|
}
|
|
317
354
|
function getDaemonBuildInfo() {
|
|
318
355
|
if (cached) return cached;
|
|
319
|
-
const commit = readInjected(true ? "
|
|
320
|
-
const commitShort = readInjected(true ? "
|
|
321
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
322
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
356
|
+
const commit = readInjected(true ? "b4484284652748bf8096f40a00eb5cb463963576" : void 0) ?? "unknown";
|
|
357
|
+
const commitShort = readInjected(true ? "b4484284" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
358
|
+
const version = readInjected(true ? "0.9.82-rc.317" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
359
|
+
const builtAt = readInjected(true ? "2026-06-18T08:55:18.955Z" : void 0);
|
|
323
360
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
324
361
|
return cached;
|
|
325
362
|
}
|
|
@@ -645,14 +682,79 @@ function emptyStatus(workspace, lastCheckedAt, error) {
|
|
|
645
682
|
async function getSubmoduleStatuses(repo, options) {
|
|
646
683
|
if (!repo.repoRoot) return [];
|
|
647
684
|
try {
|
|
648
|
-
const
|
|
649
|
-
const submodules = parseSubmoduleStatusOutput(result.stdout, repo.repoRoot, options.submoduleIgnorePaths);
|
|
685
|
+
const submodules = await deriveSubmoduleGitlinkStatuses(repo, options);
|
|
650
686
|
await Promise.all(submodules.map((submodule) => enrichSubmoduleWorktreeStatus(repo, submodule, options)));
|
|
651
687
|
return submodules;
|
|
652
688
|
} catch {
|
|
653
689
|
return [];
|
|
654
690
|
}
|
|
655
691
|
}
|
|
692
|
+
async function deriveSubmoduleGitlinkStatuses(repo, options) {
|
|
693
|
+
if (!repo.repoRoot) return [];
|
|
694
|
+
const paths = await readSubmodulePaths(repo, options);
|
|
695
|
+
const ignoreSet = new Set(options.submoduleIgnorePaths || []);
|
|
696
|
+
const lastCheckedAt = Date.now();
|
|
697
|
+
const entries = await Promise.all(
|
|
698
|
+
paths.filter((path41) => !ignoreSet.has(path41)).map(async (path41) => {
|
|
699
|
+
const repoPath = repo.repoRoot + "/" + path41;
|
|
700
|
+
const expected = await readGitlinkExpectedSha(repo, path41, options);
|
|
701
|
+
const actual = await readSubmoduleHeadSha(repo, repoPath, options);
|
|
702
|
+
const outOfSync = actual === null ? true : expected !== null && expected !== actual;
|
|
703
|
+
return {
|
|
704
|
+
path: path41,
|
|
705
|
+
// Prefer the recorded gitlink SHA (matches the legacy column); fall back
|
|
706
|
+
// to the checked-out SHA so the field is never empty when both are known.
|
|
707
|
+
commit: expected ?? actual ?? "",
|
|
708
|
+
repoPath,
|
|
709
|
+
dirty: false,
|
|
710
|
+
outOfSync,
|
|
711
|
+
lastCheckedAt
|
|
712
|
+
};
|
|
713
|
+
})
|
|
714
|
+
);
|
|
715
|
+
return entries;
|
|
716
|
+
}
|
|
717
|
+
async function readSubmodulePaths(repo, options) {
|
|
718
|
+
if (!repo.repoRoot) return [];
|
|
719
|
+
const gitmodulesPath = repo.repoRoot + "/.gitmodules";
|
|
720
|
+
try {
|
|
721
|
+
const result = await runGit(
|
|
722
|
+
repo,
|
|
723
|
+
["config", "--file", gitmodulesPath, "--get-regexp", "^submodule\\..*\\.path$"],
|
|
724
|
+
options
|
|
725
|
+
);
|
|
726
|
+
const paths = [];
|
|
727
|
+
for (const line of result.stdout.split("\n")) {
|
|
728
|
+
const spaceIdx = line.indexOf(" ");
|
|
729
|
+
if (spaceIdx < 0) continue;
|
|
730
|
+
const value = line.slice(spaceIdx + 1).trim();
|
|
731
|
+
if (value) paths.push(value);
|
|
732
|
+
}
|
|
733
|
+
return paths;
|
|
734
|
+
} catch {
|
|
735
|
+
return [];
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
async function readGitlinkExpectedSha(repo, submodulePath, options) {
|
|
739
|
+
try {
|
|
740
|
+
const result = await runGit(repo, ["ls-tree", "HEAD", submodulePath], options);
|
|
741
|
+
const line = result.stdout.split("\n").find((l) => l.trim().length > 0);
|
|
742
|
+
if (!line) return null;
|
|
743
|
+
const match = line.match(/^\s*\d+\s+commit\s+([0-9a-f]{40})\b/);
|
|
744
|
+
return match ? match[1] : null;
|
|
745
|
+
} catch {
|
|
746
|
+
return null;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
async function readSubmoduleHeadSha(repo, repoPath, options) {
|
|
750
|
+
try {
|
|
751
|
+
const result = await runGit(repo, ["rev-parse", "HEAD"], { ...options, cwd: repoPath });
|
|
752
|
+
const sha = result.stdout.trim();
|
|
753
|
+
return /^[0-9a-f]{40}$/.test(sha) ? sha : null;
|
|
754
|
+
} catch {
|
|
755
|
+
return null;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
656
758
|
async function enrichSubmoduleWorktreeStatus(repo, submodule, options) {
|
|
657
759
|
try {
|
|
658
760
|
const result = await runGit(repo, ["status", "--porcelain=v2", "--branch"], {
|
|
@@ -667,28 +769,6 @@ async function enrichSubmoduleWorktreeStatus(repo, submodule, options) {
|
|
|
667
769
|
submodule.error = formatGitError(error);
|
|
668
770
|
}
|
|
669
771
|
}
|
|
670
|
-
function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
|
|
671
|
-
const submodules = [];
|
|
672
|
-
const ignoreSet = new Set(ignorePaths || []);
|
|
673
|
-
for (const line of output.split("\n")) {
|
|
674
|
-
if (!line.trim()) continue;
|
|
675
|
-
const match = line.match(/^([\-+U\s])([0-9a-f]{40})\s+(\S+)(?:\s+\(([^)]+)\))?/);
|
|
676
|
-
if (!match) continue;
|
|
677
|
-
const prefix = match[1];
|
|
678
|
-
const commit = match[2];
|
|
679
|
-
const path41 = match[3];
|
|
680
|
-
if (ignoreSet.has(path41)) continue;
|
|
681
|
-
submodules.push({
|
|
682
|
-
path: path41,
|
|
683
|
-
commit,
|
|
684
|
-
repoPath: repoRoot + "/" + path41,
|
|
685
|
-
dirty: prefix === "U",
|
|
686
|
-
outOfSync: prefix === "-" || prefix === "+",
|
|
687
|
-
lastCheckedAt: Date.now()
|
|
688
|
-
});
|
|
689
|
-
}
|
|
690
|
-
return submodules;
|
|
691
|
-
}
|
|
692
772
|
var lastKnownGoodStatus, DAEMON_RUNTIME_PACKAGES, WEB_ONLY_PACKAGES;
|
|
693
773
|
var init_git_status = __esm({
|
|
694
774
|
"src/git/git-status.ts"() {
|
|
@@ -1577,8 +1657,61 @@ function mergeMeshPolicy(base, patch) {
|
|
|
1577
1657
|
} else {
|
|
1578
1658
|
delete policy.autoConvergeCodeChange;
|
|
1579
1659
|
}
|
|
1660
|
+
const normalizedAffinity = normalizeTaskAffinityPolicy(policy.taskAffinity);
|
|
1661
|
+
if (normalizedAffinity) {
|
|
1662
|
+
policy.taskAffinity = normalizedAffinity;
|
|
1663
|
+
} else {
|
|
1664
|
+
delete policy.taskAffinity;
|
|
1665
|
+
}
|
|
1580
1666
|
return policy;
|
|
1581
1667
|
}
|
|
1668
|
+
function normalizeTaskAffinityPolicy(value) {
|
|
1669
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1670
|
+
const record = value;
|
|
1671
|
+
const out = {};
|
|
1672
|
+
let hasContent = false;
|
|
1673
|
+
if (typeof record.enabled === "boolean") {
|
|
1674
|
+
out.enabled = record.enabled;
|
|
1675
|
+
if (record.enabled === false) hasContent = true;
|
|
1676
|
+
else delete out.enabled;
|
|
1677
|
+
}
|
|
1678
|
+
if (record.byTaskMode && typeof record.byTaskMode === "object" && !Array.isArray(record.byTaskMode)) {
|
|
1679
|
+
const byTaskMode = {};
|
|
1680
|
+
for (const [mode, raw] of Object.entries(record.byTaskMode)) {
|
|
1681
|
+
const modeKey = mode.trim();
|
|
1682
|
+
if (!modeKey) continue;
|
|
1683
|
+
if (typeof raw !== "string") continue;
|
|
1684
|
+
const role = raw.trim().toLowerCase();
|
|
1685
|
+
byTaskMode[modeKey] = role;
|
|
1686
|
+
if (role && !STANDARD_MESH_ROLES.includes(role)) {
|
|
1687
|
+
try {
|
|
1688
|
+
console.warn(`[mesh] task_affinity.byTaskMode.${modeKey}: custom role "${role}" is not a standard mesh role (${STANDARD_MESH_ROLES.join("/")}); routing still applies`);
|
|
1689
|
+
} catch {
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
if (Object.keys(byTaskMode).length > 0) {
|
|
1694
|
+
out.byTaskMode = byTaskMode;
|
|
1695
|
+
hasContent = true;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
if (Array.isArray(record.customRoles)) {
|
|
1699
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1700
|
+
const customRoles = [];
|
|
1701
|
+
for (const raw of record.customRoles) {
|
|
1702
|
+
if (typeof raw !== "string") continue;
|
|
1703
|
+
const role = raw.trim().toLowerCase();
|
|
1704
|
+
if (!role || seen.has(role)) continue;
|
|
1705
|
+
seen.add(role);
|
|
1706
|
+
customRoles.push(role);
|
|
1707
|
+
}
|
|
1708
|
+
if (customRoles.length > 0) {
|
|
1709
|
+
out.customRoles = customRoles;
|
|
1710
|
+
hasContent = true;
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
return hasContent ? out : void 0;
|
|
1714
|
+
}
|
|
1582
1715
|
function normalizeAutoFastForwardPolicy(value) {
|
|
1583
1716
|
const record = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1584
1717
|
const maxBehind = Number(record.maxBehind);
|
|
@@ -2872,6 +3005,7 @@ __export(mesh_work_queue_exports, {
|
|
|
2872
3005
|
recordTaskAutoLaunch: () => recordTaskAutoLaunch,
|
|
2873
3006
|
requeueTask: () => requeueTask,
|
|
2874
3007
|
resolveConvergeRequiredTags: () => resolveConvergeRequiredTags,
|
|
3008
|
+
resolveTaskAffinityRequiredTags: () => resolveTaskAffinityRequiredTags,
|
|
2875
3009
|
updateDirectDispatchStatus: () => updateDirectDispatchStatus,
|
|
2876
3010
|
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
2877
3011
|
updateTaskStatus: () => updateTaskStatus,
|
|
@@ -3010,6 +3144,31 @@ function resolveConvergeRequiredTags(meshId, taskMode, explicitRequiredTags, opt
|
|
|
3010
3144
|
if (!optedIn) return explicitRequiredTags;
|
|
3011
3145
|
return normalizeMeshCapabilityTags([...explicitRequiredTags, MESH_CONVERGE_REFINE_TAG]);
|
|
3012
3146
|
}
|
|
3147
|
+
function meshHasNodeAdvertisingRole(nodes, role) {
|
|
3148
|
+
if (!Array.isArray(nodes) || nodes.length === 0) return false;
|
|
3149
|
+
const wanted = `role=${role}`;
|
|
3150
|
+
return nodes.some((node) => buildMeshNodeCapabilityTags(node).includes(wanted));
|
|
3151
|
+
}
|
|
3152
|
+
function resolveTaskAffinityRequiredTags(meshId, taskMode, explicitRequiredTags, opts) {
|
|
3153
|
+
if (typeof opts?.targetNodeId === "string" && opts.targetNodeId.trim()) return explicitRequiredTags;
|
|
3154
|
+
if (opts?.callerSpecifiedRequiredTags === true) return explicitRequiredTags;
|
|
3155
|
+
let mesh;
|
|
3156
|
+
try {
|
|
3157
|
+
mesh = getMesh(meshId);
|
|
3158
|
+
} catch {
|
|
3159
|
+
return explicitRequiredTags;
|
|
3160
|
+
}
|
|
3161
|
+
const role = resolveTaskAffinityRole(taskMode, mesh?.policy?.taskAffinity);
|
|
3162
|
+
if (!role) return explicitRequiredTags;
|
|
3163
|
+
if (!meshHasNodeAdvertisingRole(mesh?.nodes, role)) {
|
|
3164
|
+
try {
|
|
3165
|
+
console.warn(`[mesh] task_affinity: no node advertises role=${role} for taskMode=${taskMode} in mesh ${meshId}; skipping injection (least_loaded fallback)`);
|
|
3166
|
+
} catch {
|
|
3167
|
+
}
|
|
3168
|
+
return explicitRequiredTags;
|
|
3169
|
+
}
|
|
3170
|
+
return normalizeMeshCapabilityTags([...explicitRequiredTags, `role=${role}`]);
|
|
3171
|
+
}
|
|
3013
3172
|
function withQueueLock(_meshId, fn) {
|
|
3014
3173
|
return MeshRuntimeStore.getInstance().transaction(fn);
|
|
3015
3174
|
}
|
|
@@ -3060,6 +3219,20 @@ function enqueueTask(meshId, message, opts) {
|
|
|
3060
3219
|
throw new Error(`duplicate_task_id: task '${id}' already exists in mesh '${meshId}'`);
|
|
3061
3220
|
}
|
|
3062
3221
|
assertNoDependencyCycle(meshId, id, dependsOn);
|
|
3222
|
+
const callerTags = normalizeMeshCapabilityTags(opts?.requiredTags);
|
|
3223
|
+
const callerSpecifiedRequiredTags = callerTags.length > 0;
|
|
3224
|
+
let resolvedRequiredTags = resolveConvergeRequiredTags(
|
|
3225
|
+
meshId,
|
|
3226
|
+
modeValidation.taskMode,
|
|
3227
|
+
callerTags,
|
|
3228
|
+
{ targetNodeId: opts?.targetNodeId }
|
|
3229
|
+
);
|
|
3230
|
+
resolvedRequiredTags = resolveTaskAffinityRequiredTags(
|
|
3231
|
+
meshId,
|
|
3232
|
+
modeValidation.taskMode,
|
|
3233
|
+
resolvedRequiredTags,
|
|
3234
|
+
{ targetNodeId: opts?.targetNodeId, callerSpecifiedRequiredTags }
|
|
3235
|
+
);
|
|
3063
3236
|
const entry = {
|
|
3064
3237
|
id,
|
|
3065
3238
|
meshId,
|
|
@@ -3068,15 +3241,7 @@ function enqueueTask(meshId, message, opts) {
|
|
|
3068
3241
|
taskMode: modeValidation.taskMode,
|
|
3069
3242
|
targetNodeId: opts?.targetNodeId,
|
|
3070
3243
|
targetSessionId: opts?.targetSessionId,
|
|
3071
|
-
|
|
3072
|
-
// tasks so they hard-filter onto refine-capable worktree nodes. No-op unless
|
|
3073
|
-
// the mesh opts in; explicit target_node_id / required_tags are preserved.
|
|
3074
|
-
requiredTags: resolveConvergeRequiredTags(
|
|
3075
|
-
meshId,
|
|
3076
|
-
modeValidation.taskMode,
|
|
3077
|
-
normalizeMeshCapabilityTags(opts?.requiredTags),
|
|
3078
|
-
{ targetNodeId: opts?.targetNodeId }
|
|
3079
|
-
),
|
|
3244
|
+
requiredTags: resolvedRequiredTags,
|
|
3080
3245
|
...dependsOn.length > 0 ? { dependsOn } : {},
|
|
3081
3246
|
...typeof opts?.missionId === "string" && opts.missionId.trim() ? { missionId: opts.missionId.trim() } : {},
|
|
3082
3247
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -3833,6 +3998,18 @@ var init_mesh_runtime_store = __esm({
|
|
|
3833
3998
|
`).get(meshId, nodeId);
|
|
3834
3999
|
return row?.count ?? 0;
|
|
3835
4000
|
}
|
|
4001
|
+
/**
|
|
4002
|
+
* O(1) count of queue tasks in 'pending' status for a mesh. A COUNT(*) over the
|
|
4003
|
+
* indexed status column, so it avoids JSON.parse-ing every queue row — used as a
|
|
4004
|
+
* cheap guard before the reconcile loop runs a full triggerMeshQueue scan.
|
|
4005
|
+
*/
|
|
4006
|
+
pendingQueueTaskCount(meshId) {
|
|
4007
|
+
const row = this.db.prepare(`
|
|
4008
|
+
SELECT COUNT(*) as count FROM mesh_queue
|
|
4009
|
+
WHERE mesh_id = ? AND status = 'pending'
|
|
4010
|
+
`).get(meshId);
|
|
4011
|
+
return row?.count ?? 0;
|
|
4012
|
+
}
|
|
3836
4013
|
/**
|
|
3837
4014
|
* Read the current per-mesh round-robin cursor (0 when unset). Used to rotate
|
|
3838
4015
|
* the tie-break winner among nodes tied at the least load.
|
|
@@ -8766,7 +8943,7 @@ async function triggerMeshQueue(components, meshId) {
|
|
|
8766
8943
|
}
|
|
8767
8944
|
const remoteCandidates = [];
|
|
8768
8945
|
for (const idle of remoteSessions) {
|
|
8769
|
-
const node = mesh.nodes.find((n) => n
|
|
8946
|
+
const node = mesh.nodes.find((n) => meshNodeIdMatches(n, idle.nodeId));
|
|
8770
8947
|
if (node) {
|
|
8771
8948
|
remoteIdleSessionsChecked += 1;
|
|
8772
8949
|
remoteCandidates.push({ nodeId: idle.nodeId, sessionId: idle.sessionId, providerType: idle.providerType, origin: "remote", node });
|
|
@@ -9570,6 +9747,21 @@ async function runMeshReconcileTick(components) {
|
|
|
9570
9747
|
}
|
|
9571
9748
|
}
|
|
9572
9749
|
}
|
|
9750
|
+
for (const mesh of listMeshes()) {
|
|
9751
|
+
const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
|
|
9752
|
+
if (!daemonHostsMesh(mesh, selfIds)) continue;
|
|
9753
|
+
if (store) {
|
|
9754
|
+
try {
|
|
9755
|
+
if (store.pendingQueueTaskCount(mesh.id) === 0) continue;
|
|
9756
|
+
} catch {
|
|
9757
|
+
}
|
|
9758
|
+
}
|
|
9759
|
+
try {
|
|
9760
|
+
await triggerMeshQueue(components, mesh.id);
|
|
9761
|
+
} catch (e) {
|
|
9762
|
+
LOG.warn("MeshReconcile", `Pending-claim recovery trigger failed for mesh ${mesh.id}: ${e?.message || e}`);
|
|
9763
|
+
}
|
|
9764
|
+
}
|
|
9573
9765
|
const coordinators = findLiveCoordinators(components);
|
|
9574
9766
|
if (coordinators.length === 0) {
|
|
9575
9767
|
return;
|
|
@@ -10961,8 +11153,24 @@ function findBinary(name) {
|
|
|
10961
11153
|
}
|
|
10962
11154
|
const isWin = os12.platform() === "win32";
|
|
10963
11155
|
const paths = (process.env.PATH || "").split(path17.delimiter);
|
|
11156
|
+
const extraDirs = [];
|
|
11157
|
+
if (isWin) {
|
|
11158
|
+
if (process.env.APPDATA) extraDirs.push(path17.join(process.env.APPDATA, "npm"));
|
|
11159
|
+
try {
|
|
11160
|
+
extraDirs.push(path17.dirname(process.execPath));
|
|
11161
|
+
} catch {
|
|
11162
|
+
}
|
|
11163
|
+
} else {
|
|
11164
|
+
extraDirs.push(path17.join(os12.homedir(), ".npm-global", "bin"));
|
|
11165
|
+
extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
|
|
11166
|
+
try {
|
|
11167
|
+
extraDirs.push(path17.dirname(process.execPath));
|
|
11168
|
+
} catch {
|
|
11169
|
+
}
|
|
11170
|
+
}
|
|
11171
|
+
const searchDirs = [...paths, ...extraDirs];
|
|
10964
11172
|
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
10965
|
-
for (const p of
|
|
11173
|
+
for (const p of searchDirs) {
|
|
10966
11174
|
if (!p) continue;
|
|
10967
11175
|
for (const ext of exes) {
|
|
10968
11176
|
const fullPath = path17.join(p, trimmed + ext);
|
|
@@ -14362,6 +14570,37 @@ ${lastSnapshot}`;
|
|
|
14362
14570
|
if (!this.ptyProcess || typeof this.ptyProcess.getMetadata !== "function") return null;
|
|
14363
14571
|
return this.ptyProcess.getMetadata();
|
|
14364
14572
|
}
|
|
14573
|
+
/**
|
|
14574
|
+
* Launch metadata for the dashboard Session info panel. Re-derives the spawn plan
|
|
14575
|
+
* (pure — same inputs the live PTY was spawned with) so the dashboard sees the
|
|
14576
|
+
* resolved binary, full arg vector, and cwd without us having to persist it.
|
|
14577
|
+
* extraEnv values are intentionally dropped (keys only) so secrets passed at
|
|
14578
|
+
* launch time never reach the dashboard.
|
|
14579
|
+
*/
|
|
14580
|
+
getLaunchInfo() {
|
|
14581
|
+
let command;
|
|
14582
|
+
let args = [...this.extraArgs];
|
|
14583
|
+
try {
|
|
14584
|
+
const plan = resolveCliSpawnPlan({
|
|
14585
|
+
provider: this.provider,
|
|
14586
|
+
runtimeSettings: this.runtimeSettings,
|
|
14587
|
+
workingDir: this.workingDir,
|
|
14588
|
+
extraArgs: this.extraArgs,
|
|
14589
|
+
extraEnv: this.extraEnv
|
|
14590
|
+
});
|
|
14591
|
+
command = plan.binaryPath;
|
|
14592
|
+
args = plan.allArgs;
|
|
14593
|
+
} catch {
|
|
14594
|
+
}
|
|
14595
|
+
return {
|
|
14596
|
+
command,
|
|
14597
|
+
args,
|
|
14598
|
+
extraArgs: [...this.extraArgs],
|
|
14599
|
+
cwd: this.workingDir,
|
|
14600
|
+
extraEnvKeys: Object.keys(this.extraEnv || {}),
|
|
14601
|
+
providerSessionId: this.providerSessionId || void 0
|
|
14602
|
+
};
|
|
14603
|
+
}
|
|
14365
14604
|
updateRuntimeMeta(meta, replace = false) {
|
|
14366
14605
|
const nextProviderSessionId = typeof meta?.providerSessionId === "string" ? meta.providerSessionId.trim() : "";
|
|
14367
14606
|
if (nextProviderSessionId) {
|
|
@@ -15704,6 +15943,7 @@ __export(index_exports, {
|
|
|
15704
15943
|
DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS: () => DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS,
|
|
15705
15944
|
DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS,
|
|
15706
15945
|
DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS,
|
|
15946
|
+
DEFAULT_TASKMODE_ROLE_MAP: () => DEFAULT_TASKMODE_ROLE_MAP,
|
|
15707
15947
|
DEV_SERVER_PORT: () => DEV_SERVER_PORT,
|
|
15708
15948
|
DaemonAgentStreamManager: () => DaemonAgentStreamManager,
|
|
15709
15949
|
DaemonCdpInitializer: () => DaemonCdpInitializer,
|
|
@@ -15743,6 +15983,7 @@ __export(index_exports, {
|
|
|
15743
15983
|
RawTerminalAttachment: () => RawTerminalAttachment,
|
|
15744
15984
|
STALE_TERMINAL_REFINE_WINDOW_MS: () => STALE_TERMINAL_REFINE_WINDOW_MS,
|
|
15745
15985
|
STANDALONE_CDP_SCAN_INTERVAL_MS: () => STANDALONE_CDP_SCAN_INTERVAL_MS,
|
|
15986
|
+
STANDARD_MESH_ROLES: () => STANDARD_MESH_ROLES,
|
|
15746
15987
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
|
|
15747
15988
|
TerminalAdapter: () => TerminalAdapter,
|
|
15748
15989
|
TurnSnapshotTracker: () => TurnSnapshotTracker,
|
|
@@ -15976,9 +16217,12 @@ __export(index_exports, {
|
|
|
15976
16217
|
resolveGitRepository: () => resolveGitRepository,
|
|
15977
16218
|
resolveMeshHostStatus: () => resolveMeshHostStatus,
|
|
15978
16219
|
resolveMeshRefineValidationPlan: () => resolveMeshRefineValidationPlan,
|
|
16220
|
+
resolveMeshRoleOptions: () => resolveMeshRoleOptions,
|
|
15979
16221
|
resolveNodeSchedulingPriority: () => resolveNodeSchedulingPriority,
|
|
15980
16222
|
resolveSessionHostAppName: () => resolveSessionHostAppName,
|
|
15981
16223
|
resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution,
|
|
16224
|
+
resolveTaskAffinityRequiredTags: () => resolveTaskAffinityRequiredTags,
|
|
16225
|
+
resolveTaskAffinityRole: () => resolveTaskAffinityRole,
|
|
15982
16226
|
resolveWorktreePath: () => resolveWorktreePath,
|
|
15983
16227
|
runAsyncBatch: () => runAsyncBatch,
|
|
15984
16228
|
runGit: () => runGit,
|
|
@@ -18940,8 +19184,8 @@ async function detectIDEs(providerLoader) {
|
|
|
18940
19184
|
if ((0, import_fs12.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
18941
19185
|
}
|
|
18942
19186
|
if (!resolvedCli && appPath && os30 === "win32") {
|
|
18943
|
-
const { dirname:
|
|
18944
|
-
const appDir =
|
|
19187
|
+
const { dirname: dirname15 } = await import("path");
|
|
19188
|
+
const appDir = dirname15(appPath);
|
|
18945
19189
|
const candidates = [
|
|
18946
19190
|
`${appDir}\\\\bin\\\\${def.cli}.cmd`,
|
|
18947
19191
|
`${appDir}\\\\bin\\\\${def.cli}`,
|
|
@@ -43123,7 +43367,15 @@ var MESH_DIRECT_PROBE_MAX_RETRIES = 2;
|
|
|
43123
43367
|
function readMeshConnectionState(connection) {
|
|
43124
43368
|
return readStringValue(connection?.state);
|
|
43125
43369
|
}
|
|
43370
|
+
function isMeshConnectionDefinitivelyDown(connection) {
|
|
43371
|
+
if (!connection) return true;
|
|
43372
|
+
const state = readMeshConnectionState(connection);
|
|
43373
|
+
return state === "failed" || state === "closed" || state === "disconnected";
|
|
43374
|
+
}
|
|
43126
43375
|
async function probeRemoteMeshGitStatusWithRetry(args) {
|
|
43376
|
+
if (args.getConnection && isMeshConnectionDefinitivelyDown(args.getConnection(args.daemonId))) {
|
|
43377
|
+
return null;
|
|
43378
|
+
}
|
|
43127
43379
|
for (let attempt = 0; attempt <= MESH_DIRECT_PROBE_MAX_RETRIES; attempt += 1) {
|
|
43128
43380
|
if (attempt > 0) {
|
|
43129
43381
|
const connection = args.getConnection?.(args.daemonId);
|
|
@@ -47104,6 +47356,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
47104
47356
|
if (!target && !coord) return { success: false, error: "Session not found", sessionId };
|
|
47105
47357
|
const adapter = target ? this.deps.cliManager.findAdapter(target.providerType, { instanceKey: sessionId })?.adapter : void 0;
|
|
47106
47358
|
const runtimeMeta = adapter && typeof adapter.getRuntimeMetadata === "function" ? adapter.getRuntimeMetadata() : void 0;
|
|
47359
|
+
const launchInfo = adapter && typeof adapter.getLaunchInfo === "function" ? adapter.getLaunchInfo() : void 0;
|
|
47107
47360
|
const providerType = target?.providerType || coord?.cliType || "";
|
|
47108
47361
|
const providerMetaForSession = providerType ? this.deps.providerLoader.resolve?.(providerType) || this.deps.providerLoader.getMeta(providerType) : void 0;
|
|
47109
47362
|
return {
|
|
@@ -47115,8 +47368,11 @@ ${hintLines.join("\n")}` : "",
|
|
|
47115
47368
|
transport: target?.transport,
|
|
47116
47369
|
workspace: target?.workspace || coord?.workspace,
|
|
47117
47370
|
spawnedAtMs: target?.spawnedAtMs || coord?.startedAt,
|
|
47118
|
-
providerSessionId
|
|
47119
|
-
|
|
47371
|
+
// providerSessionId now comes from the live adapter's launch info
|
|
47372
|
+
// (the registry target never carried it — it was always undefined).
|
|
47373
|
+
providerSessionId: launchInfo?.providerSessionId || target?.providerSessionId,
|
|
47374
|
+
runtimeMetadata: runtimeMeta,
|
|
47375
|
+
launch: launchInfo
|
|
47120
47376
|
},
|
|
47121
47377
|
coordinator: coord ? {
|
|
47122
47378
|
meshId: coord.meshId,
|
|
@@ -48957,7 +49213,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48957
49213
|
};
|
|
48958
49214
|
}
|
|
48959
49215
|
const { existsSync: existsSync44, readFileSync: readFileSync35, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
|
|
48960
|
-
const { dirname:
|
|
49216
|
+
const { dirname: dirname15 } = await import("path");
|
|
48961
49217
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
48962
49218
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
48963
49219
|
let hermesBaseConfig = null;
|
|
@@ -48992,7 +49248,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48992
49248
|
};
|
|
48993
49249
|
}
|
|
48994
49250
|
try {
|
|
48995
|
-
mkdirSync21(
|
|
49251
|
+
mkdirSync21(dirname15(mcpConfigPath), { recursive: true });
|
|
48996
49252
|
} catch (error) {
|
|
48997
49253
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
48998
49254
|
LOG.error("MeshCoordinator", message);
|
|
@@ -49002,7 +49258,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
49002
49258
|
const hadExistingMcpConfig = existsSync44(mcpConfigPath);
|
|
49003
49259
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
49004
49260
|
if (hermesBaseConfig) {
|
|
49005
|
-
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome,
|
|
49261
|
+
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname15(mcpConfigPath));
|
|
49006
49262
|
}
|
|
49007
49263
|
if (hadExistingMcpConfig) {
|
|
49008
49264
|
try {
|
|
@@ -49040,7 +49296,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
49040
49296
|
const cliArgs = [];
|
|
49041
49297
|
const launchEnv = {};
|
|
49042
49298
|
if (configFormat === "hermes_config_yaml") {
|
|
49043
|
-
launchEnv.HERMES_HOME =
|
|
49299
|
+
launchEnv.HERMES_HOME = dirname15(mcpConfigPath);
|
|
49044
49300
|
launchEnv.HERMES_IGNORE_USER_CONFIG = "";
|
|
49045
49301
|
}
|
|
49046
49302
|
let autoImportContextFilePath;
|
|
@@ -58168,6 +58424,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
58168
58424
|
DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS,
|
|
58169
58425
|
DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS,
|
|
58170
58426
|
DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS,
|
|
58427
|
+
DEFAULT_TASKMODE_ROLE_MAP,
|
|
58171
58428
|
DEV_SERVER_PORT,
|
|
58172
58429
|
DaemonAgentStreamManager,
|
|
58173
58430
|
DaemonCdpInitializer,
|
|
@@ -58207,6 +58464,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
58207
58464
|
RawTerminalAttachment,
|
|
58208
58465
|
STALE_TERMINAL_REFINE_WINDOW_MS,
|
|
58209
58466
|
STANDALONE_CDP_SCAN_INTERVAL_MS,
|
|
58467
|
+
STANDARD_MESH_ROLES,
|
|
58210
58468
|
SessionHostPtyTransportFactory,
|
|
58211
58469
|
TerminalAdapter,
|
|
58212
58470
|
TurnSnapshotTracker,
|
|
@@ -58440,9 +58698,12 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
58440
58698
|
resolveGitRepository,
|
|
58441
58699
|
resolveMeshHostStatus,
|
|
58442
58700
|
resolveMeshRefineValidationPlan,
|
|
58701
|
+
resolveMeshRoleOptions,
|
|
58443
58702
|
resolveNodeSchedulingPriority,
|
|
58444
58703
|
resolveSessionHostAppName,
|
|
58445
58704
|
resolveSessionHostAppNameResolution,
|
|
58705
|
+
resolveTaskAffinityRequiredTags,
|
|
58706
|
+
resolveTaskAffinityRole,
|
|
58446
58707
|
resolveWorktreePath,
|
|
58447
58708
|
runAsyncBatch,
|
|
58448
58709
|
runGit,
|