@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,62 @@
1
+ import type { Command } from "commander";
2
+ import { type AgencyClient, type ClientCosts, type ClientHologramLink, type Machine } from "@qoren/sdk";
3
+ import { type Context, type GlobalOptions } from "../context.js";
4
+ /** The upstream refusal for an account without clients. */
5
+ export declare const CLIENTS_DISABLED = "Clients are not enabled for this account.";
6
+ /**
7
+ * The feature refusal as a plain failure; any other error untouched.
8
+ *
9
+ * A bare 403 exits 3 ("sign in again"), which is the wrong advice here: the
10
+ * credential is fine, the account just does not have the feature. The message
11
+ * is the server's own, so it stays one clean sentence.
12
+ */
13
+ export declare function clientsGateError(err: unknown): unknown;
14
+ /** Await a gated call, reporting the feature refusal cleanly. */
15
+ export declare function gated<T>(call: Promise<T>): Promise<T>;
16
+ /**
17
+ * Pick one client by id or exact name. Ids win, then active names (unique
18
+ * upstream), then an archived name when only one matches. Pure so the rules
19
+ * are testable without a control plane.
20
+ */
21
+ export declare function matchClient(clients: AgencyClient[], ref: string): AgencyClient;
22
+ /** Look a client up by id or exact name, archived ones included. */
23
+ export declare function resolveClient(ctx: Context, ref: string): Promise<AgencyClient>;
24
+ /** Pick one environment by id or exact name. */
25
+ export declare function matchEnvironment(machines: Machine[], ref: string): Machine;
26
+ /**
27
+ * The window for `qoren account costs`, as unix ms.
28
+ *
29
+ * Accepts any ISO date or date-time. A bare date for --to means the whole of
30
+ * that day (UTC), because "--to 2026-09-30" read as midnight would silently
31
+ * leave the 30th out. With nothing given, the last 30 days.
32
+ */
33
+ export declare function parseCostWindow(from: string | undefined, to: string | undefined, now?: number): {
34
+ from: number;
35
+ to: number;
36
+ };
37
+ export type CostRow = {
38
+ label: string;
39
+ credits: number;
40
+ total?: boolean;
41
+ };
42
+ /**
43
+ * The rows `qoren account costs` prints: each client by spend, then the
44
+ * environments with no client, then account-level spend, then spend from
45
+ * before cost tracking (only when there is some), then the total.
46
+ */
47
+ export declare function costRows(costs: ClientCosts): CostRow[];
48
+ /**
49
+ * The whole window by category: every client, no client, the account line
50
+ * and spend from before tracking. Categories with no spend are left out.
51
+ */
52
+ export declare function categoryRows(costs: ClientCosts): CostRow[];
53
+ /** Credits to two decimal places at most, without trailing zeros. */
54
+ export declare const formatCredits: (credits: number) => string;
55
+ /** Dollars are credits / 1000. */
56
+ export declare const formatDollars: (credits: number) => string;
57
+ /** Print a costs response as tables plus the caveats a reader needs. */
58
+ export declare function renderCosts(costs: ClientCosts): void;
59
+ export declare function clientsCommands(program: Command, global: () => GlobalOptions): void;
60
+ /** What `qoren clients hologram` prints. The URL alone goes to stdout, so it can be piped. */
61
+ export declare function hologramDetails(client: AgencyClient, link: ClientHologramLink, revoked: boolean): void;
62
+ //# sourceMappingURL=clients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../src/commands/clients.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EAEvB,KAAK,OAAO,EACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAuB,KAAK,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAStF,2DAA2D;AAC3D,eAAO,MAAM,gBAAgB,8CAA8C,CAAC;AAE5E;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAYtD;AAED,iEAAiE;AACjE,wBAAsB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAM3D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,YAAY,EAAE,EACvB,GAAG,EAAE,MAAM,GACV,YAAY,CAed;AAED,oEAAoE;AACpE,wBAAsB,aAAa,CACjC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,YAAY,CAAC,CAKvB;AAED,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAa1E;AAKD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,GAAG,GAAE,MAAmB,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAiB9B;AAED,MAAM,MAAM,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,EAAE,CAiBtD;AAWD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,EAAE,CAU1D;AAED,qEAAqE;AACrE,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,KAAG,MACP,CAAC;AAE1C,kCAAkC;AAClC,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,KAAG,MACb,CAAC;AAIpC,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAgCpD;AAwDD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,QAqG5E;AAED,8FAA8F;AAC9F,wBAAgB,eAAe,CAC7B,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,OAAO,GACf,IAAI,CAmBN"}
@@ -0,0 +1,311 @@
1
+ import { QorenError, } from "@qoren/sdk";
2
+ import { requireContext, run } from "../context.js";
3
+ import { age, bold, details, dim, emit, note, table } from "../output.js";
4
+ // Agency clients: the businesses an agency runs environments and agents for.
5
+ //
6
+ // The API calls them customers; this CLI never says so. Everything here is
7
+ // gated per account upstream, and an account without the feature is told so
8
+ // in one sentence rather than being sent to sign in again.
9
+ /** The upstream refusal for an account without clients. */
10
+ export const CLIENTS_DISABLED = "Clients are not enabled for this account.";
11
+ /**
12
+ * The feature refusal as a plain failure; any other error untouched.
13
+ *
14
+ * A bare 403 exits 3 ("sign in again"), which is the wrong advice here: the
15
+ * credential is fine, the account just does not have the feature. The message
16
+ * is the server's own, so it stays one clean sentence.
17
+ */
18
+ export function clientsGateError(err) {
19
+ if (err instanceof QorenError &&
20
+ err.status === 403 &&
21
+ // The Custom agent routes say so with a code; the older client routes
22
+ // only in words.
23
+ (err.code === "agency_clients_disabled" ||
24
+ /clients are not enabled/i.test(err.message))) {
25
+ return new Error(err.message || CLIENTS_DISABLED);
26
+ }
27
+ return err;
28
+ }
29
+ /** Await a gated call, reporting the feature refusal cleanly. */
30
+ export async function gated(call) {
31
+ try {
32
+ return await call;
33
+ }
34
+ catch (err) {
35
+ throw clientsGateError(err);
36
+ }
37
+ }
38
+ /**
39
+ * Pick one client by id or exact name. Ids win, then active names (unique
40
+ * upstream), then an archived name when only one matches. Pure so the rules
41
+ * are testable without a control plane.
42
+ */
43
+ export function matchClient(clients, ref) {
44
+ const byId = clients.find((c) => c.id === ref);
45
+ if (byId)
46
+ return byId;
47
+ const named = clients.filter((c) => c.name === ref);
48
+ const active = named.filter((c) => c.archivedAt === null);
49
+ if (active.length === 1 && active[0])
50
+ return active[0];
51
+ if (active.length === 0 && named.length === 1 && named[0])
52
+ return named[0];
53
+ if (named.length > 1) {
54
+ throw new Error(`More than one client is named "${ref}". Use its id (see qoren clients list --archived).`);
55
+ }
56
+ throw new Error(`No client has the id or name "${ref}". Run qoren clients list to see them.`);
57
+ }
58
+ /** Look a client up by id or exact name, archived ones included. */
59
+ export async function resolveClient(ctx, ref) {
60
+ const clients = await gated(ctx.qoren.clients.list({ includeArchived: true }));
61
+ return matchClient(clients, ref);
62
+ }
63
+ /** Pick one environment by id or exact name. */
64
+ export function matchEnvironment(machines, ref) {
65
+ const byId = machines.find((m) => m.id === ref);
66
+ if (byId)
67
+ return byId;
68
+ const named = machines.filter((m) => m.name === ref);
69
+ if (named.length === 1 && named[0])
70
+ return named[0];
71
+ if (named.length > 1) {
72
+ throw new Error(`More than one environment is named "${ref}". Use its id (see qoren env ls).`);
73
+ }
74
+ throw new Error(`No environment has the id or name "${ref}". Run qoren env ls to see them.`);
75
+ }
76
+ const DAY_MS = 86_400_000;
77
+ const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
78
+ /**
79
+ * The window for `qoren account costs`, as unix ms.
80
+ *
81
+ * Accepts any ISO date or date-time. A bare date for --to means the whole of
82
+ * that day (UTC), because "--to 2026-09-30" read as midnight would silently
83
+ * leave the 30th out. With nothing given, the last 30 days.
84
+ */
85
+ export function parseCostWindow(from, to, now = Date.now()) {
86
+ const parse = (value, flag) => {
87
+ const ms = Date.parse(value);
88
+ if (Number.isNaN(ms)) {
89
+ throw new Error(`${flag} must be an ISO date such as 2026-09-01, not "${value}".`);
90
+ }
91
+ return ms;
92
+ };
93
+ const end = to === undefined
94
+ ? now
95
+ : parse(to, "--to") + (DATE_ONLY.test(to.trim()) ? DAY_MS : 0);
96
+ const start = from === undefined ? end - 30 * DAY_MS : parse(from, "--from");
97
+ if (start >= end)
98
+ throw new Error("--from must be before --to.");
99
+ return { from: start, to: end };
100
+ }
101
+ /**
102
+ * The rows `qoren account costs` prints: each client by spend, then the
103
+ * environments with no client, then account-level spend, then spend from
104
+ * before cost tracking (only when there is some), then the total.
105
+ */
106
+ export function costRows(costs) {
107
+ const named = costs.customers
108
+ .filter((c) => c.customerId !== null)
109
+ .map((c) => ({ label: c.name ?? c.customerId ?? "", credits: c.credits }))
110
+ .sort((a, b) => b.credits - a.credits);
111
+ const unassigned = costs.customers
112
+ .filter((c) => c.customerId === null)
113
+ .reduce((sum, c) => sum + c.credits, 0);
114
+ return [
115
+ ...named,
116
+ { label: "No client", credits: unassigned },
117
+ { label: "Account", credits: costs.account.credits },
118
+ ...(costs.beforeTracking.credits > 0
119
+ ? [{ label: "Before client tracking", credits: costs.beforeTracking.credits }]
120
+ : []),
121
+ { label: "Total", credits: costs.totalCredits, total: true },
122
+ ];
123
+ }
124
+ /** The categories, in the order the console lists them. */
125
+ const CATEGORIES = [
126
+ { key: "environment", label: "Hosting" },
127
+ { key: "llm", label: "Models" },
128
+ { key: "webSearch", label: "Web search" },
129
+ { key: "runs", label: "Custom agent runs" },
130
+ { key: "tools", label: "Custom agent tools" },
131
+ ];
132
+ /**
133
+ * The whole window by category: every client, no client, the account line
134
+ * and spend from before tracking. Categories with no spend are left out.
135
+ */
136
+ export function categoryRows(costs) {
137
+ const all = [
138
+ ...costs.customers.map((c) => c.byKind),
139
+ costs.account.byKind,
140
+ costs.beforeTracking.byKind,
141
+ ];
142
+ return CATEGORIES.map(({ key, label }) => ({
143
+ label,
144
+ credits: all.reduce((sum, b) => sum + b[key], 0),
145
+ })).filter((r) => r.credits > 0);
146
+ }
147
+ /** Credits to two decimal places at most, without trailing zeros. */
148
+ export const formatCredits = (credits) => String(Math.round(credits * 100) / 100);
149
+ /** Dollars are credits / 1000. */
150
+ export const formatDollars = (credits) => `$${(credits / 1000).toFixed(2)}`;
151
+ const day = (ms) => new Date(ms).toISOString().slice(0, 10);
152
+ /** Print a costs response as tables plus the caveats a reader needs. */
153
+ export function renderCosts(costs) {
154
+ note(dim(`${day(costs.from)} to ${day(costs.to)}`));
155
+ costTable(costRows(costs), "client");
156
+ const categories = categoryRows(costs);
157
+ if (categories.length > 0) {
158
+ process.stdout.write("\n");
159
+ costTable(categories, "category");
160
+ }
161
+ if (costs.trackingSince === null) {
162
+ note(dim("No spend has been attributed to clients yet."));
163
+ }
164
+ else if (costs.trackingSince > costs.from) {
165
+ note(dim(`Spend is broken down by client from ${day(costs.trackingSince)}; earlier spend is under "Before client tracking".`));
166
+ }
167
+ if (costs.beforeTracking.estimated) {
168
+ note(dim("Model spend from before client tracking is estimated from the raw model cost."));
169
+ }
170
+ if (costs.pendingSettlements > 0) {
171
+ note(dim(`${String(costs.pendingSettlements)} ${costs.pendingSettlements === 1 ? "charge is" : "charges are"} still settling and not included above.`));
172
+ }
173
+ note(dim("Mailbox charges and the plan fee are not included; see Clients in the console."));
174
+ }
175
+ function costTable(rows, header) {
176
+ table(rows, [
177
+ {
178
+ header,
179
+ value: (r) => (r.total ? bold(r.label) : r.label),
180
+ },
181
+ {
182
+ header: "credits",
183
+ value: (r) => {
184
+ const text = formatCredits(r.credits);
185
+ return r.total ? bold(text) : text;
186
+ },
187
+ },
188
+ {
189
+ header: "dollars",
190
+ value: (r) => {
191
+ const text = formatDollars(r.credits);
192
+ return r.total ? bold(text) : text;
193
+ },
194
+ },
195
+ ]);
196
+ }
197
+ function clientTable(rows, showStatus) {
198
+ table(rows, [
199
+ { header: "id", value: (c) => c.id },
200
+ { header: "name", value: (c) => c.name },
201
+ { header: "email", value: (c) => c.contactEmail ?? "" },
202
+ { header: "environments", value: (c) => String(c.environmentCount) },
203
+ { header: "agents", value: (c) => String(c.agentCount) },
204
+ ...(showStatus
205
+ ? [
206
+ {
207
+ header: "status",
208
+ value: (c) => (c.archivedAt ? "archived" : "active"),
209
+ },
210
+ ]
211
+ : []),
212
+ { header: "age", value: (c) => age(c.createdAt) },
213
+ ]);
214
+ }
215
+ function clientDetails(c) {
216
+ details([
217
+ ["Id", c.id],
218
+ ["Name", c.name],
219
+ ["Email", c.contactEmail ?? ""],
220
+ ["Notes", c.notes ?? ""],
221
+ ["Environments", String(c.environmentCount)],
222
+ ["Agents", String(c.agentCount)],
223
+ ["Status", c.archivedAt ? `archived ${c.archivedAt}` : "active"],
224
+ ]);
225
+ }
226
+ export function clientsCommands(program, global) {
227
+ const clients = program
228
+ .command("clients")
229
+ .alias("client")
230
+ .description("Manage the clients your environments are run for");
231
+ clients
232
+ .command("list")
233
+ .alias("ls")
234
+ .description("List your clients")
235
+ .option("--archived", "include archived clients")
236
+ .action((options) => run(async () => {
237
+ const ctx = requireContext(global());
238
+ const rows = await gated(ctx.qoren.clients.list({ includeArchived: options.archived === true }));
239
+ emit(rows, () => clientTable(rows, options.archived === true));
240
+ })());
241
+ clients
242
+ .command("create <name>")
243
+ .description("Add a client")
244
+ .option("--email <email>", "contact email")
245
+ .option("--notes <notes>", "free-form notes")
246
+ .action((name, options) => run(async () => {
247
+ const ctx = requireContext(global());
248
+ const created = await gated(ctx.qoren.clients.create({
249
+ name,
250
+ ...(options.email !== undefined
251
+ ? { contactEmail: options.email }
252
+ : {}),
253
+ ...(options.notes !== undefined ? { notes: options.notes } : {}),
254
+ }));
255
+ emit(created, () => {
256
+ clientDetails(created);
257
+ note(`Client ${bold(created.name)} added. Assign an environment with qoren env assign <environment> ${created.id}.`);
258
+ });
259
+ })());
260
+ clients
261
+ .command("rename <client> <name>")
262
+ .description("Rename a client (by id or current name)")
263
+ .action((ref, name) => run(async () => {
264
+ const ctx = requireContext(global());
265
+ const client = await resolveClient(ctx, ref);
266
+ const updated = await gated(ctx.qoren.clients.update(client.id, { name }));
267
+ emit(updated, () => note(`Renamed to ${bold(updated.name)}.`));
268
+ })());
269
+ clients
270
+ .command("archive <client>")
271
+ .description("Archive a client (by id or name); its environments must be unassigned first")
272
+ .action((ref) => run(async () => {
273
+ const ctx = requireContext(global());
274
+ const client = await resolveClient(ctx, ref);
275
+ const archived = await gated(ctx.qoren.clients.archive(client.id));
276
+ emit(archived, () => note(`Client ${bold(archived.name)} archived. Its cost history is kept.`));
277
+ })());
278
+ clients
279
+ .command("hologram <client>")
280
+ .description("Show, create or revoke a client's public hologram link (account owners only)")
281
+ .option("--new", "create the link, or replace it (the old URL stops working)")
282
+ .option("--revoke", "switch the link off")
283
+ .action((ref, options) => run(async () => {
284
+ if (options.new && options.revoke) {
285
+ throw new Error("Use --new or --revoke, not both.");
286
+ }
287
+ const ctx = requireContext(global());
288
+ const client = await resolveClient(ctx, ref);
289
+ const link = await gated(options.revoke
290
+ ? ctx.qoren.clients.revokeHologramLink(client.id)
291
+ : options.new
292
+ ? ctx.qoren.clients.createHologramLink(client.id)
293
+ : ctx.qoren.clients.hologramLink(client.id));
294
+ emit(link, () => hologramDetails(client, link, options.revoke === true));
295
+ })());
296
+ }
297
+ /** What `qoren clients hologram` prints. The URL alone goes to stdout, so it can be piped. */
298
+ export function hologramDetails(client, link, revoked) {
299
+ if (!link.active) {
300
+ note(revoked
301
+ ? `The hologram link for ${bold(client.name)} is off. Its URL no longer works.`
302
+ : `${bold(client.name)} has no hologram link. Create one with qoren clients hologram ${client.id} --new.`);
303
+ return;
304
+ }
305
+ if (link.url)
306
+ process.stdout.write(`${link.url}\n`);
307
+ else
308
+ note(`The link for ${bold(client.name)} is on, but its URL cannot be shown again. Replace it with --new to get a new URL.`);
309
+ note(dim(`Anyone with this URL sees ${client.name}'s environments and agents, live, without signing in. Created ${link.createdAt ?? ""}.`));
310
+ }
311
+ //# sourceMappingURL=clients.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.js","sourceRoot":"","sources":["../../src/commands/clients.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,GAMX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,GAAG,EAAoC,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1E,6EAA6E;AAC7E,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,2DAA2D;AAE3D,2DAA2D;AAC3D,MAAM,CAAC,MAAM,gBAAgB,GAAG,2CAA2C,CAAC;AAE5E;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,IACE,GAAG,YAAY,UAAU;QACzB,GAAG,CAAC,MAAM,KAAK,GAAG;QAClB,sEAAsE;QACtE,iBAAiB;QACjB,CAAC,GAAG,CAAC,IAAI,KAAK,yBAAyB;YACrC,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAC/C,CAAC;QACD,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,KAAK,CAAI,IAAgB;IAC7C,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,OAAuB,EACvB,GAAW;IAEX,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;IAC/C,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC;IAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,kCAAkC,GAAG,oDAAoD,CAC1F,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,KAAK,CACb,iCAAiC,GAAG,wCAAwC,CAC7E,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAY,EACZ,GAAW;IAEX,MAAM,OAAO,GAAG,MAAM,KAAK,CACzB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAClD,CAAC;IACF,OAAO,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,gBAAgB,CAAC,QAAmB,EAAE,GAAW;IAC/D,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;IAChD,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IACpD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,uCAAuC,GAAG,mCAAmC,CAC9E,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,KAAK,CACb,sCAAsC,GAAG,kCAAkC,CAC5E,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,SAAS,GAAG,qBAAqB,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAwB,EACxB,EAAsB,EACtB,MAAc,IAAI,CAAC,GAAG,EAAE;IAExB,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,IAAY,EAAU,EAAE;QACpD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,iDAAiD,KAAK,IAAI,CAClE,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IACF,MAAM,GAAG,GACP,EAAE,KAAK,SAAS;QACd,CAAC,CAAC,GAAG;QACL,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC7E,IAAI,KAAK,IAAI,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;AAClC,CAAC;AAID;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAkB;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC;SACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,UAAU,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;SACzE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS;SAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC;SACpC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC1C,OAAO;QACL,GAAG,KAAK;QACR,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE;QAC3C,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE;QACpD,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC;YAClC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,OAAO,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YAC9E,CAAC,CAAC,EAAE,CAAC;QACP,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE;KAC7D,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,GAAgD;IAC9D,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE;IACxC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC/B,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE;IACzC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE;IAC3C,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE;CAC9C,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAkB;IAC7C,MAAM,GAAG,GAAG;QACV,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QACvC,KAAK,CAAC,OAAO,CAAC,MAAM;QACpB,KAAK,CAAC,cAAc,CAAC,MAAM;KAC5B,CAAC;IACF,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACzC,KAAK;QACL,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;KACjD,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAe,EAAU,EAAE,CACvD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAE1C,kCAAkC;AAClC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAe,EAAU,EAAE,CACvD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;AAEpC,MAAM,GAAG,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAE5E,wEAAwE;AACxE,MAAM,UAAU,WAAW,CAAC,KAAkB;IAC5C,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACpD,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,KAAK,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;IAC5D,CAAC;SAAM,IAAI,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,CACF,GAAG,CACD,uCAAuC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,oDAAoD,CACpH,CACF,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;QACnC,IAAI,CACF,GAAG,CACD,+EAA+E,CAChF,CACF,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC;QACjC,IAAI,CACF,GAAG,CACD,GAAG,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,KAAK,CAAC,kBAAkB,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,yCAAyC,CAC7I,CACF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,gFAAgF,CAAC,CAAC,CAAC;AAC9F,CAAC;AAED,SAAS,SAAS,CAAC,IAAe,EAAE,MAAc;IAChD,KAAK,CAAC,IAAI,EAAE;QACV;YACE,MAAM;YACN,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;SAClD;QACD;YACE,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;gBACX,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBACtC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACrC,CAAC;SACF;QACD;YACE,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;gBACX,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBACtC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACrC,CAAC;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,IAAoB,EAAE,UAAmB;IAC5D,KAAK,CAAC,IAAI,EAAE;QACV,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QACpC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;QACxC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,EAAE;QACvD,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE;QACpE,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;QACxD,GAAG,CAAC,UAAU;YACZ,CAAC,CAAC;gBACE;oBACE,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,CAAC,CAAe,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;iBACnE;aACF;YACH,CAAC,CAAC,EAAE,CAAC;QACP,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE;KAClD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,CAAe;IACpC,OAAO,CAAC;QACN,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QACZ,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC;QAChB,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC;QAC/B,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACxB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;QAC5C,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAChC,CAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;KACjE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,MAA2B;IAC3E,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,SAAS,CAAC;SAClB,KAAK,CAAC,QAAQ,CAAC;SACf,WAAW,CAAC,kDAAkD,CAAC,CAAC;IAEnE,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,KAAK,CAAC,IAAI,CAAC;SACX,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,YAAY,EAAE,0BAA0B,CAAC;SAChD,MAAM,CAAC,CAAC,OAA+B,EAAE,EAAE,CAC1C,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,MAAM,KAAK,CACtB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC,CACvE,CAAC;QACF,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,EAAE,CACL,CAAC;IAEJ,OAAO;SACJ,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,cAAc,CAAC;SAC3B,MAAM,CAAC,iBAAiB,EAAE,eAAe,CAAC;SAC1C,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;SAC5C,MAAM,CAAC,CAAC,IAAY,EAAE,OAA2C,EAAE,EAAE,CACpE,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,KAAK,CACzB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACvB,IAAI;YACJ,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS;gBAC7B,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,KAAK,EAAE;gBACjC,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC,CACH,CAAC;QACF,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACjB,aAAa,CAAC,OAAO,CAAC,CAAC;YACvB,IAAI,CACF,UAAU,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,qEAAqE,OAAO,CAAC,EAAE,GAAG,CAC/G,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,EAAE,CACL,CAAC;IAEJ,OAAO;SACJ,OAAO,CAAC,wBAAwB,CAAC;SACjC,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,CAAC,GAAW,EAAE,IAAY,EAAE,EAAE,CACpC,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,KAAK,CACzB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAC9C,CAAC;QACF,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,EAAE,CACL,CAAC;IAEJ,OAAO;SACJ,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CACV,6EAA6E,CAC9E;SACA,MAAM,CAAC,CAAC,GAAW,EAAE,EAAE,CACtB,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAClB,IAAI,CAAC,UAAU,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAC1E,CAAC;IACJ,CAAC,CAAC,EAAE,CACL,CAAC;IAEJ,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CACV,8EAA8E,CAC/E;SACA,MAAM,CAAC,OAAO,EAAE,4DAA4D,CAAC;SAC7E,MAAM,CAAC,UAAU,EAAE,qBAAqB,CAAC;SACzC,MAAM,CAAC,CAAC,GAAW,EAAE,OAA4C,EAAE,EAAE,CACpE,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,KAAK,CACtB,OAAO,CAAC,MAAM;YACZ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;YACjD,CAAC,CAAC,OAAO,CAAC,GAAG;gBACX,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;gBACjD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAChD,CAAC;QACF,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,EAAE,CACL,CAAC;AACN,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAC7B,MAAoB,EACpB,IAAwB,EACxB,OAAgB;IAEhB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,IAAI,CACF,OAAO;YACL,CAAC,CAAC,yBAAyB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC;YAC/E,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iEAAiE,MAAM,CAAC,EAAE,SAAS,CAC5G,CAAC;QACF,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;;QAElD,IAAI,CACF,gBAAgB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oFAAoF,CACtH,CAAC;IACJ,IAAI,CACF,GAAG,CACD,6BAA6B,MAAM,CAAC,IAAI,iEAAiE,IAAI,CAAC,SAAS,IAAI,EAAE,GAAG,CACjI,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ import { type GlobalOptions } from "../context.js";
3
+ export declare function consoleCommand(program: Command, global: () => GlobalOptions): void;
4
+ //# sourceMappingURL=console.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/commands/console.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAUxE,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,QAoB3E"}
@@ -0,0 +1,26 @@
1
+ import { requireContext, run } from "../context.js";
2
+ import { isJsonMode } from "../output.js";
3
+ // The interactive console.
4
+ //
5
+ // Ink and React are a good deal heavier than the rest of this package, and most
6
+ // invocations are a single command in a script that will never draw a frame. So
7
+ // the console is imported dynamically: `qoren env ls --json` pays nothing for
8
+ // it, and only someone who actually asked for a console waits for it to load.
9
+ export function consoleCommand(program, global) {
10
+ program
11
+ .command("tui")
12
+ .alias("console")
13
+ .description("Open the interactive console")
14
+ .action(() => run(async () => {
15
+ if (isJsonMode()) {
16
+ // --json promises stdout carries data and nothing else. A console
17
+ // that took over the screen would break that promise rather than
18
+ // bend it, so say so instead of half-honouring both.
19
+ throw new Error("The console cannot run with --json. Drop the flag, or use the commands.");
20
+ }
21
+ const ctx = requireContext(global());
22
+ const { runConsole } = await import("../tui/index.js");
23
+ await runConsole(ctx);
24
+ })());
25
+ }
26
+ //# sourceMappingURL=console.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/commands/console.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,GAAG,EAAsB,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,2BAA2B;AAC3B,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,8EAA8E;AAC9E,8EAA8E;AAE9E,MAAM,UAAU,cAAc,CAAC,OAAgB,EAAE,MAA2B;IAC1E,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,KAAK,CAAC,SAAS,CAAC;SAChB,WAAW,CAAC,8BAA8B,CAAC;SAC3C,MAAM,CAAC,GAAG,EAAE,CACX,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,kEAAkE;YAClE,iEAAiE;YACjE,qDAAqD;YACrD,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACvD,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC,CAAC,EAAE,CACL,CAAC;AACN,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { Command } from "commander";
2
+ import { type AddChannelInput, type DesignRun } from "@qoren/sdk";
3
+ import { type GlobalOptions } from "../context.js";
4
+ export declare function isTerminalRun(status: string): boolean;
5
+ /** How long a run took, or has been going. */
6
+ export declare function runDuration(r: Pick<DesignRun, "startedAt" | "endedAt">, now?: number): string;
7
+ /** A run's status with what it waits on, e.g. "waiting (approval)". */
8
+ export declare function runStatus(r: Pick<DesignRun, "status" | "waitingOn">): string;
9
+ export declare function printRun(r: DesignRun): void;
10
+ /**
11
+ * Poll a run until it finishes or the time is up. Says once what a waiting run
12
+ * waits on, because an approval can take hours and silence looks like a hang.
13
+ * `read` fetches the run: an agent's run or a design's test run.
14
+ */
15
+ export declare function waitForRun(read: () => Promise<DesignRun>, timeoutSeconds: number): Promise<{
16
+ run: DesignRun;
17
+ finished: boolean;
18
+ }>;
19
+ /** Read `--timeout` for a `--wait`. */
20
+ export declare function parseWaitTimeout(value: string): number;
21
+ /** The end of a waited-for run, for a person: outcome, cost, result. Sets the
22
+ * exit code when it did not succeed or is still going. */
23
+ export declare function reportWaitedRun({ run: r, finished }: {
24
+ run: DesignRun;
25
+ finished: boolean;
26
+ }, timeoutText: string, checkBack: string, options?: {
27
+ trace?: boolean;
28
+ }): void;
29
+ export type ChannelAddOptions = {
30
+ botToken?: string;
31
+ signingSecret?: string;
32
+ guild?: string;
33
+ botName?: string;
34
+ allMessages?: boolean;
35
+ };
36
+ /** The connect request for `channel add`, refusing what the control plane
37
+ * would refuse before anything is sent: an unknown kind, no bot token, a Slack
38
+ * app without its signing secret, or a Discord bot without its server id
39
+ * (the bot only ignores other servers when it is bound to one). */
40
+ export declare function channelInput(kind: string, options: ChannelAddOptions): AddChannelInput;
41
+ export declare function customAgentCommands(agent: Command, global: () => GlobalOptions): void;
42
+ //# sourceMappingURL=customAgent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customAgent.d.ts","sourceRoot":"","sources":["../../src/commands/customAgent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAEL,KAAK,eAAe,EAGpB,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AA8BxE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,8CAA8C;AAC9C,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,GAAG,SAAS,CAAC,EAAE,GAAG,SAAa,GAAG,MAAM,CAMjG;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,WAAW,CAAC,GAAG,MAAM,CAI5E;AA0BD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CA2B3C;AAID;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,EAC9B,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,GAAG,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAchD;AAED,uCAAuC;AACvC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;0DAC0D;AAC1D,wBAAgB,eAAe,CAC7B,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,GAAG,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,EAC3D,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,IAAI,CAeN;AAWD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF;;;mEAGmE;AACnE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,eAAe,CAkCtF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,QA6U9E"}