@cotal-ai/cli 0.155.0 → 0.155.1

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.
@@ -1,8 +1,8 @@
1
- import { accessSync, constants, existsSync } from "node:fs";
1
+ import { accessSync, constants, existsSync, lstatSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { CotalEndpoint, agentFilePath, dialerFor, EpEnvelopeError, formatAge, isReachable, mintCreds, mintLifecycleUid, resolveService, realDirNoSymlink, invokeRepairingSplit, standaloneConnectOpts, newIdentity, idFromCreds, principalKey, DEV_OWNER, unansweredRequest, resolveAuthProvider, personaDir, presenceText, } from "@cotal-ai/core";
5
- import { stoppedLoopbackListener, accountInventory, assessMaintenanceClaim, authDir, isCommandFailure, readMaintenanceJournal, recordsElsewhereError, recordsElsewhereText, restoreRolledBackRuns, targetErrorSpace, brokerAddressForDisplay, brokerCheck, canonicalRoot, CLI_USER_ACTOR, codeSpan, CommandFailure, deliveryCredsKey, DELIVERY_PIDFILE, extensionsDir, findCotalRoot, folderSpaceOverSelection, meshesForRoot, resolveReadsLiveness, stoppedStack, unsettledStackOperation, withdrawOperationNote, hasUserAuthState, homeCotalDir, cachedPreferences, loadLaunchPersonaFile, resolvePreference, isMeshRegistryError, isWorkspaceTargetError, jsonFlag, loadManagerInstanceIdentity, loadSoleSpaceAuth, localProcessPath, localProcessVisible, MANAGER_PIDFILE, oneLine, PREFERENCE_KEYS, parsePid, plainFlag, preflightTarget, presentationOf, principalFromBearer, probeLiveness, probeWebReadiness, readCurrent, readMeshRegistry, readPidfile, preparedRecordSkipped, readPreparedSpaces, readRenewalRecord, renderWorkspaceError, resolveMeshTarget, serverFlag, spaceFlag, userAuthStateDir, WEB_PIDFILE, WEB_READINESS_HEADER, workspaceSecretStore, writeResult, workspaceErrorParts, preferencesPath, preferencesFolderWarning, cotalDirLink, movedProject, spaceStreamsAbsent, spaceStreamsExpected, resolveControlTarget, } from "@cotal-ai/workspace";
5
+ import { stoppedLoopbackListener, accountInventory, assessMaintenanceClaim, authDir, isCommandFailure, readMaintenanceJournal, recordsElsewhereError, recordsElsewhereText, restoreRolledBackRuns, targetErrorSpace, brokerAddressForDisplay, brokerCheck, canonicalRoot, CLI_USER_ACTOR, codeSpan, CommandFailure, deliveryCredsKey, DELIVERY_PIDFILE, extensionsDir, findCotalRoot, folderSpaceOverSelection, meshesForRoot, resolveReadsLiveness, stoppedStack, unsettledStackOperation, withdrawOperationNote, hasUserAuthState, homeCotalDir, cachedPreferences, loadLaunchPersonaFile, resolvePreference, isMeshRegistryError, isWorkspaceTargetError, jsonFlag, loadManagerInstanceIdentity, loadSoleSpaceAuth, localProcessPath, localProcessVisible, MANAGER_PIDFILE, oneLine, PREFERENCE_KEYS, parsePid, plainFlag, preflightTarget, presentationOf, principalFromBearer, probeLiveness, probeWebReadiness, readCurrent, readMeshRegistry, readPidfile, preparedRecordSkipped, readPreparedSpaces, stackJournalPath, readRenewalRecord, renderWorkspaceError, resolveMeshTarget, serverFlag, spaceFlag, userAuthStateDir, WEB_PIDFILE, WEB_READINESS_HEADER, workspaceSecretStore, writeResult, workspaceErrorParts, preferencesPath, preferencesFolderWarning, cotalDirLink, movedProject, spaceStreamsAbsent, spaceStreamsExpected, resolveControlTarget, } from "@cotal-ai/workspace";
6
6
  import { localProcessSurface } from "../ext-loader.js";
7
7
  import { cliVersion, cliProvenance, readExtensionVersions } from "../lib/version.js";
8
8
  import { agentSkillsSkew } from "../lib/agent-skills.js";
@@ -239,7 +239,7 @@ function folderReadProblem(root) {
239
239
  /** The folder section for a folder this account cannot read: every part of it is unread. */
240
240
  function unreadFolder(root, code) {
241
241
  const error = `${root} cannot be read by this account (${code})`;
242
- return { root, auth: { state: "unreadable", spaces: [], userAuth: false, error }, personas: { root: personaDir(root), default: "unreadable", demo: null, error }, launches: null, processes: null, processSpace: null, storedState: false, controllerStack: false, noManager: false, stackBlock: null };
242
+ return { root, auth: { state: "unreadable", spaces: [], userAuth: false, error }, personas: { root: personaDir(root), default: "unreadable", demo: null, error }, launches: null, processes: null, processSpace: null, storedState: false, controllerStack: false, stackJournal: "unreadable", noManager: false, stackBlock: null };
243
243
  }
244
244
  /** The folder's maintenance journal, read only. An unreadable one is reported, never taken for none. */
245
245
  function readMaintenance(root, gaps) {
@@ -549,6 +549,13 @@ async function readResponderAxis(selected, preflight) {
549
549
  }
550
550
  async function readFolder(root, selected, values, responder, gaps, hints) {
551
551
  const cmd = displayCmd();
552
+ let stackJournal;
553
+ try {
554
+ stackJournal = lstatSync(stackJournalPath(root), { throwIfNoEntry: false }) === undefined ? "absent" : "present";
555
+ }
556
+ catch {
557
+ stackJournal = "unreadable";
558
+ }
552
559
  const folder = (auth, processes = null, storedState = false, processSpace = null, controllerStack = false, noManager = false, stackBlock = null, stackUnfinished = null) => ({
553
560
  root,
554
561
  auth,
@@ -557,6 +564,7 @@ async function readFolder(root, selected, values, responder, gaps, hints) {
557
564
  processSpace,
558
565
  storedState,
559
566
  controllerStack,
567
+ stackJournal,
560
568
  noManager,
561
569
  stackBlock,
562
570
  stackUnfinished,
@@ -1009,9 +1017,10 @@ async function readMeshes(cwd, selected, all, gaps, offline, preflight) {
1009
1017
  catalog: m.origin === "catalog" ? { name: m.catalogName && m.catalogName !== m.space ? m.catalogName : null, fetchedAt: m.catalogFetchedAt ?? null, error: m.catalogError ?? null } : null,
1010
1018
  })));
1011
1019
  // The prepared spaces folder, or a record in it, that cannot be read is named the same way.
1012
- let currentPrepared = false, currentStopped = false;
1020
+ let currentPrepared = false, currentStopped = false, hasPrepared = false;
1013
1021
  try {
1014
1022
  const prepared = readPreparedSpaces();
1023
+ hasPrepared = prepared.spaces.length > 0;
1015
1024
  // Named with the warning a command that skips it gives, so a run that also skipped it says it once.
1016
1025
  for (const e of prepared.unusable) {
1017
1026
  const skipped = preparedRecordSkipped(e);
@@ -1031,6 +1040,7 @@ async function readMeshes(cwd, selected, all, gaps, offline, preflight) {
1031
1040
  current,
1032
1041
  currentRecorded: current === null || entries.some((m) => m.space === current),
1033
1042
  currentPrepared,
1043
+ hasPrepared,
1034
1044
  currentStopped,
1035
1045
  folder,
1036
1046
  unreadable,
@@ -1609,7 +1619,8 @@ function extensionsCell(e) {
1609
1619
  * does not have is what `cotal setup` adds, which the applications line already counts. So an
1610
1620
  * application's own rows (the Claude plugin, Desktop and skills) appear only for an application that
1611
1621
  * IS set up, and only when they are not current; the broker executable appears when it is missing or
1612
- * refused; the dashboard, which is optional, appears when its record cannot be read. `--all` and
1622
+ * refused and local broker records make it relevant; the dashboard, which is optional, appears
1623
+ * when its record cannot be read. `--all` and
1613
1624
  * `--wide` print every row, and `--verbose` adds the installation paths ({@link machineSection}).
1614
1625
  *
1615
1626
  * It used to print one row per known connector whether or not it was set up, every extension label
@@ -1632,7 +1643,15 @@ function machineOverview(r, wide) {
1632
1643
  continue;
1633
1644
  rows.push([connector.name, stateCell(connector.missing.length ? `${connector.missing.join(", ")} not on PATH` : connector.requires.length ? "available on PATH" : "in-process", connector.missing.length ? "waiting" : "ok")]);
1634
1645
  }
1635
- if (wide || m.nats === "missing" || m.natsProblem)
1646
+ // A remote registration uses the broker elsewhere. Keep executable readiness in the full
1647
+ // diagnostics, without making a hosted client repair a binary it does not need to run.
1648
+ const localBroker = r.meshes.hasPrepared || r.meshes.currentPrepared || r.meshes.unreadable.length > 0 ||
1649
+ r.meshes.items.some((entry) => entry.origin !== "manual" && entry.origin !== "catalog") ||
1650
+ r.folder.controllerStack || r.folder.storedState || r.folder.auth.state !== "none" ||
1651
+ (r.folder.stackJournal !== undefined && r.folder.stackJournal !== "absent") ||
1652
+ r.folder.processes?.some((row) => row.name === "nats" && (row.pid !== null || row.state === "unreadable")) ||
1653
+ (!r.selected.resolved && (r.selected.code === "not-started" || r.selected.code === "unregistered-root" || r.selected.code === "unreadable-auth"));
1654
+ if (wide || (localBroker && (m.nats === "missing" || m.natsProblem)))
1636
1655
  rows.push(["Broker executable", stateCell(m.nats === "missing" ? "not installed" : brokerExecutable(m), m.nats === "missing" ? "waiting" : m.natsProblem ? "failed" : "ok")]);
1637
1656
  if (wide || (m.skills.state !== "current" && setUp.length))
1638
1657
  rows.push(["Agent skills", skillsCell(m.skills)]);