@letterstory/cli 0.147.0 → 0.148.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cli.mjs +3 -1
- package/lib/commands/org.mjs +31 -1
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
|
|
66
66
|
// Matches cli/package.json; publish-cli.yml rewrites both to the published version.
|
|
67
67
|
// Matches cli/package.json; publish-cli.yml rewrites both to the published version.
|
|
68
|
-
export const VERSION = "0.
|
|
68
|
+
export const VERSION = "0.148.0";
|
|
69
69
|
|
|
70
70
|
// Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
|
|
71
71
|
// can't accidentally swallow the id as --json's value. Every `type: "bool"` flag (and its
|
|
@@ -1107,6 +1107,8 @@ Seers (event-driven signals -> drafts):
|
|
|
1107
1107
|
Usage billing: plan, this period against the
|
|
1108
1108
|
allowance and spend cap, failed payments; set
|
|
1109
1109
|
the cap (admins) or ask the admins for more
|
|
1110
|
+
org billing usage This period by product and collection: quantities,
|
|
1111
|
+
and tokens and dollars when billed by usage
|
|
1110
1112
|
org linear [teams [--team <id|key>] | set --team <id|key> [--project <id>|none] | disconnect]
|
|
1111
1113
|
Where Letter files Linear issues (connect in Settings)
|
|
1112
1114
|
org diff <file|dir> What applying a bundle would change (reads only)
|
package/lib/commands/org.mjs
CHANGED
|
@@ -28,6 +28,7 @@ export const ARGS = {
|
|
|
28
28
|
describe_org_config_fields: {},
|
|
29
29
|
get_org_config_source: {},
|
|
30
30
|
get_billing_payments: {},
|
|
31
|
+
get_billing: {},
|
|
31
32
|
set_billing_spend_cap: {
|
|
32
33
|
cap_usd: { value: (_flags, positionals) => capFrom(requirePositional(positionals, 0, "dollars|off")) },
|
|
33
34
|
reason: { flag: "why" },
|
|
@@ -111,7 +112,7 @@ const usd = (n) => `$${Number(n).toFixed(2)}`;
|
|
|
111
112
|
* `org billing`: the org's plan on Lago, this period against its allowance and spend cap, whether
|
|
112
113
|
* it is past due, and its failed payments (get_billing_payments). `org billing cap <dollars|off>`
|
|
113
114
|
* sets the cap (set_billing_spend_cap, admins); `org billing request` asks the admins for more
|
|
114
|
-
* (request_billing_tokens).
|
|
115
|
+
* (request_billing_tokens); `org billing usage` is this period by product and collection (get_billing).
|
|
115
116
|
*/
|
|
116
117
|
async function orgBilling(ctx) {
|
|
117
118
|
const { client, flags, io, positionals } = ctx;
|
|
@@ -149,6 +150,12 @@ async function orgBilling(ctx) {
|
|
|
149
150
|
printResult(io, flags, result, (r) => `Asked ${r.emailedTo} admin${r.emailedTo === 1 ? "" : "s"} for more.`);
|
|
150
151
|
return 0;
|
|
151
152
|
}
|
|
153
|
+
if (positionals[0] === "usage") {
|
|
154
|
+
refuseUnknownFlags(ctx, ARGS.get_billing, []);
|
|
155
|
+
const result = await client.callTool("get_billing", argsFromFlags(ARGS.get_billing, flags, []));
|
|
156
|
+
printResult(io, flags, result, billingUsageText);
|
|
157
|
+
return 0;
|
|
158
|
+
}
|
|
152
159
|
refuseUnknownFlags(ctx, {}, []);
|
|
153
160
|
const result = await client.callTool("get_billing_payments", {});
|
|
154
161
|
printResult(io, flags, result, (r) =>
|
|
@@ -180,6 +187,29 @@ async function orgBilling(ctx) {
|
|
|
180
187
|
return 0;
|
|
181
188
|
}
|
|
182
189
|
|
|
190
|
+
const tokensOrQty = (p) => `${p.billableQuantity}${p.tokens === null ? "" : ` ${p.tokens} tokens`}`;
|
|
191
|
+
|
|
192
|
+
/** `org billing usage` as text: the period, the totals, then each product and each collection. */
|
|
193
|
+
function billingUsageText(r) {
|
|
194
|
+
const lines = [
|
|
195
|
+
`${r.plan ? `Plan: ${r.plan.name}${r.plan.ratio !== 1 ? ` (${r.plan.ratio}x)` : ""}. ` : ""}This period: ${r.period.from.slice(0, 10)} to ${r.period.to.slice(0, 10)}${r.period.basis === "ours" ? " (Lago unreadable: our own rating)" : ""}.`,
|
|
196
|
+
];
|
|
197
|
+
if (r.tokens)
|
|
198
|
+
lines.push(
|
|
199
|
+
`Tokens: ${r.tokens.used} used of ${r.tokens.allowance} included${r.tokens.complimentary ? ` (+${r.tokens.complimentary} complimentary)` : ""}${r.tokens.arriving ? ` (${r.tokens.arriving} of them still being counted)` : ""}${r.tokens.running ? `, ${r.tokens.running} held by running work` : ""}.`
|
|
200
|
+
);
|
|
201
|
+
else lines.push("Not billed by usage: quantities only.");
|
|
202
|
+
if (r.usd) lines.push(`Plan fee ${usd(r.usd.planFee)}; overage so far ${usd(r.usd.overage)}.`);
|
|
203
|
+
if (r.byProduct.length === 0) return [...lines, "No usage this period."].join("\n");
|
|
204
|
+
lines.push("", "By product:", ...r.byProduct.map((p) => ` ${p.label} ${tokensOrQty(p)}`));
|
|
205
|
+
lines.push("", "By collection:");
|
|
206
|
+
for (const c of r.byCollection) {
|
|
207
|
+
lines.push(` ${c.name}${c.tokens === null ? "" : ` ${c.tokens} tokens`}`);
|
|
208
|
+
for (const p of c.products) lines.push(` ${p.label} ${tokensOrQty(p)}`);
|
|
209
|
+
}
|
|
210
|
+
return lines.join("\n");
|
|
211
|
+
}
|
|
212
|
+
|
|
183
213
|
/** `org fields [section]`: what each setting in the bundle means (describe_org_config_fields). */
|
|
184
214
|
async function orgFields(ctx) {
|
|
185
215
|
const { client, flags, io, positionals } = ctx;
|