fluxy-bot 0.8.9 → 0.9.0
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 +53 -84
- package/bin/cli.js +1717 -6
- package/components.json +18 -18
- package/package.json +98 -109
- package/postcss.config.js +3 -3
- package/scripts/install.ps1 +1 -1
- package/scripts/install.sh +1 -1
- package/scripts/postinstall.js +47 -58
- package/shared/ai.ts +118 -202
- package/shared/config.ts +37 -39
- package/shared/logger.ts +6 -14
- package/shared/paths.ts +10 -16
- package/shared/relay.ts +89 -98
- package/supervisor/backend.ts +77 -89
- package/supervisor/chat/ARCHITECTURE.md +13 -14
- package/supervisor/chat/OnboardWizard.tsx +2194 -3419
- package/supervisor/chat/fluxy-main.tsx +495 -633
- package/supervisor/chat/fluxy.html +24 -36
- package/supervisor/chat/onboard-main.tsx +8 -8
- package/supervisor/chat/onboard.html +10 -13
- package/supervisor/chat/src/components/Chat/AudioBubble.tsx +94 -108
- package/supervisor/chat/src/components/Chat/ChatView.tsx +14 -36
- package/supervisor/chat/src/components/Chat/ImageLightbox.tsx +71 -89
- package/supervisor/chat/src/components/Chat/InputBar.tsx +498 -728
- package/supervisor/chat/src/components/Chat/MessageBubble.tsx +154 -246
- package/supervisor/chat/src/components/Chat/MessageList.tsx +114 -138
- package/supervisor/chat/src/components/Chat/TypingIndicator.tsx +38 -50
- package/supervisor/chat/src/components/LoginScreen.tsx +245 -296
- package/supervisor/chat/src/hooks/useChat.ts +210 -259
- package/supervisor/chat/src/hooks/useFluxyChat.ts +232 -322
- package/supervisor/chat/src/hooks/useSpeechRecognition.ts +126 -148
- package/supervisor/chat/src/lib/auth.ts +20 -23
- package/supervisor/chat/src/lib/ws-client.ts +113 -125
- package/supervisor/chat/src/styles/globals.css +76 -85
- package/supervisor/file-saver.ts +39 -52
- package/supervisor/fluxy-agent.ts +213 -292
- package/supervisor/index.ts +895 -1263
- package/supervisor/scheduler.ts +237 -299
- package/supervisor/tunnel.ts +113 -167
- package/supervisor/vite-dev.ts +51 -61
- package/supervisor/widget.js +135 -147
- package/supervisor/worker.ts +45 -49
- package/tsconfig.json +18 -24
- package/vite.config.ts +48 -55
- package/vite.fluxy.config.ts +34 -34
- package/worker/claude-auth.ts +202 -265
- package/worker/codex-auth.ts +144 -181
- package/worker/db.ts +63 -191
- package/worker/index.ts +601 -842
- package/workspace/MYSELF.md +1 -1
- package/workspace/PULSE.json +6 -6
- package/workspace/backend/index.ts +16 -19
- package/workspace/client/index.html +47 -60
- package/workspace/client/public/manifest.json +21 -21
- package/workspace/client/public/sw.js +29 -31
- package/workspace/client/src/App.tsx +91 -136
- package/workspace/client/src/components/Dashboard/DashboardPage.tsx +68 -72
- package/workspace/client/src/components/ErrorBoundary.tsx +11 -11
- package/workspace/client/src/components/Layout/DashboardLayout.tsx +35 -35
- package/workspace/client/src/components/Layout/Footer.tsx +12 -12
- package/workspace/client/src/components/Layout/MobileNav.tsx +23 -23
- package/workspace/client/src/components/Layout/Sidebar.tsx +81 -81
- package/workspace/client/src/components/ui/avatar.tsx +85 -85
- package/workspace/client/src/components/ui/badge.tsx +40 -41
- package/workspace/client/src/components/ui/button.tsx +56 -57
- package/workspace/client/src/components/ui/card.tsx +75 -75
- package/workspace/client/src/components/ui/dialog.tsx +114 -117
- package/workspace/client/src/components/ui/dropdown-menu.tsx +191 -199
- package/workspace/client/src/components/ui/input.tsx +17 -17
- package/workspace/client/src/components/ui/scroll-area.tsx +47 -47
- package/workspace/client/src/components/ui/select.tsx +145 -151
- package/workspace/client/src/components/ui/separator.tsx +21 -21
- package/workspace/client/src/components/ui/sheet.tsx +102 -102
- package/workspace/client/src/components/ui/skeleton.tsx +10 -10
- package/workspace/client/src/components/ui/switch.tsx +26 -26
- package/workspace/client/src/components/ui/tabs.tsx +69 -69
- package/workspace/client/src/components/ui/textarea.tsx +14 -14
- package/workspace/client/src/components/ui/tooltip.tsx +37 -37
- package/workspace/client/src/lib/utils.ts +1 -1
- package/workspace/client/src/main.tsx +3 -3
- package/workspace/client/src/styles/globals.css +76 -85
- package/workspace/skills/code-reviewer/.claude-plugin/plugin.json +3 -3
- package/workspace/skills/code-reviewer/skills/code-reviewer/SKILL.md +0 -6
- package/workspace/skills/daily-standup/.claude-plugin/plugin.json +3 -3
- package/workspace/skills/daily-standup/skills/daily-standup/SKILL.md +0 -7
- package/workspace/skills/workspace-helper/.claude-plugin/plugin.json +3 -3
- package/workspace/skills/workspace-helper/skills/workspace-helper/SKILL.md +0 -2
- package/bin/cli.backup.js +0 -2138
- package/cli/commands/daemon.ts +0 -42
- package/cli/commands/init.ts +0 -32
- package/cli/commands/start.ts +0 -113
- package/cli/commands/tunnel.temp.ts +0 -206
- package/cli/commands/tunnel.ts +0 -227
- package/cli/commands/update.ts +0 -163
- package/cli/core/base-adapter.ts +0 -156
- package/cli/core/cloudflared.ts +0 -113
- package/cli/core/config.ts +0 -73
- package/cli/core/os-detector.ts +0 -43
- package/cli/core/server.ts +0 -109
- package/cli/core/types.ts +0 -15
- package/cli/index.ts +0 -72
- package/cli/platforms/darwin.ts +0 -146
- package/cli/platforms/index.ts +0 -21
- package/cli/platforms/linux.ts +0 -156
- package/cli/platforms/win32.ts +0 -34
- package/cli/utils/ui.ts +0 -37
package/cli/index.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { getAdapter } from './platforms/index.js';
|
|
3
|
-
import { DATA_DIR } from './core/config.js';
|
|
4
|
-
import os from 'node:os';
|
|
5
|
-
|
|
6
|
-
import { registerDaemonCommand } from './commands/daemon.js';
|
|
7
|
-
import { registerStartCommand } from './commands/start.js';
|
|
8
|
-
import { registerTunnelCommand } from './commands/tunnel.js';
|
|
9
|
-
import { registerUpdateCommand } from './commands/update.js';
|
|
10
|
-
import { registerInitCommand } from './commands/init.js';
|
|
11
|
-
import { pkg } from './core/config.js';
|
|
12
|
-
|
|
13
|
-
const program = new Command();
|
|
14
|
-
|
|
15
|
-
program
|
|
16
|
-
.name('fluxy')
|
|
17
|
-
.description('Fluxy Local AI and Tunneling Supervisor')
|
|
18
|
-
.version(pkg.version);
|
|
19
|
-
|
|
20
|
-
registerStartCommand(program);
|
|
21
|
-
registerDaemonCommand(program);
|
|
22
|
-
registerTunnelCommand(program);
|
|
23
|
-
registerUpdateCommand(program);
|
|
24
|
-
registerInitCommand(program);
|
|
25
|
-
|
|
26
|
-
// Aliases for convenience matching the old CLI
|
|
27
|
-
program
|
|
28
|
-
.command('stop')
|
|
29
|
-
.description('Stop the Fluxy daemon')
|
|
30
|
-
.action(() => {
|
|
31
|
-
getAdapter().handleDaemonAction('stop', {
|
|
32
|
-
user: process.env.SUDO_USER || os.userInfo().username,
|
|
33
|
-
home: process.env.FLUXY_REAL_HOME || os.homedir(),
|
|
34
|
-
nodePath: process.env.FLUXY_NODE_PATH || process.execPath,
|
|
35
|
-
dataDir: DATA_DIR
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
program
|
|
40
|
-
.command('status')
|
|
41
|
-
.description('Check the Fluxy daemon status')
|
|
42
|
-
.action(() => {
|
|
43
|
-
getAdapter().handleDaemonAction('status', {
|
|
44
|
-
user: process.env.SUDO_USER || os.userInfo().username,
|
|
45
|
-
home: process.env.FLUXY_REAL_HOME || os.homedir(),
|
|
46
|
-
nodePath: process.env.FLUXY_NODE_PATH || process.execPath,
|
|
47
|
-
dataDir: DATA_DIR
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
program
|
|
52
|
-
.command('logs')
|
|
53
|
-
.description('View the Fluxy daemon logs')
|
|
54
|
-
.action(() => {
|
|
55
|
-
getAdapter().handleDaemonAction('logs', {
|
|
56
|
-
user: process.env.SUDO_USER || os.userInfo().username,
|
|
57
|
-
home: process.env.FLUXY_REAL_HOME || os.homedir(),
|
|
58
|
-
nodePath: process.env.FLUXY_NODE_PATH || process.execPath,
|
|
59
|
-
dataDir: DATA_DIR
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
if (process.argv.length === 2) {
|
|
64
|
-
const fs = await import('node:fs');
|
|
65
|
-
const { CONFIG_PATH } = await import('./core/config.js');
|
|
66
|
-
if (fs.existsSync(CONFIG_PATH)) {
|
|
67
|
-
process.argv.push('start');
|
|
68
|
-
} else {
|
|
69
|
-
process.argv.push('init');
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
program.parse(process.argv);
|
package/cli/platforms/darwin.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { execSync, spawnSync } from 'node:child_process';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
|
|
6
|
-
import { BaseAdapter } from '../core/base-adapter.js';
|
|
7
|
-
import type { DaemonConfig } from '../core/types.js';
|
|
8
|
-
|
|
9
|
-
const LAUNCHD_LABEL = 'com.fluxy.bot';
|
|
10
|
-
|
|
11
|
-
const LAUNCHD_PLIST_PATH = path.join(
|
|
12
|
-
os.homedir(),
|
|
13
|
-
'Library',
|
|
14
|
-
'LaunchAgents',
|
|
15
|
-
`${LAUNCHD_LABEL}.plist`
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
const LAUNCHD_LOG_DIR = path.join(os.homedir(), 'Library', 'Logs', 'fluxy');
|
|
19
|
-
|
|
20
|
-
function generateLaunchdPlist({ nodePath, dataDir }: DaemonConfig) {
|
|
21
|
-
const nodeBinDir = path.dirname(nodePath);
|
|
22
|
-
fs.mkdirSync(LAUNCHD_LOG_DIR, { recursive: true });
|
|
23
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
24
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
25
|
-
<plist version="1.0">
|
|
26
|
-
<dict>
|
|
27
|
-
<key>Label</key>
|
|
28
|
-
<string>${LAUNCHD_LABEL}</string>
|
|
29
|
-
<key>ProgramArguments</key>
|
|
30
|
-
<array>
|
|
31
|
-
<string>${nodePath}</string>
|
|
32
|
-
<string>--import</string>
|
|
33
|
-
<string>tsx/esm</string>
|
|
34
|
-
<string>${dataDir}/supervisor/index.ts</string>
|
|
35
|
-
</array>
|
|
36
|
-
<key>WorkingDirectory</key>
|
|
37
|
-
<string>${dataDir}</string>
|
|
38
|
-
<key>EnvironmentVariables</key>
|
|
39
|
-
<dict>
|
|
40
|
-
<key>HOME</key>
|
|
41
|
-
<string>${os.homedir()}</string>
|
|
42
|
-
<key>NODE_ENV</key>
|
|
43
|
-
<string>development</string>
|
|
44
|
-
<key>NODE_PATH</key>
|
|
45
|
-
<string>${dataDir}/node_modules</string>
|
|
46
|
-
<key>PATH</key>
|
|
47
|
-
<string>${nodeBinDir}:${dataDir}/node_modules/.bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
|
|
48
|
-
</dict>
|
|
49
|
-
<key>RunAtLoad</key>
|
|
50
|
-
<true/>
|
|
51
|
-
<key>KeepAlive</key>
|
|
52
|
-
<dict>
|
|
53
|
-
<key>SuccessfulExit</key>
|
|
54
|
-
<false/>
|
|
55
|
-
</dict>
|
|
56
|
-
<key>ThrottleInterval</key>
|
|
57
|
-
<integer>5</integer>
|
|
58
|
-
<key>StandardOutPath</key>
|
|
59
|
-
<string>${LAUNCHD_LOG_DIR}/fluxy.log</string>
|
|
60
|
-
<key>StandardErrorPath</key>
|
|
61
|
-
<string>${LAUNCHD_LOG_DIR}/fluxy.error.log</string>
|
|
62
|
-
</dict>
|
|
63
|
-
</plist>`;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export class DarwinAdapter extends BaseAdapter {
|
|
67
|
-
get hasDaemonSupport() {
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
get isInstalled() {
|
|
72
|
-
return fs.existsSync(LAUNCHD_PLIST_PATH);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
get isActive() {
|
|
76
|
-
try {
|
|
77
|
-
const out = execSync(
|
|
78
|
-
`launchctl list ${LAUNCHD_LABEL} 2>/dev/null`,
|
|
79
|
-
{
|
|
80
|
-
encoding: 'utf-8'
|
|
81
|
-
}
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
const pidLine = out.split('\n').find(l => l.includes('PID'));
|
|
85
|
-
if (pidLine) {
|
|
86
|
-
const pid = pidLine.split('=')[1]?.trim();
|
|
87
|
-
return Boolean(pid && pid !== '0' && pid !== '-');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return !out.includes('"PID" = 0;');
|
|
91
|
-
} catch {
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
protected installService(config: DaemonConfig): void {
|
|
97
|
-
const plist = generateLaunchdPlist(config);
|
|
98
|
-
|
|
99
|
-
fs.mkdirSync(path.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
|
|
100
|
-
fs.writeFileSync(LAUNCHD_PLIST_PATH, plist);
|
|
101
|
-
|
|
102
|
-
execSync(`launchctl load "${LAUNCHD_PLIST_PATH}"`, {
|
|
103
|
-
stdio: 'inherit'
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
protected startService(): void {
|
|
108
|
-
execSync(
|
|
109
|
-
`launchctl unload "${LAUNCHD_PLIST_PATH}" 2>/dev/null; launchctl load "${LAUNCHD_PLIST_PATH}"`,
|
|
110
|
-
{ stdio: 'inherit' }
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
protected stopService(): void {
|
|
115
|
-
execSync(`launchctl unload "${LAUNCHD_PLIST_PATH}"`, {
|
|
116
|
-
stdio: 'inherit'
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
protected uninstallService(): void {
|
|
121
|
-
try {
|
|
122
|
-
execSync(`launchctl unload "${LAUNCHD_PLIST_PATH}" 2>/dev/null`, {
|
|
123
|
-
stdio: 'ignore'
|
|
124
|
-
});
|
|
125
|
-
} catch {}
|
|
126
|
-
if (fs.existsSync(LAUNCHD_PLIST_PATH)) {
|
|
127
|
-
fs.unlinkSync(LAUNCHD_PLIST_PATH);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
protected showLogs(): void {
|
|
132
|
-
const logPath = `${LAUNCHD_LOG_DIR}/fluxy.log`;
|
|
133
|
-
if (fs.existsSync(logPath)) {
|
|
134
|
-
spawnSync('tail', ['-f', logPath], { stdio: 'inherit' });
|
|
135
|
-
} else {
|
|
136
|
-
// oxlint-disable-next-line no-console
|
|
137
|
-
console.log('Log file not found yet.');
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
protected checkStatus(): void {
|
|
142
|
-
try {
|
|
143
|
-
execSync(`launchctl list ${LAUNCHD_LABEL}`, { stdio: 'inherit' });
|
|
144
|
-
} catch {}
|
|
145
|
-
}
|
|
146
|
-
}
|
package/cli/platforms/index.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { getPlatform } from '../core/os-detector.js';
|
|
2
|
-
import { BaseAdapter } from '../core/base-adapter.js';
|
|
3
|
-
|
|
4
|
-
import { DarwinAdapter } from './darwin.js';
|
|
5
|
-
import { LinuxAdapter } from './linux.js';
|
|
6
|
-
import { WindowsAdapter } from './win32.js';
|
|
7
|
-
|
|
8
|
-
export function getAdapter(): BaseAdapter {
|
|
9
|
-
const platform = getPlatform();
|
|
10
|
-
|
|
11
|
-
switch (platform) {
|
|
12
|
-
case 'darwin':
|
|
13
|
-
return new DarwinAdapter();
|
|
14
|
-
case 'win32':
|
|
15
|
-
return new WindowsAdapter();
|
|
16
|
-
case 'linux':
|
|
17
|
-
default:
|
|
18
|
-
// Assuming fallback to linux for other unix-like
|
|
19
|
-
return new LinuxAdapter();
|
|
20
|
-
}
|
|
21
|
-
}
|
package/cli/platforms/linux.ts
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
// oxlint-disable no-console
|
|
2
|
-
import { execSync, spawnSync } from 'node:child_process';
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import os from 'node:os';
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
|
|
7
|
-
import pc from 'picocolors';
|
|
8
|
-
|
|
9
|
-
import { BaseAdapter } from '../core/base-adapter.js';
|
|
10
|
-
import { SERVICE_NAME } from '../core/config.js';
|
|
11
|
-
import type { DaemonAction, DaemonConfig } from '../core/types.js';
|
|
12
|
-
|
|
13
|
-
const SERVICE_PATH = `/etc/systemd/system/${SERVICE_NAME}.service`;
|
|
14
|
-
|
|
15
|
-
function generateUnitFile({ user, home, nodePath, dataDir }: DaemonConfig) {
|
|
16
|
-
const nodeBinDir = path.dirname(nodePath);
|
|
17
|
-
return `[Unit]
|
|
18
|
-
Description=Fluxy Bot
|
|
19
|
-
After=network-online.target
|
|
20
|
-
Wants=network-online.target
|
|
21
|
-
|
|
22
|
-
[Service]
|
|
23
|
-
Type=simple
|
|
24
|
-
User=${user}
|
|
25
|
-
WorkingDirectory=${dataDir}
|
|
26
|
-
ExecStart=${nodePath} --import tsx/esm ${dataDir}/supervisor/index.ts
|
|
27
|
-
Restart=on-failure
|
|
28
|
-
RestartSec=5
|
|
29
|
-
Environment=HOME=${home}
|
|
30
|
-
Environment=NODE_ENV=development
|
|
31
|
-
Environment=NODE_PATH=${dataDir}/node_modules
|
|
32
|
-
Environment=PATH=${nodeBinDir}:${dataDir}/node_modules/.bin:/usr/local/bin:/usr/bin:/bin
|
|
33
|
-
StandardOutput=journal
|
|
34
|
-
StandardError=journal
|
|
35
|
-
SyslogIdentifier=fluxy
|
|
36
|
-
|
|
37
|
-
[Install]
|
|
38
|
-
WantedBy=multi-user.target
|
|
39
|
-
`;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export class LinuxAdapter extends BaseAdapter {
|
|
43
|
-
get hasDaemonSupport(): boolean {
|
|
44
|
-
try {
|
|
45
|
-
execSync('systemctl --version', { stdio: 'ignore' });
|
|
46
|
-
return true;
|
|
47
|
-
} catch {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
get isInstalled(): boolean {
|
|
53
|
-
return fs.existsSync(SERVICE_PATH);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
get isActive(): boolean {
|
|
57
|
-
try {
|
|
58
|
-
execSync(`systemctl is-active ${SERVICE_NAME}`, {
|
|
59
|
-
stdio: 'ignore'
|
|
60
|
-
});
|
|
61
|
-
return true;
|
|
62
|
-
} catch {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
protected requiresPrivilegeEscalation(action: DaemonAction): boolean {
|
|
68
|
-
if (action === 'status' || action === 'logs') return false;
|
|
69
|
-
return process.getuid?.() !== 0;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
protected escalatePrivileges(): void {
|
|
73
|
-
const nodePath = process.env.FLUXY_NODE_PATH || process.execPath;
|
|
74
|
-
const realHome = process.env.FLUXY_REAL_HOME || this.getRealHome();
|
|
75
|
-
const args = process.argv.slice(1);
|
|
76
|
-
|
|
77
|
-
console.log(pc.yellow('Sudo is required for this action.'));
|
|
78
|
-
const result = spawnSync(
|
|
79
|
-
'sudo',
|
|
80
|
-
[
|
|
81
|
-
`FLUXY_NODE_PATH=${nodePath}`,
|
|
82
|
-
`FLUXY_REAL_HOME=${realHome}`,
|
|
83
|
-
nodePath,
|
|
84
|
-
...args
|
|
85
|
-
],
|
|
86
|
-
{ stdio: 'inherit' }
|
|
87
|
-
);
|
|
88
|
-
process.exit(result.status ?? 1);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
private getRealUser() {
|
|
92
|
-
return process.env.SUDO_USER || os.userInfo().username;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
private getRealHome() {
|
|
96
|
-
try {
|
|
97
|
-
return execSync(`getent passwd ${this.getRealUser()}`, {
|
|
98
|
-
encoding: 'utf-8'
|
|
99
|
-
})
|
|
100
|
-
.split(':')[5]
|
|
101
|
-
.trim();
|
|
102
|
-
} catch {
|
|
103
|
-
return os.homedir();
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
protected installService(config: DaemonConfig): void {
|
|
108
|
-
const unit = generateUnitFile(config);
|
|
109
|
-
fs.writeFileSync(SERVICE_PATH, unit);
|
|
110
|
-
|
|
111
|
-
execSync(
|
|
112
|
-
[
|
|
113
|
-
`systemctl daemon-reload`,
|
|
114
|
-
`systemctl enable ${SERVICE_NAME}`,
|
|
115
|
-
`systemctl start ${SERVICE_NAME}`
|
|
116
|
-
].join('; '),
|
|
117
|
-
{ stdio: 'inherit' }
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
protected startService(): void {
|
|
122
|
-
execSync(`systemctl start ${SERVICE_NAME}`, { stdio: 'inherit' });
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
protected stopService(): void {
|
|
126
|
-
execSync(`systemctl stop ${SERVICE_NAME}`, { stdio: 'inherit' });
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
protected uninstallService(): void {
|
|
130
|
-
execSync(
|
|
131
|
-
[
|
|
132
|
-
`systemctl disable ${SERVICE_NAME}`,
|
|
133
|
-
`systemctl stop ${SERVICE_NAME}`
|
|
134
|
-
].join('; '),
|
|
135
|
-
{ stdio: 'ignore' }
|
|
136
|
-
);
|
|
137
|
-
if (fs.existsSync(SERVICE_PATH)) {
|
|
138
|
-
fs.unlinkSync(SERVICE_PATH);
|
|
139
|
-
}
|
|
140
|
-
execSync(`systemctl daemon-reload`, { stdio: 'ignore' });
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
protected showLogs(): void {
|
|
144
|
-
spawnSync('journalctl', ['-u', SERVICE_NAME, '-f', '-n', '50'], {
|
|
145
|
-
stdio: 'inherit'
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
protected checkStatus(): void {
|
|
150
|
-
try {
|
|
151
|
-
execSync(`systemctl status ${SERVICE_NAME}`, { stdio: 'inherit' });
|
|
152
|
-
} catch {
|
|
153
|
-
// systemctl status returns non-zero when not active, ignoring
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
package/cli/platforms/win32.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// oxlint-disable no-console
|
|
2
|
-
// oxlint-disable no-unused-vars
|
|
3
|
-
import pc from 'picocolors';
|
|
4
|
-
|
|
5
|
-
import { BaseAdapter } from '../core/base-adapter.js';
|
|
6
|
-
import type { DaemonConfig } from '../core/types.js';
|
|
7
|
-
|
|
8
|
-
export class WindowsAdapter extends BaseAdapter {
|
|
9
|
-
get hasDaemonSupport() {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
get isInstalled() {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
get isActive() {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
protected installService(config: DaemonConfig): void {
|
|
22
|
-
console.log(
|
|
23
|
-
pc.yellow(
|
|
24
|
-
'Daemon mode is not supported on Windows natively yet. Use Task Scheduler.'
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
protected startService(): void {}
|
|
30
|
-
protected stopService(): void {}
|
|
31
|
-
protected uninstallService(): void {}
|
|
32
|
-
protected showLogs(): void {}
|
|
33
|
-
protected checkStatus(): void {}
|
|
34
|
-
}
|
package/cli/utils/ui.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import pc from 'picocolors';
|
|
2
|
-
import { pkg } from '../core/config.ts';
|
|
3
|
-
|
|
4
|
-
export const logger = {
|
|
5
|
-
info(...lines: (string | null | undefined)[]) {
|
|
6
|
-
console.log(lines.filter(l => l != null).join('\n'));
|
|
7
|
-
},
|
|
8
|
-
warn(...lines: (string | null | undefined)[]) {
|
|
9
|
-
console.warn(lines.filter(l => l != null).join('\n'));
|
|
10
|
-
},
|
|
11
|
-
error(...lines: (string | null | undefined)[]) {
|
|
12
|
-
console.error(lines.filter(l => l != null).join('\n'));
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export function banner() {
|
|
17
|
-
// A nice gradient-like or colorful output
|
|
18
|
-
const b1 = (s: string) => pc.bold(pc.blue(s));
|
|
19
|
-
const b2 = (s: string) => pc.bold(pc.magenta(s));
|
|
20
|
-
const dim = pc.dim;
|
|
21
|
-
|
|
22
|
-
logger.info(
|
|
23
|
-
``,
|
|
24
|
-
b1(` _______ _ `),
|
|
25
|
-
b1(` (_______) | `),
|
|
26
|
-
b1(` _____ | |_ _ _ _ _ _ `),
|
|
27
|
-
b1(` | ___) | | | | ( \\ / ) | | | `),
|
|
28
|
-
b2(` | | | | |_| |) X (| |_| | `),
|
|
29
|
-
b2(` |_| |_|\\____(_/ \\_)\\__ | `),
|
|
30
|
-
b2(` (____/ `),
|
|
31
|
-
dim(`v${pkg.version || '1.0.0'} · Self-hosted AI agent `)
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function commandExample(name: string, cmd: string) {
|
|
36
|
-
return ` ${pc.dim(name)} ${pc.magenta(cmd)}`;
|
|
37
|
-
}
|