@abe-ing/cli 0.3.0 → 0.4.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 +17 -2
- package/dist/api.js +24 -1
- package/dist/api.js.map +1 -1
- package/dist/commands/worksheets.js +17 -0
- package/dist/commands/worksheets.js.map +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/output.js +40 -7
- package/dist/output.js.map +1 -1
- package/package.json +3 -3
- package/dist/api.test.js +0 -91
- package/dist/api.test.js.map +0 -1
- package/dist/commands/auth.test.js +0 -129
- package/dist/commands/auth.test.js.map +0 -1
- package/dist/commands/boards.test.js +0 -32
- package/dist/commands/boards.test.js.map +0 -1
- package/dist/commands/tasks.test.js +0 -85
- package/dist/commands/tasks.test.js.map +0 -1
- package/dist/config.test.js +0 -70
- package/dist/config.test.js.map +0 -1
- package/dist/output.test.js +0 -49
- package/dist/output.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @abe-ing/cli — the `abe` command
|
|
2
2
|
|
|
3
|
-
Drive [ABE](https://abe.ing) project boards and tasks from the command line. Built for humans **and** agents — run engineering issues inside ABE instead of GitHub, and let Claude Code (or any shell-driven agent) create boards, file issues, and move cards via `abe ... --json`.
|
|
3
|
+
Drive [ABE](https://abe.ing) project boards and tasks from the command line, and read the worksheets (docs) behind them. Built for humans **and** agents — run engineering issues inside ABE instead of GitHub, and let Claude Code (or any shell-driven agent) create boards, file issues, and move cards via `abe ... --json`.
|
|
4
4
|
|
|
5
5
|
It is a thin, dependency-light wrapper over the [ABE REST API](../../docs/agent-api/rest-api.md), authenticated with a Personal Access Token.
|
|
6
6
|
|
|
@@ -75,9 +75,11 @@ abe task complete 91
|
|
|
75
75
|
abe task list --board engineering # your OPEN tasks on that board
|
|
76
76
|
abe task list --board engineering --all --include-done # full set (admin/full token)
|
|
77
77
|
abe task board --board engineering # full board state incl. done — best for reconciliation
|
|
78
|
-
abe task show 91
|
|
78
|
+
abe task show 91 # header + the task BODY (its worksheet doc, rendered as markdown)
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
`task show` prints the task's `ref` (`ABE-91`, the form to cite in PRs), its `worksheet` id, and the task's body — the linked worksheet doc rendered to markdown — under the header block. `--json` carries the body as `task.body_markdown` (plus `task.description`, the create-time text, and `task.worksheet_id`). Prefer `body_markdown`: `description` stops tracking the doc once it has been edited in the editor. The CLI requests the body with `?render=markdown`; it is `null` when the doc is hidden from your token (e.g. a token without the `tasks` scope, or a private doc you can't see).
|
|
82
|
+
|
|
81
83
|
Invalid `--priority/--type/--size/--status` fail fast (exit 2) before any network call. `--column` is **not** client-validated (columns are per-board) — an invalid column returns the server's `422` listing the valid set.
|
|
82
84
|
|
|
83
85
|
### Comments, history & delete
|
|
@@ -97,6 +99,19 @@ abe task delete 91 --yes # PERMANENT — refuses without --yes
|
|
|
97
99
|
|
|
98
100
|
`task delete` is irreversible; prefer `task complete` for finished work. It refuses without `--yes` so an agent can't destroy a task by accident.
|
|
99
101
|
|
|
102
|
+
## Worksheets
|
|
103
|
+
|
|
104
|
+
Worksheets are ABE's docs. Every task's body is a worksheet (`task.worksheet_id`); pages, specs, and plans are worksheets too. Read one directly — by a task's `worksheet_id`, or any other doc id:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
abe worksheet show 6325 # "# <title>" then the body as markdown
|
|
108
|
+
abe --json worksheet show 6325 | jq -r '.worksheet.bodyMarkdown'
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The **server** renders the markdown (`GET /worksheets/:id?render=markdown`), so the CLI never carries its own Tiptap converter. Task docs need a token with the `tasks` scope (or `full`) — exit 6 otherwise. Private docs are readable only by their creator, people they're shared with, and workspace admins, exactly as in the web app (exit 7 when not visible). Read-only: edit docs in ABE.
|
|
112
|
+
|
|
113
|
+
`--json` emits a stable subset of the server's worksheet payload — `id`, `title`, `body` (Tiptap JSON), `bodyMarkdown`, `visibility`, `lastEditedAt`, `createdByName` — never the share token, owner email, or share/mention rosters the web editor receives.
|
|
114
|
+
|
|
100
115
|
## Members
|
|
101
116
|
|
|
102
117
|
```bash
|
package/dist/api.js
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { CliError, EXIT } from './errors.js';
|
|
2
|
+
// The worksheet fields the CLI exposes. The server's payload is the web
|
|
3
|
+
// editor's — it also carries shareToken (a public-share secret),
|
|
4
|
+
// createdByEmail, and the share/mention/customer rosters — none of which
|
|
5
|
+
// belongs on an agent's stdout or in its transcript. Project to this stable,
|
|
6
|
+
// documented subset (README → Worksheets).
|
|
7
|
+
export const WORKSHEET_FIELDS = ['id', 'title', 'body', 'bodyMarkdown', 'visibility', 'lastEditedAt', 'createdByName'];
|
|
8
|
+
export function pickWorksheet(raw) {
|
|
9
|
+
const out = {};
|
|
10
|
+
for (const k of WORKSHEET_FIELDS)
|
|
11
|
+
if (k in raw)
|
|
12
|
+
out[k] = raw[k];
|
|
13
|
+
return out;
|
|
14
|
+
}
|
|
2
15
|
export class ApiClient {
|
|
3
16
|
baseUrl;
|
|
4
17
|
token;
|
|
@@ -48,8 +61,18 @@ export class ApiClient {
|
|
|
48
61
|
boardState(boardId) {
|
|
49
62
|
return this.request('GET', `/tasks/board?board_id=${boardId}`);
|
|
50
63
|
}
|
|
64
|
+
// Opts in to the rendered body (`body_markdown`); the web app calls the
|
|
65
|
+
// same route without it and gets the lean projection.
|
|
51
66
|
getTask(id) {
|
|
52
|
-
return this.request('GET', `/tasks/${id}`);
|
|
67
|
+
return this.request('GET', `/tasks/${id}?render=markdown`);
|
|
68
|
+
}
|
|
69
|
+
// A worksheet (a task's doc, or any other doc) with its body rendered to
|
|
70
|
+
// markdown server-side — ONE Tiptap→markdown converter, and it lives on
|
|
71
|
+
// the server. Same visibility + PAT-scope rules as the web app. Projected
|
|
72
|
+
// to WORKSHEET_FIELDS before it reaches any output path.
|
|
73
|
+
async getWorksheet(id) {
|
|
74
|
+
const { worksheet } = await this.request('GET', `/worksheets/${id}?render=markdown`);
|
|
75
|
+
return { worksheet: pickWorksheet(worksheet ?? {}) };
|
|
53
76
|
}
|
|
54
77
|
createTask(body) {
|
|
55
78
|
return this.request('POST', '/tasks', body);
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { buildContext } from '../context.js';
|
|
2
|
+
import { printWorksheet } from '../output.js';
|
|
3
|
+
// Worksheets are ABE's docs. Every task's body lives in its linked worksheet
|
|
4
|
+
// (`abe task show` prints it inline); other pages/specs/plans are worksheets
|
|
5
|
+
// too. Read-only here — the doc editor owns writes.
|
|
6
|
+
export function registerWorksheetCommands(program) {
|
|
7
|
+
const worksheet = program.command('worksheet').description('Read worksheets (the docs behind tasks and other pages)');
|
|
8
|
+
worksheet
|
|
9
|
+
.command('show <id>')
|
|
10
|
+
.description('Show a worksheet with its body rendered as markdown')
|
|
11
|
+
.action(async (id, _o, cmd) => {
|
|
12
|
+
const { client, json } = buildContext(cmd.optsWithGlobals());
|
|
13
|
+
const { worksheet: found } = await client.getWorksheet(Number(id));
|
|
14
|
+
printWorksheet(found, { json });
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=worksheets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worksheets.js","sourceRoot":"","sources":["../../src/commands/worksheets.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAc,MAAM,eAAe,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,6EAA6E;AAC7E,6EAA6E;AAC7E,oDAAoD;AACpD,MAAM,UAAU,yBAAyB,CAAC,OAAgB;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,yDAAyD,CAAC,CAAA;IAErH,SAAS;SACN,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,qDAAqD,CAAC;SAClE,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAW,EAAE,GAAY,EAAE,EAAE;QACtD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,eAAe,EAAgB,CAAC,CAAA;QAC1E,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QAClE,cAAc,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;AACN,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { registerAuthCommands } from './commands/auth.js';
|
|
|
5
5
|
import { registerBoardCommands } from './commands/boards.js';
|
|
6
6
|
import { registerTaskCommands } from './commands/tasks.js';
|
|
7
7
|
import { registerMembersCommands } from './commands/members.js';
|
|
8
|
+
import { registerWorksheetCommands } from './commands/worksheets.js';
|
|
8
9
|
// Read the version from package.json so `abe --version` never drifts from the
|
|
9
10
|
// published package (package.json ships alongside dist/ in the npm tarball).
|
|
10
11
|
function packageVersion() {
|
|
@@ -19,7 +20,7 @@ function packageVersion() {
|
|
|
19
20
|
export function buildProgram() {
|
|
20
21
|
const program = new Command('abe');
|
|
21
22
|
program
|
|
22
|
-
.description('Drive ABE project boards and
|
|
23
|
+
.description('Drive ABE project boards, tasks, and worksheets from the command line.')
|
|
23
24
|
.version(packageVersion())
|
|
24
25
|
.option('--json', 'machine-readable JSON output on stdout (status text goes to stderr)')
|
|
25
26
|
.option('--api-url <url>', 'ABE API base URL (env: ABE_API_URL)')
|
|
@@ -31,6 +32,7 @@ export function buildProgram() {
|
|
|
31
32
|
registerAuthCommands(program);
|
|
32
33
|
registerBoardCommands(program);
|
|
33
34
|
registerTaskCommands(program);
|
|
35
|
+
registerWorksheetCommands(program);
|
|
34
36
|
registerMembersCommands(program);
|
|
35
37
|
return program;
|
|
36
38
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/output.js
CHANGED
|
@@ -55,16 +55,49 @@ export function printTasks(tasks, opts) {
|
|
|
55
55
|
export function printTask(task, opts) {
|
|
56
56
|
if (opts.json)
|
|
57
57
|
return emit({ task }, opts);
|
|
58
|
+
// Labels padded to one width so values line up in a column (awk-able).
|
|
58
59
|
const lines = [
|
|
59
60
|
`#${task.id} ${task.title}`,
|
|
60
|
-
`
|
|
61
|
-
`
|
|
62
|
-
`
|
|
63
|
-
`
|
|
64
|
-
`
|
|
65
|
-
`
|
|
66
|
-
`
|
|
61
|
+
...(task.ref ? [`ref: ${task.ref}`] : []),
|
|
62
|
+
`status: ${task.status}`,
|
|
63
|
+
`priority: ${task.priority}`,
|
|
64
|
+
`type: ${task.task_type}`,
|
|
65
|
+
`column: ${task.board_column}`,
|
|
66
|
+
`board: ${task.task_board_id ?? '(none)'}`,
|
|
67
|
+
`assignee: ${task.assignee_name ?? '(unassigned)'}`,
|
|
68
|
+
`labels: ${(task.labels ?? []).join(', ') || '(none)'}`,
|
|
69
|
+
`worksheet: ${task.worksheet_id ?? '(none)'}`,
|
|
67
70
|
];
|
|
71
|
+
// The body: the rendered worksheet doc when the server sent a non-empty
|
|
72
|
+
// one (a doc can legitimately render to nothing), else the create-time
|
|
73
|
+
// description. Truthiness, not `??`, so an empty render still falls back.
|
|
74
|
+
// After a blank line so the header block above stays greppable on its own.
|
|
75
|
+
const rendered = (task.body_markdown ?? '').trim();
|
|
76
|
+
const body = rendered || (task.description ?? '').trim();
|
|
77
|
+
if (body)
|
|
78
|
+
lines.push('', body);
|
|
68
79
|
process.stdout.write(`${lines.join('\n')}\n`);
|
|
69
80
|
}
|
|
81
|
+
export function printWorksheet(ws, opts) {
|
|
82
|
+
if (opts.json)
|
|
83
|
+
return emit({ worksheet: ws }, opts);
|
|
84
|
+
process.stdout.write(`# ${ws.title}\n`);
|
|
85
|
+
const body = (ws.bodyMarkdown ?? '').trim();
|
|
86
|
+
if (body) {
|
|
87
|
+
process.stdout.write(`\n${body}\n`);
|
|
88
|
+
}
|
|
89
|
+
else if (!('bodyMarkdown' in ws)) {
|
|
90
|
+
// Key ABSENT: an older server that ignores ?render=markdown. Never dump
|
|
91
|
+
// the Tiptap JSON `body` at a human instead.
|
|
92
|
+
status('(no rendered body — upgrade ABE for ?render=markdown support)');
|
|
93
|
+
}
|
|
94
|
+
else if (ws.bodyMarkdown === null) {
|
|
95
|
+
// Key present but null: the server saw the request and could not render
|
|
96
|
+
// this doc (malformed content). Not a client/version problem.
|
|
97
|
+
status('(the server could not render this doc — open it in ABE)');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
status('(empty)');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
70
103
|
//# sourceMappingURL=output.js.map
|
package/dist/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAMA,yEAAyE;AACzE,8EAA8E;AAC9E,2CAA2C;AAC3C,MAAM,UAAU,IAAI,CAAC,IAAa,EAAE,IAAgB;IAClD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAe;IACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAA;AACtC,CAAC;AAED,SAAS,GAAG,CAAC,CAAS,EAAE,KAAa;IACnC,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IACnB,OAAO,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;AACzE,CAAC;AAED,SAAS,KAAK,CAAC,OAAiB,EAAE,IAAgB;IAChD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACjG,MAAM,IAAI,GAAG,CAAC,KAAe,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAA;IAC7F,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC9F,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAe,EAAE,IAAgB;IAC3D,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;IAC5C,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,CAAC,YAAY,CAAC,CAAA;QACpB,OAAM;IACR,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACZ,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI;QACN,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;KAC7B,CAAC,CAAA;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;AACrF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,IAAgB;IACxD,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAA;IAC3C,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,CAAC,WAAW,CAAC,CAAA;QACnB,OAAM;IACR,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACZ,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,aAAa,IAAI,EAAE;KACtB,CAAC,CAAA;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/G,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAU,EAAE,IAAgB;IACpD,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,CAAA;IAC1C,uEAAuE;IACvE,MAAM,KAAK,GAAG;QACZ,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE;QAC5B,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,cAAc,IAAI,CAAC,MAAM,EAAE;QAC3B,cAAc,IAAI,CAAC,QAAQ,EAAE;QAC7B,cAAc,IAAI,CAAC,SAAS,EAAE;QAC9B,cAAc,IAAI,CAAC,YAAY,EAAE;QACjC,cAAc,IAAI,CAAC,aAAa,IAAI,QAAQ,EAAE;QAC9C,cAAc,IAAI,CAAC,aAAa,IAAI,cAAc,EAAE;QACpD,cAAc,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,EAAE;QAC1D,cAAc,IAAI,CAAC,YAAY,IAAI,QAAQ,EAAE;KAC9C,CAAA;IACD,wEAAwE;IACxE,uEAAuE;IACvE,0EAA0E;IAC1E,2EAA2E;IAC3E,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAClD,MAAM,IAAI,GAAG,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACxD,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAa,EAAE,IAAgB;IAC5D,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;IACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,CAAA;IACvC,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC3C,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAA;IACrC,CAAC;SAAM,IAAI,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,CAAC;QACnC,wEAAwE;QACxE,6CAA6C;QAC7C,MAAM,CAAC,+DAA+D,CAAC,CAAA;IACzE,CAAC;SAAM,IAAI,EAAE,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;QACpC,wEAAwE;QACxE,8DAA8D;QAC9D,MAAM,CAAC,yDAAyD,CAAC,CAAA;IACnE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,SAAS,CAAC,CAAA;IACnB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abe-ing/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Command-line interface for driving ABE project boards and tasks.",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Command-line interface for driving ABE project boards and tasks, and reading the worksheets behind them.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"abe": "./dist/cli.js"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"dist"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "tsc -p tsconfig.json",
|
|
17
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
18
18
|
"dev": "tsc -w",
|
|
19
19
|
"test": "vitest run",
|
|
20
20
|
"test:watch": "vitest",
|
package/dist/api.test.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
2
|
-
import { ApiClient, mapError } from './api.js';
|
|
3
|
-
import { EXIT } from './errors.js';
|
|
4
|
-
function mockFetch(status, body) {
|
|
5
|
-
return vi.fn().mockResolvedValue({
|
|
6
|
-
ok: status >= 200 && status < 300,
|
|
7
|
-
status,
|
|
8
|
-
text: async () => (body === undefined ? '' : JSON.stringify(body)),
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
describe('ApiClient.request', () => {
|
|
12
|
-
afterEach(() => vi.unstubAllGlobals());
|
|
13
|
-
it('sends the Bearer token, JSON headers, and the /api/v1 prefix', async () => {
|
|
14
|
-
const f = mockFetch(200, { boards: [] });
|
|
15
|
-
vi.stubGlobal('fetch', f);
|
|
16
|
-
await new ApiClient('http://h', 'abe_pat_x').listBoards();
|
|
17
|
-
expect(f).toHaveBeenCalledWith('http://h/api/v1/task_boards', expect.objectContaining({
|
|
18
|
-
method: 'GET',
|
|
19
|
-
headers: expect.objectContaining({
|
|
20
|
-
Authorization: 'Bearer abe_pat_x',
|
|
21
|
-
'Content-Type': 'application/json',
|
|
22
|
-
}),
|
|
23
|
-
}));
|
|
24
|
-
});
|
|
25
|
-
it('uses correct method/path/body for task mutations', async () => {
|
|
26
|
-
const f = mockFetch(200, { task: {} });
|
|
27
|
-
vi.stubGlobal('fetch', f);
|
|
28
|
-
const c = new ApiClient('http://h', 't');
|
|
29
|
-
await c.createTask({ title: 'x', task_board_id: 5 });
|
|
30
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks', expect.objectContaining({ method: 'POST', body: JSON.stringify({ title: 'x', task_board_id: 5 }) }));
|
|
31
|
-
await c.updateTask(9, { priority: 'P0' });
|
|
32
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks/9', expect.objectContaining({ method: 'PUT', body: JSON.stringify({ priority: 'P0' }) }));
|
|
33
|
-
await c.moveTask(9, 'review');
|
|
34
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks/9/move', expect.objectContaining({ method: 'POST', body: JSON.stringify({ column: 'review' }) }));
|
|
35
|
-
await c.completeTask(9);
|
|
36
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks/9/complete', expect.objectContaining({ method: 'POST' }));
|
|
37
|
-
});
|
|
38
|
-
it('uses correct method/path/body for comments, history, and delete', async () => {
|
|
39
|
-
const f = mockFetch(200, { comment: {} });
|
|
40
|
-
vi.stubGlobal('fetch', f);
|
|
41
|
-
const c = new ApiClient('http://h', 't');
|
|
42
|
-
// comment body is a FLAT top-level `body` param (not nested)
|
|
43
|
-
await c.addComment(9, 'shipped it');
|
|
44
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks/9/comments', expect.objectContaining({ method: 'POST', body: JSON.stringify({ body: 'shipped it' }) }));
|
|
45
|
-
await c.listComments(9);
|
|
46
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks/9/comments', expect.objectContaining({ method: 'GET' }));
|
|
47
|
-
await c.updateComment(9, 3, 'edited');
|
|
48
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks/9/comments/3', expect.objectContaining({ method: 'PATCH', body: JSON.stringify({ body: 'edited' }) }));
|
|
49
|
-
await c.deleteComment(9, 3);
|
|
50
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks/9/comments/3', expect.objectContaining({ method: 'DELETE' }));
|
|
51
|
-
await c.taskHistory(9);
|
|
52
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks/9/history', expect.objectContaining({ method: 'GET' }));
|
|
53
|
-
await c.deleteTask(9);
|
|
54
|
-
expect(f).toHaveBeenLastCalledWith('http://h/api/v1/tasks/9', expect.objectContaining({ method: 'DELETE' }));
|
|
55
|
-
});
|
|
56
|
-
it('builds the list query string including include_done and all', async () => {
|
|
57
|
-
const f = mockFetch(200, { tasks: [], total: 0 });
|
|
58
|
-
vi.stubGlobal('fetch', f);
|
|
59
|
-
await new ApiClient('http://h', 't').listTasks({ board_id: 5, all: true, include_done: true, status: undefined });
|
|
60
|
-
const url = f.mock.calls[0][0];
|
|
61
|
-
expect(url).toContain('/api/v1/tasks?');
|
|
62
|
-
expect(url).toContain('board_id=5');
|
|
63
|
-
expect(url).toContain('all=true');
|
|
64
|
-
expect(url).toContain('include_done=true');
|
|
65
|
-
expect(url).not.toContain('status=');
|
|
66
|
-
});
|
|
67
|
-
it('throws a network CliError when fetch rejects', async () => {
|
|
68
|
-
vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('boom')));
|
|
69
|
-
await expect(new ApiClient('http://h', 't').listBoards()).rejects.toMatchObject({ exitCode: EXIT.NETWORK });
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
describe('mapError', () => {
|
|
73
|
-
it('maps statuses to stable exit codes', () => {
|
|
74
|
-
expect(mapError(400, { error: 'bad' }).exitCode).toBe(EXIT.VALIDATION);
|
|
75
|
-
expect(mapError(401, {}).exitCode).toBe(EXIT.AUTH);
|
|
76
|
-
expect(mapError(403, { error: 'nope' }).exitCode).toBe(EXIT.FORBIDDEN);
|
|
77
|
-
expect(mapError(403, { error: 'nope' }).message).toBe('nope');
|
|
78
|
-
expect(mapError(404, {}).exitCode).toBe(EXIT.NOT_FOUND);
|
|
79
|
-
expect(mapError(422, { error: 'Invalid column' }).exitCode).toBe(EXIT.VALIDATION);
|
|
80
|
-
expect(mapError(422, { error: 'Invalid column' }).message).toBe('Invalid column');
|
|
81
|
-
expect(mapError(500, {}).exitCode).toBe(EXIT.SERVER);
|
|
82
|
-
expect(mapError(418, {}).exitCode).toBe(EXIT.GENERIC);
|
|
83
|
-
});
|
|
84
|
-
it('does NOT print the machine billing_locked token; uses reason instead', () => {
|
|
85
|
-
const e = mapError(402, { error: 'billing_locked', reason: 'trial_expired' });
|
|
86
|
-
expect(e.exitCode).toBe(EXIT.BILLING);
|
|
87
|
-
expect(e.message).not.toContain('billing_locked');
|
|
88
|
-
expect(e.message).toContain('trial_expired');
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
//# sourceMappingURL=api.test.js.map
|
package/dist/api.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.test.js","sourceRoot":"","sources":["../src/api.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import os from 'node:os';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
5
|
-
import { buildProgram, run } from '../index.js';
|
|
6
|
-
import { EXIT } from '../errors.js';
|
|
7
|
-
function okFetch(body) {
|
|
8
|
-
return vi.fn().mockResolvedValue({ ok: true, status: 200, text: async () => JSON.stringify(body) });
|
|
9
|
-
}
|
|
10
|
-
function errFetch(status, body) {
|
|
11
|
-
return vi.fn().mockResolvedValue({ ok: false, status, text: async () => JSON.stringify(body) });
|
|
12
|
-
}
|
|
13
|
-
let tmpDir;
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'abe-cli-auth-'));
|
|
16
|
-
process.env.ABE_CONFIG_DIR = tmpDir;
|
|
17
|
-
delete process.env.ABE_TOKEN;
|
|
18
|
-
delete process.env.ABE_API_URL;
|
|
19
|
-
});
|
|
20
|
-
afterEach(() => {
|
|
21
|
-
vi.unstubAllGlobals();
|
|
22
|
-
vi.restoreAllMocks();
|
|
23
|
-
delete process.env.ABE_CONFIG_DIR;
|
|
24
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
25
|
-
});
|
|
26
|
-
function readWrittenConfig() {
|
|
27
|
-
return JSON.parse(fs.readFileSync(path.join(tmpDir, 'config.json'), 'utf8'));
|
|
28
|
-
}
|
|
29
|
-
describe('auth login', () => {
|
|
30
|
-
// Regression: --token/--api-url were declared BOTH as program globals and on
|
|
31
|
-
// the login subcommand; the global swallowed the value while the subcommand's
|
|
32
|
-
// requiredOption still errored — `abe auth login --token X` could NEVER
|
|
33
|
-
// succeed. The flag now flows through optsWithGlobals in either position.
|
|
34
|
-
it('logs in with --token after the subcommand (the previously-broken form)', async () => {
|
|
35
|
-
const f = okFetch({ boards: [] });
|
|
36
|
-
vi.stubGlobal('fetch', f);
|
|
37
|
-
await buildProgram().parseAsync([
|
|
38
|
-
'node', 'abe', 'auth', 'login',
|
|
39
|
-
'--token', 'abe_pat_secret1234', '--api-url', 'http://h',
|
|
40
|
-
]);
|
|
41
|
-
expect(f).toHaveBeenCalledOnce();
|
|
42
|
-
expect(String(f.mock.calls[0][0])).toBe('http://h/api/v1/task_boards');
|
|
43
|
-
expect(f.mock.calls[0][1].headers).toMatchObject({
|
|
44
|
-
Authorization: 'Bearer abe_pat_secret1234',
|
|
45
|
-
});
|
|
46
|
-
expect(readWrittenConfig()).toMatchObject({ apiUrl: 'http://h', token: 'abe_pat_secret1234' });
|
|
47
|
-
});
|
|
48
|
-
it('logs in with the global --token before the subcommand', async () => {
|
|
49
|
-
vi.stubGlobal('fetch', okFetch({ boards: [] }));
|
|
50
|
-
await buildProgram().parseAsync([
|
|
51
|
-
'node', 'abe', '--token', 'abe_pat_secret1234', '--api-url', 'http://h',
|
|
52
|
-
'auth', 'login', '--tenant', 'acme',
|
|
53
|
-
]);
|
|
54
|
-
expect(readWrittenConfig()).toMatchObject({
|
|
55
|
-
apiUrl: 'http://h',
|
|
56
|
-
token: 'abe_pat_secret1234',
|
|
57
|
-
tenant: 'acme',
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
it('exits 2 with a usage hint when --token is missing', async () => {
|
|
61
|
-
const writes = [];
|
|
62
|
-
vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
|
|
63
|
-
writes.push(String(chunk));
|
|
64
|
-
return true;
|
|
65
|
-
});
|
|
66
|
-
const fetchSpy = vi.fn();
|
|
67
|
-
vi.stubGlobal('fetch', fetchSpy);
|
|
68
|
-
const code = await run(['node', 'abe', 'auth', 'login']);
|
|
69
|
-
expect(code).toBe(EXIT.USAGE);
|
|
70
|
-
expect(fetchSpy).not.toHaveBeenCalled();
|
|
71
|
-
expect(fs.existsSync(path.join(tmpDir, 'config.json'))).toBe(false);
|
|
72
|
-
const combined = writes.join('');
|
|
73
|
-
expect(combined).toContain('Missing --token');
|
|
74
|
-
expect(combined).toContain('abe auth login --token');
|
|
75
|
-
});
|
|
76
|
-
it('treats a 402 billing-locked probe as a successful login with a warning', async () => {
|
|
77
|
-
const writes = [];
|
|
78
|
-
vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
|
|
79
|
-
writes.push(String(chunk));
|
|
80
|
-
return true;
|
|
81
|
-
});
|
|
82
|
-
vi.stubGlobal('fetch', errFetch(402, { error: 'billing_locked' }));
|
|
83
|
-
await buildProgram().parseAsync([
|
|
84
|
-
'node', 'abe', 'auth', 'login', '--token', 'abe_pat_secret1234', '--api-url', 'http://h',
|
|
85
|
-
]);
|
|
86
|
-
expect(readWrittenConfig()).toMatchObject({ token: 'abe_pat_secret1234' });
|
|
87
|
-
expect(writes.join('')).toMatch(/locked for billing/i);
|
|
88
|
-
});
|
|
89
|
-
it('does not store the token when the probe rejects it (401)', async () => {
|
|
90
|
-
vi.stubGlobal('fetch', errFetch(401, { error: 'unauthorized' }));
|
|
91
|
-
const code = await run([
|
|
92
|
-
'node', 'abe', 'auth', 'login', '--token', 'abe_pat_wrong', '--api-url', 'http://h',
|
|
93
|
-
]);
|
|
94
|
-
expect(code).toBe(EXIT.AUTH);
|
|
95
|
-
expect(fs.existsSync(path.join(tmpDir, 'config.json'))).toBe(false);
|
|
96
|
-
});
|
|
97
|
-
it('never prints the full token', async () => {
|
|
98
|
-
const writes = [];
|
|
99
|
-
vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
|
|
100
|
-
writes.push(String(chunk));
|
|
101
|
-
return true;
|
|
102
|
-
});
|
|
103
|
-
vi.stubGlobal('fetch', okFetch({ boards: [] }));
|
|
104
|
-
await buildProgram().parseAsync([
|
|
105
|
-
'node', 'abe', 'auth', 'login', '--token', 'abe_pat_secret1234', '--api-url', 'http://h',
|
|
106
|
-
]);
|
|
107
|
-
const combined = writes.join('');
|
|
108
|
-
expect(combined).not.toContain('abe_pat_secret1234');
|
|
109
|
-
expect(combined).toContain('…1234');
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
describe('usage errors', () => {
|
|
113
|
-
// Regression: Commander writes usage errors to stderr itself (exitOverride
|
|
114
|
-
// only suppresses process.exit); run() used to write the message AGAIN, so
|
|
115
|
-
// every usage error appeared twice.
|
|
116
|
-
it('prints a commander usage error exactly once', async () => {
|
|
117
|
-
const writes = [];
|
|
118
|
-
vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
|
|
119
|
-
writes.push(String(chunk));
|
|
120
|
-
return true;
|
|
121
|
-
});
|
|
122
|
-
const code = await run(['node', 'abe', 'task', 'move', '99']);
|
|
123
|
-
expect(code).toBe(EXIT.USAGE);
|
|
124
|
-
const combined = writes.join('');
|
|
125
|
-
const occurrences = combined.match(/required option '--column <key>' not specified/g) ?? [];
|
|
126
|
-
expect(occurrences).toHaveLength(1);
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
//# sourceMappingURL=auth.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../../src/commands/auth.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { buildProgram } from '../index.js';
|
|
3
|
-
function okFetch(body) {
|
|
4
|
-
return vi.fn().mockResolvedValue({ ok: true, status: 200, text: async () => JSON.stringify(body) });
|
|
5
|
-
}
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
process.env.ABE_NO_CONFIG = '1';
|
|
8
|
-
});
|
|
9
|
-
afterEach(() => {
|
|
10
|
-
vi.unstubAllGlobals();
|
|
11
|
-
delete process.env.ABE_NO_CONFIG;
|
|
12
|
-
});
|
|
13
|
-
describe('board create', () => {
|
|
14
|
-
it('normalizes columns and posts a nested task_board payload', async () => {
|
|
15
|
-
const f = okFetch({ board: { id: 1, name: 'Eng', slug: 'eng', columns: [] } });
|
|
16
|
-
vi.stubGlobal('fetch', f);
|
|
17
|
-
await buildProgram().parseAsync([
|
|
18
|
-
'node', 'abe', 'board', 'create', 'Engineering',
|
|
19
|
-
'--columns', 'Backlog, In Progress, Done',
|
|
20
|
-
'--description', 'eng board',
|
|
21
|
-
'--token', 'abe_pat_x', '--api-url', 'http://h',
|
|
22
|
-
]);
|
|
23
|
-
const body = JSON.parse(f.mock.calls[0][1].body);
|
|
24
|
-
// Flat top-level params — the endpoint does NOT accept a { task_board: ... } wrapper.
|
|
25
|
-
expect(body).toEqual({
|
|
26
|
-
name: 'Engineering',
|
|
27
|
-
description: 'eng board',
|
|
28
|
-
columns: ['backlog', 'in_progress', 'done'],
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
//# sourceMappingURL=boards.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"boards.test.js","sourceRoot":"","sources":["../../src/commands/boards.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,SAAS,OAAO,CAAC,IAAa;IAC5B,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAc,CAAC,CAAA;AACjH,CAAC;AAED,UAAU,CAAC,GAAG,EAAE;IACd,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,GAAG,CAAA;AACjC,CAAC,CAAC,CAAA;AACF,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,gBAAgB,EAAE,CAAA;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAA;AAClC,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAC9E,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACzB,MAAM,YAAY,EAAE,CAAC,UAAU,CAAC;YAC9B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa;YAC/C,WAAW,EAAE,4BAA4B;YACzC,eAAe,EAAE,WAAW;YAC5B,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU;SAChD,CAAC,CAAA;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAiB,CAAC,IAAc,CAAC,CAAA;QAC3E,sFAAsF;QACtF,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,WAAW;YACxB,OAAO,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,MAAM,CAAC;SAC5C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { buildProgram } from '../index.js';
|
|
3
|
-
import { EXIT } from '../errors.js';
|
|
4
|
-
// Parse-and-run helper: runs a command line through the real program with a
|
|
5
|
-
// stubbed fetch, returning the captured fetch mock.
|
|
6
|
-
function run(argv, fetchImpl) {
|
|
7
|
-
vi.stubGlobal('fetch', fetchImpl);
|
|
8
|
-
return buildProgram().parseAsync(['node', 'abe', ...argv, '--token', 'abe_pat_x', '--api-url', 'http://h']);
|
|
9
|
-
}
|
|
10
|
-
function okFetch(body) {
|
|
11
|
-
return vi.fn().mockResolvedValue({ ok: true, status: 200, text: async () => JSON.stringify(body) });
|
|
12
|
-
}
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
process.env.ABE_NO_CONFIG = '1';
|
|
15
|
-
});
|
|
16
|
-
afterEach(() => {
|
|
17
|
-
vi.unstubAllGlobals();
|
|
18
|
-
delete process.env.ABE_NO_CONFIG;
|
|
19
|
-
});
|
|
20
|
-
describe('task create', () => {
|
|
21
|
-
it('maps flags to the exact create_params keys', async () => {
|
|
22
|
-
const f = okFetch({ task: { id: 1, title: 'x' } });
|
|
23
|
-
await run([
|
|
24
|
-
'task', 'create', 'Ship it',
|
|
25
|
-
'--board', '5',
|
|
26
|
-
'--type', 'bug',
|
|
27
|
-
'--priority', 'P1',
|
|
28
|
-
'--size', 'M',
|
|
29
|
-
'--labels', 'backend, security',
|
|
30
|
-
'--assignee', 'matt@viewcy.com',
|
|
31
|
-
'--due', '2026-07-01',
|
|
32
|
-
], f);
|
|
33
|
-
const [, init] = f.mock.calls[0];
|
|
34
|
-
const body = JSON.parse(init.body);
|
|
35
|
-
expect(body).toMatchObject({
|
|
36
|
-
title: 'Ship it',
|
|
37
|
-
task_board_id: 5,
|
|
38
|
-
task_type: 'bug',
|
|
39
|
-
priority: 'P1',
|
|
40
|
-
size: 'M',
|
|
41
|
-
labels: ['backend', 'security'],
|
|
42
|
-
assignee_email: 'matt@viewcy.com',
|
|
43
|
-
due_date: '2026-07-01',
|
|
44
|
-
source: 'abe_cli',
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
it('passes --assignee-id as assignee_id and omits assignee_email', async () => {
|
|
48
|
-
const f = okFetch({ task: { id: 1 } });
|
|
49
|
-
await run(['task', 'create', 'x', '--board', '5', '--assignee-id', '42'], f);
|
|
50
|
-
const body = JSON.parse(f.mock.calls[0][1].body);
|
|
51
|
-
expect(body.assignee_id).toBe(42);
|
|
52
|
-
expect(body.assignee_email).toBeUndefined();
|
|
53
|
-
});
|
|
54
|
-
it('rejects an invalid --priority before any fetch (exit 2)', async () => {
|
|
55
|
-
const f = okFetch({});
|
|
56
|
-
await expect(run(['task', 'create', 'x', '--board', '5', '--priority', 'nope'], f)).rejects.toMatchObject({
|
|
57
|
-
exitCode: EXIT.USAGE,
|
|
58
|
-
});
|
|
59
|
-
expect(f).not.toHaveBeenCalled();
|
|
60
|
-
});
|
|
61
|
-
it('does not client-validate --column (relies on the server 422)', async () => {
|
|
62
|
-
const f = okFetch({ task: { id: 1 } });
|
|
63
|
-
await run(['task', 'create', 'x', '--board', '5', '--column', 'Weird Column'], f);
|
|
64
|
-
const body = JSON.parse(f.mock.calls[0][1].body);
|
|
65
|
-
expect(body.board_column).toBe('weird_column'); // normalized, not rejected
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
describe('task update / move', () => {
|
|
69
|
-
it('sends only the provided fields', async () => {
|
|
70
|
-
const f = okFetch({ task: { id: 7 } });
|
|
71
|
-
await run(['task', 'update', '7', '--priority', 'P0'], f);
|
|
72
|
-
const url = f.mock.calls[0][0];
|
|
73
|
-
const body = JSON.parse(f.mock.calls[0][1].body);
|
|
74
|
-
expect(url).toBe('http://h/api/v1/tasks/7');
|
|
75
|
-
expect(body).toEqual({ priority: 'P0' });
|
|
76
|
-
});
|
|
77
|
-
it('move without --column errors before any fetch', async () => {
|
|
78
|
-
const f = okFetch({});
|
|
79
|
-
// Commander rejects the missing required option during parse (main() maps it
|
|
80
|
-
// to exit 2); the action — and therefore fetch — never runs.
|
|
81
|
-
await expect(run(['task', 'move', '7'], f)).rejects.toBeTruthy();
|
|
82
|
-
expect(f).not.toHaveBeenCalled();
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
//# sourceMappingURL=tasks.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.test.js","sourceRoot":"","sources":["../../src/commands/tasks.test.ts"],"names":[],"mappings":"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"}
|
package/dist/config.test.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { resolveSettings, requireToken, redactToken, writeConfig, readConfig, configFile } from './config.js';
|
|
6
|
-
import { CliError, EXIT } from './errors.js';
|
|
7
|
-
describe('resolveSettings precedence', () => {
|
|
8
|
-
const env = { ABE_NO_CONFIG: '1' }; // ignore any real ~/.abe during unit tests
|
|
9
|
-
it('defaults the apiUrl when nothing is set', () => {
|
|
10
|
-
expect(resolveSettings({}, env).apiUrl).toBe('https://api.abe.ing');
|
|
11
|
-
});
|
|
12
|
-
it('prefers flag > env for each key', () => {
|
|
13
|
-
const e = { ...env, ABE_API_URL: 'http://env', ABE_TOKEN: 'env-tok', ABE_TENANT: 'env-ten' };
|
|
14
|
-
expect(resolveSettings({ apiUrl: 'http://flag', token: 'flag-tok', tenant: 'flag-ten' }, e)).toEqual({
|
|
15
|
-
apiUrl: 'http://flag',
|
|
16
|
-
token: 'flag-tok',
|
|
17
|
-
tenant: 'flag-ten',
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
it('falls back to env when no flag', () => {
|
|
21
|
-
const e = { ...env, ABE_API_URL: 'http://env', ABE_TOKEN: 'env-tok' };
|
|
22
|
-
const s = resolveSettings({}, e);
|
|
23
|
-
expect(s.apiUrl).toBe('http://env');
|
|
24
|
-
expect(s.token).toBe('env-tok');
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
describe('requireToken', () => {
|
|
28
|
-
it('throws EXIT.AUTH when no token', () => {
|
|
29
|
-
try {
|
|
30
|
-
requireToken({ apiUrl: 'x' });
|
|
31
|
-
throw new Error('should have thrown');
|
|
32
|
-
}
|
|
33
|
-
catch (e) {
|
|
34
|
-
expect(e).toBeInstanceOf(CliError);
|
|
35
|
-
expect(e.exitCode).toBe(EXIT.AUTH);
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
it('returns the token when present', () => {
|
|
39
|
-
expect(requireToken({ apiUrl: 'x', token: 'abe_pat_z' })).toBe('abe_pat_z');
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
describe('redactToken', () => {
|
|
43
|
-
it('reveals only the last 4 chars', () => {
|
|
44
|
-
expect(redactToken('abe_pat_abcdEFGH')).toBe('abe_pat_…EFGH');
|
|
45
|
-
expect(redactToken(undefined)).toBe('(none)');
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
describe('config file', () => {
|
|
49
|
-
let tmp;
|
|
50
|
-
beforeEach(() => {
|
|
51
|
-
tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'abe-cli-'));
|
|
52
|
-
process.env.ABE_CONFIG_DIR = tmp; // never touch the real ~/.abe
|
|
53
|
-
});
|
|
54
|
-
afterEach(() => {
|
|
55
|
-
delete process.env.ABE_CONFIG_DIR;
|
|
56
|
-
fs.rmSync(tmp, { recursive: true, force: true });
|
|
57
|
-
});
|
|
58
|
-
it('readConfig tolerates a missing or garbage file', () => {
|
|
59
|
-
expect(readConfig()).toEqual({});
|
|
60
|
-
fs.writeFileSync(configFile(), 'not json');
|
|
61
|
-
expect(readConfig()).toEqual({});
|
|
62
|
-
});
|
|
63
|
-
it('writeConfig persists 0600 and round-trips', () => {
|
|
64
|
-
writeConfig({ apiUrl: 'http://x', token: 'abe_pat_secret', tenant: 't' });
|
|
65
|
-
const mode = fs.statSync(configFile()).mode & 0o777;
|
|
66
|
-
expect(mode).toBe(0o600);
|
|
67
|
-
expect(readConfig()).toEqual({ apiUrl: 'http://x', token: 'abe_pat_secret', tenant: 't' });
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
//# sourceMappingURL=config.test.js.map
|
package/dist/config.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../src/config.test.ts"],"names":[],"mappings":"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"}
|
package/dist/output.test.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { buildProgram } from './index.js';
|
|
3
|
-
function fetchReturning(status, body) {
|
|
4
|
-
return vi.fn().mockResolvedValue({
|
|
5
|
-
ok: status >= 200 && status < 300,
|
|
6
|
-
status,
|
|
7
|
-
text: async () => JSON.stringify(body),
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
let outChunks;
|
|
11
|
-
let errChunks;
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
process.env.ABE_NO_CONFIG = '1';
|
|
14
|
-
outChunks = [];
|
|
15
|
-
errChunks = [];
|
|
16
|
-
vi.spyOn(process.stdout, 'write').mockImplementation((c) => {
|
|
17
|
-
outChunks.push(String(c));
|
|
18
|
-
return true;
|
|
19
|
-
});
|
|
20
|
-
vi.spyOn(process.stderr, 'write').mockImplementation((c) => {
|
|
21
|
-
errChunks.push(String(c));
|
|
22
|
-
return true;
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
afterEach(() => {
|
|
26
|
-
vi.unstubAllGlobals();
|
|
27
|
-
vi.restoreAllMocks();
|
|
28
|
-
delete process.env.ABE_NO_CONFIG;
|
|
29
|
-
});
|
|
30
|
-
describe('--json output is stdout-pure', () => {
|
|
31
|
-
it('writes ONLY valid JSON to stdout for board list', async () => {
|
|
32
|
-
vi.stubGlobal('fetch', fetchReturning(200, { boards: [{ id: 1, name: 'Eng', slug: 'eng', columns: ['todo'] }] }));
|
|
33
|
-
await buildProgram().parseAsync(['node', 'abe', '--json', 'board', 'list', '--token', 'abe_pat_secret', '--api-url', 'http://h']);
|
|
34
|
-
const stdout = outChunks.join('');
|
|
35
|
-
expect(() => JSON.parse(stdout)).not.toThrow();
|
|
36
|
-
expect(JSON.parse(stdout)).toEqual({ boards: [{ id: 1, name: 'Eng', slug: 'eng', columns: ['todo'] }] });
|
|
37
|
-
});
|
|
38
|
-
it('never leaks the token to stdout or stderr, even on a 401', async () => {
|
|
39
|
-
vi.stubGlobal('fetch', fetchReturning(401, { error: 'Unauthorized' }));
|
|
40
|
-
await buildProgram()
|
|
41
|
-
.parseAsync(['node', 'abe', 'board', 'list', '--token', 'abe_pat_secret', '--api-url', 'http://h'])
|
|
42
|
-
.catch(() => {
|
|
43
|
-
/* expected to reject — assert on captured output below */
|
|
44
|
-
});
|
|
45
|
-
const all = outChunks.join('') + errChunks.join('');
|
|
46
|
-
expect(all).not.toContain('abe_pat_secret');
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
//# sourceMappingURL=output.test.js.map
|
package/dist/output.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"output.test.js","sourceRoot":"","sources":["../src/output.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,SAAS,cAAc,CAAC,MAAc,EAAE,IAAa;IACnD,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;QAC/B,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG;QACjC,MAAM;QACN,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAA;AAChB,CAAC;AAED,IAAI,SAAmB,CAAA;AACvB,IAAI,SAAmB,CAAA;AAEvB,UAAU,CAAC,GAAG,EAAE;IACd,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,GAAG,CAAA;IAC/B,SAAS,GAAG,EAAE,CAAA;IACd,SAAS,GAAG,EAAE,CAAA;IACd,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAsB,EAAE,EAAE;QAC9E,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;IACF,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAsB,EAAE,EAAE;QAC9E,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AACF,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,gBAAgB,EAAE,CAAA;IACrB,EAAE,CAAC,eAAe,EAAE,CAAA;IACpB,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAA;AAClC,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QACjH,MAAM,YAAY,EAAE,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAA;QACjI,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACjC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;QAC9C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAC1G,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAA;QACtE,MAAM,YAAY,EAAE;aACjB,UAAU,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;aAClG,KAAK,CAAC,GAAG,EAAE;YACV,0DAA0D;QAC5D,CAAC,CAAC,CAAA;QACJ,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACnD,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|