@vibecompany/247-cli 0.1.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 +110 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +277 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/hooks.d.ts +3 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +127 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +116 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +3 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +38 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/service.d.ts +3 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +235 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/start.d.ts +3 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +109 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +62 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +3 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +23 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +121 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/hooks/installer.d.ts +36 -0
- package/dist/hooks/installer.d.ts.map +1 -0
- package/dist/hooks/installer.js +175 -0
- package/dist/hooks/installer.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +46 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +88 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/paths.d.ts +34 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +76 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/prerequisites.d.ts +36 -0
- package/dist/lib/prerequisites.d.ts.map +1 -0
- package/dist/lib/prerequisites.js +181 -0
- package/dist/lib/prerequisites.js.map +1 -0
- package/dist/lib/process.d.ts +39 -0
- package/dist/lib/process.d.ts.map +1 -0
- package/dist/lib/process.js +188 -0
- package/dist/lib/process.js.map +1 -0
- package/dist/service/index.d.ts +44 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/index.js +18 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/launchd.d.ts +18 -0
- package/dist/service/launchd.d.ts.map +1 -0
- package/dist/service/launchd.js +208 -0
- package/dist/service/launchd.js.map +1 -0
- package/dist/service/systemd.d.ts +18 -0
- package/dist/service/systemd.d.ts.map +1 -0
- package/dist/service/systemd.js +196 -0
- package/dist/service/systemd.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { exec } from 'child_process';
|
|
5
|
+
import { promisify } from 'util';
|
|
6
|
+
import { createServiceManager } from '../service/index.js';
|
|
7
|
+
import { isAgentRunning, stopAgent } from '../lib/process.js';
|
|
8
|
+
import { installHooks } from '../hooks/installer.js';
|
|
9
|
+
const execAsync = promisify(exec);
|
|
10
|
+
const PACKAGE_NAME = '@vibecompany/247';
|
|
11
|
+
export const updateCommand = new Command('update')
|
|
12
|
+
.description('Update 247 to the latest version')
|
|
13
|
+
.option('--check', 'Only check for updates without installing')
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
console.log(chalk.bold('\n247 Update\n'));
|
|
16
|
+
const checkSpinner = ora('Checking for updates...').start();
|
|
17
|
+
try {
|
|
18
|
+
// Get current version
|
|
19
|
+
const pkg = await import('../../package.json', {
|
|
20
|
+
with: { type: 'json' },
|
|
21
|
+
});
|
|
22
|
+
const currentVersion = pkg.default.version;
|
|
23
|
+
// Check npm for latest version
|
|
24
|
+
let latestVersion;
|
|
25
|
+
try {
|
|
26
|
+
const { stdout } = await execAsync(`npm view ${PACKAGE_NAME} version 2>/dev/null`);
|
|
27
|
+
latestVersion = stdout.trim();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
checkSpinner.fail('Failed to check for updates. Are you connected to the internet?');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
if (currentVersion === latestVersion) {
|
|
34
|
+
checkSpinner.succeed(`Already on the latest version (${currentVersion})`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
checkSpinner.succeed(`Update available: ${currentVersion} → ${latestVersion}`);
|
|
38
|
+
if (options.check) {
|
|
39
|
+
console.log(chalk.dim('\nRun "247 update" to install the update.\n'));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log();
|
|
43
|
+
// Check if service is running
|
|
44
|
+
const serviceManager = createServiceManager();
|
|
45
|
+
let serviceWasRunning = false;
|
|
46
|
+
try {
|
|
47
|
+
const serviceStatus = await serviceManager.status();
|
|
48
|
+
serviceWasRunning = serviceStatus.running;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Service not installed, check daemon
|
|
52
|
+
const daemonStatus = isAgentRunning();
|
|
53
|
+
serviceWasRunning = daemonStatus.running;
|
|
54
|
+
}
|
|
55
|
+
// Stop agent if running
|
|
56
|
+
if (serviceWasRunning) {
|
|
57
|
+
const stopSpinner = ora('Stopping agent...').start();
|
|
58
|
+
try {
|
|
59
|
+
const serviceStatus = await serviceManager.status();
|
|
60
|
+
if (serviceStatus.installed && serviceStatus.running) {
|
|
61
|
+
await serviceManager.stop();
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
await stopAgent();
|
|
65
|
+
}
|
|
66
|
+
stopSpinner.succeed('Agent stopped');
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
stopSpinner.warn(`Could not stop agent: ${err.message}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Update via npm
|
|
73
|
+
const updateSpinner = ora('Updating via npm...').start();
|
|
74
|
+
try {
|
|
75
|
+
await execAsync(`npm install -g ${PACKAGE_NAME}@latest`);
|
|
76
|
+
updateSpinner.succeed('Package updated');
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
updateSpinner.fail(`Failed to update: ${err.message}`);
|
|
80
|
+
console.log(chalk.dim('\nTry running manually: npm install -g @vibecompany/247@latest\n'));
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
// Update hooks
|
|
84
|
+
const hooksSpinner = ora('Updating hooks...').start();
|
|
85
|
+
const hooksResult = installHooks();
|
|
86
|
+
if (hooksResult.success) {
|
|
87
|
+
hooksSpinner.succeed('Hooks updated');
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
hooksSpinner.warn(`Could not update hooks: ${hooksResult.error}`);
|
|
91
|
+
}
|
|
92
|
+
// Restart agent if it was running
|
|
93
|
+
if (serviceWasRunning) {
|
|
94
|
+
const startSpinner = ora('Restarting agent...').start();
|
|
95
|
+
try {
|
|
96
|
+
const serviceStatus = await serviceManager.status();
|
|
97
|
+
if (serviceStatus.installed) {
|
|
98
|
+
await serviceManager.start();
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// Will use the daemon mode - but after update the binary changed
|
|
102
|
+
// so we should tell user to restart manually
|
|
103
|
+
startSpinner.info('Please restart the agent manually: 247 start');
|
|
104
|
+
}
|
|
105
|
+
startSpinner.succeed('Agent restarted');
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
startSpinner.warn(`Could not restart agent: ${err.message}`);
|
|
109
|
+
console.log(chalk.dim('Run "247 start" to start the agent manually.'));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
console.log();
|
|
113
|
+
console.log(chalk.green('✓ Update complete!'));
|
|
114
|
+
console.log();
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
checkSpinner.fail(`Error: ${err.message}`);
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface HooksInstallResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
installed: boolean;
|
|
4
|
+
updated: boolean;
|
|
5
|
+
path: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface HooksStatus {
|
|
9
|
+
installed: boolean;
|
|
10
|
+
path: string;
|
|
11
|
+
isSymlink: boolean;
|
|
12
|
+
sourceVersion?: string;
|
|
13
|
+
installedVersion?: string;
|
|
14
|
+
needsUpdate: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get hooks installation status
|
|
18
|
+
*/
|
|
19
|
+
export declare function getHooksStatus(): HooksStatus;
|
|
20
|
+
/**
|
|
21
|
+
* Install hooks to ~/.claude-plugins/247-hooks/
|
|
22
|
+
* In dev mode: creates a symlink
|
|
23
|
+
* In prod mode: copies files
|
|
24
|
+
*/
|
|
25
|
+
export declare function installHooks(options?: {
|
|
26
|
+
force?: boolean;
|
|
27
|
+
useSymlink?: boolean;
|
|
28
|
+
}): HooksInstallResult;
|
|
29
|
+
/**
|
|
30
|
+
* Uninstall hooks from ~/.claude-plugins/
|
|
31
|
+
*/
|
|
32
|
+
export declare function uninstallHooks(): {
|
|
33
|
+
success: boolean;
|
|
34
|
+
error?: string;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/hooks/installer.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAgD5C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,kBAAkB,CAiFxG;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAmBrE"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, copyFileSync, symlinkSync, unlinkSync, readFileSync, readdirSync, lstatSync, rmSync } from 'fs';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { getAgentPaths } from '../lib/paths.js';
|
|
4
|
+
/**
|
|
5
|
+
* Get hooks installation status
|
|
6
|
+
*/
|
|
7
|
+
export function getHooksStatus() {
|
|
8
|
+
const paths = getAgentPaths();
|
|
9
|
+
const dest = paths.hooksDestination;
|
|
10
|
+
const pluginJsonPath = join(dest, '.claude-plugin', 'plugin.json');
|
|
11
|
+
const installed = existsSync(pluginJsonPath);
|
|
12
|
+
let isSymlink = false;
|
|
13
|
+
if (installed) {
|
|
14
|
+
try {
|
|
15
|
+
isSymlink = lstatSync(dest).isSymbolicLink();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// Not a symlink
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
let sourceVersion;
|
|
22
|
+
let installedVersion;
|
|
23
|
+
// Read source version
|
|
24
|
+
const sourcePluginJson = join(paths.hooksSource, '.claude-plugin', 'plugin.json');
|
|
25
|
+
if (existsSync(sourcePluginJson)) {
|
|
26
|
+
try {
|
|
27
|
+
const data = JSON.parse(readFileSync(sourcePluginJson, 'utf-8'));
|
|
28
|
+
sourceVersion = data.version;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Ignore parse errors
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Read installed version
|
|
35
|
+
if (installed) {
|
|
36
|
+
try {
|
|
37
|
+
const data = JSON.parse(readFileSync(pluginJsonPath, 'utf-8'));
|
|
38
|
+
installedVersion = data.version;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Ignore parse errors
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
installed,
|
|
46
|
+
path: dest,
|
|
47
|
+
isSymlink,
|
|
48
|
+
sourceVersion,
|
|
49
|
+
installedVersion,
|
|
50
|
+
needsUpdate: installed && sourceVersion !== installedVersion,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Install hooks to ~/.claude-plugins/247-hooks/
|
|
55
|
+
* In dev mode: creates a symlink
|
|
56
|
+
* In prod mode: copies files
|
|
57
|
+
*/
|
|
58
|
+
export function installHooks(options = {}) {
|
|
59
|
+
const paths = getAgentPaths();
|
|
60
|
+
const source = paths.hooksSource;
|
|
61
|
+
const dest = paths.hooksDestination;
|
|
62
|
+
// Verify source exists
|
|
63
|
+
if (!existsSync(source)) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
installed: false,
|
|
67
|
+
updated: false,
|
|
68
|
+
path: dest,
|
|
69
|
+
error: `Hooks source not found at ${source}`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Create parent directory if needed
|
|
73
|
+
const parentDir = dirname(dest);
|
|
74
|
+
if (!existsSync(parentDir)) {
|
|
75
|
+
mkdirSync(parentDir, { recursive: true });
|
|
76
|
+
}
|
|
77
|
+
const status = getHooksStatus();
|
|
78
|
+
const alreadyInstalled = status.installed;
|
|
79
|
+
// Skip if already up to date (unless force)
|
|
80
|
+
if (alreadyInstalled && !options.force && !status.needsUpdate) {
|
|
81
|
+
return {
|
|
82
|
+
success: true,
|
|
83
|
+
installed: false,
|
|
84
|
+
updated: false,
|
|
85
|
+
path: dest,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Remove existing if updating or force
|
|
89
|
+
if (existsSync(dest)) {
|
|
90
|
+
try {
|
|
91
|
+
if (status.isSymlink) {
|
|
92
|
+
unlinkSync(dest);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
rmSync(dest, { recursive: true, force: true });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
return {
|
|
100
|
+
success: false,
|
|
101
|
+
installed: false,
|
|
102
|
+
updated: false,
|
|
103
|
+
path: dest,
|
|
104
|
+
error: `Failed to remove existing: ${err.message}`,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Determine install method
|
|
109
|
+
const useSymlink = options.useSymlink ?? paths.isDev;
|
|
110
|
+
try {
|
|
111
|
+
if (useSymlink) {
|
|
112
|
+
// Symlink for dev - changes to hooks are immediately reflected
|
|
113
|
+
symlinkSync(source, dest, 'dir');
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Copy for prod - stable installation
|
|
117
|
+
copyDirectoryRecursive(source, dest);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
return {
|
|
122
|
+
success: false,
|
|
123
|
+
installed: false,
|
|
124
|
+
updated: false,
|
|
125
|
+
path: dest,
|
|
126
|
+
error: `Failed to install: ${err.message}`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
success: true,
|
|
131
|
+
installed: !alreadyInstalled,
|
|
132
|
+
updated: alreadyInstalled,
|
|
133
|
+
path: dest,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Uninstall hooks from ~/.claude-plugins/
|
|
138
|
+
*/
|
|
139
|
+
export function uninstallHooks() {
|
|
140
|
+
const paths = getAgentPaths();
|
|
141
|
+
const dest = paths.hooksDestination;
|
|
142
|
+
if (!existsSync(dest)) {
|
|
143
|
+
return { success: true }; // Already uninstalled
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
const status = getHooksStatus();
|
|
147
|
+
if (status.isSymlink) {
|
|
148
|
+
unlinkSync(dest);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
rmSync(dest, { recursive: true, force: true });
|
|
152
|
+
}
|
|
153
|
+
return { success: true };
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
return { success: false, error: err.message };
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Recursively copy a directory
|
|
161
|
+
*/
|
|
162
|
+
function copyDirectoryRecursive(source, dest) {
|
|
163
|
+
mkdirSync(dest, { recursive: true });
|
|
164
|
+
for (const entry of readdirSync(source, { withFileTypes: true })) {
|
|
165
|
+
const srcPath = join(source, entry.name);
|
|
166
|
+
const destPath = join(dest, entry.name);
|
|
167
|
+
if (entry.isDirectory()) {
|
|
168
|
+
copyDirectoryRecursive(srcPath, destPath);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
copyFileSync(srcPath, destPath);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/hooks/installer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { initCommand } from './commands/init.js';
|
|
4
|
+
import { startCommand } from './commands/start.js';
|
|
5
|
+
import { stopCommand } from './commands/stop.js';
|
|
6
|
+
import { statusCommand } from './commands/status.js';
|
|
7
|
+
import { logsCommand } from './commands/logs.js';
|
|
8
|
+
import { serviceCommand } from './commands/service.js';
|
|
9
|
+
import { hooksCommand } from './commands/hooks.js';
|
|
10
|
+
import { updateCommand } from './commands/update.js';
|
|
11
|
+
import { doctorCommand } from './commands/doctor.js';
|
|
12
|
+
const program = new Command();
|
|
13
|
+
program
|
|
14
|
+
.name('247')
|
|
15
|
+
.description('247 - Access Claude Code from anywhere 24/7\nby The Vibe Company')
|
|
16
|
+
.version('0.1.0');
|
|
17
|
+
// Add commands
|
|
18
|
+
program.addCommand(initCommand);
|
|
19
|
+
program.addCommand(startCommand);
|
|
20
|
+
program.addCommand(stopCommand);
|
|
21
|
+
program.addCommand(statusCommand);
|
|
22
|
+
program.addCommand(logsCommand);
|
|
23
|
+
program.addCommand(serviceCommand);
|
|
24
|
+
program.addCommand(hooksCommand);
|
|
25
|
+
program.addCommand(updateCommand);
|
|
26
|
+
program.addCommand(doctorCommand);
|
|
27
|
+
// Default action (no command)
|
|
28
|
+
program.action(() => {
|
|
29
|
+
console.log(`
|
|
30
|
+
╭──────────────────────────────────╮
|
|
31
|
+
│ 247 - The Vibe Company │
|
|
32
|
+
│ Access Claude Code 24/7 │
|
|
33
|
+
╰──────────────────────────────────╯
|
|
34
|
+
`);
|
|
35
|
+
program.help();
|
|
36
|
+
});
|
|
37
|
+
program.parse();
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,kEAAkE,CAAC;KAC/E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,eAAe;AACf,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,8BAA8B;AAC9B,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE;IAClB,OAAO,CAAC,GAAG,CAAC;;;;;CAKb,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface AgentConfig {
|
|
2
|
+
machine: {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
};
|
|
6
|
+
agent: {
|
|
7
|
+
port: number;
|
|
8
|
+
};
|
|
9
|
+
projects: {
|
|
10
|
+
basePath: string;
|
|
11
|
+
whitelist: string[];
|
|
12
|
+
};
|
|
13
|
+
editor?: {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
portRange: {
|
|
16
|
+
start: number;
|
|
17
|
+
end: number;
|
|
18
|
+
};
|
|
19
|
+
idleTimeout: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Load configuration from ~/.247/config.json
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadConfig(): AgentConfig | null;
|
|
26
|
+
/**
|
|
27
|
+
* Save configuration to ~/.247/config.json
|
|
28
|
+
*/
|
|
29
|
+
export declare function saveConfig(config: AgentConfig): void;
|
|
30
|
+
/**
|
|
31
|
+
* Create a new configuration with defaults
|
|
32
|
+
*/
|
|
33
|
+
export declare function createConfig(options: {
|
|
34
|
+
machineName: string;
|
|
35
|
+
port?: number;
|
|
36
|
+
projectsPath?: string;
|
|
37
|
+
}): AgentConfig;
|
|
38
|
+
/**
|
|
39
|
+
* Check if configuration exists
|
|
40
|
+
*/
|
|
41
|
+
export declare function configExists(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Get default configuration
|
|
44
|
+
*/
|
|
45
|
+
export declare function getDefaultConfig(): AgentConfig;
|
|
46
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;QAC1C,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAqBD;;GAEG;AACH,wBAAgB,UAAU,IAAI,WAAW,GAAG,IAAI,CAwB/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAMpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,WAAW,CAed;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAGtC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAE9C"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
import { getAgentPaths, ensureDirectories } from './paths.js';
|
|
4
|
+
const DEFAULT_CONFIG = {
|
|
5
|
+
machine: {
|
|
6
|
+
id: '',
|
|
7
|
+
name: '',
|
|
8
|
+
},
|
|
9
|
+
agent: {
|
|
10
|
+
port: 4678,
|
|
11
|
+
},
|
|
12
|
+
projects: {
|
|
13
|
+
basePath: '~/Dev',
|
|
14
|
+
whitelist: [],
|
|
15
|
+
},
|
|
16
|
+
editor: {
|
|
17
|
+
enabled: false,
|
|
18
|
+
portRange: { start: 4680, end: 4699 },
|
|
19
|
+
idleTimeout: 1800000,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Load configuration from ~/.247/config.json
|
|
24
|
+
*/
|
|
25
|
+
export function loadConfig() {
|
|
26
|
+
const paths = getAgentPaths();
|
|
27
|
+
if (!existsSync(paths.configPath)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const content = readFileSync(paths.configPath, 'utf-8');
|
|
32
|
+
const config = JSON.parse(content);
|
|
33
|
+
// Apply environment overrides
|
|
34
|
+
if (process.env.AGENT_247_PORT) {
|
|
35
|
+
config.agent.port = parseInt(process.env.AGENT_247_PORT, 10);
|
|
36
|
+
}
|
|
37
|
+
if (process.env.AGENT_247_PROJECTS) {
|
|
38
|
+
config.projects.basePath = process.env.AGENT_247_PROJECTS;
|
|
39
|
+
}
|
|
40
|
+
return config;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error(`Failed to load config: ${err.message}`);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Save configuration to ~/.247/config.json
|
|
49
|
+
*/
|
|
50
|
+
export function saveConfig(config) {
|
|
51
|
+
const paths = getAgentPaths();
|
|
52
|
+
ensureDirectories();
|
|
53
|
+
const content = JSON.stringify(config, null, 2);
|
|
54
|
+
writeFileSync(paths.configPath, content, 'utf-8');
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create a new configuration with defaults
|
|
58
|
+
*/
|
|
59
|
+
export function createConfig(options) {
|
|
60
|
+
return {
|
|
61
|
+
...DEFAULT_CONFIG,
|
|
62
|
+
machine: {
|
|
63
|
+
id: randomUUID(),
|
|
64
|
+
name: options.machineName,
|
|
65
|
+
},
|
|
66
|
+
agent: {
|
|
67
|
+
port: options.port ?? DEFAULT_CONFIG.agent.port,
|
|
68
|
+
},
|
|
69
|
+
projects: {
|
|
70
|
+
basePath: options.projectsPath ?? DEFAULT_CONFIG.projects.basePath,
|
|
71
|
+
whitelist: [],
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if configuration exists
|
|
77
|
+
*/
|
|
78
|
+
export function configExists() {
|
|
79
|
+
const paths = getAgentPaths();
|
|
80
|
+
return existsSync(paths.configPath);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get default configuration
|
|
84
|
+
*/
|
|
85
|
+
export function getDefaultConfig() {
|
|
86
|
+
return { ...DEFAULT_CONFIG };
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface AgentPaths {
|
|
2
|
+
/** Where the CLI package is installed */
|
|
3
|
+
cliRoot: string;
|
|
4
|
+
/** Where the agent server code is located */
|
|
5
|
+
agentRoot: string;
|
|
6
|
+
/** Where the hooks package source is located */
|
|
7
|
+
hooksSource: string;
|
|
8
|
+
/** Where hooks should be installed for Claude Code */
|
|
9
|
+
hooksDestination: string;
|
|
10
|
+
/** Configuration directory (~/.247/) */
|
|
11
|
+
configDir: string;
|
|
12
|
+
/** Configuration file path */
|
|
13
|
+
configPath: string;
|
|
14
|
+
/** Data directory for SQLite */
|
|
15
|
+
dataDir: string;
|
|
16
|
+
/** Log directory */
|
|
17
|
+
logDir: string;
|
|
18
|
+
/** PID file path */
|
|
19
|
+
pidFile: string;
|
|
20
|
+
/** Node binary path */
|
|
21
|
+
nodePath: string;
|
|
22
|
+
/** Is this a development install? */
|
|
23
|
+
isDev: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function getAgentPaths(): AgentPaths;
|
|
26
|
+
/**
|
|
27
|
+
* Ensure all required directories exist
|
|
28
|
+
*/
|
|
29
|
+
export declare function ensureDirectories(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Clear cached paths (useful for testing)
|
|
32
|
+
*/
|
|
33
|
+
export declare function clearPathsCache(): void;
|
|
34
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAEhB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAElB,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IAEpB,sDAAsD;IACtD,gBAAgB,EAAE,MAAM,CAAC;IAEzB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAElB,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IAEnB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAEhB,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAC;IAEf,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAEhB,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;IAEjB,qCAAqC;IACrC,KAAK,EAAE,OAAO,CAAC;CAChB;AAID,wBAAgB,aAAa,IAAI,UAAU,CAmD1C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAcxC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { dirname, join, resolve } from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
4
|
+
import { homedir, platform } from 'os';
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
let cachedPaths = null;
|
|
7
|
+
export function getAgentPaths() {
|
|
8
|
+
if (cachedPaths)
|
|
9
|
+
return cachedPaths;
|
|
10
|
+
// CLI root is 2 levels up from lib/ (dist/lib -> dist -> cli root)
|
|
11
|
+
const cliRoot = resolve(__dirname, '..', '..');
|
|
12
|
+
// Check if running from source (monorepo) or installed (npm global)
|
|
13
|
+
// In monorepo: cliRoot is packages/cli, parent has pnpm-workspace.yaml
|
|
14
|
+
const monorepoRoot = resolve(cliRoot, '..', '..');
|
|
15
|
+
const isDev = existsSync(join(monorepoRoot, 'pnpm-workspace.yaml'));
|
|
16
|
+
let agentRoot;
|
|
17
|
+
let hooksSource;
|
|
18
|
+
if (isDev) {
|
|
19
|
+
// Development: agent and hooks are in the monorepo
|
|
20
|
+
agentRoot = resolve(monorepoRoot, 'apps', 'agent');
|
|
21
|
+
hooksSource = resolve(monorepoRoot, 'packages', 'hooks');
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
// Production: agent code is bundled with CLI
|
|
25
|
+
agentRoot = join(cliRoot, 'agent');
|
|
26
|
+
hooksSource = join(cliRoot, 'hooks');
|
|
27
|
+
}
|
|
28
|
+
// Configuration directory
|
|
29
|
+
const configDir = join(homedir(), '.247');
|
|
30
|
+
// Log directory varies by platform
|
|
31
|
+
const os = platform();
|
|
32
|
+
let logDir;
|
|
33
|
+
if (os === 'darwin') {
|
|
34
|
+
logDir = join(homedir(), 'Library', 'Logs', '247-agent');
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
logDir = join(homedir(), '.local', 'log', '247-agent');
|
|
38
|
+
}
|
|
39
|
+
cachedPaths = {
|
|
40
|
+
cliRoot,
|
|
41
|
+
agentRoot,
|
|
42
|
+
hooksSource,
|
|
43
|
+
hooksDestination: join(homedir(), '.claude-plugins', '247-hooks'),
|
|
44
|
+
configDir,
|
|
45
|
+
configPath: join(configDir, 'config.json'),
|
|
46
|
+
dataDir: join(configDir, 'data'),
|
|
47
|
+
logDir,
|
|
48
|
+
pidFile: join(configDir, 'agent.pid'),
|
|
49
|
+
nodePath: process.execPath,
|
|
50
|
+
isDev,
|
|
51
|
+
};
|
|
52
|
+
return cachedPaths;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Ensure all required directories exist
|
|
56
|
+
*/
|
|
57
|
+
export function ensureDirectories() {
|
|
58
|
+
const paths = getAgentPaths();
|
|
59
|
+
const dirs = [
|
|
60
|
+
paths.configDir,
|
|
61
|
+
paths.dataDir,
|
|
62
|
+
paths.logDir,
|
|
63
|
+
];
|
|
64
|
+
for (const dir of dirs) {
|
|
65
|
+
if (!existsSync(dir)) {
|
|
66
|
+
mkdirSync(dir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Clear cached paths (useful for testing)
|
|
72
|
+
*/
|
|
73
|
+
export function clearPathsCache() {
|
|
74
|
+
cachedPaths = null;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=paths.js.map
|