@fnmoa/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 +102 -0
- package/dist/args.js +33 -0
- package/dist/args.js.map +1 -0
- package/dist/client.js +100 -0
- package/dist/client.js.map +1 -0
- package/dist/command.js +2 -0
- package/dist/command.js.map +1 -0
- package/dist/commands/config.js +129 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/github.js +19 -0
- package/dist/commands/github.js.map +1 -0
- package/dist/commands/oracle.js +86 -0
- package/dist/commands/oracle.js.map +1 -0
- package/dist/commands/status.js +78 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/tasks.js +156 -0
- package/dist/commands/tasks.js.map +1 -0
- package/dist/commands/track.js +31 -0
- package/dist/commands/track.js.map +1 -0
- package/dist/commands/whoami.js +18 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/commands/workflows.js +304 -0
- package/dist/commands/workflows.js.map +1 -0
- package/dist/config.js +65 -0
- package/dist/config.js.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/poll.js +24 -0
- package/dist/poll.js.map +1 -0
- package/dist/registry.js +50 -0
- package/dist/registry.js.map +1 -0
- package/dist/ui.js +40 -0
- package/dist/ui.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# `@moa/cli` — `moa`
|
|
2
|
+
|
|
3
|
+
A terminal client for the Moa server — drives tasks and workflows over the same
|
|
4
|
+
HTTP API the dashboard uses. Lets the **agent** (inside the container) and the
|
|
5
|
+
**operator** (on the host) manage everything without the UI.
|
|
6
|
+
|
|
7
|
+
## Run
|
|
8
|
+
|
|
9
|
+
**Inside the container** (the agent's path) — `moa` is on `PATH`, talks to the
|
|
10
|
+
local server automatically:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
moa status
|
|
14
|
+
moa wf pending
|
|
15
|
+
moa wf solve mhbspot/repo 42 --watch
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**On the host** — point it at the published API port (see
|
|
19
|
+
`docker-compose.override.yml`, default `127.0.0.1:3030`):
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
export MOA_API_URL=http://localhost:3030
|
|
23
|
+
pnpm --filter @moa/cli exec tsx src/index.ts status
|
|
24
|
+
# or, after `pnpm --filter @moa/cli build`, use the `moa` bin
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
moa status overview snapshot
|
|
31
|
+
moa setup connector (Claude/GitHub) status
|
|
32
|
+
moa tasks | task <id> list / show tasks
|
|
33
|
+
moa run "<prompt>" [--dir D] [--autonomous] [--watch]
|
|
34
|
+
moa cancel <taskId>
|
|
35
|
+
|
|
36
|
+
moa wf list runs
|
|
37
|
+
moa wf pending available issues/PRs
|
|
38
|
+
moa wf get <id> [--watch] one run + step timeline
|
|
39
|
+
moa wf cancel <id>
|
|
40
|
+
moa wf solve <repo> <issue#> [--base B] [--watch]
|
|
41
|
+
moa wf triage <repo> <issue#> [--watch]
|
|
42
|
+
moa wf review <repo> <pr#> [--watch]
|
|
43
|
+
moa wf address <repo> <pr#> [--watch]
|
|
44
|
+
moa wf fix-ci <repo> <pr#> [--watch]
|
|
45
|
+
moa wf merge <repo> <pr#> [--watch]
|
|
46
|
+
|
|
47
|
+
moa oracle list list oracle domains
|
|
48
|
+
moa oracle consult <domain> "<question>" [--watch]
|
|
49
|
+
moa oracle history
|
|
50
|
+
|
|
51
|
+
moa gh pulls | issues
|
|
52
|
+
|
|
53
|
+
moa config show effective URL/key + file path
|
|
54
|
+
moa config set url <url> persist the API URL (~/.moa/cli.json)
|
|
55
|
+
moa config set key <key> persist an API key
|
|
56
|
+
moa config clear
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Knowledge base for agents
|
|
60
|
+
|
|
61
|
+
The command set is a **self-describing registry** — `moa help --json` emits the
|
|
62
|
+
full catalog (every command + sub-action, with `usage` and documented `args`)
|
|
63
|
+
as JSON, so an agent can discover capabilities programmatically:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
moa help --json
|
|
67
|
+
# { "api": "...", "commands": [ { "name": "wf solve", "usage": "...", "args": [...] }, ... ] }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`moa help` (text) is rendered from the same registry, so docs never drift.
|
|
71
|
+
|
|
72
|
+
## Structure (modular)
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
src/
|
|
76
|
+
index.ts entry: parse argv → dispatch → help/--json
|
|
77
|
+
registry.ts COMMANDS list + catalog() (the KB)
|
|
78
|
+
command.ts Command / CommandMeta types
|
|
79
|
+
args.ts argv parser
|
|
80
|
+
ui.ts color + status formatting
|
|
81
|
+
client.ts HTTP API client
|
|
82
|
+
commands/ one module per group: status, tasks, workflows, github
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Add a command by writing a `Command` in `commands/` and listing it in
|
|
86
|
+
`registry.ts` — it appears in help, the JSON catalog, and dispatch automatically.
|
|
87
|
+
|
|
88
|
+
## Config
|
|
89
|
+
|
|
90
|
+
URL/key resolve **env var → `~/.moa/cli.json` (`moa config`) → default**, so you
|
|
91
|
+
can persist them once instead of exporting env vars:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
moa config set url http://localhost:3030
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
| Env | Default | |
|
|
98
|
+
| --- | --- | --- |
|
|
99
|
+
| `MOA_API_URL` | `http://localhost:3000` | Server base URL |
|
|
100
|
+
| `MOA_API_KEY` | — | API key; if unset, the CLI bootstraps the single default operator |
|
|
101
|
+
| `MOA_CONFIG` | `~/.moa/cli.json` | Config file path |
|
|
102
|
+
| `NO_COLOR` | — | Disable ANSI colors |
|
package/dist/args.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Minimal argv parser: positionals + `--flag[=val]` / `--flag val` / boolean flags.
|
|
2
|
+
/** Flags that never take a value — they must NOT consume the next positional
|
|
3
|
+
* (`moa run --autonomous "fix tests"` keeps the prompt as a positional). */
|
|
4
|
+
const BOOLEAN_FLAGS = new Set(['watch', 'autonomous', 'restart', 'json', 'help', 'wait']);
|
|
5
|
+
export function parse(argv) {
|
|
6
|
+
const pos = [];
|
|
7
|
+
const flags = {};
|
|
8
|
+
for (let i = 0; i < argv.length; i++) {
|
|
9
|
+
const a = argv[i];
|
|
10
|
+
if (a.startsWith('--')) {
|
|
11
|
+
const eq = a.indexOf('=');
|
|
12
|
+
if (eq >= 0)
|
|
13
|
+
flags[a.slice(2, eq)] = a.slice(eq + 1);
|
|
14
|
+
else if (!BOOLEAN_FLAGS.has(a.slice(2)) && argv[i + 1] && !argv[i + 1].startsWith('--'))
|
|
15
|
+
flags[a.slice(2)] = argv[++i];
|
|
16
|
+
else
|
|
17
|
+
flags[a.slice(2)] = true;
|
|
18
|
+
}
|
|
19
|
+
else
|
|
20
|
+
pos.push(a);
|
|
21
|
+
}
|
|
22
|
+
return { pos, flags };
|
|
23
|
+
}
|
|
24
|
+
export const flagStr = (a, k) => typeof a.flags[k] === 'string' ? a.flags[k] : undefined;
|
|
25
|
+
export const flagNum = (a, k) => {
|
|
26
|
+
const v = a.flags[k];
|
|
27
|
+
if (typeof v !== 'string')
|
|
28
|
+
return undefined;
|
|
29
|
+
const n = Number(v);
|
|
30
|
+
return Number.isFinite(n) && n > 0 ? Math.floor(n) : undefined;
|
|
31
|
+
};
|
|
32
|
+
export const hasFlag = (a, k) => !!a.flags[k];
|
|
33
|
+
//# sourceMappingURL=args.js.map
|
package/dist/args.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAOpF;6EAC6E;AAC7E,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE1F,MAAM,UAAU,KAAK,CAAC,IAAc;IAClC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,KAAK,GAAqC,EAAE,CAAC;IACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,EAAE,IAAI,CAAC;gBAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;iBAChD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;gBACrF,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;;gBAC3B,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QAChC,CAAC;;YAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAO,EAAE,CAAS,EAAsB,EAAE,CAChE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,SAAS,CAAC;AAEtE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAO,EAAE,CAAS,EAAsB,EAAE;IAChE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAO,EAAE,CAAS,EAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Thin HTTP client for the Moa server — same API the dashboard uses.
|
|
2
|
+
// URL/key resolution: env var → active profile in ~/.moa/cli.json → default/bootstrap.
|
|
3
|
+
import { resolveProfile, saveKeyToCurrent } from './config.js';
|
|
4
|
+
const profile = resolveProfile();
|
|
5
|
+
/** The active profile name (env $MOA_PROFILE / config.current / 'default'). */
|
|
6
|
+
export const PROFILE = profile.name;
|
|
7
|
+
export const API_URL = profile.apiUrl;
|
|
8
|
+
let cachedKey = profile.apiKey;
|
|
9
|
+
/** HTTP error carrying the status code (so callers can branch on 401/403/503). */
|
|
10
|
+
export class ApiError extends Error {
|
|
11
|
+
status;
|
|
12
|
+
constructor(msg, status) {
|
|
13
|
+
super(msg);
|
|
14
|
+
this.status = status;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function req(path, opts = {}) {
|
|
18
|
+
let res;
|
|
19
|
+
try {
|
|
20
|
+
res = await fetch(`${API_URL}${path}`, {
|
|
21
|
+
method: opts.method,
|
|
22
|
+
headers: { 'content-type': 'application/json', ...(opts.headers ?? {}) },
|
|
23
|
+
body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
const cause = e.cause;
|
|
28
|
+
const why = cause?.code ?? cause?.message ?? (e instanceof Error ? e.message : String(e));
|
|
29
|
+
throw new Error(`cannot reach ${API_URL} (${why}) — is the server running? Set $MOA_API_URL or \`moa config set url <url>\``);
|
|
30
|
+
}
|
|
31
|
+
const text = await res.text();
|
|
32
|
+
let body = null;
|
|
33
|
+
try {
|
|
34
|
+
body = text ? JSON.parse(text) : null;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
/* non-JSON body (e.g. proxy HTML) — fall through to the HTTP-status error */
|
|
38
|
+
}
|
|
39
|
+
if (!res.ok) {
|
|
40
|
+
const b = body;
|
|
41
|
+
const snippet = text.replace(/\s+/g, ' ').trim().slice(0, 120);
|
|
42
|
+
throw new ApiError(b?.error?.message ?? b?.message ?? `HTTP ${res.status}${snippet ? `: ${snippet}` : ''}`, res.status);
|
|
43
|
+
}
|
|
44
|
+
return body;
|
|
45
|
+
}
|
|
46
|
+
/** Resolve the API key: env var / saved config, else bootstrap the single default
|
|
47
|
+
* operator once and persist the key (bootstrap rotates the default key, so
|
|
48
|
+
* re-bootstrapping every run would invalidate everyone else's). */
|
|
49
|
+
async function key() {
|
|
50
|
+
if (cachedKey)
|
|
51
|
+
return cachedKey;
|
|
52
|
+
try {
|
|
53
|
+
const r = await req('/auth/bootstrap', { method: 'POST', body: {} });
|
|
54
|
+
cachedKey = r.apiKey;
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
if (e instanceof ApiError && [401, 403, 503].includes(e.status)) {
|
|
58
|
+
throw new Error('auto-bootstrap is unavailable on this workspace (enrolled to a control-plane). ' +
|
|
59
|
+
'Set $MOA_API_KEY or save a key with: moa config set key <key>');
|
|
60
|
+
}
|
|
61
|
+
throw e;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
saveKeyToCurrent(cachedKey);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
/* best effort — worst case the next run bootstraps again */
|
|
68
|
+
}
|
|
69
|
+
return cachedKey;
|
|
70
|
+
}
|
|
71
|
+
async function authReq(path, opts = {}) {
|
|
72
|
+
return req(path, { ...opts, headers: { 'x-api-key': await key(), ...(opts.headers ?? {}) } });
|
|
73
|
+
}
|
|
74
|
+
const limitQs = (limit) => (limit ? `?limit=${limit}` : '');
|
|
75
|
+
export const api = {
|
|
76
|
+
status: () => authReq('/status'),
|
|
77
|
+
statusSpend: (since) => authReq(`/status/spend${since ? `?since=${encodeURIComponent(since)}` : ''}`),
|
|
78
|
+
setup: () => authReq('/setup/status'),
|
|
79
|
+
webDomains: () => authReq('/setup/web'),
|
|
80
|
+
setWebDomains: (domains) => authReq('/setup/web', { method: 'PUT', body: { domains } }),
|
|
81
|
+
tasks: (limit) => authReq(`/tasks${limitQs(limit)}`),
|
|
82
|
+
task: (id, waitMs) => authReq(`/tasks/${id}${waitMs && waitMs > 0 ? `?waitMs=${Math.floor(waitMs)}` : ''}`),
|
|
83
|
+
run: (input) => authReq('/tasks', { method: 'POST', body: input }),
|
|
84
|
+
cancelTask: (id) => authReq(`/tasks/${id}`, { method: 'DELETE' }),
|
|
85
|
+
workflows: (limit) => authReq(`/workflows${limitQs(limit)}`),
|
|
86
|
+
pending: () => authReq('/workflows/pending'),
|
|
87
|
+
workflow: (id) => authReq(`/workflows/${id}`),
|
|
88
|
+
cancelWorkflow: (id) => authReq(`/workflows/${id}`, { method: 'DELETE' }),
|
|
89
|
+
approveWorkflow: (id, opts) => authReq(`/workflows/${id}/approve`, { method: 'POST', body: opts ?? {} }),
|
|
90
|
+
trigger: (path, body) => authReq(`/workflows/${path}`, { method: 'POST', body }),
|
|
91
|
+
tracks: () => authReq('/tracks'),
|
|
92
|
+
ghPulls: () => authReq('/github/pulls'),
|
|
93
|
+
ghIssues: () => authReq('/github/issues'),
|
|
94
|
+
ghIssuesByLabel: (repo, label) => authReq(`/github/issues?repo=${encodeURIComponent(repo)}&label=${encodeURIComponent(label)}`),
|
|
95
|
+
oracleDomains: () => authReq('/oracle/domains'),
|
|
96
|
+
consult: (domains, question) => authReq('/oracle', { method: 'POST', body: { domain: domains, question } }),
|
|
97
|
+
consults: (limit) => authReq(`/oracle${limitQs(limit)}`),
|
|
98
|
+
consultGet: (id) => authReq(`/oracle/${id}`),
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/command.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { CONFIG_PATH, DEFAULT_URL, readConfig, writeConfig, mask, currentProfileName, listProfiles, resolveProfile, setProfileField, } from '../config.js';
|
|
2
|
+
import { c, die } from '../ui.js';
|
|
3
|
+
import { flagStr, hasFlag } from '../args.js';
|
|
4
|
+
const cleanUrl = (u) => u.replace(/\/$/, '');
|
|
5
|
+
/** Render the profile table (● = active). */
|
|
6
|
+
function printProfiles() {
|
|
7
|
+
const cfg = readConfig();
|
|
8
|
+
const active = currentProfileName(cfg);
|
|
9
|
+
const profiles = listProfiles(cfg);
|
|
10
|
+
const names = Object.keys(profiles).sort();
|
|
11
|
+
if (!names.length) {
|
|
12
|
+
console.log(c.dim('no profiles yet — add one: moa config add <name> --url <url> --key <key>'));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
for (const n of names) {
|
|
16
|
+
const p = profiles[n];
|
|
17
|
+
const mark = n === active ? c.green('●') : c.dim('○');
|
|
18
|
+
const key = p.apiKey ? c.dim(mask(p.apiKey)) : c.dim('(auto-bootstrap)');
|
|
19
|
+
console.log(` ${mark} ${n.padEnd(14)} ${(p.apiUrl || DEFAULT_URL).padEnd(28)} ${key}${p.label ? ' ' + c.dim(p.label) : ''}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export const configCmd = {
|
|
23
|
+
name: 'config',
|
|
24
|
+
group: 'config',
|
|
25
|
+
summary: 'View/switch profiles (multi-user) and the API URL / key. Persisted to ~/.moa/cli.json.',
|
|
26
|
+
usage: 'moa config | moa config use <name> | moa config add <name> --url <url> --key <key>',
|
|
27
|
+
subcommands: [
|
|
28
|
+
{ name: 'config', group: 'config', summary: 'Show the active profile + list all.', usage: 'moa config' },
|
|
29
|
+
{ name: 'config list', group: 'config', summary: 'List profiles (● = active).', usage: 'moa config list' },
|
|
30
|
+
{ name: 'config use', group: 'config', summary: 'Switch the active profile.', usage: 'moa config use <name>' },
|
|
31
|
+
{ name: 'config add', group: 'config', summary: 'Add/update a profile (operator/org).', usage: 'moa config add <name> [--url <url>] [--key <key>] [--label <text>] [--use]' },
|
|
32
|
+
{ name: 'config remove', group: 'config', summary: 'Delete a profile.', usage: 'moa config remove <name>' },
|
|
33
|
+
{ name: 'config set', group: 'config', summary: 'Set url/key/label on the active profile.', usage: 'moa config set <url|key|label> <value>' },
|
|
34
|
+
{ name: 'config clear', group: 'config', summary: 'Clear the active profile (--all wipes everything).', usage: 'moa config clear [--all]' },
|
|
35
|
+
],
|
|
36
|
+
async run(a) {
|
|
37
|
+
const sub = a.pos[0];
|
|
38
|
+
// Show active profile + the full list.
|
|
39
|
+
if (!sub) {
|
|
40
|
+
const { name, apiUrl, apiKey } = resolveProfile();
|
|
41
|
+
console.log(`path : ${c.dim(CONFIG_PATH)}`);
|
|
42
|
+
console.log(`profile : ${c.green(name)}${process.env.MOA_PROFILE ? c.dim(' (from $MOA_PROFILE)') : ''}`);
|
|
43
|
+
console.log(`url : ${apiUrl}`);
|
|
44
|
+
console.log(`key : ${apiKey ? mask(apiKey) : c.dim('(auto-bootstrap)')}`);
|
|
45
|
+
console.log(c.dim('\nprofiles:'));
|
|
46
|
+
printProfiles();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (sub === 'list' || sub === 'profiles') {
|
|
50
|
+
printProfiles();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (sub === 'use') {
|
|
54
|
+
const name = a.pos[1];
|
|
55
|
+
if (!name)
|
|
56
|
+
die('usage: moa config use <name>');
|
|
57
|
+
const cfg = readConfig();
|
|
58
|
+
cfg.profiles = cfg.profiles ?? {};
|
|
59
|
+
if (!listProfiles(cfg)[name])
|
|
60
|
+
cfg.profiles[name] = {}; // create empty so you can populate it after
|
|
61
|
+
cfg.current = name;
|
|
62
|
+
writeConfig(cfg);
|
|
63
|
+
console.log(c.green(`switched to profile '${name}'`));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (sub === 'add') {
|
|
67
|
+
const name = a.pos[1];
|
|
68
|
+
if (!name)
|
|
69
|
+
die('usage: moa config add <name> [--url <url>] [--key <key>] [--label <text>] [--use]');
|
|
70
|
+
const url = flagStr(a, 'url');
|
|
71
|
+
const apiKey = flagStr(a, 'key');
|
|
72
|
+
const label = flagStr(a, 'label');
|
|
73
|
+
const cfg = readConfig();
|
|
74
|
+
cfg.profiles = cfg.profiles ?? {};
|
|
75
|
+
const prev = cfg.profiles[name] ?? {};
|
|
76
|
+
cfg.profiles[name] = {
|
|
77
|
+
apiUrl: url ? cleanUrl(url) : prev.apiUrl,
|
|
78
|
+
apiKey: apiKey ?? prev.apiKey,
|
|
79
|
+
label: label ?? prev.label,
|
|
80
|
+
};
|
|
81
|
+
if (!cfg.current || hasFlag(a, 'use'))
|
|
82
|
+
cfg.current = name;
|
|
83
|
+
writeConfig(cfg);
|
|
84
|
+
console.log(c.green(`saved profile '${name}'`) + (cfg.current === name ? c.dim(' (active)') : ''));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (sub === 'remove' || sub === 'rm') {
|
|
88
|
+
const name = a.pos[1];
|
|
89
|
+
if (!name)
|
|
90
|
+
die('usage: moa config remove <name>');
|
|
91
|
+
const cfg = readConfig();
|
|
92
|
+
const existed = Boolean(cfg.profiles?.[name]);
|
|
93
|
+
if (cfg.profiles)
|
|
94
|
+
delete cfg.profiles[name];
|
|
95
|
+
if (cfg.current === name)
|
|
96
|
+
delete cfg.current; // falls back to 'default'
|
|
97
|
+
writeConfig(cfg);
|
|
98
|
+
console.log(existed ? c.green(`removed profile '${name}'`) : c.dim(`no profile '${name}'`));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (sub === 'set') {
|
|
102
|
+
const field = a.pos[1];
|
|
103
|
+
const value = a.pos[2];
|
|
104
|
+
if (!['url', 'key', 'label'].includes(field) || !value)
|
|
105
|
+
die('usage: moa config set <url|key|label> <value>');
|
|
106
|
+
const name = currentProfileName();
|
|
107
|
+
const map = { url: 'apiUrl', key: 'apiKey', label: 'label' };
|
|
108
|
+
setProfileField(name, map[field], field === 'url' ? cleanUrl(value) : value);
|
|
109
|
+
console.log(c.green(`saved ${field} on profile '${name}'`));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (sub === 'clear') {
|
|
113
|
+
if (hasFlag(a, 'all')) {
|
|
114
|
+
writeConfig({});
|
|
115
|
+
console.log(c.green('cleared all config'));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const cfg = readConfig();
|
|
119
|
+
const name = currentProfileName(cfg);
|
|
120
|
+
if (cfg.profiles?.[name])
|
|
121
|
+
delete cfg.profiles[name];
|
|
122
|
+
writeConfig(cfg);
|
|
123
|
+
console.log(c.green(`cleared profile '${name}'`) + c.dim(' (use --all to wipe everything)'));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
die(`unknown config command: ${sub}`);
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { api } from '../client.js';
|
|
2
|
+
import { c, die } from '../ui.js';
|
|
3
|
+
export const ghCmd = {
|
|
4
|
+
name: 'gh',
|
|
5
|
+
group: 'github',
|
|
6
|
+
summary: 'GitHub feed: open PRs or issues for the operator.',
|
|
7
|
+
usage: 'moa gh pulls | issues',
|
|
8
|
+
args: [{ name: 'which', required: true, desc: 'pulls | issues' }],
|
|
9
|
+
async run(a) {
|
|
10
|
+
const which = a.pos[0];
|
|
11
|
+
const data = which === 'issues' ? await api.ghIssues() : which === 'pulls' ? await api.ghPulls() : die('usage: moa gh pulls|issues');
|
|
12
|
+
if (!data.connected)
|
|
13
|
+
return console.log(c.red('GitHub not connected'));
|
|
14
|
+
if (!data.items.length)
|
|
15
|
+
return console.log(c.dim('nothing'));
|
|
16
|
+
data.items.forEach((it) => console.log(`${it.repo}#${it.number} ${c.dim(it.title)}`));
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/commands/github.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAIlC,MAAM,CAAC,MAAM,KAAK,GAAY;IAC5B,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,QAAQ;IACf,OAAO,EAAE,mDAAmD;IAC5D,KAAK,EAAE,uBAAuB;IAC9B,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACjE,KAAK,CAAC,GAAG,CAAC,CAAO;QACf,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,IAAI,GACR,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1H,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IACzF,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { api } from '../client.js';
|
|
2
|
+
import { c, statusColor, die } from '../ui.js';
|
|
3
|
+
import { flagNum, hasFlag } from '../args.js';
|
|
4
|
+
import { pollRetry, sleep } from '../poll.js';
|
|
5
|
+
export const oracleCmd = {
|
|
6
|
+
name: 'oracle',
|
|
7
|
+
group: 'oracle',
|
|
8
|
+
summary: 'Consult grounded domain oracles (cited Q&A from curated KBs).',
|
|
9
|
+
usage: 'moa oracle [list] | moa oracle consult <domain>[,domain,…] "<question>" [--watch]',
|
|
10
|
+
subcommands: [
|
|
11
|
+
{ name: 'oracle list', group: 'oracle', summary: 'List available oracle domains.', usage: 'moa oracle list', examples: ['moa oracle list'] },
|
|
12
|
+
{
|
|
13
|
+
name: 'oracle consult',
|
|
14
|
+
group: 'oracle',
|
|
15
|
+
summary: 'Ask one or more oracles a question (grounded, cited).',
|
|
16
|
+
usage: 'moa oracle consult <domain>[,domain,…] "<question>" [--watch]',
|
|
17
|
+
args: [
|
|
18
|
+
{ name: 'domain', required: true, desc: 'oracle domain(s), comma-separated (see `moa oracle list`)' },
|
|
19
|
+
{ name: 'question', required: true, desc: 'the question to ask' },
|
|
20
|
+
{ name: '--watch', desc: 'wait for and print the answer' },
|
|
21
|
+
],
|
|
22
|
+
examples: [
|
|
23
|
+
'moa oracle consult ts-engineer "enum vs literal union?" --watch',
|
|
24
|
+
'moa oracle consult ts-engineer,rust-engineer "async patterns?" --watch',
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'oracle history',
|
|
29
|
+
group: 'oracle',
|
|
30
|
+
summary: 'List recent consults.',
|
|
31
|
+
usage: 'moa oracle history [--limit N] [--json]',
|
|
32
|
+
args: [
|
|
33
|
+
{ name: '--limit', desc: 'max consults to show (default 30)' },
|
|
34
|
+
{ name: '--json', desc: 'print the raw API response as JSON' },
|
|
35
|
+
],
|
|
36
|
+
examples: ['moa oracle history'],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
async run(a) {
|
|
40
|
+
const sub = a.pos[0];
|
|
41
|
+
if (!sub || sub === 'list') {
|
|
42
|
+
const { domains } = await api.oracleDomains();
|
|
43
|
+
console.log(domains.length ? domains.join('\n') : c.dim('no oracle domains'));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (sub === 'history') {
|
|
47
|
+
const limit = flagNum(a, 'limit') ?? 30;
|
|
48
|
+
const cs = (await api.consults(limit)).slice(0, limit);
|
|
49
|
+
if (hasFlag(a, 'json'))
|
|
50
|
+
return console.log(JSON.stringify(cs, null, 2));
|
|
51
|
+
if (!cs.length)
|
|
52
|
+
return console.log(c.dim('no consults'));
|
|
53
|
+
cs.forEach((x) => console.log(`${c.dim(x.id.slice(0, 8))} ${statusColor(x.status.padEnd(9))} ${c.bold(x.domain.padEnd(8))} ${x.question.slice(0, 60)}`));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (sub === 'consult') {
|
|
57
|
+
const raw = a.pos[1] ?? die('usage: moa oracle consult <domain>[,domain,…] "<question>"');
|
|
58
|
+
const domains = raw.split(',').map((s) => s.trim()).filter(Boolean);
|
|
59
|
+
if (!domains.length)
|
|
60
|
+
die('usage: moa oracle consult <domain>[,domain,…] "<question>"');
|
|
61
|
+
const question = a.pos.slice(2).join(' ');
|
|
62
|
+
if (!question)
|
|
63
|
+
die('usage: moa oracle consult <domain>[,domain,…] "<question>"');
|
|
64
|
+
const con = await api.consult(domains.length === 1 ? domains[0] : domains, question);
|
|
65
|
+
console.log(c.green(`consulting ${domains.join(', ')} → ${con.id.slice(0, 8)}`));
|
|
66
|
+
if (!hasFlag(a, 'watch'))
|
|
67
|
+
return;
|
|
68
|
+
for (;;) {
|
|
69
|
+
const cur = await pollRetry(() => api.consultGet(con.id));
|
|
70
|
+
if (cur.status !== 'running') {
|
|
71
|
+
console.log(statusColor(cur.status) + (cur.costUsd != null ? ' ' + c.dim('$' + cur.costUsd.toFixed(4)) : ''));
|
|
72
|
+
if (cur.result)
|
|
73
|
+
console.log('\n' + cur.result);
|
|
74
|
+
if (cur.error)
|
|
75
|
+
console.log(c.red('\n' + cur.error));
|
|
76
|
+
if (cur.status !== 'succeeded')
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await sleep(3000);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
die(`unknown oracle command: ${sub}`);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=oracle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oracle.js","sourceRoot":"","sources":["../../src/commands/oracle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { api, API_URL } from '../client.js';
|
|
2
|
+
import { c } from '../ui.js';
|
|
3
|
+
import { flagStr, hasFlag } from '../args.js';
|
|
4
|
+
export const statusCmd = {
|
|
5
|
+
name: 'status',
|
|
6
|
+
group: 'status',
|
|
7
|
+
summary: 'Server overview snapshot (oracles, counts). Add --spend for cumulative cost.',
|
|
8
|
+
usage: 'moa status [--spend [--since <ISO-date>]] [--json]',
|
|
9
|
+
args: [
|
|
10
|
+
{ name: '--json', desc: 'print the raw API response as JSON' },
|
|
11
|
+
{ name: '--spend', desc: 'show cumulative workflow cost for this operator' },
|
|
12
|
+
{ name: '--since', desc: 'ISO date to filter spend from, e.g. 2026-06-19 (implies --spend)' },
|
|
13
|
+
],
|
|
14
|
+
async run(a) {
|
|
15
|
+
if (hasFlag(a, 'spend') || flagStr(a, 'since') !== undefined) {
|
|
16
|
+
const since = flagStr(a, 'since');
|
|
17
|
+
const s = await api.statusSpend(since);
|
|
18
|
+
if (hasFlag(a, 'json'))
|
|
19
|
+
return console.log(JSON.stringify(s, null, 2));
|
|
20
|
+
const window = s.since ? `since ${s.since.slice(0, 10)}` : 'all time';
|
|
21
|
+
console.log(` spend ${c.bold('$' + s.costUsd.toFixed(4))} ${c.dim(`(${s.runs} runs, ${window})`)}`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const s = await api.status();
|
|
25
|
+
if (hasFlag(a, 'json'))
|
|
26
|
+
return console.log(JSON.stringify(s, null, 2));
|
|
27
|
+
const counts = (s.counts ?? {});
|
|
28
|
+
console.log(c.bold('Moa') + c.dim(` ${API_URL}`));
|
|
29
|
+
console.log(` oracles : ${s.oracleDomains?.join(', ') ?? '-'}`);
|
|
30
|
+
console.log(` tasks : ${counts.tasks ?? 0} sessions: ${counts.sessions ?? 0} keys: ${counts.apiKeys ?? 0}`);
|
|
31
|
+
const q = s.workflowQueue;
|
|
32
|
+
if (q && (q.running > 0 || q.queued > 0))
|
|
33
|
+
console.log(` running ${q.running}/${q.limit} · queued ${q.queued}`);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
/** `moa setup web [--domains a,b,c | --clear]` — view/set the org's WebFetch allowlist
|
|
37
|
+
* (the agent web policy's fetch stage). No flags = show current. */
|
|
38
|
+
async function runWebSetup(a) {
|
|
39
|
+
let res;
|
|
40
|
+
if (hasFlag(a, 'clear')) {
|
|
41
|
+
res = await api.setWebDomains([]);
|
|
42
|
+
}
|
|
43
|
+
else if (flagStr(a, 'domains') !== undefined) {
|
|
44
|
+
const domains = flagStr(a, 'domains').split(',').map((d) => d.trim()).filter(Boolean);
|
|
45
|
+
res = await api.setWebDomains(domains);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
res = await api.webDomains();
|
|
49
|
+
}
|
|
50
|
+
const src = res.source === 'org' ? c.dim('(org)') : c.dim('(env default)');
|
|
51
|
+
const list = res.domains.includes('*')
|
|
52
|
+
? 'all hosts (any domain)'
|
|
53
|
+
: res.domains.length
|
|
54
|
+
? res.domains.join(', ')
|
|
55
|
+
: c.dim('(none — fetch disabled)');
|
|
56
|
+
console.log(` webfetch allowlist ${src}: ${list}`);
|
|
57
|
+
}
|
|
58
|
+
export const setupCmd = {
|
|
59
|
+
name: 'setup',
|
|
60
|
+
group: 'status',
|
|
61
|
+
summary: 'Connector status, or manage the WebFetch allowlist (`setup web`).',
|
|
62
|
+
usage: 'moa setup [web [--domains a,b,c | --clear]]',
|
|
63
|
+
args: [
|
|
64
|
+
{ name: 'web', desc: 'show the WebFetch allowlist; --domains <csv> to restrict (or "none" to disable), --clear to reset to the default (all hosts)' },
|
|
65
|
+
],
|
|
66
|
+
subcommands: [
|
|
67
|
+
{ name: 'setup web', group: 'status', summary: "View/set the org's WebFetch allowlist (default: all hosts).", usage: 'moa setup web [--domains a,b,c|none | --clear]' },
|
|
68
|
+
],
|
|
69
|
+
async run(a) {
|
|
70
|
+
if (a.pos[0] === 'web')
|
|
71
|
+
return runWebSetup(a);
|
|
72
|
+
const s = (await api.setup());
|
|
73
|
+
const mark = (b) => (b ? c.green('connected') : c.red('not connected'));
|
|
74
|
+
console.log(` claude : ${mark(s.claude?.connected)} ${c.dim(s.claude?.email ?? '')}`);
|
|
75
|
+
console.log(` github : ${mark(s.github?.connected)} ${c.dim(s.github?.login ? '@' + s.github.login : '')}`);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|