@corelayer-ai/cli 0.5.1 → 0.5.3

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.
@@ -0,0 +1,51 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { CorelayerClient } from "../lib/api-client.js";
3
+ import { readFlag } from "../lib/args.js";
4
+ import { resolveApiUrl, resolveToken } from "../lib/config.js";
5
+ import { fail, printJson } from "../lib/output.js";
6
+ export async function runSchedules(args, ctx) {
7
+ if (args.includes("--help") || args.includes("-h")) {
8
+ process.stdout.write(`corelayer schedules - Manage native scheduled tasks\n\nUSAGE:\n corelayer schedules list --group <id>\n corelayer schedules create --group <id> --file schedule.json\n corelayer schedules update <id> --group <id> --file patch.json\n corelayer schedules pause|resume|delete|runs <id> --group <id>\n\nCREATE FILE:\n {"label":"Daily review","prompt":"Review open issues","schedule_kind":"cron","schedule_expr":"0 9 * * 1-5","timezone":"America/New_York","is_enabled":true}\n\nRun output is saved in Monitoring > Schedules. Jobs are scoped to the selected group.\n`);
9
+ return;
10
+ }
11
+ const action = args[0], group = readFlag(args, "--group"), id = args[1];
12
+ if (!group || group.startsWith("--"))
13
+ fail("Provide --group <id>.");
14
+ if (!["list", "create", "update", "pause", "resume", "delete", "runs"].includes(action))
15
+ fail("Run corelayer schedules --help for usage.");
16
+ if (!["list", "create"].includes(action) && (!id || id.startsWith("--")))
17
+ fail("Provide a schedule id.");
18
+ const token = resolveToken();
19
+ if (!token)
20
+ fail("Not authenticated. Run corelayer login.");
21
+ const client = new CorelayerClient(resolveApiUrl(ctx.apiUrlOverride), token);
22
+ const query = `?groupId=${encodeURIComponent(group)}`, target = `/${encodeURIComponent(id ?? "")}`;
23
+ const body = readScheduleBody(action, args);
24
+ const result = action === "list"
25
+ ? await client.scheduleRequest("GET", query)
26
+ : action === "runs"
27
+ ? await client.scheduleRequest("GET", `${target}/runs${query}`)
28
+ : action === "delete"
29
+ ? await client.scheduleRequest("DELETE", `${target}${query}`)
30
+ : await client.scheduleRequest(action === "create" ? "POST" : "PATCH", action === "create" ? "" : target, {
31
+ ...body,
32
+ groupId: group,
33
+ ...(action === "pause" || action === "resume"
34
+ ? { is_enabled: action === "resume" }
35
+ : {}),
36
+ });
37
+ printJson(result);
38
+ }
39
+ function readScheduleBody(action, args) {
40
+ let body = {};
41
+ if (action === "create" || action === "update") {
42
+ const file = readFlag(args, "--file");
43
+ if (!file || file.startsWith("--"))
44
+ fail("Provide --file <JSON file>.");
45
+ const parsed = JSON.parse(readFileSync(file, "utf8"));
46
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
47
+ fail("The file must contain a JSON object.");
48
+ body = parsed;
49
+ }
50
+ return body;
51
+ }
package/dist/index.js CHANGED
@@ -1,14 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { runApiKeys } from "./commands/api-keys.js";
3
2
  import { createRequire } from "node:module";
3
+ import { runAnomalies } from "./commands/anomalies.js";
4
+ import { runApiKeys } from "./commands/api-keys.js";
4
5
  import { runConfig } from "./commands/config.js";
5
6
  import { runGroups } from "./commands/groups.js";
7
+ import { runInstallSkill, runUninstallSkill, } from "./commands/install-skill.js";
6
8
  import { runIntegrations } from "./commands/integrations.js";
7
9
  import { runIssues } from "./commands/issues.js";
8
- import { runInstallSkill, runUninstallSkill, } from "./commands/install-skill.js";
9
10
  import { runLogin } from "./commands/login.js";
10
11
  import { runLogout } from "./commands/logout.js";
11
12
  import { runPreflight } from "./commands/preflight.js";
13
+ import { runSchedules } from "./commands/schedules.js";
12
14
  const require = createRequire(import.meta.url);
13
15
  const { version } = require("../package.json");
14
16
  function printHelp() {
@@ -24,6 +26,8 @@ COMMANDS:
24
26
  api-keys Create Corelayer API keys
25
27
  groups List and inspect groups
26
28
  issues List, inspect, and manage issues
29
+ schedules Create and manage native scheduled tasks
30
+ anomalies List and inspect configured anomaly monitors
27
31
  preflight Check a change against org memory before you push
28
32
  integrations List integrations for a group
29
33
  config Read and write local CLI config
@@ -112,6 +116,12 @@ async function main() {
112
116
  case "issues":
113
117
  await runIssues(rest, ctx);
114
118
  return;
119
+ case "anomalies":
120
+ await runAnomalies(rest, ctx);
121
+ return;
122
+ case "schedules":
123
+ await runSchedules(rest, ctx);
124
+ break;
115
125
  case "groups":
116
126
  await runGroups(rest, ctx);
117
127
  return;
@@ -139,7 +149,7 @@ async function main() {
139
149
  process.exit(1);
140
150
  }
141
151
  }
142
- main().catch(error => {
152
+ main().catch((error) => {
143
153
  process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
144
154
  process.exit(1);
145
155
  });
@@ -1,3 +1,4 @@
1
+ import { AnomalyApiClient } from "@corelayer-ai/sdk";
1
2
  async function parseError(res) {
2
3
  let body = null;
3
4
  try {
@@ -18,13 +19,15 @@ async function parseError(res) {
18
19
  export class CorelayerClient {
19
20
  baseUrl;
20
21
  token;
22
+ anomalies;
21
23
  constructor(baseUrl, token) {
22
24
  this.baseUrl = baseUrl;
23
25
  this.token = token;
26
+ this.anomalies = new AnomalyApiClient((method, path) => this.request(method, path));
24
27
  }
25
- async request(method, path, body) {
28
+ async request(method, path, body, timeoutMs = 30_000) {
26
29
  const controller = new AbortController();
27
- const timer = setTimeout(() => controller.abort(), 30_000);
30
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
28
31
  let res;
29
32
  try {
30
33
  res = await fetch(`${this.baseUrl}${path}`, {
@@ -48,10 +51,17 @@ export class CorelayerClient {
48
51
  clearTimeout(timer);
49
52
  }
50
53
  if (!res.ok) {
51
- throw new Error(await parseError(res));
54
+ throw Object.assign(new Error(await parseError(res)), {
55
+ status: res.status,
56
+ });
52
57
  }
53
58
  return (await res.json());
54
59
  }
60
+ async ticketRequest(method, issueId, action, input) {
61
+ const base = `/api/v1/issues/${encodeURIComponent(issueId)}/tickets${action}`;
62
+ const query = new URLSearchParams(Object.entries(input).map(([key, value]) => [key, String(value)]));
63
+ return this.request(method, method === "GET" ? `${base}?${query}` : base, method === "POST" ? input : undefined, 120_000);
64
+ }
55
65
  async listIssues(groupId, filters) {
56
66
  const params = new URLSearchParams({ groupId });
57
67
  for (const [key, value] of Object.entries(filters)) {
@@ -61,6 +71,9 @@ export class CorelayerClient {
61
71
  }
62
72
  return this.request("GET", `/api/v1/issues?${params.toString()}`);
63
73
  }
74
+ async scheduleRequest(method, suffix, body) {
75
+ return this.request(method, `/api/v1/schedules${suffix}`, body);
76
+ }
64
77
  async getIssue(issueId) {
65
78
  return this.request("GET", `/api/v1/issues/${issueId}`);
66
79
  }
@@ -134,6 +147,9 @@ export class CorelayerClient {
134
147
  rawKey: data.rawKey,
135
148
  };
136
149
  }
150
+ async logout() {
151
+ await this.request("POST", "/api/v1/cli/logout");
152
+ }
137
153
  async listIntegrations(groupId) {
138
154
  const params = new URLSearchParams();
139
155
  if (groupId) {
@@ -187,7 +203,9 @@ export async function exchangeCliCode(baseUrl, code) {
187
203
  clearTimeout(timer);
188
204
  }
189
205
  if (!res.ok) {
190
- throw new Error(await parseError(res));
206
+ throw Object.assign(new Error(await parseError(res)), {
207
+ status: res.status,
208
+ });
191
209
  }
192
210
  return (await res.json());
193
211
  }
@@ -0,0 +1,4 @@
1
+ export function readFlag(args, flag) {
2
+ const index = args.indexOf(flag);
3
+ return index === -1 ? undefined : args[index + 1];
4
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corelayer-ai/cli",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Corelayer CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,9 +18,11 @@
18
18
  "dev": "tsx src/index.ts",
19
19
  "prepublishOnly": "npm run build"
20
20
  },
21
- "dependencies": {},
21
+ "dependencies": {
22
+ "@corelayer-ai/sdk": "^0.2.1"
23
+ },
22
24
  "devDependencies": {
23
- "@types/node": "^20.17.57",
25
+ "@types/node": "^24.19.2",
24
26
  "tsx": "^4.22.4",
25
27
  "typescript": "^5.8.3"
26
28
  }