@corelayer-ai/cli 0.4.4 → 0.4.5
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/dist/commands/issues.js +85 -13
- package/dist/lib/api-client.js +12 -3
- package/package.json +2 -2
- package/skill/SKILL.md +27 -4
package/dist/commands/issues.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { createInterface } from "node:readline/promises";
|
|
2
1
|
import { stdin as input, stdout as output } from "node:process";
|
|
2
|
+
import { createInterface } from "node:readline/promises";
|
|
3
3
|
import { CorelayerClient } from "../lib/api-client.js";
|
|
4
|
-
import { readConfig,
|
|
4
|
+
import { readConfig, resolveApiUrl, resolveToken } from "../lib/config.js";
|
|
5
5
|
import { fail, formatDate, printJson, printTable } from "../lib/output.js";
|
|
6
6
|
function readFlag(args, flag) {
|
|
7
7
|
const index = args.indexOf(flag);
|
|
@@ -27,7 +27,9 @@ function removeFlags(args) {
|
|
|
27
27
|
arg === "--page" ||
|
|
28
28
|
arg === "--feedback" ||
|
|
29
29
|
arg === "--last-seen-before" ||
|
|
30
|
-
arg === "--last-seen-before-or-on"
|
|
30
|
+
arg === "--last-seen-before-or-on" ||
|
|
31
|
+
arg === "--since" ||
|
|
32
|
+
arg === "--duration") {
|
|
31
33
|
skipNext = true;
|
|
32
34
|
continue;
|
|
33
35
|
}
|
|
@@ -55,8 +57,9 @@ USAGE:
|
|
|
55
57
|
|
|
56
58
|
SUBCOMMANDS:
|
|
57
59
|
list List issues in a group
|
|
58
|
-
get <id>
|
|
60
|
+
get <id|slug> Show details for one issue
|
|
59
61
|
summary Summarize issue health for a group
|
|
62
|
+
diff Show issues new or changed since a timestamp
|
|
60
63
|
close <id> Close an issue (write operation)
|
|
61
64
|
bulk-close Close many issues in one request (write operation)
|
|
62
65
|
reopen <id> Reopen a closed issue (write operation)
|
|
@@ -66,25 +69,49 @@ OPTIONS:
|
|
|
66
69
|
--group <id> Group ID (or set default-group via 'corelayer config set')
|
|
67
70
|
--status <status> Filter by status (list)
|
|
68
71
|
--severity <sev> Filter by severity (list)
|
|
69
|
-
--limit <n> Limit results (list)
|
|
70
|
-
--page <n> Page number (list)
|
|
72
|
+
--limit <n> Limit results (list, diff)
|
|
73
|
+
--page <n> Page number (list, diff)
|
|
71
74
|
--feedback <text> Feedback message (close)
|
|
72
75
|
--last-seen-before <date|preset>
|
|
73
76
|
Filter bulk-close to issues seen before a cutoff
|
|
74
77
|
--last-seen-before-or-on <date|preset>
|
|
75
78
|
Filter bulk-close to issues seen on or before a cutoff
|
|
79
|
+
--since <timestamp|preset>
|
|
80
|
+
Diff: ISO 8601 timestamp or preset (1hour, 24hours, 7days, 14days, 30days)
|
|
81
|
+
--duration <duration>
|
|
82
|
+
Diff: human-friendly duration (e.g. 2hours, 4hours, 30m, 1d)
|
|
76
83
|
--yes Skip confirmation prompt (delete)
|
|
77
84
|
--json Output as JSON
|
|
78
85
|
-h, --help Print help
|
|
79
86
|
|
|
80
87
|
EXAMPLES:
|
|
81
88
|
corelayer issues list --group g_123 --status Open
|
|
82
|
-
corelayer issues get
|
|
89
|
+
corelayer issues get corelayer-prod-engine-20260602-1 --json
|
|
90
|
+
corelayer issues diff --group g_123 --since 2026-06-01T00:00:00Z
|
|
91
|
+
corelayer issues diff --group g_123 --since 24hours
|
|
92
|
+
corelayer issues diff --group g_123 --duration 2hours --limit 50
|
|
83
93
|
corelayer issues close i_456 --feedback "fixed in deploy 2026-04-07"
|
|
84
94
|
corelayer issues bulk-close --group g_123 --last-seen-before-or-on 14days --feedback "Not seen in two weeks"
|
|
85
95
|
corelayer issues delete i_456 --yes
|
|
86
96
|
`);
|
|
87
97
|
}
|
|
98
|
+
function parseDuration(value) {
|
|
99
|
+
const match = value
|
|
100
|
+
.trim()
|
|
101
|
+
.toLowerCase()
|
|
102
|
+
.match(/^(\d+(?:\.\d+)?)\s*(m|min|minutes?|h|hr|hours?|d|days?)$/);
|
|
103
|
+
if (!match)
|
|
104
|
+
return null;
|
|
105
|
+
const n = parseFloat(match[1]);
|
|
106
|
+
const unit = match[2];
|
|
107
|
+
if (unit.startsWith("m"))
|
|
108
|
+
return Math.round(n * 60 * 1000);
|
|
109
|
+
if (unit.startsWith("h"))
|
|
110
|
+
return Math.round(n * 60 * 60 * 1000);
|
|
111
|
+
if (unit.startsWith("d"))
|
|
112
|
+
return Math.round(n * 24 * 60 * 60 * 1000);
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
88
115
|
export async function runIssues(args, ctx) {
|
|
89
116
|
if (args.includes("--help") || args.includes("-h")) {
|
|
90
117
|
printHelp();
|
|
@@ -114,7 +141,7 @@ export async function runIssues(args, ctx) {
|
|
|
114
141
|
printJson(result);
|
|
115
142
|
return;
|
|
116
143
|
}
|
|
117
|
-
const rows = result.issues.map(issue => [
|
|
144
|
+
const rows = result.issues.map((issue) => [
|
|
118
145
|
issue.id,
|
|
119
146
|
issue.slug || "-",
|
|
120
147
|
issue.severity || "-",
|
|
@@ -129,11 +156,11 @@ export async function runIssues(args, ctx) {
|
|
|
129
156
|
return;
|
|
130
157
|
}
|
|
131
158
|
if (sub === "get") {
|
|
132
|
-
const
|
|
133
|
-
if (!
|
|
134
|
-
fail("Usage: corelayer issues get <issueId>");
|
|
159
|
+
const issueIdentifier = commandArgs[0];
|
|
160
|
+
if (!issueIdentifier) {
|
|
161
|
+
fail("Usage: corelayer issues get <issueId|slug>");
|
|
135
162
|
}
|
|
136
|
-
const issue = await client.getIssue(
|
|
163
|
+
const issue = await client.getIssue(issueIdentifier);
|
|
137
164
|
if (ctx.json) {
|
|
138
165
|
printJson(issue);
|
|
139
166
|
return;
|
|
@@ -239,5 +266,50 @@ export async function runIssues(args, ctx) {
|
|
|
239
266
|
printJson(summary);
|
|
240
267
|
return;
|
|
241
268
|
}
|
|
242
|
-
|
|
269
|
+
if (sub === "diff") {
|
|
270
|
+
const groupId = readFlag(args, "--group") || config.defaults?.group;
|
|
271
|
+
if (!groupId) {
|
|
272
|
+
fail("groupId is required. Use --group <groupId> or set default-group via corelayer config set default-group <groupId>");
|
|
273
|
+
}
|
|
274
|
+
const sinceFlag = readFlag(args, "--since");
|
|
275
|
+
const durationFlag = readFlag(args, "--duration");
|
|
276
|
+
if (!sinceFlag && !durationFlag) {
|
|
277
|
+
fail("One of --since <timestamp|preset> or --duration <duration> is required.\n" +
|
|
278
|
+
"Examples: --since 2026-06-01T00:00:00Z --since 24hours --duration 2hours");
|
|
279
|
+
}
|
|
280
|
+
let sinceValue;
|
|
281
|
+
if (durationFlag) {
|
|
282
|
+
const ms = parseDuration(durationFlag);
|
|
283
|
+
if (ms === null) {
|
|
284
|
+
fail(`Invalid --duration value: "${durationFlag}". Examples: 30m, 2hours, 4h, 1d, 7days`);
|
|
285
|
+
}
|
|
286
|
+
sinceValue = new Date(Date.now() - ms).toISOString();
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
sinceValue = sinceFlag;
|
|
290
|
+
}
|
|
291
|
+
const result = await client.diffIssues(groupId, sinceValue, {
|
|
292
|
+
limit: readFlag(args, "--limit"),
|
|
293
|
+
page: readFlag(args, "--page"),
|
|
294
|
+
});
|
|
295
|
+
if (ctx.json) {
|
|
296
|
+
printJson(result);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
process.stdout.write(`DIFF SINCE ${result.since}\n`);
|
|
300
|
+
const rows = result.issues.map((issue) => [
|
|
301
|
+
issue.id,
|
|
302
|
+
issue.slug || "-",
|
|
303
|
+
issue.severity || "-",
|
|
304
|
+
issue.status || "-",
|
|
305
|
+
issue.title || "-",
|
|
306
|
+
formatDate(issue.last_seen_at || issue.lastSeenAt),
|
|
307
|
+
]);
|
|
308
|
+
printTable(["ID", "SLUG", "SEVERITY", "STATUS", "TITLE", "LAST SEEN"], rows);
|
|
309
|
+
if (!ctx.quiet) {
|
|
310
|
+
process.stdout.write(`${result.total} issue${result.total === 1 ? "" : "s"} changed since ${result.since}\n`);
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
fail("Usage: corelayer issues <list|get|close|bulk-close|reopen|delete|summary|diff> [options]");
|
|
243
315
|
}
|
package/dist/lib/api-client.js
CHANGED
|
@@ -94,6 +94,15 @@ export class CorelayerClient {
|
|
|
94
94
|
async deleteIssue(issueId) {
|
|
95
95
|
await this.request("DELETE", `/api/v1/issues/${issueId}`);
|
|
96
96
|
}
|
|
97
|
+
async diffIssues(groupId, since, options = {}) {
|
|
98
|
+
const params = new URLSearchParams({ groupId, since });
|
|
99
|
+
for (const [key, value] of Object.entries(options)) {
|
|
100
|
+
if (value !== undefined && value !== null && value !== "") {
|
|
101
|
+
params.set(key, String(value));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return this.request("GET", `/api/v1/issues/diff?${params.toString()}`);
|
|
105
|
+
}
|
|
97
106
|
async getIssueSummary(groupId) {
|
|
98
107
|
const params = new URLSearchParams({ groupId });
|
|
99
108
|
return this.request("GET", `/api/v1/issues/summary?${params.toString()}`);
|
|
@@ -130,13 +139,13 @@ export class CorelayerClient {
|
|
|
130
139
|
const suffix = params.toString() ? `?${params.toString()}` : "";
|
|
131
140
|
const raw = await this.request("GET", `/api/v1/integrations/accounts${suffix}`);
|
|
132
141
|
return {
|
|
133
|
-
accounts: (raw.accounts ?? []).map(account => ({
|
|
142
|
+
accounts: (raw.accounts ?? []).map((account) => ({
|
|
134
143
|
id: account.id,
|
|
135
144
|
group_id: account.group_id,
|
|
136
145
|
provider_code: account.provider_code,
|
|
137
146
|
is_active: account.is_active,
|
|
138
147
|
created_at: account.created_at,
|
|
139
|
-
resources: (account.resources ?? []).map(resource => ({
|
|
148
|
+
resources: (account.resources ?? []).map((resource) => ({
|
|
140
149
|
id: resource.id,
|
|
141
150
|
resource_type: resource.resource_type,
|
|
142
151
|
external_id: resource.external_id,
|
|
@@ -144,7 +153,7 @@ export class CorelayerClient {
|
|
|
144
153
|
is_active: resource.is_active,
|
|
145
154
|
})),
|
|
146
155
|
})),
|
|
147
|
-
providers: (raw.providers ?? []).map(provider => ({
|
|
156
|
+
providers: (raw.providers ?? []).map((provider) => ({
|
|
148
157
|
provider_code: provider.provider_code,
|
|
149
158
|
display_name: provider.display_name,
|
|
150
159
|
})),
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -37,12 +37,23 @@ corelayer issues list --status open
|
|
|
37
37
|
### Inspect a specific issue
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
corelayer issues get <issueId>
|
|
41
|
-
corelayer issues get <issueId> --json
|
|
40
|
+
corelayer issues get <issueId|slug>
|
|
41
|
+
corelayer issues get <issueId|slug> --json
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
Returns: title, status, severity, event count, what happened, root cause, and next steps.
|
|
45
45
|
|
|
46
|
+
### Diff issues since a timestamp (post-deploy triage)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
corelayer issues diff --group <groupId> --since 2026-06-01T00:00:00Z
|
|
50
|
+
corelayer issues diff --group <groupId> --since 24hours
|
|
51
|
+
corelayer issues diff --group <groupId> --duration 2hours --limit 50
|
|
52
|
+
corelayer issues diff --group <groupId> --duration 30m --json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Returns issues that are new or changed since the given timestamp. Useful after PR merges/deploys to identify regressions or newly surfaced issues.
|
|
56
|
+
|
|
46
57
|
### Triage issues
|
|
47
58
|
|
|
48
59
|
```bash
|
|
@@ -84,7 +95,7 @@ Setting a default group avoids repeating `--group` on every command.
|
|
|
84
95
|
List issues for a group. Requires `--group` or a configured default group.
|
|
85
96
|
Filterable by status (`open`, `closed`) and severity (`critical`, `high`, `medium`, `low`).
|
|
86
97
|
|
|
87
|
-
### `corelayer issues get <issueId>`
|
|
98
|
+
### `corelayer issues get <issueId|slug>`
|
|
88
99
|
|
|
89
100
|
Get full details for an issue including AI-generated analysis: what happened, root cause, and next steps.
|
|
90
101
|
|
|
@@ -92,6 +103,18 @@ Get full details for an issue including AI-generated analysis: what happened, ro
|
|
|
92
103
|
|
|
93
104
|
Returns a JSON severity breakdown for the group.
|
|
94
105
|
|
|
106
|
+
### `corelayer issues diff --group <id> (--since <timestamp|preset> | --duration <duration>) [--limit <n>] [--page <n>]`
|
|
107
|
+
|
|
108
|
+
Returns issues that are new or updated since the given point in time. Useful for post-deploy triage — run after a PR merge to see what regressions or new errors have surfaced.
|
|
109
|
+
|
|
110
|
+
`--since` accepts an ISO 8601 timestamp (`2026-06-01T00:00:00Z`) or a preset: `1hour`, `24hours`, `7days`, `14days`, `30days`.
|
|
111
|
+
|
|
112
|
+
`--duration` accepts human-friendly durations: `30m`, `2hours`, `4h`, `1d`, `7days`. The duration is subtracted from the current time to compute the since-timestamp.
|
|
113
|
+
|
|
114
|
+
`--limit` and `--page` paginate results. The API defaults to 20 results and caps `--limit` at 100.
|
|
115
|
+
|
|
116
|
+
Use `--json` for machine-readable output suitable for agent automation.
|
|
117
|
+
|
|
95
118
|
### `corelayer issues close <issueId> [--feedback "..."]`
|
|
96
119
|
|
|
97
120
|
Close an issue. Optionally provide feedback (e.g., link to the fix).
|
|
@@ -139,7 +162,7 @@ Clear stored credentials.
|
|
|
139
162
|
```bash
|
|
140
163
|
corelayer issues summary
|
|
141
164
|
corelayer issues list --severity critical
|
|
142
|
-
corelayer issues get <
|
|
165
|
+
corelayer issues get <issueId|slug> --json
|
|
143
166
|
```
|
|
144
167
|
|
|
145
168
|
### Scripting and automation
|