@cotal-ai/workspace 0.11.1 → 0.11.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.
@@ -1,14 +1,16 @@
1
- import type { Command, FlagSpec } from "@cotal-ai/core";
1
+ import type { Command, Extension, ExtensionRef, FlagSpec } from "@cotal-ai/core";
2
+ import { type LocalProcess } from "./local-process.js";
2
3
  /**
3
- * Operator-installed CLI extensions (`cotal ext add <npm-package>`): the workstation state.
4
+ * Operator-installed extensions (`cotal ext add <npm-package>`): the workstation state.
4
5
  *
5
6
  * Extensions install into a cotal-owned npm prefix (`$XDG_CONFIG_HOME/cotal/extensions/`, with
6
7
  * its own package.json) — never the user's project. A MANIFEST records each installed package
7
- * plus a CACHE of the command metadata it contributed. Two hard rules from the design review:
8
+ * plus a cache of every registry key it contributed and display metadata for commands. Two hard
9
+ * rules from the design review:
8
10
  *
9
- * - The manifest is a DISPLAY/TAB cache ONLY. Help and `__complete` read it (so a <TAB> never
10
- * imports an extension), but at dispatch the freshly-imported command's LIVE specs are
11
- * authoritative cached specs never drive parsing (version skew would corrupt `run`'s input).
11
+ * - Cached command specs are DISPLAY/TAB ONLY: dispatch uses the freshly imported command's live
12
+ * grammar. Local-process metadata is deliberately declarative and operational, so lifecycle
13
+ * commands can act without importing third-party code.
12
14
  * - `name@version` is pinned at add time and verified at run-import; a mismatch is a loud error
13
15
  * prescribing `cotal ext add` again — never a silent re-cache.
14
16
  */
@@ -31,7 +33,12 @@ export interface InstalledExtension {
31
33
  readonly version: string;
32
34
  /** The spec the operator passed to `ext add` (registry range, file:, tarball…) — for re-adds. */
33
35
  readonly spec: string;
36
+ /** Every registry contribution made by the package. Older command-only manifests omit this; the
37
+ * loader derives `command:<name>` entries from `commands` for compatibility. */
38
+ readonly provides?: readonly ExtensionRef[];
34
39
  readonly commands: readonly CachedCommand[];
40
+ /** Declarative process metadata used without importing package code. */
41
+ readonly localProcesses?: readonly LocalProcess[];
35
42
  }
36
43
  export interface ExtensionsManifest {
37
44
  readonly extensions: readonly InstalledExtension[];
@@ -39,12 +46,28 @@ export interface ExtensionsManifest {
39
46
  /** The extensions prefix: `<config>/cotal/extensions` — its own npm installation root. */
40
47
  export declare function extensionsDir(): string;
41
48
  export declare function extensionsManifestPath(): string;
49
+ export declare function extensionMutationLockPath(): string;
50
+ export type ExtensionMutationLockState = {
51
+ readonly state: "absent" | "stale";
52
+ } | {
53
+ readonly state: "active";
54
+ readonly owner: number;
55
+ };
56
+ /** Inspect the extension-prefix writer lock. Permission denial means the owner may still be live;
57
+ * only ESRCH proves that a recorded owner is gone. */
58
+ export declare function extensionMutationLockState(): ExtensionMutationLockState;
42
59
  /** Load the manifest. Missing file → no extensions. A CORRUPT file is a loud error (never treat
43
60
  * installed extensions as absent — commands would silently vanish from help). */
44
61
  export declare function loadExtensionsManifest(): ExtensionsManifest;
45
62
  export declare function saveExtensionsManifest(m: ExtensionsManifest): void;
46
63
  /** Strip a live {@link Command} down to its serializable display surface for the cache. */
47
64
  export declare function cacheCommand(cmd: Command): CachedCommand;
65
+ /** Stable, serializable registry keys contributed by one imported package. */
66
+ export declare function cacheExtension(ext: Extension): ExtensionRef;
67
+ export declare function cacheLocalProcess(component: LocalProcess): LocalProcess;
68
+ export declare function extensionLocalProcesses(ext: InstalledExtension): readonly LocalProcess[];
69
+ /** Registry contributions recorded for an installed package, including old command-only entries. */
70
+ export declare function extensionProvides(ext: InstalledExtension): readonly ExtensionRef[];
48
71
  /** The installed package's on-disk root inside the prefix. */
49
72
  export declare function extensionPackageDir(pkg: string): string;
50
73
  /** The installed package's CURRENT version, read from disk (undefined when not installed). */
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAGxD;;;;;;;;;;;;GAYG;AAEH;;qBAEqB;AACrB,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iGAAiG;IACjG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACpD;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;kFACkF;AAClF,wBAAgB,sBAAsB,IAAI,kBAAkB,CAY3D;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAGlE;AAED,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAUxD;AAED,8DAA8D;AAC9D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,8FAA8F;AAC9F,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKzE"}
1
+ {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEzE;;;;;;;;;;;;;GAaG;AAEH;;qBAEqB;AACrB,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iGAAiG;IACjG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;qFACiF;IACjF,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,wEAAwE;IACxE,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACpD;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAA;CAAE,GACtC;IAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD;sDACsD;AACtD,wBAAgB,0BAA0B,IAAI,0BAA0B,CAqBvE;AAED;kFACkF;AAClF,wBAAgB,sBAAsB,IAAI,kBAAkB,CAY3D;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAGlE;AAED,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAUxD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,YAAY,CAE3D;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,YAAY,GAAG,YAAY,CAkBvE;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,kBAAkB,GAAG,SAAS,YAAY,EAAE,CAExF;AAED,oGAAoG;AACpG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,kBAAkB,GAAG,SAAS,YAAY,EAAE,CAElF;AAED,8DAA8D;AAC9D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,8FAA8F;AAC9F,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKzE"}
@@ -1,6 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { join } from "node:path";
2
+ import { dirname, join } from "node:path";
3
3
  import { globalConfigDir } from "@cotal-ai/core";
4
+ import { localProcessPath } from "./local-process.js";
4
5
  /** The extensions prefix: `<config>/cotal/extensions` — its own npm installation root. */
5
6
  export function extensionsDir() {
6
7
  return join(globalConfigDir(), "extensions");
@@ -8,6 +9,38 @@ export function extensionsDir() {
8
9
  export function extensionsManifestPath() {
9
10
  return join(extensionsDir(), "extensions.json");
10
11
  }
12
+ export function extensionMutationLockPath() {
13
+ return join(dirname(extensionsDir()), ".extensions.lock");
14
+ }
15
+ /** Inspect the extension-prefix writer lock. Permission denial means the owner may still be live;
16
+ * only ESRCH proves that a recorded owner is gone. */
17
+ export function extensionMutationLockState() {
18
+ const lock = extensionMutationLockPath();
19
+ let raw;
20
+ try {
21
+ raw = readFileSync(lock, "utf8");
22
+ }
23
+ catch (e) {
24
+ if (e.code === "ENOENT")
25
+ return { state: "absent" };
26
+ throw new Error(`can't read extension mutation lock ${lock}: ${e.message}`);
27
+ }
28
+ const owner = Number(raw.trim());
29
+ if (!Number.isInteger(owner) || owner <= 0)
30
+ return { state: "stale" };
31
+ try {
32
+ process.kill(owner, 0);
33
+ return { state: "active", owner };
34
+ }
35
+ catch (e) {
36
+ const code = e.code;
37
+ if (code === "ESRCH")
38
+ return { state: "stale" };
39
+ if (code === "EPERM")
40
+ return { state: "active", owner };
41
+ throw new Error(`can't check extension mutation lock owner ${owner}: ${e.message}`);
42
+ }
43
+ }
11
44
  /** Load the manifest. Missing file → no extensions. A CORRUPT file is a loud error (never treat
12
45
  * installed extensions as absent — commands would silently vanish from help). */
13
46
  export function loadExtensionsManifest() {
@@ -42,6 +75,38 @@ export function cacheCommand(cmd) {
42
75
  positionals: cmd.positionals,
43
76
  };
44
77
  }
78
+ /** Stable, serializable registry keys contributed by one imported package. */
79
+ export function cacheExtension(ext) {
80
+ return { kind: ext.kind, name: ext.name };
81
+ }
82
+ export function cacheLocalProcess(component) {
83
+ if (typeof component.pidFile !== "string")
84
+ throw new Error(`local-process ${component.name} must declare a string pidFile template`);
85
+ localProcessPath(component.pidFile, { root: process.cwd(), space: "validation" });
86
+ for (const artifact of component.artifacts ?? []) {
87
+ if (typeof artifact !== "string")
88
+ throw new Error(`local-process ${component.name} artifacts must be string templates`);
89
+ localProcessPath(artifact, { root: process.cwd(), space: "validation" });
90
+ }
91
+ return {
92
+ kind: "local-process",
93
+ name: component.name,
94
+ label: component.label,
95
+ order: component.order,
96
+ pidFile: component.pidFile,
97
+ artifacts: component.artifacts,
98
+ stopLast: component.stopLast,
99
+ clearsMesh: component.clearsMesh,
100
+ visibleWhen: component.visibleWhen,
101
+ };
102
+ }
103
+ export function extensionLocalProcesses(ext) {
104
+ return ext.localProcesses ?? [];
105
+ }
106
+ /** Registry contributions recorded for an installed package, including old command-only entries. */
107
+ export function extensionProvides(ext) {
108
+ return ext.provides ?? ext.commands.map((command) => ({ kind: "command", name: command.name }));
109
+ }
45
110
  /** The installed package's on-disk root inside the prefix. */
46
111
  export function extensionPackageDir(pkg) {
47
112
  return join(extensionsDir(), "node_modules", pkg);
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA2CjD,0FAA0F;AAC1F,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,eAAe,EAAE,EAAE,YAAY,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,CAAC,aAAa,EAAE,EAAE,iBAAiB,CAAC,CAAC;AAClD,CAAC;AAED;kFACkF;AAClF,MAAM,UAAU,sBAAsB;IACpC,MAAM,CAAC,GAAG,sBAAsB,EAAE,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC9C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,KAAM,CAAW,CAAC,OAAO,mDAAmD,CAAC,CAAC;IAChI,CAAC;IACD,MAAM,CAAC,GAAG,MAA4B,CAAC;IACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,yBAAyB,CAAC,CAAC;IAC7G,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,CAAqB;IAC1D,SAAS,CAAC,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,aAAa,CAAC,sBAAsB,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC7E,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,WAAW,EAAE,GAAG,CAAC,WAAW;KAC7B,CAAC;AACJ,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,OAAO,IAAI,CAAC,aAAa,EAAE,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;AACpD,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,yBAAyB,CAAC,GAAW;IACnD,MAAM,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACrC,MAAM,CAAC,GAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAA0B,CAAC,OAAO,CAAC;IAChF,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export * from "./colors.js";
5
5
  export * from "./connect.js";
6
6
  export * from "./default-agent.js";
7
7
  export * from "./extensions.js";
8
+ export * from "./local-process.js";
8
9
  export * from "./flags.js";
9
10
  export * from "./provenance.js";
10
11
  export * from "./mesh-registry.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ export * from "./colors.js";
5
5
  export * from "./connect.js";
6
6
  export * from "./default-agent.js";
7
7
  export * from "./extensions.js";
8
+ export * from "./local-process.js";
8
9
  export * from "./flags.js";
9
10
  export * from "./provenance.js";
10
11
  export * from "./mesh-registry.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { Extension } from "@cotal-ai/core";
2
+ /** Context supplied to local process providers by workstation commands such as `down` and `status`. */
3
+ export interface LocalProcessContext {
4
+ readonly root: string;
5
+ readonly space: string;
6
+ readonly userAuth?: boolean;
7
+ }
8
+ /** A workstation-owned process recorded by a pidfile under a mesh root. Optional packages register
9
+ * these beside their commands so lifecycle commands stay ignorant of package-specific processes.
10
+ * Metadata is declarative and cached at install time: status/down never import package code. An
11
+ * extension-provided process must claim its pidfile with an exclusive create and refuse an existing
12
+ * file; extension removal reserves the same path so startup and uninstall cannot cross. */
13
+ export interface LocalProcess extends Extension {
14
+ readonly kind: "local-process";
15
+ readonly name: string;
16
+ readonly label: string;
17
+ /** Lower orders stop first; the broker should remain last so dependants can shut down cleanly. */
18
+ readonly order?: number;
19
+ /** Path relative to `<root>/.cotal`; `{space}` expands to the URL-encoded space name. */
20
+ readonly pidFile: string;
21
+ /** Files removed only after the process is confirmed gone. Same template rules as `pidFile`. */
22
+ readonly artifacts?: readonly string[];
23
+ /** Refuse selective shutdown while any unselected registered process is still live. */
24
+ readonly stopLast?: boolean;
25
+ /** Removing this process also clears transient run state and the machine mesh registry entry. */
26
+ readonly clearsMesh?: boolean;
27
+ /** Hide this process from status unless the selected mesh uses per-user auth. */
28
+ readonly visibleWhen?: "user-auth";
29
+ }
30
+ /** Resolve a declarative local-process path, rejecting absolute/traversal templates. */
31
+ export declare function localProcessPath(template: string, context: LocalProcessContext): string;
32
+ export declare function localProcessVisible(process: LocalProcess, context: LocalProcessContext): boolean;
33
+ //# sourceMappingURL=local-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-process.d.ts","sourceRoot":"","sources":["../src/local-process.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,uGAAuG;AACvG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;4FAI4F;AAC5F,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kGAAkG;IAClG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gGAAgG;IAChG,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,iGAAiG;IACjG,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,iFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;CACpC;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAOvF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAEhG"}
@@ -0,0 +1,15 @@
1
+ import { isAbsolute, join, normalize } from "node:path";
2
+ /** Resolve a declarative local-process path, rejecting absolute/traversal templates. */
3
+ export function localProcessPath(template, context) {
4
+ if (!template.trim())
5
+ throw new Error("local-process path must not be empty");
6
+ const expanded = template.replaceAll("{space}", encodeURIComponent(context.space));
7
+ const normalized = normalize(expanded);
8
+ if (normalized === "." || isAbsolute(expanded) || normalized === ".." || normalized.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`))
9
+ throw new Error(`local-process path must stay under .cotal: ${JSON.stringify(template)}`);
10
+ return join(context.root, ".cotal", normalized);
11
+ }
12
+ export function localProcessVisible(process, context) {
13
+ return process.visibleWhen !== "user-auth" || context.userAuth === true;
14
+ }
15
+ //# sourceMappingURL=local-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-process.js","sourceRoot":"","sources":["../src/local-process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAiCxD,wFAAwF;AACxF,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,OAA4B;IAC7E,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACnF,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QAC9I,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC5F,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAqB,EAAE,OAA4B;IACrF,OAAO,OAAO,CAAC,WAAW,KAAK,WAAW,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC;AAC1E,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.11.1",
4
+ "version": "0.11.3",
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.11.1"
21
+ "@cotal-ai/core": "0.11.3"
22
22
  },
23
23
  "files": [
24
24
  "dist"