wtt-connect 0.2.0 → 0.2.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.
package/README.md CHANGED
@@ -138,6 +138,12 @@ On macOS the same profile and state paths are used, while the service file is:
138
138
 
139
139
  A profile contains exactly one WTT identity: `WTT_AGENT_ID`, `WTT_TOKEN`, adapter, workdir, permission mode, and state directory. Multiple profiles may point at the same local `codex` or `claude` CLI binary; they must not share `WTT_AGENT_ID`, `WTT_TOKEN`, or `WTT_CONNECT_STATE_DIR`.
140
140
 
141
+ Workdir rules:
142
+
143
+ - If `--workdir` or `WTT_CONNECT_WORKDIR` is provided, that exact directory is used for agent execution, shell, terminal, runtime info, and adapter cwd.
144
+ - If no workdir is provided, `wtt-connect` uses `./workspaces/<agent_id>` under the current default directory. This prevents multiple claimed agents on the same host from sharing the `wtt-connect` package directory.
145
+ - For an existing profile, edit `~/.config/wtt-connect/profiles/<profile>.env` and change `WTT_CONNECT_WORKDIR`, then run `wtt-connect restart <profile>`.
146
+
141
147
  Useful flags:
142
148
 
143
149
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wtt-connect",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
5
  "description": "WTT-native connector daemon for Codex, Claude Code, Cursor, Gemini, ACP, and other coding agent surfaces.",
6
6
  "type": "module",
package/src/config.js CHANGED
@@ -26,7 +26,8 @@ export function loadConfig(argv = {}) {
26
26
  const token = process.env.WTT_TOKEN || process.env.WTT_AGENT_TOKEN || fileConfig.token || '';
27
27
  const adapter = process.env.WTT_CONNECT_ADAPTER || fileConfig.adapter || 'codex';
28
28
  const adapters = String(process.env.WTT_CONNECT_ADAPTERS || fileConfig.adapters || adapter).split(',').map((x) => x.trim()).filter(Boolean);
29
- const workDir = process.env.WTT_CONNECT_WORKDIR || fileConfig.workDir || process.cwd();
29
+ const explicitWorkDir = process.env.WTT_CONNECT_WORKDIR || fileConfig.workDir || '';
30
+ const workDir = resolveAgentWorkDir(explicitWorkDir, agentId);
30
31
  const stateDir = process.env.WTT_CONNECT_STATE_DIR || fileConfig.stateDir || path.join(workDir, '.wtt-connect');
31
32
  return {
32
33
  configFile: argv.config || process.env.WTT_CONNECT_CONFIG || '',
@@ -99,6 +100,20 @@ export function loadConfig(argv = {}) {
99
100
  };
100
101
  }
101
102
 
103
+ export function resolveAgentWorkDir(explicitWorkDir, agentId, baseDir = process.cwd()) {
104
+ if (explicitWorkDir) return path.resolve(String(explicitWorkDir));
105
+ return path.resolve(baseDir, 'workspaces', safeAgentPathSegment(agentId));
106
+ }
107
+
108
+ export function safeAgentPathSegment(agentId) {
109
+ const value = String(agentId || 'unbound-agent')
110
+ .trim()
111
+ .replace(/[^a-zA-Z0-9._-]+/g, '-')
112
+ .replace(/^-+|-+$/g, '')
113
+ .slice(0, 96);
114
+ return value || 'unbound-agent';
115
+ }
116
+
102
117
  function resolveOpenDesignSkillsDir() {
103
118
  const candidates = [
104
119
  path.resolve(process.cwd(), 'opendesign-skills'),
package/src/runner.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { WTTClient } from './wtt-client.js';
2
+ import fs from 'node:fs';
2
3
  import { WTTApi } from './wtt-api.js';
3
4
  import { SessionManager } from './session-manager.js';
4
5
  import { TTSManager } from './tts.js';
@@ -40,6 +41,7 @@ export class Runner {
40
41
  }
41
42
 
42
43
  async start() {
44
+ fs.mkdirSync(this.config.workDir, { recursive: true });
43
45
  log('info', 'wtt-connect starting', {
44
46
  agentId: this.config.agentId,
45
47
  adapters: this.registry.list().join(','),
@@ -4,6 +4,7 @@ import path from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { spawnSync } from 'node:child_process';
6
6
  import { normalizeAdapterName } from './adapters/index.js';
7
+ import { resolveAgentWorkDir } from './config.js';
7
8
 
8
9
  const DEFAULT_BASE_URL = 'https://www.waxbyte.com';
9
10
  const DEFAULT_MODE = 'full-auto';
@@ -32,7 +33,7 @@ export async function up(argv) {
32
33
  const stateDir = path.resolve(argv.stateDir || defaultStateDir(profile));
33
34
  const envFile = path.resolve(argv.envFile || profileEnvFile(profile));
34
35
  const root = packageRoot();
35
- const workDir = path.resolve(argv.workdir || argv.workDir || process.cwd());
36
+ const workDir = resolveAgentWorkDir(argv.workdir || argv.workDir || '', agentId, process.cwd());
36
37
  const baseUrl = argv.baseUrl || process.env.WTT_BASE_URL || DEFAULT_BASE_URL;
37
38
  const nodeBin = argv.nodeBin || process.execPath;
38
39
  const codexBin = argv.codexBin || findBinary('codex');
@@ -42,6 +43,7 @@ export async function up(argv) {
42
43
  ensureDir(configDir);
43
44
  ensureDir(path.dirname(envFile));
44
45
  ensureDir(stateDir);
46
+ ensureDir(workDir);
45
47
 
46
48
  const profileValues = {
47
49
  WTT_BASE_URL: baseUrl,