@qoren/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.
Files changed (171) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +162 -0
  3. package/dist/args.d.ts +5 -0
  4. package/dist/args.d.ts.map +1 -0
  5. package/dist/args.js +23 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/commands/account.d.ts +4 -0
  8. package/dist/commands/account.d.ts.map +1 -0
  9. package/dist/commands/account.js +154 -0
  10. package/dist/commands/account.js.map +1 -0
  11. package/dist/commands/agent.d.ts +27 -0
  12. package/dist/commands/agent.d.ts.map +1 -0
  13. package/dist/commands/agent.js +968 -0
  14. package/dist/commands/agent.js.map +1 -0
  15. package/dist/commands/api.d.ts +4 -0
  16. package/dist/commands/api.d.ts.map +1 -0
  17. package/dist/commands/api.js +66 -0
  18. package/dist/commands/api.js.map +1 -0
  19. package/dist/commands/approvals.d.ts +11 -0
  20. package/dist/commands/approvals.d.ts.map +1 -0
  21. package/dist/commands/approvals.js +140 -0
  22. package/dist/commands/approvals.js.map +1 -0
  23. package/dist/commands/auth.d.ts +4 -0
  24. package/dist/commands/auth.d.ts.map +1 -0
  25. package/dist/commands/auth.js +215 -0
  26. package/dist/commands/auth.js.map +1 -0
  27. package/dist/commands/clients.d.ts +62 -0
  28. package/dist/commands/clients.d.ts.map +1 -0
  29. package/dist/commands/clients.js +311 -0
  30. package/dist/commands/clients.js.map +1 -0
  31. package/dist/commands/console.d.ts +4 -0
  32. package/dist/commands/console.d.ts.map +1 -0
  33. package/dist/commands/console.js +26 -0
  34. package/dist/commands/console.js.map +1 -0
  35. package/dist/commands/customAgent.d.ts +42 -0
  36. package/dist/commands/customAgent.d.ts.map +1 -0
  37. package/dist/commands/customAgent.js +449 -0
  38. package/dist/commands/customAgent.js.map +1 -0
  39. package/dist/commands/designer.d.ts +32 -0
  40. package/dist/commands/designer.d.ts.map +1 -0
  41. package/dist/commands/designer.js +682 -0
  42. package/dist/commands/designer.js.map +1 -0
  43. package/dist/commands/env.d.ts +15 -0
  44. package/dist/commands/env.d.ts.map +1 -0
  45. package/dist/commands/env.js +245 -0
  46. package/dist/commands/env.js.map +1 -0
  47. package/dist/commands/interactive.d.ts +4 -0
  48. package/dist/commands/interactive.d.ts.map +1 -0
  49. package/dist/commands/interactive.js +30 -0
  50. package/dist/commands/interactive.js.map +1 -0
  51. package/dist/commands/jobs.d.ts +4 -0
  52. package/dist/commands/jobs.d.ts.map +1 -0
  53. package/dist/commands/jobs.js +59 -0
  54. package/dist/commands/jobs.js.map +1 -0
  55. package/dist/commands/secrets.d.ts +15 -0
  56. package/dist/commands/secrets.d.ts.map +1 -0
  57. package/dist/commands/secrets.js +164 -0
  58. package/dist/commands/secrets.js.map +1 -0
  59. package/dist/commands/webhook.d.ts +4 -0
  60. package/dist/commands/webhook.d.ts.map +1 -0
  61. package/dist/commands/webhook.js +275 -0
  62. package/dist/commands/webhook.js.map +1 -0
  63. package/dist/config.d.ts +38 -0
  64. package/dist/config.d.ts.map +1 -0
  65. package/dist/config.js +117 -0
  66. package/dist/config.js.map +1 -0
  67. package/dist/context.d.ts +52 -0
  68. package/dist/context.d.ts.map +1 -0
  69. package/dist/context.js +163 -0
  70. package/dist/context.js.map +1 -0
  71. package/dist/duration.d.ts +9 -0
  72. package/dist/duration.d.ts.map +1 -0
  73. package/dist/duration.js +30 -0
  74. package/dist/duration.js.map +1 -0
  75. package/dist/index.d.ts +3 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +27 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/issues.d.ts +10 -0
  80. package/dist/issues.d.ts.map +1 -0
  81. package/dist/issues.js +45 -0
  82. package/dist/issues.js.map +1 -0
  83. package/dist/jobProgress.d.ts +12 -0
  84. package/dist/jobProgress.d.ts.map +1 -0
  85. package/dist/jobProgress.js +56 -0
  86. package/dist/jobProgress.js.map +1 -0
  87. package/dist/loopback.d.ts +28 -0
  88. package/dist/loopback.d.ts.map +1 -0
  89. package/dist/loopback.js +110 -0
  90. package/dist/loopback.js.map +1 -0
  91. package/dist/migrate/apply.d.ts +29 -0
  92. package/dist/migrate/apply.d.ts.map +1 -0
  93. package/dist/migrate/apply.js +135 -0
  94. package/dist/migrate/apply.js.map +1 -0
  95. package/dist/migrate/bundle.d.ts +89 -0
  96. package/dist/migrate/bundle.d.ts.map +1 -0
  97. package/dist/migrate/bundle.js +681 -0
  98. package/dist/migrate/bundle.js.map +1 -0
  99. package/dist/migrate/tar.d.ts +9 -0
  100. package/dist/migrate/tar.d.ts.map +1 -0
  101. package/dist/migrate/tar.js +89 -0
  102. package/dist/migrate/tar.js.map +1 -0
  103. package/dist/output.d.ts +46 -0
  104. package/dist/output.d.ts.map +1 -0
  105. package/dist/output.js +152 -0
  106. package/dist/output.js.map +1 -0
  107. package/dist/program.d.ts +17 -0
  108. package/dist/program.d.ts.map +1 -0
  109. package/dist/program.js +89 -0
  110. package/dist/program.js.map +1 -0
  111. package/dist/runtimes.d.ts +11 -0
  112. package/dist/runtimes.d.ts.map +1 -0
  113. package/dist/runtimes.js +20 -0
  114. package/dist/runtimes.js.map +1 -0
  115. package/dist/slug.d.ts +3 -0
  116. package/dist/slug.d.ts.map +1 -0
  117. package/dist/slug.js +15 -0
  118. package/dist/slug.js.map +1 -0
  119. package/dist/taskChain.d.ts +20 -0
  120. package/dist/taskChain.d.ts.map +1 -0
  121. package/dist/taskChain.js +40 -0
  122. package/dist/taskChain.js.map +1 -0
  123. package/dist/taskDelivery.d.ts +33 -0
  124. package/dist/taskDelivery.d.ts.map +1 -0
  125. package/dist/taskDelivery.js +67 -0
  126. package/dist/taskDelivery.js.map +1 -0
  127. package/dist/tui/app.d.ts +5 -0
  128. package/dist/tui/app.d.ts.map +1 -0
  129. package/dist/tui/app.js +130 -0
  130. package/dist/tui/app.js.map +1 -0
  131. package/dist/tui/index.d.ts +12 -0
  132. package/dist/tui/index.d.ts.map +1 -0
  133. package/dist/tui/index.js +34 -0
  134. package/dist/tui/index.js.map +1 -0
  135. package/dist/tui/model.d.ts +110 -0
  136. package/dist/tui/model.d.ts.map +1 -0
  137. package/dist/tui/model.js +257 -0
  138. package/dist/tui/model.js.map +1 -0
  139. package/dist/tui/overlay.d.ts +66 -0
  140. package/dist/tui/overlay.d.ts.map +1 -0
  141. package/dist/tui/overlay.js +216 -0
  142. package/dist/tui/overlay.js.map +1 -0
  143. package/dist/tui/panes/account.d.ts +5 -0
  144. package/dist/tui/panes/account.d.ts.map +1 -0
  145. package/dist/tui/panes/account.js +108 -0
  146. package/dist/tui/panes/account.js.map +1 -0
  147. package/dist/tui/panes/agents.d.ts +9 -0
  148. package/dist/tui/panes/agents.d.ts.map +1 -0
  149. package/dist/tui/panes/agents.js +340 -0
  150. package/dist/tui/panes/agents.js.map +1 -0
  151. package/dist/tui/panes/chat.d.ts +14 -0
  152. package/dist/tui/panes/chat.d.ts.map +1 -0
  153. package/dist/tui/panes/chat.js +169 -0
  154. package/dist/tui/panes/chat.js.map +1 -0
  155. package/dist/tui/panes/environments.d.ts +6 -0
  156. package/dist/tui/panes/environments.d.ts.map +1 -0
  157. package/dist/tui/panes/environments.js +364 -0
  158. package/dist/tui/panes/environments.js.map +1 -0
  159. package/dist/tui/panes/jobs.d.ts +5 -0
  160. package/dist/tui/panes/jobs.d.ts.map +1 -0
  161. package/dist/tui/panes/jobs.js +104 -0
  162. package/dist/tui/panes/jobs.js.map +1 -0
  163. package/dist/tui/store.d.ts +40 -0
  164. package/dist/tui/store.d.ts.map +1 -0
  165. package/dist/tui/store.js +124 -0
  166. package/dist/tui/store.js.map +1 -0
  167. package/dist/tui/ui.d.ts +95 -0
  168. package/dist/tui/ui.d.ts.map +1 -0
  169. package/dist/tui/ui.js +144 -0
  170. package/dist/tui/ui.js.map +1 -0
  171. package/package.json +51 -0
@@ -0,0 +1,164 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { extname } from "node:path";
3
+ import { orgSlug, requireContext, run, } from "../context.js";
4
+ import { age, details, dim, emit, note, table } from "../output.js";
5
+ import { gated, resolveClient } from "./clients.js";
6
+ // The vault: API keys and other values agents receive by NAME at setup.
7
+ //
8
+ // echo "$HUBSPOT_KEY" | qoren secrets set HUBSPOT_API_KEY --client Acme
9
+ //
10
+ // A secret is agency-wide, or belongs to one of your clients (--client). The
11
+ // same name can be saved once agency-wide and once per client. An agent gets
12
+ // its own client's secret first, then the agency-wide one, and never another
13
+ // client's, so client B's agent can't end up with client A's key.
14
+ //
15
+ // Values go in on stdin, from --file, or with --value (which leaves the value
16
+ // in your shell history). They never come back out except through `reveal`,
17
+ // which is audited.
18
+ /** "all clients" for an agency-wide row, else the client's name. */
19
+ export const scopeLabel = (s) => s.customerId ? (s.customerName ?? s.customerId) : "all clients";
20
+ /** The agents a row is used by, two by name and the rest counted. */
21
+ export function usedByLabel(agents) {
22
+ if (agents.length === 0)
23
+ return "none";
24
+ const shown = agents.slice(0, 2).map((a) => a.name).join(", ");
25
+ return agents.length > 2 ? `${shown} +${agents.length - 2}` : shown;
26
+ }
27
+ /** The rows `secrets list` prints, narrowed to one client when asked: that
28
+ * client's own secrets plus the agency-wide ones its agents can fall back to,
29
+ * with the agency-wide row left out where the client has its own. */
30
+ export function secretsFor(rows, customerId) {
31
+ if (customerId === undefined)
32
+ return rows;
33
+ if (customerId === null)
34
+ return rows.filter((r) => !r.customerId);
35
+ const own = new Set(rows.filter((r) => r.customerId === customerId).map((r) => r.name));
36
+ return rows.filter((r) => r.customerId === customerId || (!r.customerId && !own.has(r.name)));
37
+ }
38
+ /** The scope a --client / --agency pair asks for: undefined = every scope. */
39
+ async function scopeOf(ctx, options) {
40
+ if (options.client && options.agency) {
41
+ throw new Error("Pass --client or --agency, not both.");
42
+ }
43
+ if (options.agency)
44
+ return { id: null, name: "all clients" };
45
+ if (!options.client)
46
+ return undefined;
47
+ const client = await resolveClient(ctx, options.client);
48
+ return { id: client.id, name: client.name };
49
+ }
50
+ async function readStdin() {
51
+ const chunks = [];
52
+ for await (const chunk of process.stdin) {
53
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk, "utf8") : chunk);
54
+ }
55
+ return Buffer.concat(chunks).toString("utf8").replace(/\r?\n$/, "");
56
+ }
57
+ export function secretsCommands(program, global) {
58
+ const secrets = program
59
+ .command("secrets")
60
+ .alias("secret")
61
+ .alias("vault")
62
+ .description("Keys your agents receive by name, agency-wide or per client");
63
+ secrets
64
+ .command("list")
65
+ .alias("ls")
66
+ .description("Secret names and who they belong to. Never values")
67
+ .option("--client <client>", "only what an agent of this client would get (id or exact name)")
68
+ .option("--agency", "only the agency-wide secrets")
69
+ .action((options) => run(async () => {
70
+ const ctx = requireContext(global());
71
+ const scope = await scopeOf(ctx, options);
72
+ const rows = secretsFor(await ctx.qoren.secrets.list(await orgSlug(ctx)), scope?.id);
73
+ emit(rows, () => {
74
+ if (scope)
75
+ note(dim(`As an agent of ${scope.name} sees them`));
76
+ table(rows, [
77
+ { header: "name", value: (s) => s.name },
78
+ { header: "client", value: (s) => scopeLabel(s) },
79
+ { header: "kind", value: (s) => s.kind ?? "value" },
80
+ // Absent on a control plane older than the batched used-by list: leave the cell blank.
81
+ { header: "used by", value: (s) => (s.usedBy ? usedByLabel(s.usedBy) : "") },
82
+ { header: "description", value: (s) => s.description ?? "" },
83
+ { header: "updated", value: (s) => age(s.updatedAt) },
84
+ ]);
85
+ });
86
+ })());
87
+ secrets
88
+ .command("set <name>")
89
+ .description("Save or replace a secret. Reads the value from stdin unless --value or --file")
90
+ .option("--client <client>", "save it for one client only (id or exact name)")
91
+ .option("--value <value>", "the value (stays in your shell history; prefer stdin)")
92
+ .option("--file <path>", "store this file's contents as a file secret")
93
+ .option("--description <text>", "a note shown beside the name")
94
+ .action((name, options) => run(async () => {
95
+ const ctx = requireContext(global());
96
+ if (options.value !== undefined && options.file) {
97
+ throw new Error("Pass --value or --file, not both.");
98
+ }
99
+ let value;
100
+ if (options.file)
101
+ value = await readFile(options.file, "utf8");
102
+ else if (options.value !== undefined)
103
+ value = options.value;
104
+ else if (process.stdin.isTTY) {
105
+ throw new Error("Pipe the value on stdin, or pass --file or --value.");
106
+ }
107
+ else
108
+ value = await readStdin();
109
+ if (!value)
110
+ throw new Error("The value is empty.");
111
+ const scope = await scopeOf(ctx, { client: options.client });
112
+ const saved = (await gated(ctx.qoren.secrets.set(await orgSlug(ctx), {
113
+ name,
114
+ value,
115
+ description: options.description,
116
+ ...(options.file
117
+ ? { kind: "file", fileExt: extname(options.file).replace(/^\./, "") || undefined }
118
+ : {}),
119
+ customerId: scope?.id ?? null,
120
+ })));
121
+ emit(saved, () => details([
122
+ ["Saved", saved.name],
123
+ ["For", scopeLabel(saved)],
124
+ ["Kind", saved.kind ?? "value"],
125
+ ]));
126
+ })());
127
+ secrets
128
+ .command("rm <name>")
129
+ .alias("remove")
130
+ .description("Delete one secret. Agents that already have it keep their copy")
131
+ .option("--client <client>", "the client's secret (id or exact name); default is the agency-wide one")
132
+ .action((name, options) => run(async () => {
133
+ const ctx = requireContext(global());
134
+ const scope = await scopeOf(ctx, options);
135
+ const result = await ctx.qoren.secrets.remove(await orgSlug(ctx), name, scope?.id ?? null);
136
+ emit(result, () => note(`Deleted ${name.toUpperCase()} (${scope?.name ?? "all clients"}).`));
137
+ })());
138
+ secrets
139
+ .command("reveal <name>")
140
+ .description("Print one value. Every reveal is recorded in the audit log")
141
+ .option("--client <client>", "the client's secret (id or exact name); default is the agency-wide one")
142
+ .action((name, options) => run(async () => {
143
+ const ctx = requireContext(global());
144
+ const scope = await scopeOf(ctx, options);
145
+ const revealed = await ctx.qoren.secrets.reveal(await orgSlug(ctx), name, scope?.id ?? null);
146
+ emit(revealed, () => process.stdout.write(`${revealed.value}\n`));
147
+ })());
148
+ secrets
149
+ .command("used-by <name>")
150
+ .description("Agents that have this secret injected")
151
+ .option("--client <client>", "the client's secret (id or exact name); default is the agency-wide one")
152
+ .action((name, options) => run(async () => {
153
+ const ctx = requireContext(global());
154
+ const scope = await scopeOf(ctx, options);
155
+ const agents = await ctx.qoren.secrets.usedBy(await orgSlug(ctx), name, scope?.id ?? null);
156
+ emit(agents, () => table(agents, [
157
+ { header: "id", value: (a) => a.id },
158
+ { header: "agent", value: (a) => a.name },
159
+ { header: "environment", value: (a) => a.machineName },
160
+ { header: "status", value: (a) => a.status },
161
+ ]));
162
+ })());
163
+ }
164
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/commands/secrets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ import { type GlobalOptions } from "../context.js";
3
+ export declare function webhookCommands(program: Command, global: () => GlobalOptions): void;
4
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/commands/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAgFxE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,aAAa,QAwT5B"}
@@ -0,0 +1,275 @@
1
+ import { requireContext, run } from "../context.js";
2
+ import { age, bold, details, dim, emit, note, statusColor, table, warn, } from "../output.js";
3
+ // Webhook triggers: what wakes an agent when you are not there.
4
+ //
5
+ // The shape of the whole thing in one line:
6
+ //
7
+ // qoren webhook create <agent> --name "Bookings" --source cal \
8
+ // --event BOOKING_CREATED --rules "Add the attendee to the CRM and brief me."
9
+ //
10
+ // That prints a URL and a secret, once. Paste both into cal.com's webhook
11
+ // settings and the agent starts getting bookings.
12
+ //
13
+ // `deliveries` is the command you will actually live in: it says whether an
14
+ // event arrived, whether it was acted on, and if not, why not.
15
+ const SOURCES = [
16
+ "cal",
17
+ "github",
18
+ "stripe",
19
+ "generic",
20
+ "none",
21
+ ];
22
+ function triggerTable(rows) {
23
+ table(rows, [
24
+ { header: "id", value: (t) => t.id },
25
+ { header: "name", value: (t) => t.name },
26
+ { header: "source", value: (t) => t.source },
27
+ { header: "status", value: (t) => statusColor(t.status) },
28
+ { header: "events", value: (t) => t.events.join(", ") || "all" },
29
+ { header: "autonomy", value: (t) => t.autonomy },
30
+ { header: "deliveries", value: (t) => String(t.deliveryCount) },
31
+ { header: "last", value: (t) => age(t.lastDeliveryAt) },
32
+ ]);
33
+ }
34
+ function deliveryTable(rows) {
35
+ table(rows, [
36
+ { header: "id", value: (d) => d.id },
37
+ { header: "event", value: (d) => d.eventType },
38
+ { header: "status", value: (d) => statusColor(d.status) },
39
+ { header: "summary", value: (d) => d.summary ?? d.error ?? "" },
40
+ { header: "when", value: (d) => age(d.createdAt) },
41
+ ]);
42
+ }
43
+ /** Print the URL and secret with the one instruction that matters: this is the
44
+ * only time either is readable. Goes to stderr via `note` so `--json` still
45
+ * pipes clean data — a script storing the secret reads it from the JSON. */
46
+ function printSecret(value, what) {
47
+ note(`${what}. Copy both of these into your webhook settings now:`);
48
+ details([
49
+ ["URL", value.url],
50
+ ["Secret", value.secret],
51
+ ...(value.signatureHeader
52
+ ? [["Signature header", value.signatureHeader]]
53
+ : []),
54
+ ]);
55
+ warn("Neither is readable again. Lose them and you rotate.");
56
+ if (value.url.startsWith("/")) {
57
+ warn("That URL has no host: the control plane has no public URL configured. Fix that, then rotate to get a complete one.");
58
+ }
59
+ }
60
+ export function webhookCommands(program, global) {
61
+ const webhook = program
62
+ .command("webhook")
63
+ .alias("webhooks")
64
+ .alias("trigger")
65
+ .description("Let an outside service wake an agent");
66
+ webhook
67
+ .command("sources")
68
+ .description("Services Qoren can receive webhooks from")
69
+ .action(() => run(async () => {
70
+ const ctx = requireContext(global());
71
+ const sources = await ctx.qoren.webhooks.sources();
72
+ emit(sources, () => table(sources, [
73
+ { header: "source", value: (s) => s.source },
74
+ { header: "name", value: (s) => s.label },
75
+ { header: "verified", value: (s) => (s.verified ? "yes" : "no") },
76
+ {
77
+ header: "known events",
78
+ value: (s) => (s.events.length ? String(s.events.length) : "any"),
79
+ },
80
+ ]));
81
+ })());
82
+ webhook
83
+ .command("ls <agentId>")
84
+ .alias("list")
85
+ .description("List an agent's triggers")
86
+ .action((agentId) => run(async () => {
87
+ const ctx = requireContext(global());
88
+ const triggers = await ctx.qoren.webhooks.list(agentId);
89
+ emit(triggers, () => triggers.length
90
+ ? triggerTable(triggers)
91
+ : note(`No triggers yet. ${dim(`qoren webhook create ${agentId} --name … --source cal`)}`));
92
+ })());
93
+ webhook
94
+ .command("get <id>")
95
+ .description("Show one trigger")
96
+ .action((id) => run(async () => {
97
+ const ctx = requireContext(global());
98
+ const t = await ctx.qoren.webhooks.get(id);
99
+ emit(t, () => details([
100
+ ["Id", t.id],
101
+ ["Name", t.name],
102
+ ["Agent", t.agentSlug ?? t.agentId],
103
+ ["Source", t.source],
104
+ ["Status", statusColor(t.status)],
105
+ ["Events", t.events.join(", ") || "all"],
106
+ ["Autonomy", t.autonomy],
107
+ ["Rules", t.instructions ?? ""],
108
+ ["Limit", `${t.maxPerHour}/hour`],
109
+ ["Deliveries", `${t.deliveryCount} (${t.failureCount} failed)`],
110
+ ["Last delivery", t.lastDeliveryAt ?? "never"],
111
+ ]));
112
+ })());
113
+ webhook
114
+ .command("create <agentId>")
115
+ .description("Create a trigger and print its URL and secret")
116
+ .requiredOption("--name <name>", "what this trigger is for")
117
+ .option(`--source <source>`, SOURCES.join(" | "), "cal")
118
+ .option("--event <name...>", "only act on these events (repeatable; omit for all)")
119
+ .option("--rules <text>", "what the agent should do when this fires")
120
+ .option("--propose", "let the agent only propose actions, not take them")
121
+ .option("--max-per-hour <n>", "paid turns per hour before throttling")
122
+ .option("--secret <secret>", "the secret the sender already has")
123
+ .option("--header <name>", "custom source: header carrying the signature")
124
+ .option("--encoding <encoding>", "custom source: hex | base64")
125
+ .option("--prefix <prefix>", "custom source: signature prefix, e.g. sha256=")
126
+ .option("--event-path <path>", "custom source: path to the event name")
127
+ .action((agentId, options) => run(async () => {
128
+ const ctx = requireContext(global());
129
+ const body = {
130
+ name: options.name,
131
+ source: options.source,
132
+ ...(options.event ? { events: options.event } : {}),
133
+ ...(options.rules !== undefined
134
+ ? { instructions: options.rules }
135
+ : {}),
136
+ ...(options.propose ? { autonomy: "propose" } : {}),
137
+ ...(options.maxPerHour !== undefined
138
+ ? { maxPerHour: Number(options.maxPerHour) }
139
+ : {}),
140
+ ...(options.secret !== undefined
141
+ ? { secret: options.secret }
142
+ : {}),
143
+ ...(options.header !== undefined
144
+ ? { headerName: options.header }
145
+ : {}),
146
+ ...(options.encoding !== undefined
147
+ ? { encoding: options.encoding }
148
+ : {}),
149
+ ...(options.prefix !== undefined
150
+ ? { signaturePrefix: options.prefix }
151
+ : {}),
152
+ ...(options.eventPath !== undefined
153
+ ? { eventPath: options.eventPath }
154
+ : {}),
155
+ };
156
+ const created = await ctx.qoren.webhooks.create(agentId, body);
157
+ emit(created, () => {
158
+ printSecret(created, `Trigger ${bold(options.name)} created`);
159
+ if (!options.event?.length) {
160
+ warn("This trigger fires on every event the source sends, and each one is a paid agent turn. Narrow it with --event.");
161
+ }
162
+ });
163
+ })());
164
+ webhook
165
+ .command("rules <id> <text>")
166
+ .description("Rewrite what the agent should do when this trigger fires")
167
+ .action((id, text) => run(async () => {
168
+ const ctx = requireContext(global());
169
+ const t = await ctx.qoren.webhooks.update(id, { instructions: text });
170
+ emit(t, () => note(`Updated the rules for ${bold(t.name)}.`));
171
+ })());
172
+ webhook
173
+ .command("events <id> [names...]")
174
+ .description("Set which events this trigger acts on (none = all)")
175
+ .action((id, names) => run(async () => {
176
+ const ctx = requireContext(global());
177
+ const t = await ctx.qoren.webhooks.update(id, { events: names });
178
+ emit(t, () => note(names.length
179
+ ? `${bold(t.name)} now acts on ${names.join(", ")}.`
180
+ : `${bold(t.name)} now acts on every event the source sends.`));
181
+ })());
182
+ webhook
183
+ .command("pause <id>")
184
+ .description("Stop deliveries without changing the URL")
185
+ .action((id) => run(async () => {
186
+ const ctx = requireContext(global());
187
+ const t = await ctx.qoren.webhooks.update(id, { status: "paused" });
188
+ emit(t, () => note(`${bold(t.name)} is paused. Its URL still answers, and ignores.`));
189
+ })());
190
+ webhook
191
+ .command("resume <id>")
192
+ .description("Start accepting deliveries again")
193
+ .action((id) => run(async () => {
194
+ const ctx = requireContext(global());
195
+ const t = await ctx.qoren.webhooks.update(id, { status: "active" });
196
+ emit(t, () => note(`${bold(t.name)} is live again.`));
197
+ })());
198
+ webhook
199
+ .command("rotate <id>")
200
+ .description("Issue a new URL and secret, invalidating the old pair")
201
+ .action((id) => run(async () => {
202
+ const ctx = requireContext(global());
203
+ const rotated = await ctx.qoren.webhooks.rotate(id);
204
+ emit(rotated, () => {
205
+ printSecret(rotated, "Rotated");
206
+ warn("The old URL now 404s, so the sender stops working until you paste these in.");
207
+ });
208
+ })());
209
+ webhook
210
+ .command("test <id>")
211
+ .description("Send a sample event through the real path")
212
+ .option("--event <name>", "event name to simulate")
213
+ .action((id, options) => run(async () => {
214
+ const ctx = requireContext(global());
215
+ const delivery = await ctx.qoren.webhooks.test(id, options.event !== undefined ? { eventType: options.event } : {});
216
+ emit(delivery, () => note(`Delivery ${bold(delivery.id)} is ${delivery.status}. ${dim(`qoren webhook delivery ${id} ${delivery.id}`)}`));
217
+ })());
218
+ webhook
219
+ .command("deliveries <id>")
220
+ .alias("log")
221
+ .description("What this trigger has received, newest first")
222
+ .option("--limit <n>", "how many to show", "20")
223
+ .action((id, options) => run(async () => {
224
+ const ctx = requireContext(global());
225
+ const rows = await ctx.qoren.webhooks.deliveries(id, Number(options.limit));
226
+ emit(rows, () => rows.length
227
+ ? deliveryTable(rows)
228
+ : note("Nothing has arrived at this trigger yet."));
229
+ })());
230
+ webhook
231
+ .command("delivery <id> <deliveryId>")
232
+ .description("One delivery: the payload, the prompt, and the agent's reply")
233
+ .action((id, deliveryId) => run(async () => {
234
+ const ctx = requireContext(global());
235
+ const d = await ctx.qoren.webhooks.delivery(id, deliveryId);
236
+ emit(d, () => {
237
+ details([
238
+ ["Id", d.delivery.id],
239
+ ["Event", d.delivery.eventType],
240
+ ["Status", statusColor(d.delivery.status)],
241
+ ["Summary", d.delivery.summary ?? ""],
242
+ ["Error", d.delivery.error ?? ""],
243
+ ["Job", d.delivery.jobId ?? "never reached the agent"],
244
+ ["Received", d.delivery.createdAt],
245
+ ["Finished", d.delivery.finishedAt ?? ""],
246
+ ]);
247
+ if (d.payload) {
248
+ note("Payload");
249
+ process.stdout.write(`${d.payload}\n`);
250
+ }
251
+ if (d.agentResult) {
252
+ note("The agent replied");
253
+ process.stdout.write(`${d.agentResult}\n`);
254
+ }
255
+ });
256
+ })());
257
+ webhook
258
+ .command("replay <id> <deliveryId>")
259
+ .description("Run a past delivery's payload through the agent again")
260
+ .action((id, deliveryId) => run(async () => {
261
+ const ctx = requireContext(global());
262
+ const replayed = await ctx.qoren.webhooks.replay(id, deliveryId);
263
+ emit(replayed, () => note(`Replayed as delivery ${bold(replayed.id)}.`));
264
+ })());
265
+ webhook
266
+ .command("rm <id>")
267
+ .alias("delete")
268
+ .description("Delete a trigger and its delivery log")
269
+ .action((id) => run(async () => {
270
+ const ctx = requireContext(global());
271
+ const result = await ctx.qoren.webhooks.remove(id);
272
+ emit(result, () => note(`Removed ${bold(result.removed)}. Its URL now 404s.`));
273
+ })());
274
+ }
275
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/commands/webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ export declare const DEFAULT_BASE_URL = "https://qoren.sh";
2
+ export type Profile = {
3
+ token: string;
4
+ baseUrl: string;
5
+ /** Cached from `GET /clients` so environment commands don't re-resolve the
6
+ * org's fleet tenant on every invocation. Refreshed on a miss. */
7
+ orgSlug?: string;
8
+ email?: string;
9
+ };
10
+ export declare function configDir(): string;
11
+ export declare function configPath(): string;
12
+ /** The name of the profile a command should use. */
13
+ export declare function profileName(explicit?: string): string;
14
+ /**
15
+ * The credentials to run with, or null when there are none.
16
+ *
17
+ * Resolution order, highest first:
18
+ * 1. QOREN_TOKEN / QOREN_API_URL (CI, and any deliberate override)
19
+ * 2. --api-url (a flag beats stored config)
20
+ * 3. the named profile
21
+ */
22
+ export declare function resolveProfile(options: {
23
+ profile?: string;
24
+ baseUrl?: string;
25
+ }): Profile | null;
26
+ /** The base URL to talk to even when there is no stored login (so `qoren login`
27
+ * knows where to send the browser). */
28
+ export declare function resolveBaseUrl(explicit?: string): string;
29
+ /** Store a profile and make it current. */
30
+ export declare function saveProfile(name: string, profile: Profile): void;
31
+ /** Update fields on an existing profile, e.g. caching the resolved org slug.
32
+ * A no-op when the profile isn't stored (an env-token session has no file). */
33
+ export declare function patchProfile(name: string, patch: Partial<Profile>): void;
34
+ /** Forget a profile. Returns false when there was nothing to forget. */
35
+ export declare function removeProfile(name: string): boolean;
36
+ /** Every stored profile name, for `qoren logout --all` and diagnostics. */
37
+ export declare function listProfiles(): string[];
38
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB;sEACkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAQF,wBAAgB,SAAS,IAAI,MAAM,CAGlC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAsBD,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,GAAG,IAAI,CAgBjB;AAED;uCACuC;AACvC,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAOhE;AAED;+EAC+E;AAC/E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAQxE;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAWnD;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC"}
package/dist/config.js ADDED
@@ -0,0 +1,117 @@
1
+ import { chmodSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+ // Where the CLI keeps its credentials.
5
+ //
6
+ // One file, `~/.config/qoren/config.json`, holding named profiles so a person
7
+ // who works across accounts can switch with --profile rather than logging out.
8
+ // It is written 0600 and its directory 0700: it holds bearer tokens, and a
9
+ // world-readable token is the same as a published one.
10
+ //
11
+ // Environment variables win over the file, always. That is what makes CI work
12
+ // without a login step, and it means a script can never accidentally pick up a
13
+ // developer's personal profile — set QOREN_TOKEN and the file is not consulted.
14
+ export const DEFAULT_BASE_URL = "https://qoren.sh";
15
+ export function configDir() {
16
+ const xdg = process.env.XDG_CONFIG_HOME?.trim();
17
+ return xdg ? join(xdg, "qoren") : join(homedir(), ".config", "qoren");
18
+ }
19
+ export function configPath() {
20
+ return join(configDir(), "config.json");
21
+ }
22
+ function readFile() {
23
+ try {
24
+ return JSON.parse(readFileSync(configPath(), "utf8"));
25
+ }
26
+ catch {
27
+ // Missing, unreadable or corrupt all mean the same thing to a CLI: there is
28
+ // no stored login. Refusing to run would only strand someone whose file got
29
+ // truncated, when `qoren login` fixes it.
30
+ return {};
31
+ }
32
+ }
33
+ function writeFileAtomically(config) {
34
+ const path = configPath();
35
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
36
+ writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`, { mode: 0o600 });
37
+ // writeFileSync's mode only applies when it CREATES the file, so an existing
38
+ // file keeps whatever permissions it had. Set them every time.
39
+ chmodSync(path, 0o600);
40
+ }
41
+ /** The name of the profile a command should use. */
42
+ export function profileName(explicit) {
43
+ return explicit ?? process.env.QOREN_PROFILE?.trim() ?? readFile().current ?? "default";
44
+ }
45
+ /**
46
+ * The credentials to run with, or null when there are none.
47
+ *
48
+ * Resolution order, highest first:
49
+ * 1. QOREN_TOKEN / QOREN_API_URL (CI, and any deliberate override)
50
+ * 2. --api-url (a flag beats stored config)
51
+ * 3. the named profile
52
+ */
53
+ export function resolveProfile(options) {
54
+ const envToken = process.env.QOREN_TOKEN?.trim();
55
+ const envUrl = process.env.QOREN_API_URL?.trim();
56
+ if (envToken) {
57
+ return {
58
+ token: envToken,
59
+ baseUrl: options.baseUrl ?? envUrl ?? DEFAULT_BASE_URL,
60
+ };
61
+ }
62
+ const stored = readFile().profiles?.[profileName(options.profile)];
63
+ if (!stored)
64
+ return null;
65
+ return {
66
+ ...stored,
67
+ baseUrl: options.baseUrl ?? envUrl ?? stored.baseUrl ?? DEFAULT_BASE_URL,
68
+ };
69
+ }
70
+ /** The base URL to talk to even when there is no stored login (so `qoren login`
71
+ * knows where to send the browser). */
72
+ export function resolveBaseUrl(explicit) {
73
+ return (explicit ??
74
+ process.env.QOREN_API_URL?.trim() ??
75
+ resolveProfile({})?.baseUrl ??
76
+ DEFAULT_BASE_URL);
77
+ }
78
+ /** Store a profile and make it current. */
79
+ export function saveProfile(name, profile) {
80
+ const config = readFile();
81
+ writeFileAtomically({
82
+ ...config,
83
+ current: name,
84
+ profiles: { ...config.profiles, [name]: profile },
85
+ });
86
+ }
87
+ /** Update fields on an existing profile, e.g. caching the resolved org slug.
88
+ * A no-op when the profile isn't stored (an env-token session has no file). */
89
+ export function patchProfile(name, patch) {
90
+ const config = readFile();
91
+ const existing = config.profiles?.[name];
92
+ if (!existing)
93
+ return;
94
+ writeFileAtomically({
95
+ ...config,
96
+ profiles: { ...config.profiles, [name]: { ...existing, ...patch } },
97
+ });
98
+ }
99
+ /** Forget a profile. Returns false when there was nothing to forget. */
100
+ export function removeProfile(name) {
101
+ const config = readFile();
102
+ if (!config.profiles?.[name])
103
+ return false;
104
+ const profiles = { ...config.profiles };
105
+ delete profiles[name];
106
+ writeFileAtomically({
107
+ ...config,
108
+ profiles,
109
+ ...(config.current === name ? { current: undefined } : {}),
110
+ });
111
+ return true;
112
+ }
113
+ /** Every stored profile name, for `qoren logout --all` and diagnostics. */
114
+ export function listProfiles() {
115
+ return Object.keys(readFile().profiles ?? {});
116
+ }
117
+ //# sourceMappingURL=config.js.map