comisai 1.0.5 → 1.0.6

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,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/agent",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "AI agent executor, budget control, and session management for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/channels",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Chat platform adapters — Discord, Telegram, Slack, WhatsApp, Signal, iMessage, IRC, LINE",
@@ -11,16 +11,48 @@
11
11
  import { existsSync, readFileSync } from "node:fs";
12
12
  import os from "node:os";
13
13
  import WebSocket from "ws";
14
+ import { loadEnvFile } from "@comis/core";
14
15
  /** Default connection timeout in milliseconds. */
15
16
  const CONNECTION_TIMEOUT_MS = 2000;
16
17
  /** Fallback gateway WebSocket URL when no config is found. */
17
18
  const FALLBACK_GATEWAY_URL = "ws://localhost:4766/ws";
19
+ /** Whether we have already loaded ~/.comis/.env into process.env. */
20
+ let envFileLoaded = false;
21
+ /**
22
+ * Ensure ~/.comis/.env is loaded into process.env (once).
23
+ *
24
+ * The daemon calls loadEnvFile() at startup, but the CLI does not.
25
+ * Config values like `${COMIS_GATEWAY_TOKEN}` reference env vars that
26
+ * live in the .env file, so the CLI must load it too before resolving.
27
+ */
28
+ function ensureEnvFileLoaded() {
29
+ if (envFileLoaded)
30
+ return;
31
+ envFileLoaded = true;
32
+ const envPath = os.homedir() + "/.comis/.env";
33
+ loadEnvFile(envPath);
34
+ }
35
+ /**
36
+ * Resolve `${VAR}` references in a string using process.env.
37
+ *
38
+ * Returns the original string if it contains no references or if the
39
+ * referenced variable is not set.
40
+ */
41
+ function resolveEnvRef(value) {
42
+ const match = value.match(/^\$\{([A-Z_][A-Z0-9_]*)\}$/);
43
+ if (!match)
44
+ return value;
45
+ // eslint-disable-next-line no-restricted-syntax -- CLI bootstrap before SecretManager
46
+ const resolved = process.env[match[1]];
47
+ return resolved ?? value;
48
+ }
18
49
  /**
19
50
  * Resolve gateway URL, token, and TLS status from config file on disk.
20
51
  *
21
52
  * Reads ~/.comis/config.yaml (matching daemon defaults) to extract
22
53
  * gateway.host, gateway.port, TLS configuration, and the first token secret.
23
54
  * Uses a minimal line-based parser to avoid importing the full YAML library.
55
+ * Resolves `${VAR}` references in token values via ~/.comis/.env.
24
56
  */
25
57
  function resolveFromConfig() {
26
58
  const configPath = os.homedir() + "/.comis/config.yaml";
@@ -86,6 +118,15 @@ function resolveFromConfig() {
86
118
  }
87
119
  }
88
120
  }
121
+ // Resolve ${VAR} references in the token (e.g. ${COMIS_GATEWAY_TOKEN})
122
+ if (token && token.startsWith("${")) {
123
+ ensureEnvFileLoaded();
124
+ token = resolveEnvRef(token);
125
+ // If still unresolved, treat as no token
126
+ if (token.startsWith("${")) {
127
+ token = undefined;
128
+ }
129
+ }
89
130
  const protocol = tls ? "wss" : "ws";
90
131
  return { url: `${protocol}://${host}:${port}/ws`, token, tls };
91
132
  }
@@ -161,6 +202,7 @@ export async function createRpcClient(url, token) {
161
202
  }
162
203
  const ws = new WebSocket(url, { headers });
163
204
  let nextId = 1;
205
+ let closed = false;
164
206
  const pending = new Map();
165
207
  const notificationHandlers = [];
166
208
  // Connection timeout
@@ -172,6 +214,9 @@ export async function createRpcClient(url, token) {
172
214
  clearTimeout(timeout);
173
215
  resolve({
174
216
  call(method, params) {
217
+ if (closed) {
218
+ return Promise.reject(new Error("Connection closed unexpectedly"));
219
+ }
175
220
  const id = nextId++;
176
221
  return new Promise((res, rej) => {
177
222
  pending.set(id, { resolve: res, reject: rej });
@@ -179,6 +224,7 @@ export async function createRpcClient(url, token) {
179
224
  });
180
225
  },
181
226
  close() {
227
+ closed = true;
182
228
  // Reject all pending requests
183
229
  for (const [, p] of pending) {
184
230
  p.reject(new Error("Client closed"));
@@ -237,6 +283,7 @@ export async function createRpcClient(url, token) {
237
283
  });
238
284
  ws.on("close", () => {
239
285
  clearTimeout(timeout);
286
+ closed = true;
240
287
  // Reject all pending requests on unexpected close
241
288
  for (const [, p] of pending) {
242
289
  p.reject(new Error("Connection closed unexpectedly"));
@@ -255,6 +302,7 @@ export async function createRpcClient(url, token) {
255
302
  * @returns The result of fn
256
303
  */
257
304
  export async function withClient(fn) {
305
+ ensureEnvFileLoaded();
258
306
  const configDefaults = resolveFromConfig();
259
307
  // eslint-disable-next-line no-restricted-syntax -- CLI bootstrap before SecretManager
260
308
  const url = process.env["COMIS_GATEWAY_URL"] ?? configDefaults.url;
@@ -8,14 +8,46 @@
8
8
  *
9
9
  * @module
10
10
  */
11
+ import * as os from "node:os";
11
12
  import chalk from "chalk";
12
- import { loadConfigFile, validateConfig, deepMerge } from "@comis/core";
13
+ import { loadConfigFile, validateConfig, deepMerge, loadEnvFile } from "@comis/core";
13
14
  import { withClient } from "../client/rpc-client.js";
14
15
  import { success, error, info, warn, json } from "../output/format.js";
15
16
  import { withSpinner } from "../output/spinner.js";
16
17
  import { renderTable, renderKeyValue } from "../output/table.js";
17
18
  /** Default config paths to check (matching daemon defaults). */
18
- const DEFAULT_CONFIG_PATHS = ["/etc/comis/config.yaml", "/etc/comis/config.local.yaml"];
19
+ const DEFAULT_CONFIG_PATHS = [
20
+ os.homedir() + "/.comis/config.yaml",
21
+ os.homedir() + "/.comis/config.local.yaml",
22
+ "/etc/comis/config.yaml",
23
+ "/etc/comis/config.local.yaml",
24
+ ];
25
+ /** Pattern matching `${VAR_NAME}` env var references. */
26
+ const ENV_REF_RE = /\$\{([A-Z_][A-Z0-9_]*)\}/g;
27
+ /**
28
+ * Deep-walk an object and resolve `${VAR}` references using process.env.
29
+ * Mutates in place for efficiency since the input is a transient merge result.
30
+ */
31
+ function resolveEnvRefs(obj) {
32
+ for (const [key, value] of Object.entries(obj)) {
33
+ if (typeof value === "string" && value.includes("${")) {
34
+ obj[key] = value.replace(ENV_REF_RE, (match, varName) => {
35
+ // eslint-disable-next-line no-restricted-syntax -- CLI bootstrap before SecretManager
36
+ return process.env[varName] ?? match;
37
+ });
38
+ }
39
+ else if (value && typeof value === "object" && !Array.isArray(value)) {
40
+ resolveEnvRefs(value);
41
+ }
42
+ else if (Array.isArray(value)) {
43
+ for (const item of value) {
44
+ if (item && typeof item === "object") {
45
+ resolveEnvRefs(item);
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
19
51
  /**
20
52
  * Register the `config` subcommand group on the program.
21
53
  *
@@ -56,6 +88,9 @@ export function registerConfigCommand(program) {
56
88
  if (!anyFound) {
57
89
  info("No config files found. Validating with defaults only.");
58
90
  }
91
+ // Load .env so ${VAR} references resolve before validation
92
+ loadEnvFile(os.homedir() + "/.comis/.env");
93
+ resolveEnvRefs(merged);
59
94
  // Validate merged config
60
95
  const validation = validateConfig(merged);
61
96
  if (validation.ok) {
@@ -181,6 +181,19 @@ async function detectServiceManager() {
181
181
  function systemctlArgs(manager, ...rest) {
182
182
  return manager === "systemd-user" ? ["--user", ...rest] : rest;
183
183
  }
184
+ /**
185
+ * Execute a systemctl command, auto-escalating to sudo for system-scope
186
+ * services when running as a non-root user.
187
+ */
188
+ async function execSystemctl(manager, ...args) {
189
+ const fullArgs = systemctlArgs(manager, ...args);
190
+ // System-scope systemd requires root; escalate via sudo if we're not root
191
+ // eslint-disable-next-line no-restricted-syntax -- CLI bootstrap before SecretManager
192
+ if (manager === "systemd" && process.getuid?.() !== 0) {
193
+ return exec("sudo", ["systemctl", ...fullArgs], { timeout: 15_000 });
194
+ }
195
+ return exec("systemctl", fullArgs, { timeout: 15_000 });
196
+ }
184
197
  // ---------- Subcommand handlers ----------
185
198
  /**
186
199
  * Start the daemon in direct mode (no systemd).
@@ -242,7 +255,7 @@ async function handleDaemonStart() {
242
255
  case "systemd-user": {
243
256
  const scope = manager === "systemd-user" ? "systemd (user scope)" : "systemd";
244
257
  info(`Starting daemon via ${scope}...`);
245
- await exec("systemctl", systemctlArgs(manager, "start", "comis"), { timeout: 10_000 });
258
+ await execSystemctl(manager, "start", "comis");
246
259
  success("Daemon started");
247
260
  return;
248
261
  }
@@ -273,7 +286,7 @@ async function handleDaemonStop() {
273
286
  case "systemd-user": {
274
287
  const scope = manager === "systemd-user" ? "systemd (user scope)" : "systemd";
275
288
  info(`Stopping daemon via ${scope}...`);
276
- await exec("systemctl", systemctlArgs(manager, "stop", "comis"), { timeout: 15_000 });
289
+ await execSystemctl(manager, "stop", "comis");
277
290
  success("Daemon stopped");
278
291
  return;
279
292
  }
@@ -477,24 +490,44 @@ async function handleDaemonLogs(options) {
477
490
  }
478
491
  }
479
492
  async function streamSystemdLogs(scope, options) {
480
- const args = ["--unit=comis", "--no-pager", `-n${options.lines}`];
493
+ const jArgs = ["--unit=comis", "--no-pager", `-n${options.lines}`];
481
494
  if (scope === "systemd-user")
482
- args.push("--user");
495
+ jArgs.push("--user");
496
+ if (options.follow)
497
+ jArgs.push("--follow");
483
498
  if (options.follow) {
484
- args.push("--follow");
485
- const child = spawn("journalctl", args, { stdio: "inherit" });
499
+ const child = spawn("journalctl", jArgs, { stdio: "inherit" });
486
500
  child.on("error", (err) => {
487
501
  error(`Failed to read logs: ${err.message}`);
488
502
  process.exit(1);
489
503
  });
490
504
  return;
491
505
  }
492
- const { stdout } = await exec("journalctl", args, { timeout: 10_000 });
493
- if (stdout.trim()) {
494
- console.log(stdout);
506
+ // Try journalctl directly first (works when user is in systemd-journal group),
507
+ // then fall back to sudo for system-scope journals.
508
+ try {
509
+ const { stdout } = await exec("journalctl", jArgs, { timeout: 10_000 });
510
+ if (stdout.trim()) {
511
+ console.log(stdout);
512
+ }
513
+ else {
514
+ info("No logs found");
515
+ }
495
516
  }
496
- else {
497
- info("No logs found");
517
+ catch {
518
+ // eslint-disable-next-line no-restricted-syntax -- CLI bootstrap before SecretManager
519
+ if (scope === "systemd" && process.getuid?.() !== 0) {
520
+ const { stdout } = await exec("sudo", ["journalctl", ...jArgs], { timeout: 10_000 });
521
+ if (stdout.trim()) {
522
+ console.log(stdout);
523
+ }
524
+ else {
525
+ info("No logs found");
526
+ }
527
+ }
528
+ else {
529
+ throw new Error("Failed to read journal logs");
530
+ }
498
531
  }
499
532
  }
500
533
  function streamPm2Logs(options) {
@@ -9,7 +9,7 @@
9
9
  * @module
10
10
  */
11
11
  import * as os from "node:os";
12
- import { readFileSync } from "node:fs";
12
+ import { existsSync, readFileSync } from "node:fs";
13
13
  import { loadConfigFile, validateConfig } from "@comis/core";
14
14
  import { success, error, info } from "../output/format.js";
15
15
  import { withSpinner } from "../output/spinner.js";
@@ -31,6 +31,23 @@ const ALL_CHECKS = [
31
31
  channelHealthCheck,
32
32
  workspaceHealthCheck,
33
33
  ];
34
+ /**
35
+ * Resolve default config paths from COMIS_CONFIG_PATHS env var or standard locations.
36
+ */
37
+ function resolveDefaultConfigPaths() {
38
+ // eslint-disable-next-line no-restricted-syntax -- CLI bootstrap before SecretManager
39
+ const envPaths = process.env["COMIS_CONFIG_PATHS"];
40
+ if (envPaths) {
41
+ return envPaths.split(":").filter((p) => p.length > 0);
42
+ }
43
+ const candidates = [
44
+ os.homedir() + "/.comis/config.yaml",
45
+ os.homedir() + "/.comis/config.local.yaml",
46
+ "/etc/comis/config.yaml",
47
+ "/etc/comis/config.local.yaml",
48
+ ];
49
+ return candidates.filter((p) => existsSync(p));
50
+ }
34
51
  /**
35
52
  * Build a DoctorContext from CLI options.
36
53
  *
@@ -93,7 +110,7 @@ export function registerDoctorCommand(program) {
93
110
  .option("-c, --config <paths...>", "Config file paths to check")
94
111
  .option("--format <format>", 'Output format: "table" or "json"', "table")
95
112
  .action(async (options) => {
96
- const configPaths = options.config ?? [];
113
+ const configPaths = options.config ?? resolveDefaultConfigPaths();
97
114
  const context = buildDoctorContext(configPaths);
98
115
  const result = await withSpinner("Running diagnostics...", () => runDoctorChecks(ALL_CHECKS, context));
99
116
  // Render results
@@ -10,7 +10,7 @@
10
10
  * @module
11
11
  */
12
12
  import * as os from "node:os";
13
- import { readFileSync } from "node:fs";
13
+ import { existsSync, readFileSync } from "node:fs";
14
14
  import { loadConfigFile, validateConfig } from "@comis/core";
15
15
  import chalk from "chalk";
16
16
  import { json } from "../output/format.js";
@@ -29,6 +29,23 @@ const ALL_CHECKS = [
29
29
  channelHealthCheck,
30
30
  workspaceHealthCheck,
31
31
  ];
32
+ /**
33
+ * Resolve default config paths from COMIS_CONFIG_PATHS env var or standard locations.
34
+ */
35
+ function resolveDefaultConfigPaths() {
36
+ // eslint-disable-next-line no-restricted-syntax -- CLI bootstrap before SecretManager
37
+ const envPaths = process.env["COMIS_CONFIG_PATHS"];
38
+ if (envPaths) {
39
+ return envPaths.split(":").filter((p) => p.length > 0);
40
+ }
41
+ const candidates = [
42
+ os.homedir() + "/.comis/config.yaml",
43
+ os.homedir() + "/.comis/config.local.yaml",
44
+ "/etc/comis/config.yaml",
45
+ "/etc/comis/config.local.yaml",
46
+ ];
47
+ return candidates.filter((p) => existsSync(p));
48
+ }
32
49
  /**
33
50
  * Build a DoctorContext from CLI config paths.
34
51
  *
@@ -136,7 +153,7 @@ export function registerHealthCommand(program) {
136
153
  .option("--format <format>", 'Output format: "table" or "json"', "table")
137
154
  .option("--all", "Show all findings including passing checks", false)
138
155
  .action(async (options) => {
139
- const configPaths = options.config ?? [];
156
+ const configPaths = options.config ?? resolveDefaultConfigPaths();
140
157
  const context = buildHealthContext(configPaths);
141
158
  const result = await withSpinner("Checking health...", () => runDoctorChecks(ALL_CHECKS, context));
142
159
  // Filter findings: by default only fail/warn
@@ -9,6 +9,7 @@
9
9
  * @module
10
10
  */
11
11
  import * as fs from "node:fs";
12
+ import * as os from "node:os";
12
13
  import chalk from "chalk";
13
14
  import { parseDocument } from "yaml";
14
15
  import { createModelCatalog } from "@comis/agent";
@@ -16,8 +17,10 @@ import { withClient } from "../client/rpc-client.js";
16
17
  import { success, error, info, json } from "../output/format.js";
17
18
  import { withSpinner } from "../output/spinner.js";
18
19
  import { renderTable } from "../output/table.js";
19
- /** Default config paths to check (matching daemon defaults). */
20
+ /** Default config paths to check (matching daemon and CLI defaults). */
20
21
  const DEFAULT_CONFIG_PATHS = [
22
+ os.homedir() + "/.comis/config.yaml",
23
+ os.homedir() + "/.comis/config.local.yaml",
21
24
  "/etc/comis/config.yaml",
22
25
  "/etc/comis/config.local.yaml",
23
26
  ];
@@ -201,11 +204,10 @@ export function registerModelsCommand(program) {
201
204
  process.exit(1);
202
205
  }
203
206
  // Get old model value for display
204
- const oldModel = doc.getIn([...agentsPath, agent, "defaultModel"]);
207
+ const oldModel = doc.getIn([...agentsPath, agent, "model"]);
205
208
  const oldModelStr = typeof oldModel === "string" ? oldModel : "(not set)";
206
209
  // Update the model field
207
- const fullModelId = `${entry.provider}/${entry.modelId}`;
208
- doc.setIn([...agentsPath, agent, "defaultModel"], fullModelId);
210
+ doc.setIn([...agentsPath, agent, "model"], entry.modelId);
209
211
  // Write config back preserving format
210
212
  const dir = configPath.substring(0, configPath.lastIndexOf("/"));
211
213
  if (dir) {
@@ -213,7 +215,7 @@ export function registerModelsCommand(program) {
213
215
  }
214
216
  fs.writeFileSync(configPath, doc.toString(), { mode: 0o600 });
215
217
  success(`Model updated for agent "${agent}"`);
216
- console.log(` ${chalk.gray(oldModelStr)} ${chalk.white("->")} ${chalk.cyan(fullModelId)}`);
218
+ console.log(` ${chalk.gray(oldModelStr)} ${chalk.white("->")} ${chalk.cyan(entry.modelId)}`);
217
219
  info("Daemon will restart to apply the change");
218
220
  }
219
221
  catch (err) {
@@ -9,8 +9,28 @@
9
9
  * @module
10
10
  */
11
11
  import { readFileSync } from "node:fs";
12
+ import os from "node:os";
12
13
  import { parse as parseYaml } from "yaml";
13
- import { AppConfigSchema } from "@comis/core";
14
+ import { AppConfigSchema, loadEnvFile } from "@comis/core";
15
+ const ENV_REF_RE = /\$\{([A-Z_][A-Z0-9_]*)\}/g;
16
+ /** Deep-walk an object and resolve `${VAR}` references using process.env. */
17
+ function resolveEnvRefs(obj) {
18
+ for (const [key, value] of Object.entries(obj)) {
19
+ if (typeof value === "string" && value.includes("${")) {
20
+ // eslint-disable-next-line no-restricted-syntax -- CLI bootstrap before SecretManager
21
+ obj[key] = value.replace(ENV_REF_RE, (match, varName) => process.env[varName] ?? match);
22
+ }
23
+ else if (value && typeof value === "object" && !Array.isArray(value)) {
24
+ resolveEnvRefs(value);
25
+ }
26
+ else if (Array.isArray(value)) {
27
+ for (const item of value) {
28
+ if (item && typeof item === "object")
29
+ resolveEnvRefs(item);
30
+ }
31
+ }
32
+ }
33
+ }
14
34
  const CATEGORY = "config";
15
35
  /**
16
36
  * Doctor check: config file health.
@@ -89,6 +109,9 @@ export const configHealthCheck = {
89
109
  });
90
110
  return findings;
91
111
  }
112
+ // Resolve ${VAR} references before validation (mirrors daemon startup)
113
+ loadEnvFile(os.homedir() + "/.comis/.env");
114
+ resolveEnvRefs(parsed);
92
115
  // Validate against schema
93
116
  const result = AppConfigSchema.safeParse(parsed);
94
117
  if (!result.success) {
@@ -71,6 +71,11 @@ export async function repairConfig(findings, configPaths) {
71
71
  }
72
72
  else if (finding.message.includes("not found") || finding.message.includes("No config")) {
73
73
  // Config missing -- create directory and write defaults
74
+ // Guard: never overwrite an existing config file
75
+ if (existsSync(targetPath)) {
76
+ actions.push(`Config already exists at ${targetPath} (skipped overwrite). Use -c ${targetPath} to check it.`);
77
+ continue;
78
+ }
74
79
  const lastSlash = targetPath.lastIndexOf("/");
75
80
  if (lastSlash > 0) {
76
81
  const dir = targetPath.slice(0, lastSlash);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/cli",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Command-line interface for the Comis AI agent platform",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/core",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Core domain types, ports, event bus, security, and config for Comis",
@@ -135,6 +135,7 @@ export function registerRpcMethods(deps) {
135
135
  registerRpcPassthrough(dynamicRouter, rpcCall, [
136
136
  "agents.list", "agents.create", "agents.get", "agents.update",
137
137
  "agents.delete", "agents.suspend", "agents.resume",
138
+ "agent.getOperationModels",
138
139
  ], "admin");
139
140
  // -------------------------------------------------------------------------
140
141
  // Session management admin methods
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/daemon",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Background daemon and orchestrator for the Comis platform",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/gateway",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "HTTP, JSON-RPC, and WebSocket gateway for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/infra",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Structured logging infrastructure for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/memory",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "SQLite memory, embeddings, and RAG storage for Comis agents",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/scheduler",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Task scheduling and cron management for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/shared",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Shared types and utilities for the Comis platform",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/skills",
3
3
  "private": true,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Skill system, MCP integration, and tool sandbox for Comis agents",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comisai",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "author": "Moshe Anconina",
5
5
  "license": "Apache-2.0",
6
6
  "description": "Security-first AI agent platform — connects AI agents to Discord, Telegram, Slack, WhatsApp, and more",
@@ -115,17 +115,17 @@
115
115
  "@comis/daemon"
116
116
  ],
117
117
  "dependencies": {
118
- "@comis/shared": "1.0.5",
119
- "@comis/core": "1.0.5",
120
- "@comis/infra": "1.0.5",
121
- "@comis/memory": "1.0.5",
122
- "@comis/gateway": "1.0.5",
123
- "@comis/skills": "1.0.5",
124
- "@comis/scheduler": "1.0.5",
125
- "@comis/agent": "1.0.5",
126
- "@comis/channels": "1.0.5",
127
- "@comis/cli": "1.0.5",
128
- "@comis/daemon": "1.0.5",
118
+ "@comis/shared": "1.0.6",
119
+ "@comis/core": "1.0.6",
120
+ "@comis/infra": "1.0.6",
121
+ "@comis/memory": "1.0.6",
122
+ "@comis/gateway": "1.0.6",
123
+ "@comis/skills": "1.0.6",
124
+ "@comis/scheduler": "1.0.6",
125
+ "@comis/agent": "1.0.6",
126
+ "@comis/channels": "1.0.6",
127
+ "@comis/cli": "1.0.6",
128
+ "@comis/daemon": "1.0.6",
129
129
  "@agentclientprotocol/sdk": "^0.15.0",
130
130
  "@clack/core": "^1.1.0",
131
131
  "@clack/prompts": "^1.1.0",