@cotal-ai/workspace 0.10.1 → 0.11.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.
Files changed (44) hide show
  1. package/dist/agent-health.d.ts +20 -0
  2. package/dist/agent-health.d.ts.map +1 -0
  3. package/dist/agent-health.js +40 -0
  4. package/dist/agent-health.js.map +1 -0
  5. package/dist/auth-paths.d.ts +6 -0
  6. package/dist/auth-paths.d.ts.map +1 -1
  7. package/dist/auth-paths.js +8 -0
  8. package/dist/auth-paths.js.map +1 -1
  9. package/dist/colors.d.ts +1 -1
  10. package/dist/colors.js +1 -1
  11. package/dist/connect.d.ts +49 -4
  12. package/dist/connect.d.ts.map +1 -1
  13. package/dist/connect.js +155 -7
  14. package/dist/connect.js.map +1 -1
  15. package/dist/extensions.js +1 -1
  16. package/dist/flags.d.ts +15 -0
  17. package/dist/flags.d.ts.map +1 -1
  18. package/dist/flags.js +31 -0
  19. package/dist/flags.js.map +1 -1
  20. package/dist/index.d.ts +2 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +2 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/mesh-registry.d.ts +38 -1
  25. package/dist/mesh-registry.d.ts.map +1 -1
  26. package/dist/mesh-registry.js +44 -2
  27. package/dist/mesh-registry.js.map +1 -1
  28. package/dist/mesh-target.d.ts +10 -2
  29. package/dist/mesh-target.d.ts.map +1 -1
  30. package/dist/mesh-target.js +45 -4
  31. package/dist/mesh-target.js.map +1 -1
  32. package/dist/preflight.d.ts +2 -2
  33. package/dist/preflight.d.ts.map +1 -1
  34. package/dist/preflight.js +11 -0
  35. package/dist/preflight.js.map +1 -1
  36. package/dist/render.d.ts +1 -1
  37. package/dist/render.d.ts.map +1 -1
  38. package/dist/render.js +21 -12
  39. package/dist/render.js.map +1 -1
  40. package/dist/renewal.d.ts +46 -0
  41. package/dist/renewal.d.ts.map +1 -0
  42. package/dist/renewal.js +61 -0
  43. package/dist/renewal.js.map +1 -0
  44. package/package.json +2 -2
@@ -18,10 +18,41 @@ export interface MeshEntry {
18
18
  server: string;
19
19
  /** Absolute path whose `.cotal/{auth,agents}` hold this mesh's trust material + personas. */
20
20
  root: string;
21
- mode: "auth" | "open";
21
+ /** How the broker authenticates: static per-agent JWT creds (`auth`), none (`open`), or
22
+ * per-USER auth (`user`) — login + bearer through the space's auth service. `user` is its own
23
+ * connect path: it must never be treated as `auth` with missing creds, nor as `open`. */
24
+ mode: "auth" | "open" | "user";
25
+ /** The user-auth client metadata, present iff `mode === "user"` — how a connect from any
26
+ * directory on THIS machine finds the login target and exchange. Local operator config, not
27
+ * broker truth: it lives under the user's protected registry dir and is trusted the way the
28
+ * registry itself is; remote/cross-machine discovery is explicitly out of its scope. */
29
+ userAuth?: UserAuthInfo;
22
30
  /** ISO timestamp of when the record was written. */
23
31
  ts: string;
24
32
  }
33
+ /** Non-secret user-auth metadata on a {@link MeshEntry}. TRUST PINS and CONVENIENCE ENDPOINTS are
34
+ * deliberately separate fields: `idp` is what the operator pinned at `up --user-auth` time (the
35
+ * login/exchange trust config — error messages and login guidance use THIS); `endpoints` is where
36
+ * the local auth service happened to bind (runtime, may change across restarts, re-recorded by
37
+ * `up`). Nothing here is ever taken from a presented token or an unauthenticated response. */
38
+ export interface UserAuthInfo {
39
+ /** The registered auth provider's name (registry key, e.g. `"cotal"`). */
40
+ provider: string;
41
+ /** The pinned IdP: the login target (`cotal login --idp <url>`) + exact issuer/audience pins. */
42
+ idp: {
43
+ url: string;
44
+ issuer: string;
45
+ audience: string;
46
+ };
47
+ /** The local auth service's runtime endpoints (exchange/JWKS base URL). Convenience, not trust. */
48
+ endpoints?: {
49
+ url?: string;
50
+ };
51
+ }
52
+ /** Runtime-validate a provider's opaque `publicAuth` blob into a {@link UserAuthInfo} — the
53
+ * workstation layer owns this shape (core stays IdP-agnostic), so the boundary where an
54
+ * arbitrary provider's metadata enters the registry is checked here, fail-loud. */
55
+ export declare function assertUserAuthInfo(v: unknown): UserAuthInfo;
25
56
  /** The cotal machine-home dir, overridable via `COTAL_HOME` so tests sandbox it and never touch the
26
57
  * real one. POSIX: `~/.cotal`. Windows: `%LOCALAPPDATA%\Cotal` — the platform's place for per-user
27
58
  * app state (a dotdir in the profile root is a Unix idiom; `%LOCALAPPDATA%` is already a per-user
@@ -34,6 +65,12 @@ export declare function meshesDir(): string;
34
65
  export declare function recordMesh(m: MeshEntry): void;
35
66
  /** Drop a mesh from the registry (on `cotal down` / a stale-entry prune). Absent ⇒ no-op. */
36
67
  export declare function removeMesh(space: string): void;
68
+ /** Drop every registry entry recorded for THIS project root (realpath-canonical, so symlinked
69
+ * roots like macOS /var match), releasing the `current` pointer per removed entry. The root is
70
+ * the only sound key for a local teardown (`cotal down` / `cotal clean all`): an OPEN mesh has
71
+ * no auth material, so resolving its space NAME falls back to the default space and would
72
+ * delete an unrelated mesh's entry. Returns the removed space names. */
73
+ export declare function removeMeshesByRoot(root: string): string[];
37
74
  /** All currently-recorded meshes. An unparseable/partially-written entry is skipped, not fatal —
38
75
  * one bad file must not hide the rest. */
39
76
  export declare function loadMeshes(): MeshEntry[];
@@ -1 +1 @@
1
- {"version":3,"file":"mesh-registry.d.ts","sourceRoot":"","sources":["../src/mesh-registry.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;6DAI6D;AAC7D,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,yEAAyE;AACzE,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAUD,kGAAkG;AAClG,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAW7C;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;2CAC2C;AAC3C,wBAAgB,UAAU,IAAI,SAAS,EAAE,CAgBxC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAE7D;AAED;;oBAEoB;AACpB,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAM/C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG9C;AAED,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
1
+ {"version":3,"file":"mesh-registry.d.ts","sourceRoot":"","sources":["../src/mesh-registry.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;IACb;;8FAE0F;IAC1F,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAC/B;;;6FAGyF;IACzF,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;+FAI+F;AAC/F,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,mGAAmG;IACnG,SAAS,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9B;AAED;;oFAEoF;AACpF,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,YAAY,CAY3D;AAED;;;;6DAI6D;AAC7D,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,yEAAyE;AACzE,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAUD,kGAAkG;AAClG,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAW7C;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;;;yEAIyE;AACzE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAazD;AAED;2CAC2C;AAC3C,wBAAgB,UAAU,IAAI,SAAS,EAAE,CAgBxC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAE7D;AAED;;oBAEoB;AACpB,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAM/C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG9C;AAED,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
@@ -1,7 +1,23 @@
1
- import { readFileSync, readdirSync, renameSync, rmSync } from "node:fs";
1
+ import { readFileSync, readdirSync, realpathSync, renameSync, rmSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
- import { join } from "node:path";
3
+ import { join, resolve } from "node:path";
4
4
  import { mkSecretDir, writeSecretFile } from "@cotal-ai/core";
5
+ /** Runtime-validate a provider's opaque `publicAuth` blob into a {@link UserAuthInfo} — the
6
+ * workstation layer owns this shape (core stays IdP-agnostic), so the boundary where an
7
+ * arbitrary provider's metadata enters the registry is checked here, fail-loud. */
8
+ export function assertUserAuthInfo(v) {
9
+ const o = v;
10
+ if (o === null || typeof o !== "object" || typeof o.provider !== "string" || !o.provider)
11
+ throw new Error("auth provider publicAuth: a provider name is required");
12
+ if (o.idp === null || typeof o.idp !== "object" || typeof o.idp.url !== "string" || !o.idp.url ||
13
+ typeof o.idp.issuer !== "string" || !o.idp.issuer || typeof o.idp.audience !== "string" || !o.idp.audience)
14
+ throw new Error("auth provider publicAuth: idp { url, issuer, audience } trust pins are required");
15
+ if (o.endpoints !== undefined && (o.endpoints === null || typeof o.endpoints !== "object" ||
16
+ (o.endpoints.url !== undefined && typeof o.endpoints.url !== "string")))
17
+ throw new Error("auth provider publicAuth: endpoints, when present, must be { url?: string }");
18
+ return { provider: o.provider, idp: { url: o.idp.url, issuer: o.idp.issuer, audience: o.idp.audience },
19
+ ...(o.endpoints ? { endpoints: { ...(o.endpoints.url ? { url: o.endpoints.url } : {}) } } : {}) };
20
+ }
5
21
  /** The cotal machine-home dir, overridable via `COTAL_HOME` so tests sandbox it and never touch the
6
22
  * real one. POSIX: `~/.cotal`. Windows: `%LOCALAPPDATA%\Cotal` — the platform's place for per-user
7
23
  * app state (a dotdir in the profile root is a Unix idiom; `%LOCALAPPDATA%` is already a per-user
@@ -41,6 +57,32 @@ export function recordMesh(m) {
41
57
  export function removeMesh(space) {
42
58
  rmSync(meshFile(space), { force: true });
43
59
  }
60
+ /** Drop every registry entry recorded for THIS project root (realpath-canonical, so symlinked
61
+ * roots like macOS /var match), releasing the `current` pointer per removed entry. The root is
62
+ * the only sound key for a local teardown (`cotal down` / `cotal clean all`): an OPEN mesh has
63
+ * no auth material, so resolving its space NAME falls back to the default space and would
64
+ * delete an unrelated mesh's entry. Returns the removed space names. */
65
+ export function removeMeshesByRoot(root) {
66
+ const canonical = (p) => {
67
+ try {
68
+ return realpathSync.native(p);
69
+ }
70
+ catch {
71
+ return resolve(p);
72
+ }
73
+ };
74
+ const rootKey = canonical(root);
75
+ const removed = [];
76
+ for (const m of loadMeshes()) {
77
+ if (canonical(m.root) !== rootKey)
78
+ continue;
79
+ removeMesh(m.space);
80
+ if (getCurrent() === m.space)
81
+ clearCurrent();
82
+ removed.push(m.space);
83
+ }
84
+ return removed;
85
+ }
44
86
  /** All currently-recorded meshes. An unparseable/partially-written entry is skipped, not fatal —
45
87
  * one bad file must not hide the rest. */
46
88
  export function loadMeshes() {
@@ -1 +1 @@
1
- {"version":3,"file":"mesh-registry.js","sourceRoot":"","sources":["../src/mesh-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mesh-registry.js","sourceRoot":"","sources":["../src/mesh-registry.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type SpaceAuth } from "@cotal-ai/core";
2
+ import { type MeshEntry, type UserAuthInfo } from "./mesh-registry.js";
2
3
  /**
3
4
  * One coherent answer to "which mesh does this command act on, and where do its creds + personas
4
5
  * live" — resolved identically for both, so a spawn can never authenticate to mesh A while loading
@@ -13,8 +14,15 @@ export interface MeshTarget {
13
14
  root: string;
14
15
  server: string;
15
16
  space: string;
16
- /** Trust material, or undefined for an open mesh. */
17
+ /** The mesh's auth mode `user` is its OWN connect path (login + bearer), a hard branch:
18
+ * it never static-mints from `auth` and never connects credlessly like `open`. */
19
+ mode: MeshEntry["mode"];
20
+ /** Trust material, for a STATIC-auth mesh only — undefined for open AND for user mode (a
21
+ * user-mode root may still hold `auth.json` on disk; deliberately not loaded here so no caller
22
+ * can drift into minting static creds for a user-auth space). */
17
23
  auth?: SpaceAuth;
24
+ /** User-auth client metadata (from the registry entry), present iff `mode === "user"`. */
25
+ userAuth?: UserAuthInfo;
18
26
  /** `<root>/.cotal/agents` — the persona catalog for this mesh. */
19
27
  personaRoot: string;
20
28
  /** Where the target came from — this also carries OWNERSHIP for pruning. `registry`/`current`/
@@ -35,7 +43,7 @@ export interface ResolveFlags {
35
43
  /** The distinct, command-agnostic reasons {@link resolveMeshTarget} can't pick a single mesh. Each
36
44
  * maps 1:1 to a former prose-throw; the recovery copy (`cotal up`/`meshes`/`use`) is the renderer's
37
45
  * job ({@link renderWorkspaceError}), not the protocol's. */
38
- export type MeshTargetErrorCode = "no-meshes" | "unknown-space" | "ambiguous-target" | "default-occupied" | "stale-auth-root";
46
+ export type MeshTargetErrorCode = "no-meshes" | "unknown-space" | "ambiguous-target" | "default-occupied" | "stale-auth-root" | "user-auth-unrecorded";
39
47
  /** Structured context for a {@link MeshTargetError} — enough for any surface to render its own
40
48
  * recovery affordance (a CLI sentence, a web button, an SDK embed that wants no command at all). */
41
49
  export interface MeshTargetErrorDetails {
@@ -1 +1 @@
1
- {"version":3,"file":"mesh-target.d.ts","sourceRoot":"","sources":["../src/mesh-target.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAW/E;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;4GAMwG;IACxG,MAAM,EACF,aAAa,GACb,YAAY,GACZ,qBAAqB,GACrB,aAAa,GACb,gBAAgB,GAChB,UAAU,GACV,SAAS,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;8DAE8D;AAC9D,MAAM,MAAM,mBAAmB,GAC3B,WAAW,GACX,eAAe,GACf,kBAAkB,GAClB,kBAAkB,GAClB,iBAAiB,CAAC;AAEtB;qGACqG;AACrG,MAAM,WAAW,sBAAsB;IACrC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,uCAA0B;IACxC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;gBAEvC,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,sBAA2B,EACpC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAOhC;AAED;uGACuG;AACvG,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,eAAe,CAMvE;AAgDD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,YAAiB,GAAG,UAAU,CAyDnF"}
1
+ {"version":3,"file":"mesh-target.d.ts","sourceRoot":"","sources":["../src/mesh-target.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE/E,OAAO,EAML,KAAK,SAAS,EACd,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd;uFACmF;IACnF,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACxB;;sEAEkE;IAClE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;4GAMwG;IACxG,MAAM,EACF,aAAa,GACb,YAAY,GACZ,qBAAqB,GACrB,aAAa,GACb,gBAAgB,GAChB,UAAU,GACV,SAAS,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;8DAE8D;AAC9D,MAAM,MAAM,mBAAmB,GAC3B,WAAW,GACX,eAAe,GACf,kBAAkB,GAClB,kBAAkB,GAClB,iBAAiB,GACjB,sBAAsB,CAAC;AAE3B;qGACqG;AACrG,MAAM,WAAW,sBAAsB;IACrC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,uCAA0B;IACxC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;gBAEvC,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,sBAA2B,EACpC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAOhC;AAED;uGACuG;AACvG,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,eAAe,CAMvE;AAmGD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,YAAiB,GAAG,UAAU,CAyDnF"}
@@ -1,7 +1,7 @@
1
- import { existsSync } from "node:fs";
1
+ import { existsSync, readdirSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
3
  import { DEFAULT_SERVER, DEFAULT_SPACE } from "@cotal-ai/core";
4
- import { authDir, findCotalRoot, loadSpaceAuth } from "./auth-paths.js";
4
+ import { authDir, findCotalRoot, loadSpaceAuth, userAuthStateDir } from "./auth-paths.js";
5
5
  import { findMesh, getCurrent, homeCotalDir, loadMeshes, removeMesh, } from "./mesh-registry.js";
6
6
  const WORKSPACE_TARGET_ERROR = "cotal:workspace:mesh-target-error";
7
7
  /**
@@ -34,8 +34,10 @@ function personaRoot(root) {
34
34
  function targetFromEntry(m, server, source) {
35
35
  // Honor the recorded mode: an OPEN mesh connects credlessly even if its root still has auth
36
36
  // material on disk (e.g. a root that once ran auth mode). Loading it would make `spawn` mint
37
- // creds against a broker that takes none.
37
+ // creds against a broker that takes none. A USER mesh loads NO static auth either — its connect
38
+ // material comes from the login/bearer path; the entry's `userAuth` metadata rides the target.
38
39
  let auth;
40
+ let userAuth;
39
41
  if (m.mode === "auth") {
40
42
  auth = loadSpaceAuth(authDir(m.root));
41
43
  // Defense in depth: the root's on-disk auth must still be for THIS space. A divergence (the root
@@ -46,18 +48,57 @@ function targetFromEntry(m, server, source) {
46
48
  throw new MeshTargetError("stale-auth-root", `registry entry "${m.space}" points at ${m.root}, whose on-disk auth is now for "${auth.space}"`, { space: m.space, root: m.root, found: auth.space });
47
49
  }
48
50
  }
51
+ else if (m.mode === "user") {
52
+ // A user entry without its metadata cannot produce an actionable login line — treat it as the
53
+ // unrecorded case (re-`up` rewrites the entry) rather than half-connecting.
54
+ if (!m.userAuth)
55
+ throw new MeshTargetError("user-auth-unrecorded", `registry entry "${m.space}" is user-auth but carries no IdP metadata`, { space: m.space, root: m.root });
56
+ userAuth = m.userAuth;
57
+ }
49
58
  return {
50
59
  root: m.root,
51
60
  server,
52
61
  space: m.space,
62
+ mode: m.mode,
53
63
  auth,
64
+ ...(userAuth ? { userAuth } : {}),
54
65
  personaRoot: personaRoot(m.root),
55
66
  source,
56
67
  };
57
68
  }
58
69
  function localTarget(root, server, source) {
59
70
  const auth = loadSpaceAuth(authDir(root));
60
- return { root, server, space: auth?.space ?? DEFAULT_SPACE, auth, personaRoot: personaRoot(root), source };
71
+ const space = auth?.space ?? DEFAULT_SPACE;
72
+ // U10 guard: a user-auth space resolved WITHOUT its registry entry (pruned/never recorded) must
73
+ // not silently static-mint — static creds DO work on a user-auth broker, which would connect the
74
+ // operator on the wrong identity plane. The on-disk marker is the space-scoped user-auth state
75
+ // dir; the recovery (re-`cotal up` in that root) rewrites the registry entry with the IdP pins.
76
+ // The marker binds even when `auth.json` itself is missing/corrupt — a surviving state dir alone
77
+ // proves user auth was enabled here, and the alternative would classify the root "open" and
78
+ // connect credlessly toward a user-auth broker. Fail closed on the marker, whichever half died.
79
+ const userSpace = auth
80
+ ? existsSync(userAuthStateDir(root, space))
81
+ ? space
82
+ : undefined
83
+ : userAuthSpacesOnDisk(authDir(root))[0];
84
+ if (userSpace !== undefined)
85
+ throw new MeshTargetError("user-auth-unrecorded", `space "${userSpace}" has user auth enabled on disk but no usable registry entry`, { space: userSpace, root });
86
+ return { root, server, space, mode: auth ? "auth" : "open", auth, personaRoot: personaRoot(root), source };
87
+ }
88
+ /** Space names with user-auth state under a root's auth dir, detectable WITHOUT `auth.json`: each
89
+ * enabled space is a subdirectory (encodeURIComponent(space)) holding the provider's pinned
90
+ * material — `idp.json` is written first at enable, `callout.json` right after, so either one
91
+ * marks the dir as user-auth state (never confusable with a stray empty folder). */
92
+ function userAuthSpacesOnDisk(dir) {
93
+ try {
94
+ return readdirSync(dir, { withFileTypes: true })
95
+ .filter((e) => e.isDirectory() &&
96
+ (existsSync(join(dir, e.name, "idp.json")) || existsSync(join(dir, e.name, "callout.json"))))
97
+ .map((e) => decodeURIComponent(e.name));
98
+ }
99
+ catch {
100
+ return []; // no auth dir at all — nothing user-auth here
101
+ }
61
102
  }
62
103
  /** A `.cotal/` that a user actually created here — not the machine-home dir the cwd walk-up lands on
63
104
  * from outside any project (which has no space, just the daemon's pid/onboard files). */
@@ -1 +1 @@
1
- {"version":3,"file":"mesh-target.js","sourceRoot":"","sources":["../src/mesh-target.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mesh-target.js","sourceRoot":"","sources":["../src/mesh-target.ts"],"names":[],"mappings":"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"}
@@ -13,14 +13,14 @@ import type { MeshTarget } from "./mesh-target.js";
13
13
  /** The five distinct ways a preflight fails. Each also carries whether the target OWNS its registry
14
14
  * entry (→ prune): `fromRegistry` means the server+mode came from a registry record (incl. a
15
15
  * `local-recorded` project matched by root), so a definitive failure is a stale-entry signal. */
16
- export type PreflightFailure = "unreachable" | "registry-creds-rejected" | "registry-open-now-auth" | "creds-rejected" | "open-wants-auth";
16
+ export type PreflightFailure = "unreachable" | "registry-creds-rejected" | "registry-open-now-auth" | "creds-rejected" | "open-wants-auth" | "stale-auth";
17
17
  /** Pure decision tree — separated from I/O so the whole branch tree is unit-testable (it's the
18
18
  * riskiest logic: a wrong branch prunes a LIVE registry entry). Only a registry-OWNED source
19
19
  * (`registry`/`current`/`flag-space`/`local-recorded`) is ever pruned. A non-registry source —
20
20
  * `flag-server`/`local-space`, a raw `--creds` connection, or `flag-space-override` (a `--space`
21
21
  * whose `--server` overrides the recorded broker) — is NEVER pruned: the probed endpoint is
22
22
  * operator-supplied, so a failure there is the user's to diagnose, not a stale-registry signal. */
23
- export declare function classifyPreflightFailure(source: MeshTarget["source"], reason: "auth-required" | "unreachable", hasAuth: boolean): {
23
+ export declare function classifyPreflightFailure(source: MeshTarget["source"], reason: "auth-required" | "stale-auth" | "unreachable", hasAuth: boolean): {
24
24
  prune: boolean;
25
25
  kind: PreflightFailure;
26
26
  };
@@ -1 +1 @@
1
- {"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;;;;;;;GAUG;AAEH;;kGAEkG;AAClG,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,yBAAyB,GACzB,wBAAwB,GACxB,gBAAgB,GAChB,iBAAiB,CAAC;AAEtB;;;;;oGAKoG;AACpG,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,EAC5B,MAAM,EAAE,eAAe,GAAG,aAAa,EACvC,OAAO,EAAE,OAAO,GACf;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAa5C;AAED;;;uFAGuF;AACvF,wBAAsB,eAAe,CACnC,MAAM,EAAE,UAAU,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAO/E;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMtD"}
1
+ {"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;;;;;;;GAUG;AAEH;;kGAEkG;AAClG,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,yBAAyB,GACzB,wBAAwB,GACxB,gBAAgB,GAChB,iBAAiB,GACjB,YAAY,CAAC;AAEjB;;;;;oGAKoG;AACpG,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,EAC5B,MAAM,EAAE,eAAe,GAAG,YAAY,GAAG,aAAa,EACtD,OAAO,EAAE,OAAO,GACf;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAkB5C;AAED;;;uFAGuF;AACvF,wBAAsB,eAAe,CACnC,MAAM,EAAE,UAAU,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAY/E;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMtD"}
package/dist/preflight.js CHANGED
@@ -15,6 +15,12 @@ export function classifyPreflightFailure(source, reason, hasAuth) {
15
15
  source === "local-recorded";
16
16
  if (reason === "unreachable")
17
17
  return { prune: fromRegistry, kind: "unreachable" };
18
+ // STALE-AUTH (D5 slice 6): the broker is UP and answered — only the presented CREDENTIAL is dead
19
+ // (bounded lifetime / credential death). NEVER a prune signal, whatever the source: deleting a
20
+ // live mesh's registry entry because a cred expired would misdirect the repair (the fix is
21
+ // `doctor auth`, not re-registration) — the same misdiagnosis class as the gate-1 prune bug.
22
+ if (reason === "stale-auth")
23
+ return { prune: false, kind: "stale-auth" };
18
24
  if (fromRegistry && hasAuth)
19
25
  return { prune: true, kind: "registry-creds-rejected" };
20
26
  if (fromRegistry)
@@ -28,6 +34,11 @@ export function classifyPreflightFailure(source, reason, hasAuth) {
28
34
  * exit. Probes with `probeCreds` when given (the caller's `--creds`/minted creds); otherwise mints
29
35
  * a throwaway identity from the target's own trust material to test mere liveness. */
30
36
  export async function preflightTarget(target, probeCreds) {
37
+ // A user-mode target has no probe credential by design (its auth is a per-connect bearer) — a
38
+ // credless probe would be DENIED by the callout and misclassified as a stale registry entry
39
+ // (prune:true). Callers own the user connect; reaching here with one is a caller bug, fail loud.
40
+ if (target.mode === "user")
41
+ throw new Error("preflightTarget: a user-mode target cannot be credless-probed - the caller owns the user connect (see preflightOrExit's user branch)");
31
42
  const creds = probeCreds ?? (target.auth ? await mintCreds(target.auth, newIdentity(), "probe") : undefined);
32
43
  const probe = await probeConnect(target.server, creds ? { creds } : {});
33
44
  if (probe.ok)
@@ -1 +1 @@
1
- {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAyB5D;;;;;oGAKoG;AACpG,MAAM,UAAU,wBAAwB,CACtC,MAA4B,EAC5B,MAAuC,EACvC,OAAgB;IAEhB,mGAAmG;IACnG,iGAAiG;IACjG,MAAM,YAAY,GAChB,MAAM,KAAK,UAAU;QACrB,MAAM,KAAK,SAAS;QACpB,MAAM,KAAK,YAAY;QACvB,MAAM,KAAK,gBAAgB,CAAC;IAC9B,IAAI,MAAM,KAAK,aAAa;QAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IAClF,IAAI,YAAY,IAAI,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;IACrF,IAAI,YAAY;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC;IACzE,IAAI,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;IAC7D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC;AACnD,CAAC;AAED;;;uFAGuF;AACvF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAkB,EAClB,UAAmB;IAEnB,MAAM,KAAK,GACT,UAAU,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACjG,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,IAAI,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAClC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,wBAAwB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACpG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,OAAO,CAAC,GAAG,CACf,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AA0B5D;;;;;oGAKoG;AACpG,MAAM,UAAU,wBAAwB,CACtC,MAA4B,EAC5B,MAAsD,EACtD,OAAgB;IAEhB,mGAAmG;IACnG,iGAAiG;IACjG,MAAM,YAAY,GAChB,MAAM,KAAK,UAAU;QACrB,MAAM,KAAK,SAAS;QACpB,MAAM,KAAK,YAAY;QACvB,MAAM,KAAK,gBAAgB,CAAC;IAC9B,IAAI,MAAM,KAAK,aAAa;QAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IAClF,iGAAiG;IACjG,+FAA+F;IAC/F,2FAA2F;IAC3F,6FAA6F;IAC7F,IAAI,MAAM,KAAK,YAAY;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IACzE,IAAI,YAAY,IAAI,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;IACrF,IAAI,YAAY;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC;IACzE,IAAI,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;IAC7D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC;AACnD,CAAC;AAED;;;uFAGuF;AACvF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAkB,EAClB,UAAmB;IAEnB,8FAA8F;IAC9F,4FAA4F;IAC5F,iGAAiG;IACjG,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;QACxB,MAAM,IAAI,KAAK,CAAC,sIAAsI,CAAC,CAAC;IAC1J,MAAM,KAAK,GACT,UAAU,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACjG,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,IAAI,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAClC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,wBAAwB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACpG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,OAAO,CAAC,GAAG,CACf,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
package/dist/render.d.ts CHANGED
@@ -21,7 +21,7 @@ export type WorkspaceError = {
21
21
  pruned: boolean;
22
22
  } | {
23
23
  kind: "reachable";
24
- reason: "auth-required" | "unreachable";
24
+ reason: "auth-required" | "stale-auth" | "unreachable";
25
25
  server: string;
26
26
  };
27
27
  /** Render a workspace failure as the canonical one-line `cotal …` sentence. */
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACrF;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAS9D"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACrF;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,YAAY,GAAG,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElG,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAS9D"}
package/dist/render.js CHANGED
@@ -14,37 +14,46 @@ function renderTargetError(err) {
14
14
  const d = err.details;
15
15
  switch (err.code) {
16
16
  case "no-meshes":
17
- return "✗ no mesh running run `cotal up` in a project, or pass `--server`";
17
+ return "✗ no mesh running - run `cotal up` in a project, or pass `--server`";
18
18
  case "unknown-space":
19
- return `✗ no mesh named "${d.requested}" is running see \`cotal meshes\``;
19
+ return `✗ no mesh named "${d.requested}" is running - see \`cotal meshes\``;
20
20
  case "ambiguous-target":
21
- return `✗ multiple meshes running ${(d.available ?? []).join(", ")}. Pick one with \`--space <name>\` or set a default with \`cotal use <name>\`.`;
21
+ return `✗ multiple meshes running - ${(d.available ?? []).join(", ")}. Pick one with \`--space <name>\` or set a default with \`cotal use <name>\`.`;
22
22
  case "default-occupied":
23
- return `✗ another mesh ("${d.space}") is running at ${d.server} run \`cotal up\` here to start yours, or \`--space ${d.space}\` to join it`;
23
+ return `✗ another mesh ("${d.space}") is running at ${d.server} - run \`cotal up\` here to start yours, or \`--space ${d.space}\` to join it`;
24
24
  case "stale-auth-root":
25
- return `✗ registry entry "${d.space}" points at ${d.root}, whose auth is now for "${d.found}" stale entry removed; re-run \`cotal up\` or check \`cotal meshes\``;
25
+ return `✗ registry entry "${d.space}" points at ${d.root}, whose auth is now for "${d.found}" - stale entry removed; re-run \`cotal up\` or check \`cotal meshes\``;
26
+ case "user-auth-unrecorded":
27
+ // U11: without a TRUSTED local record of the space's IdP there is no actionable
28
+ // `cotal login --idp <?>` line to print — the honest recovery is re-registering the mesh
29
+ // where its user-auth state lives, and remote discovery is explicitly not supported yet.
30
+ return `✗ space "${d.space}" requires user auth, but no trusted IdP config for it is registered on this machine - re-run \`cotal up --user-auth\` in ${d.root ?? "its broker root"} to re-register it (user-auth spaces are configured where their broker runs; remote discovery is not supported yet)`;
26
31
  }
27
32
  }
28
33
  /** "Is it live" failures on a registry-resolved target — the classified preflight sentence. */
29
34
  function renderPreflightFailure(kind, t, pruned) {
30
35
  switch (kind) {
31
36
  case "unreachable":
32
- return `✗ no mesh running at ${t.server}${pruned ? " (stale registry entry removed)" : ""} run \`cotal up\``;
37
+ return `✗ no mesh running at ${t.server}${pruned ? " (stale registry entry - removed)" : ""} - run \`cotal up\``;
33
38
  case "registry-creds-rejected":
34
- return `✗ mesh "${t.space}" at ${t.server} no longer matches its registry entry (credentials rejected port reused?) re-run \`cotal up\` from ${t.root}, or \`cotal meshes\` to see what's live`;
39
+ return `✗ mesh "${t.space}" at ${t.server} no longer matches its registry entry (credentials rejected - port reused?) - re-run \`cotal up\` from ${t.root}, or \`cotal meshes\` to see what's live`;
35
40
  case "registry-open-now-auth":
36
- return `✗ open mesh "${t.space}" at ${t.server} no longer matches its registry entry (broker now requires auth port reused?) re-run \`cotal up\` from ${t.root}, or \`cotal meshes\` to see what's live`;
41
+ return `✗ open mesh "${t.space}" at ${t.server} no longer matches its registry entry (broker now requires auth - port reused?) - re-run \`cotal up\` from ${t.root}, or \`cotal meshes\` to see what's live`;
37
42
  case "creds-rejected":
38
- return `✗ credentials for "${t.space}" were rejected at ${t.server} a different mesh may be running there. Run \`cotal meshes\` to check, or \`cotal up\` here to start yours`;
43
+ return `✗ credentials for "${t.space}" were rejected at ${t.server} - a different mesh may be running there. Run \`cotal meshes\` to check, or \`cotal up\` here to start yours`;
39
44
  case "open-wants-auth":
40
- return `✗ broker at ${t.server} requires auth, but this mesh is open (no trust material) use \`--space <name>\` for an auth mesh, or run \`cotal up\` here without \`--open\``;
45
+ return `✗ broker at ${t.server} requires auth, but this mesh is open (no trust material) - use \`--space <name>\` for an auth mesh, or run \`cotal up\` here without \`--open\``;
46
+ case "stale-auth":
47
+ return `✗ credentials for "${t.space}" have EXPIRED - this mesh enforces bounded credential lifetimes; run \`cotal doctor auth\` in ${t.root} for the diagnosis + exact repair (the mesh itself is up)`;
41
48
  }
42
49
  }
43
50
  /** Plain reachability for a RAW (off-registry) probe — the `--creds` / `--server`+unregistered-`--space`
44
51
  * escape hatch, which never touches the registry (no prune, no stale-entry wording). */
45
52
  function renderReachable(reason, server) {
53
+ if (reason === "stale-auth")
54
+ return `✗ credential EXPIRED at ${server} - bounded lifetime reached (credential death); run \`cotal doctor auth\` where the mesh runs, or re-mint the credential`;
46
55
  return reason === "auth-required"
47
- ? `✗ credentials rejected at ${server} check your creds, or the broker wants different auth`
48
- : `✗ can't reach a broker at ${server} is it running? (\`cotal up\`)`;
56
+ ? `✗ credentials rejected at ${server} - check your creds, or the broker wants different auth`
57
+ : `✗ can't reach a broker at ${server} - is it running? (\`cotal up\`)`;
49
58
  }
50
59
  //# sourceMappingURL=render.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAmBA,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAAC,CAAiB;IACpD,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,QAAQ;YACX,OAAO,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACpC,KAAK,WAAW;YACd,OAAO,sBAAsB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QAC/D,KAAK,WAAW;YACd,OAAO,eAAe,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,qGAAqG;AACrG,SAAS,iBAAiB,CAAC,GAAoB;IAC7C,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;IACtB,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,WAAW;YACd,OAAO,qEAAqE,CAAC;QAC/E,KAAK,eAAe;YAClB,OAAO,oBAAoB,CAAC,CAAC,SAAS,qCAAqC,CAAC;QAC9E,KAAK,kBAAkB;YACrB,OAAO,+BAA+B,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,gFAAgF,CAAC;QACvJ,KAAK,kBAAkB;YACrB,OAAO,oBAAoB,CAAC,CAAC,KAAK,oBAAoB,CAAC,CAAC,MAAM,yDAAyD,CAAC,CAAC,KAAK,eAAe,CAAC;QAChJ,KAAK,iBAAiB;YACpB,OAAO,qBAAqB,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,IAAI,4BAA4B,CAAC,CAAC,KAAK,wEAAwE,CAAC;IACxK,CAAC;AACH,CAAC;AAED,+FAA+F;AAC/F,SAAS,sBAAsB,CAAC,IAAsB,EAAE,CAAa,EAAE,MAAe;IACpF,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa;YAChB,OAAO,wBAAwB,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC;QACnH,KAAK,yBAAyB;YAC5B,OAAO,WAAW,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM,0GAA0G,CAAC,CAAC,IAAI,0CAA0C,CAAC;QACtM,KAAK,wBAAwB;YAC3B,OAAO,gBAAgB,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM,8GAA8G,CAAC,CAAC,IAAI,0CAA0C,CAAC;QAC/M,KAAK,gBAAgB;YACnB,OAAO,sBAAsB,CAAC,CAAC,KAAK,sBAAsB,CAAC,CAAC,MAAM,8GAA8G,CAAC;QACnL,KAAK,iBAAiB;YACpB,OAAO,eAAe,CAAC,CAAC,MAAM,kJAAkJ,CAAC;IACrL,CAAC;AACH,CAAC;AAED;yFACyF;AACzF,SAAS,eAAe,CAAC,MAAuC,EAAE,MAAc;IAC9E,OAAO,MAAM,KAAK,eAAe;QAC/B,CAAC,CAAC,6BAA6B,MAAM,yDAAyD;QAC9F,CAAC,CAAC,6BAA6B,MAAM,kCAAkC,CAAC;AAC5E,CAAC"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAmBA,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAAC,CAAiB;IACpD,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,QAAQ;YACX,OAAO,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACpC,KAAK,WAAW;YACd,OAAO,sBAAsB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QAC/D,KAAK,WAAW;YACd,OAAO,eAAe,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,qGAAqG;AACrG,SAAS,iBAAiB,CAAC,GAAoB;IAC7C,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;IACtB,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,WAAW;YACd,OAAO,qEAAqE,CAAC;QAC/E,KAAK,eAAe;YAClB,OAAO,oBAAoB,CAAC,CAAC,SAAS,qCAAqC,CAAC;QAC9E,KAAK,kBAAkB;YACrB,OAAO,+BAA+B,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,gFAAgF,CAAC;QACvJ,KAAK,kBAAkB;YACrB,OAAO,oBAAoB,CAAC,CAAC,KAAK,oBAAoB,CAAC,CAAC,MAAM,yDAAyD,CAAC,CAAC,KAAK,eAAe,CAAC;QAChJ,KAAK,iBAAiB;YACpB,OAAO,qBAAqB,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,IAAI,4BAA4B,CAAC,CAAC,KAAK,wEAAwE,CAAC;QACtK,KAAK,sBAAsB;YACzB,gFAAgF;YAChF,yFAAyF;YACzF,yFAAyF;YACzF,OAAO,YAAY,CAAC,CAAC,KAAK,6HAA6H,CAAC,CAAC,IAAI,IAAI,iBAAiB,qHAAqH,CAAC;IAC5S,CAAC;AACH,CAAC;AAED,+FAA+F;AAC/F,SAAS,sBAAsB,CAAC,IAAsB,EAAE,CAAa,EAAE,MAAe;IACpF,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa;YAChB,OAAO,wBAAwB,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC;QACnH,KAAK,yBAAyB;YAC5B,OAAO,WAAW,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM,0GAA0G,CAAC,CAAC,IAAI,0CAA0C,CAAC;QACtM,KAAK,wBAAwB;YAC3B,OAAO,gBAAgB,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM,8GAA8G,CAAC,CAAC,IAAI,0CAA0C,CAAC;QAC/M,KAAK,gBAAgB;YACnB,OAAO,sBAAsB,CAAC,CAAC,KAAK,sBAAsB,CAAC,CAAC,MAAM,8GAA8G,CAAC;QACnL,KAAK,iBAAiB;YACpB,OAAO,eAAe,CAAC,CAAC,MAAM,kJAAkJ,CAAC;QACnL,KAAK,YAAY;YACf,OAAO,sBAAsB,CAAC,CAAC,KAAK,kGAAkG,CAAC,CAAC,IAAI,2DAA2D,CAAC;IAC5M,CAAC;AACH,CAAC;AAED;yFACyF;AACzF,SAAS,eAAe,CAAC,MAAsD,EAAE,MAAc;IAC7F,IAAI,MAAM,KAAK,YAAY;QACzB,OAAO,2BAA2B,MAAM,0HAA0H,CAAC;IACrK,OAAO,MAAM,KAAK,eAAe;QAC/B,CAAC,CAAC,6BAA6B,MAAM,yDAAyD;QAC9F,CAAC,CAAC,6BAA6B,MAAM,kCAAkC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { type Profile } from "@cotal-ai/core";
2
+ /**
3
+ * D5 slice 5 class-2 standing renewal — the RENEWAL OWNER'S half, shared by the manager (the
4
+ * resident owner in every mesh mode) and `cotal doctor auth --fix` (the operator repair). The
5
+ * daemon's half is the explicit `reloadCreds` adoption op on the delivery-admin rail (plus the
6
+ * passive 75% source re-read as backstop). Machine-local file work lives here in the workspace
7
+ * layer: implementations never import each other.
8
+ */
9
+ /** The seed-less daemon creds files a renewal owner re-signs. The $SYS files
10
+ * (membership-observer, connection-evictor) are deliberately ABSENT: they are rotation-renewed —
11
+ * no persisted seed can re-sign them, by design. */
12
+ export declare const REMINTABLE_DAEMON_CREDS: ReadonlyArray<{
13
+ file: string;
14
+ profile: Profile;
15
+ }>;
16
+ export interface RemintResult {
17
+ file: string;
18
+ /** true = re-signed; false = failed (see error); undefined ok with `skipped` = file absent. */
19
+ ok: boolean;
20
+ skipped?: "missing-file" | "no-auth";
21
+ error?: string;
22
+ }
23
+ /** Re-sign the daemon creds files for their EXISTING nkeys (a renewal must never swap a daemon's
24
+ * identity — the daemon side pins it). Structured per-file results, never throws: a failed remint
25
+ * leaves the old cred running toward its loud expiry and the caller records/reports the failure. */
26
+ export declare function remintDaemonCreds(root: string): Promise<RemintResult[]>;
27
+ /** The renewal owner's audit record — what `cotal doctor auth` renders so "file re-signed" and
28
+ * "daemon adopted" are distinguishable states, per the D5 panel gate. One file, overwritten per
29
+ * pass: the CURRENT renewal state, not a log (history is the git/ops layer's job). */
30
+ export interface RenewalRecord {
31
+ /** ISO timestamp of the renewal pass. */
32
+ ts: string;
33
+ /** Who ran the pass (e.g. "manager", "doctor --fix"). */
34
+ owner: string;
35
+ results: RemintResult[];
36
+ /** The daemon's explicit reloadCreds adoption outcome; absent when nothing was re-signed. */
37
+ adoption?: {
38
+ ok: boolean;
39
+ detail?: unknown;
40
+ error?: string;
41
+ };
42
+ }
43
+ export declare function renewalRecordPath(root: string): string;
44
+ export declare function writeRenewalRecord(root: string, record: RenewalRecord): void;
45
+ export declare function readRenewalRecord(root: string): RenewalRecord | undefined;
46
+ //# sourceMappingURL=renewal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renewal.d.ts","sourceRoot":"","sources":["../src/renewal.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,OAAO,EACb,MAAM,gBAAgB,CAAC;AAGxB;;;;;;GAMG;AAEH;;qDAEqD;AACrD,eAAO,MAAM,uBAAuB,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAGrF,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,+FAA+F;IAC/F,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;qGAEqG;AACrG,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAmB7E;AAED;;uFAEuF;AACvF,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAE5E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAQzE"}
@@ -0,0 +1,61 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { identityFromCreds, mintCreds, writeSecretFile, } from "@cotal-ai/core";
4
+ import { authDir, loadSpaceAuth } from "./auth-paths.js";
5
+ /**
6
+ * D5 slice 5 class-2 standing renewal — the RENEWAL OWNER'S half, shared by the manager (the
7
+ * resident owner in every mesh mode) and `cotal doctor auth --fix` (the operator repair). The
8
+ * daemon's half is the explicit `reloadCreds` adoption op on the delivery-admin rail (plus the
9
+ * passive 75% source re-read as backstop). Machine-local file work lives here in the workspace
10
+ * layer: implementations never import each other.
11
+ */
12
+ /** The seed-less daemon creds files a renewal owner re-signs. The $SYS files
13
+ * (membership-observer, connection-evictor) are deliberately ABSENT: they are rotation-renewed —
14
+ * no persisted seed can re-sign them, by design. */
15
+ export const REMINTABLE_DAEMON_CREDS = [
16
+ { file: "delivery.creds", profile: "delivery" },
17
+ { file: "membership-rw.creds", profile: "membership-rw" },
18
+ ];
19
+ /** Re-sign the daemon creds files for their EXISTING nkeys (a renewal must never swap a daemon's
20
+ * identity — the daemon side pins it). Structured per-file results, never throws: a failed remint
21
+ * leaves the old cred running toward its loud expiry and the caller records/reports the failure. */
22
+ export async function remintDaemonCreds(root) {
23
+ const auth = loadSpaceAuth(authDir(root));
24
+ if (!auth)
25
+ return REMINTABLE_DAEMON_CREDS.map(({ file }) => ({ file, ok: false, skipped: "no-auth" }));
26
+ const results = [];
27
+ for (const { file, profile } of REMINTABLE_DAEMON_CREDS) {
28
+ const path = join(root, ".cotal", file);
29
+ if (!existsSync(path)) {
30
+ results.push({ file, ok: false, skipped: "missing-file" });
31
+ continue;
32
+ }
33
+ try {
34
+ const identity = identityFromCreds(readFileSync(path, "utf8"));
35
+ writeSecretFile(path, await mintCreds(auth, identity, profile));
36
+ results.push({ file, ok: true });
37
+ }
38
+ catch (e) {
39
+ results.push({ file, ok: false, error: e.message });
40
+ }
41
+ }
42
+ return results;
43
+ }
44
+ export function renewalRecordPath(root) {
45
+ return join(root, ".cotal", "renewal.json");
46
+ }
47
+ export function writeRenewalRecord(root, record) {
48
+ writeSecretFile(renewalRecordPath(root), JSON.stringify(record, null, 2));
49
+ }
50
+ export function readRenewalRecord(root) {
51
+ const p = renewalRecordPath(root);
52
+ if (!existsSync(p))
53
+ return undefined;
54
+ try {
55
+ return JSON.parse(readFileSync(p, "utf8"));
56
+ }
57
+ catch {
58
+ return undefined; // a corrupt record is rendered as "no renewal record", never a crash
59
+ }
60
+ }
61
+ //# sourceMappingURL=renewal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renewal.js","sourceRoot":"","sources":["../src/renewal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,eAAe,GAEhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEzD;;;;;;GAMG;AAEH;;qDAEqD;AACrD,MAAM,CAAC,MAAM,uBAAuB,GAAsD;IACxF,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,UAAU,EAAE;IAC/C,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,eAAe,EAAE;CAC1D,CAAC;AAUF;;qGAEqG;AACrG,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAClD,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAI;QAAE,OAAO,uBAAuB,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAkB,EAAE,CAAC,CAAC,CAAC;IAChH,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,uBAAuB,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;YAC3D,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,iBAAiB,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YAC/D,eAAe,CAAC,IAAI,EAAE,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAeD,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,MAAqB;IACpE,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACrC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAkB,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC,CAAC,qEAAqE;IACzF,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cotal-ai/workspace",
3
3
  "description": "Cotal machine-local workstation layer: the ~/.cotal mesh registry, target resolution, preflight, on-disk auth-path I/O, and the command-copy renderer — operator concerns over a local checkout, kept separate from the wire protocol in @cotal-ai/core.",
4
- "version": "0.10.1",
4
+ "version": "0.11.1",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -18,7 +18,7 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
- "@cotal-ai/core": "0.10.1"
21
+ "@cotal-ai/core": "0.11.1"
22
22
  },
23
23
  "files": [
24
24
  "dist"