wtt-connect 0.2.0 → 0.2.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/README.md +6 -0
- package/package.json +1 -1
- package/src/config.js +16 -1
- package/src/main.js +5 -1
- package/src/runner.js +2 -0
- package/src/service-manager.js +27 -1
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, run `wtt-connect workdir <profile> /path/to/workspace --restart`. This updates `~/.config/wtt-connect/profiles/<profile>.env`, creates the directory, and restarts the service.
|
|
146
|
+
|
|
141
147
|
Useful flags:
|
|
142
148
|
|
|
143
149
|
```bash
|
package/package.json
CHANGED
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
|
|
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/main.js
CHANGED
|
@@ -10,7 +10,7 @@ import { DurableStore } from './store.js';
|
|
|
10
10
|
import { log, redact } from './logger.js';
|
|
11
11
|
import { adapterBin, normalizeProfileName } from './adapters/generic-cli.js';
|
|
12
12
|
import { normalizeAdapterName } from './adapters/index.js';
|
|
13
|
-
import { down, listProfiles, logs, resolveProfileEnvFile, restart, status, up } from './service-manager.js';
|
|
13
|
+
import { down, listProfiles, logs, resolveProfileEnvFile, restart, status, up, workdir } from './service-manager.js';
|
|
14
14
|
|
|
15
15
|
export async function main(args) {
|
|
16
16
|
const cmd = args[0] || 'help';
|
|
@@ -23,6 +23,7 @@ export async function main(args) {
|
|
|
23
23
|
if (cmd === 'status') return status(argv);
|
|
24
24
|
if (cmd === 'restart') return restart(argv);
|
|
25
25
|
if (cmd === 'logs') return logs(argv);
|
|
26
|
+
if (cmd === 'workdir') return workdir(argv);
|
|
26
27
|
if (cmd === 'down' || cmd === 'unlink') return down(argv);
|
|
27
28
|
if (cmd === 'doctor') return doctor(loadConfig(argv));
|
|
28
29
|
if (cmd === 'setup') return setup(loadConfig(argv), argv);
|
|
@@ -61,6 +62,7 @@ function parseArgs(args) {
|
|
|
61
62
|
else if (a === '--allow-yolo' || a === '--allow-dangerous-permissions') out.allowYolo = true;
|
|
62
63
|
else if (a === '--yes' || a === '-y') out.yes = true;
|
|
63
64
|
else if (a === '--publish-progress') out.publishProgress = true;
|
|
65
|
+
else if (a === '--restart') out.restart = true;
|
|
64
66
|
else if (a === '--enable-linger') out.enableLinger = true;
|
|
65
67
|
else if (a === '--no-start') out.noStart = true;
|
|
66
68
|
else if (a === '--node-bin') out.nodeBin = args[++i];
|
|
@@ -97,6 +99,8 @@ Commands:
|
|
|
97
99
|
status [profile|all] Show systemd service status for profiles
|
|
98
100
|
restart [profile|all] Restart one or all configured services
|
|
99
101
|
logs <profile> [--lines 100] Show service logs
|
|
102
|
+
workdir <profile> [path] [--restart]
|
|
103
|
+
Show or update the agent execution directory
|
|
100
104
|
down <profile> Stop/disable service; keep profile/state files
|
|
101
105
|
unlink <profile> Alias for down
|
|
102
106
|
setup [--claim-code] Register/write local .env and optionally print claim code
|
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(','),
|
package/src/service-manager.js
CHANGED
|
@@ -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 =
|
|
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,
|
|
@@ -140,6 +142,30 @@ export function logs(argv) {
|
|
|
140
142
|
throw new Error(`unsupported platform: ${process.platform}`);
|
|
141
143
|
}
|
|
142
144
|
|
|
145
|
+
export function workdir(argv) {
|
|
146
|
+
const [profile = '', nextDir = ''] = argv._ || [];
|
|
147
|
+
if (!profile) throw new Error('usage: wtt-connect workdir <profile> [path] [--restart]');
|
|
148
|
+
const safe = sanitizeProfile(profile);
|
|
149
|
+
const envFile = profileEnvFile(safe);
|
|
150
|
+
if (!fs.existsSync(envFile)) throw new Error(`profile not found: ${safe}`);
|
|
151
|
+
const env = readEnv(envFile);
|
|
152
|
+
if (!nextDir) {
|
|
153
|
+
console.log(env.WTT_CONNECT_WORKDIR || '');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const resolved = path.resolve(nextDir);
|
|
157
|
+
ensureDir(resolved);
|
|
158
|
+
env.WTT_CONNECT_WORKDIR = resolved;
|
|
159
|
+
writeProfileEnv(envFile, env);
|
|
160
|
+
console.log(`updated ${safe} workdir: ${resolved}`);
|
|
161
|
+
if (argv.restart) {
|
|
162
|
+
restartService(safe);
|
|
163
|
+
console.log(`${safe}: ${serviceStatus(safe)}`);
|
|
164
|
+
} else {
|
|
165
|
+
console.log(`restart required: wtt-connect restart ${safe}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
143
169
|
export function down(argv) {
|
|
144
170
|
const [profile = ''] = argv._ || [];
|
|
145
171
|
if (!profile) throw new Error('usage: wtt-connect down <profile>');
|