comisai 1.0.17 → 1.0.19

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.17",
4
+ "version": "1.0.19",
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.17",
4
+ "version": "1.0.19",
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",
@@ -68,16 +68,14 @@ function extractStateFromConfig(raw, envRecord = {}) {
68
68
  bindMode = "custom";
69
69
  customIp = host;
70
70
  }
71
- // Recover gateway.web.enabled (default true) when reloading existing config
72
- const webRaw = gatewayRaw["web"];
73
- const webEnabled = webRaw && typeof webRaw["enabled"] === "boolean" ? webRaw["enabled"] : true;
74
71
  if (port !== undefined) {
72
+ const webRaw = gatewayRaw["web"];
75
73
  gateway = {
76
74
  port,
77
75
  bindMode,
78
76
  ...(customIp !== undefined && { customIp }),
79
77
  authMethod: "token",
80
- webEnabled,
78
+ webEnabled: typeof webRaw?.["enabled"] === "boolean" ? webRaw["enabled"] : true,
81
79
  };
82
80
  }
83
81
  }
@@ -2,11 +2,10 @@
2
2
  * Finish step -- step 12 of the init wizard.
3
3
  *
4
4
  * Displays a quick-reference card with essential CLI commands,
5
- * gateway access info with WebSocket URL and token location,
6
- * offers shell completion setup, and ends with a branded outro.
7
- *
8
- * This is the user's last impression of the wizard -- clear, concise,
9
- * and immediately actionable.
5
+ * gateway access info (URLs), the full access token with a secure-storage
6
+ * warning, and -- when the gateway binds loopback-only -- a copy-paste SSH
7
+ * tunnel recipe so non-technical users can open the dashboard from another
8
+ * computer. Ends with a shell-completion offer and a branded outro.
10
9
  *
11
10
  * @module
12
11
  */
@@ -3,15 +3,14 @@
3
3
  * Finish step -- step 12 of the init wizard.
4
4
  *
5
5
  * Displays a quick-reference card with essential CLI commands,
6
- * gateway access info with WebSocket URL and token location,
7
- * offers shell completion setup, and ends with a branded outro.
8
- *
9
- * This is the user's last impression of the wizard -- clear, concise,
10
- * and immediately actionable.
6
+ * gateway access info (URLs), the full access token with a secure-storage
7
+ * warning, and -- when the gateway binds loopback-only -- a copy-paste SSH
8
+ * tunnel recipe so non-technical users can open the dashboard from another
9
+ * computer. Ends with a shell-completion offer and a branded outro.
11
10
  *
12
11
  * @module
13
12
  */
14
- import { updateState, sectionSeparator, brand } from "../index.js";
13
+ import { brand, info, sectionSeparator, updateState, warning } from "../index.js";
15
14
  // ---------- Helpers ----------
16
15
  /**
17
16
  * Build the quick-reference card lines.
@@ -31,44 +30,94 @@ function buildReferenceCard() {
31
30
  const lines = commands.map(([label, cmd]) => ` ${label.padEnd(18)}${brand(cmd)}`);
32
31
  return lines.join("\n");
33
32
  }
33
+ function resolveHost(gateway) {
34
+ switch (gateway.bindMode) {
35
+ case "loopback":
36
+ return "127.0.0.1";
37
+ case "lan":
38
+ return "0.0.0.0";
39
+ case "custom":
40
+ return gateway.customIp ?? "127.0.0.1";
41
+ }
42
+ }
34
43
  /**
35
- * Build the gateway access info block from wizard state.
36
- *
37
- * Returns undefined if no gateway config exists.
44
+ * URLs block dashboard + websocket only. No auth hints here;
45
+ * the token/password lives in its own block so the user sees it
46
+ * as the thing to copy.
38
47
  */
39
48
  function buildGatewayInfo(state) {
40
49
  if (!state.gateway)
41
50
  return undefined;
42
- let host;
43
- switch (state.gateway.bindMode) {
44
- case "loopback":
45
- host = "127.0.0.1";
46
- break;
47
- case "lan":
48
- host = "0.0.0.0";
49
- break;
50
- case "custom":
51
- host = state.gateway.customIp ?? "127.0.0.1";
52
- break;
53
- default:
54
- host = "127.0.0.1";
51
+ const host = resolveHost(state.gateway);
52
+ const { port } = state.gateway;
53
+ const lines = [];
54
+ if (state.gateway.webEnabled) {
55
+ lines.push(` Dashboard: ${brand(`http://${host}:${port}/app/`)}`);
55
56
  }
56
- const wsLine = ` WebSocket: ${brand(`ws://${host}:${state.gateway.port}/ws`)}`;
57
- const dashboardLine = state.gateway.webEnabled
58
- ? ` Dashboard: ${brand(`http://${host}:${state.gateway.port}/app/`)}`
59
- : undefined;
60
- let authLine;
57
+ lines.push(` WebSocket: ${brand(`ws://${host}:${port}/ws`)}`);
58
+ return lines.join("\n");
59
+ }
60
+ /**
61
+ * Access token block — prints the full token on its own line so
62
+ * copy-paste works cleanly, plus a prominent "keep secret" warning
63
+ * and storage guidance. For password auth, points the user at the
64
+ * password they already chose.
65
+ */
66
+ function buildAccessTokenBlock(state) {
67
+ if (!state.gateway)
68
+ return undefined;
61
69
  if (state.gateway.authMethod === "password") {
62
- authLine = " Auth: Password auth (in ~/.comis/.env)";
63
- }
64
- else {
65
- const tokenPreview = state.gateway.token
66
- ? `${state.gateway.token.slice(0, 8)}...`
67
- : "see file";
68
- authLine = ` Token: ${tokenPreview} (in ~/.comis/.env)`;
70
+ return [
71
+ "You chose a password for gateway access.",
72
+ "",
73
+ info("Use the password you set earlier when the dashboard asks for it."),
74
+ info("It is also stored in ~/.comis/.env — keep that file private."),
75
+ ].join("\n");
69
76
  }
70
- const lines = [wsLine, dashboardLine, authLine].filter((l) => l !== undefined);
71
- return lines.join("\n");
77
+ if (!state.gateway.token)
78
+ return undefined;
79
+ return [
80
+ "Copy this token now — you will need it to sign in to the dashboard:",
81
+ "",
82
+ ` ${brand(state.gateway.token)}`,
83
+ "",
84
+ warning("Keep it secret. Anyone with this token can control your agents."),
85
+ info("Save it in a password manager (1Password, Bitwarden, Apple Passwords)."),
86
+ info("It is also stored at ~/.comis/.env — keep that file private."),
87
+ ].join("\n");
88
+ }
89
+ /**
90
+ * SSH tunnel recipe — shown only when the gateway is loopback-only
91
+ * and the dashboard is enabled. Walks the user through ssh -N -L
92
+ * with a clear YOUR-SERVER placeholder and the localhost URL to
93
+ * open on their laptop.
94
+ */
95
+ function buildTunnelInstructions(state) {
96
+ if (!state.gateway || !state.gateway.webEnabled)
97
+ return undefined;
98
+ if (state.gateway.bindMode !== "loopback")
99
+ return undefined;
100
+ const { port } = state.gateway;
101
+ return [
102
+ "Your dashboard is only reachable from this computer right now.",
103
+ "To open it from your laptop, follow these steps one time:",
104
+ "",
105
+ ` ${brand("1.")} On your laptop, open a Terminal window and run:`,
106
+ "",
107
+ ` ${brand(`ssh -N -L ${port}:127.0.0.1:${port} root@YOUR-SERVER`)}`,
108
+ "",
109
+ ` Replace ${brand("YOUR-SERVER")} with this server's IP address or`,
110
+ " hostname (ask your hosting provider if you are not sure).",
111
+ " Leave that Terminal window open.",
112
+ "",
113
+ ` ${brand("2.")} In your laptop's web browser, open:`,
114
+ "",
115
+ ` ${brand(`http://localhost:${port}/app/`)}`,
116
+ "",
117
+ ` ${brand("3.")} Paste your access token when asked.`,
118
+ "",
119
+ info("When you are done, close the Terminal window to disconnect."),
120
+ ].join("\n");
72
121
  }
73
122
  // ---------- Step Implementation ----------
74
123
  export const finishStep = {
@@ -77,12 +126,22 @@ export const finishStep = {
77
126
  async execute(state, prompter) {
78
127
  // 1. Quick-reference card
79
128
  prompter.note(buildReferenceCard(), sectionSeparator("Quick Reference"));
80
- // 2. Gateway access info
129
+ // 2. Gateway URLs
81
130
  const gatewayInfo = buildGatewayInfo(state);
82
131
  if (gatewayInfo) {
83
132
  prompter.note(gatewayInfo, sectionSeparator("Gateway Access"));
84
133
  }
85
- // 3. Shell completion offer
134
+ // 3. Access token (or password pointer) — its own highlighted block
135
+ const tokenBlock = buildAccessTokenBlock(state);
136
+ if (tokenBlock) {
137
+ prompter.note(tokenBlock, sectionSeparator("Your Access Token"));
138
+ }
139
+ // 4. Copy-paste SSH tunnel recipe (loopback only)
140
+ const tunnelBlock = buildTunnelInstructions(state);
141
+ if (tunnelBlock) {
142
+ prompter.note(tunnelBlock, sectionSeparator("Open the Dashboard from Another Computer"));
143
+ }
144
+ // 5. Shell completion offer
86
145
  const wantCompletions = await prompter.confirm({
87
146
  message: "Enable shell completions for comis?",
88
147
  initialValue: true,
@@ -90,9 +149,9 @@ export const finishStep = {
90
149
  if (wantCompletions) {
91
150
  prompter.log.info("Run 'comis --help' to see available commands including shell completion setup");
92
151
  }
93
- // 4. Branded outro
152
+ // 6. Branded outro
94
153
  prompter.outro("Happy building! Run 'comis status' to see your system.");
95
- // 5. Return state unchanged -- wizard complete
154
+ // 7. Return state unchanged -- wizard complete
96
155
  return updateState(state, {});
97
156
  },
98
157
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/cli",
3
3
  "private": true,
4
- "version": "1.0.17",
4
+ "version": "1.0.19",
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.17",
4
+ "version": "1.0.19",
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",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/daemon",
3
3
  "private": true,
4
- "version": "1.0.17",
4
+ "version": "1.0.19",
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.17",
4
+ "version": "1.0.19",
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.17",
4
+ "version": "1.0.19",
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.17",
4
+ "version": "1.0.19",
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.17",
4
+ "version": "1.0.19",
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.17",
4
+ "version": "1.0.19",
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.17",
4
+ "version": "1.0.19",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Skill system, MCP integration, and tool sandbox for Comis agents",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comis/web",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "description": "Web dashboard SPA for Comis agent management",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comisai",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
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",
@@ -116,18 +116,18 @@
116
116
  "@comis/web"
117
117
  ],
118
118
  "dependencies": {
119
- "@comis/shared": "1.0.17",
120
- "@comis/core": "1.0.17",
121
- "@comis/infra": "1.0.17",
122
- "@comis/memory": "1.0.17",
123
- "@comis/gateway": "1.0.17",
124
- "@comis/skills": "1.0.17",
125
- "@comis/scheduler": "1.0.17",
126
- "@comis/agent": "1.0.17",
127
- "@comis/channels": "1.0.17",
128
- "@comis/cli": "1.0.17",
129
- "@comis/daemon": "1.0.17",
130
- "@comis/web": "1.0.17",
119
+ "@comis/shared": "1.0.19",
120
+ "@comis/core": "1.0.19",
121
+ "@comis/infra": "1.0.19",
122
+ "@comis/memory": "1.0.19",
123
+ "@comis/gateway": "1.0.19",
124
+ "@comis/skills": "1.0.19",
125
+ "@comis/scheduler": "1.0.19",
126
+ "@comis/agent": "1.0.19",
127
+ "@comis/channels": "1.0.19",
128
+ "@comis/cli": "1.0.19",
129
+ "@comis/daemon": "1.0.19",
130
+ "@comis/web": "1.0.19",
131
131
  "@agentclientprotocol/sdk": "^0.15.0",
132
132
  "@clack/core": "^1.1.0",
133
133
  "@clack/prompts": "^1.1.0",