agent-transport-system 0.3.1 → 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 +1230 -537
- package/dist/ats.js.map +1 -1
- package/package.json +2 -2
- package/skills/ats-cli/SKILL.md +8 -3
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-
|
|
31
|
+
atsReleaseDate: "2026-04-17",
|
|
32
32
|
description: "Agent Transport System CLI - https://ats.sh",
|
|
33
33
|
license: "MIT",
|
|
34
34
|
type: "module",
|
|
@@ -4319,7 +4319,7 @@ const daemonRouteObservationSummarySchema = strictObject({
|
|
|
4319
4319
|
});
|
|
4320
4320
|
|
|
4321
4321
|
//#endregion
|
|
4322
|
-
//#region ../../packages/schemas/dist/entry-brief-
|
|
4322
|
+
//#region ../../packages/schemas/dist/entry-brief-B2jV7t7E.js
|
|
4323
4323
|
const providerConversationExternalImportCapabilitySchema = _enum(["unsupported", "by_ref_id"]);
|
|
4324
4324
|
const providerConversationResumeCapabilitySchema = _enum(["unsupported", "by_ref_id"]);
|
|
4325
4325
|
const providerConversationDiscoverCapabilitySchema = literal("unsupported");
|
|
@@ -6576,6 +6576,7 @@ const REPLY_READINESS_REASON_CODE_VALUES = [
|
|
|
6576
6576
|
"runtime.adapter.unsupported",
|
|
6577
6577
|
"controller.bootstrap.failed",
|
|
6578
6578
|
"controller.gateway.unhealthy",
|
|
6579
|
+
"local_agents.none_needed",
|
|
6579
6580
|
"route.offline",
|
|
6580
6581
|
"route.not_registered"
|
|
6581
6582
|
];
|
|
@@ -11423,6 +11424,10 @@ function buildSkillsSharedNotes(context) {
|
|
|
11423
11424
|
//#endregion
|
|
11424
11425
|
//#region src/command-entry-checks/command-check-requirements.ts
|
|
11425
11426
|
const SKIP_ALL_CHECKS = {
|
|
11427
|
+
disclaimer: {
|
|
11428
|
+
mode: "skip",
|
|
11429
|
+
stage: "before-entry"
|
|
11430
|
+
},
|
|
11426
11431
|
cliUpdate: {
|
|
11427
11432
|
mode: "skip",
|
|
11428
11433
|
stage: "before-entry"
|
|
@@ -11452,6 +11457,10 @@ const OPTIONAL_CLI_UPDATE = { cliUpdate: {
|
|
|
11452
11457
|
mode: "optional",
|
|
11453
11458
|
stage: "before-entry"
|
|
11454
11459
|
} };
|
|
11460
|
+
const REQUIRED_DISCLAIMER = { disclaimer: {
|
|
11461
|
+
mode: "required",
|
|
11462
|
+
stage: "before-entry"
|
|
11463
|
+
} };
|
|
11455
11464
|
const AUTO_FIX_LOCAL_RUNTIME = { localRuntimeState: {
|
|
11456
11465
|
mode: "auto-fix",
|
|
11457
11466
|
stage: "before-entry"
|
|
@@ -11480,10 +11489,6 @@ const STATUS_ONLY_SELECTED_PROFILE = { selectedProfile: {
|
|
|
11480
11489
|
mode: "status-only",
|
|
11481
11490
|
stage: "status-only"
|
|
11482
11491
|
} };
|
|
11483
|
-
const OPTIONAL_SERVICE_AFTER_PROFILE = { service: {
|
|
11484
|
-
mode: "optional",
|
|
11485
|
-
stage: "after-profile"
|
|
11486
|
-
} };
|
|
11487
11492
|
const STATUS_ONLY_SERVICE = { service: {
|
|
11488
11493
|
mode: "status-only",
|
|
11489
11494
|
stage: "status-only"
|
|
@@ -11494,77 +11499,77 @@ function buildCommandChecks(...parts) {
|
|
|
11494
11499
|
const COMMAND_CHECK_REQUIREMENTS = Object.freeze({
|
|
11495
11500
|
root: buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11496
11501
|
view: buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11497
|
-
start: buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11498
|
-
"repair.local-state": buildCommandChecks(),
|
|
11499
|
-
uninstall: buildCommandChecks(),
|
|
11500
|
-
reset: buildCommandChecks(),
|
|
11501
|
-
upgrade: buildCommandChecks(),
|
|
11502
|
-
"auth.menu": buildCommandChecks(),
|
|
11503
|
-
"auth.status": buildCommandChecks(),
|
|
11504
|
-
"auth.login": buildCommandChecks(),
|
|
11505
|
-
"auth.logout": buildCommandChecks(),
|
|
11506
|
-
"skills.menu": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11507
|
-
"skills.install": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11508
|
-
"skills.uninstall": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11509
|
-
"skills.list": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11510
|
-
"skills.check": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11511
|
-
"skills.update": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11512
|
-
"agents.menu": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11513
|
-
"agents.detect": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11514
|
-
"agents.list": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11515
|
-
"agents.manage": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11516
|
-
"agents.enable": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11517
|
-
"agents.repair": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11518
|
-
"agents.disable": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11519
|
-
"agents.show": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11520
|
-
"agents.custom.list": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11521
|
-
"agents.custom.add": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11522
|
-
"agents.custom.update": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11523
|
-
"agents.custom.remove": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11524
|
-
"agents.config": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11525
|
-
"service.menu": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11526
|
-
"service.run": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11527
|
-
"service.status": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11528
|
-
"service.snapshot": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11529
|
-
"service.interrupt": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11530
|
-
"service.cancel": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11531
|
-
"service.trace": buildCommandChecks(OPTIONAL_CLI_UPDATE, REQUIRED_SIGN_IN, REQUIRED_SELECTED_PROFILE),
|
|
11532
|
-
"service.install": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11533
|
-
"service.uninstall": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11534
|
-
"service.reinstall": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11535
|
-
"service.stop": buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11536
|
-
"space.menu": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11537
|
-
"space.create": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE
|
|
11538
|
-
"space.delete": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11539
|
-
"space.conversation.bind": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11540
|
-
"space.conversation.clear": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11541
|
-
"space.conversation.status": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11542
|
-
"space.join": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE
|
|
11543
|
-
"space.add-members": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11544
|
-
"space.remove-members": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11545
|
-
"space.watch": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE
|
|
11546
|
-
"space.send": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11547
|
-
"space.history": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11548
|
-
"space.contract": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11549
|
-
"space.contract.set": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11550
|
-
"space.status": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11551
|
-
"space.updates": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11552
|
-
"space.result": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11553
|
-
"space.list": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11554
|
-
"space.password": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11555
|
-
"space.guide": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11556
|
-
"space.guide.set": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11557
|
-
"space.guide.clear": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11558
|
-
doctor: buildCommandChecks(OPTIONAL_CLI_UPDATE, OPTIONAL_SIGN_IN, STATUS_ONLY_SERVICE),
|
|
11559
|
-
whoami: buildCommandChecks(OPTIONAL_CLI_UPDATE),
|
|
11560
|
-
"profile.menu": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11561
|
-
"profile.create": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11562
|
-
"profile.list": buildCommandChecks(OPTIONAL_CLI_UPDATE, REQUIRED_SIGN_IN),
|
|
11563
|
-
"profile.ready": buildCommandChecks(OPTIONAL_CLI_UPDATE, STATUS_ONLY_SIGN_IN, STATUS_ONLY_SELECTED_PROFILE),
|
|
11564
|
-
"profile.set": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11565
|
-
"profile.show": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11566
|
-
"profile.update": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11567
|
-
"profile.delete": buildCommandChecks(OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN)
|
|
11502
|
+
start: buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11503
|
+
"repair.local-state": buildCommandChecks(REQUIRED_DISCLAIMER),
|
|
11504
|
+
uninstall: buildCommandChecks(REQUIRED_DISCLAIMER),
|
|
11505
|
+
reset: buildCommandChecks(REQUIRED_DISCLAIMER),
|
|
11506
|
+
upgrade: buildCommandChecks(REQUIRED_DISCLAIMER),
|
|
11507
|
+
"auth.menu": buildCommandChecks(REQUIRED_DISCLAIMER),
|
|
11508
|
+
"auth.status": buildCommandChecks(REQUIRED_DISCLAIMER),
|
|
11509
|
+
"auth.login": buildCommandChecks(REQUIRED_DISCLAIMER),
|
|
11510
|
+
"auth.logout": buildCommandChecks(REQUIRED_DISCLAIMER),
|
|
11511
|
+
"skills.menu": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11512
|
+
"skills.install": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11513
|
+
"skills.uninstall": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11514
|
+
"skills.list": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11515
|
+
"skills.check": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11516
|
+
"skills.update": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11517
|
+
"agents.menu": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11518
|
+
"agents.detect": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11519
|
+
"agents.list": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11520
|
+
"agents.manage": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11521
|
+
"agents.enable": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11522
|
+
"agents.repair": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11523
|
+
"agents.disable": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11524
|
+
"agents.show": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11525
|
+
"agents.custom.list": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11526
|
+
"agents.custom.add": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11527
|
+
"agents.custom.update": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11528
|
+
"agents.custom.remove": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11529
|
+
"agents.config": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11530
|
+
"service.menu": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11531
|
+
"service.run": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11532
|
+
"service.status": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11533
|
+
"service.snapshot": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11534
|
+
"service.interrupt": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11535
|
+
"service.cancel": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME),
|
|
11536
|
+
"service.trace": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, REQUIRED_SIGN_IN, REQUIRED_SELECTED_PROFILE),
|
|
11537
|
+
"service.install": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11538
|
+
"service.uninstall": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11539
|
+
"service.reinstall": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11540
|
+
"service.stop": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11541
|
+
"space.menu": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11542
|
+
"space.create": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11543
|
+
"space.delete": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11544
|
+
"space.conversation.bind": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11545
|
+
"space.conversation.clear": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11546
|
+
"space.conversation.status": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11547
|
+
"space.join": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11548
|
+
"space.add-members": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11549
|
+
"space.remove-members": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11550
|
+
"space.watch": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11551
|
+
"space.send": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11552
|
+
"space.history": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11553
|
+
"space.contract": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11554
|
+
"space.contract.set": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11555
|
+
"space.status": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11556
|
+
"space.updates": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11557
|
+
"space.result": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11558
|
+
"space.list": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11559
|
+
"space.password": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11560
|
+
"space.guide": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11561
|
+
"space.guide.set": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11562
|
+
"space.guide.clear": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN, CONFIRM_SELECTED_PROFILE),
|
|
11563
|
+
doctor: buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, OPTIONAL_SIGN_IN, STATUS_ONLY_SERVICE),
|
|
11564
|
+
whoami: buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE),
|
|
11565
|
+
"profile.menu": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11566
|
+
"profile.create": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11567
|
+
"profile.list": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, REQUIRED_SIGN_IN),
|
|
11568
|
+
"profile.ready": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, STATUS_ONLY_SIGN_IN, STATUS_ONLY_SELECTED_PROFILE),
|
|
11569
|
+
"profile.set": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11570
|
+
"profile.show": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11571
|
+
"profile.update": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN),
|
|
11572
|
+
"profile.delete": buildCommandChecks(REQUIRED_DISCLAIMER, OPTIONAL_CLI_UPDATE, AUTO_FIX_LOCAL_RUNTIME, REQUIRED_SIGN_IN)
|
|
11568
11573
|
});
|
|
11569
11574
|
function getCommandCheckRequirements(entryName) {
|
|
11570
11575
|
return COMMAND_CHECK_REQUIREMENTS[entryName];
|
|
@@ -14670,6 +14675,9 @@ async function getConfiguredDaemonDispatchLimits() {
|
|
|
14670
14675
|
async function getConfiguredOnboardingConfig() {
|
|
14671
14676
|
return (await readRuntimeConfig())?.onboarding ?? null;
|
|
14672
14677
|
}
|
|
14678
|
+
async function getConfiguredOnboardingDisclaimerAcceptedAt() {
|
|
14679
|
+
return (await getConfiguredOnboardingConfig())?.disclaimerAcceptedAt ?? null;
|
|
14680
|
+
}
|
|
14673
14681
|
async function getConfiguredStartV1OnboardingState() {
|
|
14674
14682
|
return (await getConfiguredOnboardingConfig())?.startV1 ?? null;
|
|
14675
14683
|
}
|
|
@@ -14734,10 +14742,23 @@ async function updateConfiguredDeviceRuntimeState(updater) {
|
|
|
14734
14742
|
async function updateConfiguredStartV1OnboardingState(updater) {
|
|
14735
14743
|
await withRuntimeConfigLock(async () => {
|
|
14736
14744
|
const previous = await readRuntimeConfig();
|
|
14737
|
-
const
|
|
14745
|
+
const previousOnboarding = previous?.onboarding ?? null;
|
|
14746
|
+
const previousStartV1 = previousOnboarding?.startV1 ?? null;
|
|
14738
14747
|
const nextStartV1 = updater(previousStartV1);
|
|
14739
14748
|
if (JSON.stringify(previousStartV1) === JSON.stringify(nextStartV1)) return;
|
|
14740
|
-
await writeRuntimeConfig(buildNextConfig(previous, { onboarding: nextStartV1 ? {
|
|
14749
|
+
await writeRuntimeConfig(buildNextConfig(previous, { onboarding: nextStartV1 || previousOnboarding?.disclaimerAcceptedAt ? {
|
|
14750
|
+
...previousOnboarding?.disclaimerAcceptedAt ? { disclaimerAcceptedAt: previousOnboarding.disclaimerAcceptedAt } : {},
|
|
14751
|
+
...nextStartV1 ? { startV1: nextStartV1 } : {}
|
|
14752
|
+
} : null }));
|
|
14753
|
+
});
|
|
14754
|
+
}
|
|
14755
|
+
async function updateConfiguredOnboardingConfig(updater) {
|
|
14756
|
+
await withRuntimeConfigLock(async () => {
|
|
14757
|
+
const previous = await readRuntimeConfig();
|
|
14758
|
+
const previousOnboarding = previous?.onboarding ?? null;
|
|
14759
|
+
const nextOnboarding = updater(previousOnboarding);
|
|
14760
|
+
if (JSON.stringify(previousOnboarding) === JSON.stringify(nextOnboarding)) return;
|
|
14761
|
+
await writeRuntimeConfig(buildNextConfig(previous, { onboarding: nextOnboarding }));
|
|
14741
14762
|
});
|
|
14742
14763
|
}
|
|
14743
14764
|
function buildNextConfig(previous, overrides) {
|
|
@@ -14867,9 +14888,14 @@ function parseRuntimeDeviceRuntimeStateObject(value) {
|
|
|
14867
14888
|
}
|
|
14868
14889
|
function parseRuntimeOnboardingConfig(value) {
|
|
14869
14890
|
if (!value || typeof value !== "object") return;
|
|
14870
|
-
const
|
|
14871
|
-
|
|
14872
|
-
|
|
14891
|
+
const obj = value;
|
|
14892
|
+
const disclaimerAcceptedAt = toTrimmedStringOrUndefined(obj.disclaimerAcceptedAt);
|
|
14893
|
+
const startV1 = parseRuntimeStartV1OnboardingState(obj.startV1);
|
|
14894
|
+
if (!(disclaimerAcceptedAt || startV1)) return;
|
|
14895
|
+
return {
|
|
14896
|
+
...disclaimerAcceptedAt ? { disclaimerAcceptedAt } : {},
|
|
14897
|
+
...startV1 ? { startV1 } : {}
|
|
14898
|
+
};
|
|
14873
14899
|
}
|
|
14874
14900
|
function parseRuntimeStartV1OnboardingState(value) {
|
|
14875
14901
|
if (!value || typeof value !== "object") return;
|
|
@@ -16611,8 +16637,77 @@ function createPresenter(context) {
|
|
|
16611
16637
|
|
|
16612
16638
|
//#endregion
|
|
16613
16639
|
//#region src/system/daemon-install-attention.ts
|
|
16640
|
+
const DAEMON_INSTALL_DECISION_CHOICE = {
|
|
16641
|
+
install: "install",
|
|
16642
|
+
notNow: "not_now"
|
|
16643
|
+
};
|
|
16614
16644
|
const DAEMON_INSTALL_COMMAND = "ats service install";
|
|
16615
16645
|
const DAEMON_UPGRADE_COMMAND = "ats upgrade";
|
|
16646
|
+
const DAEMON_DECISION_RECOMMENDED_HINT = "Recommended";
|
|
16647
|
+
const DAEMON_INSTALL_DECISION_COPY = {
|
|
16648
|
+
missing: {
|
|
16649
|
+
question: "ATS Service is missing. Install it now?",
|
|
16650
|
+
explanation: "Without it, local agents on this device can't reply from Space.",
|
|
16651
|
+
primaryLabel: "Yes, install it for me",
|
|
16652
|
+
deferred: "ATS Service is still missing. Local agents on this device can't reply from Space until you install it later with `ats service install`.",
|
|
16653
|
+
failed: "ATS Service could not be installed. Local agents on this device still can't reply from Space. Run `ats service install`."
|
|
16654
|
+
},
|
|
16655
|
+
outdated: {
|
|
16656
|
+
question: "ATS Service needs an update. Fix it now?",
|
|
16657
|
+
explanation: "Until ATS fixes it, local agents on this device may not be able to reply from Space.",
|
|
16658
|
+
primaryLabel: "Yes, fix it for me",
|
|
16659
|
+
deferred: "ATS Service still needs an update. Local agents on this device may not be able to reply from Space until ATS fixes it. Run `ats service install` later.",
|
|
16660
|
+
failed: "ATS Service was not updated. Local agents on this device may not be able to reply from Space. Run `ats service install`."
|
|
16661
|
+
}
|
|
16662
|
+
};
|
|
16663
|
+
function buildDaemonInstallDecisionPromptConfig(input) {
|
|
16664
|
+
const copy = DAEMON_INSTALL_DECISION_COPY[input.kind];
|
|
16665
|
+
const detailLine = input.kind === "outdated" && typeof input.installedVersion === "string" && typeof input.expectedVersion === "string" ? `Installed v${input.installedVersion}, expected v${input.expectedVersion}.` : null;
|
|
16666
|
+
return {
|
|
16667
|
+
message: [
|
|
16668
|
+
copy.question,
|
|
16669
|
+
copy.explanation,
|
|
16670
|
+
detailLine
|
|
16671
|
+
].filter((line) => typeof line === "string" && line.length > 0).join("\n"),
|
|
16672
|
+
initialValue: DAEMON_INSTALL_DECISION_CHOICE.install,
|
|
16673
|
+
options: [{
|
|
16674
|
+
value: DAEMON_INSTALL_DECISION_CHOICE.install,
|
|
16675
|
+
label: copy.primaryLabel,
|
|
16676
|
+
hint: DAEMON_DECISION_RECOMMENDED_HINT
|
|
16677
|
+
}, {
|
|
16678
|
+
value: DAEMON_INSTALL_DECISION_CHOICE.notNow,
|
|
16679
|
+
label: "Not now"
|
|
16680
|
+
}]
|
|
16681
|
+
};
|
|
16682
|
+
}
|
|
16683
|
+
async function promptForDaemonInstallDecision(input) {
|
|
16684
|
+
const choice = await select(buildDaemonInstallDecisionPromptConfig(input));
|
|
16685
|
+
if (isCancel(choice)) return "cancelled";
|
|
16686
|
+
return choice === DAEMON_INSTALL_DECISION_CHOICE.install ? DAEMON_INSTALL_DECISION_CHOICE.install : DAEMON_INSTALL_DECISION_CHOICE.notNow;
|
|
16687
|
+
}
|
|
16688
|
+
async function runDaemonInstallDecisionPrompt(input) {
|
|
16689
|
+
const decision = await promptForDaemonInstallDecision({
|
|
16690
|
+
kind: input.kind,
|
|
16691
|
+
installedVersion: input.installedVersion,
|
|
16692
|
+
expectedVersion: input.expectedVersion
|
|
16693
|
+
});
|
|
16694
|
+
if (decision === DAEMON_INSTALL_DECISION_CHOICE.install) try {
|
|
16695
|
+
await input.installService();
|
|
16696
|
+
return "install";
|
|
16697
|
+
} catch {
|
|
16698
|
+
await input.emitLine(formatDaemonInstallFailedMessage(input.kind));
|
|
16699
|
+
return "failed";
|
|
16700
|
+
}
|
|
16701
|
+
if (decision === "cancelled") return "cancelled";
|
|
16702
|
+
await input.emitLine(formatDaemonInstallDeferredMessage(input.kind));
|
|
16703
|
+
return decision;
|
|
16704
|
+
}
|
|
16705
|
+
function formatDaemonInstallDeferredMessage(kind) {
|
|
16706
|
+
return formatInlineAtsCliCommands(DAEMON_INSTALL_DECISION_COPY[kind].deferred);
|
|
16707
|
+
}
|
|
16708
|
+
function formatDaemonInstallFailedMessage(kind) {
|
|
16709
|
+
return formatInlineAtsCliCommands(DAEMON_INSTALL_DECISION_COPY[kind].failed);
|
|
16710
|
+
}
|
|
16616
16711
|
function formatDaemonServiceMissingRecommendation() {
|
|
16617
16712
|
return "ATS Service is not installed yet. Local agents on this device can't reply from Space until it is installed.";
|
|
16618
16713
|
}
|
|
@@ -19712,6 +19807,12 @@ function getStepOrderIndex$1(stepId) {
|
|
|
19712
19807
|
if (index === -1) throw new Error(`unknown start session step "${stepId}"`);
|
|
19713
19808
|
return index;
|
|
19714
19809
|
}
|
|
19810
|
+
function resolveServiceParticipationRequirement(input) {
|
|
19811
|
+
if (input.humanOnlyParticipation) return "not_needed";
|
|
19812
|
+
if (input.explicitSelectedLocalAgents) return input.selectedAgentProfilesHaveRunnableLocalSetup ? "offer_service_gate" : "agent_setup_needed";
|
|
19813
|
+
if (input.deviceLocalDemand === "keep_running") return "offer_service_gate";
|
|
19814
|
+
return "not_needed";
|
|
19815
|
+
}
|
|
19715
19816
|
function buildDaemonRouteObservationPresentation$1(observation) {
|
|
19716
19817
|
if (observation.status === "online") return {
|
|
19717
19818
|
detail: "ATS server can see an active daemon route for this profile.",
|
|
@@ -19774,6 +19875,7 @@ function formatStartReplyReadinessReason(reasonCode) {
|
|
|
19774
19875
|
case "runtime.adapter.unsupported": return "This agent setup can't reply from this device";
|
|
19775
19876
|
case "controller.bootstrap.failed": return "ATS couldn't finish setting up OpenClaw on this device";
|
|
19776
19877
|
case "controller.gateway.unhealthy": return "OpenClaw is not ready on this device yet";
|
|
19878
|
+
case "local_agents.none_needed": return "This device does not need ATS Service until you choose local agents to bring into a space";
|
|
19777
19879
|
case "route.offline": return "ATS server can't currently see an active daemon route for this profile";
|
|
19778
19880
|
case "route.not_registered": return "ATS is still setting up replies for this profile on this device";
|
|
19779
19881
|
default: return reasonCode ? "ATS can't confirm reply status yet" : null;
|
|
@@ -26911,6 +27013,7 @@ function emitStructuredReconcileEvidence(eventName, payload) {
|
|
|
26911
27013
|
|
|
26912
27014
|
//#endregion
|
|
26913
27015
|
//#region src/system/device-runtime-state-sync.ts
|
|
27016
|
+
const NO_LOCAL_AGENTS_NEED_ATS_SERVICE_REASON = "No local agents on this device need ATS Service right now";
|
|
26914
27017
|
async function syncDeviceRuntimeStateProjection(input) {
|
|
26915
27018
|
const mode = input?.mode ?? "check";
|
|
26916
27019
|
const currentControllers = await readCurrentControllers();
|
|
@@ -26950,7 +27053,7 @@ async function syncDeviceRuntimeStateProjection(input) {
|
|
|
26950
27053
|
disabledControllerIds: [],
|
|
26951
27054
|
repairRequiredControllerIds: [],
|
|
26952
27055
|
repairedControllerIds: [],
|
|
26953
|
-
reason:
|
|
27056
|
+
reason: NO_LOCAL_AGENTS_NEED_ATS_SERVICE_REASON
|
|
26954
27057
|
});
|
|
26955
27058
|
const gap = resolveProjectionGap({
|
|
26956
27059
|
currentControllers,
|
|
@@ -28039,7 +28142,7 @@ function normalizeOptionalString$14(value) {
|
|
|
28039
28142
|
}
|
|
28040
28143
|
function resolveZeroLocalValueReason(projection) {
|
|
28041
28144
|
if (!projection) return "no wakeable local agent routes are available";
|
|
28042
|
-
if (projection.status === "ok" && projection.projectedControllerIds.length === 0) return
|
|
28145
|
+
if (projection.status === "ok" && projection.projectedControllerIds.length === 0) return NO_LOCAL_AGENTS_NEED_ATS_SERVICE_REASON;
|
|
28043
28146
|
if (projection.status === "degraded") return "projected local controllers are not currently wakeable";
|
|
28044
28147
|
return "no wakeable local agent routes are available";
|
|
28045
28148
|
}
|
|
@@ -28117,7 +28220,28 @@ function resolveBootstrapCommandUnavailableSummary(message) {
|
|
|
28117
28220
|
|
|
28118
28221
|
//#endregion
|
|
28119
28222
|
//#region src/system/reply-readiness.ts
|
|
28120
|
-
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
|
+
];
|
|
28121
28245
|
const MANUAL_SPACE_PARTICIPATION_REASON = "You can still join the space and send messages yourself";
|
|
28122
28246
|
async function resolveDeviceReplyReadinessStatus(input = {}) {
|
|
28123
28247
|
const status = input.status ?? await getDaemonStatus();
|
|
@@ -28472,13 +28596,17 @@ function resolveDeviceReplyReadinessFromRuntimeProjection(runtimeProjection) {
|
|
|
28472
28596
|
return null;
|
|
28473
28597
|
}
|
|
28474
28598
|
function createRouteNotRegisteredReplyReadinessStatus(input) {
|
|
28599
|
+
const projectionWithoutLocalDemand = input.localDemand?.projection ?? input.runtimeProjection;
|
|
28475
28600
|
return createDeviceReplyReadinessStatus({
|
|
28476
|
-
reasonCode: "route.not_registered",
|
|
28477
|
-
reasonText:
|
|
28478
|
-
replyReadiness: input.runtimeProjection?.status === "skipped" ? "unknown" : "blocked",
|
|
28601
|
+
reasonCode: input.runtimeProjection?.status === "skipped" || hasNoProjectedLocalControllers(projectionWithoutLocalDemand) ? "local_agents.none_needed" : "route.not_registered",
|
|
28602
|
+
reasonText: normalizeOptionalText$17(input.localDemand?.reason ?? input.runtimeProjection?.reason) ?? "ATS is still setting up replies on this device",
|
|
28603
|
+
replyReadiness: input.runtimeProjection?.status === "skipped" || hasNoProjectedLocalControllers(projectionWithoutLocalDemand) ? "unknown" : "blocked",
|
|
28479
28604
|
wakeableRouteCount: 0
|
|
28480
28605
|
});
|
|
28481
28606
|
}
|
|
28607
|
+
function hasNoProjectedLocalControllers(projection) {
|
|
28608
|
+
return projection?.status === "ok" && projection.projectedControllerIds.length === 0;
|
|
28609
|
+
}
|
|
28482
28610
|
function createDeviceReplyReadinessStatus(input) {
|
|
28483
28611
|
return {
|
|
28484
28612
|
reasonCodes: sortReplyReadinessReasonCodes(input.reasonCode ? [input.reasonCode] : []),
|
|
@@ -28531,6 +28659,7 @@ function describeReplyReadinessReason(reasonCode) {
|
|
|
28531
28659
|
case "runtime.adapter.unsupported": return "the local agent controller setup is not supported";
|
|
28532
28660
|
case "controller.bootstrap.failed": return "ATS couldn't finish setting up the local OpenClaw agent for this profile";
|
|
28533
28661
|
case "controller.gateway.unhealthy": return "the local OpenClaw Gateway is not healthy on this device";
|
|
28662
|
+
case "local_agents.none_needed": return "no local agents on this device need ATS Service right now";
|
|
28534
28663
|
case "route.offline": return "ATS server can't currently see an active daemon route for this profile";
|
|
28535
28664
|
case "route.not_registered": return "ATS is still setting up replies for this profile on this device";
|
|
28536
28665
|
default: return "ATS can't confirm local reply readiness yet";
|
|
@@ -30889,7 +31018,7 @@ const COMMAND_ENTRY_COPY_BY_NAME = Object.freeze({
|
|
|
30889
31018
|
signInAction: "creating a space",
|
|
30890
31019
|
profileAction: "creating a space",
|
|
30891
31020
|
cliUpdateAction: "creating a space",
|
|
30892
|
-
serviceAction:
|
|
31021
|
+
serviceAction: null
|
|
30893
31022
|
},
|
|
30894
31023
|
"space.delete": {
|
|
30895
31024
|
signInAction: "deleting a space",
|
|
@@ -30919,7 +31048,7 @@ const COMMAND_ENTRY_COPY_BY_NAME = Object.freeze({
|
|
|
30919
31048
|
signInAction: "joining a space",
|
|
30920
31049
|
profileAction: "joining a space",
|
|
30921
31050
|
cliUpdateAction: "joining a space",
|
|
30922
|
-
serviceAction:
|
|
31051
|
+
serviceAction: null
|
|
30923
31052
|
},
|
|
30924
31053
|
"space.add-members": {
|
|
30925
31054
|
signInAction: "adding members to a space",
|
|
@@ -30937,7 +31066,7 @@ const COMMAND_ENTRY_COPY_BY_NAME = Object.freeze({
|
|
|
30937
31066
|
signInAction: "watching a space",
|
|
30938
31067
|
profileAction: "watching a space",
|
|
30939
31068
|
cliUpdateAction: "watching a space",
|
|
30940
|
-
serviceAction:
|
|
31069
|
+
serviceAction: null
|
|
30941
31070
|
},
|
|
30942
31071
|
"space.send": {
|
|
30943
31072
|
signInAction: "sending a message",
|
|
@@ -31346,6 +31475,82 @@ async function runCliUpdateCheck(input) {
|
|
|
31346
31475
|
};
|
|
31347
31476
|
}
|
|
31348
31477
|
|
|
31478
|
+
//#endregion
|
|
31479
|
+
//#region src/onboarding/disclaimer.ts
|
|
31480
|
+
const ATS_ACCEPT_DISCLAIMER_ENV = "ATS_ACCEPT_DISCLAIMER";
|
|
31481
|
+
const ATS_ONBOARDING_DISCLAIMER_ACCEPT = "__onboarding_disclaimer_accept__";
|
|
31482
|
+
const ATS_ONBOARDING_DISCLAIMER_DECLINE = "__onboarding_disclaimer_decline__";
|
|
31483
|
+
const ATS_ONBOARDING_DISCLAIMER_TEXT = "ATSD is experimental and changes rapidly. Breaking changes may occur. You are fully responsible for data security and sensitive information handling. Use ATSD only in trusted environments.";
|
|
31484
|
+
async function runOnboardingDisclaimerGate(input) {
|
|
31485
|
+
if (await getConfiguredOnboardingDisclaimerAcceptedAt().catch(() => null)) return true;
|
|
31486
|
+
if (shouldBypassDisclaimerWithEnv()) {
|
|
31487
|
+
await persistOnboardingDisclaimerAccepted();
|
|
31488
|
+
return true;
|
|
31489
|
+
}
|
|
31490
|
+
if (input.runtime.resolvedView === "agent") {
|
|
31491
|
+
input.presenter.data({
|
|
31492
|
+
code: input.codePrefix,
|
|
31493
|
+
payload: {
|
|
31494
|
+
acceptedAt: null,
|
|
31495
|
+
text: ATS_ONBOARDING_DISCLAIMER_TEXT,
|
|
31496
|
+
mode: "agent_notice",
|
|
31497
|
+
requiresConfirmation: false
|
|
31498
|
+
}
|
|
31499
|
+
});
|
|
31500
|
+
await persistOnboardingDisclaimerAccepted();
|
|
31501
|
+
return true;
|
|
31502
|
+
}
|
|
31503
|
+
note(`⚠️ ${ATS_ONBOARDING_DISCLAIMER_TEXT}`, "Disclaimer");
|
|
31504
|
+
if (!input.interactive) {
|
|
31505
|
+
input.presenter.line({
|
|
31506
|
+
code: `${input.codePrefix}.auto_continue`,
|
|
31507
|
+
text: "Non-interactive session: disclaimer displayed and ATS continues."
|
|
31508
|
+
});
|
|
31509
|
+
await persistOnboardingDisclaimerAccepted();
|
|
31510
|
+
return true;
|
|
31511
|
+
}
|
|
31512
|
+
const decision = await select({
|
|
31513
|
+
message: "Do you accept and continue?",
|
|
31514
|
+
options: [{
|
|
31515
|
+
value: ATS_ONBOARDING_DISCLAIMER_ACCEPT,
|
|
31516
|
+
label: "Yes, continue"
|
|
31517
|
+
}, {
|
|
31518
|
+
value: ATS_ONBOARDING_DISCLAIMER_DECLINE,
|
|
31519
|
+
label: "No, exit"
|
|
31520
|
+
}],
|
|
31521
|
+
initialValue: ATS_ONBOARDING_DISCLAIMER_ACCEPT
|
|
31522
|
+
});
|
|
31523
|
+
if (isCancel(decision) || decision === ATS_ONBOARDING_DISCLAIMER_DECLINE) {
|
|
31524
|
+
cancel("Cancelled.");
|
|
31525
|
+
return false;
|
|
31526
|
+
}
|
|
31527
|
+
await persistOnboardingDisclaimerAccepted();
|
|
31528
|
+
return true;
|
|
31529
|
+
}
|
|
31530
|
+
function shouldBypassDisclaimerWithEnv() {
|
|
31531
|
+
return String(process.env[ATS_ACCEPT_DISCLAIMER_ENV] ?? "").trim() === "1";
|
|
31532
|
+
}
|
|
31533
|
+
async function persistOnboardingDisclaimerAccepted() {
|
|
31534
|
+
const acceptedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
31535
|
+
await updateConfiguredOnboardingConfig((current) => ({
|
|
31536
|
+
...current ?? {},
|
|
31537
|
+
disclaimerAcceptedAt: acceptedAt
|
|
31538
|
+
}));
|
|
31539
|
+
}
|
|
31540
|
+
|
|
31541
|
+
//#endregion
|
|
31542
|
+
//#region src/command-entry-checks/check-disclaimer.ts
|
|
31543
|
+
async function runDisclaimerCheck(input) {
|
|
31544
|
+
if (input.requirement.mode === "skip") return { status: "continue" };
|
|
31545
|
+
if (await runOnboardingDisclaimerGate({
|
|
31546
|
+
runtime: input.context.runtime,
|
|
31547
|
+
presenter: input.context.presenter,
|
|
31548
|
+
interactive: input.context.allowPrompt,
|
|
31549
|
+
codePrefix: "command.entry.disclaimer"
|
|
31550
|
+
})) return { status: "continue" };
|
|
31551
|
+
return { status: "cancelled" };
|
|
31552
|
+
}
|
|
31553
|
+
|
|
31349
31554
|
//#endregion
|
|
31350
31555
|
//#region src/config/storage-version.ts
|
|
31351
31556
|
const STORAGE_VERSION_SCHEMA = "ats-local-state-v1";
|
|
@@ -46783,7 +46988,7 @@ function resolveServiceParticipationReadiness(input) {
|
|
|
46783
46988
|
};
|
|
46784
46989
|
}
|
|
46785
46990
|
if (reasonCodes.includes("service.not_installed")) {
|
|
46786
|
-
const nextSteps = formatAtsCliCommands(["ats service install", "ats service run
|
|
46991
|
+
const nextSteps = formatAtsCliCommands(["ats service install", "ats service run"]);
|
|
46787
46992
|
return {
|
|
46788
46993
|
serviceReadiness: "not_installed",
|
|
46789
46994
|
summaryText: "Not installed",
|
|
@@ -46794,7 +46999,7 @@ function resolveServiceParticipationReadiness(input) {
|
|
|
46794
46999
|
};
|
|
46795
47000
|
}
|
|
46796
47001
|
if (reasonCodes.includes("service.not_running")) {
|
|
46797
|
-
const nextSteps = [formatAtsCliCommand("ats service run
|
|
47002
|
+
const nextSteps = [formatAtsCliCommand("ats service run")];
|
|
46798
47003
|
return {
|
|
46799
47004
|
serviceReadiness: "not_running",
|
|
46800
47005
|
summaryText: "Not running",
|
|
@@ -46812,6 +47017,21 @@ function resolveServiceParticipationReadiness(input) {
|
|
|
46812
47017
|
nextSteps: [],
|
|
46813
47018
|
runtimeHeadline
|
|
46814
47019
|
};
|
|
47020
|
+
if (reasonCodes.includes("local_agents.none_needed")) {
|
|
47021
|
+
const nextSteps = formatAtsCliCommands([
|
|
47022
|
+
"ats start",
|
|
47023
|
+
"ats service install",
|
|
47024
|
+
"ats service run"
|
|
47025
|
+
]);
|
|
47026
|
+
return {
|
|
47027
|
+
serviceReadiness: "unknown",
|
|
47028
|
+
summaryText: "Not needed yet",
|
|
47029
|
+
detailText: input.deviceReplyReadiness.reasonText,
|
|
47030
|
+
nextStepSummary: "If you later choose local agents to bring into a space, rerun `ats start` or enable ATS Service directly.",
|
|
47031
|
+
nextSteps,
|
|
47032
|
+
runtimeHeadline
|
|
47033
|
+
};
|
|
47034
|
+
}
|
|
46815
47035
|
const nextSteps = [formatAtsCliCommand("ats service status")];
|
|
46816
47036
|
return {
|
|
46817
47037
|
serviceReadiness: "unknown",
|
|
@@ -47268,7 +47488,10 @@ async function runDaemon(input) {
|
|
|
47268
47488
|
return;
|
|
47269
47489
|
}
|
|
47270
47490
|
if (canUseInteractivePrompts(runtime)) {
|
|
47271
|
-
await runInteractiveDaemonMenu({
|
|
47491
|
+
await runInteractiveDaemonMenu({
|
|
47492
|
+
gatewayUrl: input.gatewayUrl,
|
|
47493
|
+
view: runtime.resolvedView
|
|
47494
|
+
});
|
|
47272
47495
|
return;
|
|
47273
47496
|
}
|
|
47274
47497
|
presenter.line({
|
|
@@ -48494,6 +48717,7 @@ async function runDaemonStatusFlow(input, options = {}) {
|
|
|
48494
48717
|
await runDaemonStatus(input);
|
|
48495
48718
|
if (!(options.offerStartPrompt && interactiveHuman)) return "completed";
|
|
48496
48719
|
return await maybeOfferDaemonStartAfterStatus({
|
|
48720
|
+
gatewayUrl: input.gatewayUrl,
|
|
48497
48721
|
view: "human",
|
|
48498
48722
|
ownerUserId
|
|
48499
48723
|
});
|
|
@@ -49656,6 +49880,7 @@ async function runDaemonBackgroundStartForDecision(input) {
|
|
|
49656
49880
|
const previousExitCode = process.exitCode;
|
|
49657
49881
|
const result = await runDaemonRun({
|
|
49658
49882
|
agentOverviewHandled: true,
|
|
49883
|
+
gatewayUrl: input.gatewayUrl,
|
|
49659
49884
|
mode: "background",
|
|
49660
49885
|
view: input.view
|
|
49661
49886
|
});
|
|
@@ -50738,7 +50963,10 @@ async function handleInteractiveDaemonMenuChoice(input, choice) {
|
|
|
50738
50963
|
}
|
|
50739
50964
|
if (choice === DAEMON_MENU_CHOICE.reinstall) {
|
|
50740
50965
|
const result = await runDaemonReinstall(input, { suppressInstallOutput: true });
|
|
50741
|
-
if (isDaemonReinstallCompletedAndStopped(result)) return await maybeOfferDaemonStartAfterStatus({
|
|
50966
|
+
if (isDaemonReinstallCompletedAndStopped(result)) return await maybeOfferDaemonStartAfterStatus({
|
|
50967
|
+
gatewayUrl: input.gatewayUrl,
|
|
50968
|
+
view: input.view
|
|
50969
|
+
}) === "cancelled";
|
|
50742
50970
|
return result.result === "cancelled";
|
|
50743
50971
|
}
|
|
50744
50972
|
return await runDaemonUninstall(input) === "cancelled";
|
|
@@ -50749,7 +50977,10 @@ async function maybeOfferDaemonStartAfterStatus(input) {
|
|
|
50749
50977
|
localDemand: input.localDemand
|
|
50750
50978
|
})).offerStartPrompt) return "completed";
|
|
50751
50979
|
const presenter = createPresenter(await resolveRuntimeContext({ view: input.view }));
|
|
50752
|
-
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
|
+
}) });
|
|
50753
50984
|
if (decision === "cancelled") return "cancelled";
|
|
50754
50985
|
if (decision === "deferred_with_card") return "completed";
|
|
50755
50986
|
if (decision === "not_now") {
|
|
@@ -50851,7 +51082,7 @@ function mapLocalControllerStatusReason(reason) {
|
|
|
50851
51082
|
const projectedControllersDisabledReason = "one or more projected controllers are disabled locally";
|
|
50852
51083
|
if (reason.includes("already exists")) return "setup is already prepared";
|
|
50853
51084
|
if (reason.includes("authentication is not valid")) return "sign in required";
|
|
50854
|
-
if (reason.includes(
|
|
51085
|
+
if (reason.includes(NO_LOCAL_AGENTS_NEED_ATS_SERVICE_REASON)) return "no local agent is configured for this device";
|
|
50855
51086
|
if (reason.includes(missingOrDisabledReason)) return "some local agents are missing or turned off";
|
|
50856
51087
|
if (reason.includes("is missing for one or more bound controllers")) return "some local agents are missing";
|
|
50857
51088
|
if (reason.includes(projectedControllersDisabledReason)) return "some local agent entries are disabled";
|
|
@@ -51057,6 +51288,183 @@ async function ensureDaemonVersionForCliStartup(input) {
|
|
|
51057
51288
|
};
|
|
51058
51289
|
}
|
|
51059
51290
|
|
|
51291
|
+
//#endregion
|
|
51292
|
+
//#region src/system/daemon-service-participation-gate.ts
|
|
51293
|
+
function shouldRequireDaemonServiceParticipation(localDemand) {
|
|
51294
|
+
return localDemand?.decision === "keep_running";
|
|
51295
|
+
}
|
|
51296
|
+
async function resolveDaemonServiceParticipationStatus(input) {
|
|
51297
|
+
const expectedVersion = input?.expectedVersion ?? resolveCurrentDaemonExpectedVersion();
|
|
51298
|
+
const inventory = await inspectDaemonServiceInventory({ expectedVersion });
|
|
51299
|
+
if (!(inventory.installStatus.installed && inventory.installStatus.state)) return {
|
|
51300
|
+
kind: "missing",
|
|
51301
|
+
expectedVersion
|
|
51302
|
+
};
|
|
51303
|
+
const installedVersion = inventory.installStatus.state.daemonVersion;
|
|
51304
|
+
if (installedVersion !== expectedVersion) return {
|
|
51305
|
+
kind: "outdated",
|
|
51306
|
+
expectedVersion,
|
|
51307
|
+
installedVersion
|
|
51308
|
+
};
|
|
51309
|
+
const repairAnomalies = inventory.anomalies.filter((anomaly) => DAEMON_SERVICE_REPAIR_ANOMALIES.has(anomaly.code));
|
|
51310
|
+
if (repairAnomalies.length > 0) return {
|
|
51311
|
+
kind: "needs_repair",
|
|
51312
|
+
expectedVersion,
|
|
51313
|
+
installedVersion,
|
|
51314
|
+
runtimeStatus: inventory.runtimeStatus.status,
|
|
51315
|
+
detail: repairAnomalies[0]?.message ?? "ATS found conflicting local service state on this device.",
|
|
51316
|
+
anomalyCodes: repairAnomalies.map((anomaly) => anomaly.code)
|
|
51317
|
+
};
|
|
51318
|
+
if (inventory.runtimeStatus.status !== "running") return {
|
|
51319
|
+
kind: "not_running",
|
|
51320
|
+
expectedVersion,
|
|
51321
|
+
installedVersion,
|
|
51322
|
+
runtimeStatus: inventory.runtimeStatus.status
|
|
51323
|
+
};
|
|
51324
|
+
return {
|
|
51325
|
+
kind: "ready",
|
|
51326
|
+
expectedVersion,
|
|
51327
|
+
installedVersion,
|
|
51328
|
+
runtimeStatus: inventory.runtimeStatus.status
|
|
51329
|
+
};
|
|
51330
|
+
}
|
|
51331
|
+
async function runDaemonServiceParticipationGate(input) {
|
|
51332
|
+
if (!shouldRunDaemonServiceParticipationGate(input)) return { status: "aligned" };
|
|
51333
|
+
const initialStatus = await resolveDaemonServiceParticipationStatus();
|
|
51334
|
+
if (initialStatus.kind === "ready") return { status: "aligned" };
|
|
51335
|
+
const codePrefix = resolveDaemonServiceParticipationCodePrefix(input.intent);
|
|
51336
|
+
const installStageResult = await runDaemonServiceParticipationInstallStage({
|
|
51337
|
+
input,
|
|
51338
|
+
codePrefix,
|
|
51339
|
+
status: initialStatus
|
|
51340
|
+
});
|
|
51341
|
+
if (installStageResult.result) return installStageResult.result;
|
|
51342
|
+
return await runDaemonServiceParticipationActionStage({
|
|
51343
|
+
input,
|
|
51344
|
+
codePrefix,
|
|
51345
|
+
status: installStageResult.status
|
|
51346
|
+
});
|
|
51347
|
+
}
|
|
51348
|
+
function shouldRunDaemonServiceParticipationGate(input) {
|
|
51349
|
+
return input.resolvedView === "human" && input.allowPrompt && (input.forcePrompt === true || shouldRequireDaemonServiceParticipation(input.localDemand));
|
|
51350
|
+
}
|
|
51351
|
+
async function runDaemonServiceParticipationInstallStage(input) {
|
|
51352
|
+
if (input.status.kind !== "missing" && input.status.kind !== "outdated") return { status: input.status };
|
|
51353
|
+
const installResult = await runDaemonInstallDecisionPrompt({
|
|
51354
|
+
kind: input.status.kind,
|
|
51355
|
+
...input.status.kind === "outdated" ? { installedVersion: input.status.installedVersion } : {},
|
|
51356
|
+
expectedVersion: input.status.expectedVersion,
|
|
51357
|
+
emitLine: (text) => {
|
|
51358
|
+
input.input.presenter.line({
|
|
51359
|
+
code: `${input.codePrefix}.install`,
|
|
51360
|
+
text
|
|
51361
|
+
});
|
|
51362
|
+
},
|
|
51363
|
+
installService: async () => {
|
|
51364
|
+
await runDaemonInstall({ view: input.input.view }, { suppressHumanOutput: shouldSuppressHumanInstallOutput(input.input.intent) });
|
|
51365
|
+
}
|
|
51366
|
+
});
|
|
51367
|
+
if (installResult === "cancelled") return {
|
|
51368
|
+
status: input.status,
|
|
51369
|
+
result: { status: "cancelled" }
|
|
51370
|
+
};
|
|
51371
|
+
if (installResult === "failed") return {
|
|
51372
|
+
status: input.status,
|
|
51373
|
+
result: { status: "needs_attention" }
|
|
51374
|
+
};
|
|
51375
|
+
if (installResult === "not_now" || !shouldStartAfterDaemonInstall(input.input.intent)) return {
|
|
51376
|
+
status: input.status,
|
|
51377
|
+
result: { status: "declined" }
|
|
51378
|
+
};
|
|
51379
|
+
const refreshedStatus = await resolveDaemonServiceParticipationStatus();
|
|
51380
|
+
if (refreshedStatus.kind === "ready") return {
|
|
51381
|
+
status: refreshedStatus,
|
|
51382
|
+
result: { status: "aligned" }
|
|
51383
|
+
};
|
|
51384
|
+
if (refreshedStatus.kind === "missing" || refreshedStatus.kind === "outdated") {
|
|
51385
|
+
renderDaemonStartNeedsAttention({
|
|
51386
|
+
presenter: input.input.presenter,
|
|
51387
|
+
codePrefix: input.codePrefix,
|
|
51388
|
+
summary: refreshedStatus.kind === "missing" ? formatDaemonInstallFailedMessage("missing") : formatDaemonInstallFailedMessage("outdated")
|
|
51389
|
+
});
|
|
51390
|
+
return {
|
|
51391
|
+
status: refreshedStatus,
|
|
51392
|
+
result: { status: "needs_attention" }
|
|
51393
|
+
};
|
|
51394
|
+
}
|
|
51395
|
+
return { status: refreshedStatus };
|
|
51396
|
+
}
|
|
51397
|
+
async function runDaemonServiceParticipationActionStage(input) {
|
|
51398
|
+
if (input.status.kind === "needs_repair") return mapDaemonBackgroundStartResult(await runDaemonBackgroundStartForDecision({
|
|
51399
|
+
gatewayUrl: input.input.gatewayUrl,
|
|
51400
|
+
view: input.input.view
|
|
51401
|
+
}), {
|
|
51402
|
+
presenter: input.input.presenter,
|
|
51403
|
+
codePrefix: input.codePrefix
|
|
51404
|
+
});
|
|
51405
|
+
if (input.status.kind !== "not_running") return { status: "aligned" };
|
|
51406
|
+
return mapDaemonBackgroundStartResult(await runDaemonStartDecisionPrompt({ startService: async () => await runDaemonBackgroundStartForDecision({
|
|
51407
|
+
gatewayUrl: input.input.gatewayUrl,
|
|
51408
|
+
view: input.input.view
|
|
51409
|
+
}) }), {
|
|
51410
|
+
presenter: input.input.presenter,
|
|
51411
|
+
codePrefix: input.codePrefix
|
|
51412
|
+
});
|
|
51413
|
+
}
|
|
51414
|
+
function resolveDaemonServiceParticipationCodePrefix(intent) {
|
|
51415
|
+
switch (intent) {
|
|
51416
|
+
case "start": return "start.service";
|
|
51417
|
+
case "space_create_join": return "space.create_join.service";
|
|
51418
|
+
case "space_join": return "space.join.service";
|
|
51419
|
+
case "space_add_members": return "space.add_members.service";
|
|
51420
|
+
default: throw new Error(`Unknown daemon service participation intent: ${intent}`);
|
|
51421
|
+
}
|
|
51422
|
+
}
|
|
51423
|
+
function shouldStartAfterDaemonInstall(_intent) {
|
|
51424
|
+
return true;
|
|
51425
|
+
}
|
|
51426
|
+
function shouldSuppressHumanInstallOutput(intent) {
|
|
51427
|
+
return intent !== "start";
|
|
51428
|
+
}
|
|
51429
|
+
function mapDaemonBackgroundStartResult(result, input) {
|
|
51430
|
+
if (result === "started" || result === "deferred_with_card") return { status: "aligned" };
|
|
51431
|
+
if (result === "cancelled") return { status: "cancelled" };
|
|
51432
|
+
if (result === "not_now") {
|
|
51433
|
+
renderDaemonStartDeferred({
|
|
51434
|
+
presenter: input.presenter,
|
|
51435
|
+
codePrefix: input.codePrefix
|
|
51436
|
+
});
|
|
51437
|
+
return { status: "declined" };
|
|
51438
|
+
}
|
|
51439
|
+
if (result === "failed") {
|
|
51440
|
+
renderDaemonStartNeedsAttention({
|
|
51441
|
+
presenter: input.presenter,
|
|
51442
|
+
codePrefix: input.codePrefix,
|
|
51443
|
+
summary: "ATS could not finish starting ATS Service."
|
|
51444
|
+
});
|
|
51445
|
+
return { status: "needs_attention" };
|
|
51446
|
+
}
|
|
51447
|
+
return { status: "needs_attention" };
|
|
51448
|
+
}
|
|
51449
|
+
function renderDaemonStartDeferred(input) {
|
|
51450
|
+
const card = buildDaemonStartDeferredCard();
|
|
51451
|
+
renderInfoCard({
|
|
51452
|
+
presenter: input.presenter,
|
|
51453
|
+
title: card.title,
|
|
51454
|
+
codePrefix: `${input.codePrefix}.deferred`,
|
|
51455
|
+
rows: card.rows
|
|
51456
|
+
});
|
|
51457
|
+
}
|
|
51458
|
+
function renderDaemonStartNeedsAttention(input) {
|
|
51459
|
+
const card = buildDaemonStartNeedsAttentionCard({ summary: input.summary });
|
|
51460
|
+
renderInfoCard({
|
|
51461
|
+
presenter: input.presenter,
|
|
51462
|
+
title: card.title,
|
|
51463
|
+
codePrefix: `${input.codePrefix}.failed`,
|
|
51464
|
+
rows: card.rows
|
|
51465
|
+
});
|
|
51466
|
+
}
|
|
51467
|
+
|
|
51060
51468
|
//#endregion
|
|
51061
51469
|
//#region src/command-entry-checks/check-service.ts
|
|
51062
51470
|
const FIX_SERVICE = "__command_entry_fix_service__";
|
|
@@ -51069,10 +51477,9 @@ async function runServiceCheck(input) {
|
|
|
51069
51477
|
shouldAutoRepair: input.requirement.mode !== "status-only",
|
|
51070
51478
|
view: input.context.runtime.resolvedView
|
|
51071
51479
|
});
|
|
51072
|
-
const shouldSuppressStandaloneHumanServiceCard = shouldDeferHumanServiceCardToJoinQuickCheck(input.context);
|
|
51073
51480
|
if (serviceStatus.kind === "ready") return { status: "continue" };
|
|
51074
51481
|
if (input.requirement.mode === "status-only") {
|
|
51075
|
-
|
|
51482
|
+
emitServiceStatus({
|
|
51076
51483
|
context: input.context,
|
|
51077
51484
|
serviceStatus,
|
|
51078
51485
|
blocking: false
|
|
@@ -51080,22 +51487,21 @@ async function runServiceCheck(input) {
|
|
|
51080
51487
|
return { status: "continue" };
|
|
51081
51488
|
}
|
|
51082
51489
|
if (input.context.runtime.resolvedView !== "human" || !input.context.allowPrompt) {
|
|
51083
|
-
|
|
51490
|
+
emitServiceStatus({
|
|
51084
51491
|
context: input.context,
|
|
51085
51492
|
serviceStatus,
|
|
51086
51493
|
blocking: false
|
|
51087
51494
|
});
|
|
51088
51495
|
return { status: "continue" };
|
|
51089
51496
|
}
|
|
51090
|
-
if (serviceStatus.kind === "repair_blocked" || serviceStatus.kind === "repair_failed") {
|
|
51091
|
-
|
|
51497
|
+
if (serviceStatus.kind === "needs_repair" || serviceStatus.kind === "repair_blocked" || serviceStatus.kind === "repair_failed") {
|
|
51498
|
+
emitServiceStatus({
|
|
51092
51499
|
context: input.context,
|
|
51093
51500
|
serviceStatus,
|
|
51094
51501
|
blocking: false
|
|
51095
51502
|
});
|
|
51096
51503
|
return { status: "continue" };
|
|
51097
51504
|
}
|
|
51098
|
-
if (shouldSuppressStandaloneHumanServiceCard) return { status: "continue" };
|
|
51099
51505
|
const copy = getCommandEntryCopy(input.context.entryName);
|
|
51100
51506
|
showHumanCheckCard({
|
|
51101
51507
|
presenter: input.context.presenter,
|
|
@@ -51127,15 +51533,27 @@ async function runServiceCheck(input) {
|
|
|
51127
51533
|
return { status: "cancelled" };
|
|
51128
51534
|
}
|
|
51129
51535
|
if (selected === CONTINUE_WITHOUT_SERVICE) return { status: "continue" };
|
|
51130
|
-
if (!await fixServiceStatus(
|
|
51536
|
+
if (!await fixServiceStatus({
|
|
51537
|
+
gatewayUrl: input.context.gatewayUrl,
|
|
51538
|
+
serviceStatus
|
|
51539
|
+
})) return { status: "continue" };
|
|
51131
51540
|
return { status: "continue" };
|
|
51132
51541
|
}
|
|
51133
|
-
function shouldDeferHumanServiceCardToJoinQuickCheck(context) {
|
|
51134
|
-
return context.entryName === "space.join" && context.runtime.resolvedView === "human";
|
|
51135
|
-
}
|
|
51136
51542
|
async function resolveServiceStatus(input) {
|
|
51137
51543
|
const expectedVersion = resolveCurrentDaemonExpectedVersion();
|
|
51138
|
-
const currentStatus = await
|
|
51544
|
+
const currentStatus = await resolveDaemonServiceParticipationStatus({ expectedVersion }).catch((error) => {
|
|
51545
|
+
warnServiceCheckIssue("resolveDaemonServiceParticipationStatus failed", {
|
|
51546
|
+
error,
|
|
51547
|
+
expectedVersion,
|
|
51548
|
+
view: input.view
|
|
51549
|
+
});
|
|
51550
|
+
return {
|
|
51551
|
+
kind: "not_running",
|
|
51552
|
+
expectedVersion,
|
|
51553
|
+
installedVersion: null,
|
|
51554
|
+
runtimeStatus: null
|
|
51555
|
+
};
|
|
51556
|
+
});
|
|
51139
51557
|
if (currentStatus.kind === "ready") return currentStatus;
|
|
51140
51558
|
if (input.shouldAutoRepair) {
|
|
51141
51559
|
const preflight = await runDaemonStartupPreflight({
|
|
@@ -51158,38 +51576,30 @@ async function resolveServiceStatus(input) {
|
|
|
51158
51576
|
detail: buildStartupPreflightAttentionDetail(preflight)
|
|
51159
51577
|
};
|
|
51160
51578
|
}
|
|
51161
|
-
return await
|
|
51162
|
-
|
|
51163
|
-
|
|
51164
|
-
|
|
51165
|
-
|
|
51166
|
-
if (daemonStatus.state.daemonVersion !== expectedVersion) return {
|
|
51167
|
-
kind: "outdated",
|
|
51168
|
-
installedVersion: daemonStatus.state.daemonVersion
|
|
51169
|
-
};
|
|
51170
|
-
const runtime = await readCurrentDaemonRuntimeContext({ status: daemonStatus }).catch((error) => {
|
|
51171
|
-
warnServiceCheckIssue("readCurrentDaemonRuntimeContext failed", {
|
|
51172
|
-
daemonStatus,
|
|
51173
|
-
error
|
|
51579
|
+
return await resolveDaemonServiceParticipationStatus({ expectedVersion }).catch((error) => {
|
|
51580
|
+
warnServiceCheckIssue("resolveDaemonServiceParticipationStatus failed", {
|
|
51581
|
+
error,
|
|
51582
|
+
expectedVersion,
|
|
51583
|
+
view: input.view
|
|
51174
51584
|
});
|
|
51175
|
-
return
|
|
51585
|
+
return {
|
|
51586
|
+
kind: "not_running",
|
|
51587
|
+
expectedVersion,
|
|
51588
|
+
installedVersion: null,
|
|
51589
|
+
runtimeStatus: null
|
|
51590
|
+
};
|
|
51176
51591
|
});
|
|
51177
|
-
if (!runtime || runtime.effectiveRuntimeStatus !== "running") return {
|
|
51178
|
-
kind: "not_running",
|
|
51179
|
-
runtimeStatus: runtime?.runtimeStatus ?? null
|
|
51180
|
-
};
|
|
51181
|
-
return { kind: "ready" };
|
|
51182
51592
|
}
|
|
51183
|
-
async function fixServiceStatus(
|
|
51593
|
+
async function fixServiceStatus(input) {
|
|
51184
51594
|
const expectedVersion = resolveCurrentDaemonExpectedVersion();
|
|
51185
|
-
if (serviceStatus.kind === "missing") {
|
|
51595
|
+
if (input.serviceStatus.kind === "missing") {
|
|
51186
51596
|
await ensureDaemonInstalledForCliStartup({
|
|
51187
51597
|
daemonVersion: expectedVersion,
|
|
51188
51598
|
mode: "always"
|
|
51189
51599
|
});
|
|
51190
51600
|
return true;
|
|
51191
51601
|
}
|
|
51192
|
-
if (serviceStatus.kind === "outdated") {
|
|
51602
|
+
if (input.serviceStatus.kind === "outdated") {
|
|
51193
51603
|
const daemonStatus = await getDaemonStatus();
|
|
51194
51604
|
await ensureDaemonVersionForCliStartup({
|
|
51195
51605
|
daemonVersion: expectedVersion,
|
|
@@ -51198,8 +51608,15 @@ async function fixServiceStatus(serviceStatus) {
|
|
|
51198
51608
|
});
|
|
51199
51609
|
return true;
|
|
51200
51610
|
}
|
|
51201
|
-
if (serviceStatus.kind === "not_running") return await runDaemonBackgroundStartForDecision({
|
|
51202
|
-
|
|
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") {
|
|
51203
51620
|
await runDaemonStatusSafely();
|
|
51204
51621
|
return false;
|
|
51205
51622
|
}
|
|
@@ -51248,6 +51665,7 @@ function emitServiceStatus(input) {
|
|
|
51248
51665
|
function buildServiceStatusText(serviceStatus) {
|
|
51249
51666
|
if (serviceStatus.kind === "missing") return "ATS Service is not installed on this device.";
|
|
51250
51667
|
if (serviceStatus.kind === "outdated") return `ATS Service is on ${serviceStatus.installedVersion}. ${resolveCurrentDaemonExpectedVersion()} is needed.`;
|
|
51668
|
+
if (serviceStatus.kind === "needs_repair") return "ATS Service needs cleanup before local agents on this device can reply from Space.";
|
|
51251
51669
|
if (serviceStatus.kind === "repair_blocked") return "ATS Service needs manual repair before ATS can align it automatically.";
|
|
51252
51670
|
if (serviceStatus.kind === "repair_failed") return "ATS tried to repair ATS Service automatically, but the service still needs attention.";
|
|
51253
51671
|
return "ATS Service is installed but not running.";
|
|
@@ -51255,17 +51673,19 @@ function buildServiceStatusText(serviceStatus) {
|
|
|
51255
51673
|
function buildServiceNextText(serviceStatus, action) {
|
|
51256
51674
|
if (serviceStatus.kind === "missing") return action ? `Install ATS Service now, or continue ${action} without it.` : "Install ATS Service now, or continue without it.";
|
|
51257
51675
|
if (serviceStatus.kind === "outdated") return "Update ATS Service now to match the current ATS CLI.";
|
|
51676
|
+
if (serviceStatus.kind === "needs_repair") return "Repair ATS Service now so local agents on this device can reply from Space again.";
|
|
51258
51677
|
if (serviceStatus.kind === "repair_blocked" || serviceStatus.kind === "repair_failed") return "Run `ats service status` first. If ATS still says the service needs repair, run `ats service reinstall`.";
|
|
51259
51678
|
return action ? `Start ATS Service now, or continue ${action} without it.` : "Start ATS Service now, or continue without it.";
|
|
51260
51679
|
}
|
|
51261
51680
|
function buildServiceFixLabel(serviceStatus) {
|
|
51262
51681
|
if (serviceStatus.kind === "missing") return "Install ATS Service now (Recommended)";
|
|
51263
51682
|
if (serviceStatus.kind === "outdated") return "Update ATS Service now (Recommended)";
|
|
51683
|
+
if (serviceStatus.kind === "needs_repair") return "Repair ATS Service now (Recommended)";
|
|
51264
51684
|
if (serviceStatus.kind === "repair_blocked" || serviceStatus.kind === "repair_failed") return "Open ATS Service diagnostics (Recommended)";
|
|
51265
51685
|
return "Start ATS Service now (Recommended)";
|
|
51266
51686
|
}
|
|
51267
51687
|
function buildServiceAgentNextSteps(serviceStatus) {
|
|
51268
|
-
if (serviceStatus.kind === "repair_blocked" || serviceStatus.kind === "repair_failed") return formatAtsCliCommands(["ats service status", "ats service reinstall"]);
|
|
51688
|
+
if (serviceStatus.kind === "needs_repair" || serviceStatus.kind === "repair_blocked" || serviceStatus.kind === "repair_failed") return formatAtsCliCommands(["ats service status", "ats service reinstall"]);
|
|
51269
51689
|
return formatAtsCliCommands(["ats service install", "ats service run"]);
|
|
51270
51690
|
}
|
|
51271
51691
|
function buildStartupPreflightAttentionDetail(preflight) {
|
|
@@ -54683,6 +55103,7 @@ async function runSkillsCheck(input) {
|
|
|
54683
55103
|
//#endregion
|
|
54684
55104
|
//#region src/command-entry-checks/run-command-entry-flow.ts
|
|
54685
55105
|
const CHECK_RUNNERS = {
|
|
55106
|
+
disclaimer: runDisclaimerCheck,
|
|
54686
55107
|
cliUpdate: runCliUpdateCheck,
|
|
54687
55108
|
signIn: runSignInCheck,
|
|
54688
55109
|
selectedProfile: runSelectedProfileCheck,
|
|
@@ -54697,6 +55118,7 @@ const CHECK_STAGES = [
|
|
|
54697
55118
|
"status-only"
|
|
54698
55119
|
];
|
|
54699
55120
|
const CHECK_ORDER = [
|
|
55121
|
+
"disclaimer",
|
|
54700
55122
|
"cliUpdate",
|
|
54701
55123
|
"localRuntimeState",
|
|
54702
55124
|
"signIn",
|
|
@@ -60578,6 +61000,7 @@ function buildServiceReplyReadinessGuidance(input) {
|
|
|
60578
61000
|
}
|
|
60579
61001
|
function buildReplyReadinessGuidanceSummary(reasonCode) {
|
|
60580
61002
|
switch (reasonCode) {
|
|
61003
|
+
case "local_agents.none_needed": return "This device does not need ATS Service until you choose local agents to bring into a space.";
|
|
60581
61004
|
case "profile.inactive": return "Choose an active agent profile first.";
|
|
60582
61005
|
case "profile.unbound": return "This profile is not connected to an agent yet.";
|
|
60583
61006
|
case "controller.binding.disabled": return "This profile's agent is turned off.";
|
|
@@ -60606,8 +61029,15 @@ function buildReplyReadinessNextSteps(input) {
|
|
|
60606
61029
|
controllerRef
|
|
60607
61030
|
}) ?? controllerRef ?? "<agent-id>";
|
|
60608
61031
|
switch (input.reasonCode) {
|
|
61032
|
+
case "local_agents.none_needed": return [
|
|
61033
|
+
formatAtsCliCommand("ats start"),
|
|
61034
|
+
formatAtsCliCommand("ats service install"),
|
|
61035
|
+
formatAtsCliCommand("ats service run")
|
|
61036
|
+
];
|
|
60609
61037
|
case "profile.inactive": return [formatAtsCliCommand("ats profile list"), formatAtsCliCommand("ats profile set <agent-profile-id>")];
|
|
60610
|
-
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")];
|
|
60611
61041
|
case "controller.binding.disabled": return [formatAtsCliCommand(`ats profile update ${profileId} --controller-enabled true`)];
|
|
60612
61042
|
case "projection.missing": return [formatAtsCliCommand("ats doctor --repair")];
|
|
60613
61043
|
case "controller.registry.disabled": return [formatAtsCliCommand(`ats agents enable --agent ${agentCommandId}`), formatAtsCliCommand("ats doctor --repair")];
|
|
@@ -62628,19 +63058,6 @@ function normalizeOptionalString$5(value) {
|
|
|
62628
63058
|
|
|
62629
63059
|
//#endregion
|
|
62630
63060
|
//#region src/start-foundation/selectors.ts
|
|
62631
|
-
const BACKGROUND_HELPER_REASON_CODES = new Set([
|
|
62632
|
-
"background_helper.not_installed",
|
|
62633
|
-
"background_helper.installed_outdated",
|
|
62634
|
-
"background_helper.not_running",
|
|
62635
|
-
"background_helper.stale",
|
|
62636
|
-
"background_helper.unknown"
|
|
62637
|
-
]);
|
|
62638
|
-
function isCliStartBackgroundHelperReasonCode(reasonCode) {
|
|
62639
|
-
return BACKGROUND_HELPER_REASON_CODES.has(reasonCode);
|
|
62640
|
-
}
|
|
62641
|
-
function isCliStartBackgroundHelperSignal(signal) {
|
|
62642
|
-
return signal.actionId === "device_check" && isCliStartBackgroundHelperReasonCode(signal.reasonCode);
|
|
62643
|
-
}
|
|
62644
63061
|
function findCliStartSelectedProfileReadinessEntry(input) {
|
|
62645
63062
|
return input.foundation.foundationState.readModel.profileReadiness.find((entry) => entry.profileId === input.profileId) ?? null;
|
|
62646
63063
|
}
|
|
@@ -62650,8 +63067,13 @@ function readCliStartDeviceProjection(foundation) {
|
|
|
62650
63067
|
function isCliStartNextActionBlocked(foundation) {
|
|
62651
63068
|
return foundation.foundationState.decision.status === "blocking";
|
|
62652
63069
|
}
|
|
62653
|
-
function
|
|
62654
|
-
return
|
|
63070
|
+
function hasCliStartSelectedLocalAgents(foundation) {
|
|
63071
|
+
return foundation.foundationState.readModel.session.value?.agentSelection.mode === "selected_agents";
|
|
63072
|
+
}
|
|
63073
|
+
function readCliStartSelectedLocalAgentIds(foundation) {
|
|
63074
|
+
const agentSelection = foundation.foundationState.readModel.session.value?.agentSelection;
|
|
63075
|
+
if (!agentSelection || agentSelection.mode !== "selected_agents") return [];
|
|
63076
|
+
return agentSelection.selectedAgentIds;
|
|
62655
63077
|
}
|
|
62656
63078
|
|
|
62657
63079
|
//#endregion
|
|
@@ -62945,12 +63367,6 @@ function collectStartLocalBackgroundHelperReadiness() {
|
|
|
62945
63367
|
async function resolveStartLocalBackgroundHelperDemand(input) {
|
|
62946
63368
|
return await resolveDaemonLocalServiceDemand(input);
|
|
62947
63369
|
}
|
|
62948
|
-
async function runStartLocalBackgroundHelperInstall(input) {
|
|
62949
|
-
await runDaemonInstall({ view: input.view });
|
|
62950
|
-
}
|
|
62951
|
-
async function runStartLocalBackgroundHelperBackgroundStart(input) {
|
|
62952
|
-
return await runDaemonBackgroundStartForDecision({ view: input.view });
|
|
62953
|
-
}
|
|
62954
63370
|
|
|
62955
63371
|
//#endregion
|
|
62956
63372
|
//#region src/start-local/skills-local.ts
|
|
@@ -62993,49 +63409,13 @@ async function collectStartLocalReadiness(input) {
|
|
|
62993
63409
|
|
|
62994
63410
|
//#endregion
|
|
62995
63411
|
//#region src/commands/start-auth-and-readiness.ts
|
|
62996
|
-
const START_DISCLAIMER_ACCEPT = "__start_disclaimer_accept__";
|
|
62997
|
-
const START_DISCLAIMER_DECLINE = "__start_disclaimer_decline__";
|
|
62998
|
-
const START_V1_DISCLAIMER_VERSION = "start-v1-2026-03-02";
|
|
62999
|
-
const START_V1_DISCLAIMER_TEXT = "ATSD is experimental and changes rapidly. Breaking changes may occur. You are fully responsible for data security and sensitive information handling. Use ATSD only in trusted environments.";
|
|
63000
63412
|
async function runStartDisclaimerStep(input) {
|
|
63001
|
-
|
|
63002
|
-
|
|
63003
|
-
input.presenter
|
|
63004
|
-
|
|
63005
|
-
|
|
63006
|
-
version: START_V1_DISCLAIMER_VERSION,
|
|
63007
|
-
text: START_V1_DISCLAIMER_TEXT,
|
|
63008
|
-
mode: "agent_notice",
|
|
63009
|
-
requiresConfirmation: false
|
|
63010
|
-
}
|
|
63011
|
-
});
|
|
63012
|
-
return true;
|
|
63013
|
-
}
|
|
63014
|
-
note(`⚠️ ${START_V1_DISCLAIMER_TEXT}`, "Disclaimer");
|
|
63015
|
-
if (!input.interactive) {
|
|
63016
|
-
input.presenter.line({
|
|
63017
|
-
code: "start.disclaimer.auto_continue",
|
|
63018
|
-
text: "Non-interactive session: disclaimer displayed and onboarding continues."
|
|
63019
|
-
});
|
|
63020
|
-
return true;
|
|
63021
|
-
}
|
|
63022
|
-
const decision = await select({
|
|
63023
|
-
message: "Do you accept and continue?",
|
|
63024
|
-
options: [{
|
|
63025
|
-
value: START_DISCLAIMER_ACCEPT,
|
|
63026
|
-
label: "Yes, continue"
|
|
63027
|
-
}, {
|
|
63028
|
-
value: START_DISCLAIMER_DECLINE,
|
|
63029
|
-
label: "No, exit"
|
|
63030
|
-
}],
|
|
63031
|
-
initialValue: START_DISCLAIMER_ACCEPT
|
|
63413
|
+
return await runOnboardingDisclaimerGate({
|
|
63414
|
+
runtime: input.runtime,
|
|
63415
|
+
presenter: input.presenter,
|
|
63416
|
+
interactive: input.interactive,
|
|
63417
|
+
codePrefix: "start.disclaimer"
|
|
63032
63418
|
});
|
|
63033
|
-
if (isCancel(decision) || decision === START_DISCLAIMER_DECLINE) {
|
|
63034
|
-
cancel("Cancelled.");
|
|
63035
|
-
return false;
|
|
63036
|
-
}
|
|
63037
|
-
await persistStartDisclaimerAccepted();
|
|
63038
|
-
return true;
|
|
63039
63419
|
}
|
|
63040
63420
|
async function markStartV1Completed() {
|
|
63041
63421
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -63122,12 +63502,6 @@ function formatReadinessLine(input) {
|
|
|
63122
63502
|
if (!input.detail) return line;
|
|
63123
63503
|
return `${line} ${pc.dim(input.detail)}`;
|
|
63124
63504
|
}
|
|
63125
|
-
async function persistStartDisclaimerAccepted() {
|
|
63126
|
-
await updateConfiguredStartV1OnboardingState((current) => ({
|
|
63127
|
-
...current ?? {},
|
|
63128
|
-
disclaimerAcceptedVersion: START_V1_DISCLAIMER_VERSION
|
|
63129
|
-
}));
|
|
63130
|
-
}
|
|
63131
63505
|
function evaluateStartAuthentication(input) {
|
|
63132
63506
|
return evaluateCommandAuthentication({ gatewayUrl: input.gatewayUrl });
|
|
63133
63507
|
}
|
|
@@ -63932,41 +64306,20 @@ async function runStartSkillsStep(input) {
|
|
|
63932
64306
|
}
|
|
63933
64307
|
}
|
|
63934
64308
|
async function runStartAgentsStep(input) {
|
|
63935
|
-
const
|
|
63936
|
-
const selectableCandidates = builtinCandidates.filter((candidate) => candidate.selectable);
|
|
63937
|
-
const payload = buildStartAgentsPayload({
|
|
63938
|
-
builtinCandidates,
|
|
63939
|
-
selectableCandidates
|
|
63940
|
-
});
|
|
63941
|
-
const onboardingState = await getConfiguredStartV1OnboardingState().catch(() => null);
|
|
63942
|
-
const preconfiguredAgentSelection = resolvePreconfiguredStartAgentSelection({
|
|
63943
|
-
builtinCandidates,
|
|
63944
|
-
localAgentsSetupCompleted: typeof onboardingState?.localAgentsSetupCompletedAt === "string" && onboardingState.localAgentsSetupCompletedAt.length > 0,
|
|
63945
|
-
selectableCandidates
|
|
63946
|
-
});
|
|
64309
|
+
const agentSelectionState = await resolveStartAgentSelectionState();
|
|
63947
64310
|
if (input.runtime.resolvedView === "agent") {
|
|
63948
64311
|
input.presenter.data({
|
|
63949
64312
|
code: "start.agents",
|
|
63950
|
-
payload
|
|
64313
|
+
payload: agentSelectionState.payload
|
|
64314
|
+
});
|
|
64315
|
+
return createStartAgentsStepResult(agentSelectionState.preconfiguredAgentSelection ?? {
|
|
64316
|
+
mode: "unresolved",
|
|
64317
|
+
selectedAgentIds: []
|
|
63951
64318
|
});
|
|
63952
|
-
if (preconfiguredAgentSelection) return {
|
|
63953
|
-
agentSelection: preconfiguredAgentSelection,
|
|
63954
|
-
allowBackFromProfile: false
|
|
63955
|
-
};
|
|
63956
|
-
return {
|
|
63957
|
-
agentSelection: {
|
|
63958
|
-
mode: "unresolved",
|
|
63959
|
-
selectedAgentIds: []
|
|
63960
|
-
},
|
|
63961
|
-
allowBackFromProfile: false
|
|
63962
|
-
};
|
|
63963
64319
|
}
|
|
63964
|
-
if (preconfiguredAgentSelection) return
|
|
63965
|
-
agentSelection: preconfiguredAgentSelection,
|
|
63966
|
-
allowBackFromProfile: false
|
|
63967
|
-
};
|
|
64320
|
+
if (agentSelectionState.preconfiguredAgentSelection) return createStartAgentsStepResult(agentSelectionState.preconfiguredAgentSelection);
|
|
63968
64321
|
if (!input.interactive) {
|
|
63969
|
-
if (selectableCandidates.length > 0) input.presenter.line({
|
|
64322
|
+
if (agentSelectionState.selectableCandidates.length > 0) input.presenter.line({
|
|
63970
64323
|
code: "start.agents.non_interactive",
|
|
63971
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.")
|
|
63972
64325
|
});
|
|
@@ -63978,69 +64331,135 @@ async function runStartAgentsStep(input) {
|
|
|
63978
64331
|
allowBackFromProfile: false
|
|
63979
64332
|
};
|
|
63980
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) {
|
|
63981
64367
|
for (;;) {
|
|
63982
64368
|
const localAgentDecision = await promptStartLocalAgentDecision();
|
|
63983
64369
|
if (localAgentDecision === "cancelled" || localAgentDecision === "exit") {
|
|
63984
64370
|
cancel("Cancelled.");
|
|
63985
64371
|
return "cancelled";
|
|
63986
64372
|
}
|
|
63987
|
-
if (localAgentDecision === "no_agents") {
|
|
63988
|
-
|
|
63989
|
-
|
|
63990
|
-
|
|
63991
|
-
|
|
63992
|
-
|
|
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.")
|
|
63993
64393
|
});
|
|
63994
|
-
|
|
63995
|
-
emitStartLocalAgentsSetupSaved(input.presenter);
|
|
63996
|
-
return {
|
|
63997
|
-
agentSelection: {
|
|
63998
|
-
mode: "no_agents",
|
|
63999
|
-
selectedAgentIds: []
|
|
64000
|
-
},
|
|
64001
|
-
allowBackFromProfile: true
|
|
64002
|
-
};
|
|
64394
|
+
continue;
|
|
64003
64395
|
}
|
|
64004
|
-
const selectedAgentIds = await promptStartAgentSelection(
|
|
64396
|
+
const selectedAgentIds = await promptStartAgentSelection(repairedBuiltinCandidates);
|
|
64005
64397
|
if (selectedAgentIds === "cancelled") {
|
|
64006
64398
|
cancel("Cancelled.");
|
|
64007
64399
|
return "cancelled";
|
|
64008
64400
|
}
|
|
64009
64401
|
if (selectedAgentIds === "back") continue;
|
|
64010
|
-
if (selectedAgentIds.length === 0) {
|
|
64011
|
-
|
|
64012
|
-
builtinCandidates,
|
|
64013
|
-
selectedAgentIds,
|
|
64014
|
-
profile: input.profile,
|
|
64015
|
-
view: input.view
|
|
64016
|
-
});
|
|
64017
|
-
await persistStartLocalAgentsSetupCompleted();
|
|
64018
|
-
emitStartLocalAgentsSetupSaved(input.presenter);
|
|
64019
|
-
return {
|
|
64020
|
-
agentSelection: {
|
|
64021
|
-
mode: "no_agents",
|
|
64022
|
-
selectedAgentIds: []
|
|
64023
|
-
},
|
|
64024
|
-
allowBackFromProfile: true
|
|
64025
|
-
};
|
|
64026
|
-
}
|
|
64027
|
-
await syncStartLocalAgentSelection({
|
|
64028
|
-
builtinCandidates,
|
|
64029
|
-
selectedAgentIds,
|
|
64402
|
+
if (selectedAgentIds.length === 0) return await completeStartLocalAgentSelection({
|
|
64403
|
+
builtinCandidates: input.builtinCandidates,
|
|
64030
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,
|
|
64031
64414
|
view: input.view
|
|
64032
64415
|
});
|
|
64033
|
-
await persistStartLocalAgentsSetupCompleted();
|
|
64034
|
-
emitStartLocalAgentsSetupSaved(input.presenter);
|
|
64035
|
-
return {
|
|
64036
|
-
agentSelection: {
|
|
64037
|
-
mode: "selected_agents",
|
|
64038
|
-
selectedAgentIds
|
|
64039
|
-
},
|
|
64040
|
-
allowBackFromProfile: true
|
|
64041
|
-
};
|
|
64042
64416
|
}
|
|
64043
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
|
+
}
|
|
64044
64463
|
function buildStartAgentsPayload(input) {
|
|
64045
64464
|
return {
|
|
64046
64465
|
candidates: input.builtinCandidates.map((candidate) => ({
|
|
@@ -64072,11 +64491,17 @@ function resolveSavedStartAgentSelection(selectableCandidates) {
|
|
|
64072
64491
|
};
|
|
64073
64492
|
}
|
|
64074
64493
|
function resolvePreconfiguredStartAgentSelection(input) {
|
|
64075
|
-
|
|
64494
|
+
const hasRepairableCandidates = input.builtinCandidates.some((candidate) => candidate.detected && !candidate.selectable && candidate.selectableReason === "needs_repair");
|
|
64495
|
+
if (input.builtinCandidates.length === 0) return {
|
|
64076
64496
|
mode: "no_agents",
|
|
64077
64497
|
selectedAgentIds: []
|
|
64078
64498
|
};
|
|
64499
|
+
if (input.selectableCandidates.length === 0 && hasRepairableCandidates) return null;
|
|
64079
64500
|
if (!input.localAgentsSetupCompleted) return null;
|
|
64501
|
+
if (input.selectableCandidates.length === 0) return {
|
|
64502
|
+
mode: "no_agents",
|
|
64503
|
+
selectedAgentIds: []
|
|
64504
|
+
};
|
|
64080
64505
|
return resolveSavedStartAgentSelection([...input.selectableCandidates]);
|
|
64081
64506
|
}
|
|
64082
64507
|
async function persistStartLocalAgentsSetupCompleted() {
|
|
@@ -64292,10 +64717,14 @@ function resolveStartBackgroundHelperShellState(input) {
|
|
|
64292
64717
|
runtimeStatus: input.readiness.service.runtime?.status ?? "unknown"
|
|
64293
64718
|
};
|
|
64294
64719
|
}
|
|
64295
|
-
function
|
|
64296
|
-
|
|
64297
|
-
if (
|
|
64298
|
-
|
|
64720
|
+
function haveRunnableSelectedLocalAgentSetup(input) {
|
|
64721
|
+
const selectedAgentIds = readCliStartSelectedLocalAgentIds(input.foundation);
|
|
64722
|
+
if (selectedAgentIds.length === 0) return false;
|
|
64723
|
+
const candidateById = new Map(input.readiness.agents.candidates.map((candidate) => [candidate.agentId, candidate]));
|
|
64724
|
+
return selectedAgentIds.every((selectedAgentId) => {
|
|
64725
|
+
const candidate = candidateById.get(selectedAgentId);
|
|
64726
|
+
return candidate?.enabled === true && candidate.selectable === true;
|
|
64727
|
+
});
|
|
64299
64728
|
}
|
|
64300
64729
|
function emitStartServiceNonInteractiveLine(input) {
|
|
64301
64730
|
const text = input.backgroundHelper.status === "installed_current" ? formatInlineAtsCliCommands("⚠️ ATS Service: Installed and up to date, but not currently running. Start it manually with `ats service run`.") : formatInlineAtsCliCommands(input.backgroundHelper.status === "not_installed" ? `⚠️ ATS Service: ${formatDaemonServiceMissingStatus()} ${formatDaemonServiceMissingAction()}` : `⚠️ ATS Service: ${formatDaemonServiceOutdatedStatus({
|
|
@@ -64307,78 +64736,47 @@ function emitStartServiceNonInteractiveLine(input) {
|
|
|
64307
64736
|
text
|
|
64308
64737
|
});
|
|
64309
64738
|
}
|
|
64310
|
-
|
|
64311
|
-
|
|
64312
|
-
|
|
64313
|
-
|
|
64314
|
-
|
|
64739
|
+
|
|
64740
|
+
//#endregion
|
|
64741
|
+
//#region src/system/service-participation-policy.ts
|
|
64742
|
+
function resolveCliServiceParticipationRequirement(input) {
|
|
64743
|
+
return resolveServiceParticipationRequirement({
|
|
64744
|
+
intent: input.intent,
|
|
64745
|
+
humanOnlyParticipation: input.humanOnlyParticipation,
|
|
64746
|
+
explicitSelectedLocalAgents: input.explicitSelectedLocalAgents,
|
|
64747
|
+
selectedAgentProfilesHaveRunnableLocalSetup: input.selectedAgentProfilesHaveRunnableLocalSetup,
|
|
64748
|
+
deviceLocalDemand: mapDaemonLocalServiceDemandToSharedValue(input.localDemand)
|
|
64315
64749
|
});
|
|
64316
64750
|
}
|
|
64317
|
-
function
|
|
64318
|
-
|
|
64319
|
-
renderInfoCard({
|
|
64320
|
-
presenter: input.presenter,
|
|
64321
|
-
title: card.title,
|
|
64322
|
-
codePrefix: "start.service.deferred",
|
|
64323
|
-
rows: card.rows
|
|
64324
|
-
});
|
|
64751
|
+
function isExplicitLocalAgentProfile(profile) {
|
|
64752
|
+
return profile.profileKind === "agent";
|
|
64325
64753
|
}
|
|
64326
|
-
function
|
|
64327
|
-
|
|
64328
|
-
|
|
64329
|
-
|
|
64330
|
-
|
|
64331
|
-
codePrefix: "start.service.failed",
|
|
64332
|
-
rows: card.rows
|
|
64754
|
+
function hasRunnableLocalAgentSetup(profile) {
|
|
64755
|
+
return hasRunnableLocalAgentParticipationCandidate({
|
|
64756
|
+
profileKind: profile.profileKind === "agent" ? "agent" : "human",
|
|
64757
|
+
controllerRef: profile.controllerBinding?.controllerRef,
|
|
64758
|
+
controllerEnabled: profile.controllerBinding?.controllerEnabled
|
|
64333
64759
|
});
|
|
64334
64760
|
}
|
|
64335
|
-
|
|
64336
|
-
|
|
64337
|
-
const statusLine = input.kind === "outdated" ? formatDaemonServiceOutdatedStatus({
|
|
64338
|
-
installedVersion: input.installedVersion,
|
|
64339
|
-
expectedVersion: input.expectedVersion
|
|
64340
|
-
}) : formatDaemonServiceMissingStatus();
|
|
64341
|
-
const explanation = input.recommendation === "recommended" ? "ATS Service lets local agents on this device reply from Space, so we recommend it for this setup." : "You can keep going without ATS Service, but local agents on this device won't be able to reply from Space.";
|
|
64342
|
-
const detailLine = input.kind === "outdated" && input.installedVersion ? `Installed v${input.installedVersion}, expected v${input.expectedVersion}.` : null;
|
|
64343
|
-
const decision = await select({
|
|
64344
|
-
message: [
|
|
64345
|
-
input.kind === "outdated" ? "ATS Service needs an update. Fix it now?" : "ATS Service is missing. Install it now?",
|
|
64346
|
-
explanation,
|
|
64347
|
-
`Current status: ${statusLine}`,
|
|
64348
|
-
detailLine
|
|
64349
|
-
].filter((line) => typeof line === "string" && line.length > 0).join("\n"),
|
|
64350
|
-
initialValue: "fix_now",
|
|
64351
|
-
options: [{
|
|
64352
|
-
value: "fix_now",
|
|
64353
|
-
label: actionLabel,
|
|
64354
|
-
hint: input.recommendation === "recommended" ? "Recommended" : "Optional"
|
|
64355
|
-
}, {
|
|
64356
|
-
value: "not_now",
|
|
64357
|
-
label: "Not now"
|
|
64358
|
-
}]
|
|
64359
|
-
});
|
|
64360
|
-
if (isCancel(decision)) return "cancelled";
|
|
64361
|
-
return decision === "fix_now" ? "fix_now" : "not_now";
|
|
64761
|
+
function hasAnyExplicitLocalAgentCandidates(candidates) {
|
|
64762
|
+
return candidates.some((candidate) => candidate.profileKind === "agent");
|
|
64362
64763
|
}
|
|
64363
|
-
function
|
|
64364
|
-
|
|
64365
|
-
|
|
64764
|
+
function haveAllExplicitLocalAgentCandidatesRunnable(candidates) {
|
|
64765
|
+
const agentCandidates = candidates.filter((candidate) => candidate.profileKind === "agent");
|
|
64766
|
+
if (agentCandidates.length === 0) return false;
|
|
64767
|
+
return agentCandidates.every((candidate) => hasRunnableLocalAgentParticipationCandidate(candidate));
|
|
64366
64768
|
}
|
|
64367
|
-
|
|
64368
|
-
|
|
64369
|
-
|
|
64370
|
-
|
|
64371
|
-
|
|
64372
|
-
|
|
64373
|
-
|
|
64374
|
-
|
|
64375
|
-
|
|
64376
|
-
|
|
64377
|
-
|
|
64378
|
-
}]
|
|
64379
|
-
});
|
|
64380
|
-
if (isCancel(decision)) return "cancelled";
|
|
64381
|
-
return decision === "fix_now" ? "fix_now" : "not_now";
|
|
64769
|
+
function hasRunnableLocalAgentParticipationCandidate(candidate) {
|
|
64770
|
+
if (candidate.profileKind !== "agent") return false;
|
|
64771
|
+
return candidate.controllerEnabled === true && typeof candidate.controllerRef === "string" && candidate.controllerRef.trim().length > 0;
|
|
64772
|
+
}
|
|
64773
|
+
function mapDaemonLocalServiceDemandToSharedValue(localDemand) {
|
|
64774
|
+
switch (localDemand?.decision) {
|
|
64775
|
+
case "keep_running":
|
|
64776
|
+
case "allow_auto_stop":
|
|
64777
|
+
case "indeterminate": return localDemand.decision;
|
|
64778
|
+
default: return "indeterminate";
|
|
64779
|
+
}
|
|
64382
64780
|
}
|
|
64383
64781
|
|
|
64384
64782
|
//#endregion
|
|
@@ -64388,6 +64786,7 @@ async function runStartServiceStep(input) {
|
|
|
64388
64786
|
foundation: input.foundation,
|
|
64389
64787
|
readiness: input.readiness
|
|
64390
64788
|
});
|
|
64789
|
+
const selectedLocalAgentsRequireService = hasCliStartSelectedLocalAgents(input.foundation);
|
|
64391
64790
|
const payload = buildStartServicePayload({
|
|
64392
64791
|
readiness: input.readiness,
|
|
64393
64792
|
backgroundHelper
|
|
@@ -64399,15 +64798,7 @@ async function runStartServiceStep(input) {
|
|
|
64399
64798
|
});
|
|
64400
64799
|
return "continue";
|
|
64401
64800
|
}
|
|
64402
|
-
if (backgroundHelper.status === "installed_current") return
|
|
64403
|
-
...input,
|
|
64404
|
-
backgroundHelper
|
|
64405
|
-
});
|
|
64406
|
-
const recommendation = resolveStartServiceRecommendation({
|
|
64407
|
-
backgroundHelper,
|
|
64408
|
-
foundation: input.foundation,
|
|
64409
|
-
localDemand: null
|
|
64410
|
-
});
|
|
64801
|
+
if (backgroundHelper.status === "installed_current" && backgroundHelper.runtimeStatus === "running") return "continue";
|
|
64411
64802
|
if (!input.interactive) {
|
|
64412
64803
|
emitStartServiceNonInteractiveLine({
|
|
64413
64804
|
presenter: input.presenter,
|
|
@@ -64415,78 +64806,47 @@ async function runStartServiceStep(input) {
|
|
|
64415
64806
|
});
|
|
64416
64807
|
return "continue";
|
|
64417
64808
|
}
|
|
64418
|
-
const
|
|
64419
|
-
|
|
64420
|
-
|
|
64421
|
-
|
|
64422
|
-
|
|
64809
|
+
const localDemand = await resolveStartLocalBackgroundHelperDemand({ ownerUserId: input.ownerUserId }).catch(() => null);
|
|
64810
|
+
const currentProfileIsExplicitLocalAgent = isExplicitLocalAgentProfile(input.profile);
|
|
64811
|
+
const selectedLocalAgentsHaveRunnableLocalSetup = !selectedLocalAgentsRequireService || haveRunnableSelectedLocalAgentSetup({
|
|
64812
|
+
foundation: input.foundation,
|
|
64813
|
+
readiness: input.readiness
|
|
64423
64814
|
});
|
|
64424
|
-
|
|
64425
|
-
|
|
64426
|
-
|
|
64427
|
-
|
|
64428
|
-
|
|
64429
|
-
|
|
64430
|
-
|
|
64431
|
-
} catch {
|
|
64432
|
-
emitStartServiceSkippedLine({
|
|
64433
|
-
presenter: input.presenter,
|
|
64434
|
-
backgroundHelper,
|
|
64435
|
-
outcome: "failed_install"
|
|
64436
|
-
});
|
|
64437
|
-
return "needs_attention";
|
|
64438
|
-
}
|
|
64439
|
-
return "continue";
|
|
64440
|
-
}
|
|
64441
|
-
emitStartServiceSkippedLine({
|
|
64442
|
-
presenter: input.presenter,
|
|
64443
|
-
backgroundHelper,
|
|
64444
|
-
outcome: "not_fixed"
|
|
64815
|
+
const currentProfileHasRunnableLocalSetup = !currentProfileIsExplicitLocalAgent || hasRunnableLocalAgentSetup(input.profile);
|
|
64816
|
+
const serviceRequirement = resolveCliServiceParticipationRequirement({
|
|
64817
|
+
intent: "start",
|
|
64818
|
+
humanOnlyParticipation: !(selectedLocalAgentsRequireService || currentProfileIsExplicitLocalAgent) && localDemand?.decision !== "keep_running",
|
|
64819
|
+
explicitSelectedLocalAgents: selectedLocalAgentsRequireService || currentProfileIsExplicitLocalAgent,
|
|
64820
|
+
selectedAgentProfilesHaveRunnableLocalSetup: selectedLocalAgentsHaveRunnableLocalSetup && currentProfileHasRunnableLocalSetup,
|
|
64821
|
+
localDemand
|
|
64445
64822
|
});
|
|
64446
|
-
return "continue";
|
|
64447
|
-
|
|
64448
|
-
|
|
64449
|
-
|
|
64450
|
-
|
|
64451
|
-
if (localDemand && localDemand.decision !== "keep_running") return "continue";
|
|
64452
|
-
if (!input.interactive) {
|
|
64453
|
-
emitStartServiceNonInteractiveLine({
|
|
64454
|
-
presenter: input.presenter,
|
|
64455
|
-
backgroundHelper: input.backgroundHelper
|
|
64823
|
+
if (serviceRequirement === "not_needed") return "continue";
|
|
64824
|
+
if (serviceRequirement === "agent_setup_needed") {
|
|
64825
|
+
input.presenter.line({
|
|
64826
|
+
code: "start.service.agent_setup_needed",
|
|
64827
|
+
text: `Finish local agent setup before you bring this profile into a space. Use \`ats profile ready --profile ${input.profile.atsProfileId}\` or rerun \`ats start\`.`
|
|
64456
64828
|
});
|
|
64457
64829
|
return "continue";
|
|
64458
64830
|
}
|
|
64459
|
-
|
|
64831
|
+
const gateResult = await runDaemonServiceParticipationGate({
|
|
64832
|
+
intent: "start",
|
|
64460
64833
|
presenter: input.presenter,
|
|
64461
|
-
|
|
64462
|
-
|
|
64463
|
-
|
|
64464
|
-
|
|
64465
|
-
|
|
64834
|
+
resolvedView: input.runtime.resolvedView,
|
|
64835
|
+
allowPrompt: input.interactive,
|
|
64836
|
+
gatewayUrl: input.gatewayUrl,
|
|
64837
|
+
localDemand,
|
|
64838
|
+
forcePrompt: selectedLocalAgentsRequireService || currentProfileIsExplicitLocalAgent,
|
|
64466
64839
|
view: input.view
|
|
64467
64840
|
});
|
|
64468
|
-
|
|
64469
|
-
async function handleInstalledCurrentStartServiceDecision(input) {
|
|
64470
|
-
const decision = await promptForStartServiceStartDecision({ recommendation: input.recommendation });
|
|
64471
|
-
if (decision === "cancelled") {
|
|
64841
|
+
if (gateResult.status === "cancelled") {
|
|
64472
64842
|
cancel("Cancelled.");
|
|
64473
64843
|
return "cancelled";
|
|
64474
64844
|
}
|
|
64475
|
-
if (
|
|
64476
|
-
|
|
64477
|
-
|
|
64478
|
-
|
|
64479
|
-
|
|
64480
|
-
if (startResult === "cancelled") {
|
|
64481
|
-
cancel("Cancelled.");
|
|
64482
|
-
return "cancelled";
|
|
64483
|
-
}
|
|
64484
|
-
if (startResult === "deferred_with_card") return "continue";
|
|
64485
|
-
if (startResult === "failed") {
|
|
64486
|
-
renderStartServiceFailureCard({ presenter: input.presenter });
|
|
64487
|
-
return "needs_attention";
|
|
64488
|
-
}
|
|
64489
|
-
if (startResult === "failed_with_card") return "needs_attention";
|
|
64845
|
+
if (gateResult.status === "needs_attention") return "needs_attention";
|
|
64846
|
+
if (gateResult.status === "declined") input.presenter.line({
|
|
64847
|
+
code: "start.service.declined",
|
|
64848
|
+
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`."
|
|
64849
|
+
});
|
|
64490
64850
|
return "continue";
|
|
64491
64851
|
}
|
|
64492
64852
|
|
|
@@ -64623,6 +64983,7 @@ async function runStartHandoff(input) {
|
|
|
64623
64983
|
const serviceStepResult = await runHandoffLocalStepWithFailedProgressSync({
|
|
64624
64984
|
run: async () => await runStartServiceStep({
|
|
64625
64985
|
foundation,
|
|
64986
|
+
gatewayUrl,
|
|
64626
64987
|
runtime: input.runtime,
|
|
64627
64988
|
presenter: input.presenter,
|
|
64628
64989
|
interactive: true,
|
|
@@ -71960,6 +72321,11 @@ async function emitSpaceCommandPreflight(input) {
|
|
|
71960
72321
|
},
|
|
71961
72322
|
serviceRepairGuidance: resolveSpacePreflightRepairGuidance({ serviceParticipationReadiness })
|
|
71962
72323
|
};
|
|
72324
|
+
if (!shouldEmitSpaceCommandPreflightOutput(input.emitOutput)) return {
|
|
72325
|
+
deviceReplyReadiness: replyReadinessSnapshot.deviceReplyReadiness,
|
|
72326
|
+
payload,
|
|
72327
|
+
serviceParticipationReadiness
|
|
72328
|
+
};
|
|
71963
72329
|
if (input.resolvedView === "human") {
|
|
71964
72330
|
const authLabel = buildHumanPreflightAuthLabel(payload.auth);
|
|
71965
72331
|
const agentReplyReadinessLabel = payload.agentReplyReadiness && input.profile.profileKind === "agent" && shouldSurfaceSenderReplyReadinessInPreflightHeadline(input.command) ? formatReplyReadinessSummary(payload.agentReplyReadiness) : null;
|
|
@@ -71971,7 +72337,8 @@ async function emitSpaceCommandPreflight(input) {
|
|
|
71971
72337
|
profileName: payload.profile.profileName,
|
|
71972
72338
|
agentReplyReadinessLabel,
|
|
71973
72339
|
guidance: payload.serviceRepairGuidance,
|
|
71974
|
-
serviceParticipationReadiness
|
|
72340
|
+
serviceParticipationReadiness,
|
|
72341
|
+
humanServiceGuidanceMode: input.humanServiceGuidanceMode ?? "show"
|
|
71975
72342
|
});
|
|
71976
72343
|
return {
|
|
71977
72344
|
deviceReplyReadiness: replyReadinessSnapshot.deviceReplyReadiness,
|
|
@@ -72029,7 +72396,8 @@ function emitHumanSpaceCommandPreflight(input) {
|
|
|
72029
72396
|
emitSpacePreflightRepairGuidance({
|
|
72030
72397
|
presenter: input.presenter,
|
|
72031
72398
|
command: input.command,
|
|
72032
|
-
guidance: input.guidance
|
|
72399
|
+
guidance: input.guidance,
|
|
72400
|
+
mode: input.humanServiceGuidanceMode
|
|
72033
72401
|
});
|
|
72034
72402
|
return;
|
|
72035
72403
|
}
|
|
@@ -72040,7 +72408,8 @@ function emitHumanSpaceCommandPreflight(input) {
|
|
|
72040
72408
|
emitSpacePreflightRepairGuidance({
|
|
72041
72409
|
presenter: input.presenter,
|
|
72042
72410
|
command: input.command,
|
|
72043
|
-
guidance: input.guidance
|
|
72411
|
+
guidance: input.guidance,
|
|
72412
|
+
mode: input.humanServiceGuidanceMode
|
|
72044
72413
|
});
|
|
72045
72414
|
}
|
|
72046
72415
|
function shouldSurfaceSenderReplyReadinessInPreflightHeadline(command) {
|
|
@@ -72108,7 +72477,7 @@ function toSpacePreflightAgentReplyReadiness(input) {
|
|
|
72108
72477
|
};
|
|
72109
72478
|
}
|
|
72110
72479
|
function emitSpacePreflightRepairGuidance(input) {
|
|
72111
|
-
if (!input.guidance) return;
|
|
72480
|
+
if (!input.guidance || input.mode === "suppress") return;
|
|
72112
72481
|
input.presenter.line({
|
|
72113
72482
|
code: `space.${input.command}.preflight.next_step`,
|
|
72114
72483
|
text: `Next step: ${input.guidance.summary}`,
|
|
@@ -72118,6 +72487,9 @@ function emitSpacePreflightRepairGuidance(input) {
|
|
|
72118
72487
|
}
|
|
72119
72488
|
});
|
|
72120
72489
|
}
|
|
72490
|
+
function shouldEmitSpaceCommandPreflightOutput(emitOutput) {
|
|
72491
|
+
return emitOutput !== false;
|
|
72492
|
+
}
|
|
72121
72493
|
function emitSpaceFailureNextStep(input) {
|
|
72122
72494
|
const guidance = resolveSpaceFailureGuidance(input.error);
|
|
72123
72495
|
if (!guidance) return;
|
|
@@ -79347,15 +79719,31 @@ function emitSpaceJoinLockBlocked(input) {
|
|
|
79347
79719
|
|
|
79348
79720
|
//#endregion
|
|
79349
79721
|
//#region src/space/join-entry.ts
|
|
79350
|
-
const NOT_INSTALLED_DAEMON_STATUS = {
|
|
79351
|
-
installed: false,
|
|
79352
|
-
state: null
|
|
79353
|
-
};
|
|
79354
79722
|
const LOCAL_SERVICE_ONLY_JOIN_BLOCK_REASON_CODES = new Set([
|
|
79355
79723
|
"service.drifted",
|
|
79356
79724
|
"service.not_installed",
|
|
79357
79725
|
"service.not_running"
|
|
79358
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
|
+
]);
|
|
79359
79747
|
async function prepareSpaceJoinEntryContext(input) {
|
|
79360
79748
|
const runtime = await resolveRuntimeContext({
|
|
79361
79749
|
profile: input.profile,
|
|
@@ -79458,99 +79846,134 @@ async function prepareSpaceJoinServiceState(input) {
|
|
|
79458
79846
|
};
|
|
79459
79847
|
}
|
|
79460
79848
|
async function assertSpaceJoinTargetPreflightReady(input) {
|
|
79849
|
+
const { explicitLocalAgentProfile, serviceRequirement } = resolveSpaceJoinLocalParticipationState(input);
|
|
79850
|
+
let emittedMembershipOnlyGuidance = false;
|
|
79851
|
+
let emittedServiceGuidance = false;
|
|
79852
|
+
if (serviceRequirement === "agent_setup_needed") {
|
|
79853
|
+
input.presenter.line({
|
|
79854
|
+
code: "space.join.local_participation.pending",
|
|
79855
|
+
text: buildSpaceJoinMembershipOnlyMessage({
|
|
79856
|
+
atsProfile: input.atsProfile,
|
|
79857
|
+
reasonCodes: ["profile.unbound"]
|
|
79858
|
+
})
|
|
79859
|
+
});
|
|
79860
|
+
emittedMembershipOnlyGuidance = true;
|
|
79861
|
+
}
|
|
79862
|
+
const shouldManageServiceParticipation = serviceRequirement === "offer_service_gate";
|
|
79461
79863
|
const runPreflight = async () => await emitSpaceCommandPreflight({
|
|
79462
79864
|
presenter: input.presenter,
|
|
79463
79865
|
command: "join",
|
|
79464
79866
|
profile: input.atsProfile,
|
|
79465
79867
|
baseUrl: input.baseUrl,
|
|
79466
|
-
resolvedView: input.resolvedView
|
|
79467
|
-
});
|
|
79468
|
-
let preflight = await runPreflight();
|
|
79469
|
-
const blockingLocalServiceOutcome = await maybeHandleBlockingLocalServiceAttentionBeforeSpaceJoin({
|
|
79470
|
-
localDemand: input.localDemand ?? null,
|
|
79471
|
-
preflight,
|
|
79472
|
-
presenter: input.presenter,
|
|
79473
79868
|
resolvedView: input.resolvedView,
|
|
79474
|
-
|
|
79869
|
+
humanServiceGuidanceMode: shouldManageServiceParticipation || serviceRequirement === "not_needed" ? "suppress" : "show"
|
|
79475
79870
|
});
|
|
79476
|
-
|
|
79477
|
-
if (
|
|
79478
|
-
|
|
79479
|
-
|
|
79480
|
-
|
|
79871
|
+
let preflight = await runPreflight();
|
|
79872
|
+
if (shouldManageServiceParticipation) {
|
|
79873
|
+
const gateResult = await runSpaceJoinServiceParticipationGate({
|
|
79874
|
+
allowPrompt: input.allowPrompt,
|
|
79875
|
+
explicitLocalAgentProfile,
|
|
79876
|
+
gatewayUrl: input.baseUrl,
|
|
79877
|
+
localDemand: input.localDemand,
|
|
79481
79878
|
presenter: input.presenter,
|
|
79879
|
+
resolvedView: input.resolvedView,
|
|
79880
|
+
serviceIntent: input.serviceIntent,
|
|
79482
79881
|
view: input.view
|
|
79483
|
-
})
|
|
79484
|
-
if (
|
|
79485
|
-
|
|
79882
|
+
});
|
|
79883
|
+
if (gateResult.status === "cancelled") return "cancelled";
|
|
79884
|
+
preflight = await emitSpaceCommandPreflight({
|
|
79885
|
+
presenter: input.presenter,
|
|
79886
|
+
command: "join",
|
|
79887
|
+
profile: input.atsProfile,
|
|
79888
|
+
baseUrl: input.baseUrl,
|
|
79889
|
+
resolvedView: input.resolvedView,
|
|
79890
|
+
humanServiceGuidanceMode: "suppress",
|
|
79891
|
+
emitOutput: false
|
|
79892
|
+
});
|
|
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
|
+
}
|
|
79486
79900
|
}
|
|
79487
|
-
|
|
79488
|
-
|
|
79489
|
-
|
|
79901
|
+
const blockedJoinResult = handleBlockedSpaceJoinLocalParticipation({
|
|
79902
|
+
atsProfile: input.atsProfile,
|
|
79903
|
+
explicitLocalAgentProfile,
|
|
79904
|
+
preflight,
|
|
79490
79905
|
presenter: input.presenter,
|
|
79491
|
-
|
|
79906
|
+
serviceRequirement,
|
|
79907
|
+
emittedMembershipOnlyGuidance,
|
|
79908
|
+
emittedServiceGuidance
|
|
79492
79909
|
});
|
|
79910
|
+
if (blockedJoinResult) return blockedJoinResult;
|
|
79911
|
+
if (preflight.deviceReplyReadiness.replyReadiness === "blocked") throw new Error(preflight.deviceReplyReadiness.reasonText);
|
|
79912
|
+
return "continue";
|
|
79493
79913
|
}
|
|
79494
|
-
|
|
79495
|
-
|
|
79496
|
-
|
|
79497
|
-
|
|
79498
|
-
|
|
79499
|
-
|
|
79500
|
-
|
|
79501
|
-
|
|
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",
|
|
79502
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,
|
|
79503
79936
|
view: input.view
|
|
79504
|
-
}) ? "recovered" : "continue_without_service";
|
|
79505
|
-
}
|
|
79506
|
-
function isBlockingLocalServiceJoinAttention(preflight) {
|
|
79507
|
-
const { deviceReplyReadiness } = preflight;
|
|
79508
|
-
return deviceReplyReadiness.replyReadiness === "blocked" && deviceReplyReadiness.reasonCodes.length > 0 && deviceReplyReadiness.reasonCodes.every((reasonCode) => LOCAL_SERVICE_ONLY_JOIN_BLOCK_REASON_CODES.has(reasonCode));
|
|
79509
|
-
}
|
|
79510
|
-
async function maybeOfferDaemonRepairBeforeSpaceJoin(input) {
|
|
79511
|
-
if (!isHumanInteractiveJoinRuntime(await resolveRuntimeContext({ view: input.view }))) return false;
|
|
79512
|
-
if (input.localDemand?.decision !== "keep_running") return false;
|
|
79513
|
-
return await runDaemonBackgroundStartForDecision({ view: input.view }) === "started";
|
|
79514
|
-
}
|
|
79515
|
-
async function maybeOfferDaemonStartBeforeSpaceJoin(input) {
|
|
79516
|
-
const runtime = await resolveRuntimeContext({ view: input.view });
|
|
79517
|
-
if (runtime.resolvedView !== "human" || !canUseInteractivePrompts(runtime)) return false;
|
|
79518
|
-
if (input.localDemand?.decision !== "keep_running") return false;
|
|
79519
|
-
const daemonStatus = await getDaemonStatus().catch(() => NOT_INSTALLED_DAEMON_STATUS);
|
|
79520
|
-
if (!daemonStatus.installed) return false;
|
|
79521
|
-
const runtimeState = await resolveDaemonRuntimeState(daemonStatus);
|
|
79522
|
-
if (!runtimeState) return false;
|
|
79523
|
-
const { serviceManagerStatus } = await resolveDaemonServiceManagerForRuntimeState({
|
|
79524
|
-
runtimeState,
|
|
79525
|
-
status: daemonStatus
|
|
79526
79937
|
});
|
|
79527
|
-
|
|
79528
|
-
|
|
79529
|
-
|
|
79530
|
-
|
|
79531
|
-
|
|
79532
|
-
|
|
79533
|
-
|
|
79534
|
-
|
|
79535
|
-
|
|
79536
|
-
|
|
79537
|
-
codePrefix: "space.join.service.deferred",
|
|
79538
|
-
rows: card.rows
|
|
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
|
+
})
|
|
79539
79948
|
});
|
|
79540
|
-
return
|
|
79949
|
+
return "continue";
|
|
79541
79950
|
}
|
|
79542
|
-
if (
|
|
79543
|
-
|
|
79544
|
-
|
|
79545
|
-
|
|
79546
|
-
presenter: input.presenter,
|
|
79547
|
-
title: card.title,
|
|
79548
|
-
codePrefix: "space.join.service.failed",
|
|
79549
|
-
rows: card.rows
|
|
79951
|
+
if (input.serviceRequirement === "not_needed") {
|
|
79952
|
+
input.presenter.line({
|
|
79953
|
+
code: "space.join.service.not_needed",
|
|
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`."
|
|
79550
79955
|
});
|
|
79551
|
-
return
|
|
79956
|
+
return "continue";
|
|
79552
79957
|
}
|
|
79553
|
-
|
|
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
|
+
});
|
|
79962
|
+
return "continue";
|
|
79963
|
+
}
|
|
79964
|
+
function isBlockingLocalParticipationJoinAttention(preflight) {
|
|
79965
|
+
const { deviceReplyReadiness } = preflight;
|
|
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\`.`;
|
|
79554
79977
|
}
|
|
79555
79978
|
function buildJoinTargetMissingMessage(input) {
|
|
79556
79979
|
return formatMessage(input.resolvedView, "space.target.missing", { command: "join" });
|
|
@@ -79902,14 +80325,15 @@ function normalizeSpaceJoinMembershipCandidate(value) {
|
|
|
79902
80325
|
ownerProfileName: normalizeOptionalString$2(candidate.ownerProfileName),
|
|
79903
80326
|
ownerUserId: normalizeOptionalString$2(candidate.ownerUserId),
|
|
79904
80327
|
ownerName: normalizeOptionalString$2(candidate.ownerName),
|
|
79905
|
-
controllerRef: normalizeOptionalString$2(candidate.controllerRef)
|
|
80328
|
+
controllerRef: normalizeOptionalString$2(candidate.controllerRef),
|
|
80329
|
+
controllerEnabled: candidate.controllerEnabled === true
|
|
79906
80330
|
};
|
|
79907
80331
|
}
|
|
79908
80332
|
function resolveSpaceJoinMembershipProfileKind(value) {
|
|
79909
80333
|
return value === "human" || value === "agent" ? value : null;
|
|
79910
80334
|
}
|
|
79911
80335
|
function normalizeOptionalString$2(value) {
|
|
79912
|
-
return typeof value === "string" ? value :
|
|
80336
|
+
return typeof value === "string" ? value : void 0;
|
|
79913
80337
|
}
|
|
79914
80338
|
function buildLocallyCreatedPendingSpaceJoinMembershipCandidate(profile) {
|
|
79915
80339
|
return {
|
|
@@ -79918,8 +80342,9 @@ function buildLocallyCreatedPendingSpaceJoinMembershipCandidate(profile) {
|
|
|
79918
80342
|
profileName: profile.profileName,
|
|
79919
80343
|
profileKind: profile.profileKind === "agent" ? "agent" : "human",
|
|
79920
80344
|
ownerUserId: profile.ownerUserId,
|
|
79921
|
-
ownerName: typeof profile.ownerName === "string" ? profile.ownerName :
|
|
79922
|
-
controllerRef: profile.controllerBinding?.controllerRef
|
|
80345
|
+
ownerName: typeof profile.ownerName === "string" ? profile.ownerName : void 0,
|
|
80346
|
+
controllerRef: profile.controllerBinding?.controllerRef,
|
|
80347
|
+
controllerEnabled: profile.controllerBinding?.controllerEnabled === true,
|
|
79923
80348
|
alreadyJoined: false,
|
|
79924
80349
|
needsActivation: false
|
|
79925
80350
|
};
|
|
@@ -80131,9 +80556,16 @@ async function applySelectedSpaceAddMembersBeforeJoin(input, dependencies) {
|
|
|
80131
80556
|
});
|
|
80132
80557
|
}
|
|
80133
80558
|
if (confirmedCandidates.candidates.length === 0) return "completed";
|
|
80134
|
-
const
|
|
80559
|
+
const servicePreparationResult = await dependencies.prepareSpaceMemberCandidatesLocalParticipation({
|
|
80135
80560
|
actorProfile: input.actorProfile,
|
|
80136
80561
|
candidates: confirmedCandidates.candidates,
|
|
80562
|
+
presenter: input.presenter,
|
|
80563
|
+
resolvedView: input.resolvedView
|
|
80564
|
+
});
|
|
80565
|
+
if (servicePreparationResult.status === "cancelled") return input.cancelResult;
|
|
80566
|
+
const result = await dependencies.applySpaceAddMembers({
|
|
80567
|
+
actorProfile: input.actorProfile,
|
|
80568
|
+
candidates: servicePreparationResult.candidates,
|
|
80137
80569
|
space: input.space,
|
|
80138
80570
|
baseUrl: input.baseUrl,
|
|
80139
80571
|
password: input.password
|
|
@@ -80149,7 +80581,7 @@ async function applySelectedSpaceAddMembersBeforeJoin(input, dependencies) {
|
|
|
80149
80581
|
presenter: input.presenter,
|
|
80150
80582
|
resolvedView: input.resolvedView,
|
|
80151
80583
|
space: input.space,
|
|
80152
|
-
selectedCount:
|
|
80584
|
+
selectedCount: servicePreparationResult.candidates.length,
|
|
80153
80585
|
result,
|
|
80154
80586
|
joinNoticeSummary
|
|
80155
80587
|
});
|
|
@@ -80659,6 +81091,7 @@ function buildPostCreateJoinRequest(input) {
|
|
|
80659
81091
|
...typeof input.postCreateJoin?.mentionAlias === "string" ? { mentionAlias: input.postCreateJoin.mentionAlias } : {},
|
|
80660
81092
|
...typeof input.postCreateJoin?.rawStream === "boolean" ? { rawStream: input.postCreateJoin.rawStream } : {},
|
|
80661
81093
|
...typeof input.postCreateJoin?.skipBringProfilesPrompt === "boolean" ? { skipBringProfilesPrompt: input.postCreateJoin.skipBringProfilesPrompt } : {},
|
|
81094
|
+
serviceIntent: input.postCreateJoin?.serviceIntent ?? "space_create_join",
|
|
80662
81095
|
entryChecksHandled: true
|
|
80663
81096
|
};
|
|
80664
81097
|
}
|
|
@@ -80688,7 +81121,8 @@ async function runSpaceCreate(input) {
|
|
|
80688
81121
|
command: "create",
|
|
80689
81122
|
profile: atsProfile,
|
|
80690
81123
|
baseUrl,
|
|
80691
|
-
resolvedView: contextRuntime.resolvedView
|
|
81124
|
+
resolvedView: contextRuntime.resolvedView,
|
|
81125
|
+
humanServiceGuidanceMode: isHumanInteractiveSpaceRuntime(contextRuntime) ? "suppress" : "show"
|
|
80692
81126
|
});
|
|
80693
81127
|
await ensureSpaceCreateAuthReady({ baseUrl });
|
|
80694
81128
|
const createInput = await resolveSpaceCreateInput({
|
|
@@ -81788,9 +82222,22 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
81788
82222
|
selectedProfileIds
|
|
81789
82223
|
});
|
|
81790
82224
|
if (selectedCandidates.length === 0) return { status: "completed" };
|
|
82225
|
+
const servicePreparationResult = await ensureSpaceMemberCandidatesLocalParticipationReady({
|
|
82226
|
+
atsProfile: input.atsProfile,
|
|
82227
|
+
candidates: selectedCandidates,
|
|
82228
|
+
presenter: input.presenter,
|
|
82229
|
+
resolvedView: input.runtime.resolvedView,
|
|
82230
|
+
allowPrompt: input.allowPrompt,
|
|
82231
|
+
view: input.view
|
|
82232
|
+
});
|
|
82233
|
+
if (servicePreparationResult.status === "cancelled") return input.allowBackToCaller ? {
|
|
82234
|
+
status: "repeat_target",
|
|
82235
|
+
authenticatedGatewayUrl
|
|
82236
|
+
} : { status: "cancelled" };
|
|
82237
|
+
const preparedCandidates = servicePreparationResult.candidates;
|
|
81791
82238
|
const result = await applySpaceAddMembers({
|
|
81792
82239
|
actorProfile: input.atsProfile,
|
|
81793
|
-
candidates:
|
|
82240
|
+
candidates: preparedCandidates,
|
|
81794
82241
|
space: input.target.space,
|
|
81795
82242
|
baseUrl: targetBaseUrl,
|
|
81796
82243
|
password: input.password
|
|
@@ -81806,7 +82253,7 @@ async function runSpaceAddMembersForTarget(input) {
|
|
|
81806
82253
|
presenter: input.presenter,
|
|
81807
82254
|
resolvedView: input.runtime.resolvedView,
|
|
81808
82255
|
space: input.target.space,
|
|
81809
|
-
selectedCount:
|
|
82256
|
+
selectedCount: preparedCandidates.length,
|
|
81810
82257
|
result,
|
|
81811
82258
|
joinNoticeSummary
|
|
81812
82259
|
});
|
|
@@ -81894,6 +82341,159 @@ async function runSpaceRemoveMembersForTarget(input) {
|
|
|
81894
82341
|
function resolveSelectedSpaceMemberCandidates(input) {
|
|
81895
82342
|
return input.selectedProfileIds.map((profileId) => input.candidates.find((candidate) => candidate.profileId === profileId)).filter((candidate) => Boolean(candidate));
|
|
81896
82343
|
}
|
|
82344
|
+
async function ensureSpaceMemberCandidatesLocalParticipationReady(input) {
|
|
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({
|
|
82370
|
+
intent: "space_add_members",
|
|
82371
|
+
humanOnlyParticipation: !explicitSelectedLocalAgents,
|
|
82372
|
+
explicitSelectedLocalAgents,
|
|
82373
|
+
selectedAgentProfilesHaveRunnableLocalSetup: haveAllExplicitLocalAgentCandidatesRunnable(wakeableLocalCandidates),
|
|
82374
|
+
localDemand: input.resolvedView === "human" ? await resolveDaemonLocalServiceDemand({ ownerUserId: input.atsProfile.ownerUserId }).catch(() => null) : null
|
|
82375
|
+
}) === "not_needed") return {
|
|
82376
|
+
status: "continue",
|
|
82377
|
+
candidates: preparedCandidates
|
|
82378
|
+
};
|
|
82379
|
+
if (!(input.resolvedView === "human" && input.allowPrompt)) {
|
|
82380
|
+
input.presenter.line({
|
|
82381
|
+
code: "space.add_members.service.deferred",
|
|
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`."
|
|
82383
|
+
});
|
|
82384
|
+
return {
|
|
82385
|
+
status: "continue",
|
|
82386
|
+
candidates: preparedCandidates
|
|
82387
|
+
};
|
|
82388
|
+
}
|
|
82389
|
+
const gateResult = await runDaemonServiceParticipationGate({
|
|
82390
|
+
intent: "space_add_members",
|
|
82391
|
+
presenter: input.presenter,
|
|
82392
|
+
resolvedView: input.resolvedView,
|
|
82393
|
+
allowPrompt: input.allowPrompt,
|
|
82394
|
+
gatewayUrl: input.gatewayUrl,
|
|
82395
|
+
localDemand: await resolveDaemonLocalServiceDemand({ ownerUserId: input.atsProfile.ownerUserId }).catch(() => null),
|
|
82396
|
+
forcePrompt: explicitSelectedLocalAgents,
|
|
82397
|
+
view: input.view
|
|
82398
|
+
});
|
|
82399
|
+
if (gateResult.status === "cancelled") return { status: "cancelled" };
|
|
82400
|
+
if (gateResult.status !== "aligned") input.presenter.line({
|
|
82401
|
+
code: "space.add_members.service.declined",
|
|
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`."
|
|
82403
|
+
});
|
|
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?`;
|
|
82496
|
+
}
|
|
81897
82497
|
async function runSpaceJoin(input) {
|
|
81898
82498
|
let failureRuntime = null;
|
|
81899
82499
|
let failurePresenter = null;
|
|
@@ -81934,7 +82534,8 @@ async function runSpaceJoin(input) {
|
|
|
81934
82534
|
role: input.role,
|
|
81935
82535
|
roleInstructions: input.roleInstructions,
|
|
81936
82536
|
mentionAlias: input.mentionAlias,
|
|
81937
|
-
rawStream: input.rawStream === true
|
|
82537
|
+
rawStream: input.rawStream === true,
|
|
82538
|
+
serviceIntent: input.serviceIntent ?? "space_join"
|
|
81938
82539
|
});
|
|
81939
82540
|
} catch (error) {
|
|
81940
82541
|
const runtime = failureRuntime ?? await resolveRuntimeContext({
|
|
@@ -81981,7 +82582,8 @@ async function runSpaceJoinTargetLoop(input) {
|
|
|
81981
82582
|
rawStream: input.rawStream,
|
|
81982
82583
|
skipBringProfilesPrompt: input.skipBringProfilesPrompt,
|
|
81983
82584
|
output: input.output,
|
|
81984
|
-
view: input.view
|
|
82585
|
+
view: input.view,
|
|
82586
|
+
serviceIntent: "space_create_join"
|
|
81985
82587
|
}
|
|
81986
82588
|
});
|
|
81987
82589
|
}
|
|
@@ -81993,14 +82595,16 @@ async function runSpaceJoinTargetLoop(input) {
|
|
|
81993
82595
|
space: target.space
|
|
81994
82596
|
}), "reading an existing local space config before join");
|
|
81995
82597
|
const targetBaseUrl = input.hasExplicitBaseUrlInput ? input.baseUrl : target.baseUrl ?? input.baseUrl;
|
|
81996
|
-
await assertSpaceJoinTargetPreflightReady({
|
|
82598
|
+
if (await assertSpaceJoinTargetPreflightReady({
|
|
81997
82599
|
atsProfile: input.atsProfile,
|
|
81998
82600
|
baseUrl: targetBaseUrl,
|
|
82601
|
+
allowPrompt: input.canPromptPreJoinActions,
|
|
81999
82602
|
localDemand: input.localDemand,
|
|
82000
82603
|
presenter: input.presenter,
|
|
82001
82604
|
resolvedView: input.runtime.resolvedView,
|
|
82605
|
+
serviceIntent: input.serviceIntent,
|
|
82002
82606
|
view: input.view
|
|
82003
|
-
});
|
|
82607
|
+
}) === "cancelled") return "cancelled";
|
|
82004
82608
|
authenticatedGatewayUrl = await ensureSpaceCommandGatewayAuthenticationOrCancel({
|
|
82005
82609
|
runtime: input.runtime,
|
|
82006
82610
|
gatewayUrl: targetBaseUrl,
|
|
@@ -82042,6 +82646,15 @@ async function runSpaceJoinTargetLoop(input) {
|
|
|
82042
82646
|
resolveCreateProfileName,
|
|
82043
82647
|
resolveAgentProfileSetup,
|
|
82044
82648
|
persistAgentTransportSelection,
|
|
82649
|
+
prepareSpaceMemberCandidatesLocalParticipation: async ({ actorProfile, candidates, presenter, resolvedView }) => await ensureSpaceMemberCandidatesLocalParticipationReady({
|
|
82650
|
+
atsProfile: actorProfile,
|
|
82651
|
+
candidates,
|
|
82652
|
+
gatewayUrl: targetBaseUrl,
|
|
82653
|
+
presenter,
|
|
82654
|
+
resolvedView,
|
|
82655
|
+
allowPrompt: input.canPromptPreJoinActions,
|
|
82656
|
+
view: input.view
|
|
82657
|
+
}),
|
|
82045
82658
|
applySpaceAddMembers,
|
|
82046
82659
|
persistSpaceAddMembersJoinNotices,
|
|
82047
82660
|
emitSpaceAddMembersResult
|
|
@@ -83053,6 +83666,8 @@ async function resolveSpaceRemoveMembersTarget(input) {
|
|
|
83053
83666
|
}
|
|
83054
83667
|
async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
83055
83668
|
const profiles = await listAtsProfiles();
|
|
83669
|
+
const localTargetStates = await listAgentTargetStates().catch(() => []);
|
|
83670
|
+
const localTargetStateById = new Map(localTargetStates.map((state) => [state.agentId, state]));
|
|
83056
83671
|
const ownerProfileNameByOwnerUserId = buildOwnerProfileNameByOwnerUserId(profiles);
|
|
83057
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);
|
|
83058
83673
|
if (candidateProfiles.length === 0) return [];
|
|
@@ -83062,24 +83677,55 @@ async function resolveSpaceMemberCandidatesForAdd(input) {
|
|
|
83062
83677
|
...input.password === void 0 ? {} : { spacePassword: input.password }
|
|
83063
83678
|
});
|
|
83064
83679
|
const memberProfileIds = new Set([...membersSnapshot.humans, ...membersSnapshot.agents].map((member) => member.profileId));
|
|
83065
|
-
return candidateProfiles.map((profile) => {
|
|
83066
|
-
|
|
83067
|
-
|
|
83068
|
-
|
|
83069
|
-
|
|
83070
|
-
|
|
83071
|
-
ownerProfileName: ownerProfileNameByOwnerUserId.get(profile.ownerUserId),
|
|
83072
|
-
ownerUserId: profile.ownerUserId,
|
|
83073
|
-
ownerName: profile.ownerName,
|
|
83074
|
-
controllerRef: profile.controllerBinding?.controllerRef,
|
|
83075
|
-
alreadyJoined: memberProfileIds.has(profile.atsProfileId),
|
|
83076
|
-
needsActivation: false
|
|
83077
|
-
};
|
|
83078
|
-
}).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) => {
|
|
83079
83686
|
const byName = left.profileName.localeCompare(right.profileName);
|
|
83080
83687
|
if (byName !== 0) return byName;
|
|
83081
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
|
|
83082
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;
|
|
83083
83729
|
}
|
|
83084
83730
|
async function resolveSpaceMemberCandidatesForRemove(input) {
|
|
83085
83731
|
const membersSnapshot = await createCliSpaceApi(input.baseUrl).getMembersSnapshot({
|
|
@@ -83429,6 +84075,7 @@ async function applySpaceAddMembers(input) {
|
|
|
83429
84075
|
return result;
|
|
83430
84076
|
}
|
|
83431
84077
|
function emitSpaceAddMembersResult(input) {
|
|
84078
|
+
const localParticipationFollowUps = input.result.added.map((candidate) => buildSpaceMemberJoinedFollowUp(candidate)).filter((followUp) => followUp !== null);
|
|
83432
84079
|
if (input.resolvedView === "agent") {
|
|
83433
84080
|
input.presenter.data({
|
|
83434
84081
|
code: "space.add_members",
|
|
@@ -83449,7 +84096,11 @@ function emitSpaceAddMembersResult(input) {
|
|
|
83449
84096
|
recordedCount: input.joinNoticeSummary.recordedCount,
|
|
83450
84097
|
failedCount: input.joinNoticeSummary.failedCount,
|
|
83451
84098
|
...input.joinNoticeSummary.firstFailure ? { firstFailure: input.joinNoticeSummary.firstFailure } : {}
|
|
83452
|
-
}
|
|
84099
|
+
},
|
|
84100
|
+
localParticipationFollowUps: localParticipationFollowUps.map((followUp) => ({
|
|
84101
|
+
profileId: followUp.profileId,
|
|
84102
|
+
message: followUp.text
|
|
84103
|
+
}))
|
|
83453
84104
|
}
|
|
83454
84105
|
});
|
|
83455
84106
|
return;
|
|
@@ -83467,6 +84118,10 @@ function emitSpaceAddMembersResult(input) {
|
|
|
83467
84118
|
sanitize: true,
|
|
83468
84119
|
minContentWidth: 56
|
|
83469
84120
|
});
|
|
84121
|
+
for (const followUp of localParticipationFollowUps) input.presenter.line({
|
|
84122
|
+
code: "space.add_members.local_participation_follow_up",
|
|
84123
|
+
text: followUp.text
|
|
84124
|
+
});
|
|
83470
84125
|
if (input.result.failed.length > 0) for (const failure of input.result.failed) input.presenter.line({
|
|
83471
84126
|
code: "space.add_members.failed",
|
|
83472
84127
|
text: `${failure.candidate.profileId}: ${toErrorMessage$2(failure.error)}`
|
|
@@ -83486,6 +84141,22 @@ function emitSpaceAddMembersResult(input) {
|
|
|
83486
84141
|
firstFailure: input.joinNoticeSummary.firstFailure
|
|
83487
84142
|
});
|
|
83488
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
|
+
}
|
|
83489
84160
|
async function applySpaceRemoveMembers(input) {
|
|
83490
84161
|
const result = {
|
|
83491
84162
|
removed: [],
|
|
@@ -83826,7 +84497,7 @@ function formatSpaceMemberCandidateLabel(candidate) {
|
|
|
83826
84497
|
function formatSpaceMemberCandidateHint(candidate) {
|
|
83827
84498
|
if (candidate.alreadyJoined) return "Already in this space";
|
|
83828
84499
|
if (candidate.needsActivation) return "Needs mention setup";
|
|
83829
|
-
return "Selectable";
|
|
84500
|
+
return resolveSpaceMemberCandidateStatusLabel(candidate) ?? "Selectable";
|
|
83830
84501
|
}
|
|
83831
84502
|
function buildHumanSpaceMemberCandidateSearchItem(candidate) {
|
|
83832
84503
|
return {
|
|
@@ -83838,10 +84509,12 @@ function buildHumanSpaceMemberCandidateSearchItem(candidate) {
|
|
|
83838
84509
|
};
|
|
83839
84510
|
}
|
|
83840
84511
|
function buildHumanSpaceMemberCandidateDetail(candidate) {
|
|
83841
|
-
|
|
83842
|
-
if (candidate.alreadyJoined === true)
|
|
83843
|
-
else if (candidate.needsActivation)
|
|
83844
|
-
|
|
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)}`;
|
|
83845
84518
|
}
|
|
83846
84519
|
function buildHumanSpaceMemberCandidateSearchText(candidate) {
|
|
83847
84520
|
return [
|
|
@@ -83852,10 +84525,26 @@ function buildHumanSpaceMemberCandidateSearchText(candidate) {
|
|
|
83852
84525
|
sanitizeSingleLinePromptText(normalizeOptionalString$1(candidate.ownerName)),
|
|
83853
84526
|
sanitizeSingleLinePromptText(normalizeOptionalString$1(candidate.ownerUserId)),
|
|
83854
84527
|
sanitizeSingleLinePromptText(normalizeOptionalString$1(candidate.controllerRef)),
|
|
84528
|
+
...resolveSpaceMemberCandidateStatusBadges(candidate),
|
|
83855
84529
|
candidate.alreadyJoined ? "already in this space" : null,
|
|
83856
84530
|
candidate.needsActivation ? "needs mention setup" : null
|
|
83857
84531
|
].filter((value) => typeof value === "string").join("\n");
|
|
83858
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
|
+
}
|
|
83859
84548
|
function normalizeRequestedMemberIds(value) {
|
|
83860
84549
|
if (!Array.isArray(value)) return [];
|
|
83861
84550
|
const ids = [];
|
|
@@ -87071,11 +87760,13 @@ async function runStart(input) {
|
|
|
87071
87760
|
const presenter = createPresenter(runtime);
|
|
87072
87761
|
const interactive = canUseInteractivePrompts(runtime);
|
|
87073
87762
|
if (interactive && runtime.resolvedView === "human") intro(`\n${renderAtsHeader()}`);
|
|
87074
|
-
if (!
|
|
87075
|
-
|
|
87076
|
-
|
|
87077
|
-
|
|
87078
|
-
|
|
87763
|
+
if (!input.entryChecksHandled) {
|
|
87764
|
+
if (!await runStartDisclaimerStep({
|
|
87765
|
+
runtime,
|
|
87766
|
+
presenter,
|
|
87767
|
+
interactive
|
|
87768
|
+
})) return;
|
|
87769
|
+
}
|
|
87079
87770
|
if (input.startSession) {
|
|
87080
87771
|
await runStartHandoff({
|
|
87081
87772
|
...input,
|
|
@@ -87159,6 +87850,7 @@ async function runStart(input) {
|
|
|
87159
87850
|
});
|
|
87160
87851
|
const serviceStepResult = await runStartServiceStep({
|
|
87161
87852
|
foundation,
|
|
87853
|
+
gatewayUrl,
|
|
87162
87854
|
runtime,
|
|
87163
87855
|
presenter,
|
|
87164
87856
|
interactive,
|
|
@@ -91712,7 +92404,8 @@ async function runStartFromCliOptions(opts) {
|
|
|
91712
92404
|
baseUrl: opts.gatewayUrl,
|
|
91713
92405
|
startSession: opts.startSession,
|
|
91714
92406
|
skillsMode: opts.skillsMode,
|
|
91715
|
-
view: opts.view
|
|
92407
|
+
view: opts.view,
|
|
92408
|
+
entryChecksHandled: true
|
|
91716
92409
|
});
|
|
91717
92410
|
}
|
|
91718
92411
|
function withSpaceProfileOption(cmd) {
|