@agent-hive/cli 0.3.1 → 0.4.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/dist/hive.js +161 -11
- package/package.json +2 -1
- package/skills/claude-code/SKILL.md +1 -1
- package/skills/generic/SKILL.md +1 -1
package/dist/hive.js
CHANGED
|
@@ -10,7 +10,14 @@ const __filename_resolved = typeof __filename !== 'undefined'
|
|
|
10
10
|
: fileURLToPath(import.meta.url);
|
|
11
11
|
const __dirname_resolved = dirname(__filename_resolved);
|
|
12
12
|
const CONFIG_DIR = join(homedir(), '.hive');
|
|
13
|
-
|
|
13
|
+
function credentialsPath(profile) {
|
|
14
|
+
return profile
|
|
15
|
+
? join(CONFIG_DIR, `credentials.${profile}.json`)
|
|
16
|
+
: join(CONFIG_DIR, 'credentials.json');
|
|
17
|
+
}
|
|
18
|
+
function getProfile() {
|
|
19
|
+
return program.opts().profile;
|
|
20
|
+
}
|
|
14
21
|
// API URL with fallback chain: env var → credentials file → default
|
|
15
22
|
function getApiUrl() {
|
|
16
23
|
if (process.env.HIVE_API_URL) {
|
|
@@ -27,18 +34,19 @@ if (!existsSync(CONFIG_DIR)) {
|
|
|
27
34
|
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
28
35
|
}
|
|
29
36
|
function getCredentials() {
|
|
30
|
-
|
|
37
|
+
const file = credentialsPath(getProfile());
|
|
38
|
+
if (!existsSync(file)) {
|
|
31
39
|
return null;
|
|
32
40
|
}
|
|
33
41
|
try {
|
|
34
|
-
return JSON.parse(readFileSync(
|
|
42
|
+
return JSON.parse(readFileSync(file, 'utf-8'));
|
|
35
43
|
}
|
|
36
44
|
catch {
|
|
37
45
|
return null;
|
|
38
46
|
}
|
|
39
47
|
}
|
|
40
48
|
function saveCredentials(creds) {
|
|
41
|
-
writeFileSync(
|
|
49
|
+
writeFileSync(credentialsPath(getProfile()), JSON.stringify(creds, null, 2));
|
|
42
50
|
}
|
|
43
51
|
function getCliVersion() {
|
|
44
52
|
const pkgPaths = [
|
|
@@ -78,7 +86,8 @@ function checkSkillVersion() {
|
|
|
78
86
|
program
|
|
79
87
|
.name('hive')
|
|
80
88
|
.description('CLI tools for Hive marketplace operators')
|
|
81
|
-
.version(
|
|
89
|
+
.version(getCliVersion())
|
|
90
|
+
.option('--profile <name>', 'Use named credential profile (reads ~/.hive/credentials.<name>.json)');
|
|
82
91
|
program
|
|
83
92
|
.command('register')
|
|
84
93
|
.description('Register as a new Hive operator (Step 1: sends verification email)')
|
|
@@ -116,8 +125,9 @@ program
|
|
|
116
125
|
console.log('');
|
|
117
126
|
console.log(' 📧 Check your email for a 6-digit verification code.');
|
|
118
127
|
console.log('');
|
|
128
|
+
const profileFlag = getProfile() ? ` --profile ${getProfile()}` : '';
|
|
119
129
|
console.log('Next step:');
|
|
120
|
-
console.log(` npx hive verify --email ${options.email} --code <6-digit-code> --api-url ${apiUrl}`);
|
|
130
|
+
console.log(` npx hive${profileFlag} verify --email ${options.email} --code <6-digit-code> --api-url ${apiUrl}`);
|
|
121
131
|
}
|
|
122
132
|
catch (err) {
|
|
123
133
|
console.error('Failed to connect to Hive API at', apiUrl);
|
|
@@ -169,7 +179,7 @@ program
|
|
|
169
179
|
console.log('');
|
|
170
180
|
console.log(' ⚠️ Save this API key - it won\'t be shown again!');
|
|
171
181
|
console.log('');
|
|
172
|
-
console.log(
|
|
182
|
+
console.log(`Credentials saved to ${credentialsPath(getProfile())}`);
|
|
173
183
|
console.log('');
|
|
174
184
|
if (data.name) {
|
|
175
185
|
console.log(` Your agent name is "${data.name}".`);
|
|
@@ -225,7 +235,7 @@ program
|
|
|
225
235
|
console.log(` Operator ID: ${stats.operator_id}`);
|
|
226
236
|
console.log(` API URL: ${apiUrl}`);
|
|
227
237
|
console.log('');
|
|
228
|
-
console.log(
|
|
238
|
+
console.log(`Credentials saved to ${credentialsPath(getProfile())}`);
|
|
229
239
|
}
|
|
230
240
|
catch (err) {
|
|
231
241
|
console.error('Failed to connect to Hive API at', apiUrl);
|
|
@@ -412,6 +422,38 @@ program
|
|
|
412
422
|
process.exit(1);
|
|
413
423
|
}
|
|
414
424
|
});
|
|
425
|
+
program
|
|
426
|
+
.command('unclaim <task-id>')
|
|
427
|
+
.description('Unclaim a task to signal you are no longer working on it')
|
|
428
|
+
.action(async (taskId) => {
|
|
429
|
+
checkSkillVersion();
|
|
430
|
+
const creds = getCredentials();
|
|
431
|
+
if (!creds) {
|
|
432
|
+
console.error(JSON.stringify({ error: 'Not logged in. Run: npx hive login' }));
|
|
433
|
+
process.exit(1);
|
|
434
|
+
}
|
|
435
|
+
const apiUrl = getApiUrl();
|
|
436
|
+
try {
|
|
437
|
+
const res = await fetch(`${apiUrl}/tasks/${taskId}/unclaim`, {
|
|
438
|
+
method: 'POST',
|
|
439
|
+
headers: {
|
|
440
|
+
'X-Hive-Api-Key': creds.api_key,
|
|
441
|
+
'Content-Type': 'application/json',
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
if (!res.ok) {
|
|
445
|
+
const data = await res.json();
|
|
446
|
+
console.error(JSON.stringify({ error: data.error || 'Failed to unclaim task', hint: data.hint }));
|
|
447
|
+
process.exit(1);
|
|
448
|
+
}
|
|
449
|
+
const data = await res.json();
|
|
450
|
+
console.log(JSON.stringify(data, null, 2));
|
|
451
|
+
}
|
|
452
|
+
catch (err) {
|
|
453
|
+
console.error(JSON.stringify({ error: 'Failed to unclaim task' }));
|
|
454
|
+
process.exit(1);
|
|
455
|
+
}
|
|
456
|
+
});
|
|
415
457
|
program
|
|
416
458
|
.command('download <task-id>')
|
|
417
459
|
.description('Download all assets for a task to the current directory')
|
|
@@ -664,10 +706,12 @@ program
|
|
|
664
706
|
.command('logout')
|
|
665
707
|
.description('Remove saved credentials')
|
|
666
708
|
.action(() => {
|
|
667
|
-
|
|
709
|
+
const file = credentialsPath(getProfile());
|
|
710
|
+
if (existsSync(file)) {
|
|
668
711
|
const { unlinkSync } = require('fs');
|
|
669
|
-
unlinkSync(
|
|
670
|
-
|
|
712
|
+
unlinkSync(file);
|
|
713
|
+
const suffix = getProfile() ? ` (profile: ${getProfile()})` : '';
|
|
714
|
+
console.log(`✓ Logged out. Credentials removed${suffix}.`);
|
|
671
715
|
}
|
|
672
716
|
else {
|
|
673
717
|
console.log('Not logged in.');
|
|
@@ -834,4 +878,110 @@ stripe
|
|
|
834
878
|
process.exit(1);
|
|
835
879
|
}
|
|
836
880
|
});
|
|
881
|
+
// =============================================================================
|
|
882
|
+
// Agent Commands
|
|
883
|
+
// =============================================================================
|
|
884
|
+
const agent = program
|
|
885
|
+
.command('agent')
|
|
886
|
+
.description('Autonomous agent mode');
|
|
887
|
+
agent
|
|
888
|
+
.command('setup')
|
|
889
|
+
.description('Scaffold workspace and install skills for autonomous operation')
|
|
890
|
+
.option('--workspace <path>', 'Custom workspace directory (default: ~/.hive/workspace/)')
|
|
891
|
+
.action(async (options) => {
|
|
892
|
+
const { setup } = await import('@agent-hive/agent');
|
|
893
|
+
await setup({ workspace: options.workspace, profile: getProfile() });
|
|
894
|
+
});
|
|
895
|
+
agent
|
|
896
|
+
.command('start')
|
|
897
|
+
.description('Start the autonomous agent dispatcher')
|
|
898
|
+
.option('--budget <usd>', 'Max spend per worker run in USD', '2.00')
|
|
899
|
+
.option('--model <model>', 'Model for the worker agent')
|
|
900
|
+
.option('--worker-timeout <ms>', 'Worker timeout in milliseconds', '600000')
|
|
901
|
+
.option('--workspace <path>', 'Override workspace directory')
|
|
902
|
+
.action(async (options) => {
|
|
903
|
+
const { startDispatcher } = await import('@agent-hive/agent');
|
|
904
|
+
await startDispatcher({
|
|
905
|
+
budgetPerRun: parseFloat(options.budget),
|
|
906
|
+
model: options.model,
|
|
907
|
+
workerTimeoutMs: parseInt(options.workerTimeout),
|
|
908
|
+
workspace: options.workspace,
|
|
909
|
+
profile: getProfile(),
|
|
910
|
+
});
|
|
911
|
+
});
|
|
912
|
+
agent
|
|
913
|
+
.command('status')
|
|
914
|
+
.description('Show workspace info and recent activity')
|
|
915
|
+
.option('--workspace <path>', 'Override workspace directory')
|
|
916
|
+
.action(async (options) => {
|
|
917
|
+
const { readFileSync, existsSync, readdirSync } = await import('fs');
|
|
918
|
+
const { join } = await import('path');
|
|
919
|
+
const { getWorkspaceDir } = await import('@agent-hive/agent');
|
|
920
|
+
const workspaceDir = getWorkspaceDir(options.workspace);
|
|
921
|
+
const logsDir = join(workspaceDir, 'logs');
|
|
922
|
+
console.log('');
|
|
923
|
+
console.log('Hive Agent Status');
|
|
924
|
+
console.log('-----------------');
|
|
925
|
+
console.log('');
|
|
926
|
+
// Workspace
|
|
927
|
+
if (existsSync(workspaceDir)) {
|
|
928
|
+
console.log(` Workspace: ${workspaceDir}`);
|
|
929
|
+
}
|
|
930
|
+
else {
|
|
931
|
+
console.log(' Workspace: Not set up');
|
|
932
|
+
console.log('');
|
|
933
|
+
console.log(' Run: npx hive agent setup');
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
// CLAUDE.md
|
|
937
|
+
const claudeMd = join(workspaceDir, 'CLAUDE.md');
|
|
938
|
+
console.log(` CLAUDE.md: ${existsSync(claudeMd) ? 'present' : 'missing'}`);
|
|
939
|
+
// Skills
|
|
940
|
+
const skillsDir = join(workspaceDir, '.agents', 'skills');
|
|
941
|
+
if (existsSync(skillsDir)) {
|
|
942
|
+
try {
|
|
943
|
+
const skillDirs = readdirSync(skillsDir, { withFileTypes: true })
|
|
944
|
+
.filter(d => d.isDirectory())
|
|
945
|
+
.map(d => d.name);
|
|
946
|
+
console.log(` Skills: ${skillDirs.length > 0 ? skillDirs.join(', ') : 'none'}`);
|
|
947
|
+
}
|
|
948
|
+
catch {
|
|
949
|
+
console.log(' Skills: unable to read');
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
else {
|
|
953
|
+
console.log(' Skills: none installed');
|
|
954
|
+
}
|
|
955
|
+
// Recent logs
|
|
956
|
+
console.log('');
|
|
957
|
+
if (existsSync(logsDir)) {
|
|
958
|
+
const logFiles = readdirSync(logsDir)
|
|
959
|
+
.filter(f => f.endsWith('.jsonl'))
|
|
960
|
+
.sort()
|
|
961
|
+
.reverse();
|
|
962
|
+
if (logFiles.length > 0) {
|
|
963
|
+
console.log(' Recent activity:');
|
|
964
|
+
const latestLog = join(logsDir, logFiles[0]);
|
|
965
|
+
const lines = readFileSync(latestLog, 'utf-8').trim().split('\n');
|
|
966
|
+
const recentLines = lines.slice(-10);
|
|
967
|
+
for (const line of recentLines) {
|
|
968
|
+
try {
|
|
969
|
+
const entry = JSON.parse(line);
|
|
970
|
+
const time = entry.timestamp?.slice(11, 19) || '??:??:??';
|
|
971
|
+
console.log(` ${time} [${entry.event}] ${entry.message}`);
|
|
972
|
+
}
|
|
973
|
+
catch {
|
|
974
|
+
// skip malformed lines
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
else {
|
|
979
|
+
console.log(' No activity logged yet.');
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
else {
|
|
983
|
+
console.log(' No logs directory.');
|
|
984
|
+
}
|
|
985
|
+
console.log('');
|
|
986
|
+
});
|
|
837
987
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-hive/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "CLI tools for Hive marketplace agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"prepublishOnly": "npm run build"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
+
"@agent-hive/agent": "*",
|
|
16
17
|
"chalk": "^5.3.0",
|
|
17
18
|
"commander": "^11.1.0",
|
|
18
19
|
"open": "^10.0.3"
|