@fnmoa/cli 0.3.0 → 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.
Files changed (50) hide show
  1. package/LICENSE +31 -0
  2. package/README.md +273 -70
  3. package/dist/assets/worker.js +216 -0
  4. package/dist/main.js +326 -0
  5. package/package.json +34 -27
  6. package/dist/args.js +0 -33
  7. package/dist/args.js.map +0 -1
  8. package/dist/client.js +0 -103
  9. package/dist/client.js.map +0 -1
  10. package/dist/command.js +0 -2
  11. package/dist/command.js.map +0 -1
  12. package/dist/commands/config.js +0 -129
  13. package/dist/commands/config.js.map +0 -1
  14. package/dist/commands/github.js +0 -19
  15. package/dist/commands/github.js.map +0 -1
  16. package/dist/commands/login.js +0 -128
  17. package/dist/commands/login.js.map +0 -1
  18. package/dist/commands/oracle.js +0 -86
  19. package/dist/commands/oracle.js.map +0 -1
  20. package/dist/commands/repos.js +0 -70
  21. package/dist/commands/repos.js.map +0 -1
  22. package/dist/commands/skills.js +0 -225
  23. package/dist/commands/skills.js.map +0 -1
  24. package/dist/commands/status.js +0 -78
  25. package/dist/commands/status.js.map +0 -1
  26. package/dist/commands/tasks.js +0 -171
  27. package/dist/commands/tasks.js.map +0 -1
  28. package/dist/commands/track.js +0 -31
  29. package/dist/commands/track.js.map +0 -1
  30. package/dist/commands/whoami.js +0 -22
  31. package/dist/commands/whoami.js.map +0 -1
  32. package/dist/commands/workflows.js +0 -304
  33. package/dist/commands/workflows.js.map +0 -1
  34. package/dist/config.js +0 -65
  35. package/dist/config.js.map +0 -1
  36. package/dist/index.js +0 -105
  37. package/dist/index.js.map +0 -1
  38. package/dist/poll.js +0 -24
  39. package/dist/poll.js.map +0 -1
  40. package/dist/registry.js +0 -56
  41. package/dist/registry.js.map +0 -1
  42. package/dist/ui.js +0 -56
  43. package/dist/ui.js.map +0 -1
  44. package/src/skills/moa-oracle/SKILL.md +0 -35
  45. package/src/skills/moa-profiles/SKILL.md +0 -49
  46. package/src/skills/moa-review-pr/SKILL.md +0 -47
  47. package/src/skills/moa-run-task/SKILL.md +0 -44
  48. package/src/skills/moa-setup/SKILL.md +0 -60
  49. package/src/skills/moa-ship-issue/SKILL.md +0 -54
  50. package/src/skills/moa-triage-audit/SKILL.md +0 -47
package/package.json CHANGED
@@ -1,48 +1,55 @@
1
1
  {
2
2
  "name": "@fnmoa/cli",
3
- "version": "0.3.0",
4
- "description": "Terminal client for the Moa server — drive tasks and GitHub workflows over its HTTP API",
3
+ "version": "0.4.1",
4
+ "description": "moa — talk to a workspace from a terminal.",
5
+ "license": "UNLICENSED",
5
6
  "type": "module",
6
7
  "bin": {
7
- "moa": "./dist/index.js"
8
+ "moa": "./dist/main.js"
8
9
  },
9
- "main": "dist/index.js",
10
+ "main": "./dist/main.js",
10
11
  "files": [
11
12
  "dist",
12
- "src/skills",
13
+ "LICENSE",
13
14
  "README.md"
14
15
  ],
15
16
  "engines": {
16
- "node": ">=18"
17
+ "node": ">=22"
18
+ },
19
+ "devDependencies": {
20
+ "@fnmoa/licence": "0.4.1",
21
+ "@types/node": "^24.10.1",
22
+ "@types/react": "^19.3.0",
23
+ "ink-testing-library": "^4.0.0",
24
+ "typescript": "^5.9.3",
25
+ "vitest": "^3.2.4"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "registry": "https://registry.npmjs.org"
17
30
  },
18
- "license": "MIT",
19
31
  "repository": {
20
32
  "type": "git",
21
- "url": "git+https://github.com/fnLog0/moa.git",
33
+ "url": "git+https://github.com/fnLog0/fnmoa.git",
22
34
  "directory": "apps/cli"
23
35
  },
24
- "homepage": "https://github.com/fnLog0/moa/tree/main/apps/cli#readme",
25
- "bugs": "https://github.com/fnLog0/moa/issues",
26
36
  "keywords": [
27
- "moa",
37
+ "agents",
28
38
  "cli",
29
- "github",
30
- "automation",
31
- "workflows",
32
- "coding-agent"
39
+ "claude",
40
+ "codex",
41
+ "cursor",
42
+ "orchestration"
33
43
  ],
34
- "publishConfig": {
35
- "access": "public"
44
+ "dependencies": {
45
+ "@vercel/sandbox": "^3.5.1",
46
+ "ink": "^7.1.1",
47
+ "react": "^19.3.0"
36
48
  },
37
49
  "scripts": {
38
- "start": "tsx src/index.ts",
39
- "build": "tsc -p tsconfig.json",
40
- "prepublishOnly": "pnpm build",
41
- "typecheck": "tsc --noEmit"
42
- },
43
- "devDependencies": {
44
- "@types/node": "^25.9.1",
45
- "tsx": "^4.22.4",
46
- "typescript": "^6.0.3"
50
+ "build": "tsc -p tsconfig.json && node ./scripts/executable.mjs",
51
+ "typecheck": "tsc -p tsconfig.test.json",
52
+ "test": "vitest run --passWithNoTests",
53
+ "clean": "rm -rf dist"
47
54
  }
48
- }
55
+ }
package/dist/args.js DELETED
@@ -1,33 +0,0 @@
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', 'version']);
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 DELETED
@@ -1 +0,0 @@
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,EAAE,SAAS,CAAC,CAAC,CAAC;AAErG,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 DELETED
@@ -1,103 +0,0 @@
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
- 'Run `moa login` to set your API key (or set $MOA_API_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
- repos: () => authReq('/setup/repos'),
82
- addRepo: (repo) => authReq('/setup/repos', { method: 'POST', body: { repo } }),
83
- removeRepo: (repo) => authReq('/setup/repos', { method: 'DELETE', body: { repo } }),
84
- tasks: (limit) => authReq(`/tasks${limitQs(limit)}`),
85
- task: (id, waitMs) => authReq(`/tasks/${id}${waitMs && waitMs > 0 ? `?waitMs=${Math.floor(waitMs)}` : ''}`),
86
- run: (input) => authReq('/tasks', { method: 'POST', body: input }),
87
- cancelTask: (id) => authReq(`/tasks/${id}`, { method: 'DELETE' }),
88
- workflows: (limit) => authReq(`/workflows${limitQs(limit)}`),
89
- pending: () => authReq('/workflows/pending'),
90
- workflow: (id) => authReq(`/workflows/${id}`),
91
- cancelWorkflow: (id) => authReq(`/workflows/${id}`, { method: 'DELETE' }),
92
- approveWorkflow: (id, opts) => authReq(`/workflows/${id}/approve`, { method: 'POST', body: opts ?? {} }),
93
- trigger: (path, body) => authReq(`/workflows/${path}`, { method: 'POST', body }),
94
- tracks: () => authReq('/tracks'),
95
- ghPulls: () => authReq('/github/pulls'),
96
- ghIssues: () => authReq('/github/issues'),
97
- ghIssuesByLabel: (repo, label) => authReq(`/github/issues?repo=${encodeURIComponent(repo)}&label=${encodeURIComponent(label)}`),
98
- oracleDomains: () => authReq('/oracle/domains'),
99
- consult: (domains, question) => authReq('/oracle', { method: 'POST', body: { domain: domains, question } }),
100
- consults: (limit) => authReq(`/oracle${limitQs(limit)}`),
101
- consultGet: (id) => authReq(`/oracle/${id}`),
102
- };
103
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/command.js DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=command.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":""}
@@ -1,129 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,128 +0,0 @@
1
- import { createInterface } from 'node:readline';
2
- import { DEFAULT_URL, CONFIG_PATH, resolveProfile, currentProfileName, setProfileField, mask, } from '../config.js';
3
- import { banner, c, die } from '../ui.js';
4
- const cleanUrl = (u) => u.replace(/\/$/, '');
5
- const RULE = '─'.repeat(48);
6
- /** Ask a question with an optional default (Enter accepts the default). Set
7
- * `bracket: false` to accept the default on Enter without showing the `[def]`
8
- * hint inline (used when the default is already shown on its own line). */
9
- function ask(rl, query, def, opts = {}) {
10
- const showBracket = opts.bracket ?? true;
11
- const prompt = def && showBracket ? `${query} ${c.dim(`[${def}]`)} ` : `${query} `;
12
- return new Promise((resolve) => rl.question(prompt, (a) => resolve(a.trim() || def || '')));
13
- }
14
- /** Ask for a secret without echoing keystrokes to the terminal. */
15
- function askSecret(rl, query) {
16
- process.stdout.write(`${query} `);
17
- rl.muted = true;
18
- return new Promise((resolve) => rl.question('', (a) => {
19
- rl.muted = false;
20
- process.stdout.write('\n');
21
- resolve(a.trim());
22
- }));
23
- }
24
- /** Probe the server with the key — returns `{ error }` (null on success) plus the
25
- * operator's GitHub login when reachable, so login can confirm *who* the key acts as.
26
- * Lenient by design: only a definitive 401/403 means a bad key, and a network
27
- * failure/timeout means unreachable. Any other HTTP status (the public URL is a
28
- * control-plane proxy whose exact routes vary) counts as "reached, key accepted".
29
- * Done with a raw fetch so it uses the freshly-entered url/key, not the client's
30
- * cached profile resolved at import time. */
31
- async function verify(url, key) {
32
- try {
33
- const res = await fetch(`${url}/setup/status`, {
34
- headers: { 'x-api-key': key },
35
- signal: AbortSignal.timeout(6000),
36
- });
37
- if (res.status === 401 || res.status === 403)
38
- return { error: 'key rejected' };
39
- let login;
40
- try {
41
- const body = (await res.json());
42
- login = body?.github?.login;
43
- }
44
- catch {
45
- /* non-JSON body from a proxy is fine — still "reached" */
46
- }
47
- return { error: null, login };
48
- }
49
- catch (e) {
50
- if (e instanceof Error && e.name === 'TimeoutError')
51
- return { error: 'no response (timed out)' };
52
- return { error: e instanceof Error ? e.message : String(e) };
53
- }
54
- }
55
- export async function runLogin(_a) {
56
- console.log(banner());
57
- if (!process.stdin.isTTY) {
58
- die('login is interactive — run it in a terminal, or use `moa config set url <url>` and `moa config set key <key>`');
59
- }
60
- const current = resolveProfile();
61
- const name = currentProfileName();
62
- const existing = current.apiKey;
63
- const reconfigure = !!existing;
64
- // Header + rule. Reconfiguring an existing profile shows its name so it's clear
65
- // which profile this edits (multi-operator / multi-org setups have several).
66
- console.log(` ${c.bold('connect the moa CLI')}${reconfigure ? c.dim(` · profile "${name}"`) : ''}`);
67
- console.log(` ${c.dim(RULE)}\n`);
68
- // Already configured → show what's set so the user knows what Enter will keep.
69
- if (reconfigure) {
70
- console.log(` ${c.dim('already connected:')}`);
71
- console.log(` url ${c.cyan(current.apiUrl)}`);
72
- console.log(` key ${mask(existing)} ${c.dim('(saved)')}`);
73
- console.log(`\n ${c.dim('Press Enter to keep each, or type a new value.')}\n`);
74
- }
75
- const rl = createInterface({ input: process.stdin, output: process.stdout });
76
- // Honor muting so secret entry doesn't echo to the terminal.
77
- rl._writeToOutput = (s) => {
78
- if (!rl.muted)
79
- process.stdout.write(s);
80
- };
81
- let url;
82
- let key;
83
- try {
84
- // Step 1 — Workspace URL. Default shown on its own line; Enter accepts it.
85
- const urlDefault = current.apiUrl || DEFAULT_URL;
86
- console.log(` ${c.bold('Step 1/2')} ${c.dim('·')} Workspace URL`);
87
- console.log(` ${c.dim('default ▸')} ${c.cyan(urlDefault)} ${c.dim('(press Enter to accept)')}`);
88
- url = cleanUrl(await ask(rl, ' url ▸', urlDefault, { bracket: false }));
89
- // Step 2 — API key. Tell the user exactly where to get it; mask on entry.
90
- console.log(`\n ${c.bold('Step 2/2')} ${c.dim('·')} API key`);
91
- if (reconfigure) {
92
- console.log(` ${c.dim(`Enter keeps ${mask(existing)}, or paste a new key`)}`);
93
- }
94
- else {
95
- console.log(` ${c.dim('get one ▸')} ${c.cyan('app.fnmoa.com')} ${c.dim('▸ Settings ▸ CLI')}`);
96
- }
97
- key = (await askSecret(rl, ' key ▸')) || existing || '';
98
- }
99
- finally {
100
- rl.close();
101
- }
102
- if (!key)
103
- die('no API key provided — grab one from app.fnmoa.com ▸ Settings ▸ CLI, then run `moa login` again.');
104
- process.stdout.write(`\n ${c.dim('verifying…')}`);
105
- const { error: err, login } = await verify(url, key);
106
- process.stdout.write('\r\x1b[K'); // clear the "verifying…" line
107
- setProfileField(name, 'apiUrl', url);
108
- setProfileField(name, 'apiKey', key);
109
- if (err) {
110
- console.log(` ${c.yellow('⚠')} couldn't verify ${c.dim(`(${err})`)} — saved anyway; check the URL/key.`);
111
- }
112
- else {
113
- const who = login ? ` ${c.dim('as')} ${c.cyan('@' + login)}` : '';
114
- console.log(` ${c.green('✓')} connected${who} ${c.dim('▸')} ${c.cyan(url)}`);
115
- }
116
- console.log(` ${c.green('✓')} saved ${c.dim('▸')} profile ${c.bold(name)} ${c.dim(`(${CONFIG_PATH})`)}\n`);
117
- console.log(` ${c.dim('next ▸')} ${c.cyan('moa status')} ${c.dim('·')} ${c.cyan('moa wf pending')} ${c.dim('·')} ${c.cyan('moa whoami')}\n`);
118
- }
119
- export const loginCmd = {
120
- name: 'login',
121
- group: 'config',
122
- summary: 'Connect the CLI: set your server URL + API key (interactive).',
123
- usage: 'moa login',
124
- async run(a) {
125
- await runLogin(a);
126
- },
127
- };
128
- //# sourceMappingURL=login.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -1,86 +0,0 @@
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