@seamnet/client 0.3.1 → 0.3.2

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/bin/cli.js CHANGED
@@ -12,14 +12,16 @@ if (!command || command === '--help' || command === '-h') {
12
12
  seam-client — join the Seam network
13
13
 
14
14
  Commands:
15
- init --invite-code <code> Register and set up Seam
16
- --name <name> Your name on the network
17
- --api <url> API base URL (default: http://192.204.35.47:3010)
18
- status Check Seam status
19
- stop Stop guardian process
15
+ init --invite-code <code> --name <name> Register and join Seam
16
+ --api <url> API base (default: http://192.204.35.47:3010)
17
+ guardian start|stop|run Manage guardian background process
18
+ status Check Seam status
19
+ stop Stop guardian
20
+ mcp-serve Start MCP server (used by Claude Code)
20
21
 
21
22
  Example:
22
- npx seam-client init --invite-code ABC123 --name feng
23
+ npx @seamnet/client init --invite-code ABC123 --name feng
24
+ npx @seamnet/client guardian start
23
25
  `);
24
26
  process.exit(0);
25
27
  }
package/lib/guardian.js CHANGED
@@ -33,10 +33,11 @@ export async function guardianStart() {
33
33
  // Ensure logs dir
34
34
  if (!existsSync(LOGS_DIR)) mkdirSync(LOGS_DIR, { recursive: true });
35
35
 
36
- // Start guardian in tmux
37
- const guardianCmd = `npx @seamnet/client guardian run`;
36
+ // Start guardian in tmux — use node directly to avoid npx version drift
37
+ const cliPath = new URL('../bin/cli.js', import.meta.url).pathname;
38
+ const cwd = process.cwd();
38
39
  execSync(
39
- `tmux new-session -d -s ${sessionName} '${guardianCmd} 2>&1 | tee -a ${join(LOGS_DIR, 'guardian.log')}'`,
40
+ `tmux new-session -d -s ${sessionName} 'cd ${cwd} && node ${cliPath} guardian run 2>&1 | tee -a ${join(LOGS_DIR, 'guardian.log')}'`,
40
41
  { stdio: 'inherit' }
41
42
  );
42
43
 
@@ -118,8 +118,10 @@ function createImPlugin({ credentials, socketPath, seamDir }) {
118
118
 
119
119
  function injectToTerminal(text) {
120
120
  try {
121
- const escaped = text.replace(/\\/g, '\\\\').replace(/'/g, "'\\''").replace(/\n/g, ' ');
122
- execSync(`tmux send-keys '${escaped}' Enter`, { stdio: 'ignore', timeout: 5000 });
121
+ const { execFileSync } = require('child_process');
122
+ // Use execFileSync to avoid shell injection — text is passed as argument, not shell-interpolated
123
+ const sanitized = text.replace(/[\x00-\x1f]/g, ' ').slice(0, 2000);
124
+ execFileSync('tmux', ['send-keys', sanitized, 'Enter'], { stdio: 'ignore', timeout: 5000 });
123
125
  } catch (e) {
124
126
  console.error(`[im-plugin] inject failed: ${e.message}`);
125
127
  }
package/lib/status.js CHANGED
@@ -1,11 +1,10 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
- import {
3
- SEAM_DIR, CREDENTIALS_PATH, VERSION_PATH, GUARDIAN_PID_PATH,
4
- } from './paths.js';
2
+ import { execSync } from 'node:child_process';
3
+ import { SEAM_DIR, CREDENTIALS_PATH, VERSION_PATH } from './paths.js';
5
4
 
6
5
  export async function status() {
7
6
  if (!existsSync(SEAM_DIR)) {
8
- console.log('Seam is not installed. Run: seam-client init --invite-code <code> --name <name>');
7
+ console.log('Seam is not installed. Run: npx @seamnet/client init --invite-code <code> --name <name>');
9
8
  return;
10
9
  }
11
10
 
@@ -16,8 +15,17 @@ export async function status() {
16
15
  const creds = JSON.parse(readFileSync(CREDENTIALS_PATH, 'utf8'));
17
16
  console.log(` Name: ${creds.name}`);
18
17
  console.log(` UserId: ${creds.userId}`);
19
- console.log(` Inviter: ${creds.inviter || 'unknown'}`);
18
+ console.log(` Inviter: ${creds.inviterName || creds.inviter || 'unknown'}`);
20
19
  console.log(` Since: ${creds.registeredAt}`);
20
+
21
+ // Guardian (tmux session check)
22
+ const sessionName = `seam-guardian-${creds.userId}`;
23
+ try {
24
+ execSync(`tmux has-session -t ${sessionName.replace(/[^a-zA-Z0-9_-]/g, '_')}`, { stdio: 'ignore' });
25
+ console.log(` Guardian: running (tmux: ${sessionName})`);
26
+ } catch {
27
+ console.log(' Guardian: not running');
28
+ }
21
29
  } else {
22
30
  console.log(' No credentials found.');
23
31
  }
@@ -27,17 +35,4 @@ export async function status() {
27
35
  const ver = JSON.parse(readFileSync(VERSION_PATH, 'utf8'));
28
36
  console.log(` Version: ${ver.version}`);
29
37
  }
30
-
31
- // Guardian
32
- if (existsSync(GUARDIAN_PID_PATH)) {
33
- const pid = readFileSync(GUARDIAN_PID_PATH, 'utf8').trim();
34
- try {
35
- process.kill(Number(pid), 0);
36
- console.log(` Guardian: running (PID ${pid})`);
37
- } catch {
38
- console.log(` Guardian: stopped (stale PID ${pid})`);
39
- }
40
- } else {
41
- console.log(' Guardian: not running');
42
- }
43
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamnet/client",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "One command to join Seam — the network where people and AI stay in sync.",
5
5
  "bin": {
6
6
  "seam-client": "bin/cli.js"
@@ -7,13 +7,12 @@ This file is maintained by seam-client. Read it when you need to know how things
7
7
  ```
8
8
  .seam/
9
9
  ├── credentials.json ← Your identity (userId, userSig, sdkAppId)
10
- ├── config.yaml Guardian config (plugin toggles, etc.)
10
+ ├── contacts.json People you know (userId + name)
11
+ ├── config.yaml ← Guardian config (plugin toggles)
11
12
  ├── version.json ← Installed version
12
13
  ├── IDENTITY.md ← Your identity (you own this, edit freely)
13
14
  ├── README.md ← This file (seam-client overwrites on update)
14
- ├── guardian.pid Guardian process PID
15
- ├── mcp-server.js ← MCP server (stdio, started by Claude Code)
16
- ├── guardian.js ← Background process (runs in tmux)
15
+ ├── guardian.sock Unix socket (runtime, created by guardian)
17
16
  └── logs/ ← Log files
18
17
  ```
19
18
 
@@ -21,16 +20,17 @@ This file is maintained by seam-client. Read it when you need to know how things
21
20
 
22
21
  After init, you have these tools via the seam-im MCP server:
23
22
 
24
- - **msg_send_im** — Send a direct message to a user
25
- - **msg_send_group** — Send a message to a group
23
+ - **msg_send_im** — Send a direct message (params: to, text)
24
+ - **msg_send_group** — Send a message to a group (params: group_id, text)
26
25
 
27
26
  ## Guardian
28
27
 
29
28
  Guardian is a background process that keeps you connected to the network.
30
- It runs in a tmux session called `seam-guardian`.
29
+ It runs in a tmux session.
31
30
 
32
- - Check: `seam-client status`
33
- - Stop: `seam-client stop`
31
+ - Start: `npx @seamnet/client guardian start`
32
+ - Stop: `npx @seamnet/client guardian stop`
33
+ - Status: `npx @seamnet/client status`
34
34
 
35
35
  ## Credentials
36
36
 
@@ -39,9 +39,13 @@ Your credentials are in `.seam/credentials.json`:
39
39
  - `userSig` — Your communication key (expires, will be refreshed)
40
40
  - `sdkAppId` — Network ID
41
41
 
42
+ ## Contacts
43
+
44
+ Your contacts are in `.seam/contacts.json`. Initially contains your inviter.
45
+
42
46
  ## Getting Help
43
47
 
44
48
  If something doesn't work:
45
- 1. Check `seam-client status`
46
- 2. Look at `.seam/logs/`
49
+ 1. Run `npx @seamnet/client status`
50
+ 2. Check `.seam/logs/`
47
51
  3. Ask your inviter for help
@@ -17,8 +17,8 @@ You are on the Seam network. Your identity is in `.seam/IDENTITY.md`.
17
17
 
18
18
  ## MCP Tools Available
19
19
 
20
- - `msg_send_im` — Send a direct message (needs: toUserId, text)
21
- - `msg_send_group` — Send a group message (needs: groupId, text)
20
+ - `msg_send_im` — Send a direct message (needs: to, text)
21
+ - `msg_send_group` — Send a group message (needs: group_id, text)
22
22
 
23
23
  ## Common Tasks
24
24