agent-transport-system 0.3.2 → 0.3.3
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 +542 -160
- package/dist/ats.js.map +1 -1
- package/package.json +2 -2
package/dist/ats.js
CHANGED
|
@@ -24,11 +24,11 @@ import wrapAnsi from "wrap-ansi";
|
|
|
24
24
|
import { Box, Container, Editor, Key, ProcessTerminal, TUI, Text, getEditorKeybindings, matchesKey } from "@mariozechner/pi-tui";
|
|
25
25
|
|
|
26
26
|
//#region package.json
|
|
27
|
-
var version$1 = "0.3.
|
|
27
|
+
var version$1 = "0.3.3";
|
|
28
28
|
var package_default = {
|
|
29
29
|
name: "agent-transport-system",
|
|
30
30
|
version: version$1,
|
|
31
|
-
atsReleaseDate: "2026-04-
|
|
31
|
+
atsReleaseDate: "2026-04-17",
|
|
32
32
|
description: "Agent Transport System CLI - https://ats.sh",
|
|
33
33
|
license: "MIT",
|
|
34
34
|
type: "module",
|
|
@@ -28220,7 +28220,28 @@ function resolveBootstrapCommandUnavailableSummary(message) {
|
|
|
28220
28220
|
|
|
28221
28221
|
//#endregion
|
|
28222
28222
|
//#region src/system/reply-readiness.ts
|
|
28223
|
-
const REPLY_READINESS_REASON_PRIORITY = [
|
|
28223
|
+
const REPLY_READINESS_REASON_PRIORITY = [
|
|
28224
|
+
"profile.inactive",
|
|
28225
|
+
"profile.unbound",
|
|
28226
|
+
"controller.binding.disabled",
|
|
28227
|
+
"projection.missing",
|
|
28228
|
+
"controller.registry.disabled",
|
|
28229
|
+
"controller.launch.choice_required",
|
|
28230
|
+
"controller.launch.needs_repair",
|
|
28231
|
+
"workspace.missing",
|
|
28232
|
+
"workspace.invalid",
|
|
28233
|
+
"runtime.adapter.unsupported",
|
|
28234
|
+
"controller.bootstrap.failed",
|
|
28235
|
+
"controller.gateway.unhealthy",
|
|
28236
|
+
"service.not_installed",
|
|
28237
|
+
"service.drifted",
|
|
28238
|
+
"service.not_running",
|
|
28239
|
+
"dispatch.storage_not_ready",
|
|
28240
|
+
"service.gateway_chain_unhealthy",
|
|
28241
|
+
"local_agents.none_needed",
|
|
28242
|
+
"route.offline",
|
|
28243
|
+
"route.not_registered"
|
|
28244
|
+
];
|
|
28224
28245
|
const MANUAL_SPACE_PARTICIPATION_REASON = "You can still join the space and send messages yourself";
|
|
28225
28246
|
async function resolveDeviceReplyReadinessStatus(input = {}) {
|
|
28226
28247
|
const status = input.status ?? await getDaemonStatus();
|
|
@@ -47467,7 +47488,10 @@ async function runDaemon(input) {
|
|
|
47467
47488
|
return;
|
|
47468
47489
|
}
|
|
47469
47490
|
if (canUseInteractivePrompts(runtime)) {
|
|
47470
|
-
await runInteractiveDaemonMenu({
|
|
47491
|
+
await runInteractiveDaemonMenu({
|
|
47492
|
+
gatewayUrl: input.gatewayUrl,
|
|
47493
|
+
view: runtime.resolvedView
|
|
47494
|
+
});
|
|
47471
47495
|
return;
|
|
47472
47496
|
}
|
|
47473
47497
|
presenter.line({
|
|
@@ -48693,6 +48717,7 @@ async function runDaemonStatusFlow(input, options = {}) {
|
|
|
48693
48717
|
await runDaemonStatus(input);
|
|
48694
48718
|
if (!(options.offerStartPrompt && interactiveHuman)) return "completed";
|
|
48695
48719
|
return await maybeOfferDaemonStartAfterStatus({
|
|
48720
|
+
gatewayUrl: input.gatewayUrl,
|
|
48696
48721
|
view: "human",
|
|
48697
48722
|
ownerUserId
|
|
48698
48723
|
});
|
|
@@ -49855,6 +49880,7 @@ async function runDaemonBackgroundStartForDecision(input) {
|
|
|
49855
49880
|
const previousExitCode = process.exitCode;
|
|
49856
49881
|
const result = await runDaemonRun({
|
|
49857
49882
|
agentOverviewHandled: true,
|
|
49883
|
+
gatewayUrl: input.gatewayUrl,
|
|
49858
49884
|
mode: "background",
|
|
49859
49885
|
view: input.view
|
|
49860
49886
|
});
|
|
@@ -50937,7 +50963,10 @@ async function handleInteractiveDaemonMenuChoice(input, choice) {
|
|
|
50937
50963
|
}
|
|
50938
50964
|
if (choice === DAEMON_MENU_CHOICE.reinstall) {
|
|
50939
50965
|
const result = await runDaemonReinstall(input, { suppressInstallOutput: true });
|
|
50940
|
-
if (isDaemonReinstallCompletedAndStopped(result)) return await maybeOfferDaemonStartAfterStatus({
|
|
50966
|
+
if (isDaemonReinstallCompletedAndStopped(result)) return await maybeOfferDaemonStartAfterStatus({
|
|
50967
|
+
gatewayUrl: input.gatewayUrl,
|
|
50968
|
+
view: input.view
|
|
50969
|
+
}) === "cancelled";
|
|
50941
50970
|
return result.result === "cancelled";
|
|
50942
50971
|
}
|
|
50943
50972
|
return await runDaemonUninstall(input) === "cancelled";
|
|
@@ -50948,7 +50977,10 @@ async function maybeOfferDaemonStartAfterStatus(input) {
|
|
|
50948
50977
|
localDemand: input.localDemand
|
|
50949
50978
|
})).offerStartPrompt) return "completed";
|
|
50950
50979
|
const presenter = createPresenter(await resolveRuntimeContext({ view: input.view }));
|
|
50951
|
-
const decision = await runDaemonStartDecisionPrompt({ startService: async () => await runDaemonBackgroundStartForDecision({
|
|
50980
|
+
const decision = await runDaemonStartDecisionPrompt({ startService: async () => await runDaemonBackgroundStartForDecision({
|
|
50981
|
+
gatewayUrl: input.gatewayUrl,
|
|
50982
|
+
view: input.view
|
|
50983
|
+
}) });
|
|
50952
50984
|
if (decision === "cancelled") return "cancelled";
|
|
50953
50985
|
if (decision === "deferred_with_card") return "completed";
|
|
50954
50986
|
if (decision === "not_now") {
|
|
@@ -51363,12 +51395,18 @@ async function runDaemonServiceParticipationInstallStage(input) {
|
|
|
51363
51395
|
return { status: refreshedStatus };
|
|
51364
51396
|
}
|
|
51365
51397
|
async function runDaemonServiceParticipationActionStage(input) {
|
|
51366
|
-
if (input.status.kind === "needs_repair") return mapDaemonBackgroundStartResult(await runDaemonBackgroundStartForDecision({
|
|
51398
|
+
if (input.status.kind === "needs_repair") return mapDaemonBackgroundStartResult(await runDaemonBackgroundStartForDecision({
|
|
51399
|
+
gatewayUrl: input.input.gatewayUrl,
|
|
51400
|
+
view: input.input.view
|
|
51401
|
+
}), {
|
|
51367
51402
|
presenter: input.input.presenter,
|
|
51368
51403
|
codePrefix: input.codePrefix
|
|
51369
51404
|
});
|
|
51370
51405
|
if (input.status.kind !== "not_running") return { status: "aligned" };
|
|
51371
|
-
return mapDaemonBackgroundStartResult(await runDaemonStartDecisionPrompt({ startService: async () => await runDaemonBackgroundStartForDecision({
|
|
51406
|
+
return mapDaemonBackgroundStartResult(await runDaemonStartDecisionPrompt({ startService: async () => await runDaemonBackgroundStartForDecision({
|
|
51407
|
+
gatewayUrl: input.input.gatewayUrl,
|
|
51408
|
+
view: input.input.view
|
|
51409
|
+
}) }), {
|
|
51372
51410
|
presenter: input.input.presenter,
|
|
51373
51411
|
codePrefix: input.codePrefix
|
|
51374
51412
|
});
|
|
@@ -51495,7 +51533,10 @@ async function runServiceCheck(input) {
|
|
|
51495
51533
|
return { status: "cancelled" };
|
|
51496
51534
|
}
|
|
51497
51535
|
if (selected === CONTINUE_WITHOUT_SERVICE) return { status: "continue" };
|
|
51498
|
-
if (!await fixServiceStatus(
|
|
51536
|
+
if (!await fixServiceStatus({
|
|
51537
|
+
gatewayUrl: input.context.gatewayUrl,
|
|
51538
|
+
serviceStatus
|
|
51539
|
+
})) return { status: "continue" };
|
|
51499
51540
|
return { status: "continue" };
|
|
51500
51541
|
}
|
|
51501
51542
|
async function resolveServiceStatus(input) {
|
|
@@ -51549,16 +51590,16 @@ async function resolveServiceStatus(input) {
|
|
|
51549
51590
|
};
|
|
51550
51591
|
});
|
|
51551
51592
|
}
|
|
51552
|
-
async function fixServiceStatus(
|
|
51593
|
+
async function fixServiceStatus(input) {
|
|
51553
51594
|
const expectedVersion = resolveCurrentDaemonExpectedVersion();
|
|
51554
|
-
if (serviceStatus.kind === "missing") {
|
|
51595
|
+
if (input.serviceStatus.kind === "missing") {
|
|
51555
51596
|
await ensureDaemonInstalledForCliStartup({
|
|
51556
51597
|
daemonVersion: expectedVersion,
|
|
51557
51598
|
mode: "always"
|
|
51558
51599
|
});
|
|
51559
51600
|
return true;
|
|
51560
51601
|
}
|
|
51561
|
-
if (serviceStatus.kind === "outdated") {
|
|
51602
|
+
if (input.serviceStatus.kind === "outdated") {
|
|
51562
51603
|
const daemonStatus = await getDaemonStatus();
|
|
51563
51604
|
await ensureDaemonVersionForCliStartup({
|
|
51564
51605
|
daemonVersion: expectedVersion,
|
|
@@ -51567,9 +51608,15 @@ async function fixServiceStatus(serviceStatus) {
|
|
|
51567
51608
|
});
|
|
51568
51609
|
return true;
|
|
51569
51610
|
}
|
|
51570
|
-
if (serviceStatus.kind === "not_running") return await runDaemonBackgroundStartForDecision({
|
|
51571
|
-
|
|
51572
|
-
|
|
51611
|
+
if (input.serviceStatus.kind === "not_running") return await runDaemonBackgroundStartForDecision({
|
|
51612
|
+
gatewayUrl: input.gatewayUrl ?? void 0,
|
|
51613
|
+
view: "human"
|
|
51614
|
+
}) === "started";
|
|
51615
|
+
if (input.serviceStatus.kind === "needs_repair") return await runDaemonBackgroundStartForDecision({
|
|
51616
|
+
gatewayUrl: input.gatewayUrl ?? void 0,
|
|
51617
|
+
view: "human"
|
|
51618
|
+
}) === "started";
|
|
51619
|
+
if (input.serviceStatus.kind === "repair_blocked" || input.serviceStatus.kind === "repair_failed") {
|
|
51573
51620
|
await runDaemonStatusSafely();
|
|
51574
51621
|
return false;
|
|
51575
51622
|
}
|
|
@@ -60988,7 +61035,9 @@ function buildReplyReadinessNextSteps(input) {
|
|
|
60988
61035
|
formatAtsCliCommand("ats service run")
|
|
60989
61036
|
];
|
|
60990
61037
|
case "profile.inactive": return [formatAtsCliCommand("ats profile list"), formatAtsCliCommand("ats profile set <agent-profile-id>")];
|
|
60991
|
-
case "profile.unbound":
|
|
61038
|
+
case "profile.unbound":
|
|
61039
|
+
if (controllerRef) return [formatAtsCliCommand(`ats profile update ${profileId} --controller-kind builtin --controller-ref ${controllerRef} --controller-enabled true`), formatAtsCliCommand(`ats space join <space-id> --profile ${profileId}`)];
|
|
61040
|
+
return [formatAtsCliCommand("ats start"), formatAtsCliCommand("ats agents list")];
|
|
60992
61041
|
case "controller.binding.disabled": return [formatAtsCliCommand(`ats profile update ${profileId} --controller-enabled true`)];
|
|
60993
61042
|
case "projection.missing": return [formatAtsCliCommand("ats doctor --repair")];
|
|
60994
61043
|
case "controller.registry.disabled": return [formatAtsCliCommand(`ats agents enable --agent ${agentCommandId}`), formatAtsCliCommand("ats doctor --repair")];
|
|
@@ -64257,41 +64306,20 @@ async function runStartSkillsStep(input) {
|
|
|
64257
64306
|
}
|
|
64258
64307
|
}
|
|
64259
64308
|
async function runStartAgentsStep(input) {
|
|
64260
|
-
const
|
|
64261
|
-
const selectableCandidates = builtinCandidates.filter((candidate) => candidate.selectable);
|
|
64262
|
-
const payload = buildStartAgentsPayload({
|
|
64263
|
-
builtinCandidates,
|
|
64264
|
-
selectableCandidates
|
|
64265
|
-
});
|
|
64266
|
-
const onboardingState = await getConfiguredStartV1OnboardingState().catch(() => null);
|
|
64267
|
-
const preconfiguredAgentSelection = resolvePreconfiguredStartAgentSelection({
|
|
64268
|
-
builtinCandidates,
|
|
64269
|
-
localAgentsSetupCompleted: typeof onboardingState?.localAgentsSetupCompletedAt === "string" && onboardingState.localAgentsSetupCompletedAt.length > 0,
|
|
64270
|
-
selectableCandidates
|
|
64271
|
-
});
|
|
64309
|
+
const agentSelectionState = await resolveStartAgentSelectionState();
|
|
64272
64310
|
if (input.runtime.resolvedView === "agent") {
|
|
64273
64311
|
input.presenter.data({
|
|
64274
64312
|
code: "start.agents",
|
|
64275
|
-
payload
|
|
64313
|
+
payload: agentSelectionState.payload
|
|
64314
|
+
});
|
|
64315
|
+
return createStartAgentsStepResult(agentSelectionState.preconfiguredAgentSelection ?? {
|
|
64316
|
+
mode: "unresolved",
|
|
64317
|
+
selectedAgentIds: []
|
|
64276
64318
|
});
|
|
64277
|
-
if (preconfiguredAgentSelection) return {
|
|
64278
|
-
agentSelection: preconfiguredAgentSelection,
|
|
64279
|
-
allowBackFromProfile: false
|
|
64280
|
-
};
|
|
64281
|
-
return {
|
|
64282
|
-
agentSelection: {
|
|
64283
|
-
mode: "unresolved",
|
|
64284
|
-
selectedAgentIds: []
|
|
64285
|
-
},
|
|
64286
|
-
allowBackFromProfile: false
|
|
64287
|
-
};
|
|
64288
64319
|
}
|
|
64289
|
-
if (preconfiguredAgentSelection) return
|
|
64290
|
-
agentSelection: preconfiguredAgentSelection,
|
|
64291
|
-
allowBackFromProfile: false
|
|
64292
|
-
};
|
|
64320
|
+
if (agentSelectionState.preconfiguredAgentSelection) return createStartAgentsStepResult(agentSelectionState.preconfiguredAgentSelection);
|
|
64293
64321
|
if (!input.interactive) {
|
|
64294
|
-
if (selectableCandidates.length > 0) input.presenter.line({
|
|
64322
|
+
if (agentSelectionState.selectableCandidates.length > 0) input.presenter.line({
|
|
64295
64323
|
code: "start.agents.non_interactive",
|
|
64296
64324
|
text: formatInlineAtsCliCommands("⚠️ Agent selection still needs a decision. Run `ats start` interactively or use `ats agents enable --all`, `ats agents enable --agent <id...>`, or `ats agents enable --agent <id> --install <install-id>` before continuing.")
|
|
64297
64325
|
});
|
|
@@ -64303,69 +64331,135 @@ async function runStartAgentsStep(input) {
|
|
|
64303
64331
|
allowBackFromProfile: false
|
|
64304
64332
|
};
|
|
64305
64333
|
}
|
|
64334
|
+
return await runInteractiveStartAgentsSelectionLoop({
|
|
64335
|
+
builtinCandidates: agentSelectionState.builtinCandidates,
|
|
64336
|
+
profile: input.profile,
|
|
64337
|
+
presenter: input.presenter,
|
|
64338
|
+
view: input.view
|
|
64339
|
+
});
|
|
64340
|
+
}
|
|
64341
|
+
async function resolveStartAgentSelectionState() {
|
|
64342
|
+
const builtinCandidates = (await listStartLocalBuiltinAgentCandidates()).sort(compareStartAgentCandidates);
|
|
64343
|
+
const selectableCandidates = builtinCandidates.filter((candidate) => candidate.selectable);
|
|
64344
|
+
const onboardingState = await getConfiguredStartV1OnboardingState().catch(() => null);
|
|
64345
|
+
const localAgentsSetupCompleted = typeof onboardingState?.localAgentsSetupCompletedAt === "string" && onboardingState.localAgentsSetupCompletedAt.length > 0;
|
|
64346
|
+
return {
|
|
64347
|
+
builtinCandidates,
|
|
64348
|
+
selectableCandidates,
|
|
64349
|
+
payload: buildStartAgentsPayload({
|
|
64350
|
+
builtinCandidates,
|
|
64351
|
+
selectableCandidates
|
|
64352
|
+
}),
|
|
64353
|
+
preconfiguredAgentSelection: resolvePreconfiguredStartAgentSelection({
|
|
64354
|
+
builtinCandidates,
|
|
64355
|
+
localAgentsSetupCompleted,
|
|
64356
|
+
selectableCandidates
|
|
64357
|
+
})
|
|
64358
|
+
};
|
|
64359
|
+
}
|
|
64360
|
+
function createStartAgentsStepResult(agentSelection, allowBackFromProfile = false) {
|
|
64361
|
+
return {
|
|
64362
|
+
agentSelection,
|
|
64363
|
+
allowBackFromProfile
|
|
64364
|
+
};
|
|
64365
|
+
}
|
|
64366
|
+
async function runInteractiveStartAgentsSelectionLoop(input) {
|
|
64306
64367
|
for (;;) {
|
|
64307
64368
|
const localAgentDecision = await promptStartLocalAgentDecision();
|
|
64308
64369
|
if (localAgentDecision === "cancelled" || localAgentDecision === "exit") {
|
|
64309
64370
|
cancel("Cancelled.");
|
|
64310
64371
|
return "cancelled";
|
|
64311
64372
|
}
|
|
64312
|
-
if (localAgentDecision === "no_agents") {
|
|
64313
|
-
|
|
64314
|
-
|
|
64315
|
-
|
|
64316
|
-
|
|
64317
|
-
|
|
64373
|
+
if (localAgentDecision === "no_agents") return await completeStartLocalAgentSelection({
|
|
64374
|
+
builtinCandidates: input.builtinCandidates,
|
|
64375
|
+
profile: input.profile,
|
|
64376
|
+
presenter: input.presenter,
|
|
64377
|
+
selectedAgentIds: [],
|
|
64378
|
+
view: input.view
|
|
64379
|
+
});
|
|
64380
|
+
const repairedBuiltinCandidates = await maybeRepairStartLocalAgentsBeforeSelection({
|
|
64381
|
+
builtinCandidates: input.builtinCandidates,
|
|
64382
|
+
profile: input.profile,
|
|
64383
|
+
view: input.view
|
|
64384
|
+
});
|
|
64385
|
+
if (repairedBuiltinCandidates === "cancelled") {
|
|
64386
|
+
cancel("Cancelled.");
|
|
64387
|
+
return "cancelled";
|
|
64388
|
+
}
|
|
64389
|
+
if (repairedBuiltinCandidates.filter((candidate) => candidate.selectable).length === 0) {
|
|
64390
|
+
input.presenter.line({
|
|
64391
|
+
code: "start.agents.none_ready_after_repair",
|
|
64392
|
+
text: formatInlineAtsCliCommands("No local agents are ready to use on this device yet. Repair one with `ats agents repair --agent <id>` or keep local agents off for now.")
|
|
64318
64393
|
});
|
|
64319
|
-
|
|
64320
|
-
emitStartLocalAgentsSetupSaved(input.presenter);
|
|
64321
|
-
return {
|
|
64322
|
-
agentSelection: {
|
|
64323
|
-
mode: "no_agents",
|
|
64324
|
-
selectedAgentIds: []
|
|
64325
|
-
},
|
|
64326
|
-
allowBackFromProfile: true
|
|
64327
|
-
};
|
|
64394
|
+
continue;
|
|
64328
64395
|
}
|
|
64329
|
-
const selectedAgentIds = await promptStartAgentSelection(
|
|
64396
|
+
const selectedAgentIds = await promptStartAgentSelection(repairedBuiltinCandidates);
|
|
64330
64397
|
if (selectedAgentIds === "cancelled") {
|
|
64331
64398
|
cancel("Cancelled.");
|
|
64332
64399
|
return "cancelled";
|
|
64333
64400
|
}
|
|
64334
64401
|
if (selectedAgentIds === "back") continue;
|
|
64335
|
-
if (selectedAgentIds.length === 0) {
|
|
64336
|
-
|
|
64337
|
-
builtinCandidates,
|
|
64338
|
-
selectedAgentIds,
|
|
64339
|
-
profile: input.profile,
|
|
64340
|
-
view: input.view
|
|
64341
|
-
});
|
|
64342
|
-
await persistStartLocalAgentsSetupCompleted();
|
|
64343
|
-
emitStartLocalAgentsSetupSaved(input.presenter);
|
|
64344
|
-
return {
|
|
64345
|
-
agentSelection: {
|
|
64346
|
-
mode: "no_agents",
|
|
64347
|
-
selectedAgentIds: []
|
|
64348
|
-
},
|
|
64349
|
-
allowBackFromProfile: true
|
|
64350
|
-
};
|
|
64351
|
-
}
|
|
64352
|
-
await syncStartLocalAgentSelection({
|
|
64353
|
-
builtinCandidates,
|
|
64354
|
-
selectedAgentIds,
|
|
64402
|
+
if (selectedAgentIds.length === 0) return await completeStartLocalAgentSelection({
|
|
64403
|
+
builtinCandidates: input.builtinCandidates,
|
|
64355
64404
|
profile: input.profile,
|
|
64405
|
+
presenter: input.presenter,
|
|
64406
|
+
selectedAgentIds: [],
|
|
64407
|
+
view: input.view
|
|
64408
|
+
});
|
|
64409
|
+
return await completeStartLocalAgentSelection({
|
|
64410
|
+
builtinCandidates: repairedBuiltinCandidates,
|
|
64411
|
+
profile: input.profile,
|
|
64412
|
+
presenter: input.presenter,
|
|
64413
|
+
selectedAgentIds,
|
|
64356
64414
|
view: input.view
|
|
64357
64415
|
});
|
|
64358
|
-
await persistStartLocalAgentsSetupCompleted();
|
|
64359
|
-
emitStartLocalAgentsSetupSaved(input.presenter);
|
|
64360
|
-
return {
|
|
64361
|
-
agentSelection: {
|
|
64362
|
-
mode: "selected_agents",
|
|
64363
|
-
selectedAgentIds
|
|
64364
|
-
},
|
|
64365
|
-
allowBackFromProfile: true
|
|
64366
|
-
};
|
|
64367
64416
|
}
|
|
64368
64417
|
}
|
|
64418
|
+
async function completeStartLocalAgentSelection(input) {
|
|
64419
|
+
await syncStartLocalAgentSelection({
|
|
64420
|
+
builtinCandidates: input.builtinCandidates,
|
|
64421
|
+
selectedAgentIds: input.selectedAgentIds,
|
|
64422
|
+
profile: input.profile,
|
|
64423
|
+
view: input.view
|
|
64424
|
+
});
|
|
64425
|
+
await persistStartLocalAgentsSetupCompleted();
|
|
64426
|
+
emitStartLocalAgentsSetupSaved(input.presenter);
|
|
64427
|
+
return createStartAgentsStepResult(input.selectedAgentIds.length === 0 ? {
|
|
64428
|
+
mode: "no_agents",
|
|
64429
|
+
selectedAgentIds: []
|
|
64430
|
+
} : {
|
|
64431
|
+
mode: "selected_agents",
|
|
64432
|
+
selectedAgentIds: [...input.selectedAgentIds]
|
|
64433
|
+
}, true);
|
|
64434
|
+
}
|
|
64435
|
+
async function maybeRepairStartLocalAgentsBeforeSelection(input) {
|
|
64436
|
+
const repairableCandidates = input.builtinCandidates.filter((candidate) => candidate.detected && !candidate.selectable && candidate.selectableReason === "needs_repair");
|
|
64437
|
+
if (repairableCandidates.length === 0) return input.builtinCandidates;
|
|
64438
|
+
const repairDecision = await select({
|
|
64439
|
+
message: buildStartLocalAgentRepairPromptMessage(repairableCandidates),
|
|
64440
|
+
initialValue: "repair_now",
|
|
64441
|
+
options: [{
|
|
64442
|
+
value: "repair_now",
|
|
64443
|
+
label: "Repair now"
|
|
64444
|
+
}, {
|
|
64445
|
+
value: "skip_for_now",
|
|
64446
|
+
label: "Skip for now"
|
|
64447
|
+
}]
|
|
64448
|
+
});
|
|
64449
|
+
if (isCancel(repairDecision)) return "cancelled";
|
|
64450
|
+
if (repairDecision !== "repair_now") return input.builtinCandidates;
|
|
64451
|
+
await runAgentsRepair({
|
|
64452
|
+
agent: repairableCandidates.map((candidate) => candidate.agentId),
|
|
64453
|
+
profile: input.profile,
|
|
64454
|
+
view: input.view
|
|
64455
|
+
});
|
|
64456
|
+
return await listStartLocalBuiltinAgentCandidates();
|
|
64457
|
+
}
|
|
64458
|
+
function buildStartLocalAgentRepairPromptMessage(candidates) {
|
|
64459
|
+
const displayNames = candidates.map((candidate) => candidate.displayName);
|
|
64460
|
+
if (displayNames.length === 1) return `${displayNames[0]} needs repair on this device before ATS can use it. Repair it now?`;
|
|
64461
|
+
return `${displayNames.join(", ")} need repair on this device before ATS can use them. Repair them now?`;
|
|
64462
|
+
}
|
|
64369
64463
|
function buildStartAgentsPayload(input) {
|
|
64370
64464
|
return {
|
|
64371
64465
|
candidates: input.builtinCandidates.map((candidate) => ({
|
|
@@ -64397,11 +64491,17 @@ function resolveSavedStartAgentSelection(selectableCandidates) {
|
|
|
64397
64491
|
};
|
|
64398
64492
|
}
|
|
64399
64493
|
function resolvePreconfiguredStartAgentSelection(input) {
|
|
64400
|
-
|
|
64494
|
+
const hasRepairableCandidates = input.builtinCandidates.some((candidate) => candidate.detected && !candidate.selectable && candidate.selectableReason === "needs_repair");
|
|
64495
|
+
if (input.builtinCandidates.length === 0) return {
|
|
64401
64496
|
mode: "no_agents",
|
|
64402
64497
|
selectedAgentIds: []
|
|
64403
64498
|
};
|
|
64499
|
+
if (input.selectableCandidates.length === 0 && hasRepairableCandidates) return null;
|
|
64404
64500
|
if (!input.localAgentsSetupCompleted) return null;
|
|
64501
|
+
if (input.selectableCandidates.length === 0) return {
|
|
64502
|
+
mode: "no_agents",
|
|
64503
|
+
selectedAgentIds: []
|
|
64504
|
+
};
|
|
64405
64505
|
return resolveSavedStartAgentSelection([...input.selectableCandidates]);
|
|
64406
64506
|
}
|
|
64407
64507
|
async function persistStartLocalAgentsSetupCompleted() {
|
|
@@ -64733,6 +64833,7 @@ async function runStartServiceStep(input) {
|
|
|
64733
64833
|
presenter: input.presenter,
|
|
64734
64834
|
resolvedView: input.runtime.resolvedView,
|
|
64735
64835
|
allowPrompt: input.interactive,
|
|
64836
|
+
gatewayUrl: input.gatewayUrl,
|
|
64736
64837
|
localDemand,
|
|
64737
64838
|
forcePrompt: selectedLocalAgentsRequireService || currentProfileIsExplicitLocalAgent,
|
|
64738
64839
|
view: input.view
|
|
@@ -64882,6 +64983,7 @@ async function runStartHandoff(input) {
|
|
|
64882
64983
|
const serviceStepResult = await runHandoffLocalStepWithFailedProgressSync({
|
|
64883
64984
|
run: async () => await runStartServiceStep({
|
|
64884
64985
|
foundation,
|
|
64986
|
+
gatewayUrl,
|
|
64885
64987
|
runtime: input.runtime,
|
|
64886
64988
|
presenter: input.presenter,
|
|
64887
64989
|
interactive: true,
|
|
@@ -79622,6 +79724,26 @@ const LOCAL_SERVICE_ONLY_JOIN_BLOCK_REASON_CODES = new Set([
|
|
|
79622
79724
|
"service.not_installed",
|
|
79623
79725
|
"service.not_running"
|
|
79624
79726
|
]);
|
|
79727
|
+
const LOCAL_PARTICIPATION_ONLY_JOIN_BLOCK_REASON_CODES = new Set([
|
|
79728
|
+
"service.not_installed",
|
|
79729
|
+
"service.drifted",
|
|
79730
|
+
"service.not_running",
|
|
79731
|
+
"dispatch.storage_not_ready",
|
|
79732
|
+
"service.gateway_chain_unhealthy",
|
|
79733
|
+
"profile.unbound",
|
|
79734
|
+
"controller.binding.disabled",
|
|
79735
|
+
"projection.missing",
|
|
79736
|
+
"controller.registry.disabled",
|
|
79737
|
+
"controller.launch.choice_required",
|
|
79738
|
+
"controller.launch.needs_repair",
|
|
79739
|
+
"workspace.missing",
|
|
79740
|
+
"workspace.invalid",
|
|
79741
|
+
"runtime.adapter.unsupported",
|
|
79742
|
+
"controller.bootstrap.failed",
|
|
79743
|
+
"controller.gateway.unhealthy",
|
|
79744
|
+
"route.offline",
|
|
79745
|
+
"route.not_registered"
|
|
79746
|
+
]);
|
|
79625
79747
|
async function prepareSpaceJoinEntryContext(input) {
|
|
79626
79748
|
const runtime = await resolveRuntimeContext({
|
|
79627
79749
|
profile: input.profile,
|
|
@@ -79724,19 +79846,18 @@ async function prepareSpaceJoinServiceState(input) {
|
|
|
79724
79846
|
};
|
|
79725
79847
|
}
|
|
79726
79848
|
async function assertSpaceJoinTargetPreflightReady(input) {
|
|
79727
|
-
const
|
|
79728
|
-
|
|
79729
|
-
|
|
79730
|
-
explicitSelectedLocalAgents: isExplicitLocalAgentProfile(input.atsProfile),
|
|
79731
|
-
selectedAgentProfilesHaveRunnableLocalSetup: hasRunnableLocalAgentSetup(input.atsProfile),
|
|
79732
|
-
localDemand: input.localDemand ?? null
|
|
79733
|
-
}) : "not_needed";
|
|
79849
|
+
const { explicitLocalAgentProfile, serviceRequirement } = resolveSpaceJoinLocalParticipationState(input);
|
|
79850
|
+
let emittedMembershipOnlyGuidance = false;
|
|
79851
|
+
let emittedServiceGuidance = false;
|
|
79734
79852
|
if (serviceRequirement === "agent_setup_needed") {
|
|
79735
79853
|
input.presenter.line({
|
|
79736
|
-
code: "space.join.
|
|
79737
|
-
text:
|
|
79854
|
+
code: "space.join.local_participation.pending",
|
|
79855
|
+
text: buildSpaceJoinMembershipOnlyMessage({
|
|
79856
|
+
atsProfile: input.atsProfile,
|
|
79857
|
+
reasonCodes: ["profile.unbound"]
|
|
79858
|
+
})
|
|
79738
79859
|
});
|
|
79739
|
-
|
|
79860
|
+
emittedMembershipOnlyGuidance = true;
|
|
79740
79861
|
}
|
|
79741
79862
|
const shouldManageServiceParticipation = serviceRequirement === "offer_service_gate";
|
|
79742
79863
|
const runPreflight = async () => await emitSpaceCommandPreflight({
|
|
@@ -79749,12 +79870,14 @@ async function assertSpaceJoinTargetPreflightReady(input) {
|
|
|
79749
79870
|
});
|
|
79750
79871
|
let preflight = await runPreflight();
|
|
79751
79872
|
if (shouldManageServiceParticipation) {
|
|
79752
|
-
const gateResult = await
|
|
79753
|
-
|
|
79873
|
+
const gateResult = await runSpaceJoinServiceParticipationGate({
|
|
79874
|
+
allowPrompt: input.allowPrompt,
|
|
79875
|
+
explicitLocalAgentProfile,
|
|
79876
|
+
gatewayUrl: input.baseUrl,
|
|
79877
|
+
localDemand: input.localDemand,
|
|
79754
79878
|
presenter: input.presenter,
|
|
79755
79879
|
resolvedView: input.resolvedView,
|
|
79756
|
-
|
|
79757
|
-
localDemand: input.localDemand ?? null,
|
|
79880
|
+
serviceIntent: input.serviceIntent,
|
|
79758
79881
|
view: input.view
|
|
79759
79882
|
});
|
|
79760
79883
|
if (gateResult.status === "cancelled") return "cancelled";
|
|
@@ -79767,24 +79890,90 @@ async function assertSpaceJoinTargetPreflightReady(input) {
|
|
|
79767
79890
|
humanServiceGuidanceMode: "suppress",
|
|
79768
79891
|
emitOutput: false
|
|
79769
79892
|
});
|
|
79770
|
-
if (gateResult.status === "declined")
|
|
79771
|
-
|
|
79772
|
-
|
|
79893
|
+
if (gateResult.status === "declined") {
|
|
79894
|
+
input.presenter.line({
|
|
79895
|
+
code: "space.join.service.declined",
|
|
79896
|
+
text: "ATS will continue joining this space without wakeable local agent participation on this device. To enable background replies later, rerun `ats start` or use `ats service install` and `ats service run`."
|
|
79897
|
+
});
|
|
79898
|
+
emittedServiceGuidance = true;
|
|
79899
|
+
}
|
|
79900
|
+
}
|
|
79901
|
+
const blockedJoinResult = handleBlockedSpaceJoinLocalParticipation({
|
|
79902
|
+
atsProfile: input.atsProfile,
|
|
79903
|
+
explicitLocalAgentProfile,
|
|
79904
|
+
preflight,
|
|
79905
|
+
presenter: input.presenter,
|
|
79906
|
+
serviceRequirement,
|
|
79907
|
+
emittedMembershipOnlyGuidance,
|
|
79908
|
+
emittedServiceGuidance
|
|
79909
|
+
});
|
|
79910
|
+
if (blockedJoinResult) return blockedJoinResult;
|
|
79911
|
+
if (preflight.deviceReplyReadiness.replyReadiness === "blocked") throw new Error(preflight.deviceReplyReadiness.reasonText);
|
|
79912
|
+
return "continue";
|
|
79913
|
+
}
|
|
79914
|
+
function resolveSpaceJoinLocalParticipationState(input) {
|
|
79915
|
+
const explicitLocalAgentProfile = isExplicitLocalAgentProfile(input.atsProfile);
|
|
79916
|
+
return {
|
|
79917
|
+
explicitLocalAgentProfile,
|
|
79918
|
+
serviceRequirement: resolveCliServiceParticipationRequirement({
|
|
79919
|
+
intent: input.serviceIntent ?? "space_join",
|
|
79920
|
+
humanOnlyParticipation: !explicitLocalAgentProfile && input.localDemand?.decision !== "keep_running",
|
|
79921
|
+
explicitSelectedLocalAgents: explicitLocalAgentProfile,
|
|
79922
|
+
selectedAgentProfilesHaveRunnableLocalSetup: hasRunnableLocalAgentSetup(input.atsProfile),
|
|
79923
|
+
localDemand: input.localDemand ?? null
|
|
79924
|
+
})
|
|
79925
|
+
};
|
|
79926
|
+
}
|
|
79927
|
+
async function runSpaceJoinServiceParticipationGate(input) {
|
|
79928
|
+
return await runDaemonServiceParticipationGate({
|
|
79929
|
+
intent: input.serviceIntent ?? "space_join",
|
|
79930
|
+
presenter: input.presenter,
|
|
79931
|
+
resolvedView: input.resolvedView,
|
|
79932
|
+
allowPrompt: input.allowPrompt ?? true,
|
|
79933
|
+
gatewayUrl: input.gatewayUrl,
|
|
79934
|
+
localDemand: input.localDemand ?? null,
|
|
79935
|
+
forcePrompt: input.explicitLocalAgentProfile,
|
|
79936
|
+
view: input.view
|
|
79937
|
+
});
|
|
79938
|
+
}
|
|
79939
|
+
function handleBlockedSpaceJoinLocalParticipation(input) {
|
|
79940
|
+
if (input.preflight.deviceReplyReadiness.replyReadiness !== "blocked" || !isBlockingLocalParticipationJoinAttention(input.preflight)) return null;
|
|
79941
|
+
if (input.explicitLocalAgentProfile) {
|
|
79942
|
+
if (!input.emittedMembershipOnlyGuidance) input.presenter.line({
|
|
79943
|
+
code: "space.join.local_participation.pending",
|
|
79944
|
+
text: buildSpaceJoinMembershipOnlyMessage({
|
|
79945
|
+
atsProfile: input.atsProfile,
|
|
79946
|
+
reasonCodes: input.preflight.deviceReplyReadiness.reasonCodes
|
|
79947
|
+
})
|
|
79773
79948
|
});
|
|
79949
|
+
return "continue";
|
|
79774
79950
|
}
|
|
79775
|
-
if (
|
|
79776
|
-
|
|
79951
|
+
if (input.serviceRequirement === "not_needed") {
|
|
79952
|
+
input.presenter.line({
|
|
79777
79953
|
code: "space.join.service.not_needed",
|
|
79778
79954
|
text: "ATS will keep joining this space without wakeable local agent participation on this device. If you decide to bring local agents later, rerun `ats start` or use `ats service install` and `ats service run`."
|
|
79779
79955
|
});
|
|
79780
79956
|
return "continue";
|
|
79781
79957
|
}
|
|
79782
|
-
if (
|
|
79958
|
+
if (!input.emittedServiceGuidance) input.presenter.line({
|
|
79959
|
+
code: "space.join.service.pending",
|
|
79960
|
+
text: "ATS will keep joining this space without wakeable local agent participation on this device until ATS Service is ready. To enable background replies later, rerun `ats start` or use `ats service install` and `ats service run`."
|
|
79961
|
+
});
|
|
79783
79962
|
return "continue";
|
|
79784
79963
|
}
|
|
79785
|
-
function
|
|
79964
|
+
function isBlockingLocalParticipationJoinAttention(preflight) {
|
|
79786
79965
|
const { deviceReplyReadiness } = preflight;
|
|
79787
|
-
return deviceReplyReadiness.replyReadiness === "blocked" && deviceReplyReadiness.reasonCodes.length > 0 && deviceReplyReadiness.reasonCodes.every((reasonCode) =>
|
|
79966
|
+
return deviceReplyReadiness.replyReadiness === "blocked" && deviceReplyReadiness.reasonCodes.length > 0 && deviceReplyReadiness.reasonCodes.every((reasonCode) => LOCAL_PARTICIPATION_ONLY_JOIN_BLOCK_REASON_CODES.has(reasonCode));
|
|
79967
|
+
}
|
|
79968
|
+
function buildSpaceJoinMembershipOnlyMessage(input) {
|
|
79969
|
+
const profileName = input.atsProfile.profileName;
|
|
79970
|
+
const profileId = input.atsProfile.atsProfileId;
|
|
79971
|
+
const reasonCodes = input.reasonCodes;
|
|
79972
|
+
const setupCommand = `ats profile ready --profile ${profileId}`;
|
|
79973
|
+
if (reasonCodes.includes("profile.unbound")) return `${profileName} will join this space, but it is not connected to a local agent on this device yet. It can appear here now, but it will not wake or reply from this device until you finish setup. Use \`${setupCommand}\` or rerun \`ats start\`.`;
|
|
79974
|
+
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 `${profileName} will join this space, but it will not wake or reply from this device until ATS Service is ready. Use \`ats service install\`, \`ats service run\`, or rerun \`ats start\`.`;
|
|
79975
|
+
if (reasonCodes.includes("controller.launch.needs_repair") || reasonCodes.includes("controller.launch.choice_required") || reasonCodes.includes("workspace.missing") || reasonCodes.includes("workspace.invalid")) return `${profileName} will join this space, but it is not ready to wake or reply from this device yet. Use \`${setupCommand}\` or rerun \`ats start\`.`;
|
|
79976
|
+
return `${profileName} will join this space, but local setup on this device is still incomplete. It can appear here now, but it will not wake or reply from this device until you finish setup. Use \`${setupCommand}\` or rerun \`ats start\`.`;
|
|
79788
79977
|
}
|
|
79789
79978
|
function buildJoinTargetMissingMessage(input) {
|
|
79790
79979
|
return formatMessage(input.resolvedView, "space.target.missing", { command: "join" });
|
|
@@ -80144,7 +80333,7 @@ function resolveSpaceJoinMembershipProfileKind(value) {
|
|
|
80144
80333
|
return value === "human" || value === "agent" ? value : null;
|
|
80145
80334
|
}
|
|
80146
80335
|
function normalizeOptionalString$2(value) {
|
|
80147
|
-
return typeof value === "string" ? value :
|
|
80336
|
+
return typeof value === "string" ? value : void 0;
|
|
80148
80337
|
}
|
|
80149
80338
|
function buildLocallyCreatedPendingSpaceJoinMembershipCandidate(profile) {
|
|
80150
80339
|
return {
|
|
@@ -80153,8 +80342,8 @@ function buildLocallyCreatedPendingSpaceJoinMembershipCandidate(profile) {
|
|
|
80153
80342
|
profileName: profile.profileName,
|
|
80154
80343
|
profileKind: profile.profileKind === "agent" ? "agent" : "human",
|
|
80155
80344
|
ownerUserId: profile.ownerUserId,
|
|
80156
|
-
ownerName: typeof profile.ownerName === "string" ? profile.ownerName :
|
|
80157
|
-
controllerRef: profile.controllerBinding?.controllerRef
|
|
80345
|
+
ownerName: typeof profile.ownerName === "string" ? profile.ownerName : void 0,
|
|
80346
|
+
controllerRef: profile.controllerBinding?.controllerRef,
|
|
80158
80347
|
controllerEnabled: profile.controllerBinding?.controllerEnabled === true,
|
|
80159
80348
|
alreadyJoined: false,
|
|
80160
80349
|
needsActivation: false
|
|
@@ -80367,15 +80556,16 @@ async function applySelectedSpaceAddMembersBeforeJoin(input, dependencies) {
|
|
|
80367
80556
|
});
|
|
80368
80557
|
}
|
|
80369
80558
|
if (confirmedCandidates.candidates.length === 0) return "completed";
|
|
80370
|
-
|
|
80559
|
+
const servicePreparationResult = await dependencies.prepareSpaceMemberCandidatesLocalParticipation({
|
|
80371
80560
|
actorProfile: input.actorProfile,
|
|
80372
80561
|
candidates: confirmedCandidates.candidates,
|
|
80373
80562
|
presenter: input.presenter,
|
|
80374
80563
|
resolvedView: input.resolvedView
|
|
80375
|
-
})
|
|
80564
|
+
});
|
|
80565
|
+
if (servicePreparationResult.status === "cancelled") return input.cancelResult;
|
|
80376
80566
|
const result = await dependencies.applySpaceAddMembers({
|
|
80377
80567
|
actorProfile: input.actorProfile,
|
|
80378
|
-
candidates:
|
|
80568
|
+
candidates: servicePreparationResult.candidates,
|
|
80379
80569
|
space: input.space,
|
|
80380
80570
|
baseUrl: input.baseUrl,
|
|
80381
80571
|
password: input.password
|
|
@@ -80391,7 +80581,7 @@ async function applySelectedSpaceAddMembersBeforeJoin(input, dependencies) {
|
|
|
80391
80581
|
presenter: input.presenter,
|
|
80392
80582
|
resolvedView: input.resolvedView,
|
|
80393
80583
|
space: input.space,
|
|
80394
|
-
selectedCount:
|
|
80584
|
+
selectedCount: servicePreparationResult.candidates.length,
|
|
80395
80585
|
result,
|
|
80396
80586
|
joinNoticeSummary
|
|
80397
80587
|
});
|
|
@@ -82032,20 +82222,22 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
82032
82222
|
selectedProfileIds
|
|
82033
82223
|
});
|
|
82034
82224
|
if (selectedCandidates.length === 0) return { status: "completed" };
|
|
82035
|
-
|
|
82225
|
+
const servicePreparationResult = await ensureSpaceMemberCandidatesLocalParticipationReady({
|
|
82036
82226
|
atsProfile: input.atsProfile,
|
|
82037
82227
|
candidates: selectedCandidates,
|
|
82038
82228
|
presenter: input.presenter,
|
|
82039
82229
|
resolvedView: input.runtime.resolvedView,
|
|
82040
82230
|
allowPrompt: input.allowPrompt,
|
|
82041
82231
|
view: input.view
|
|
82042
|
-
})
|
|
82232
|
+
});
|
|
82233
|
+
if (servicePreparationResult.status === "cancelled") return input.allowBackToCaller ? {
|
|
82043
82234
|
status: "repeat_target",
|
|
82044
82235
|
authenticatedGatewayUrl
|
|
82045
82236
|
} : { status: "cancelled" };
|
|
82237
|
+
const preparedCandidates = servicePreparationResult.candidates;
|
|
82046
82238
|
const result = await applySpaceAddMembers({
|
|
82047
82239
|
actorProfile: input.atsProfile,
|
|
82048
|
-
candidates:
|
|
82240
|
+
candidates: preparedCandidates,
|
|
82049
82241
|
space: input.target.space,
|
|
82050
82242
|
baseUrl: targetBaseUrl,
|
|
82051
82243
|
password: input.password
|
|
@@ -82061,7 +82253,7 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
82061
82253
|
presenter: input.presenter,
|
|
82062
82254
|
resolvedView: input.runtime.resolvedView,
|
|
82063
82255
|
space: input.target.space,
|
|
82064
|
-
selectedCount:
|
|
82256
|
+
selectedCount: preparedCandidates.length,
|
|
82065
82257
|
result,
|
|
82066
82258
|
joinNoticeSummary
|
|
82067
82259
|
});
|
|
@@ -82150,44 +82342,157 @@ function resolveSelectedSpaceMemberCandidates(input) {
|
|
|
82150
82342
|
return input.selectedProfileIds.map((profileId) => input.candidates.find((candidate) => candidate.profileId === profileId)).filter((candidate) => Boolean(candidate));
|
|
82151
82343
|
}
|
|
82152
82344
|
async function ensureSpaceMemberCandidatesLocalParticipationReady(input) {
|
|
82153
|
-
|
|
82154
|
-
const
|
|
82345
|
+
let preparedCandidates = await refreshSpaceMemberCandidatesLocalReadiness(input.candidates);
|
|
82346
|
+
const repairableCandidates = preparedCandidates.filter(isSpaceMemberCandidateRepairableLocalParticipationCandidate);
|
|
82347
|
+
if (repairableCandidates.length > 0 && input.resolvedView === "human" && input.allowPrompt) {
|
|
82348
|
+
const repairNow = await confirm({
|
|
82349
|
+
message: buildSpaceMemberRepairPromptMessage(repairableCandidates),
|
|
82350
|
+
active: "Repair now",
|
|
82351
|
+
inactive: "Not now",
|
|
82352
|
+
initialValue: true
|
|
82353
|
+
});
|
|
82354
|
+
if (isCancel(repairNow)) {
|
|
82355
|
+
cancel("Cancelled.");
|
|
82356
|
+
return { status: "cancelled" };
|
|
82357
|
+
}
|
|
82358
|
+
if (repairNow) {
|
|
82359
|
+
await repairSpaceMemberCandidatesLocalParticipation({
|
|
82360
|
+
atsProfile: input.atsProfile,
|
|
82361
|
+
candidates: repairableCandidates,
|
|
82362
|
+
view: input.view
|
|
82363
|
+
});
|
|
82364
|
+
preparedCandidates = await refreshSpaceMemberCandidatesLocalReadiness(preparedCandidates);
|
|
82365
|
+
}
|
|
82366
|
+
}
|
|
82367
|
+
const wakeableLocalCandidates = preparedCandidates.filter(isSpaceMemberCandidateRunnableLocalParticipationCandidate);
|
|
82368
|
+
const explicitSelectedLocalAgents = hasAnyExplicitLocalAgentCandidates(wakeableLocalCandidates);
|
|
82369
|
+
if (resolveCliServiceParticipationRequirement({
|
|
82155
82370
|
intent: "space_add_members",
|
|
82156
82371
|
humanOnlyParticipation: !explicitSelectedLocalAgents,
|
|
82157
82372
|
explicitSelectedLocalAgents,
|
|
82158
|
-
selectedAgentProfilesHaveRunnableLocalSetup: haveAllExplicitLocalAgentCandidatesRunnable(
|
|
82373
|
+
selectedAgentProfilesHaveRunnableLocalSetup: haveAllExplicitLocalAgentCandidatesRunnable(wakeableLocalCandidates),
|
|
82159
82374
|
localDemand: input.resolvedView === "human" ? await resolveDaemonLocalServiceDemand({ ownerUserId: input.atsProfile.ownerUserId }).catch(() => null) : null
|
|
82160
|
-
})
|
|
82161
|
-
|
|
82162
|
-
|
|
82163
|
-
|
|
82164
|
-
code: "space.add_members.agent_setup_needed",
|
|
82165
|
-
text: "At least one selected agent profile is not set up on this device yet. Finish agent setup first, then retry. Use `ats start` or `ats profile ready --profile <agent-profile-id>`."
|
|
82166
|
-
});
|
|
82167
|
-
return "cancelled";
|
|
82168
|
-
}
|
|
82375
|
+
}) === "not_needed") return {
|
|
82376
|
+
status: "continue",
|
|
82377
|
+
candidates: preparedCandidates
|
|
82378
|
+
};
|
|
82169
82379
|
if (!(input.resolvedView === "human" && input.allowPrompt)) {
|
|
82170
82380
|
input.presenter.line({
|
|
82171
82381
|
code: "space.add_members.service.deferred",
|
|
82172
82382
|
text: "ATS will continue without wakeable local agent participation on this device. To enable background replies later, rerun `ats start` or use `ats service install` and `ats service run`."
|
|
82173
82383
|
});
|
|
82174
|
-
return
|
|
82384
|
+
return {
|
|
82385
|
+
status: "continue",
|
|
82386
|
+
candidates: preparedCandidates
|
|
82387
|
+
};
|
|
82175
82388
|
}
|
|
82176
82389
|
const gateResult = await runDaemonServiceParticipationGate({
|
|
82177
82390
|
intent: "space_add_members",
|
|
82178
82391
|
presenter: input.presenter,
|
|
82179
82392
|
resolvedView: input.resolvedView,
|
|
82180
82393
|
allowPrompt: input.allowPrompt,
|
|
82394
|
+
gatewayUrl: input.gatewayUrl,
|
|
82181
82395
|
localDemand: await resolveDaemonLocalServiceDemand({ ownerUserId: input.atsProfile.ownerUserId }).catch(() => null),
|
|
82182
82396
|
forcePrompt: explicitSelectedLocalAgents,
|
|
82183
82397
|
view: input.view
|
|
82184
82398
|
});
|
|
82185
|
-
if (gateResult.status === "cancelled") return "cancelled";
|
|
82399
|
+
if (gateResult.status === "cancelled") return { status: "cancelled" };
|
|
82186
82400
|
if (gateResult.status !== "aligned") input.presenter.line({
|
|
82187
82401
|
code: "space.add_members.service.declined",
|
|
82188
82402
|
text: "ATS will continue adding these profiles without wakeable local agent participation on this device. To enable background replies later, rerun `ats start` or use `ats service install` and `ats service run`."
|
|
82189
82403
|
});
|
|
82190
|
-
return
|
|
82404
|
+
return {
|
|
82405
|
+
status: "continue",
|
|
82406
|
+
candidates: preparedCandidates
|
|
82407
|
+
};
|
|
82408
|
+
}
|
|
82409
|
+
async function repairSpaceMemberCandidatesLocalParticipation(input) {
|
|
82410
|
+
if (input.candidates.some((candidate) => candidate.localParticipationReasonCodes?.some((reasonCode) => reasonCode === "projection.missing" || reasonCode === "controller.launch.needs_repair"))) await syncDeviceRuntimeStateProjection({ mode: "repair" });
|
|
82411
|
+
const repairableAgentIds = [...new Set(input.candidates.map((candidate) => candidate.localTargetLaunchStatus === "needs_repair" ? candidate.localTargetAgentId ?? null : null).filter((value) => Boolean(value)))];
|
|
82412
|
+
if (repairableAgentIds.length > 0) await runAgentsRepair({
|
|
82413
|
+
agent: repairableAgentIds,
|
|
82414
|
+
profile: input.atsProfile.atsProfileId,
|
|
82415
|
+
view: input.view
|
|
82416
|
+
});
|
|
82417
|
+
if (input.candidates.some((candidate) => candidate.localParticipationReasonCodes?.some((reasonCode) => reasonCode === "workspace.missing" || reasonCode === "workspace.invalid"))) await syncProfileWorkspaceState({ mode: "repair" });
|
|
82418
|
+
if (input.candidates.some((candidate) => candidate.localParticipationReasonCodes?.some((reasonCode) => reasonCode === "dispatch.storage_not_ready" || reasonCode === "service.gateway_chain_unhealthy"))) await runDoctor({
|
|
82419
|
+
profile: input.atsProfile.atsProfileId,
|
|
82420
|
+
repair: true,
|
|
82421
|
+
view: input.view,
|
|
82422
|
+
agentOverviewHandled: true
|
|
82423
|
+
});
|
|
82424
|
+
}
|
|
82425
|
+
async function refreshSpaceMemberCandidatesLocalReadiness(candidates) {
|
|
82426
|
+
const localTargetStates = await listAgentTargetStates().catch(() => []);
|
|
82427
|
+
if (localTargetStates.length === 0) return await Promise.all(candidates.map(async (candidate) => {
|
|
82428
|
+
return await enrichSpaceMemberCandidateLocalParticipationReadiness({
|
|
82429
|
+
...candidate,
|
|
82430
|
+
localTargetDisplayName: candidate.localTargetDisplayName ?? null,
|
|
82431
|
+
localTargetLaunchStatus: candidate.localTargetLaunchStatus ?? null,
|
|
82432
|
+
localTargetSelectable: candidate.localTargetSelectable ?? false
|
|
82433
|
+
});
|
|
82434
|
+
}));
|
|
82435
|
+
const localTargetStateById = new Map(localTargetStates.map((state) => [state.agentId, state]));
|
|
82436
|
+
return await Promise.all(candidates.map(async (candidate) => {
|
|
82437
|
+
const localTargetAgentId = resolveSpaceMemberCandidateLocalTargetAgentId({
|
|
82438
|
+
profileKind: candidate.profileKind,
|
|
82439
|
+
controllerRef: candidate.controllerRef,
|
|
82440
|
+
controllerEnabled: candidate.controllerEnabled
|
|
82441
|
+
});
|
|
82442
|
+
const localTargetState = localTargetAgentId ? localTargetStateById.get(localTargetAgentId) ?? null : null;
|
|
82443
|
+
return await enrichSpaceMemberCandidateLocalParticipationReadiness({
|
|
82444
|
+
...candidate,
|
|
82445
|
+
localTargetAgentId,
|
|
82446
|
+
localTargetDisplayName: localTargetState?.displayName ?? null,
|
|
82447
|
+
localTargetLaunchStatus: localTargetState?.launchStatus ?? null,
|
|
82448
|
+
localTargetSelectable: localTargetState?.selectable ?? false
|
|
82449
|
+
});
|
|
82450
|
+
}));
|
|
82451
|
+
}
|
|
82452
|
+
async function enrichSpaceMemberCandidateLocalParticipationReadiness(candidate) {
|
|
82453
|
+
if (candidate.profileKind !== "agent" || !candidate.atsProfile || candidate.controllerEnabled !== true || typeof candidate.controllerRef !== "string" || candidate.controllerRef.trim().length === 0) return {
|
|
82454
|
+
...candidate,
|
|
82455
|
+
localParticipationReadiness: null,
|
|
82456
|
+
localParticipationReasonCodes: [],
|
|
82457
|
+
localParticipationReasonText: null
|
|
82458
|
+
};
|
|
82459
|
+
let snapshot = null;
|
|
82460
|
+
try {
|
|
82461
|
+
snapshot = await resolveCurrentReplyReadinessSnapshot({
|
|
82462
|
+
checkGatewayChain: false,
|
|
82463
|
+
ownerUserId: candidate.atsProfile.ownerUserId,
|
|
82464
|
+
profile: candidate.atsProfile
|
|
82465
|
+
});
|
|
82466
|
+
} catch {
|
|
82467
|
+
snapshot = null;
|
|
82468
|
+
}
|
|
82469
|
+
if (!snapshot) return {
|
|
82470
|
+
...candidate,
|
|
82471
|
+
localParticipationReadiness: null,
|
|
82472
|
+
localParticipationReasonCodes: [],
|
|
82473
|
+
localParticipationReasonText: null
|
|
82474
|
+
};
|
|
82475
|
+
const readinessSummary = resolveServiceParticipationReadiness({
|
|
82476
|
+
deviceReplyReadiness: snapshot.deviceReplyReadiness,
|
|
82477
|
+
runtimeStatus: snapshot.displayRuntimeStatus ?? snapshot.runtimeStatus
|
|
82478
|
+
});
|
|
82479
|
+
return {
|
|
82480
|
+
...candidate,
|
|
82481
|
+
localParticipationReadiness: readinessSummary.serviceReadiness,
|
|
82482
|
+
localParticipationReasonCodes: [...snapshot.deviceReplyReadiness.reasonCodes],
|
|
82483
|
+
localParticipationReasonText: snapshot.deviceReplyReadiness.reasonText
|
|
82484
|
+
};
|
|
82485
|
+
}
|
|
82486
|
+
function isSpaceMemberCandidateRunnableLocalParticipationCandidate(candidate) {
|
|
82487
|
+
return candidate.profileKind === "agent" && candidate.controllerEnabled === true && typeof candidate.controllerRef === "string" && candidate.controllerRef.trim().length > 0 && candidate.localTargetSelectable === true && (candidate.localParticipationReadiness === "ready" || candidate.localParticipationReadiness === "not_running" || candidate.localParticipationReadiness === "not_installed");
|
|
82488
|
+
}
|
|
82489
|
+
function isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate) {
|
|
82490
|
+
return candidate.profileKind === "agent" && candidate.controllerEnabled === true && typeof candidate.controllerRef === "string" && candidate.controllerRef.trim().length > 0 && (typeof candidate.localTargetAgentId === "string" && candidate.localTargetAgentId.trim().length > 0 && candidate.localTargetLaunchStatus === "needs_repair" || candidate.localParticipationReadiness === "needs_repair");
|
|
82491
|
+
}
|
|
82492
|
+
function buildSpaceMemberRepairPromptMessage(candidates) {
|
|
82493
|
+
const displayNames = candidates.map((candidate) => candidate.localTargetDisplayName || candidate.localTargetAgentId || candidate.profileName);
|
|
82494
|
+
if (displayNames.length === 1) return `${displayNames[0]} needs repair on this device before ATS can use it for background replies. Repair it now?`;
|
|
82495
|
+
return `${displayNames.join(", ")} need repair on this device before ATS can use them for background replies. Repair them now?`;
|
|
82191
82496
|
}
|
|
82192
82497
|
async function runSpaceJoin(input) {
|
|
82193
82498
|
let failureRuntime = null;
|
|
@@ -82344,6 +82649,7 @@ async function runSpaceJoinTargetLoop(input) {
|
|
|
82344
82649
|
prepareSpaceMemberCandidatesLocalParticipation: async ({ actorProfile, candidates, presenter, resolvedView }) => await ensureSpaceMemberCandidatesLocalParticipationReady({
|
|
82345
82650
|
atsProfile: actorProfile,
|
|
82346
82651
|
candidates,
|
|
82652
|
+
gatewayUrl: targetBaseUrl,
|
|
82347
82653
|
presenter,
|
|
82348
82654
|
resolvedView,
|
|
82349
82655
|
allowPrompt: input.canPromptPreJoinActions,
|
|
@@ -83360,6 +83666,8 @@ async function resolveSpaceRemoveMembersTarget(input) {
|
|
|
83360
83666
|
}
|
|
83361
83667
|
async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
83362
83668
|
const profiles = await listAtsProfiles();
|
|
83669
|
+
const localTargetStates = await listAgentTargetStates().catch(() => []);
|
|
83670
|
+
const localTargetStateById = new Map(localTargetStates.map((state) => [state.agentId, state]));
|
|
83363
83671
|
const ownerProfileNameByOwnerUserId = buildOwnerProfileNameByOwnerUserId(profiles);
|
|
83364
83672
|
const candidateProfiles = profiles.filter((profile) => profile.status === "active" && isSpaceMembershipProfileKind(profile.profileKind) && profile.atsProfileId !== input.currentProfile.atsProfileId).filter((profile) => typeof input.currentOwnerUserId !== "string" || input.currentOwnerUserId.trim().length === 0 || profile.ownerUserId === input.currentOwnerUserId);
|
|
83365
83673
|
if (candidateProfiles.length === 0) return [];
|
|
@@ -83369,25 +83677,55 @@ async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
|
83369
83677
|
...input.password === void 0 ? {} : { spacePassword: input.password }
|
|
83370
83678
|
});
|
|
83371
83679
|
const memberProfileIds = new Set([...membersSnapshot.humans, ...membersSnapshot.agents].map((member) => member.profileId));
|
|
83372
|
-
return candidateProfiles.map((profile) => {
|
|
83373
|
-
|
|
83374
|
-
|
|
83375
|
-
|
|
83376
|
-
|
|
83377
|
-
|
|
83378
|
-
ownerProfileName: ownerProfileNameByOwnerUserId.get(profile.ownerUserId),
|
|
83379
|
-
ownerUserId: profile.ownerUserId,
|
|
83380
|
-
ownerName: profile.ownerName,
|
|
83381
|
-
controllerRef: profile.controllerBinding?.controllerRef,
|
|
83382
|
-
controllerEnabled: profile.controllerBinding?.controllerEnabled,
|
|
83383
|
-
alreadyJoined: memberProfileIds.has(profile.atsProfileId),
|
|
83384
|
-
needsActivation: false
|
|
83385
|
-
};
|
|
83386
|
-
}).sort((left, right) => {
|
|
83680
|
+
return await refreshSpaceMemberCandidatesLocalReadiness(candidateProfiles.map((profile) => buildSpaceMemberCandidateFromProfile({
|
|
83681
|
+
profile,
|
|
83682
|
+
localTargetStateById,
|
|
83683
|
+
ownerProfileName: ownerProfileNameByOwnerUserId.get(profile.ownerUserId) ?? void 0,
|
|
83684
|
+
alreadyJoined: memberProfileIds.has(profile.atsProfileId)
|
|
83685
|
+
})).sort((left, right) => {
|
|
83387
83686
|
const byName = left.profileName.localeCompare(right.profileName);
|
|
83388
83687
|
if (byName !== 0) return byName;
|
|
83389
83688
|
return left.profileId.localeCompare(right.profileId);
|
|
83689
|
+
}));
|
|
83690
|
+
}
|
|
83691
|
+
function buildSpaceMemberCandidateFromProfile(input) {
|
|
83692
|
+
const controllerRef = input.profile.controllerBinding?.controllerRef;
|
|
83693
|
+
const controllerEnabled = input.profile.controllerBinding?.controllerEnabled;
|
|
83694
|
+
const localTargetAgentId = resolveSpaceMemberCandidateLocalTargetAgentId({
|
|
83695
|
+
profileKind: input.profile.profileKind,
|
|
83696
|
+
controllerRef,
|
|
83697
|
+
controllerEnabled
|
|
83390
83698
|
});
|
|
83699
|
+
const localTargetState = localTargetAgentId ? input.localTargetStateById.get(localTargetAgentId) ?? null : null;
|
|
83700
|
+
return {
|
|
83701
|
+
atsProfile: input.profile,
|
|
83702
|
+
profileId: input.profile.atsProfileId,
|
|
83703
|
+
profileHandle: input.profile.profileHandle,
|
|
83704
|
+
profileName: input.profile.profileName,
|
|
83705
|
+
profileKind: input.profile.profileKind,
|
|
83706
|
+
bindingState: input.profile.bindingState,
|
|
83707
|
+
ownerProfileName: input.ownerProfileName,
|
|
83708
|
+
ownerUserId: input.profile.ownerUserId,
|
|
83709
|
+
ownerName: input.profile.ownerName,
|
|
83710
|
+
controllerRef,
|
|
83711
|
+
controllerEnabled,
|
|
83712
|
+
localTargetAgentId,
|
|
83713
|
+
localTargetDisplayName: localTargetState?.displayName ?? null,
|
|
83714
|
+
localTargetLaunchStatus: localTargetState?.launchStatus ?? null,
|
|
83715
|
+
localTargetSelectable: localTargetState?.selectable ?? false,
|
|
83716
|
+
localParticipationReadiness: null,
|
|
83717
|
+
localParticipationReasonCodes: [],
|
|
83718
|
+
localParticipationReasonText: null,
|
|
83719
|
+
alreadyJoined: input.alreadyJoined,
|
|
83720
|
+
needsActivation: false
|
|
83721
|
+
};
|
|
83722
|
+
}
|
|
83723
|
+
function resolveSpaceMemberCandidateLocalTargetAgentId(input) {
|
|
83724
|
+
if (input.profileKind !== "agent" || input.controllerEnabled !== true || typeof input.controllerRef !== "string") return null;
|
|
83725
|
+
const controllerRef = input.controllerRef.trim();
|
|
83726
|
+
if (!controllerRef) return null;
|
|
83727
|
+
if (controllerRef.startsWith("builtin:")) return normalizeBuiltinControllerAgentId(controllerRef) || null;
|
|
83728
|
+
return controllerRef;
|
|
83391
83729
|
}
|
|
83392
83730
|
async function resolveSpaceMemberCandidatesForRemove(input) {
|
|
83393
83731
|
const membersSnapshot = await createCliSpaceApi(input.baseUrl).getMembersSnapshot({
|
|
@@ -83737,6 +84075,7 @@ async function applySpaceAddMembers(input) {
|
|
|
83737
84075
|
return result;
|
|
83738
84076
|
}
|
|
83739
84077
|
function emitSpaceAddMembersResult(input) {
|
|
84078
|
+
const localParticipationFollowUps = input.result.added.map((candidate) => buildSpaceMemberJoinedFollowUp(candidate)).filter((followUp) => followUp !== null);
|
|
83740
84079
|
if (input.resolvedView === "agent") {
|
|
83741
84080
|
input.presenter.data({
|
|
83742
84081
|
code: "space.add_members",
|
|
@@ -83757,7 +84096,11 @@ function emitSpaceAddMembersResult(input) {
|
|
|
83757
84096
|
recordedCount: input.joinNoticeSummary.recordedCount,
|
|
83758
84097
|
failedCount: input.joinNoticeSummary.failedCount,
|
|
83759
84098
|
...input.joinNoticeSummary.firstFailure ? { firstFailure: input.joinNoticeSummary.firstFailure } : {}
|
|
83760
|
-
}
|
|
84099
|
+
},
|
|
84100
|
+
localParticipationFollowUps: localParticipationFollowUps.map((followUp) => ({
|
|
84101
|
+
profileId: followUp.profileId,
|
|
84102
|
+
message: followUp.text
|
|
84103
|
+
}))
|
|
83761
84104
|
}
|
|
83762
84105
|
});
|
|
83763
84106
|
return;
|
|
@@ -83775,6 +84118,10 @@ function emitSpaceAddMembersResult(input) {
|
|
|
83775
84118
|
sanitize: true,
|
|
83776
84119
|
minContentWidth: 56
|
|
83777
84120
|
});
|
|
84121
|
+
for (const followUp of localParticipationFollowUps) input.presenter.line({
|
|
84122
|
+
code: "space.add_members.local_participation_follow_up",
|
|
84123
|
+
text: followUp.text
|
|
84124
|
+
});
|
|
83778
84125
|
if (input.result.failed.length > 0) for (const failure of input.result.failed) input.presenter.line({
|
|
83779
84126
|
code: "space.add_members.failed",
|
|
83780
84127
|
text: `${failure.candidate.profileId}: ${toErrorMessage$2(failure.error)}`
|
|
@@ -83794,6 +84141,22 @@ function emitSpaceAddMembersResult(input) {
|
|
|
83794
84141
|
firstFailure: input.joinNoticeSummary.firstFailure
|
|
83795
84142
|
});
|
|
83796
84143
|
}
|
|
84144
|
+
function buildSpaceMemberJoinedFollowUp(candidate) {
|
|
84145
|
+
if (candidate.profileKind !== "agent") return null;
|
|
84146
|
+
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) {
|
|
84147
|
+
const agentId = candidate.localTargetAgentId;
|
|
84148
|
+
const repairCommand = agentId ? `ats agents repair --agent ${agentId}` : "ats start";
|
|
84149
|
+
return {
|
|
84150
|
+
profileId: candidate.profileId,
|
|
84151
|
+
text: `${candidate.profileName} joined this space, but ${(candidate.localTargetDisplayName || candidate.localTargetAgentId || "this local agent").trim()} still needs repair on this device before it can wake or reply in the background. Use \`${repairCommand}\` or rerun \`ats start\`.`
|
|
84152
|
+
};
|
|
84153
|
+
}
|
|
84154
|
+
if (!isSpaceMemberCandidateRunnableLocalParticipationCandidate(candidate)) return {
|
|
84155
|
+
profileId: candidate.profileId,
|
|
84156
|
+
text: `${candidate.profileName} joined this space, but it is not connected to a local agent on this device yet. It can appear here now, but it will not wake or reply from this device until you finish setup. Use \`ats profile ready --profile ${candidate.profileId}\` or rerun \`ats start\`.`
|
|
84157
|
+
};
|
|
84158
|
+
return null;
|
|
84159
|
+
}
|
|
83797
84160
|
async function applySpaceRemoveMembers(input) {
|
|
83798
84161
|
const result = {
|
|
83799
84162
|
removed: [],
|
|
@@ -84134,7 +84497,7 @@ function formatSpaceMemberCandidateLabel(candidate) {
|
|
|
84134
84497
|
function formatSpaceMemberCandidateHint(candidate) {
|
|
84135
84498
|
if (candidate.alreadyJoined) return "Already in this space";
|
|
84136
84499
|
if (candidate.needsActivation) return "Needs mention setup";
|
|
84137
|
-
return "Selectable";
|
|
84500
|
+
return resolveSpaceMemberCandidateStatusLabel(candidate) ?? "Selectable";
|
|
84138
84501
|
}
|
|
84139
84502
|
function buildHumanSpaceMemberCandidateSearchItem(candidate) {
|
|
84140
84503
|
return {
|
|
@@ -84146,10 +84509,12 @@ function buildHumanSpaceMemberCandidateSearchItem(candidate) {
|
|
|
84146
84509
|
};
|
|
84147
84510
|
}
|
|
84148
84511
|
function buildHumanSpaceMemberCandidateDetail(candidate) {
|
|
84149
|
-
|
|
84150
|
-
if (candidate.alreadyJoined === true)
|
|
84151
|
-
else if (candidate.needsActivation)
|
|
84152
|
-
|
|
84512
|
+
const statuses = [];
|
|
84513
|
+
if (candidate.alreadyJoined === true) statuses.push("already in this space");
|
|
84514
|
+
else if (candidate.needsActivation) statuses.push("needs mention setup");
|
|
84515
|
+
const agentStatuses = resolveSpaceMemberCandidateStatusBadges(candidate);
|
|
84516
|
+
statuses.push(...agentStatuses.map((status) => status.toLowerCase()));
|
|
84517
|
+
return statuses.length > 0 ? `ID ${sanitizeSingleLinePromptText(candidate.profileId)} · ${statuses.map((status) => sanitizeSingleLinePromptText(status)).join(" · ")}` : `ID ${sanitizeSingleLinePromptText(candidate.profileId)}`;
|
|
84153
84518
|
}
|
|
84154
84519
|
function buildHumanSpaceMemberCandidateSearchText(candidate) {
|
|
84155
84520
|
return [
|
|
@@ -84160,10 +84525,26 @@ function buildHumanSpaceMemberCandidateSearchText(candidate) {
|
|
|
84160
84525
|
sanitizeSingleLinePromptText(normalizeOptionalString$1(candidate.ownerName)),
|
|
84161
84526
|
sanitizeSingleLinePromptText(normalizeOptionalString$1(candidate.ownerUserId)),
|
|
84162
84527
|
sanitizeSingleLinePromptText(normalizeOptionalString$1(candidate.controllerRef)),
|
|
84528
|
+
...resolveSpaceMemberCandidateStatusBadges(candidate),
|
|
84163
84529
|
candidate.alreadyJoined ? "already in this space" : null,
|
|
84164
84530
|
candidate.needsActivation ? "needs mention setup" : null
|
|
84165
84531
|
].filter((value) => typeof value === "string").join("\n");
|
|
84166
84532
|
}
|
|
84533
|
+
function resolveSpaceMemberCandidateStatusLabel(candidate) {
|
|
84534
|
+
const statuses = resolveSpaceMemberCandidateStatusBadges(candidate);
|
|
84535
|
+
if (statuses.length === 0) return null;
|
|
84536
|
+
return statuses.join(" · ");
|
|
84537
|
+
}
|
|
84538
|
+
function resolveSpaceMemberCandidateStatusBadges(candidate) {
|
|
84539
|
+
if (candidate.profileKind !== "agent") return [];
|
|
84540
|
+
if (isSpaceMemberCandidateBackgroundReplyReady(candidate)) return ["Ready for background replies"];
|
|
84541
|
+
if (isSpaceMemberCandidateRepairableLocalParticipationCandidate(candidate)) return ["Needs repair"];
|
|
84542
|
+
if (candidate.controllerEnabled === true && typeof candidate.controllerRef === "string" && candidate.controllerRef.trim().length > 0) return ["Can join only"];
|
|
84543
|
+
return ["Not connected", "Can join only"];
|
|
84544
|
+
}
|
|
84545
|
+
function isSpaceMemberCandidateBackgroundReplyReady(candidate) {
|
|
84546
|
+
return candidate.profileKind === "agent" && candidate.controllerEnabled === true && typeof candidate.controllerRef === "string" && candidate.controllerRef.trim().length > 0 && candidate.localTargetSelectable === true && candidate.localParticipationReadiness === "ready";
|
|
84547
|
+
}
|
|
84167
84548
|
function normalizeRequestedMemberIds(value) {
|
|
84168
84549
|
if (!Array.isArray(value)) return [];
|
|
84169
84550
|
const ids = [];
|
|
@@ -87469,6 +87850,7 @@ async function runStart(input) {
|
|
|
87469
87850
|
});
|
|
87470
87851
|
const serviceStepResult = await runStartServiceStep({
|
|
87471
87852
|
foundation,
|
|
87853
|
+
gatewayUrl,
|
|
87472
87854
|
runtime,
|
|
87473
87855
|
presenter,
|
|
87474
87856
|
interactive,
|