@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parse } from './args.js';
|
|
3
|
+
import { c, die } from './ui.js';
|
|
4
|
+
import { API_URL, PROFILE } from './client.js';
|
|
5
|
+
import { catalog, findCommand } from './registry.js';
|
|
6
|
+
// Don't crash when output is piped to `head`/`grep` and the reader closes early.
|
|
7
|
+
// (Throwing inside an 'error' listener would crash with an unhandled exception.)
|
|
8
|
+
process.stdout.on('error', (e) => {
|
|
9
|
+
if (e.code === 'EPIPE')
|
|
10
|
+
process.exit(0);
|
|
11
|
+
console.error(`stdout error: ${e.message}`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
});
|
|
14
|
+
const GROUP_ORDER = ['status', 'tasks', 'workflows', 'oracle', 'github', 'config'];
|
|
15
|
+
const GROUP_TITLE = {
|
|
16
|
+
status: 'Status',
|
|
17
|
+
tasks: 'Tasks',
|
|
18
|
+
workflows: 'Workflows',
|
|
19
|
+
oracle: 'Oracle',
|
|
20
|
+
github: 'GitHub',
|
|
21
|
+
config: 'Config',
|
|
22
|
+
};
|
|
23
|
+
function help(asJson) {
|
|
24
|
+
const cmds = catalog();
|
|
25
|
+
if (asJson) {
|
|
26
|
+
// The AI knowledge base: how to connect + every command with usage/args/examples.
|
|
27
|
+
console.log(JSON.stringify({
|
|
28
|
+
api: API_URL,
|
|
29
|
+
auth: 'Requests use the x-api-key header. If MOA_API_KEY is unset, the CLI auto-bootstraps the single default operator on first call and persists the key to the config file for reuse. On a control-plane-enrolled workspace bootstrap is gated — set MOA_API_KEY or `moa config set key <key>`.',
|
|
30
|
+
profile: PROFILE,
|
|
31
|
+
globalFlags: {
|
|
32
|
+
'--profile <name>': 'Use this config profile for one command (highest precedence: --profile → $MOA_PROFILE → config.current → "default"). e.g. `moa whoami --profile fnmoa`',
|
|
33
|
+
},
|
|
34
|
+
env: {
|
|
35
|
+
MOA_PROFILE: 'Active config profile (multi-user/org); else config.current, else "default". See `moa config`.',
|
|
36
|
+
MOA_API_URL: 'Server base URL (overrides the profile; default http://localhost:3000)',
|
|
37
|
+
MOA_API_KEY: 'API key (overrides the profile); if unset, auto-bootstrapped and saved to the active profile',
|
|
38
|
+
},
|
|
39
|
+
notes: [
|
|
40
|
+
'Add --watch to run/trigger/get commands to stream the live timeline until the run finishes; a watch exits 1 if the run ends failed/canceled.',
|
|
41
|
+
'Data commands (tasks, task get, wf list, wf get, oracle history, status) take --json for the raw API response.',
|
|
42
|
+
'Lists take --limit N (default 30). `moa task <id>` accepts a unique id prefix.',
|
|
43
|
+
'Repos are "owner/repo". Workflow actions take an issue or PR number (see each command\'s args).',
|
|
44
|
+
'Each command entry includes usage, documented args, and copy-pasteable examples.',
|
|
45
|
+
],
|
|
46
|
+
commands: cmds,
|
|
47
|
+
}, null, 2));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
console.log(`${c.bold('moa')} — Moa operator CLI ${c.dim(`(${PROFILE} · ${API_URL})`)}\n`);
|
|
51
|
+
const width = Math.max(...cmds.map((m) => m.usage.length));
|
|
52
|
+
for (const group of GROUP_ORDER) {
|
|
53
|
+
const inGroup = cmds.filter((m) => m.group === group);
|
|
54
|
+
if (!inGroup.length)
|
|
55
|
+
continue;
|
|
56
|
+
console.log(c.bold(GROUP_TITLE[group] ?? group));
|
|
57
|
+
for (const m of inGroup)
|
|
58
|
+
console.log(` ${m.usage.padEnd(width)} ${c.dim(m.summary)}`);
|
|
59
|
+
console.log('');
|
|
60
|
+
}
|
|
61
|
+
console.log(c.dim('moa help --json → machine-readable command catalog (for agents)'));
|
|
62
|
+
console.log(c.dim('Data commands take --json; lists take --limit N. Watches exit 1 on failure.'));
|
|
63
|
+
console.log(c.dim('Profiles (multi-user/org): moa config use <name> · moa config add <name> --url <url> --key <key> · $MOA_PROFILE'));
|
|
64
|
+
console.log(c.dim('Env: MOA_API_URL, MOA_API_KEY override the active profile.'));
|
|
65
|
+
}
|
|
66
|
+
async function main() {
|
|
67
|
+
const { pos, flags } = parse(process.argv.slice(2));
|
|
68
|
+
const name = pos[0];
|
|
69
|
+
if (!name || name === 'help' || name === '-h' || flags.help) {
|
|
70
|
+
return help(!!flags.json);
|
|
71
|
+
}
|
|
72
|
+
const cmd = findCommand(name);
|
|
73
|
+
if (!cmd)
|
|
74
|
+
die(`unknown command: ${name} (try: moa help)`);
|
|
75
|
+
// Strip the command name; the command sees its own positionals + flags.
|
|
76
|
+
await cmd.run({ pos: pos.slice(1), flags });
|
|
77
|
+
}
|
|
78
|
+
main().catch((e) => die(e instanceof Error ? e.message : String(e)));
|
|
79
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/poll.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Watch-loop helpers: a transient network blip must not kill an hours-long watch.
|
|
2
|
+
import { c } from './ui.js';
|
|
3
|
+
export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
4
|
+
const MAX_RETRIES = 5;
|
|
5
|
+
const MAX_BACKOFF_MS = 15_000;
|
|
6
|
+
/** Run one poll, retrying failures with exponential backoff (1s → cap 15s).
|
|
7
|
+
* Backoff is local to each call, so it resets on every successful poll. */
|
|
8
|
+
export async function pollRetry(fn) {
|
|
9
|
+
let delay = 1000;
|
|
10
|
+
for (let attempt = 0;; attempt++) {
|
|
11
|
+
try {
|
|
12
|
+
return await fn();
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
if (attempt >= MAX_RETRIES)
|
|
16
|
+
throw e;
|
|
17
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
18
|
+
console.error(c.dim(`· poll failed (${msg}) — retrying in ${Math.round(delay / 1000)}s`));
|
|
19
|
+
await sleep(delay);
|
|
20
|
+
delay = Math.min(delay * 2, MAX_BACKOFF_MS);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=poll.js.map
|
package/dist/poll.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll.js","sourceRoot":"","sources":["../src/poll.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,OAAO,EAAE,CAAC,EAAE,MAAM,SAAS,CAAC;AAE5B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EAAU,EAAiB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAE1F,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B;4EAC4E;AAC5E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,EAAoB;IACrD,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,OAAO,IAAI,WAAW;gBAAE,MAAM,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,GAAG,mBAAmB,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1F,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;YACnB,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { statusCmd, setupCmd } from './commands/status.js';
|
|
2
|
+
import { whoamiCmd } from './commands/whoami.js';
|
|
3
|
+
import { trackCmd } from './commands/track.js';
|
|
4
|
+
import { tasksCmd, taskCmd, runCmd, cancelCmd } from './commands/tasks.js';
|
|
5
|
+
import { wfCmd } from './commands/workflows.js';
|
|
6
|
+
import { ghCmd } from './commands/github.js';
|
|
7
|
+
import { oracleCmd } from './commands/oracle.js';
|
|
8
|
+
import { configCmd } from './commands/config.js';
|
|
9
|
+
/** Every top-level command. Add a module here to extend the CLI. */
|
|
10
|
+
export const COMMANDS = [
|
|
11
|
+
statusCmd,
|
|
12
|
+
setupCmd,
|
|
13
|
+
whoamiCmd,
|
|
14
|
+
tasksCmd,
|
|
15
|
+
taskCmd,
|
|
16
|
+
runCmd,
|
|
17
|
+
cancelCmd,
|
|
18
|
+
wfCmd,
|
|
19
|
+
trackCmd,
|
|
20
|
+
ghCmd,
|
|
21
|
+
oracleCmd,
|
|
22
|
+
configCmd,
|
|
23
|
+
];
|
|
24
|
+
export function findCommand(name) {
|
|
25
|
+
return COMMANDS.find((cmd) => cmd.name === name);
|
|
26
|
+
}
|
|
27
|
+
const metaOf = (cmd) => ({
|
|
28
|
+
name: cmd.name,
|
|
29
|
+
group: cmd.group,
|
|
30
|
+
summary: cmd.summary,
|
|
31
|
+
usage: cmd.usage,
|
|
32
|
+
args: cmd.args,
|
|
33
|
+
examples: cmd.examples,
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* The machine-readable command catalog — the AI knowledge base. Flattens
|
|
37
|
+
* commands + their sub-actions into a flat, documented list. Emitted by
|
|
38
|
+
* `moa help --json` so an agent can discover every capability and its usage.
|
|
39
|
+
*/
|
|
40
|
+
export function catalog() {
|
|
41
|
+
const out = [];
|
|
42
|
+
for (const cmd of COMMANDS) {
|
|
43
|
+
if (cmd.subcommands?.length)
|
|
44
|
+
out.push(...cmd.subcommands);
|
|
45
|
+
else
|
|
46
|
+
out.push(metaOf(cmd));
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD,oEAAoE;AACpE,MAAM,CAAC,MAAM,QAAQ,GAAc;IACjC,SAAS;IACT,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,OAAO;IACP,MAAM;IACN,SAAS;IACT,KAAK;IACL,QAAQ;IACR,KAAK;IACL,SAAS;IACT,SAAS;CACV,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,GAAY,EAAe,EAAE,CAAC,CAAC;IAC7C,IAAI,EAAE,GAAG,CAAC,IAAI;IACd,KAAK,EAAE,GAAG,CAAC,KAAK;IAChB,OAAO,EAAE,GAAG,CAAC,OAAO;IACpB,KAAK,EAAE,GAAG,CAAC,KAAK;IAChB,IAAI,EAAE,GAAG,CAAC,IAAI;IACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;CACvB,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,OAAO;IACrB,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;;YACrD,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/ui.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Terminal formatting helpers (color-aware, respects NO_COLOR / non-TTY).
|
|
2
|
+
const noColor = !!process.env.NO_COLOR || !process.stdout.isTTY;
|
|
3
|
+
const wrap = (code) => (s) => (noColor ? `${s}` : `\x1b[${code}m${s}\x1b[0m`);
|
|
4
|
+
export const c = {
|
|
5
|
+
dim: wrap('2'),
|
|
6
|
+
bold: wrap('1'),
|
|
7
|
+
green: wrap('32'),
|
|
8
|
+
red: wrap('31'),
|
|
9
|
+
yellow: wrap('33'),
|
|
10
|
+
cyan: wrap('36'),
|
|
11
|
+
amber: wrap('33'),
|
|
12
|
+
};
|
|
13
|
+
export const statusColor = (s) => s === 'succeeded'
|
|
14
|
+
? c.green(s)
|
|
15
|
+
: s === 'failed'
|
|
16
|
+
? c.red(s)
|
|
17
|
+
: s === 'running' || s === 'queued'
|
|
18
|
+
? c.yellow(s)
|
|
19
|
+
: c.dim(s);
|
|
20
|
+
/** Relative time for list columns: "5s ago", "3m ago", "2h ago", "4d ago". */
|
|
21
|
+
export function relTime(when) {
|
|
22
|
+
if (!when)
|
|
23
|
+
return '';
|
|
24
|
+
const t = new Date(when).getTime();
|
|
25
|
+
if (!Number.isFinite(t))
|
|
26
|
+
return '';
|
|
27
|
+
const s = Math.max(0, Math.floor((Date.now() - t) / 1000));
|
|
28
|
+
if (s < 60)
|
|
29
|
+
return `${s}s ago`;
|
|
30
|
+
if (s < 3600)
|
|
31
|
+
return `${Math.floor(s / 60)}m ago`;
|
|
32
|
+
if (s < 86400)
|
|
33
|
+
return `${Math.floor(s / 3600)}h ago`;
|
|
34
|
+
return `${Math.floor(s / 86400)}d ago`;
|
|
35
|
+
}
|
|
36
|
+
export function die(msg) {
|
|
37
|
+
console.error(c.red(`✗ ${msg}`));
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=ui.js.map
|
package/dist/ui.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;AAChE,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;AAEvG,MAAM,CAAC,MAAM,CAAC,GAAG;IACf,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IACd,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IACf,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;IACjB,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;IACf,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;IAClB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;IAChB,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAS,EAAU,EAAE,CAC/C,CAAC,KAAK,WAAW;IACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACZ,CAAC,CAAC,CAAC,KAAK,QAAQ;QACd,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACV,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,QAAQ;YACjC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACb,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAEnB,8EAA8E;AAC9E,MAAM,UAAU,OAAO,CAAC,IAA+B;IACrD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC/B,IAAI,CAAC,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC;IAClD,IAAI,CAAC,GAAG,KAAK;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;IACrD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,GAAW;IAC7B,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fnmoa/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Terminal client for the Moa server — drive tasks and GitHub workflows over its HTTP API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"moa": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/fnLog0/moa.git",
|
|
21
|
+
"directory": "apps/cli"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/fnLog0/moa/tree/main/apps/cli#readme",
|
|
24
|
+
"bugs": "https://github.com/fnLog0/moa/issues",
|
|
25
|
+
"keywords": [
|
|
26
|
+
"moa",
|
|
27
|
+
"cli",
|
|
28
|
+
"github",
|
|
29
|
+
"automation",
|
|
30
|
+
"workflows",
|
|
31
|
+
"coding-agent"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"start": "tsx src/index.ts",
|
|
38
|
+
"build": "tsc -p tsconfig.json",
|
|
39
|
+
"prepublishOnly": "pnpm build",
|
|
40
|
+
"typecheck": "tsc --noEmit"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^25.9.1",
|
|
44
|
+
"tsx": "^4.22.4",
|
|
45
|
+
"typescript": "^6.0.3"
|
|
46
|
+
}
|
|
47
|
+
}
|