agent-transport-system 0.7.5 → 0.7.6
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/ats.js +195 -75
- package/dist/ats.js.map +1 -1
- package/package.json +1 -1
package/dist/ats.js
CHANGED
|
@@ -27,7 +27,7 @@ import wrapAnsi from "wrap-ansi";
|
|
|
27
27
|
import { Box, Container, Editor, Key, ProcessTerminal, TUI, Text, getEditorKeybindings, matchesKey } from "@mariozechner/pi-tui";
|
|
28
28
|
|
|
29
29
|
//#region package.json
|
|
30
|
-
var version = "0.7.
|
|
30
|
+
var version = "0.7.6";
|
|
31
31
|
var package_default = {
|
|
32
32
|
$schema: "https://www.schemastore.org/package.json",
|
|
33
33
|
name: "agent-transport-system",
|
|
@@ -2510,6 +2510,14 @@ const SPACE_ADD_MEMBERS_PROGRESS_PHASES = [
|
|
|
2510
2510
|
}
|
|
2511
2511
|
];
|
|
2512
2512
|
const SPACE_ADD_MEMBERS_PROGRESS_OVERVIEW_STAGES = SPACE_ADD_MEMBERS_PROGRESS_PHASES.map((phase) => `${phase.stage}/${phase.phase}`);
|
|
2513
|
+
const SPACE_ADD_MEMBERS_AGENT_OVERVIEW_STAGES = [
|
|
2514
|
+
"check_arguments",
|
|
2515
|
+
"authenticate",
|
|
2516
|
+
"check_profile",
|
|
2517
|
+
"resolve_target",
|
|
2518
|
+
"add_members/write_membership",
|
|
2519
|
+
"record_join_notices/write_join_notices"
|
|
2520
|
+
];
|
|
2513
2521
|
function resolveSpaceAddMembersProgressPhase(input) {
|
|
2514
2522
|
const contract = SPACE_ADD_MEMBERS_PROGRESS_PHASES.find((phase) => phase.stage === input.stage && phase.phase === input.phase);
|
|
2515
2523
|
if (!contract) throw new Error(`unknown space add-members progress phase: ${input.stage}/${input.phase}`);
|
|
@@ -3273,7 +3281,7 @@ const COMMAND_ENTRY_CONTRACTS = {
|
|
|
3273
3281
|
},
|
|
3274
3282
|
notes: ["space is single-select; members support one or many selections.", "already-joined profiles are skipped automatically."],
|
|
3275
3283
|
pattern: getSpaceMemberSelectionPatternContract("add-members"),
|
|
3276
|
-
stages:
|
|
3284
|
+
stages: [...SPACE_ADD_MEMBERS_AGENT_OVERVIEW_STAGES],
|
|
3277
3285
|
summary: "Use `ats space add-members --profile <profile-id> <space-id> --member <profile-id...> --view agent` with explicit acting profile, Space ID, and member selection."
|
|
3278
3286
|
},
|
|
3279
3287
|
buildHints: (context) => getSpaceMemberSelectionPatternContract("add-members").buildHints?.({
|
|
@@ -60440,13 +60448,7 @@ function renderProfileSummaryCard(input) {
|
|
|
60440
60448
|
});
|
|
60441
60449
|
}
|
|
60442
60450
|
function buildAgentCreateNextSteps(profile) {
|
|
60443
|
-
if (profile.profileKind === "agent") return [
|
|
60444
|
-
formatAtsCliCommand(`ats setup --profile ${profile.atsProfileId} --local-agent <local-agent-id> --view agent`),
|
|
60445
|
-
formatAtsCliCommand(`ats setup --profile ${profile.atsProfileId} --view agent`),
|
|
60446
|
-
formatAtsCliCommand(`ats service status --profile ${profile.atsProfileId} --view agent`),
|
|
60447
|
-
formatAtsCliCommand(`ats profiles show ${profile.atsProfileId} --view agent`),
|
|
60448
|
-
formatAtsCliCommand(`ats whoami --profile ${profile.atsProfileId} --view agent`)
|
|
60449
|
-
];
|
|
60451
|
+
if (profile.profileKind === "agent") return [formatAtsCliCommand(`ats space add-members <space-id> --member ${profile.atsProfileId} --profile <human-profile-id> --view agent`)];
|
|
60450
60452
|
return [
|
|
60451
60453
|
formatAtsCliCommand("ats profiles list --view agent"),
|
|
60452
60454
|
formatAtsCliCommand(`ats profiles set ${profile.atsProfileId} --view agent`),
|
|
@@ -60460,28 +60462,24 @@ function buildAgentCreateWakeReadinessData(profile) {
|
|
|
60460
60462
|
return {
|
|
60461
60463
|
identityCreated: true,
|
|
60462
60464
|
wakeReadinessVerified: false,
|
|
60463
|
-
wakeReadinessNote: "
|
|
60465
|
+
wakeReadinessNote: "Profile creation creates the Space identity. Add it to a Space when the user wants this teammate to participate."
|
|
60464
60466
|
};
|
|
60465
60467
|
}
|
|
60466
60468
|
function buildProfileCreateWakeReadinessRows(input) {
|
|
60467
60469
|
if (input.state !== "created" || input.profile.profileKind !== "agent") return [];
|
|
60468
60470
|
return [{
|
|
60469
|
-
label: "
|
|
60470
|
-
value: "
|
|
60471
|
+
label: "Space identity",
|
|
60472
|
+
value: "Created"
|
|
60471
60473
|
}, {
|
|
60472
60474
|
label: "Next",
|
|
60473
|
-
value:
|
|
60475
|
+
value: "Add this profile to a Space when the user wants this teammate to participate."
|
|
60474
60476
|
}];
|
|
60475
60477
|
}
|
|
60476
60478
|
function buildAgentUpdateNextSteps(profile) {
|
|
60479
|
+
if (profile.profileKind === "agent") return [formatAtsCliCommand(`ats profiles show ${profile.atsProfileId} --view agent`), formatAtsCliCommand(`ats space add-members <space-id> --member ${profile.atsProfileId} --profile <human-profile-id> --view agent`)];
|
|
60477
60480
|
return [
|
|
60478
60481
|
formatAtsCliCommand(`ats profiles show ${profile.atsProfileId} --view agent`),
|
|
60479
60482
|
formatAtsCliCommand(`ats profiles update ${profile.atsProfileId} --name <new-name> --view agent`),
|
|
60480
|
-
formatAtsCliCommand(`ats setup --profile ${profile.atsProfileId} --local-agent <local-agent-id> --view agent`),
|
|
60481
|
-
formatAtsCliCommand(`ats setup --profile ${profile.atsProfileId} --view agent`),
|
|
60482
|
-
formatAtsCliCommand(`ats profiles update ${profile.atsProfileId} --workspace-mode ats-managed --view agent`),
|
|
60483
|
-
formatAtsCliCommand(`ats profiles update ${profile.atsProfileId} --workspace-mode custom --workspace-path /absolute/path --view agent`),
|
|
60484
|
-
formatAtsCliCommand(`ats whoami --profile ${profile.atsProfileId} --view agent`),
|
|
60485
60483
|
formatAtsCliCommand("ats profiles list --view agent")
|
|
60486
60484
|
];
|
|
60487
60485
|
}
|
|
@@ -69476,7 +69474,7 @@ const STAGES_BY_COMMAND = {
|
|
|
69476
69474
|
"resolve_target",
|
|
69477
69475
|
"read_or_update_guide"
|
|
69478
69476
|
],
|
|
69479
|
-
add_members:
|
|
69477
|
+
add_members: SPACE_ADD_MEMBERS_AGENT_OVERVIEW_STAGES,
|
|
69480
69478
|
remove_members: [
|
|
69481
69479
|
"check_arguments",
|
|
69482
69480
|
"authenticate",
|
|
@@ -83782,13 +83780,13 @@ function handleBlockedSpaceJoinLocalParticipation(input) {
|
|
|
83782
83780
|
if (input.assessmentState === "not_needed") {
|
|
83783
83781
|
input.presenter.line({
|
|
83784
83782
|
code: "space.join.service.not_needed",
|
|
83785
|
-
text: formatInlineAtsCliCommands("ATS will
|
|
83783
|
+
text: formatInlineAtsCliCommands("ATS will join this space. Local agent participation on this device can be checked later with `ats service status`.")
|
|
83786
83784
|
});
|
|
83787
83785
|
return "continue";
|
|
83788
83786
|
}
|
|
83789
83787
|
input.presenter.line({
|
|
83790
83788
|
code: "space.join.service.pending",
|
|
83791
|
-
text: formatInlineAtsCliCommands("ATS will
|
|
83789
|
+
text: formatInlineAtsCliCommands("ATS will join this space. Local agent participation on this device can be checked separately with `ats service status`.")
|
|
83792
83790
|
});
|
|
83793
83791
|
return "continue";
|
|
83794
83792
|
}
|
|
@@ -83801,10 +83799,10 @@ function buildSpaceJoinMembershipOnlyMessage(input) {
|
|
|
83801
83799
|
const profileId = input.atsProfile.atsProfileId;
|
|
83802
83800
|
const reasonCodes = input.reasonCodes;
|
|
83803
83801
|
const statusCommand = formatAtsCliCommand(`ats service status --profile ${profileId}`);
|
|
83804
|
-
if (reasonCodes.includes("profile.unbound")) return `${profileName} will join this space
|
|
83805
|
-
if (reasonCodes.some((reasonCode) => LOCAL_SERVICE_ONLY_JOIN_BLOCK_REASON_CODES.has(reasonCode)) || reasonCodes.includes("dispatch.storage_not_ready") || reasonCodes.includes("service.gateway_chain_unhealthy") || reasonCodes.includes("route.offline") || reasonCodes.includes("route.not_registered")) return formatInlineAtsCliCommands(`${profileName} will join this space
|
|
83802
|
+
if (reasonCodes.includes("profile.unbound")) return `${profileName} will join this space. Choose its local agent in ATS Web when you want it to handle work from this device.`;
|
|
83803
|
+
if (reasonCodes.some((reasonCode) => LOCAL_SERVICE_ONLY_JOIN_BLOCK_REASON_CODES.has(reasonCode)) || reasonCodes.includes("dispatch.storage_not_ready") || reasonCodes.includes("service.gateway_chain_unhealthy") || reasonCodes.includes("route.offline") || reasonCodes.includes("route.not_registered")) return formatInlineAtsCliCommands(`${profileName} will join this space. ATS has not confirmed its local reply path on this device yet. Use \`${statusCommand}\` to check this device.`);
|
|
83806
83804
|
if (reasonCodes.includes("controller.launch.needs_repair") || reasonCodes.includes("controller.launch.choice_required") || reasonCodes.includes("workspace.missing") || reasonCodes.includes("workspace.invalid")) return formatInlineAtsCliCommands(`${profileName} will join this space, but its local agent setup on this device needs attention. Use \`ats agents list\` to find the local agent, then run \`ats agents repair --agent <agent-id>\`.`);
|
|
83807
|
-
return `${profileName} will join this space
|
|
83805
|
+
return `${profileName} will join this space. Check Local Agents in ATS Web when you want it to handle work from this device.`;
|
|
83808
83806
|
}
|
|
83809
83807
|
function buildJoinTargetMissingMessage(input) {
|
|
83810
83808
|
return formatMessage(input.resolvedView, "space.target.missing", { command: "join" });
|
|
@@ -85054,6 +85052,8 @@ const SPACE_MEMBER_PROFILE_RECONNECT_REASON_CODES = new Set([
|
|
|
85054
85052
|
"local_service.identity_mismatch"
|
|
85055
85053
|
]);
|
|
85056
85054
|
const SPACE_MEMBER_SERVICE_STATUS_REASON_CODES = new Set([
|
|
85055
|
+
"agent_profile_binding.local_service_not_connected",
|
|
85056
|
+
"agent_profile_binding.execution_readiness_pending",
|
|
85057
85057
|
"route.offline",
|
|
85058
85058
|
"route.not_registered",
|
|
85059
85059
|
"service.gateway_chain_unhealthy",
|
|
@@ -85617,6 +85617,11 @@ function toAuthEndpoint(baseUrl, pathname) {
|
|
|
85617
85617
|
function buildSpaceWebUrl(baseUrl, spaceId) {
|
|
85618
85618
|
const url = new URL(baseUrl);
|
|
85619
85619
|
if (isLoopbackHostname(url.hostname) && url.port === "8080") url.port = "3000";
|
|
85620
|
+
if (url.hostname === "gateway.ats.sh") {
|
|
85621
|
+
url.hostname = "ats.sh";
|
|
85622
|
+
url.port = "";
|
|
85623
|
+
url.protocol = "https:";
|
|
85624
|
+
}
|
|
85620
85625
|
url.pathname = `/app/spaces/${encodeURIComponent(spaceId)}`;
|
|
85621
85626
|
url.search = "";
|
|
85622
85627
|
url.hash = "";
|
|
@@ -86129,7 +86134,7 @@ async function runSpaceAddMembers(input) {
|
|
|
86129
86134
|
resolvedView: runtime.resolvedView,
|
|
86130
86135
|
interactive
|
|
86131
86136
|
});
|
|
86132
|
-
await emitSpaceCommandPreflight({
|
|
86137
|
+
if (shouldRunSpaceAddMembersDiagnosticPreflight(input, explicitMemberIds)) await emitSpaceCommandPreflight({
|
|
86133
86138
|
presenter,
|
|
86134
86139
|
command: "add_members",
|
|
86135
86140
|
profile: atsProfile,
|
|
@@ -86321,6 +86326,12 @@ async function runSpaceLeave(input) {
|
|
|
86321
86326
|
throw error;
|
|
86322
86327
|
}
|
|
86323
86328
|
}
|
|
86329
|
+
function shouldRunSpaceAddMembersDiagnosticPreflight(input, explicitMemberIds) {
|
|
86330
|
+
return input.details === true || input.all === true || explicitMemberIds.length === 0;
|
|
86331
|
+
}
|
|
86332
|
+
function shouldUseFastExplicitSpaceAddMembers(input) {
|
|
86333
|
+
return input.details !== true && input.explicitMemberIds.length > 0;
|
|
86334
|
+
}
|
|
86324
86335
|
async function runSpaceAddMembersForTarget(input) {
|
|
86325
86336
|
const targetBaseUrl = input.hasExplicitBaseUrlInput ? input.baseUrl : input.target.baseUrl ?? input.baseUrl;
|
|
86326
86337
|
const authenticatedGatewayUrl = await ensureSpaceCommandGatewayAuthenticationOrCancel({
|
|
@@ -86338,6 +86349,7 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
86338
86349
|
};
|
|
86339
86350
|
const explicitMemberIds = normalizeRequestedMemberIds(input.explicitMembers);
|
|
86340
86351
|
const progress = input.details || explicitMemberIds.length === 0 ? addMembersProgress : void 0;
|
|
86352
|
+
const includeLocalParticipation = progress !== void 0 || explicitMemberIds.length === 0;
|
|
86341
86353
|
const candidates = await resolveSpaceMemberCandidatesForAdd({
|
|
86342
86354
|
currentProfile: input.atsProfile,
|
|
86343
86355
|
currentOwnerUserId: input.atsProfile.ownerUserId,
|
|
@@ -86345,7 +86357,12 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
86345
86357
|
baseUrl: targetBaseUrl,
|
|
86346
86358
|
password: input.password,
|
|
86347
86359
|
explicitMemberIds,
|
|
86348
|
-
progress
|
|
86360
|
+
progress,
|
|
86361
|
+
fastExplicitMembers: shouldUseFastExplicitSpaceAddMembers({
|
|
86362
|
+
details: input.details,
|
|
86363
|
+
explicitMemberIds
|
|
86364
|
+
}),
|
|
86365
|
+
includeLocalParticipation
|
|
86349
86366
|
});
|
|
86350
86367
|
if (candidates.length === 0 && explicitMemberIds.length === 0) {
|
|
86351
86368
|
input.presenter.line({
|
|
@@ -86377,15 +86394,10 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
86377
86394
|
selectedProfileIds
|
|
86378
86395
|
});
|
|
86379
86396
|
if (selectedCandidates.length === 0) return { status: "completed" };
|
|
86380
|
-
|
|
86381
|
-
stage: "check_local_wake_readiness",
|
|
86382
|
-
phase: "start",
|
|
86383
|
-
summary: "Checking whether selected agent profiles can wake from this computer. Members can still be added if local Wake setup needs attention.",
|
|
86384
|
-
profileIds: selectedCandidates.map((candidate) => candidate.profileId)
|
|
86385
|
-
});
|
|
86386
|
-
const servicePreparationResult = await ensureSpaceMemberCandidatesLocalParticipationReady({
|
|
86397
|
+
const servicePreparationResult = await prepareSpaceAddMembersLocalParticipationIfRequested({
|
|
86387
86398
|
atsProfile: input.atsProfile,
|
|
86388
86399
|
candidates: selectedCandidates,
|
|
86400
|
+
enabled: includeLocalParticipation,
|
|
86389
86401
|
progress,
|
|
86390
86402
|
presenter: input.presenter,
|
|
86391
86403
|
resolvedView: input.runtime.resolvedView,
|
|
@@ -86455,6 +86467,28 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
86455
86467
|
});
|
|
86456
86468
|
return { status: "completed" };
|
|
86457
86469
|
}
|
|
86470
|
+
async function prepareSpaceAddMembersLocalParticipationIfRequested(input) {
|
|
86471
|
+
if (!input.enabled) return {
|
|
86472
|
+
status: "continue",
|
|
86473
|
+
candidates: input.candidates
|
|
86474
|
+
};
|
|
86475
|
+
emitSpaceAddMembersProgressIfRequested(input.progress, {
|
|
86476
|
+
stage: "check_local_wake_readiness",
|
|
86477
|
+
phase: "start",
|
|
86478
|
+
summary: "Checking whether selected agent profiles can handle work from this computer. Members can still be added if local setup needs attention.",
|
|
86479
|
+
profileIds: input.candidates.map((candidate) => candidate.profileId)
|
|
86480
|
+
});
|
|
86481
|
+
return await ensureSpaceMemberCandidatesLocalParticipationReady({
|
|
86482
|
+
atsProfile: input.atsProfile,
|
|
86483
|
+
candidates: input.candidates,
|
|
86484
|
+
progress: input.progress,
|
|
86485
|
+
presenter: input.presenter,
|
|
86486
|
+
resolvedView: input.resolvedView,
|
|
86487
|
+
allowPrompt: input.allowPrompt,
|
|
86488
|
+
spaceId: input.spaceId,
|
|
86489
|
+
view: input.view
|
|
86490
|
+
});
|
|
86491
|
+
}
|
|
86458
86492
|
function emitSpaceAddMembersProgressIfRequested(progress, input) {
|
|
86459
86493
|
if (!progress) return;
|
|
86460
86494
|
emitAgentSpaceAddMembersProgress({
|
|
@@ -86503,13 +86537,13 @@ function buildSpaceAddMembersLocalWakePlanSummary(plan) {
|
|
|
86503
86537
|
if (assessment.profileKind !== "agent") continue;
|
|
86504
86538
|
counts.set(assessment.localParticipationState, (counts.get(assessment.localParticipationState) ?? 0) + 1);
|
|
86505
86539
|
}
|
|
86506
|
-
return `Local
|
|
86507
|
-
formatLocalWakePlanCount(counts.get("ready") ?? 0, "
|
|
86540
|
+
return `Local agent plan: ${[
|
|
86541
|
+
formatLocalWakePlanCount(counts.get("ready") ?? 0, "can handle work from this device"),
|
|
86508
86542
|
formatLocalWakePlanCount(counts.get("needs_agent_prepare") ?? 0, "need agent preparation"),
|
|
86509
86543
|
formatLocalWakePlanCount(counts.get("needs_ats_service") ?? 0, "need ATS Service"),
|
|
86510
86544
|
formatLocalWakePlanCount(counts.get("membership_only") ?? 0, "will be added as members only"),
|
|
86511
|
-
formatLocalWakePlanCount(counts.get("not_needed") ?? 0, "do not need local
|
|
86512
|
-
].filter((part) => Boolean(part)).join(", ")}. Adding members is separate from
|
|
86545
|
+
formatLocalWakePlanCount(counts.get("not_needed") ?? 0, "do not need local agent setup")
|
|
86546
|
+
].filter((part) => Boolean(part)).join(", ")}. Adding members is separate from local agent participation on this computer.`;
|
|
86513
86547
|
}
|
|
86514
86548
|
function formatLocalWakePlanCount(count, label) {
|
|
86515
86549
|
return count > 0 ? `${String(count)} ${label}` : null;
|
|
@@ -86672,7 +86706,7 @@ async function ensureSpaceMemberCandidatesLocalParticipationReady(input) {
|
|
|
86672
86706
|
candidates: preparedCandidates.map(toActionParticipationCandidateFromSpaceMemberCandidate)
|
|
86673
86707
|
}).shouldOfferServiceGate) input.presenter.line({
|
|
86674
86708
|
code: input.resolvedView === "human" && input.allowPrompt ? "space.add_members.service.declined" : "space.add_members.service.deferred",
|
|
86675
|
-
text: formatInlineAtsCliCommands("ATS will
|
|
86709
|
+
text: formatInlineAtsCliCommands("ATS will add these profiles to the Space. Local agent participation can be checked separately with `ats service status`.")
|
|
86676
86710
|
});
|
|
86677
86711
|
return {
|
|
86678
86712
|
status: "continue",
|
|
@@ -86746,17 +86780,18 @@ function emitSpaceMemberJoinOnlyWarnings(input) {
|
|
|
86746
86780
|
}
|
|
86747
86781
|
function buildSpaceMemberJoinOnlyWarning(candidate) {
|
|
86748
86782
|
if (candidate.profileKind !== "agent") return null;
|
|
86783
|
+
if (candidate.localParticipationChecked !== true) return null;
|
|
86749
86784
|
if (isSpaceMemberCandidateBackgroundReplyReady(candidate)) return null;
|
|
86750
86785
|
const profileLabel = resolveSpaceMemberTerminalProfileLabel(candidate.profileName);
|
|
86751
|
-
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) return `${profileLabel} can join this space now
|
|
86786
|
+
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) return `${profileLabel} can join this space now. ${resolveSpaceMemberTerminalLocalTargetLabel({
|
|
86752
86787
|
displayName: candidate.localTargetDisplayName,
|
|
86753
86788
|
agentId: candidate.localTargetAgentId
|
|
86754
|
-
})} still needs local setup on this device before it can
|
|
86789
|
+
})} still needs local setup on this device before it can handle work from the Space. Use \`${buildSpaceMemberRepairCommand({
|
|
86755
86790
|
agentId: candidate.localTargetAgentId,
|
|
86756
86791
|
profileId: candidate.profileId
|
|
86757
|
-
})}\`
|
|
86792
|
+
})}\` to repair the local agent.`;
|
|
86758
86793
|
const nextAction = resolveSpaceMemberJoinOnlyNextAction(candidate);
|
|
86759
|
-
return `${profileLabel} can join this space now
|
|
86794
|
+
return `${profileLabel} can join this space now. ATS has not confirmed its local reply path on this device yet. ${resolveSpaceMemberJoinOnlyReason(candidate)} ${formatSpaceMemberRecoveryNextAction(nextAction)}`;
|
|
86760
86795
|
}
|
|
86761
86796
|
function resolveSpaceMemberJoinOnlyNextAction(candidate) {
|
|
86762
86797
|
if (candidate.localParticipationReadiness === "not_running") return {
|
|
@@ -86834,6 +86869,7 @@ async function refreshSpaceMemberCandidatesLocalReadiness(candidates, progress,
|
|
|
86834
86869
|
async function enrichSpaceMemberCandidateLocalParticipationReadiness(candidate, progress, options = {}) {
|
|
86835
86870
|
if (candidate.profileKind !== "agent" || !candidate.atsProfile || candidate.controllerEnabled !== true || typeof candidate.controllerRef !== "string" || candidate.controllerRef.trim().length === 0) return {
|
|
86836
86871
|
...candidate,
|
|
86872
|
+
localParticipationChecked: true,
|
|
86837
86873
|
localParticipationReadiness: null,
|
|
86838
86874
|
localParticipationReasonCodes: [],
|
|
86839
86875
|
localParticipationReasonText: null
|
|
@@ -86872,6 +86908,7 @@ async function enrichSpaceMemberCandidateLocalParticipationReadiness(candidate,
|
|
|
86872
86908
|
}
|
|
86873
86909
|
if (!snapshot) return {
|
|
86874
86910
|
...candidate,
|
|
86911
|
+
localParticipationChecked: true,
|
|
86875
86912
|
localParticipationReadiness: null,
|
|
86876
86913
|
localParticipationReasonCodes: [],
|
|
86877
86914
|
localParticipationReasonText: null
|
|
@@ -86883,6 +86920,7 @@ async function enrichSpaceMemberCandidateLocalParticipationReadiness(candidate,
|
|
|
86883
86920
|
});
|
|
86884
86921
|
return {
|
|
86885
86922
|
...candidate,
|
|
86923
|
+
localParticipationChecked: true,
|
|
86886
86924
|
localParticipationReadiness: readinessSummary.serviceReadiness,
|
|
86887
86925
|
localParticipationReasonCodes: [...snapshot.deviceReplyReadiness.reasonCodes],
|
|
86888
86926
|
localParticipationReasonText: snapshot.deviceReplyReadiness.reasonText
|
|
@@ -88159,6 +88197,9 @@ function mapSpaceLeaveFailureToGuideError(input) {
|
|
|
88159
88197
|
return input.error instanceof Error ? input.error : new Error(String(input.error));
|
|
88160
88198
|
}
|
|
88161
88199
|
async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
88200
|
+
const explicitMemberIds = normalizeRequestedMemberIds(input.explicitMemberIds);
|
|
88201
|
+
const includeLocalParticipation = input.includeLocalParticipation !== false;
|
|
88202
|
+
if (input.fastExplicitMembers === true && explicitMemberIds.length > 0) return explicitMemberIds.map(buildFastExplicitSpaceMemberCandidate);
|
|
88162
88203
|
if (input.progress) emitAgentSpaceAddMembersProgress({
|
|
88163
88204
|
...input.progress,
|
|
88164
88205
|
stage: "resolve_candidates",
|
|
@@ -88166,23 +88207,19 @@ async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
|
88166
88207
|
summary: "Reading active local profile identities for this Space."
|
|
88167
88208
|
});
|
|
88168
88209
|
const profiles = await listAtsProfiles();
|
|
88169
|
-
if (input.progress) emitAgentSpaceAddMembersProgress({
|
|
88210
|
+
if (input.progress && includeLocalParticipation) emitAgentSpaceAddMembersProgress({
|
|
88170
88211
|
...input.progress,
|
|
88171
88212
|
stage: "resolve_candidates",
|
|
88172
88213
|
phase: "read_local_targets",
|
|
88173
88214
|
summary: "Reading local agent controller state for candidate profiles before selection."
|
|
88174
88215
|
});
|
|
88175
|
-
const localTargetStates =
|
|
88176
|
-
|
|
88177
|
-
|
|
88178
|
-
|
|
88179
|
-
summary: "Still reading local agent controller state for candidate profiles before selection.",
|
|
88180
|
-
operation: async () => await listAgentTargetStates().catch(() => [])
|
|
88181
|
-
}) : await listAgentTargetStates().catch(() => []);
|
|
88216
|
+
const localTargetStates = await listSpaceAddMembersLocalTargetStatesIfRequested({
|
|
88217
|
+
includeLocalParticipation,
|
|
88218
|
+
progress: input.progress
|
|
88219
|
+
});
|
|
88182
88220
|
const localTargetStateById = new Map(localTargetStates.map((state) => [state.agentId, state]));
|
|
88183
88221
|
const ownerProfileNameByOwnerUserId = buildOwnerProfileNameByOwnerUserId(profiles);
|
|
88184
88222
|
const candidateProfiles = profiles.filter((profile) => profile.status === "active" && isSpaceMembershipProfileKind(profile.profileKind) && profile.atsProfileId !== input.currentProfile.atsProfileId).filter((profile) => {
|
|
88185
|
-
const explicitMemberIds = input.explicitMemberIds ?? [];
|
|
88186
88223
|
if (explicitMemberIds.length > 0 && !explicitMemberIds.includes(profile.atsProfileId)) return false;
|
|
88187
88224
|
return typeof input.currentOwnerUserId !== "string" || input.currentOwnerUserId.trim().length === 0 || profile.ownerUserId === input.currentOwnerUserId;
|
|
88188
88225
|
});
|
|
@@ -88199,29 +88236,58 @@ async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
|
88199
88236
|
...input.password === void 0 ? {} : { spacePassword: input.password }
|
|
88200
88237
|
});
|
|
88201
88238
|
const memberProfileIds = new Set([...membersSnapshot.humans, ...membersSnapshot.agents].map((member) => member.profileId));
|
|
88202
|
-
|
|
88239
|
+
const candidates = (await Promise.all(candidateProfiles.map((profile) => buildSpaceMemberCandidateFromProfile({
|
|
88203
88240
|
baseUrl: input.baseUrl,
|
|
88204
88241
|
profile,
|
|
88205
88242
|
localTargetStateById,
|
|
88206
88243
|
ownerProfileName: ownerProfileNameByOwnerUserId.get(profile.ownerUserId) ?? void 0,
|
|
88207
88244
|
alreadyJoined: memberProfileIds.has(profile.atsProfileId),
|
|
88208
|
-
progress: input.progress
|
|
88245
|
+
progress: input.progress,
|
|
88246
|
+
includeLocalParticipation
|
|
88209
88247
|
})))).sort((left, right) => {
|
|
88210
88248
|
const byName = left.profileName.localeCompare(right.profileName);
|
|
88211
88249
|
if (byName !== 0) return byName;
|
|
88212
88250
|
return left.profileId.localeCompare(right.profileId);
|
|
88213
|
-
})
|
|
88251
|
+
});
|
|
88252
|
+
if (!includeLocalParticipation) return candidates;
|
|
88253
|
+
return await refreshSpaceMemberCandidatesLocalReadiness(candidates, input.progress, { stage: "resolve_candidates" });
|
|
88214
88254
|
}
|
|
88215
|
-
|
|
88216
|
-
|
|
88255
|
+
function buildFastExplicitSpaceMemberCandidate(profileId) {
|
|
88256
|
+
return {
|
|
88257
|
+
profileId,
|
|
88258
|
+
profileName: profileId,
|
|
88259
|
+
profileKind: profileId.startsWith("agt_") ? "agent" : "human",
|
|
88260
|
+
targetMentionLabel: null,
|
|
88261
|
+
localTargetAgentId: null,
|
|
88262
|
+
localTargetDisplayName: null,
|
|
88263
|
+
localTargetLaunchStatus: null,
|
|
88264
|
+
localTargetSelectable: false,
|
|
88265
|
+
localParticipationReadiness: null,
|
|
88266
|
+
localParticipationChecked: false,
|
|
88267
|
+
localParticipationReasonCodes: [],
|
|
88268
|
+
localParticipationReasonText: null,
|
|
88269
|
+
alreadyJoined: false,
|
|
88270
|
+
needsActivation: false
|
|
88271
|
+
};
|
|
88272
|
+
}
|
|
88273
|
+
async function listSpaceAddMembersLocalTargetStatesIfRequested(input) {
|
|
88274
|
+
if (!input.includeLocalParticipation) return [];
|
|
88275
|
+
if (!input.progress) return await listAgentTargetStates().catch(() => []);
|
|
88276
|
+
return await runSpaceAddMembersProgressHeartbeat({
|
|
88217
88277
|
...input.progress,
|
|
88218
88278
|
stage: "resolve_candidates",
|
|
88219
|
-
phase: "
|
|
88220
|
-
summary:
|
|
88221
|
-
|
|
88222
|
-
profileIds: [input.profile.atsProfileId]
|
|
88279
|
+
phase: "read_local_targets_wait",
|
|
88280
|
+
summary: "Still reading local agent controller state for candidate profiles before selection.",
|
|
88281
|
+
operation: async () => await listAgentTargetStates().catch(() => [])
|
|
88223
88282
|
});
|
|
88224
|
-
|
|
88283
|
+
}
|
|
88284
|
+
async function resolveSpaceMemberCandidateRuntimeCapabilityIfRequested(input) {
|
|
88285
|
+
if (!input.includeLocalParticipation) return null;
|
|
88286
|
+
if (!input.progress) return await resolveAgentProfilePrimaryRuntimeCapability({
|
|
88287
|
+
baseUrl: input.baseUrl,
|
|
88288
|
+
profile: input.profile
|
|
88289
|
+
}).catch(() => null);
|
|
88290
|
+
return await runSpaceAddMembersProgressHeartbeat({
|
|
88225
88291
|
...input.progress,
|
|
88226
88292
|
stage: "resolve_candidates",
|
|
88227
88293
|
phase: "read_runtime_capability_wait",
|
|
@@ -88232,10 +88298,24 @@ async function buildSpaceMemberCandidateFromProfile(input) {
|
|
|
88232
88298
|
baseUrl: input.baseUrl,
|
|
88233
88299
|
profile: input.profile
|
|
88234
88300
|
}).catch(() => null)
|
|
88235
|
-
})
|
|
88301
|
+
});
|
|
88302
|
+
}
|
|
88303
|
+
async function buildSpaceMemberCandidateFromProfile(input) {
|
|
88304
|
+
const includeLocalParticipation = input.includeLocalParticipation !== false;
|
|
88305
|
+
if (input.progress && includeLocalParticipation) emitAgentSpaceAddMembersProgress({
|
|
88306
|
+
...input.progress,
|
|
88307
|
+
stage: "resolve_candidates",
|
|
88308
|
+
phase: "read_runtime_capability",
|
|
88309
|
+
summary: `Reading runtime capability projection for ${resolveSpaceMemberTerminalProfileLabel(input.profile.profileName)}.`,
|
|
88310
|
+
profileId: input.profile.atsProfileId,
|
|
88311
|
+
profileIds: [input.profile.atsProfileId]
|
|
88312
|
+
});
|
|
88313
|
+
const runtimeCapability = await resolveSpaceMemberCandidateRuntimeCapabilityIfRequested({
|
|
88236
88314
|
baseUrl: input.baseUrl,
|
|
88237
|
-
|
|
88238
|
-
|
|
88315
|
+
includeLocalParticipation,
|
|
88316
|
+
profile: input.profile,
|
|
88317
|
+
progress: input.progress
|
|
88318
|
+
});
|
|
88239
88319
|
const controllerRef = runtimeCapability?.capabilityRef ?? void 0;
|
|
88240
88320
|
const controllerEnabled = runtimeCapability?.bindingState === "enabled_primary" && runtimeCapability.routable;
|
|
88241
88321
|
const localTargetAgentId = resolveSpaceMemberCandidateLocalTargetAgentId({
|
|
@@ -88260,6 +88340,7 @@ async function buildSpaceMemberCandidateFromProfile(input) {
|
|
|
88260
88340
|
localTargetLaunchStatus: localTargetState?.launchStatus ?? null,
|
|
88261
88341
|
localTargetSelectable: localTargetState?.selectable ?? false,
|
|
88262
88342
|
localParticipationReadiness: null,
|
|
88343
|
+
localParticipationChecked: false,
|
|
88263
88344
|
localParticipationReasonCodes: [],
|
|
88264
88345
|
localParticipationReasonText: null,
|
|
88265
88346
|
alreadyJoined: input.alreadyJoined,
|
|
@@ -88588,14 +88669,19 @@ async function applySpaceAddMembers(input) {
|
|
|
88588
88669
|
}
|
|
88589
88670
|
const addedProfileIds = new Set(response.addedMemberIds);
|
|
88590
88671
|
const alreadyMemberProfileIds = new Set(response.alreadyMemberIds);
|
|
88672
|
+
const responseItemByProfileId = new Map(response.items.map((item) => [item.profileId, item]));
|
|
88591
88673
|
const lastJoinedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
88592
88674
|
const spaceName = normalizeOptionalString$1(input.spaceName);
|
|
88593
88675
|
for (const candidate of selectedCandidates) {
|
|
88676
|
+
const nextCandidate = hydrateSpaceMemberCandidateFromResponseItem({
|
|
88677
|
+
candidate,
|
|
88678
|
+
item: responseItemByProfileId.get(candidate.profileId)
|
|
88679
|
+
});
|
|
88594
88680
|
if (addedProfileIds.has(candidate.profileId)) {
|
|
88595
|
-
result.added.push(
|
|
88681
|
+
result.added.push(nextCandidate);
|
|
88596
88682
|
continue;
|
|
88597
88683
|
}
|
|
88598
|
-
if (alreadyMemberProfileIds.has(candidate.profileId)) result.alreadyJoined.push(
|
|
88684
|
+
if (alreadyMemberProfileIds.has(candidate.profileId)) result.alreadyJoined.push(nextCandidate);
|
|
88599
88685
|
}
|
|
88600
88686
|
for (const candidate of result.added) try {
|
|
88601
88687
|
await upsertProfileSpaceHistory({
|
|
@@ -88622,6 +88708,27 @@ async function applySpaceAddMembers(input) {
|
|
|
88622
88708
|
}
|
|
88623
88709
|
return result;
|
|
88624
88710
|
}
|
|
88711
|
+
function hydrateSpaceMemberCandidateFromResponseItem(input) {
|
|
88712
|
+
if (!input.item) return input.candidate;
|
|
88713
|
+
return {
|
|
88714
|
+
...input.candidate,
|
|
88715
|
+
profileName: input.item.profileName,
|
|
88716
|
+
profileKind: input.item.profileKind,
|
|
88717
|
+
ownerUserId: normalizeOptionalString$1(input.item.ownerUserId) ?? void 0,
|
|
88718
|
+
ownerName: normalizeOptionalString$1(input.item.ownerName) ?? void 0,
|
|
88719
|
+
targetMentionLabel: resolvePrimaryMentionLabelFromSpaceMemberItem(input.item),
|
|
88720
|
+
...input.item.profileKind === "agent" ? { controllerRef: normalizeOptionalString$1(input.item.controllerRef) ?? input.candidate.controllerRef } : {}
|
|
88721
|
+
};
|
|
88722
|
+
}
|
|
88723
|
+
function resolvePrimaryMentionLabelFromSpaceMemberItem(item) {
|
|
88724
|
+
const mentionAlias = normalizeOptionalString$1(item.mentionAlias);
|
|
88725
|
+
if (mentionAlias) return mentionAlias;
|
|
88726
|
+
return resolveSingleSpaceMentionLabels({
|
|
88727
|
+
mentionAlias,
|
|
88728
|
+
profileId: item.profileId,
|
|
88729
|
+
profileName: item.profileName
|
|
88730
|
+
}).primaryMentionLabel;
|
|
88731
|
+
}
|
|
88625
88732
|
async function waitForAddedMembersWakeProjection(input) {
|
|
88626
88733
|
const expectedWakeableProfileIds = resolveExpectedWakeProjectionProfileIds(input.result);
|
|
88627
88734
|
if (expectedWakeableProfileIds.length === 0) return;
|
|
@@ -88728,6 +88835,7 @@ function emitSpaceAddMembersResult(input) {
|
|
|
88728
88835
|
}
|
|
88729
88836
|
function buildSpaceMemberJoinedFollowUp(candidate) {
|
|
88730
88837
|
if (candidate.profileKind !== "agent") return null;
|
|
88838
|
+
if (candidate.localParticipationChecked !== true) return null;
|
|
88731
88839
|
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) {
|
|
88732
88840
|
const repairCommand = buildSpaceMemberRepairCommand({
|
|
88733
88841
|
agentId: candidate.localTargetAgentId,
|
|
@@ -88741,7 +88849,7 @@ function buildSpaceMemberJoinedFollowUp(candidate) {
|
|
|
88741
88849
|
return {
|
|
88742
88850
|
profileId: candidate.profileId,
|
|
88743
88851
|
reasonCodes: candidate.localParticipationReasonCodes ?? [],
|
|
88744
|
-
text: `${profileLabel} joined this space
|
|
88852
|
+
text: `${profileLabel} joined this space. ${agentLabel} still needs repair on this device before it can handle work from the Space. Use \`${repairCommand}\` to repair the local agent.`
|
|
88745
88853
|
};
|
|
88746
88854
|
}
|
|
88747
88855
|
if (!isSpaceMemberCandidateRunnableLocalParticipationCandidate(candidate)) {
|
|
@@ -88750,7 +88858,7 @@ function buildSpaceMemberJoinedFollowUp(candidate) {
|
|
|
88750
88858
|
return {
|
|
88751
88859
|
profileId: candidate.profileId,
|
|
88752
88860
|
reasonCodes: candidate.localParticipationReasonCodes ?? [],
|
|
88753
|
-
text: `${profileLabel} joined this space
|
|
88861
|
+
text: `${profileLabel} joined this space. ATS has not confirmed its local reply path on this device yet. ${formatSpaceMemberRecoveryNextAction(nextAction)}`
|
|
88754
88862
|
};
|
|
88755
88863
|
}
|
|
88756
88864
|
return null;
|
|
@@ -88985,8 +89093,8 @@ async function persistSpaceAddMembersJoinNotices(input) {
|
|
|
88985
89093
|
failedCount: 0
|
|
88986
89094
|
};
|
|
88987
89095
|
const failures = [];
|
|
88988
|
-
let targetMentionLabelByProfileId;
|
|
88989
|
-
try {
|
|
89096
|
+
let targetMentionLabelByProfileId = buildKnownMentionLabelByProfileId(input.addedMembers);
|
|
89097
|
+
if (!hasMentionLabelsForAllMembers(input.addedMembers, targetMentionLabelByProfileId)) try {
|
|
88990
89098
|
targetMentionLabelByProfileId = buildSpacePrimaryMentionLabelByProfileId(await createCliSpaceApi(input.baseUrl).getMembersSnapshot({
|
|
88991
89099
|
spaceId: input.space,
|
|
88992
89100
|
requestContext: buildAtsRequestContextFromProfile({ atsProfile: input.actorProfile }),
|
|
@@ -89032,6 +89140,17 @@ async function persistSpaceAddMembersJoinNotices(input) {
|
|
|
89032
89140
|
...failures[0] ? { firstFailure: toStructuredGatewayFailure(failures[0].error) } : {}
|
|
89033
89141
|
};
|
|
89034
89142
|
}
|
|
89143
|
+
function buildKnownMentionLabelByProfileId(members) {
|
|
89144
|
+
const labelsByProfileId = /* @__PURE__ */ new Map();
|
|
89145
|
+
for (const member of members) {
|
|
89146
|
+
const targetMentionLabel = normalizeOptionalString$1(member.targetMentionLabel);
|
|
89147
|
+
if (targetMentionLabel) labelsByProfileId.set(member.profileId, targetMentionLabel);
|
|
89148
|
+
}
|
|
89149
|
+
return labelsByProfileId;
|
|
89150
|
+
}
|
|
89151
|
+
function hasMentionLabelsForAllMembers(members, labelsByProfileId) {
|
|
89152
|
+
return members.every((member) => labelsByProfileId.has(member.profileId));
|
|
89153
|
+
}
|
|
89035
89154
|
async function postSpaceAddMemberJoinNotice(input) {
|
|
89036
89155
|
const requestContext = buildAtsRequestContextFromProfile({ atsProfile: input.actorProfile });
|
|
89037
89156
|
await createCliSpaceApi(input.baseUrl).postNormalMessage({
|
|
@@ -89217,8 +89336,9 @@ function resolveSpaceMemberCandidateStatusLabel(candidate) {
|
|
|
89217
89336
|
const TRAILING_PERIOD_RE = /\.$/u;
|
|
89218
89337
|
function resolveSpaceMemberCandidateStatusBadges(candidate) {
|
|
89219
89338
|
if (candidate.profileKind !== "agent") return [];
|
|
89339
|
+
if (candidate.localParticipationChecked !== true) return [];
|
|
89220
89340
|
if (isSpaceMemberCandidateBackgroundReplyReady(candidate)) return ["Local setup connected"];
|
|
89221
|
-
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) return ["Needs repair
|
|
89341
|
+
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) return ["Needs repair"];
|
|
89222
89342
|
return [resolveSpaceMemberJoinOnlyReason(candidate).replace(TRAILING_PERIOD_RE, ""), "Joins only for now"];
|
|
89223
89343
|
}
|
|
89224
89344
|
function isSpaceMemberCandidateBackgroundReplyReady(candidate) {
|
|
@@ -89242,7 +89362,7 @@ function resolveSpaceMemberProfileConnectionAction(candidate) {
|
|
|
89242
89362
|
kind: "instruction"
|
|
89243
89363
|
};
|
|
89244
89364
|
if (candidate.controllerEnabled !== true || typeof candidate.controllerRef !== "string" || candidate.controllerRef.trim().length === 0 || reasonCodes.some((reasonCode) => SPACE_MEMBER_PROFILE_CONNECTION_REASON_CODES.has(reasonCode))) return {
|
|
89245
|
-
instruction: "Open this Agent in ATS Web and choose the local agent that should handle
|
|
89365
|
+
instruction: "Open this Agent in ATS Web and choose the local agent that should handle work from the Space.",
|
|
89246
89366
|
kind: "instruction"
|
|
89247
89367
|
};
|
|
89248
89368
|
if (reasonCodes.includes("controller.binding.disabled")) return {
|
|
@@ -89255,9 +89375,9 @@ function hasSpaceMemberReasonCode(candidate, reasonCodes) {
|
|
|
89255
89375
|
return (candidate.localParticipationReasonCodes ?? []).some((reasonCode) => reasonCodes.has(reasonCode));
|
|
89256
89376
|
}
|
|
89257
89377
|
function formatSpaceMemberRecoveryNextAction(action) {
|
|
89258
|
-
if (action.kind === "instruction") return
|
|
89259
|
-
if (action.command === "ats agents list") return formatInlineAtsCliCommands("Use `ats agents list` to find the local agent that needs repair
|
|
89260
|
-
return `Use \`${formatAtsCliCommand(action.command)}\`
|
|
89378
|
+
if (action.kind === "instruction") return action.instruction;
|
|
89379
|
+
if (action.command === "ats agents list") return formatInlineAtsCliCommands("Use `ats agents list` to find the local agent that needs repair.");
|
|
89380
|
+
return `Use \`${formatAtsCliCommand(action.command)}\` to check the local reply path.`;
|
|
89261
89381
|
}
|
|
89262
89382
|
function resolveSpaceMemberTerminalProfileLabel(profileName) {
|
|
89263
89383
|
return sanitizeSingleLinePromptText(normalizeOptionalString$1(profileName)) || "This agent";
|