@almyty/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 +43 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +191 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @almyty/cli
|
|
2
|
+
|
|
3
|
+
Umbrella CLI for almyty. One install, every command.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
$ npm install -g @almyty/cli
|
|
9
|
+
$ almyty login
|
|
10
|
+
$ almyty agents list
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
| Command | Delegates to | Description |
|
|
16
|
+
|---------|-------------|-------------|
|
|
17
|
+
| `almyty login` | `@almyty/auth` | Browser-based login |
|
|
18
|
+
| `almyty logout` | `@almyty/auth` | Remove stored credentials |
|
|
19
|
+
| `almyty whoami` | `@almyty/auth` | Show current identity |
|
|
20
|
+
| `almyty agents <cmd>` | `@almyty/agents` | List, run, inspect agents |
|
|
21
|
+
| `almyty chat [name\|id]` | `@almyty/chat` | Interactive chat REPL |
|
|
22
|
+
| `almyty skills <cmd>` | `@almyty/skills` | Install and manage skills |
|
|
23
|
+
| `almyty mcp <args>` | `@almyty/mcp-server` | Start MCP server |
|
|
24
|
+
|
|
25
|
+
## Standalone packages
|
|
26
|
+
|
|
27
|
+
Every subcommand is also available as a standalone package via `npx`:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
$ npx @almyty/agents list
|
|
31
|
+
$ npx @almyty/chat my-bot
|
|
32
|
+
$ npx @almyty/skills install @org/gateway
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
All packages share the same credentials file (`~/.almyty/credentials.json`), so logging in once works everywhere.
|
|
36
|
+
|
|
37
|
+
## Docs
|
|
38
|
+
|
|
39
|
+
https://almyty.com/docs
|
|
40
|
+
|
|
41
|
+
## License
|
|
42
|
+
|
|
43
|
+
BSL-1.1
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @almyty/cli — single installable almyty CLI.
|
|
4
|
+
*
|
|
5
|
+
* npm install -g @almyty/cli
|
|
6
|
+
* almyty login
|
|
7
|
+
* almyty agents list
|
|
8
|
+
* almyty chat my-research-bot
|
|
9
|
+
* almyty skills install @org/gateway
|
|
10
|
+
* almyty mcp <args>
|
|
11
|
+
*
|
|
12
|
+
* The umbrella delegates each subcommand to a standalone @almyty/<thing>
|
|
13
|
+
* package by spawning its bin. Each package can ALSO be invoked directly:
|
|
14
|
+
*
|
|
15
|
+
* npx @almyty/auth login
|
|
16
|
+
* npx @almyty/agents list
|
|
17
|
+
* npx @almyty/chat my-research-bot
|
|
18
|
+
* …
|
|
19
|
+
*
|
|
20
|
+
* The standalone packages and the umbrella stay in sync because they
|
|
21
|
+
* share the same on-disk credentials store at ~/.almyty/credentials.json.
|
|
22
|
+
*/
|
|
23
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @almyty/cli — single installable almyty CLI.
|
|
4
|
+
*
|
|
5
|
+
* npm install -g @almyty/cli
|
|
6
|
+
* almyty login
|
|
7
|
+
* almyty agents list
|
|
8
|
+
* almyty chat my-research-bot
|
|
9
|
+
* almyty skills install @org/gateway
|
|
10
|
+
* almyty mcp <args>
|
|
11
|
+
*
|
|
12
|
+
* The umbrella delegates each subcommand to a standalone @almyty/<thing>
|
|
13
|
+
* package by spawning its bin. Each package can ALSO be invoked directly:
|
|
14
|
+
*
|
|
15
|
+
* npx @almyty/auth login
|
|
16
|
+
* npx @almyty/agents list
|
|
17
|
+
* npx @almyty/chat my-research-bot
|
|
18
|
+
* …
|
|
19
|
+
*
|
|
20
|
+
* The standalone packages and the umbrella stay in sync because they
|
|
21
|
+
* share the same on-disk credentials store at ~/.almyty/credentials.json.
|
|
22
|
+
*/
|
|
23
|
+
import { spawn } from 'child_process';
|
|
24
|
+
import { createRequire } from 'module';
|
|
25
|
+
import { dirname, join } from 'path';
|
|
26
|
+
import { existsSync } from 'fs';
|
|
27
|
+
const require = createRequire(import.meta.url);
|
|
28
|
+
const VERSION = '0.1.0';
|
|
29
|
+
/**
|
|
30
|
+
* Top-level subcommand routing table. Order = display order in help.
|
|
31
|
+
*/
|
|
32
|
+
const SUBCOMMANDS = {
|
|
33
|
+
// Auth shortcuts at top level (gh-style: `almyty login` not `almyty auth login`)
|
|
34
|
+
login: { pkg: '@almyty/auth', prefixArgs: ['login'], help: 'Browser-based login' },
|
|
35
|
+
logout: { pkg: '@almyty/auth', prefixArgs: ['logout'], help: 'Remove stored credentials' },
|
|
36
|
+
whoami: { pkg: '@almyty/auth', prefixArgs: ['whoami'], help: 'Show the current identity' },
|
|
37
|
+
auth: { pkg: '@almyty/auth', help: 'Auth subcommands (login/logout/whoami)' },
|
|
38
|
+
// Domain CLIs
|
|
39
|
+
agents: { pkg: '@almyty/agents', help: 'List, run, and inspect agents' },
|
|
40
|
+
chat: { pkg: '@almyty/chat', help: 'Interactive chat REPL with an agent' },
|
|
41
|
+
skills: { pkg: '@almyty/skills', help: 'Install API skills into AI coding agents' },
|
|
42
|
+
mcp: { pkg: '@almyty/mcp-server', help: 'Run the MCP server proxy' },
|
|
43
|
+
};
|
|
44
|
+
function printHelp() {
|
|
45
|
+
console.log(`
|
|
46
|
+
almyty CLI v${VERSION}
|
|
47
|
+
|
|
48
|
+
Usage:
|
|
49
|
+
almyty <command> [args]
|
|
50
|
+
|
|
51
|
+
Auth:
|
|
52
|
+
login Browser-based login (writes ~/.almyty/credentials.json)
|
|
53
|
+
logout Remove stored credentials
|
|
54
|
+
whoami Show the currently logged-in identity
|
|
55
|
+
auth <subcommand> Pass-through to @almyty/auth
|
|
56
|
+
|
|
57
|
+
Agents:
|
|
58
|
+
agents list List agents in your organization
|
|
59
|
+
agents get <ref> Show details for one agent
|
|
60
|
+
agents run <ref> [--input ...] Invoke / start a run
|
|
61
|
+
agents runs <ref> List recent runs
|
|
62
|
+
agents cancel <ref> <runId> Cancel an in-flight run
|
|
63
|
+
|
|
64
|
+
Chat:
|
|
65
|
+
chat Interactive REPL — pick an agent from a menu
|
|
66
|
+
chat <ref> Start chatting with that agent
|
|
67
|
+
|
|
68
|
+
Skills:
|
|
69
|
+
skills install <ref> Install skills into local AI coding agents
|
|
70
|
+
skills list [ref] List available skills
|
|
71
|
+
skills daemon Sync skills on a schedule
|
|
72
|
+
skills run <ref> Execute a skill once
|
|
73
|
+
|
|
74
|
+
MCP:
|
|
75
|
+
mcp <args> Run the MCP server proxy
|
|
76
|
+
|
|
77
|
+
Other:
|
|
78
|
+
help, --help Show this help
|
|
79
|
+
version, --version Show version
|
|
80
|
+
|
|
81
|
+
Each subcommand maps to a standalone npm package. You can invoke any
|
|
82
|
+
of them directly with npx:
|
|
83
|
+
|
|
84
|
+
npx @almyty/auth login
|
|
85
|
+
npx @almyty/agents list
|
|
86
|
+
npx @almyty/chat my-research-bot
|
|
87
|
+
npx @almyty/skills install @org/gateway
|
|
88
|
+
`);
|
|
89
|
+
}
|
|
90
|
+
function resolveBinPath(packageName) {
|
|
91
|
+
// Resolve the package's package.json to find its installation root,
|
|
92
|
+
// then read the "bin" entry to find the actual script path.
|
|
93
|
+
let pkgJsonPath;
|
|
94
|
+
try {
|
|
95
|
+
pkgJsonPath = require.resolve(`${packageName}/package.json`);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const pkgRoot = dirname(pkgJsonPath);
|
|
101
|
+
let pkg;
|
|
102
|
+
try {
|
|
103
|
+
pkg = require(pkgJsonPath);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
// bin can be a string or { name: path }
|
|
109
|
+
let binRel;
|
|
110
|
+
if (typeof pkg.bin === 'string') {
|
|
111
|
+
binRel = pkg.bin;
|
|
112
|
+
}
|
|
113
|
+
else if (pkg.bin && typeof pkg.bin === 'object') {
|
|
114
|
+
// Take the first entry (or one matching the package name).
|
|
115
|
+
const keys = Object.keys(pkg.bin);
|
|
116
|
+
binRel = pkg.bin[keys[0]];
|
|
117
|
+
}
|
|
118
|
+
if (!binRel) {
|
|
119
|
+
// Fall back to dist/index.js convention used by all almyty packages.
|
|
120
|
+
binRel = pkg.main || 'dist/index.js';
|
|
121
|
+
}
|
|
122
|
+
const binAbs = join(pkgRoot, binRel);
|
|
123
|
+
return existsSync(binAbs) ? binAbs : null;
|
|
124
|
+
}
|
|
125
|
+
function delegate(packageName, args) {
|
|
126
|
+
const binPath = resolveBinPath(packageName);
|
|
127
|
+
if (!binPath) {
|
|
128
|
+
console.error(`Error: package ${packageName} is not installed.`);
|
|
129
|
+
console.error(` Install it with: npm install -g ${packageName}`);
|
|
130
|
+
console.error(` Or use: npx ${packageName} ${args.join(' ')}`);
|
|
131
|
+
return Promise.resolve(1);
|
|
132
|
+
}
|
|
133
|
+
return new Promise((resolve) => {
|
|
134
|
+
const child = spawn(process.execPath, [binPath, ...args], {
|
|
135
|
+
stdio: 'inherit',
|
|
136
|
+
});
|
|
137
|
+
// Forward Ctrl-C / Ctrl-\ so the child can clean up properly.
|
|
138
|
+
const forward = (sig) => {
|
|
139
|
+
try {
|
|
140
|
+
if (!child.killed)
|
|
141
|
+
child.kill(sig);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// best effort
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
process.on('SIGINT', forward);
|
|
148
|
+
process.on('SIGTERM', forward);
|
|
149
|
+
process.on('SIGHUP', forward);
|
|
150
|
+
child.on('exit', (code, signal) => {
|
|
151
|
+
process.removeListener('SIGINT', forward);
|
|
152
|
+
process.removeListener('SIGTERM', forward);
|
|
153
|
+
process.removeListener('SIGHUP', forward);
|
|
154
|
+
if (signal) {
|
|
155
|
+
// Re-raise the signal so our exit code reflects it.
|
|
156
|
+
process.kill(process.pid, signal);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
resolve(code ?? 0);
|
|
160
|
+
});
|
|
161
|
+
child.on('error', (err) => {
|
|
162
|
+
console.error(`Failed to launch ${packageName}: ${err.message}`);
|
|
163
|
+
resolve(1);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
async function main() {
|
|
168
|
+
const argv = process.argv.slice(2);
|
|
169
|
+
if (argv.length === 0 || argv[0] === '--help' || argv[0] === '-h' || argv[0] === 'help') {
|
|
170
|
+
printHelp();
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (argv[0] === '--version' || argv[0] === '-v' || argv[0] === 'version') {
|
|
174
|
+
console.log(VERSION);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const cmd = argv[0];
|
|
178
|
+
const sub = SUBCOMMANDS[cmd];
|
|
179
|
+
if (!sub) {
|
|
180
|
+
console.error(`Unknown command: ${cmd}`);
|
|
181
|
+
console.error(`Run \`almyty help\` for the list of commands.`);
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
const passthroughArgs = [...(sub.prefixArgs ?? []), ...argv.slice(1)];
|
|
185
|
+
const code = await delegate(sub.pkg, passthroughArgs);
|
|
186
|
+
process.exit(code);
|
|
187
|
+
}
|
|
188
|
+
main().catch((err) => {
|
|
189
|
+
console.error(`Error: ${err.message}`);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@almyty/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Single installable almyty CLI — login, agents, chat, skills, mcp under one binary",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"almyty": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsx src/index.ts",
|
|
16
|
+
"test": "vitest run",
|
|
17
|
+
"test:watch": "vitest",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"almyty",
|
|
22
|
+
"cli",
|
|
23
|
+
"agents",
|
|
24
|
+
"chat",
|
|
25
|
+
"skills",
|
|
26
|
+
"mcp"
|
|
27
|
+
],
|
|
28
|
+
"author": "almyty",
|
|
29
|
+
"license": "BSL-1.1",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@almyty/auth": "^0.1.0",
|
|
32
|
+
"@almyty/agents": "^0.1.0",
|
|
33
|
+
"@almyty/chat": "^0.1.0",
|
|
34
|
+
"@almyty/skills": "^1.0.2",
|
|
35
|
+
"@almyty/mcp-server": "^1.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^25.4.0",
|
|
39
|
+
"tsx": "^4.7.0",
|
|
40
|
+
"typescript": "^5.3.0",
|
|
41
|
+
"vitest": "^4.1.0"
|
|
42
|
+
}
|
|
43
|
+
}
|