@waiaas/cli 2.0.0-rc.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/bin/waiaas +2 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +50 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp-setup.d.ts +24 -0
- package/dist/commands/mcp-setup.d.ts.map +1 -0
- package/dist/commands/mcp-setup.js +237 -0
- package/dist/commands/mcp-setup.js.map +1 -0
- package/dist/commands/owner.d.ts +27 -0
- package/dist/commands/owner.d.ts.map +1 -0
- package/dist/commands/owner.js +145 -0
- package/dist/commands/owner.js.map +1 -0
- package/dist/commands/quickstart.d.ts +20 -0
- package/dist/commands/quickstart.d.ts.map +1 -0
- package/dist/commands/quickstart.js +192 -0
- package/dist/commands/quickstart.js.map +1 -0
- package/dist/commands/start.d.ts +10 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +54 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +10 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +80 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +10 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +68 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/upgrade.d.ts +28 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +202 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/wallet.d.ts +21 -0
- package/dist/commands/wallet.d.ts.map +1 -0
- package/dist/commands/wallet.js +99 -0
- package/dist/commands/wallet.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/data-dir.d.ts +12 -0
- package/dist/utils/data-dir.d.ts.map +1 -0
- package/dist/utils/data-dir.js +18 -0
- package/dist/utils/data-dir.js.map +1 -0
- package/dist/utils/password.d.ts +10 -0
- package/dist/utils/password.d.ts.map +1 -0
- package/dist/utils/password.js +58 -0
- package/dist/utils/password.js.map +1 -0
- package/dist/utils/slug.d.ts +27 -0
- package/dist/utils/slug.d.ts.map +1 -0
- package/dist/utils/slug.js +53 -0
- package/dist/utils/slug.js.map +1 -0
- package/dist/utils/update-notify.d.ts +23 -0
- package/dist/utils/update-notify.d.ts.map +1 -0
- package/dist/utils/update-notify.js +114 -0
- package/dist/utils/update-notify.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `waiaas quickstart` -- Create Solana + EVM wallets for quick setup.
|
|
3
|
+
*
|
|
4
|
+
* One-command multi-chain environment setup:
|
|
5
|
+
* 1. Check daemon is running (GET /health)
|
|
6
|
+
* 2. Resolve master password
|
|
7
|
+
* 3. Create Solana + EVM wallets with environment mode
|
|
8
|
+
* 4. Fetch available networks for each wallet
|
|
9
|
+
* 5. Create MCP sessions + write token files
|
|
10
|
+
* 6. Output wallet info + MCP config snippet
|
|
11
|
+
*/
|
|
12
|
+
import { writeFile, rename, mkdir } from 'node:fs/promises';
|
|
13
|
+
import { join, dirname } from 'node:path';
|
|
14
|
+
import { resolvePassword } from '../utils/password.js';
|
|
15
|
+
import { toSlug } from '../utils/slug.js';
|
|
16
|
+
/** Create session for a wallet and write token file atomically. */
|
|
17
|
+
async function createSessionAndWriteToken(opts) {
|
|
18
|
+
const sessionRes = await fetch(`${opts.baseUrl}/v1/sessions`, {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
headers: {
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
'X-Master-Password': opts.password,
|
|
23
|
+
},
|
|
24
|
+
body: JSON.stringify({
|
|
25
|
+
walletId: opts.walletId,
|
|
26
|
+
expiresIn: opts.expiresIn,
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
if (!sessionRes.ok) {
|
|
30
|
+
const body = await sessionRes.json().catch(() => null);
|
|
31
|
+
const msg = body?.['message'] ?? sessionRes.statusText;
|
|
32
|
+
console.error(`Error: Failed to create session for wallet ${opts.walletId} (${sessionRes.status}): ${msg}`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const sessionData = await sessionRes.json();
|
|
36
|
+
// Write token to mcp-tokens/<walletId> (atomic: write tmp then rename)
|
|
37
|
+
const tokenPath = join(opts.dataDir, 'mcp-tokens', opts.walletId);
|
|
38
|
+
const tmpPath = `${tokenPath}.tmp`;
|
|
39
|
+
await mkdir(dirname(tokenPath), { recursive: true });
|
|
40
|
+
await writeFile(tmpPath, sessionData.token, 'utf-8');
|
|
41
|
+
await rename(tmpPath, tokenPath);
|
|
42
|
+
return { token: sessionData.token, expiresAt: sessionData.expiresAt };
|
|
43
|
+
}
|
|
44
|
+
/** Build a single mcpServers config entry for a wallet. */
|
|
45
|
+
function buildConfigEntry(opts) {
|
|
46
|
+
const env = {
|
|
47
|
+
WAIAAS_DATA_DIR: opts.dataDir,
|
|
48
|
+
WAIAAS_BASE_URL: opts.baseUrl,
|
|
49
|
+
WAIAAS_WALLET_ID: opts.walletId,
|
|
50
|
+
};
|
|
51
|
+
if (opts.walletName) {
|
|
52
|
+
env['WAIAAS_WALLET_NAME'] = opts.walletName;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
command: 'npx',
|
|
56
|
+
args: ['@waiaas/mcp'],
|
|
57
|
+
env,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Print platform-specific Claude Desktop config.json path. */
|
|
61
|
+
function printConfigPath() {
|
|
62
|
+
const platform = process.platform;
|
|
63
|
+
if (platform === 'darwin') {
|
|
64
|
+
console.log('\nConfig location: ~/Library/Application Support/Claude/claude_desktop_config.json');
|
|
65
|
+
}
|
|
66
|
+
else if (platform === 'win32') {
|
|
67
|
+
console.log('\nConfig location: %APPDATA%\\Claude\\claude_desktop_config.json');
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
console.log('\nConfig location: ~/.config/Claude/claude_desktop_config.json');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export async function quickstartCommand(opts) {
|
|
74
|
+
const baseUrl = (opts.baseUrl ?? 'http://127.0.0.1:3100').replace(/\/+$/, '');
|
|
75
|
+
const mode = opts.mode ?? 'testnet';
|
|
76
|
+
const expiresIn = opts.expiresIn ?? 86400;
|
|
77
|
+
// Validate mode
|
|
78
|
+
if (mode !== 'testnet' && mode !== 'mainnet') {
|
|
79
|
+
console.error("Error: --mode must be 'testnet' or 'mainnet'");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
// Step 1: Check daemon is running
|
|
83
|
+
try {
|
|
84
|
+
const healthRes = await fetch(`${baseUrl}/health`, {
|
|
85
|
+
signal: AbortSignal.timeout(5000),
|
|
86
|
+
});
|
|
87
|
+
if (!healthRes.ok) {
|
|
88
|
+
console.error(`Warning: daemon returned ${healthRes.status} on health check`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
console.error('Error: Cannot reach WAIaaS daemon.');
|
|
93
|
+
console.error(` Tried: ${baseUrl}/health`);
|
|
94
|
+
console.error(' Make sure the daemon is running: waiaas start');
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
// Step 2: Resolve master password
|
|
98
|
+
const password = opts.masterPassword ?? await resolvePassword();
|
|
99
|
+
// Step 3: Create Solana + EVM wallets
|
|
100
|
+
const chains = [
|
|
101
|
+
{ chain: 'solana', name: `solana-${mode}` },
|
|
102
|
+
{ chain: 'ethereum', name: `evm-${mode}` },
|
|
103
|
+
];
|
|
104
|
+
const createdWallets = [];
|
|
105
|
+
for (const { chain, name } of chains) {
|
|
106
|
+
const walletRes = await fetch(`${baseUrl}/v1/wallets`, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: {
|
|
109
|
+
'Content-Type': 'application/json',
|
|
110
|
+
'X-Master-Password': password,
|
|
111
|
+
},
|
|
112
|
+
body: JSON.stringify({ name, chain, environment: mode }),
|
|
113
|
+
});
|
|
114
|
+
if (!walletRes.ok) {
|
|
115
|
+
const body = await walletRes.json().catch(() => null);
|
|
116
|
+
const msg = body?.['message'] ?? walletRes.statusText;
|
|
117
|
+
console.error(`Error: Failed to create ${chain} wallet (HTTP ${walletRes.status}): ${msg}`);
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
const walletData = await walletRes.json();
|
|
121
|
+
// Fetch available networks (graceful degradation on failure)
|
|
122
|
+
let availableNetworks = [];
|
|
123
|
+
try {
|
|
124
|
+
const networksRes = await fetch(`${baseUrl}/v1/wallets/${walletData.id}/networks`, {
|
|
125
|
+
headers: {
|
|
126
|
+
'Accept': 'application/json',
|
|
127
|
+
'X-Master-Password': password,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
if (networksRes.ok) {
|
|
131
|
+
const networksData = await networksRes.json();
|
|
132
|
+
availableNetworks = (networksData.networks ?? []).map((n) => n.network);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Graceful degradation: continue with empty networks
|
|
137
|
+
}
|
|
138
|
+
createdWallets.push({
|
|
139
|
+
id: walletData.id,
|
|
140
|
+
name: walletData.name,
|
|
141
|
+
chain: walletData.chain,
|
|
142
|
+
environment: walletData.environment,
|
|
143
|
+
publicKey: walletData.publicKey,
|
|
144
|
+
defaultNetwork: walletData.defaultNetwork,
|
|
145
|
+
availableNetworks,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
// Step 4: Create MCP sessions for each wallet
|
|
149
|
+
const mcpServers = {};
|
|
150
|
+
for (const wallet of createdWallets) {
|
|
151
|
+
await createSessionAndWriteToken({
|
|
152
|
+
baseUrl,
|
|
153
|
+
dataDir: opts.dataDir,
|
|
154
|
+
password,
|
|
155
|
+
walletId: wallet.id,
|
|
156
|
+
expiresIn,
|
|
157
|
+
});
|
|
158
|
+
const slug = toSlug(wallet.name);
|
|
159
|
+
mcpServers[`waiaas-${slug}`] = buildConfigEntry({
|
|
160
|
+
dataDir: opts.dataDir,
|
|
161
|
+
baseUrl,
|
|
162
|
+
walletId: wallet.id,
|
|
163
|
+
walletName: wallet.name,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
// Step 5: Output results
|
|
167
|
+
console.log('WAIaaS Quickstart Complete!');
|
|
168
|
+
console.log('');
|
|
169
|
+
console.log(`Mode: ${mode}`);
|
|
170
|
+
for (const wallet of createdWallets) {
|
|
171
|
+
const chainLabel = wallet.chain === 'solana' ? 'Solana' : 'EVM';
|
|
172
|
+
console.log('');
|
|
173
|
+
console.log(`${chainLabel} Wallet:`);
|
|
174
|
+
console.log(` Name: ${wallet.name}`);
|
|
175
|
+
console.log(` Address: ${wallet.publicKey}`);
|
|
176
|
+
console.log(` Environment: ${wallet.environment}`);
|
|
177
|
+
if (wallet.defaultNetwork) {
|
|
178
|
+
console.log(` Default Network: ${wallet.defaultNetwork}`);
|
|
179
|
+
}
|
|
180
|
+
if (wallet.availableNetworks.length > 0) {
|
|
181
|
+
console.log(` Available Networks: ${wallet.availableNetworks.join(', ')}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Step 6: MCP config snippet
|
|
185
|
+
console.log('');
|
|
186
|
+
console.log('MCP Configuration:');
|
|
187
|
+
console.log('(claude_desktop_config.json에 추가하세요)');
|
|
188
|
+
const configSnippet = { mcpServers };
|
|
189
|
+
console.log(JSON.stringify(configSnippet, null, 2));
|
|
190
|
+
printConfigPath();
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=quickstart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickstart.js","sourceRoot":"","sources":["../../src/commands/quickstart.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `waiaas start` -- Start the WAIaaS daemon.
|
|
3
|
+
*
|
|
4
|
+
* 1. Check if already running (PID file + process alive check)
|
|
5
|
+
* 2. Resolve master password
|
|
6
|
+
* 3. Call startDaemon() (in-process)
|
|
7
|
+
* 4. Process stays alive via signal handlers
|
|
8
|
+
*/
|
|
9
|
+
export declare function startCommand(dataDir: string): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CjE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `waiaas start` -- Start the WAIaaS daemon.
|
|
3
|
+
*
|
|
4
|
+
* 1. Check if already running (PID file + process alive check)
|
|
5
|
+
* 2. Resolve master password
|
|
6
|
+
* 3. Call startDaemon() (in-process)
|
|
7
|
+
* 4. Process stays alive via signal handlers
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { resolvePassword } from '../utils/password.js';
|
|
12
|
+
export async function startCommand(dataDir) {
|
|
13
|
+
const pidPath = join(dataDir, 'daemon.pid');
|
|
14
|
+
// Check if already running
|
|
15
|
+
if (existsSync(pidPath)) {
|
|
16
|
+
try {
|
|
17
|
+
const pid = parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);
|
|
18
|
+
process.kill(pid, 0); // check if process is alive
|
|
19
|
+
console.error(`Daemon already running (PID: ${pid})`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
return; // Ensure no further execution after exit
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
// ESRCH = process not found, stale PID file -- continue
|
|
25
|
+
if (err.code !== 'ESRCH') {
|
|
26
|
+
console.error(`Daemon already running (PID file exists: ${pidPath})`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
return; // Ensure no further execution after exit
|
|
29
|
+
}
|
|
30
|
+
// Stale PID file, continue with startup
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Resolve master password
|
|
34
|
+
let password;
|
|
35
|
+
try {
|
|
36
|
+
password = await resolvePassword();
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
console.error(`Failed to resolve master password: ${err.message}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
return; // Ensure no further execution after exit
|
|
42
|
+
}
|
|
43
|
+
// Start daemon (in-process)
|
|
44
|
+
try {
|
|
45
|
+
const { startDaemon } = await import('@waiaas/daemon');
|
|
46
|
+
await startDaemon(dataDir, password);
|
|
47
|
+
console.log(`WAIaaS daemon started on 127.0.0.1:3100 (PID: ${process.pid})`);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
console.error(`Failed to start daemon: ${err.message}`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAE5C,2BAA2B;IAC3B,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,4BAA4B;YAClD,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,GAAG,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO,CAAC,yCAAyC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wDAAwD;YACxD,IAAK,GAA6B,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACpD,OAAO,CAAC,KAAK,CAAC,4CAA4C,OAAO,GAAG,CAAC,CAAC;gBACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAChB,OAAO,CAAC,yCAAyC;YACnD,CAAC;YACD,wCAAwC;QAC1C,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,sCAAuC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO,CAAC,yCAAyC;IACnD,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC;QACH,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACvD,MAAM,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CACT,iDAAiD,OAAO,CAAC,GAAG,GAAG,CAChE,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,2BAA4B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `waiaas status` -- Check the WAIaaS daemon status.
|
|
3
|
+
*
|
|
4
|
+
* Reports:
|
|
5
|
+
* - running (PID + port) -- PID alive + health check OK
|
|
6
|
+
* - starting (PID) -- PID alive but health check fails
|
|
7
|
+
* - stopped -- no PID file or process not alive
|
|
8
|
+
*/
|
|
9
|
+
export declare function statusCommand(dataDir: string): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoClE"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `waiaas status` -- Check the WAIaaS daemon status.
|
|
3
|
+
*
|
|
4
|
+
* Reports:
|
|
5
|
+
* - running (PID + port) -- PID alive + health check OK
|
|
6
|
+
* - starting (PID) -- PID alive but health check fails
|
|
7
|
+
* - stopped -- no PID file or process not alive
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync, unlinkSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
/** Default daemon port if config is unavailable. */
|
|
12
|
+
const DEFAULT_PORT = 3100;
|
|
13
|
+
export async function statusCommand(dataDir) {
|
|
14
|
+
const pidPath = join(dataDir, 'daemon.pid');
|
|
15
|
+
// No PID file
|
|
16
|
+
if (!existsSync(pidPath)) {
|
|
17
|
+
console.log('Status: stopped');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const pid = parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);
|
|
21
|
+
// Check if process alive
|
|
22
|
+
if (!isProcessAlive(pid)) {
|
|
23
|
+
console.log('Status: stopped (stale PID file)');
|
|
24
|
+
try {
|
|
25
|
+
unlinkSync(pidPath);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Ignore cleanup errors
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// Resolve port from config
|
|
33
|
+
const port = resolvePort(dataDir);
|
|
34
|
+
// Health check
|
|
35
|
+
try {
|
|
36
|
+
const res = await fetch(`http://127.0.0.1:${port}/health`);
|
|
37
|
+
if (res.ok) {
|
|
38
|
+
console.log(`Status: running (PID: ${pid}, Port: ${port})`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.log(`Status: starting (PID: ${pid})`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
console.log(`Status: starting (PID: ${pid})`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function isProcessAlive(pid) {
|
|
49
|
+
try {
|
|
50
|
+
process.kill(pid, 0);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Try to read the port from config.toml. Falls back to DEFAULT_PORT.
|
|
59
|
+
* We do a simple TOML parse to avoid importing the full config loader
|
|
60
|
+
* (which pulls in many daemon dependencies).
|
|
61
|
+
*/
|
|
62
|
+
function resolvePort(dataDir) {
|
|
63
|
+
try {
|
|
64
|
+
const configPath = join(dataDir, 'config.toml');
|
|
65
|
+
if (!existsSync(configPath))
|
|
66
|
+
return DEFAULT_PORT;
|
|
67
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
68
|
+
const match = /^\s*port\s*=\s*(\d+)/m.exec(content);
|
|
69
|
+
if (match?.[1]) {
|
|
70
|
+
const port = parseInt(match[1], 10);
|
|
71
|
+
if (port > 0 && port <= 65535)
|
|
72
|
+
return port;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Ignore config read errors
|
|
77
|
+
}
|
|
78
|
+
return DEFAULT_PORT;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,oDAAoD;AACpD,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAE5C,cAAc;IACd,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAEhE,yBAAyB;IACzB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,IAAI,CAAC;YACH,UAAU,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;QACD,OAAO;IACT,CAAC;IAED,2BAA2B;IAC3B,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAElC,eAAe;IACf,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,SAAS,CAAC,CAAC;QAC3D,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,WAAW,IAAI,GAAG,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,0BAA0B,GAAG,GAAG,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,0BAA0B,GAAG,GAAG,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,OAAe;IAClC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,YAAY,CAAC;QAEjD,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,KAAK;gBAAE,OAAO,IAAI,CAAC;QAC7C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `waiaas stop` -- Stop the WAIaaS daemon.
|
|
3
|
+
*
|
|
4
|
+
* 1. Read PID file
|
|
5
|
+
* 2. Check if process alive
|
|
6
|
+
* 3. Send SIGTERM
|
|
7
|
+
* 4. Poll until process exits (or SIGKILL after timeout)
|
|
8
|
+
*/
|
|
9
|
+
export declare function stopCommand(dataDir: string): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=stop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4ChE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `waiaas stop` -- Stop the WAIaaS daemon.
|
|
3
|
+
*
|
|
4
|
+
* 1. Read PID file
|
|
5
|
+
* 2. Check if process alive
|
|
6
|
+
* 3. Send SIGTERM
|
|
7
|
+
* 4. Poll until process exits (or SIGKILL after timeout)
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync, unlinkSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
/** Maximum time to wait for graceful shutdown (ms). */
|
|
12
|
+
const STOP_TIMEOUT = 10_000;
|
|
13
|
+
/** Interval between alive checks (ms). */
|
|
14
|
+
const POLL_INTERVAL = 500;
|
|
15
|
+
export async function stopCommand(dataDir) {
|
|
16
|
+
const pidPath = join(dataDir, 'daemon.pid');
|
|
17
|
+
// Check PID file
|
|
18
|
+
if (!existsSync(pidPath)) {
|
|
19
|
+
console.log('Daemon is not running');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const pid = parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);
|
|
23
|
+
// Check if process is alive
|
|
24
|
+
if (!isProcessAlive(pid)) {
|
|
25
|
+
console.log('Daemon is not running (stale PID file)');
|
|
26
|
+
try {
|
|
27
|
+
unlinkSync(pidPath);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Ignore cleanup errors
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Send SIGTERM
|
|
35
|
+
console.log(`Stopping daemon (PID: ${pid})...`);
|
|
36
|
+
process.kill(pid, 'SIGTERM');
|
|
37
|
+
// Poll for process exit
|
|
38
|
+
const started = Date.now();
|
|
39
|
+
while (Date.now() - started < STOP_TIMEOUT) {
|
|
40
|
+
await sleep(POLL_INTERVAL);
|
|
41
|
+
if (!isProcessAlive(pid)) {
|
|
42
|
+
console.log('Daemon stopped');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Timeout -- send SIGKILL
|
|
47
|
+
console.log('Daemon did not stop within 10s, sending SIGKILL');
|
|
48
|
+
try {
|
|
49
|
+
process.kill(pid, 'SIGKILL');
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Process may have exited between check and kill
|
|
53
|
+
}
|
|
54
|
+
console.log('Daemon killed');
|
|
55
|
+
}
|
|
56
|
+
function isProcessAlive(pid) {
|
|
57
|
+
try {
|
|
58
|
+
process.kill(pid, 0);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function sleep(ms) {
|
|
66
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,uDAAuD;AACvD,MAAM,YAAY,GAAG,MAAM,CAAC;AAC5B,0CAA0C;AAC1C,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAE5C,iBAAiB;IACjB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAEhE,4BAA4B;IAC5B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,UAAU,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;QACD,OAAO;IACT,CAAC;IAED,eAAe;IACf,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,MAAM,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAE7B,wBAAwB;IACxB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,YAAY,EAAE,CAAC;QAC3C,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC;QAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAC9B,OAAO;QACT,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAC/D,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;IACnD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `waiaas upgrade` -- Upgrade WAIaaS to the latest version.
|
|
3
|
+
*
|
|
4
|
+
* Supports four modes:
|
|
5
|
+
* --check Check for available updates without upgrading
|
|
6
|
+
* --rollback Restore from the latest pre-upgrade backup
|
|
7
|
+
* --to <ver> Upgrade to a specific version
|
|
8
|
+
* (default) 7-step upgrade sequence:
|
|
9
|
+
* 1. Version check
|
|
10
|
+
* 2. Stop daemon
|
|
11
|
+
* 3. Create backup
|
|
12
|
+
* 4. Update package
|
|
13
|
+
* 5. Database migrations (deferred to daemon start)
|
|
14
|
+
* 6. Verify installation
|
|
15
|
+
* 7. Restart daemon
|
|
16
|
+
*/
|
|
17
|
+
export interface UpgradeOptions {
|
|
18
|
+
dataDir: string;
|
|
19
|
+
check?: boolean;
|
|
20
|
+
to?: string;
|
|
21
|
+
rollback?: boolean;
|
|
22
|
+
noStart?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Execute the upgrade command based on the provided options.
|
|
26
|
+
*/
|
|
27
|
+
export declare function upgradeCommand(opts: UpgradeOptions): Promise<void>;
|
|
28
|
+
//# sourceMappingURL=upgrade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAeH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAUxE"}
|