@cotal-ai/workspace 0.11.6 → 0.13.0
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/auth-paths.d.ts +52 -2
- package/dist/auth-paths.d.ts.map +1 -1
- package/dist/auth-paths.js +107 -4
- package/dist/auth-paths.js.map +1 -1
- package/dist/connect.d.ts.map +1 -1
- package/dist/connect.js +4 -1
- package/dist/connect.js.map +1 -1
- package/dist/flags.d.ts +2 -2
- package/dist/flags.d.ts.map +1 -1
- package/dist/flags.js +2 -2
- package/dist/flags.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/maintenance.d.ts +517 -0
- package/dist/maintenance.d.ts.map +1 -0
- package/dist/maintenance.js +2551 -0
- package/dist/maintenance.js.map +1 -0
- package/dist/mesh-registry.d.ts +11 -7
- package/dist/mesh-registry.d.ts.map +1 -1
- package/dist/mesh-registry.js +26 -17
- package/dist/mesh-registry.js.map +1 -1
- package/dist/mesh-target.d.ts +3 -2
- package/dist/mesh-target.d.ts.map +1 -1
- package/dist/mesh-target.js +11 -10
- package/dist/mesh-target.js.map +1 -1
- package/dist/renewal.d.ts +20 -4
- package/dist/renewal.d.ts.map +1 -1
- package/dist/renewal.js +28 -11
- package/dist/renewal.js.map +1 -1
- package/dist/secret-store-fs.d.ts +39 -0
- package/dist/secret-store-fs.d.ts.map +1 -0
- package/dist/secret-store-fs.js +80 -0
- package/dist/secret-store-fs.js.map +1 -0
- package/package.json +3 -3
package/dist/renewal.js
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { identityFromCreds, mintCreds, writeSecretFile, } from "@cotal-ai/core";
|
|
4
4
|
import { authDir, loadSpaceAuth } from "./auth-paths.js";
|
|
5
|
+
import { workspaceSecretStore } from "./secret-store-fs.js";
|
|
5
6
|
/**
|
|
6
7
|
* D5 slice 5 class-2 standing renewal — the RENEWAL OWNER'S half, shared by the manager (the
|
|
7
8
|
* resident owner in every mesh mode) and `cotal doctor auth --fix` (the operator repair). The
|
|
@@ -9,30 +10,46 @@ import { authDir, loadSpaceAuth } from "./auth-paths.js";
|
|
|
9
10
|
* passive 75% source re-read as backstop). Machine-local file work lives here in the workspace
|
|
10
11
|
* layer: implementations never import each other.
|
|
11
12
|
*/
|
|
13
|
+
/** The canonical secret-store key of the delivery daemon's scoped cred — by the FS convention the
|
|
14
|
+
* key IS the filename under `.cotal/`. The single source for every tier (the CLI writer, the
|
|
15
|
+
* delivery daemon reader, this renewal owner): a hand-copied drifted literal would silently split
|
|
16
|
+
* the kind across two store entries with no compile error. Lives in workspace because the
|
|
17
|
+
* key↔filename convention is the workspace layout's; implementations never import each other. */
|
|
18
|
+
export const DELIVERY_CREDS_KEY = "delivery.creds";
|
|
12
19
|
/** The seed-less daemon creds files a renewal owner re-signs. The $SYS files
|
|
13
20
|
* (membership-observer, connection-evictor) are deliberately ABSENT: they are rotation-renewed —
|
|
14
21
|
* no persisted seed can re-sign them, by design. */
|
|
15
22
|
export const REMINTABLE_DAEMON_CREDS = [
|
|
16
|
-
{ file:
|
|
23
|
+
{ file: DELIVERY_CREDS_KEY, profile: "delivery" },
|
|
17
24
|
{ file: "membership-rw.creds", profile: "membership-rw" },
|
|
18
25
|
];
|
|
19
26
|
/** 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).
|
|
21
|
-
*
|
|
22
|
-
|
|
27
|
+
* identity — the daemon side pins it). Reads and writes through the secret-store seam; `store` is
|
|
28
|
+
* the renewal owner's injection point, SYMMETRIC with the daemon's `runDelivery(args, store?)`.
|
|
29
|
+
* The manager — the D5 standing-renewal owner, and a hosted-path caller (manager.ts calls this
|
|
30
|
+
* unconditionally) — must pass the SAME store it gives the daemon, or a hosted composition
|
|
31
|
+
* re-signs into one store while the daemon reads another and rides to expiry. Threading the store
|
|
32
|
+
* through the manager's entry is its own slice; until it lands, hosted end-to-end renewal on an
|
|
33
|
+
* injected store is NOT yet wired, and no store means the local workspace FS composition (keys =
|
|
34
|
+
* the filenames under `.cotal/`). The store's ATOMIC put is load-bearing here, because the daemons
|
|
35
|
+
* re-read these files LIVE (the delivery endpoint's 75% source backstop, the membership rw
|
|
36
|
+
* reconnect getter) and the plain `writeSecretFile` this replaced could tear such a concurrent
|
|
37
|
+
* re-read. Structured per-file results, never throws: a failed remint leaves the old cred running
|
|
38
|
+
* toward its loud expiry and the caller records/reports the failure. */
|
|
39
|
+
export async function remintDaemonCreds(root, store) {
|
|
23
40
|
const auth = loadSpaceAuth(authDir(root));
|
|
24
41
|
if (!auth)
|
|
25
42
|
return REMINTABLE_DAEMON_CREDS.map(({ file }) => ({ file, ok: false, skipped: "no-auth" }));
|
|
43
|
+
const s = store ?? workspaceSecretStore(root);
|
|
26
44
|
const results = [];
|
|
27
45
|
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
46
|
try {
|
|
34
|
-
const
|
|
35
|
-
|
|
47
|
+
const current = await s.get(file);
|
|
48
|
+
if (current === undefined) {
|
|
49
|
+
results.push({ file, ok: false, skipped: "missing-file" });
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
await s.put(file, await mintCreds(auth, identityFromCreds(current), profile));
|
|
36
53
|
results.push({ file, ok: true });
|
|
37
54
|
}
|
|
38
55
|
catch (e) {
|
package/dist/renewal.js.map
CHANGED
|
@@ -1 +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,
|
|
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,GAGhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D;;;;;;GAMG;AAEH;;;;kGAIkG;AAClG,MAAM,CAAC,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAEnD;;qDAEqD;AACrD,MAAM,CAAC,MAAM,uBAAuB,GAAsD;IACxF,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,UAAU,EAAE;IACjD,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,eAAe,EAAE;CAC1D,CAAC;AAUF;;;;;;;;;;;;yEAYyE;AACzE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,KAAmB;IACvE,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,CAAC,GAAG,KAAK,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,uBAAuB,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;gBAC3D,SAAS;YACX,CAAC;YACD,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,SAAS,CAAC,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YAC9E,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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type SecretStore } from "@cotal-ai/core";
|
|
2
|
+
/** THE local composition of the secret keyspace: a filesystem store rooted at the workspace's
|
|
3
|
+
* `.cotal/` dir, so every canonical key (`delivery.creds`, `auth/<space>/callout.json`, …)
|
|
4
|
+
* lands byte-for-byte on today's paths. Every local caller composes through here — a hand-rolled
|
|
5
|
+
* root that drifted from `.cotal` would silently split the keyspace in two. */
|
|
6
|
+
export declare function workspaceSecretStore(root: string): FsSecretStore;
|
|
7
|
+
/**
|
|
8
|
+
* The default filesystem {@link SecretStore}: the workstation adapter behind core's abstract seam.
|
|
9
|
+
*
|
|
10
|
+
* Keys are opaque logical strings the owning packages build to MIRROR today's exact `.cotal` layout
|
|
11
|
+
* per kind — `delivery.creds`, `auth/callout.json`, `<agent>.creds`, and so on — so a local
|
|
12
|
+
* `cotal up` writes byte-for-byte the same files it does today. That layout is heterogeneous (a few
|
|
13
|
+
* kinds are already space-segmented on disk, most are not), so each key builder reproduces its
|
|
14
|
+
* kind's current path verbatim. Crucially the key carries NO injected tenant / `<space>` prefix: a
|
|
15
|
+
* hosted KMS/Vault adapter adds per-tenant scope inside ITS OWN resolve from its injection context,
|
|
16
|
+
* which keeps one backend-agnostic key per kind and preserves local byte-for-byte.
|
|
17
|
+
*
|
|
18
|
+
* This adapter adds nothing of its own: it delegates to the `secret-fs` primitives for the
|
|
19
|
+
* 0600 / icacls / atomic-replace / fail-closed guarantees. Constructed with an EXPLICIT base root
|
|
20
|
+
* (no ambient `~/.cotal`), absolutized so keys are cwd-independent. Lives in `@cotal-ai/workspace`,
|
|
21
|
+
* not core, because on-disk layout is a workstation concern, not the wire protocol.
|
|
22
|
+
*
|
|
23
|
+
* Residual (documented): a symlink UNDER the root that points outside is not caught (no realpath) —
|
|
24
|
+
* acceptable for a single-tenant workstation; a multi-tenant FS deployment should realpath-check.
|
|
25
|
+
*/
|
|
26
|
+
export declare class FsSecretStore implements SecretStore {
|
|
27
|
+
private readonly root;
|
|
28
|
+
constructor(root: string);
|
|
29
|
+
/** Resolve a logical key to an absolute path strictly UNDER `root`, fail-closed: reject empty,
|
|
30
|
+
* NUL, absolute keys, the root itself (`.`), and any key that normalizes outside the root
|
|
31
|
+
* (`..` traversal). Containment is checked via `path.relative`, not a `root + sep` prefix —
|
|
32
|
+
* the prefix form breaks at a filesystem-root base (`/` doubles the separator and rejects
|
|
33
|
+
* every key). A malformed key must never read or clobber a path outside the store's tree. */
|
|
34
|
+
private resolve;
|
|
35
|
+
get(key: string): Promise<string | undefined>;
|
|
36
|
+
put(key: string, value: string): Promise<void>;
|
|
37
|
+
delete(key: string): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=secret-store-fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-store-fs.d.ts","sourceRoot":"","sources":["../src/secret-store-fs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEtF;;;gFAGgF;AAChF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAEhE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,aAAc,YAAW,WAAW;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,IAAI,EAAE,MAAM;IAKxB;;;;kGAI8F;IAC9F,OAAO,CAAC,OAAO;IAYT,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAU7C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQzC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { readFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { join, dirname, isAbsolute, normalize, relative, resolve, sep } from "node:path";
|
|
3
|
+
import { mkSecretDir, writeSecretFileAtomic } from "@cotal-ai/core";
|
|
4
|
+
/** THE local composition of the secret keyspace: a filesystem store rooted at the workspace's
|
|
5
|
+
* `.cotal/` dir, so every canonical key (`delivery.creds`, `auth/<space>/callout.json`, …)
|
|
6
|
+
* lands byte-for-byte on today's paths. Every local caller composes through here — a hand-rolled
|
|
7
|
+
* root that drifted from `.cotal` would silently split the keyspace in two. */
|
|
8
|
+
export function workspaceSecretStore(root) {
|
|
9
|
+
return new FsSecretStore(join(root, ".cotal"));
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The default filesystem {@link SecretStore}: the workstation adapter behind core's abstract seam.
|
|
13
|
+
*
|
|
14
|
+
* Keys are opaque logical strings the owning packages build to MIRROR today's exact `.cotal` layout
|
|
15
|
+
* per kind — `delivery.creds`, `auth/callout.json`, `<agent>.creds`, and so on — so a local
|
|
16
|
+
* `cotal up` writes byte-for-byte the same files it does today. That layout is heterogeneous (a few
|
|
17
|
+
* kinds are already space-segmented on disk, most are not), so each key builder reproduces its
|
|
18
|
+
* kind's current path verbatim. Crucially the key carries NO injected tenant / `<space>` prefix: a
|
|
19
|
+
* hosted KMS/Vault adapter adds per-tenant scope inside ITS OWN resolve from its injection context,
|
|
20
|
+
* which keeps one backend-agnostic key per kind and preserves local byte-for-byte.
|
|
21
|
+
*
|
|
22
|
+
* This adapter adds nothing of its own: it delegates to the `secret-fs` primitives for the
|
|
23
|
+
* 0600 / icacls / atomic-replace / fail-closed guarantees. Constructed with an EXPLICIT base root
|
|
24
|
+
* (no ambient `~/.cotal`), absolutized so keys are cwd-independent. Lives in `@cotal-ai/workspace`,
|
|
25
|
+
* not core, because on-disk layout is a workstation concern, not the wire protocol.
|
|
26
|
+
*
|
|
27
|
+
* Residual (documented): a symlink UNDER the root that points outside is not caught (no realpath) —
|
|
28
|
+
* acceptable for a single-tenant workstation; a multi-tenant FS deployment should realpath-check.
|
|
29
|
+
*/
|
|
30
|
+
export class FsSecretStore {
|
|
31
|
+
root;
|
|
32
|
+
constructor(root) {
|
|
33
|
+
if (!root)
|
|
34
|
+
throw new Error("FsSecretStore: root is required");
|
|
35
|
+
this.root = normalize(resolve(root)); // absolutize so keys are cwd-independent
|
|
36
|
+
}
|
|
37
|
+
/** Resolve a logical key to an absolute path strictly UNDER `root`, fail-closed: reject empty,
|
|
38
|
+
* NUL, absolute keys, the root itself (`.`), and any key that normalizes outside the root
|
|
39
|
+
* (`..` traversal). Containment is checked via `path.relative`, not a `root + sep` prefix —
|
|
40
|
+
* the prefix form breaks at a filesystem-root base (`/` doubles the separator and rejects
|
|
41
|
+
* every key). A malformed key must never read or clobber a path outside the store's tree. */
|
|
42
|
+
resolve(key) {
|
|
43
|
+
if (!key || key.includes("\0"))
|
|
44
|
+
throw new Error(`FsSecretStore: invalid key ${JSON.stringify(key)}`);
|
|
45
|
+
if (isAbsolute(key))
|
|
46
|
+
throw new Error(`FsSecretStore: key must be relative, got ${JSON.stringify(key)}`);
|
|
47
|
+
const abs = normalize(join(this.root, key));
|
|
48
|
+
const rel = relative(this.root, abs);
|
|
49
|
+
if (!rel || rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel))
|
|
50
|
+
throw new Error(`FsSecretStore: key must name a file under the root: ${JSON.stringify(key)}`);
|
|
51
|
+
return abs;
|
|
52
|
+
}
|
|
53
|
+
async get(key) {
|
|
54
|
+
const p = this.resolve(key);
|
|
55
|
+
try {
|
|
56
|
+
return readFileSync(p, "utf8");
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
if (e.code === "ENOENT")
|
|
60
|
+
return undefined; // absent → undefined, race-safe
|
|
61
|
+
throw e;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async put(key, value) {
|
|
65
|
+
const p = this.resolve(key);
|
|
66
|
+
mkSecretDir(dirname(p)); // harden the parent dir before the secret lands (0700 / private ACL)
|
|
67
|
+
writeSecretFileAtomic(p, value); // temp + rename: a concurrent get sees old or new, never torn
|
|
68
|
+
}
|
|
69
|
+
async delete(key) {
|
|
70
|
+
const p = this.resolve(key);
|
|
71
|
+
try {
|
|
72
|
+
rmSync(p);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
if (e.code !== "ENOENT")
|
|
76
|
+
throw e; // already-absent is success (idempotent)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=secret-store-fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-store-fs.js","sourceRoot":"","sources":["../src/secret-store-fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAoB,MAAM,gBAAgB,CAAC;AAEtF;;;gFAGgF;AAChF,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,aAAa;IACP,IAAI,CAAS;IAE9B,YAAY,IAAY;QACtB,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,yCAAyC;IACjF,CAAC;IAED;;;;kGAI8F;IACtF,OAAO,CAAC,GAAW;QACzB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvE,IAAI,UAAU,CAAC,GAAG,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,4CAA4C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrF,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,uDAAuD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChG,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAC,CAAC,gCAAgC;YACtG,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAa;QAClC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qEAAqE;QAC9F,qBAAqB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,8DAA8D;IACjG,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,CAAC,CAAC,CAAC,CAAC;QACZ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,CAAC,CAAC,CAAC,yCAAyC;QACxG,CAAC;IACH,CAAC;CACF"}
|
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.
|
|
4
|
+
"version": "0.13.0",
|
|
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.
|
|
21
|
+
"@cotal-ai/core": "0.13.0"
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"dist"
|
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
"scripts": {
|
|
30
30
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
31
31
|
"build": "tsc -p tsconfig.json",
|
|
32
|
-
"test": "tsx smoke/preflight.smoke.ts"
|
|
32
|
+
"test": "tsx smoke/preflight.smoke.ts && tsx smoke/maintenance.smoke.ts"
|
|
33
33
|
}
|
|
34
34
|
}
|