agent-transport-system 0.7.5 → 0.7.7
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 +320 -85
- 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.7";
|
|
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?.({
|
|
@@ -3461,13 +3469,13 @@ const COMMAND_CHECK_REQUIREMENTS = Object.freeze({
|
|
|
3461
3469
|
"service.reinstall": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
3462
3470
|
"service.stop": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
3463
3471
|
"space.menu": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3464
|
-
"space.create": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE,
|
|
3472
|
+
"space.create": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3465
3473
|
"space.delete": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3466
3474
|
"space.conversation.bind": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3467
3475
|
"space.conversation.clear": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3468
3476
|
"space.conversation.status": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3469
3477
|
"space.join": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3470
|
-
"space.add-members": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE,
|
|
3478
|
+
"space.add-members": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3471
3479
|
"space.remove-members": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3472
3480
|
"space.leave": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
3473
3481
|
"space.watch": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
@@ -28442,13 +28450,21 @@ function showHumanCheckCard(input) {
|
|
|
28442
28450
|
//#region src/command-entry-checks/check-cli-update.ts
|
|
28443
28451
|
const SKIP_CLI_UPDATE_ENV = "ATS_INTERNAL_SKIP_STARTUP_UPGRADE";
|
|
28444
28452
|
const ATS_PACKAGE_NAME = "agent-transport-system";
|
|
28453
|
+
const OPTIONAL_CLI_UPDATE_CACHE_TTL_MS = 1440 * 60 * 1e3;
|
|
28445
28454
|
async function runCliUpdateCheck(input) {
|
|
28446
28455
|
if (input.requirement.mode === "skip") return { status: "continue" };
|
|
28447
28456
|
if (String(process.env[SKIP_CLI_UPDATE_ENV] ?? "").trim() === "1") return { status: "continue" };
|
|
28448
28457
|
if (!shouldCheckNpmCliUpdate(input.context)) return { status: "continue" };
|
|
28449
28458
|
const currentVersion = version;
|
|
28450
|
-
const latestVersion = await
|
|
28451
|
-
|
|
28459
|
+
const latestVersion = await resolveLatestPackageVersionForUpdateCheck({
|
|
28460
|
+
currentVersion,
|
|
28461
|
+
useLocalCache: input.requirement.mode !== "required"
|
|
28462
|
+
}).catch(() => null);
|
|
28463
|
+
const noUpdateResult = await resolveNoCliUpdateResult({
|
|
28464
|
+
currentVersion,
|
|
28465
|
+
latestVersion
|
|
28466
|
+
});
|
|
28467
|
+
if (noUpdateResult) return noUpdateResult;
|
|
28452
28468
|
const copy = getCommandEntryCopy(input.context.entryName);
|
|
28453
28469
|
if (input.context.runtime.resolvedView !== "human" || !input.context.allowPrompt) {
|
|
28454
28470
|
const isRequired = input.requirement.mode === "required";
|
|
@@ -28507,6 +28523,38 @@ async function runCliUpdateCheck(input) {
|
|
|
28507
28523
|
})
|
|
28508
28524
|
};
|
|
28509
28525
|
}
|
|
28526
|
+
async function resolveNoCliUpdateResult(input) {
|
|
28527
|
+
if (input.latestVersion && compareSemver(input.currentVersion, input.latestVersion) < 0) return null;
|
|
28528
|
+
if (input.latestVersion) await persistLatestVersionCheck({
|
|
28529
|
+
currentVersion: input.currentVersion,
|
|
28530
|
+
latestVersion: input.latestVersion
|
|
28531
|
+
});
|
|
28532
|
+
return { status: "continue" };
|
|
28533
|
+
}
|
|
28534
|
+
async function resolveLatestPackageVersionForUpdateCheck(input) {
|
|
28535
|
+
if (!input.useLocalCache) return await fetchLatestPackageVersion(ATS_PACKAGE_NAME);
|
|
28536
|
+
const previousVersionState = await readVersionState().catch(() => null);
|
|
28537
|
+
const cachedLatestVersion = resolveFreshCachedLatestVersion({
|
|
28538
|
+
currentVersion: input.currentVersion,
|
|
28539
|
+
previousVersionState
|
|
28540
|
+
});
|
|
28541
|
+
if (cachedLatestVersion) return cachedLatestVersion;
|
|
28542
|
+
return await fetchLatestPackageVersion(ATS_PACKAGE_NAME);
|
|
28543
|
+
}
|
|
28544
|
+
async function persistLatestVersionCheck(input) {
|
|
28545
|
+
await writeVersionState(buildNextVersionState({
|
|
28546
|
+
previous: await readVersionState().catch(() => null),
|
|
28547
|
+
currentVersion: input.currentVersion,
|
|
28548
|
+
latestVersion: input.latestVersion
|
|
28549
|
+
})).catch(() => void 0);
|
|
28550
|
+
}
|
|
28551
|
+
function resolveFreshCachedLatestVersion(input) {
|
|
28552
|
+
const state = input.previousVersionState;
|
|
28553
|
+
if (state?.last_version !== input.currentVersion || !state.latest_version || !state.last_checked_at) return null;
|
|
28554
|
+
const checkedAt = Date.parse(state.last_checked_at);
|
|
28555
|
+
if (Number.isNaN(checkedAt) || Date.now() - checkedAt >= OPTIONAL_CLI_UPDATE_CACHE_TTL_MS) return null;
|
|
28556
|
+
return state.latest_version;
|
|
28557
|
+
}
|
|
28510
28558
|
function shouldCheckNpmCliUpdate(context) {
|
|
28511
28559
|
return context.environmentTarget.preset === "prod" && context.environmentTarget.userFacingCommand === "ats";
|
|
28512
28560
|
}
|
|
@@ -60440,13 +60488,7 @@ function renderProfileSummaryCard(input) {
|
|
|
60440
60488
|
});
|
|
60441
60489
|
}
|
|
60442
60490
|
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
|
-
];
|
|
60491
|
+
if (profile.profileKind === "agent") return [formatAtsCliCommand(`ats space add-members <space-id> --member ${profile.atsProfileId} --profile <human-profile-id> --view agent`)];
|
|
60450
60492
|
return [
|
|
60451
60493
|
formatAtsCliCommand("ats profiles list --view agent"),
|
|
60452
60494
|
formatAtsCliCommand(`ats profiles set ${profile.atsProfileId} --view agent`),
|
|
@@ -60460,28 +60502,24 @@ function buildAgentCreateWakeReadinessData(profile) {
|
|
|
60460
60502
|
return {
|
|
60461
60503
|
identityCreated: true,
|
|
60462
60504
|
wakeReadinessVerified: false,
|
|
60463
|
-
wakeReadinessNote: "
|
|
60505
|
+
wakeReadinessNote: "Profile creation creates the Space identity. Add it to a Space when the user wants this teammate to participate."
|
|
60464
60506
|
};
|
|
60465
60507
|
}
|
|
60466
60508
|
function buildProfileCreateWakeReadinessRows(input) {
|
|
60467
60509
|
if (input.state !== "created" || input.profile.profileKind !== "agent") return [];
|
|
60468
60510
|
return [{
|
|
60469
|
-
label: "
|
|
60470
|
-
value: "
|
|
60511
|
+
label: "Space identity",
|
|
60512
|
+
value: "Created"
|
|
60471
60513
|
}, {
|
|
60472
60514
|
label: "Next",
|
|
60473
|
-
value:
|
|
60515
|
+
value: "Add this profile to a Space when the user wants this teammate to participate."
|
|
60474
60516
|
}];
|
|
60475
60517
|
}
|
|
60476
60518
|
function buildAgentUpdateNextSteps(profile) {
|
|
60519
|
+
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
60520
|
return [
|
|
60478
60521
|
formatAtsCliCommand(`ats profiles show ${profile.atsProfileId} --view agent`),
|
|
60479
60522
|
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
60523
|
formatAtsCliCommand("ats profiles list --view agent")
|
|
60486
60524
|
];
|
|
60487
60525
|
}
|
|
@@ -69476,7 +69514,7 @@ const STAGES_BY_COMMAND = {
|
|
|
69476
69514
|
"resolve_target",
|
|
69477
69515
|
"read_or_update_guide"
|
|
69478
69516
|
],
|
|
69479
|
-
add_members:
|
|
69517
|
+
add_members: SPACE_ADD_MEMBERS_AGENT_OVERVIEW_STAGES,
|
|
69480
69518
|
remove_members: [
|
|
69481
69519
|
"check_arguments",
|
|
69482
69520
|
"authenticate",
|
|
@@ -76043,13 +76081,32 @@ async function resolveSpaceSessionDiagnostics(input) {
|
|
|
76043
76081
|
};
|
|
76044
76082
|
}
|
|
76045
76083
|
async function emitSpaceCommandPreflight(input) {
|
|
76046
|
-
const
|
|
76084
|
+
const actionRequirements = resolveSpacePreflightActionRequirements(input.command);
|
|
76085
|
+
const authState = await getAuthSessionState({ validateRemote: false });
|
|
76086
|
+
if (actionRequirements.localService === "not_required") {
|
|
76087
|
+
const preflight = buildLocalServiceNotRequiredPreflight({
|
|
76088
|
+
actionRequirements,
|
|
76089
|
+
authState,
|
|
76090
|
+
baseUrl: input.baseUrl,
|
|
76091
|
+
command: input.command,
|
|
76092
|
+
profile: input.profile
|
|
76093
|
+
});
|
|
76094
|
+
if (shouldEmitSpaceCommandPreflightOutput(input.emitOutput)) emitResolvedSpaceCommandPreflight({
|
|
76095
|
+
presenter: input.presenter,
|
|
76096
|
+
command: input.command,
|
|
76097
|
+
resolvedView: input.resolvedView,
|
|
76098
|
+
humanServiceGuidanceMode: input.humanServiceGuidanceMode ?? "show",
|
|
76099
|
+
preflight
|
|
76100
|
+
});
|
|
76101
|
+
return preflight;
|
|
76102
|
+
}
|
|
76103
|
+
const replyReadinessSnapshot = await resolveCurrentReplyReadinessSnapshot({
|
|
76047
76104
|
baseUrl: input.baseUrl,
|
|
76048
|
-
checkGatewayChain: input.command === "
|
|
76105
|
+
checkGatewayChain: input.command === "join",
|
|
76049
76106
|
ownerUserId: input.profile.ownerUserId,
|
|
76050
76107
|
profile: input.profile,
|
|
76051
76108
|
runtimeProjection: input.runtimeProjection
|
|
76052
|
-
})
|
|
76109
|
+
});
|
|
76053
76110
|
const serviceParticipationReadiness = resolveServiceParticipationReadiness({
|
|
76054
76111
|
deviceReplyReadiness: replyReadinessSnapshot.deviceReplyReadiness,
|
|
76055
76112
|
inventory: replyReadinessSnapshot.inventory,
|
|
@@ -76075,7 +76132,7 @@ async function emitSpaceCommandPreflight(input) {
|
|
|
76075
76132
|
profileName: input.profile.profileName,
|
|
76076
76133
|
profileKind: input.profile.profileKind
|
|
76077
76134
|
},
|
|
76078
|
-
actionRequirements
|
|
76135
|
+
actionRequirements,
|
|
76079
76136
|
agentReplyReadiness: toSpacePreflightAgentReplyReadiness({
|
|
76080
76137
|
command: input.command,
|
|
76081
76138
|
readiness: replyReadinessSnapshot.agentReplyReadiness
|
|
@@ -76117,6 +76174,62 @@ async function emitSpaceCommandPreflight(input) {
|
|
|
76117
76174
|
serviceParticipationReadiness
|
|
76118
76175
|
};
|
|
76119
76176
|
}
|
|
76177
|
+
function buildLocalServiceNotRequiredPreflight(input) {
|
|
76178
|
+
const deviceReplyReadiness = {
|
|
76179
|
+
reasonCodes: [],
|
|
76180
|
+
reasonText: input.actionRequirements.localServiceSummary,
|
|
76181
|
+
replyReadiness: "unknown",
|
|
76182
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
76183
|
+
wakeableRouteCount: 0
|
|
76184
|
+
};
|
|
76185
|
+
const serviceParticipationReadiness = {
|
|
76186
|
+
serviceReadiness: "unknown",
|
|
76187
|
+
serviceReadinessState: "unknown",
|
|
76188
|
+
summaryText: "not required",
|
|
76189
|
+
detailText: input.actionRequirements.localServiceSummary,
|
|
76190
|
+
nextStepSummary: null,
|
|
76191
|
+
nextSteps: [],
|
|
76192
|
+
runtimeHeadline: "unknown"
|
|
76193
|
+
};
|
|
76194
|
+
return {
|
|
76195
|
+
deviceReplyReadiness,
|
|
76196
|
+
payload: {
|
|
76197
|
+
command: input.command,
|
|
76198
|
+
auth: {
|
|
76199
|
+
state: input.authState.state,
|
|
76200
|
+
ready: resolvePreflightAuthReadiness({
|
|
76201
|
+
authState: input.authState,
|
|
76202
|
+
baseUrl: input.baseUrl
|
|
76203
|
+
}),
|
|
76204
|
+
compatibleWithBaseUrl: resolvePreflightAuthCompatibility({
|
|
76205
|
+
authState: input.authState,
|
|
76206
|
+
baseUrl: input.baseUrl
|
|
76207
|
+
}),
|
|
76208
|
+
authBaseUrl: input.authState.state === "valid" && input.authState.session ? input.authState.session.authBaseUrl : null,
|
|
76209
|
+
gatewayUrl: input.baseUrl
|
|
76210
|
+
},
|
|
76211
|
+
profile: {
|
|
76212
|
+
profileId: input.profile.atsProfileId,
|
|
76213
|
+
profileName: input.profile.profileName,
|
|
76214
|
+
profileKind: input.profile.profileKind
|
|
76215
|
+
},
|
|
76216
|
+
actionRequirements: input.actionRequirements,
|
|
76217
|
+
agentReplyReadiness: null,
|
|
76218
|
+
services: { daemon: {
|
|
76219
|
+
installed: false,
|
|
76220
|
+
version: null,
|
|
76221
|
+
runtimeStatus: "unknown",
|
|
76222
|
+
runtimeReason: null
|
|
76223
|
+
} },
|
|
76224
|
+
env: {
|
|
76225
|
+
baseUrl: input.baseUrl,
|
|
76226
|
+
requestTimeoutMs: resolveSpaceRequestTimeoutMsForDiagnostics()
|
|
76227
|
+
},
|
|
76228
|
+
serviceRepairGuidance: null
|
|
76229
|
+
},
|
|
76230
|
+
serviceParticipationReadiness
|
|
76231
|
+
};
|
|
76232
|
+
}
|
|
76120
76233
|
function emitResolvedSpaceCommandPreflight(input) {
|
|
76121
76234
|
const { payload, serviceParticipationReadiness } = input.preflight;
|
|
76122
76235
|
if (input.resolvedView === "human") {
|
|
@@ -83782,13 +83895,13 @@ function handleBlockedSpaceJoinLocalParticipation(input) {
|
|
|
83782
83895
|
if (input.assessmentState === "not_needed") {
|
|
83783
83896
|
input.presenter.line({
|
|
83784
83897
|
code: "space.join.service.not_needed",
|
|
83785
|
-
text: formatInlineAtsCliCommands("ATS will
|
|
83898
|
+
text: formatInlineAtsCliCommands("ATS will join this space. Local agent participation on this device can be checked later with `ats service status`.")
|
|
83786
83899
|
});
|
|
83787
83900
|
return "continue";
|
|
83788
83901
|
}
|
|
83789
83902
|
input.presenter.line({
|
|
83790
83903
|
code: "space.join.service.pending",
|
|
83791
|
-
text: formatInlineAtsCliCommands("ATS will
|
|
83904
|
+
text: formatInlineAtsCliCommands("ATS will join this space. Local agent participation on this device can be checked separately with `ats service status`.")
|
|
83792
83905
|
});
|
|
83793
83906
|
return "continue";
|
|
83794
83907
|
}
|
|
@@ -83801,10 +83914,10 @@ function buildSpaceJoinMembershipOnlyMessage(input) {
|
|
|
83801
83914
|
const profileId = input.atsProfile.atsProfileId;
|
|
83802
83915
|
const reasonCodes = input.reasonCodes;
|
|
83803
83916
|
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
|
|
83917
|
+
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.`;
|
|
83918
|
+
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
83919
|
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
|
|
83920
|
+
return `${profileName} will join this space. Check Local Agents in ATS Web when you want it to handle work from this device.`;
|
|
83808
83921
|
}
|
|
83809
83922
|
function buildJoinTargetMissingMessage(input) {
|
|
83810
83923
|
return formatMessage(input.resolvedView, "space.target.missing", { command: "join" });
|
|
@@ -85054,6 +85167,8 @@ const SPACE_MEMBER_PROFILE_RECONNECT_REASON_CODES = new Set([
|
|
|
85054
85167
|
"local_service.identity_mismatch"
|
|
85055
85168
|
]);
|
|
85056
85169
|
const SPACE_MEMBER_SERVICE_STATUS_REASON_CODES = new Set([
|
|
85170
|
+
"agent_profile_binding.local_service_not_connected",
|
|
85171
|
+
"agent_profile_binding.execution_readiness_pending",
|
|
85057
85172
|
"route.offline",
|
|
85058
85173
|
"route.not_registered",
|
|
85059
85174
|
"service.gateway_chain_unhealthy",
|
|
@@ -85617,6 +85732,11 @@ function toAuthEndpoint(baseUrl, pathname) {
|
|
|
85617
85732
|
function buildSpaceWebUrl(baseUrl, spaceId) {
|
|
85618
85733
|
const url = new URL(baseUrl);
|
|
85619
85734
|
if (isLoopbackHostname(url.hostname) && url.port === "8080") url.port = "3000";
|
|
85735
|
+
if (url.hostname === "gateway.ats.sh") {
|
|
85736
|
+
url.hostname = "ats.sh";
|
|
85737
|
+
url.port = "";
|
|
85738
|
+
url.protocol = "https:";
|
|
85739
|
+
}
|
|
85620
85740
|
url.pathname = `/app/spaces/${encodeURIComponent(spaceId)}`;
|
|
85621
85741
|
url.search = "";
|
|
85622
85742
|
url.hash = "";
|
|
@@ -86129,7 +86249,7 @@ async function runSpaceAddMembers(input) {
|
|
|
86129
86249
|
resolvedView: runtime.resolvedView,
|
|
86130
86250
|
interactive
|
|
86131
86251
|
});
|
|
86132
|
-
await emitSpaceCommandPreflight({
|
|
86252
|
+
if (shouldRunSpaceAddMembersDiagnosticPreflight(input, explicitMemberIds)) await emitSpaceCommandPreflight({
|
|
86133
86253
|
presenter,
|
|
86134
86254
|
command: "add_members",
|
|
86135
86255
|
profile: atsProfile,
|
|
@@ -86321,6 +86441,12 @@ async function runSpaceLeave(input) {
|
|
|
86321
86441
|
throw error;
|
|
86322
86442
|
}
|
|
86323
86443
|
}
|
|
86444
|
+
function shouldRunSpaceAddMembersDiagnosticPreflight(input, explicitMemberIds) {
|
|
86445
|
+
return input.details === true || input.all === true || explicitMemberIds.length === 0;
|
|
86446
|
+
}
|
|
86447
|
+
function shouldUseFastExplicitSpaceAddMembers(input) {
|
|
86448
|
+
return input.details !== true && input.explicitMemberIds.length > 0;
|
|
86449
|
+
}
|
|
86324
86450
|
async function runSpaceAddMembersForTarget(input) {
|
|
86325
86451
|
const targetBaseUrl = input.hasExplicitBaseUrlInput ? input.baseUrl : input.target.baseUrl ?? input.baseUrl;
|
|
86326
86452
|
const authenticatedGatewayUrl = await ensureSpaceCommandGatewayAuthenticationOrCancel({
|
|
@@ -86338,6 +86464,7 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
86338
86464
|
};
|
|
86339
86465
|
const explicitMemberIds = normalizeRequestedMemberIds(input.explicitMembers);
|
|
86340
86466
|
const progress = input.details || explicitMemberIds.length === 0 ? addMembersProgress : void 0;
|
|
86467
|
+
const includeLocalParticipation = progress !== void 0 || explicitMemberIds.length === 0;
|
|
86341
86468
|
const candidates = await resolveSpaceMemberCandidatesForAdd({
|
|
86342
86469
|
currentProfile: input.atsProfile,
|
|
86343
86470
|
currentOwnerUserId: input.atsProfile.ownerUserId,
|
|
@@ -86345,7 +86472,12 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
86345
86472
|
baseUrl: targetBaseUrl,
|
|
86346
86473
|
password: input.password,
|
|
86347
86474
|
explicitMemberIds,
|
|
86348
|
-
progress
|
|
86475
|
+
progress,
|
|
86476
|
+
fastExplicitMembers: shouldUseFastExplicitSpaceAddMembers({
|
|
86477
|
+
details: input.details,
|
|
86478
|
+
explicitMemberIds
|
|
86479
|
+
}),
|
|
86480
|
+
includeLocalParticipation
|
|
86349
86481
|
});
|
|
86350
86482
|
if (candidates.length === 0 && explicitMemberIds.length === 0) {
|
|
86351
86483
|
input.presenter.line({
|
|
@@ -86377,15 +86509,10 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
86377
86509
|
selectedProfileIds
|
|
86378
86510
|
});
|
|
86379
86511
|
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({
|
|
86512
|
+
const servicePreparationResult = await prepareSpaceAddMembersLocalParticipationIfRequested({
|
|
86387
86513
|
atsProfile: input.atsProfile,
|
|
86388
86514
|
candidates: selectedCandidates,
|
|
86515
|
+
enabled: includeLocalParticipation,
|
|
86389
86516
|
progress,
|
|
86390
86517
|
presenter: input.presenter,
|
|
86391
86518
|
resolvedView: input.runtime.resolvedView,
|
|
@@ -86455,6 +86582,28 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
86455
86582
|
});
|
|
86456
86583
|
return { status: "completed" };
|
|
86457
86584
|
}
|
|
86585
|
+
async function prepareSpaceAddMembersLocalParticipationIfRequested(input) {
|
|
86586
|
+
if (!input.enabled) return {
|
|
86587
|
+
status: "continue",
|
|
86588
|
+
candidates: input.candidates
|
|
86589
|
+
};
|
|
86590
|
+
emitSpaceAddMembersProgressIfRequested(input.progress, {
|
|
86591
|
+
stage: "check_local_wake_readiness",
|
|
86592
|
+
phase: "start",
|
|
86593
|
+
summary: "Checking whether selected agent profiles can handle work from this computer. Members can still be added if local setup needs attention.",
|
|
86594
|
+
profileIds: input.candidates.map((candidate) => candidate.profileId)
|
|
86595
|
+
});
|
|
86596
|
+
return await ensureSpaceMemberCandidatesLocalParticipationReady({
|
|
86597
|
+
atsProfile: input.atsProfile,
|
|
86598
|
+
candidates: input.candidates,
|
|
86599
|
+
progress: input.progress,
|
|
86600
|
+
presenter: input.presenter,
|
|
86601
|
+
resolvedView: input.resolvedView,
|
|
86602
|
+
allowPrompt: input.allowPrompt,
|
|
86603
|
+
spaceId: input.spaceId,
|
|
86604
|
+
view: input.view
|
|
86605
|
+
});
|
|
86606
|
+
}
|
|
86458
86607
|
function emitSpaceAddMembersProgressIfRequested(progress, input) {
|
|
86459
86608
|
if (!progress) return;
|
|
86460
86609
|
emitAgentSpaceAddMembersProgress({
|
|
@@ -86503,13 +86652,13 @@ function buildSpaceAddMembersLocalWakePlanSummary(plan) {
|
|
|
86503
86652
|
if (assessment.profileKind !== "agent") continue;
|
|
86504
86653
|
counts.set(assessment.localParticipationState, (counts.get(assessment.localParticipationState) ?? 0) + 1);
|
|
86505
86654
|
}
|
|
86506
|
-
return `Local
|
|
86507
|
-
formatLocalWakePlanCount(counts.get("ready") ?? 0, "
|
|
86655
|
+
return `Local agent plan: ${[
|
|
86656
|
+
formatLocalWakePlanCount(counts.get("ready") ?? 0, "can handle work from this device"),
|
|
86508
86657
|
formatLocalWakePlanCount(counts.get("needs_agent_prepare") ?? 0, "need agent preparation"),
|
|
86509
86658
|
formatLocalWakePlanCount(counts.get("needs_ats_service") ?? 0, "need ATS Service"),
|
|
86510
86659
|
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
|
|
86660
|
+
formatLocalWakePlanCount(counts.get("not_needed") ?? 0, "do not need local agent setup")
|
|
86661
|
+
].filter((part) => Boolean(part)).join(", ")}. Adding members is separate from local agent participation on this computer.`;
|
|
86513
86662
|
}
|
|
86514
86663
|
function formatLocalWakePlanCount(count, label) {
|
|
86515
86664
|
return count > 0 ? `${String(count)} ${label}` : null;
|
|
@@ -86672,7 +86821,7 @@ async function ensureSpaceMemberCandidatesLocalParticipationReady(input) {
|
|
|
86672
86821
|
candidates: preparedCandidates.map(toActionParticipationCandidateFromSpaceMemberCandidate)
|
|
86673
86822
|
}).shouldOfferServiceGate) input.presenter.line({
|
|
86674
86823
|
code: input.resolvedView === "human" && input.allowPrompt ? "space.add_members.service.declined" : "space.add_members.service.deferred",
|
|
86675
|
-
text: formatInlineAtsCliCommands("ATS will
|
|
86824
|
+
text: formatInlineAtsCliCommands("ATS will add these profiles to the Space. Local agent participation can be checked separately with `ats service status`.")
|
|
86676
86825
|
});
|
|
86677
86826
|
return {
|
|
86678
86827
|
status: "continue",
|
|
@@ -86746,17 +86895,18 @@ function emitSpaceMemberJoinOnlyWarnings(input) {
|
|
|
86746
86895
|
}
|
|
86747
86896
|
function buildSpaceMemberJoinOnlyWarning(candidate) {
|
|
86748
86897
|
if (candidate.profileKind !== "agent") return null;
|
|
86898
|
+
if (candidate.localParticipationChecked !== true) return null;
|
|
86749
86899
|
if (isSpaceMemberCandidateBackgroundReplyReady(candidate)) return null;
|
|
86750
86900
|
const profileLabel = resolveSpaceMemberTerminalProfileLabel(candidate.profileName);
|
|
86751
|
-
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) return `${profileLabel} can join this space now
|
|
86901
|
+
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) return `${profileLabel} can join this space now. ${resolveSpaceMemberTerminalLocalTargetLabel({
|
|
86752
86902
|
displayName: candidate.localTargetDisplayName,
|
|
86753
86903
|
agentId: candidate.localTargetAgentId
|
|
86754
|
-
})} still needs local setup on this device before it can
|
|
86904
|
+
})} still needs local setup on this device before it can handle work from the Space. Use \`${buildSpaceMemberRepairCommand({
|
|
86755
86905
|
agentId: candidate.localTargetAgentId,
|
|
86756
86906
|
profileId: candidate.profileId
|
|
86757
|
-
})}\`
|
|
86907
|
+
})}\` to repair the local agent.`;
|
|
86758
86908
|
const nextAction = resolveSpaceMemberJoinOnlyNextAction(candidate);
|
|
86759
|
-
return `${profileLabel} can join this space now
|
|
86909
|
+
return `${profileLabel} can join this space now. ATS has not confirmed its local reply path on this device yet. ${resolveSpaceMemberJoinOnlyReason(candidate)} ${formatSpaceMemberRecoveryNextAction(nextAction)}`;
|
|
86760
86910
|
}
|
|
86761
86911
|
function resolveSpaceMemberJoinOnlyNextAction(candidate) {
|
|
86762
86912
|
if (candidate.localParticipationReadiness === "not_running") return {
|
|
@@ -86834,6 +86984,7 @@ async function refreshSpaceMemberCandidatesLocalReadiness(candidates, progress,
|
|
|
86834
86984
|
async function enrichSpaceMemberCandidateLocalParticipationReadiness(candidate, progress, options = {}) {
|
|
86835
86985
|
if (candidate.profileKind !== "agent" || !candidate.atsProfile || candidate.controllerEnabled !== true || typeof candidate.controllerRef !== "string" || candidate.controllerRef.trim().length === 0) return {
|
|
86836
86986
|
...candidate,
|
|
86987
|
+
localParticipationChecked: true,
|
|
86837
86988
|
localParticipationReadiness: null,
|
|
86838
86989
|
localParticipationReasonCodes: [],
|
|
86839
86990
|
localParticipationReasonText: null
|
|
@@ -86872,6 +87023,7 @@ async function enrichSpaceMemberCandidateLocalParticipationReadiness(candidate,
|
|
|
86872
87023
|
}
|
|
86873
87024
|
if (!snapshot) return {
|
|
86874
87025
|
...candidate,
|
|
87026
|
+
localParticipationChecked: true,
|
|
86875
87027
|
localParticipationReadiness: null,
|
|
86876
87028
|
localParticipationReasonCodes: [],
|
|
86877
87029
|
localParticipationReasonText: null
|
|
@@ -86883,6 +87035,7 @@ async function enrichSpaceMemberCandidateLocalParticipationReadiness(candidate,
|
|
|
86883
87035
|
});
|
|
86884
87036
|
return {
|
|
86885
87037
|
...candidate,
|
|
87038
|
+
localParticipationChecked: true,
|
|
86886
87039
|
localParticipationReadiness: readinessSummary.serviceReadiness,
|
|
86887
87040
|
localParticipationReasonCodes: [...snapshot.deviceReplyReadiness.reasonCodes],
|
|
86888
87041
|
localParticipationReasonText: snapshot.deviceReplyReadiness.reasonText
|
|
@@ -88159,6 +88312,9 @@ function mapSpaceLeaveFailureToGuideError(input) {
|
|
|
88159
88312
|
return input.error instanceof Error ? input.error : new Error(String(input.error));
|
|
88160
88313
|
}
|
|
88161
88314
|
async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
88315
|
+
const explicitMemberIds = normalizeRequestedMemberIds(input.explicitMemberIds);
|
|
88316
|
+
const includeLocalParticipation = input.includeLocalParticipation !== false;
|
|
88317
|
+
if (input.fastExplicitMembers === true && explicitMemberIds.length > 0) return explicitMemberIds.map(buildFastExplicitSpaceMemberCandidate);
|
|
88162
88318
|
if (input.progress) emitAgentSpaceAddMembersProgress({
|
|
88163
88319
|
...input.progress,
|
|
88164
88320
|
stage: "resolve_candidates",
|
|
@@ -88166,23 +88322,19 @@ async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
|
88166
88322
|
summary: "Reading active local profile identities for this Space."
|
|
88167
88323
|
});
|
|
88168
88324
|
const profiles = await listAtsProfiles();
|
|
88169
|
-
if (input.progress) emitAgentSpaceAddMembersProgress({
|
|
88325
|
+
if (input.progress && includeLocalParticipation) emitAgentSpaceAddMembersProgress({
|
|
88170
88326
|
...input.progress,
|
|
88171
88327
|
stage: "resolve_candidates",
|
|
88172
88328
|
phase: "read_local_targets",
|
|
88173
88329
|
summary: "Reading local agent controller state for candidate profiles before selection."
|
|
88174
88330
|
});
|
|
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(() => []);
|
|
88331
|
+
const localTargetStates = await listSpaceAddMembersLocalTargetStatesIfRequested({
|
|
88332
|
+
includeLocalParticipation,
|
|
88333
|
+
progress: input.progress
|
|
88334
|
+
});
|
|
88182
88335
|
const localTargetStateById = new Map(localTargetStates.map((state) => [state.agentId, state]));
|
|
88183
88336
|
const ownerProfileNameByOwnerUserId = buildOwnerProfileNameByOwnerUserId(profiles);
|
|
88184
88337
|
const candidateProfiles = profiles.filter((profile) => profile.status === "active" && isSpaceMembershipProfileKind(profile.profileKind) && profile.atsProfileId !== input.currentProfile.atsProfileId).filter((profile) => {
|
|
88185
|
-
const explicitMemberIds = input.explicitMemberIds ?? [];
|
|
88186
88338
|
if (explicitMemberIds.length > 0 && !explicitMemberIds.includes(profile.atsProfileId)) return false;
|
|
88187
88339
|
return typeof input.currentOwnerUserId !== "string" || input.currentOwnerUserId.trim().length === 0 || profile.ownerUserId === input.currentOwnerUserId;
|
|
88188
88340
|
});
|
|
@@ -88199,29 +88351,58 @@ async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
|
88199
88351
|
...input.password === void 0 ? {} : { spacePassword: input.password }
|
|
88200
88352
|
});
|
|
88201
88353
|
const memberProfileIds = new Set([...membersSnapshot.humans, ...membersSnapshot.agents].map((member) => member.profileId));
|
|
88202
|
-
|
|
88354
|
+
const candidates = (await Promise.all(candidateProfiles.map((profile) => buildSpaceMemberCandidateFromProfile({
|
|
88203
88355
|
baseUrl: input.baseUrl,
|
|
88204
88356
|
profile,
|
|
88205
88357
|
localTargetStateById,
|
|
88206
88358
|
ownerProfileName: ownerProfileNameByOwnerUserId.get(profile.ownerUserId) ?? void 0,
|
|
88207
88359
|
alreadyJoined: memberProfileIds.has(profile.atsProfileId),
|
|
88208
|
-
progress: input.progress
|
|
88360
|
+
progress: input.progress,
|
|
88361
|
+
includeLocalParticipation
|
|
88209
88362
|
})))).sort((left, right) => {
|
|
88210
88363
|
const byName = left.profileName.localeCompare(right.profileName);
|
|
88211
88364
|
if (byName !== 0) return byName;
|
|
88212
88365
|
return left.profileId.localeCompare(right.profileId);
|
|
88213
|
-
})
|
|
88366
|
+
});
|
|
88367
|
+
if (!includeLocalParticipation) return candidates;
|
|
88368
|
+
return await refreshSpaceMemberCandidatesLocalReadiness(candidates, input.progress, { stage: "resolve_candidates" });
|
|
88214
88369
|
}
|
|
88215
|
-
|
|
88216
|
-
|
|
88370
|
+
function buildFastExplicitSpaceMemberCandidate(profileId) {
|
|
88371
|
+
return {
|
|
88372
|
+
profileId,
|
|
88373
|
+
profileName: profileId,
|
|
88374
|
+
profileKind: profileId.startsWith("agt_") ? "agent" : "human",
|
|
88375
|
+
targetMentionLabel: null,
|
|
88376
|
+
localTargetAgentId: null,
|
|
88377
|
+
localTargetDisplayName: null,
|
|
88378
|
+
localTargetLaunchStatus: null,
|
|
88379
|
+
localTargetSelectable: false,
|
|
88380
|
+
localParticipationReadiness: null,
|
|
88381
|
+
localParticipationChecked: false,
|
|
88382
|
+
localParticipationReasonCodes: [],
|
|
88383
|
+
localParticipationReasonText: null,
|
|
88384
|
+
alreadyJoined: false,
|
|
88385
|
+
needsActivation: false
|
|
88386
|
+
};
|
|
88387
|
+
}
|
|
88388
|
+
async function listSpaceAddMembersLocalTargetStatesIfRequested(input) {
|
|
88389
|
+
if (!input.includeLocalParticipation) return [];
|
|
88390
|
+
if (!input.progress) return await listAgentTargetStates().catch(() => []);
|
|
88391
|
+
return await runSpaceAddMembersProgressHeartbeat({
|
|
88217
88392
|
...input.progress,
|
|
88218
88393
|
stage: "resolve_candidates",
|
|
88219
|
-
phase: "
|
|
88220
|
-
summary:
|
|
88221
|
-
|
|
88222
|
-
profileIds: [input.profile.atsProfileId]
|
|
88394
|
+
phase: "read_local_targets_wait",
|
|
88395
|
+
summary: "Still reading local agent controller state for candidate profiles before selection.",
|
|
88396
|
+
operation: async () => await listAgentTargetStates().catch(() => [])
|
|
88223
88397
|
});
|
|
88224
|
-
|
|
88398
|
+
}
|
|
88399
|
+
async function resolveSpaceMemberCandidateRuntimeCapabilityIfRequested(input) {
|
|
88400
|
+
if (!input.includeLocalParticipation) return null;
|
|
88401
|
+
if (!input.progress) return await resolveAgentProfilePrimaryRuntimeCapability({
|
|
88402
|
+
baseUrl: input.baseUrl,
|
|
88403
|
+
profile: input.profile
|
|
88404
|
+
}).catch(() => null);
|
|
88405
|
+
return await runSpaceAddMembersProgressHeartbeat({
|
|
88225
88406
|
...input.progress,
|
|
88226
88407
|
stage: "resolve_candidates",
|
|
88227
88408
|
phase: "read_runtime_capability_wait",
|
|
@@ -88232,10 +88413,24 @@ async function buildSpaceMemberCandidateFromProfile(input) {
|
|
|
88232
88413
|
baseUrl: input.baseUrl,
|
|
88233
88414
|
profile: input.profile
|
|
88234
88415
|
}).catch(() => null)
|
|
88235
|
-
})
|
|
88416
|
+
});
|
|
88417
|
+
}
|
|
88418
|
+
async function buildSpaceMemberCandidateFromProfile(input) {
|
|
88419
|
+
const includeLocalParticipation = input.includeLocalParticipation !== false;
|
|
88420
|
+
if (input.progress && includeLocalParticipation) emitAgentSpaceAddMembersProgress({
|
|
88421
|
+
...input.progress,
|
|
88422
|
+
stage: "resolve_candidates",
|
|
88423
|
+
phase: "read_runtime_capability",
|
|
88424
|
+
summary: `Reading runtime capability projection for ${resolveSpaceMemberTerminalProfileLabel(input.profile.profileName)}.`,
|
|
88425
|
+
profileId: input.profile.atsProfileId,
|
|
88426
|
+
profileIds: [input.profile.atsProfileId]
|
|
88427
|
+
});
|
|
88428
|
+
const runtimeCapability = await resolveSpaceMemberCandidateRuntimeCapabilityIfRequested({
|
|
88236
88429
|
baseUrl: input.baseUrl,
|
|
88237
|
-
|
|
88238
|
-
|
|
88430
|
+
includeLocalParticipation,
|
|
88431
|
+
profile: input.profile,
|
|
88432
|
+
progress: input.progress
|
|
88433
|
+
});
|
|
88239
88434
|
const controllerRef = runtimeCapability?.capabilityRef ?? void 0;
|
|
88240
88435
|
const controllerEnabled = runtimeCapability?.bindingState === "enabled_primary" && runtimeCapability.routable;
|
|
88241
88436
|
const localTargetAgentId = resolveSpaceMemberCandidateLocalTargetAgentId({
|
|
@@ -88260,6 +88455,7 @@ async function buildSpaceMemberCandidateFromProfile(input) {
|
|
|
88260
88455
|
localTargetLaunchStatus: localTargetState?.launchStatus ?? null,
|
|
88261
88456
|
localTargetSelectable: localTargetState?.selectable ?? false,
|
|
88262
88457
|
localParticipationReadiness: null,
|
|
88458
|
+
localParticipationChecked: false,
|
|
88263
88459
|
localParticipationReasonCodes: [],
|
|
88264
88460
|
localParticipationReasonText: null,
|
|
88265
88461
|
alreadyJoined: input.alreadyJoined,
|
|
@@ -88588,14 +88784,19 @@ async function applySpaceAddMembers(input) {
|
|
|
88588
88784
|
}
|
|
88589
88785
|
const addedProfileIds = new Set(response.addedMemberIds);
|
|
88590
88786
|
const alreadyMemberProfileIds = new Set(response.alreadyMemberIds);
|
|
88787
|
+
const responseItemByProfileId = new Map(response.items.map((item) => [item.profileId, item]));
|
|
88591
88788
|
const lastJoinedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
88592
88789
|
const spaceName = normalizeOptionalString$1(input.spaceName);
|
|
88593
88790
|
for (const candidate of selectedCandidates) {
|
|
88791
|
+
const nextCandidate = hydrateSpaceMemberCandidateFromResponseItem({
|
|
88792
|
+
candidate,
|
|
88793
|
+
item: responseItemByProfileId.get(candidate.profileId)
|
|
88794
|
+
});
|
|
88594
88795
|
if (addedProfileIds.has(candidate.profileId)) {
|
|
88595
|
-
result.added.push(
|
|
88796
|
+
result.added.push(nextCandidate);
|
|
88596
88797
|
continue;
|
|
88597
88798
|
}
|
|
88598
|
-
if (alreadyMemberProfileIds.has(candidate.profileId)) result.alreadyJoined.push(
|
|
88799
|
+
if (alreadyMemberProfileIds.has(candidate.profileId)) result.alreadyJoined.push(nextCandidate);
|
|
88599
88800
|
}
|
|
88600
88801
|
for (const candidate of result.added) try {
|
|
88601
88802
|
await upsertProfileSpaceHistory({
|
|
@@ -88622,6 +88823,27 @@ async function applySpaceAddMembers(input) {
|
|
|
88622
88823
|
}
|
|
88623
88824
|
return result;
|
|
88624
88825
|
}
|
|
88826
|
+
function hydrateSpaceMemberCandidateFromResponseItem(input) {
|
|
88827
|
+
if (!input.item) return input.candidate;
|
|
88828
|
+
return {
|
|
88829
|
+
...input.candidate,
|
|
88830
|
+
profileName: input.item.profileName,
|
|
88831
|
+
profileKind: input.item.profileKind,
|
|
88832
|
+
ownerUserId: normalizeOptionalString$1(input.item.ownerUserId) ?? void 0,
|
|
88833
|
+
ownerName: normalizeOptionalString$1(input.item.ownerName) ?? void 0,
|
|
88834
|
+
targetMentionLabel: resolvePrimaryMentionLabelFromSpaceMemberItem(input.item),
|
|
88835
|
+
...input.item.profileKind === "agent" ? { controllerRef: normalizeOptionalString$1(input.item.controllerRef) ?? input.candidate.controllerRef } : {}
|
|
88836
|
+
};
|
|
88837
|
+
}
|
|
88838
|
+
function resolvePrimaryMentionLabelFromSpaceMemberItem(item) {
|
|
88839
|
+
const mentionAlias = normalizeOptionalString$1(item.mentionAlias);
|
|
88840
|
+
if (mentionAlias) return mentionAlias;
|
|
88841
|
+
return resolveSingleSpaceMentionLabels({
|
|
88842
|
+
mentionAlias,
|
|
88843
|
+
profileId: item.profileId,
|
|
88844
|
+
profileName: item.profileName
|
|
88845
|
+
}).primaryMentionLabel;
|
|
88846
|
+
}
|
|
88625
88847
|
async function waitForAddedMembersWakeProjection(input) {
|
|
88626
88848
|
const expectedWakeableProfileIds = resolveExpectedWakeProjectionProfileIds(input.result);
|
|
88627
88849
|
if (expectedWakeableProfileIds.length === 0) return;
|
|
@@ -88728,6 +88950,7 @@ function emitSpaceAddMembersResult(input) {
|
|
|
88728
88950
|
}
|
|
88729
88951
|
function buildSpaceMemberJoinedFollowUp(candidate) {
|
|
88730
88952
|
if (candidate.profileKind !== "agent") return null;
|
|
88953
|
+
if (candidate.localParticipationChecked !== true) return null;
|
|
88731
88954
|
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) {
|
|
88732
88955
|
const repairCommand = buildSpaceMemberRepairCommand({
|
|
88733
88956
|
agentId: candidate.localTargetAgentId,
|
|
@@ -88741,7 +88964,7 @@ function buildSpaceMemberJoinedFollowUp(candidate) {
|
|
|
88741
88964
|
return {
|
|
88742
88965
|
profileId: candidate.profileId,
|
|
88743
88966
|
reasonCodes: candidate.localParticipationReasonCodes ?? [],
|
|
88744
|
-
text: `${profileLabel} joined this space
|
|
88967
|
+
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
88968
|
};
|
|
88746
88969
|
}
|
|
88747
88970
|
if (!isSpaceMemberCandidateRunnableLocalParticipationCandidate(candidate)) {
|
|
@@ -88750,7 +88973,7 @@ function buildSpaceMemberJoinedFollowUp(candidate) {
|
|
|
88750
88973
|
return {
|
|
88751
88974
|
profileId: candidate.profileId,
|
|
88752
88975
|
reasonCodes: candidate.localParticipationReasonCodes ?? [],
|
|
88753
|
-
text: `${profileLabel} joined this space
|
|
88976
|
+
text: `${profileLabel} joined this space. ATS has not confirmed its local reply path on this device yet. ${formatSpaceMemberRecoveryNextAction(nextAction)}`
|
|
88754
88977
|
};
|
|
88755
88978
|
}
|
|
88756
88979
|
return null;
|
|
@@ -88985,8 +89208,8 @@ async function persistSpaceAddMembersJoinNotices(input) {
|
|
|
88985
89208
|
failedCount: 0
|
|
88986
89209
|
};
|
|
88987
89210
|
const failures = [];
|
|
88988
|
-
let targetMentionLabelByProfileId;
|
|
88989
|
-
try {
|
|
89211
|
+
let targetMentionLabelByProfileId = buildKnownMentionLabelByProfileId(input.addedMembers);
|
|
89212
|
+
if (!hasMentionLabelsForAllMembers(input.addedMembers, targetMentionLabelByProfileId)) try {
|
|
88990
89213
|
targetMentionLabelByProfileId = buildSpacePrimaryMentionLabelByProfileId(await createCliSpaceApi(input.baseUrl).getMembersSnapshot({
|
|
88991
89214
|
spaceId: input.space,
|
|
88992
89215
|
requestContext: buildAtsRequestContextFromProfile({ atsProfile: input.actorProfile }),
|
|
@@ -89032,6 +89255,17 @@ async function persistSpaceAddMembersJoinNotices(input) {
|
|
|
89032
89255
|
...failures[0] ? { firstFailure: toStructuredGatewayFailure(failures[0].error) } : {}
|
|
89033
89256
|
};
|
|
89034
89257
|
}
|
|
89258
|
+
function buildKnownMentionLabelByProfileId(members) {
|
|
89259
|
+
const labelsByProfileId = /* @__PURE__ */ new Map();
|
|
89260
|
+
for (const member of members) {
|
|
89261
|
+
const targetMentionLabel = normalizeOptionalString$1(member.targetMentionLabel);
|
|
89262
|
+
if (targetMentionLabel) labelsByProfileId.set(member.profileId, targetMentionLabel);
|
|
89263
|
+
}
|
|
89264
|
+
return labelsByProfileId;
|
|
89265
|
+
}
|
|
89266
|
+
function hasMentionLabelsForAllMembers(members, labelsByProfileId) {
|
|
89267
|
+
return members.every((member) => labelsByProfileId.has(member.profileId));
|
|
89268
|
+
}
|
|
89035
89269
|
async function postSpaceAddMemberJoinNotice(input) {
|
|
89036
89270
|
const requestContext = buildAtsRequestContextFromProfile({ atsProfile: input.actorProfile });
|
|
89037
89271
|
await createCliSpaceApi(input.baseUrl).postNormalMessage({
|
|
@@ -89217,8 +89451,9 @@ function resolveSpaceMemberCandidateStatusLabel(candidate) {
|
|
|
89217
89451
|
const TRAILING_PERIOD_RE = /\.$/u;
|
|
89218
89452
|
function resolveSpaceMemberCandidateStatusBadges(candidate) {
|
|
89219
89453
|
if (candidate.profileKind !== "agent") return [];
|
|
89454
|
+
if (candidate.localParticipationChecked !== true) return [];
|
|
89220
89455
|
if (isSpaceMemberCandidateBackgroundReplyReady(candidate)) return ["Local setup connected"];
|
|
89221
|
-
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) return ["Needs repair
|
|
89456
|
+
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) return ["Needs repair"];
|
|
89222
89457
|
return [resolveSpaceMemberJoinOnlyReason(candidate).replace(TRAILING_PERIOD_RE, ""), "Joins only for now"];
|
|
89223
89458
|
}
|
|
89224
89459
|
function isSpaceMemberCandidateBackgroundReplyReady(candidate) {
|
|
@@ -89242,7 +89477,7 @@ function resolveSpaceMemberProfileConnectionAction(candidate) {
|
|
|
89242
89477
|
kind: "instruction"
|
|
89243
89478
|
};
|
|
89244
89479
|
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
|
|
89480
|
+
instruction: "Open this Agent in ATS Web and choose the local agent that should handle work from the Space.",
|
|
89246
89481
|
kind: "instruction"
|
|
89247
89482
|
};
|
|
89248
89483
|
if (reasonCodes.includes("controller.binding.disabled")) return {
|
|
@@ -89255,9 +89490,9 @@ function hasSpaceMemberReasonCode(candidate, reasonCodes) {
|
|
|
89255
89490
|
return (candidate.localParticipationReasonCodes ?? []).some((reasonCode) => reasonCodes.has(reasonCode));
|
|
89256
89491
|
}
|
|
89257
89492
|
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)}\`
|
|
89493
|
+
if (action.kind === "instruction") return action.instruction;
|
|
89494
|
+
if (action.command === "ats agents list") return formatInlineAtsCliCommands("Use `ats agents list` to find the local agent that needs repair.");
|
|
89495
|
+
return `Use \`${formatAtsCliCommand(action.command)}\` to check the local reply path.`;
|
|
89261
89496
|
}
|
|
89262
89497
|
function resolveSpaceMemberTerminalProfileLabel(profileName) {
|
|
89263
89498
|
return sanitizeSingleLinePromptText(normalizeOptionalString$1(profileName)) || "This agent";
|
|
@@ -100025,8 +100260,8 @@ function isSpaceCommandToken(token) {
|
|
|
100025
100260
|
}
|
|
100026
100261
|
async function resolveEffectiveViewForOutput() {
|
|
100027
100262
|
const explicitView = parseViewFromArgv(process.argv, { allowMissingValue: true });
|
|
100028
|
-
|
|
100029
|
-
const selectedView =
|
|
100263
|
+
if (explicitView === "human" || explicitView === "agent") return explicitView;
|
|
100264
|
+
const selectedView = await readConfiguredDefaultView({ argv: process.argv });
|
|
100030
100265
|
if (selectedView === "human" || selectedView === "agent") return selectedView;
|
|
100031
100266
|
return (await resolveRuntimeContext({ view: "auto" })).resolvedView;
|
|
100032
100267
|
}
|