cotal-ai 0.91.0 → 0.92.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 (37) hide show
  1. package/dist/run.js +4 -7
  2. package/package.json +17 -17
  3. package/seeded-connectors/claude/dist/index.js +59 -44
  4. package/seeded-connectors/claude/dist/mcp.cjs +855 -651
  5. package/seeded-connectors/claude/dist/mcp.d.ts.map +1 -1
  6. package/seeded-connectors/claude/dist/monitor.cjs +14 -3
  7. package/seeded-connectors/claude/dist/setup.d.ts.map +1 -1
  8. package/seeded-connectors/claude/dist/wake-feed.d.ts +3 -2
  9. package/seeded-connectors/claude/dist/wake-feed.d.ts.map +1 -1
  10. package/seeded-connectors/claude/hooks/native-wake.js +20 -3
  11. package/seeded-connectors/claude/package.json +2 -2
  12. package/seeded-connectors/codex/dist/host.d.ts.map +1 -1
  13. package/seeded-connectors/codex/dist/host.js +909 -721
  14. package/seeded-connectors/codex/dist/index.js +7 -7
  15. package/seeded-connectors/codex/package.json +1 -1
  16. package/seeded-connectors/hermes/dist/index.js +7 -7
  17. package/seeded-connectors/hermes/dist/launch.js +825 -635
  18. package/seeded-connectors/hermes/package.json +1 -1
  19. package/seeded-connectors/hermes/plugin/cotal/_sidecar/standalone.cjs +822 -635
  20. package/seeded-connectors/jcode/dist/host.d.ts.map +1 -1
  21. package/seeded-connectors/jcode/dist/host.js +831 -643
  22. package/seeded-connectors/jcode/dist/index.js +7 -7
  23. package/seeded-connectors/jcode/dist/mcp.js +584 -540
  24. package/seeded-connectors/jcode/package.json +1 -1
  25. package/seeded-connectors/opencode/dist/index.js +7 -7
  26. package/seeded-connectors/opencode/dist/plugin/index.js +834 -642
  27. package/seeded-connectors/opencode/dist/plugin.d.ts.map +1 -1
  28. package/seeded-connectors/opencode/dist/plugin2.d.ts.map +1 -1
  29. package/seeded-connectors/opencode/package.json +1 -1
  30. package/seeded-connectors/pi/dist/index.js +200 -161
  31. package/seeded-connectors/pi/dist/standalone.js +829 -642
  32. package/seeded-connectors/pi/package.json +1 -1
  33. package/seeded-connectors/web/dist/web.d.ts +3 -0
  34. package/seeded-connectors/web/dist/web.d.ts.map +1 -1
  35. package/seeded-connectors/web/dist/web.js +19 -3
  36. package/seeded-connectors/web/dist/web.js.map +1 -1
  37. package/seeded-connectors/web/package.json +1 -1
package/dist/run.js CHANGED
@@ -12,7 +12,7 @@
12
12
  // NOTE: registration order across these imports is NOT guaranteed (tsx's entry interop can
13
13
  // evaluate the smaller daemon graphs first) — display order is a non-goal here; `help` ranks
14
14
  // its groups explicitly (GROUP_ORDER in @cotal-ai/cli).
15
- import { runCli } from "@cotal-ai/cli"; // self-registers the base surface incl. spawn (foreground + --detach) / stop / ps / attach
15
+ import { runCli, stdoutError } from "@cotal-ai/cli"; // self-registers the base surface incl. spawn (foreground + --detach) / stop / ps / attach
16
16
  import "@cotal-ai/manager"; // self-registers `supervise` — the agent-supervisor daemon
17
17
  import "@cotal-ai/delivery"; // self-registers `deliver` — the server-side Plane-3 delivery daemon
18
18
  import "@cotal-ai/runtime"; // self-registers `run` — the workflow-run operator surface (start/resume/ps/journal/answer)
@@ -34,12 +34,9 @@ import { registry } from "@cotal-ai/core";
34
34
  // A CLI must exit quietly when its stdout is closed early — piped to `head`, a pager that quits,
35
35
  // or a shell's process substitution (`source <(cotal completion script bash)`). Node otherwise turns the
36
36
  // closed-pipe write into a fatal unhandled 'error' event with a stack trace. Mirror SIGPIPE: exit
37
- // 0. Registered before any command can write.
38
- process.stdout.on("error", (e) => {
39
- if (e.code === "EPIPE")
40
- process.exit(0);
41
- throw e;
42
- });
37
+ // 0. A command that must close something first, such as a chat session, owns stdout's errors while
38
+ // it runs, and this listener stands down for it. Registered before any command can write.
39
+ process.stdout.on("error", stdoutError);
43
40
  // The four agent connectors (claude/opencode/hermes/pi) are NOT imported here: they are removable,
44
41
  // install-seeded `cotal ext` plugins loaded through the manifest, exactly like a third-party
45
42
  // connector (and like the `@cotal-ai/orca` runtime already is). `runCli` seeds them on first run and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cotal-ai",
3
- "version": "0.91.0",
3
+ "version": "0.92.1",
4
4
  "description": "Cotal — lateral agent coordination over NATS. Run `npx cotal-ai` for the CLI.",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -33,25 +33,25 @@
33
33
  "node": ">=22"
34
34
  },
35
35
  "dependencies": {
36
- "@cotal-ai/auth": "0.91.0",
37
- "@cotal-ai/cli": "0.91.0",
38
- "@cotal-ai/connector-core": "0.91.0",
39
- "@cotal-ai/core": "0.91.0",
40
- "@cotal-ai/delivery": "0.91.0",
41
- "@cotal-ai/manager": "0.91.0",
42
- "@cotal-ai/runtime": "0.91.0",
43
- "@cotal-ai/workspace": "0.91.0"
36
+ "@cotal-ai/auth": "0.92.1",
37
+ "@cotal-ai/cli": "0.92.1",
38
+ "@cotal-ai/connector-core": "0.92.1",
39
+ "@cotal-ai/core": "0.92.1",
40
+ "@cotal-ai/delivery": "0.92.1",
41
+ "@cotal-ai/manager": "0.92.1",
42
+ "@cotal-ai/runtime": "0.92.1",
43
+ "@cotal-ai/workspace": "0.92.1"
44
44
  },
45
45
  "devDependencies": {
46
- "@cotal-ai/connector-claude-code": "0.91.0",
47
- "@cotal-ai/connector-codex": "0.91.0",
48
- "@cotal-ai/connector-hermes": "0.91.0",
49
- "@cotal-ai/connector-jcode": "0.91.0",
50
- "@cotal-ai/connector-opencode": "0.91.0",
51
- "@cotal-ai/linear": "0.91.0",
52
- "@cotal-ai/pi": "0.91.0",
46
+ "@cotal-ai/connector-claude-code": "0.92.1",
47
+ "@cotal-ai/connector-codex": "0.92.1",
48
+ "@cotal-ai/connector-hermes": "0.92.1",
49
+ "@cotal-ai/connector-jcode": "0.92.1",
50
+ "@cotal-ai/connector-opencode": "0.92.1",
51
+ "@cotal-ai/linear": "0.92.1",
52
+ "@cotal-ai/pi": "0.92.1",
53
53
  "@cotal-ai/smoke-kit": "0.0.0",
54
- "@cotal-ai/web": "0.91.0",
54
+ "@cotal-ai/web": "0.92.1",
55
55
  "@nats-io/jetstream": "^3.4.0",
56
56
  "@nats-io/transport-node": "^3.4.0",
57
57
  "typescript": "^5.9.3"
@@ -6567,9 +6567,9 @@ var require_ajv = __commonJS({
6567
6567
  }
6568
6568
  });
6569
6569
 
6570
- // ../../node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.20.0/node_modules/ajv-formats/dist/formats.js
6570
+ // ../../node_modules/.pnpm/ajv-formats@3.0.1/node_modules/ajv-formats/dist/formats.js
6571
6571
  var require_formats = __commonJS({
6572
- "../../node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.20.0/node_modules/ajv-formats/dist/formats.js"(exports) {
6572
+ "../../node_modules/.pnpm/ajv-formats@3.0.1/node_modules/ajv-formats/dist/formats.js"(exports) {
6573
6573
  "use strict";
6574
6574
  Object.defineProperty(exports, "__esModule", { value: true });
6575
6575
  exports.formatNames = exports.fastFormats = exports.fullFormats = void 0;
@@ -6770,9 +6770,9 @@ var require_formats = __commonJS({
6770
6770
  }
6771
6771
  });
6772
6772
 
6773
- // ../../node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.20.0/node_modules/ajv-formats/dist/limit.js
6773
+ // ../../node_modules/.pnpm/ajv-formats@3.0.1/node_modules/ajv-formats/dist/limit.js
6774
6774
  var require_limit = __commonJS({
6775
- "../../node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.20.0/node_modules/ajv-formats/dist/limit.js"(exports) {
6775
+ "../../node_modules/.pnpm/ajv-formats@3.0.1/node_modules/ajv-formats/dist/limit.js"(exports) {
6776
6776
  "use strict";
6777
6777
  Object.defineProperty(exports, "__esModule", { value: true });
6778
6778
  exports.formatLimitDefinition = void 0;
@@ -6842,9 +6842,9 @@ var require_limit = __commonJS({
6842
6842
  }
6843
6843
  });
6844
6844
 
6845
- // ../../node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.20.0/node_modules/ajv-formats/dist/index.js
6845
+ // ../../node_modules/.pnpm/ajv-formats@3.0.1/node_modules/ajv-formats/dist/index.js
6846
6846
  var require_dist = __commonJS({
6847
- "../../node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.20.0/node_modules/ajv-formats/dist/index.js"(exports, module) {
6847
+ "../../node_modules/.pnpm/ajv-formats@3.0.1/node_modules/ajv-formats/dist/index.js"(exports, module) {
6848
6848
  "use strict";
6849
6849
  Object.defineProperty(exports, "__esModule", { value: true });
6850
6850
  var formats_1 = require_formats();
@@ -6892,6 +6892,7 @@ import { homedir as homedir3 } from "node:os";
6892
6892
  import { dirname as dirname2, join as join4, relative } from "node:path";
6893
6893
  import { fileURLToPath } from "node:url";
6894
6894
  import {
6895
+ acquireLock,
6895
6896
  globalConfigPath,
6896
6897
  mcpServerProblem as mcpServerProblem2,
6897
6898
  registry as registry3,
@@ -21781,7 +21782,7 @@ config(en_default());
21781
21782
  import { isConcreteChannel as isConcreteChannel3, channelInAllow as channelInAllow3, AmbiguousPeerError, peerLabel as peerLabel4, assertLifecycleToken as assertLifecycleToken3, isPermissionDenied as isPermissionDenied2, renderLifecycleBlocked, EpEnvelopeError as EpEnvelopeError3, LANG_PROBLEM_DETAIL_KIND, formatAge, presenceAges, presenceText } from "@cotal-ai/core";
21782
21783
 
21783
21784
  // ../connector-core/dist/orientation.js
21784
- import { peerLabel as peerLabel3 } from "@cotal-ai/core";
21785
+ import { parsePrincipalKey as parsePrincipalKey2, peerLabel as peerLabel3 } from "@cotal-ai/core";
21785
21786
 
21786
21787
  // ../connector-core/dist/docs.js
21787
21788
  var STOP = new Set("a an and are as at be by do for from has how in is it of on or that the this to use using was what when where which who with you your".split(" "));
@@ -23697,6 +23698,14 @@ function cotalHome() {
23697
23698
  function marketplaceDir() {
23698
23699
  return join4(cotalHome(), "claude-plugin");
23699
23700
  }
23701
+ function withPluginLock(run) {
23702
+ const lock = acquireLock(join4(marketplaceDir(), ".setup.lock"), { label: "Claude plugin setup" });
23703
+ try {
23704
+ return run();
23705
+ } finally {
23706
+ lock.release();
23707
+ }
23708
+ }
23700
23709
  function materialize(name, root, assets, version2, files = {}) {
23701
23710
  const market = marketplaceDir();
23702
23711
  mkdirSync(market, { recursive: true });
@@ -23817,8 +23826,8 @@ function verify(name, scope, expectedVersion) {
23817
23826
  if (!match) throw new Error(`plugin ${name}@${MARKETPLACE} (${where}) is not installed`);
23818
23827
  if (match.enabled !== true || match.errors?.length)
23819
23828
  throw new Error(`plugin ${name}@${MARKETPLACE} (${where}) did not load: ${JSON.stringify({ enabled: match.enabled, errors: match.errors })}`);
23820
- if (expectedVersion && match.version !== expectedVersion)
23821
- throw new Error(`plugin ${name}@${MARKETPLACE} loaded version ${String(match.version)}; expected ${expectedVersion}`);
23829
+ if (expectedVersion && !resolvedPluginCurrent(match, expectedVersion, name))
23830
+ throw new Error(`plugin ${name}@${MARKETPLACE} resolved payload does not match version ${expectedVersion}`);
23822
23831
  }
23823
23832
  function install(name, scope, expectedVersion) {
23824
23833
  writeMarketplace();
@@ -23840,12 +23849,12 @@ function refreshInstalls(name, entries, version2) {
23840
23849
  const cwd = scope === "user" ? cotalHome() : entry.projectPath;
23841
23850
  if (typeof cwd !== "string") throw new Error(`${name}@${MARKETPLACE} (${scope} scope) has no project path`);
23842
23851
  if (!statSync2(cwd, { throwIfNoEntry: false })?.isDirectory()) continue;
23843
- if (entry.version === version2 && resolvedPluginCurrent(entry, version2, name)) continue;
23852
+ if (resolvedPluginCurrent(entry, version2, name)) continue;
23844
23853
  const update = commandIn(cwd, "plugin", "update", `${name}@${MARKETPLACE}`, "--scope", scope);
23845
23854
  if (update.status !== 0) throw new Error(`plugin update failed (${name}, ${scope} scope):
23846
23855
  ${update.output}`);
23847
23856
  const current = listPlugins(cwd).find((candidate) => candidate.id === entry.id && candidate.scope === scope && (scope === "user" || candidate.projectPath === entry.projectPath));
23848
- if (!current || current.version !== version2 || !resolvedPluginCurrent(current, version2, name))
23857
+ if (!current || !resolvedPluginCurrent(current, version2, name))
23849
23858
  throw new Error(`${name}@${MARKETPLACE} (${scope} scope) did not load the updated plugin ${version2}`);
23850
23859
  }
23851
23860
  }
@@ -23910,7 +23919,7 @@ function skillsRow(entries, { version: version2, skillsRemedy }) {
23910
23919
  if (!match || match.enabled === false) return row("off", `not installed \xB7 ${skillsRemedy}`);
23911
23920
  const errors = match.errors ?? match.error;
23912
23921
  if (Array.isArray(errors) ? errors.length > 0 : Boolean(errors)) return row("error", `load error \xB7 ${skillsRemedy}`);
23913
- if (match.version === version2) return row("ok", "current");
23922
+ if (resolvedPluginCurrent(match, version2, "cotal-skills")) return row("ok", "current");
23914
23923
  return row("warn", `${typeof match.version === "string" ? `v${match.version} \u2260 v${version2} \xB7 ` : ""}stale \xB7 ${skillsRemedy}`);
23915
23924
  }
23916
23925
  function pluginRow(entries, { version: version2 }) {
@@ -23928,7 +23937,7 @@ function pluginRow(entries, { version: version2 }) {
23928
23937
  }
23929
23938
  if (typeof materialized !== "string" || !materialized.startsWith(`${version2}+`)) return row("warn", "stale \xB7 run `cotal setup`");
23930
23939
  const active = installs.filter((entry) => entry.scope === "user" || typeof entry.projectPath !== "string" || statSync2(entry.projectPath, { throwIfNoEntry: false })?.isDirectory());
23931
- if (active.some((entry) => entry.version !== materialized || !resolvedPluginCurrent(entry, materialized)))
23940
+ if (active.some((entry) => !resolvedPluginCurrent(entry, materialized)))
23932
23941
  return row("warn", "stale \xB7 run `cotal setup`");
23933
23942
  if (installs.some((entry) => entry.scope === "user")) return row("ok", "current (user scope)");
23934
23943
  return row("ok", `current (${installs.length} install${installs.length === 1 ? "" : "s"})`);
@@ -23981,12 +23990,14 @@ var claudeSetupProvider = {
23981
23990
  explain: "Installs Cotal messaging for Claude Code, including supported local sessions in Desktop's Code tab. Reopen Claude after setup.",
23982
23991
  context: [DOCS_URL],
23983
23992
  run({ cotal }) {
23984
- const version2 = materializeCotal(cotal);
23985
- install("cotal", "user", version2);
23986
- const app = desktop(cotal, true);
23987
- const removed = retireProjectInstalls();
23988
- const replaced = removed ? `, replacing ${removed} project install${removed === 1 ? "" : "s"}` : "";
23989
- return `cotal@${MARKETPLACE} (user scope${replaced})${app ? `; ${app}` : ""}`;
23993
+ return withPluginLock(() => {
23994
+ const version2 = materializeCotal(cotal);
23995
+ install("cotal", "user", version2);
23996
+ const app = desktop(cotal, true);
23997
+ const removed = retireProjectInstalls();
23998
+ const replaced = removed ? `, replacing ${removed} project install${removed === 1 ? "" : "s"}` : "";
23999
+ return `cotal@${MARKETPLACE} (user scope${replaced})${app ? `; ${app}` : ""}`;
24000
+ });
23990
24001
  }
23991
24002
  },
23992
24003
  refresh: {
@@ -23995,28 +24006,30 @@ var claudeSetupProvider = {
23995
24006
  explain: "Rewrites the copy of the Cotal plugin that Claude Code sessions load, and Cotal's entry in Claude Desktop, for this release.",
23996
24007
  context: [DOCS_URL],
23997
24008
  run({ cotal, skills }) {
23998
- const entries = installedForRefresh();
23999
- const installs = entries.filter((entry) => entry.id === `cotal@${MARKETPLACE}`);
24000
- const skillInstalls = entries.filter((entry) => entry.id === `cotal-skills@${MARKETPLACE}`);
24001
- const path = desktopConfigPath();
24002
- const app = path !== void 0 && readDesktopEntry(path) !== void 0;
24003
- if (!installs.length && !skillInstalls.length && !app) return "not installed";
24004
- if (skillInstalls.length && !skills) throw new Error("current skills are required to refresh the installed Claude skills plugin");
24005
- const version2 = installs.length || app ? materializeCotal(cotal) : void 0;
24006
- if (skillInstalls.length) materializeSkills(skills);
24007
- if (installs.length || skillInstalls.length) writeMarketplace();
24008
- const parts = [];
24009
- if (installs.length) {
24010
- refreshInstalls("cotal", installs, version2);
24011
- parts.push(`cotal@${MARKETPLACE} ${version2}; reload plugins or reopen Claude to load it in running sessions`);
24012
- }
24013
- if (skillInstalls.length) {
24014
- refreshInstalls("cotal-skills", skillInstalls, skills.version);
24015
- parts.push(`cotal-skills@${MARKETPLACE} ${skills.version}`);
24016
- }
24017
- const desktopText = app ? desktop(cotal, false) : void 0;
24018
- if (desktopText) parts.push(desktopText);
24019
- return parts.join("; ");
24009
+ return withPluginLock(() => {
24010
+ const entries = installedForRefresh();
24011
+ const installs = entries.filter((entry) => entry.id === `cotal@${MARKETPLACE}`);
24012
+ const skillInstalls = entries.filter((entry) => entry.id === `cotal-skills@${MARKETPLACE}`);
24013
+ const path = desktopConfigPath();
24014
+ const app = path !== void 0 && readDesktopEntry(path) !== void 0;
24015
+ if (!installs.length && !skillInstalls.length && !app) return "not installed";
24016
+ if (skillInstalls.length && !skills) throw new Error("current skills are required to refresh the installed Claude skills plugin");
24017
+ const version2 = installs.length || app ? materializeCotal(cotal) : void 0;
24018
+ if (skillInstalls.length) materializeSkills(skills);
24019
+ if (installs.length || skillInstalls.length) writeMarketplace();
24020
+ const parts = [];
24021
+ if (installs.length) {
24022
+ refreshInstalls("cotal", installs, version2);
24023
+ parts.push(`cotal@${MARKETPLACE} ${version2}; reload plugins or reopen Claude to load it in running sessions`);
24024
+ }
24025
+ if (skillInstalls.length) {
24026
+ refreshInstalls("cotal-skills", skillInstalls, skills.version);
24027
+ parts.push(`cotal-skills@${MARKETPLACE} ${skills.version}`);
24028
+ }
24029
+ const desktopText = app ? desktop(cotal, false) : void 0;
24030
+ if (desktopText) parts.push(desktopText);
24031
+ return parts.join("; ");
24032
+ });
24020
24033
  }
24021
24034
  },
24022
24035
  skills: {
@@ -24025,9 +24038,11 @@ var claudeSetupProvider = {
24025
24038
  explain: "Installs Cotal's authored skills as a Claude Code plugin.",
24026
24039
  context: [DOCS_URL],
24027
24040
  run(input) {
24028
- materializeSkills(input);
24029
- install("cotal-skills", "user", input.version);
24030
- return `cotal-skills@${MARKETPLACE} (user scope)`;
24041
+ return withPluginLock(() => {
24042
+ materializeSkills(input);
24043
+ install("cotal-skills", "user", input.version);
24044
+ return `cotal-skills@${MARKETPLACE} (user scope)`;
24045
+ });
24031
24046
  }
24032
24047
  },
24033
24048
  mcpServers: {