@solidnumber/cli 2.17.0 → 2.19.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 (54) hide show
  1. package/README.md +15 -0
  2. package/dist/commands/accounting.d.ts +10 -1
  3. package/dist/commands/accounting.d.ts.map +1 -1
  4. package/dist/commands/accounting.js +77 -52
  5. package/dist/commands/accounting.js.map +1 -1
  6. package/dist/commands/agent.js +214 -0
  7. package/dist/commands/agent.js.map +1 -1
  8. package/dist/commands/apply.d.ts +10 -0
  9. package/dist/commands/apply.d.ts.map +1 -1
  10. package/dist/commands/apply.js +436 -51
  11. package/dist/commands/apply.js.map +1 -1
  12. package/dist/commands/books.d.ts +24 -0
  13. package/dist/commands/books.d.ts.map +1 -0
  14. package/dist/commands/books.js +242 -0
  15. package/dist/commands/books.js.map +1 -0
  16. package/dist/commands/call.js +11 -0
  17. package/dist/commands/call.js.map +1 -1
  18. package/dist/commands/company.js +84 -22
  19. package/dist/commands/company.js.map +1 -1
  20. package/dist/commands/dispatch_shortcuts.d.ts +7 -0
  21. package/dist/commands/dispatch_shortcuts.d.ts.map +1 -1
  22. package/dist/commands/dispatch_shortcuts.js +2 -0
  23. package/dist/commands/dispatch_shortcuts.js.map +1 -1
  24. package/dist/commands/how-to.js +1 -1
  25. package/dist/commands/how-to.js.map +1 -1
  26. package/dist/commands/update.d.ts +22 -0
  27. package/dist/commands/update.d.ts.map +1 -0
  28. package/dist/commands/update.js +197 -0
  29. package/dist/commands/update.js.map +1 -0
  30. package/dist/index.js +7 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/lib/api-client.d.ts +43 -0
  33. package/dist/lib/api-client.d.ts.map +1 -1
  34. package/dist/lib/api-client.js +39 -0
  35. package/dist/lib/api-client.js.map +1 -1
  36. package/dist/lib/apply/engine.d.ts +13 -0
  37. package/dist/lib/apply/engine.d.ts.map +1 -1
  38. package/dist/lib/apply/engine.js +122 -13
  39. package/dist/lib/apply/engine.js.map +1 -1
  40. package/dist/lib/apply/lock.d.ts +107 -0
  41. package/dist/lib/apply/lock.d.ts.map +1 -0
  42. package/dist/lib/apply/lock.js +285 -0
  43. package/dist/lib/apply/lock.js.map +1 -0
  44. package/dist/lib/apply/registry.d.ts +62 -5
  45. package/dist/lib/apply/registry.d.ts.map +1 -1
  46. package/dist/lib/apply/registry.js +151 -1
  47. package/dist/lib/apply/registry.js.map +1 -1
  48. package/dist/lib/config.d.ts +3 -0
  49. package/dist/lib/config.d.ts.map +1 -1
  50. package/dist/lib/config.js +15 -0
  51. package/dist/lib/config.js.map +1 -1
  52. package/package.json +1 -1
  53. package/platform-docs/ai.txt +2 -2
  54. package/platform-docs/llms.txt +16 -12
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The books from the terminal — money in, money out, one picture.
3
+ *
4
+ * solid books summary in vs out, owed to you, you owe
5
+ * solid invoices list|get|aging|summary money in (reads)
6
+ * solid invoices pay|cancel money in (writes, --confirm)
7
+ * solid expenses list|get|aging|summary|vendors money out (reads)
8
+ * solid expenses file|pay|void money out (writes, --confirm)
9
+ *
10
+ * ⭐ Solid# is the book of record for AR and AP — every company has these,
11
+ * with or without QuickBooks / Xero / FreshBooks (those are optional mirrors:
12
+ * `solid accounting`). Every command is a thin wrapper over a verb the same
13
+ * company's ADA, MCP and web use, so the answer is identical everywhere:
14
+ * reads → manifest verbs (invoice.*, expense.*, vendor.list, books.summary)
15
+ * writes → ADA verbs through /api/v1/ada/cli-dispatch (invoice_record_payment,
16
+ * invoice_cancel, expense_create, bill_mark_paid, expense_void)
17
+ * Writes refuse to run without --confirm. They RECORD money — none pays anyone.
18
+ * Any verb without a shortcut: `solid agent dispatch <verb> --args '{…}' --confirm`.
19
+ */
20
+ import { Command } from 'commander';
21
+ export declare const booksCommand: Command;
22
+ export declare const invoicesCommand: Command;
23
+ export declare const expensesCommand: Command;
24
+ //# sourceMappingURL=books.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"books.d.ts","sourceRoot":"","sources":["../../src/commands/books.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BpC,eAAO,MAAM,YAAY,SACsF,CAAC;AAoBhH,eAAO,MAAM,eAAe,SAC2C,CAAC;AAuFxE,eAAO,MAAM,eAAe,SAC0B,CAAC"}
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.expensesCommand = exports.invoicesCommand = exports.booksCommand = void 0;
7
+ /**
8
+ * The books from the terminal — money in, money out, one picture.
9
+ *
10
+ * solid books summary in vs out, owed to you, you owe
11
+ * solid invoices list|get|aging|summary money in (reads)
12
+ * solid invoices pay|cancel money in (writes, --confirm)
13
+ * solid expenses list|get|aging|summary|vendors money out (reads)
14
+ * solid expenses file|pay|void money out (writes, --confirm)
15
+ *
16
+ * ⭐ Solid# is the book of record for AR and AP — every company has these,
17
+ * with or without QuickBooks / Xero / FreshBooks (those are optional mirrors:
18
+ * `solid accounting`). Every command is a thin wrapper over a verb the same
19
+ * company's ADA, MCP and web use, so the answer is identical everywhere:
20
+ * reads → manifest verbs (invoice.*, expense.*, vendor.list, books.summary)
21
+ * writes → ADA verbs through /api/v1/ada/cli-dispatch (invoice_record_payment,
22
+ * invoice_cancel, expense_create, bill_mark_paid, expense_void)
23
+ * Writes refuse to run without --confirm. They RECORD money — none pays anyone.
24
+ * Any verb without a shortcut: `solid agent dispatch <verb> --args '{…}' --confirm`.
25
+ */
26
+ const commander_1 = require("commander");
27
+ const chalk_1 = __importDefault(require("chalk"));
28
+ const command_kit_1 = require("../lib/command-kit");
29
+ const dispatch_shortcuts_1 = require("./dispatch_shortcuts");
30
+ function requireConfirm(options, what) {
31
+ if (!options.confirm) {
32
+ console.error(chalk_1.default.red(`Refusing to ${what} without --confirm.`));
33
+ process.exit(2);
34
+ }
35
+ }
36
+ function money(value, flag) {
37
+ const n = Number(String(value).replace(/[$,]/g, ''));
38
+ if (!Number.isFinite(n) || n <= 0) {
39
+ console.error(chalk_1.default.red(`${flag} must be an amount greater than 0 (got "${value}").`));
40
+ process.exit(2);
41
+ }
42
+ return n;
43
+ }
44
+ function present(entries) {
45
+ return Object.fromEntries(Object.entries(entries).filter(([, v]) => v !== undefined && v !== null && v !== ''));
46
+ }
47
+ // ── solid books ─────────────────────────────────────────────────────────────
48
+ exports.booksCommand = new commander_1.Command('books')
49
+ .description("The books — money in and out from Solid#'s own records (with or without an accounting system)");
50
+ exports.booksCommand
51
+ .command('summary')
52
+ .description('Invoiced / collected, spent / billed, what customers owe you, what you owe')
53
+ .option('--since <date>', 'YYYY-MM-DD')
54
+ .option('--until <date>', 'YYYY-MM-DD')
55
+ .option('--json', 'Output as JSON')
56
+ .action(async (options) => {
57
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('books.summary', present({ since: options.since, until: options.until }), options, 'Reading the books...');
58
+ });
59
+ (0, command_kit_1.appendExamples)(exports.booksCommand, [
60
+ { cmd: 'solid books summary', why: 'How am I doing — in, out, owed both ways' },
61
+ { cmd: 'solid books summary --since 2026-09-01 --until 2026-09-30', why: 'One month' },
62
+ ]);
63
+ // ── solid invoices (money in) ───────────────────────────────────────────────
64
+ exports.invoicesCommand = new commander_1.Command('invoices')
65
+ .description('Money in — invoices, who owes you, recording payments');
66
+ exports.invoicesCommand
67
+ .command('list')
68
+ .description('Invoices, newest first')
69
+ .option('--status <status>', 'draft | sent | viewed | partial_paid | paid | overdue | cancelled')
70
+ .option('--open', 'Only invoices with money still owed')
71
+ .option('--overdue', 'Only overdue invoices')
72
+ .option('--contact-id <id>', 'One customer (CRM contact id)')
73
+ .option('--limit <n>', 'How many', '50')
74
+ .option('--json', 'Output as JSON')
75
+ .action(async (options) => {
76
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('invoice.list', present({
77
+ status: options.status, open_only: options.open ? true : undefined,
78
+ overdue_only: options.overdue ? true : undefined,
79
+ contact_id: options.contactId ? Number(options.contactId) : undefined, limit: Number(options.limit),
80
+ }), options, 'Loading invoices...');
81
+ });
82
+ exports.invoicesCommand
83
+ .command('get <invoice_id>')
84
+ .description('One invoice with its lines and every payment on it')
85
+ .option('--json', 'Output as JSON')
86
+ .action(async (invoiceId, options) => {
87
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('invoice.get', { invoice_id: Number(invoiceId) }, options, `Loading invoice ${invoiceId}...`);
88
+ });
89
+ exports.invoicesCommand
90
+ .command('aging')
91
+ .description('What customers owe you, by how overdue')
92
+ .option('--as-of <date>', 'YYYY-MM-DD; default today')
93
+ .option('--json', 'Output as JSON')
94
+ .action(async (options) => {
95
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('invoice.receivables', present({ as_of: options.asOf }), options, 'Aging receivables...');
96
+ });
97
+ exports.invoicesCommand
98
+ .command('summary')
99
+ .description('Invoiced, collected and still owed — by customer, month or status')
100
+ .option('--since <date>', 'YYYY-MM-DD')
101
+ .option('--until <date>', 'YYYY-MM-DD')
102
+ .option('--group-by <by>', 'customer | month | status', 'customer')
103
+ .option('--json', 'Output as JSON')
104
+ .action(async (options) => {
105
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('invoice.summary', present({ since: options.since, until: options.until, group_by: options.groupBy }), options, 'Summarising money in...');
106
+ });
107
+ exports.invoicesCommand
108
+ .command('pay <invoice_id>')
109
+ .description('Record money a customer paid on an invoice (records it — charges no one)')
110
+ .requiredOption('--amount <n>', 'Amount received')
111
+ .option('--method <m>', 'cash | check | card | ach | bank_transfer | venmo | zelle | other', 'other')
112
+ .option('--date <date>', 'YYYY-MM-DD received; default today')
113
+ .option('--reference <ref>', 'Check or confirmation number')
114
+ .option('--notes <text>', 'Notes')
115
+ .option('--confirm', 'Required: actually record the payment')
116
+ .option('--json', 'Output as JSON')
117
+ .action(async (invoiceId, options) => {
118
+ requireConfirm(options, 'record a payment');
119
+ await (0, dispatch_shortcuts_1.dispatchVerbShortcut)('invoice_record_payment', present({
120
+ invoice_id: Number(invoiceId), amount: money(options.amount, '--amount'), method: options.method,
121
+ received_at: options.date, reference: options.reference, notes: options.notes,
122
+ }), options, `Recording a payment on invoice ${invoiceId}...`);
123
+ });
124
+ exports.invoicesCommand
125
+ .command('cancel <invoice_id>')
126
+ .description('Cancel an invoice — never deleted; the reason stays on it')
127
+ .requiredOption('--reason <text>', 'Why')
128
+ .option('--confirm', 'Required: actually cancel the invoice')
129
+ .option('--json', 'Output as JSON')
130
+ .action(async (invoiceId, options) => {
131
+ requireConfirm(options, 'cancel an invoice');
132
+ await (0, dispatch_shortcuts_1.dispatchVerbShortcut)('invoice_cancel', { invoice_id: Number(invoiceId), reason: options.reason }, options, `Cancelling invoice ${invoiceId}...`);
133
+ });
134
+ (0, command_kit_1.appendExamples)(exports.invoicesCommand, [
135
+ { cmd: 'solid invoices aging', why: 'Who owes you, and how late' },
136
+ { cmd: 'solid invoices list --overdue', why: 'Just the overdue ones' },
137
+ { cmd: 'solid invoices pay 31 --amount 500 --method check --reference 1042 --confirm', why: 'A check came in' },
138
+ ]);
139
+ // ── solid expenses (money out) ──────────────────────────────────────────────
140
+ exports.expensesCommand = new commander_1.Command('expenses')
141
+ .description('Money out — expenses, bills, vendors');
142
+ exports.expensesCommand
143
+ .command('list')
144
+ .description('Expenses and bills, newest first')
145
+ .option('--kind <kind>', 'expense | bill')
146
+ .option('--status <status>', 'draft | posted | paid | void')
147
+ .option('--deal-id <id>', 'One job')
148
+ .option('--since <date>', 'YYYY-MM-DD')
149
+ .option('--until <date>', 'YYYY-MM-DD')
150
+ .option('--limit <n>', 'How many', '50')
151
+ .option('--json', 'Output as JSON')
152
+ .action(async (options) => {
153
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('expense.list', present({
154
+ kind: options.kind, status: options.status, deal_id: options.dealId ? Number(options.dealId) : undefined,
155
+ since: options.since, until: options.until, limit: Number(options.limit),
156
+ }), options, 'Loading expenses...');
157
+ });
158
+ exports.expensesCommand
159
+ .command('get <purchase_id>')
160
+ .description('One expense or bill with its lines')
161
+ .option('--json', 'Output as JSON')
162
+ .action(async (purchaseId, options) => {
163
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('expense.get', { purchase_id: Number(purchaseId) }, options, `Loading ${purchaseId}...`);
164
+ });
165
+ exports.expensesCommand
166
+ .command('aging')
167
+ .description('Bills you owe, by how overdue')
168
+ .option('--as-of <date>', 'YYYY-MM-DD; default today')
169
+ .option('--json', 'Output as JSON')
170
+ .action(async (options) => {
171
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('expense.payables', present({ as_of: options.asOf }), options, 'Aging payables...');
172
+ });
173
+ exports.expensesCommand
174
+ .command('summary')
175
+ .description('Money out, paid and owed apart — by category, vendor, kind or job')
176
+ .option('--since <date>', 'YYYY-MM-DD')
177
+ .option('--until <date>', 'YYYY-MM-DD')
178
+ .option('--group-by <by>', 'category | vendor | kind | deal', 'category')
179
+ .option('--json', 'Output as JSON')
180
+ .action(async (options) => {
181
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('expense.summary', present({ since: options.since, until: options.until, group_by: options.groupBy }), options, 'Summarising money out...');
182
+ });
183
+ exports.expensesCommand
184
+ .command('vendors')
185
+ .description('The vendors this business buys from')
186
+ .option('--search <text>', 'Name contains')
187
+ .option('--json', 'Output as JSON')
188
+ .action(async (options) => {
189
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('vendor.list', present({ search: options.search }), options, 'Loading vendors...');
190
+ });
191
+ exports.expensesCommand
192
+ .command('file')
193
+ .description('Record money spent (expense, paid) or owed (--bill)')
194
+ .requiredOption('--vendor <name>', 'Who it was from')
195
+ .requiredOption('--amount <n>', 'The total')
196
+ .option('--bill', 'A bill still owed, instead of an expense already paid')
197
+ .option('--category <c>', 'materials | fuel | tools | meals | rent | software …')
198
+ .option('--date <date>', 'YYYY-MM-DD; default today')
199
+ .option('--due <date>', 'Bills: YYYY-MM-DD due')
200
+ .option('--reference <ref>', "The vendor's receipt or invoice number")
201
+ .option('--deal-id <id>', 'The job it was for')
202
+ .option('--notes <text>', 'Notes')
203
+ .option('--confirm', 'Required: actually record it')
204
+ .option('--json', 'Output as JSON')
205
+ .action(async (options) => {
206
+ requireConfirm(options, 'record an expense');
207
+ await (0, dispatch_shortcuts_1.dispatchVerbShortcut)('expense_create', present({
208
+ kind: options.bill ? 'bill' : 'expense', vendor_name: options.vendor, amount: money(options.amount, '--amount'),
209
+ category: options.category, purchase_date: options.date, due_date: options.due, reference: options.reference,
210
+ deal_id: options.dealId ? Number(options.dealId) : undefined, notes: options.notes,
211
+ }), options, `Recording ${options.bill ? 'a bill' : 'an expense'} from ${options.vendor}...`);
212
+ });
213
+ exports.expensesCommand
214
+ .command('pay <purchase_id>')
215
+ .description('A bill was paid (records it — pays no one)')
216
+ .option('--date <date>', 'YYYY-MM-DD paid; default today')
217
+ .option('--method <m>', 'card | cash | check | ach | company_card | personal_reimburse | other')
218
+ .option('--reference <ref>', 'Check or confirmation number')
219
+ .option('--confirm', 'Required: actually mark it paid')
220
+ .option('--json', 'Output as JSON')
221
+ .action(async (purchaseId, options) => {
222
+ requireConfirm(options, 'mark a bill paid');
223
+ await (0, dispatch_shortcuts_1.dispatchVerbShortcut)('bill_mark_paid', present({
224
+ purchase_id: Number(purchaseId), paid_at: options.date, payment_method: options.method, reference: options.reference,
225
+ }), options, `Marking ${purchaseId} paid...`);
226
+ });
227
+ exports.expensesCommand
228
+ .command('void <purchase_id>')
229
+ .description('Void an expense or bill — never deleted; the reason stays on it')
230
+ .requiredOption('--reason <text>', 'Why')
231
+ .option('--confirm', 'Required: actually void it')
232
+ .option('--json', 'Output as JSON')
233
+ .action(async (purchaseId, options) => {
234
+ requireConfirm(options, 'void a purchase');
235
+ await (0, dispatch_shortcuts_1.dispatchVerbShortcut)('expense_void', { purchase_id: Number(purchaseId), reason: options.reason }, options, `Voiding ${purchaseId}...`);
236
+ });
237
+ (0, command_kit_1.appendExamples)(exports.expensesCommand, [
238
+ { cmd: 'solid expenses aging', why: 'Bills you owe, and how late' },
239
+ { cmd: 'solid expenses file --vendor "Ferguson" --amount 110.70 --category materials --confirm', why: 'A receipt' },
240
+ { cmd: 'solid expenses pay 12 --method check --reference 2210 --confirm', why: 'A bill was paid' },
241
+ ]);
242
+ //# sourceMappingURL=books.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"books.js","sourceRoot":"","sources":["../../src/commands/books.ts"],"names":[],"mappings":"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"}
@@ -102,6 +102,17 @@ exports.callCommand
102
102
  const tone = route ? chalk_1.default.bold : chalk_1.default.yellow;
103
103
  console.log(` ${chalk_1.default.dim(step.node)} · pressed ${chalk_1.default.cyan(step.input)} → ${tone(dest)}`);
104
104
  }
105
+ // Routes that reach nothing. NOT an error and NOT a non-zero exit — a
106
+ // department named before it is wired up is ordinary work in progress, and
107
+ // failing CI on it would make the builder unusable. But the path above
108
+ // prints "→ department (Sales)" as though it works, and on a real call
109
+ // that caller is offered a message instead. Say so.
110
+ const unreachable = result.unreachable_routes || [];
111
+ if (unreachable.length > 0)
112
+ console.log('');
113
+ for (const u of unreachable) {
114
+ console.log(chalk_1.default.yellow(` ⚠ ${u.node} · ${u.key} — ${u.reason}`));
115
+ }
105
116
  }
106
117
  catch (error) {
107
118
  spinner.fail(chalk_1.default.red(`Simulate failed: ${error.message || error}`));
@@ -1 +1 @@
1
- {"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/commands/call.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/commands/call.ts"],"names":[],"mappings":"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"}
@@ -381,14 +381,31 @@ exports.companyCommand
381
381
  }
382
382
  });
383
383
  // ════════════════════════════════════════════════════════════════════
384
- // T10 — Agency-managed companies + design-lock
384
+ // T10 — Agency-managed companies + verb-scoped locks (SPRINT-AGENT-FIREWALL Phase 0)
385
385
  // solid company create-for-client — provision + lock all + invite
386
- // solid company lock-status — read current lock map
387
- // solid company lock — lock areas
388
- // solid company unlock — unlock areas (or --all)
386
+ // solid company lock-status — read current lock map (grouped by area)
387
+ // solid company lock — lock keys (or legacy areas — the server expands them)
388
+ // solid company unlock — unlock keys (or --all)
389
+ // solid company lock-preset — apply a whole posture: design-lock | content-freeze | read-only
389
390
  // solid company request-unlock — client asks agency to unlock
390
391
  // ════════════════════════════════════════════════════════════════════
391
- const LOCK_AREAS = ['pages', 'brand', 'domains', 'modules', 'design', 'billing_lock'];
392
+ // Lock keys are `area:verb`. `{"design:write": true, "pages:delete": true}` (the
393
+ // `design-lock` preset) still lets the client add a landing page, edit copy and
394
+ // change business hours — that is what "lock my design" means. Single source of
395
+ // truth: solid-backend/services/policy/lock.py::VALID_LOCK_KEYS. A bare legacy
396
+ // area (`pages`) is still accepted and expands to every key under it.
397
+ const LOCK_KEYS = [
398
+ 'design:write',
399
+ 'pages:create', 'pages:update', 'pages:delete',
400
+ 'content:metadata',
401
+ 'brand:logo', 'brand:colors',
402
+ 'domains:add', 'domains:remove',
403
+ 'modules:deploy', 'modules:remove',
404
+ 'billing_lock',
405
+ ];
406
+ const LEGACY_LOCK_AREAS = ['pages', 'brand', 'domains', 'modules', 'design', 'billing_lock'];
407
+ const LOCK_PRESETS = ['design-lock', 'content-freeze', 'read-only'];
408
+ const LOCK_AREAS = LOCK_KEYS; // kept for callers that read the list
392
409
  function parseAreas(raw) {
393
410
  return raw
394
411
  .split(',')
@@ -396,18 +413,33 @@ function parseAreas(raw) {
396
413
  .filter((s) => s.length > 0);
397
414
  }
398
415
  function validateAreas(areas) {
399
- const invalid = areas.filter((a) => !LOCK_AREAS.includes(a));
416
+ const known = [...LOCK_KEYS, ...LEGACY_LOCK_AREAS];
417
+ const invalid = areas.filter((a) => !known.includes(a));
400
418
  if (invalid.length > 0) {
401
- return `Unknown lock area(s): ${invalid.join(', ')}. Valid: ${LOCK_AREAS.join(', ')}`;
419
+ return `Unknown lock key(s): ${invalid.join(', ')}. Valid keys: ${LOCK_KEYS.join(', ')} (legacy areas ${LEGACY_LOCK_AREAS.join(', ')} expand to every key under them)`;
402
420
  }
403
421
  return null;
404
422
  }
405
423
  function printLocks(locks) {
406
424
  console.log('');
407
- LOCK_AREAS.forEach((area) => {
408
- const locked = locks[area] === true;
409
- const badge = locked ? chalk_1.default.red('🔒 locked ') : chalk_1.default.green('✔ unlocked');
410
- console.log(` ${badge} ${chalk_1.default.dim(area)}`);
425
+ // Group by area so the map reads as a posture, not a wall of booleans.
426
+ const keys = Object.keys(locks).length ? Object.keys(locks) : [...LOCK_KEYS];
427
+ const byArea = new Map();
428
+ keys.forEach((key) => {
429
+ const area = key.includes(':') ? key.split(':')[0] : key;
430
+ byArea.set(area, [...(byArea.get(area) ?? []), key]);
431
+ });
432
+ byArea.forEach((areaKeys, area) => {
433
+ const lockedCount = areaKeys.filter((k) => locks[k] === true).length;
434
+ const rollup = lockedCount === areaKeys.length ? chalk_1.default.red('locked') :
435
+ lockedCount > 0 ? chalk_1.default.yellow('partial') : chalk_1.default.green('unlocked');
436
+ console.log(` ${chalk_1.default.bold(area.padEnd(13))} ${rollup}`);
437
+ areaKeys.forEach((key) => {
438
+ const locked = locks[key] === true;
439
+ const badge = locked ? chalk_1.default.red('🔒 locked ') : chalk_1.default.green('✔ unlocked');
440
+ const verb = key.includes(':') ? key.split(':')[1] : '';
441
+ console.log(` ${badge} ${chalk_1.default.dim(verb ? `${area}:` : '')}${verb || chalk_1.default.dim(key)}`);
442
+ });
411
443
  });
412
444
  }
413
445
  // Create a company for a client, locked by default
@@ -419,7 +451,7 @@ exports.companyCommand
419
451
  .option('--client-name <name>', 'Client contact name')
420
452
  .option('--industry <industry>', 'Industry slug (e.g. "plumber", "hvac")')
421
453
  .option('--template <template>', 'KB template name (usually same as industry)')
422
- .option('--unlock <areas>', `Comma-separated areas to leave UNLOCKED at creation (valid: ${LOCK_AREAS.join(', ')})`)
454
+ .option('--unlock <keys>', `Comma-separated lock keys to leave UNLOCKED at creation (valid: ${LOCK_KEYS.join(', ')}; a legacy area like "pages" expands to every key under it)`)
423
455
  .action(async (options) => {
424
456
  if (!config_1.config.isLoggedIn()) {
425
457
  console.error(chalk_1.default.red('Not logged in. Run `solid auth login` first.'));
@@ -475,7 +507,7 @@ exports.companyCommand
475
507
  });
476
508
  exports.companyCommand
477
509
  .command('lock-status [company_id]')
478
- .description('Show which areas are locked on a company')
510
+ .description('Show which lock keys are locked on a company, grouped by area')
479
511
  .option('--json', 'Output as JSON')
480
512
  .action(async (companyIdArg, options) => {
481
513
  if (!config_1.config.isLoggedIn()) {
@@ -510,8 +542,8 @@ exports.companyCommand
510
542
  });
511
543
  exports.companyCommand
512
544
  .command('lock <company_id>')
513
- .description('Lock one or more areas — agency owner only')
514
- .requiredOption('--area <areas>', `Comma-separated areas to lock (valid: ${LOCK_AREAS.join(', ')})`)
545
+ .description('Lock one or more keys (area:verb) — agency owner only')
546
+ .requiredOption('--area <keys>', `Comma-separated lock keys (valid: ${LOCK_KEYS.join(', ')}; a legacy area like "pages" expands to every key under it)`)
515
547
  .action(async (companyIdArg, options) => {
516
548
  if (!config_1.config.isLoggedIn()) {
517
549
  console.error(chalk_1.default.red('Not logged in. Run `solid auth login` first.'));
@@ -539,9 +571,9 @@ exports.companyCommand
539
571
  });
540
572
  exports.companyCommand
541
573
  .command('unlock <company_id>')
542
- .description('Unlock one or more areas — agency owner only')
543
- .option('--area <areas>', 'Comma-separated areas to unlock')
544
- .option('--all', 'Unlock every area (full handoff)', false)
574
+ .description('Unlock one or more keys (area:verb) — agency owner only')
575
+ .option('--area <keys>', 'Comma-separated lock keys to unlock (a legacy area expands to every key under it)')
576
+ .option('--all', 'Unlock every key (full handoff)', false)
545
577
  .action(async (companyIdArg, options) => {
546
578
  if (!config_1.config.isLoggedIn()) {
547
579
  console.error(chalk_1.default.red('Not logged in. Run `solid auth login` first.'));
@@ -561,7 +593,7 @@ exports.companyCommand
561
593
  process.exit(1);
562
594
  }
563
595
  }
564
- const label = all ? 'ALL areas' : areas.join(', ');
596
+ const label = all ? 'ALL keys' : areas.join(', ');
565
597
  const spinner = (0, ora_1.default)(`Unlocking ${label} on company #${companyId}...`).start();
566
598
  try {
567
599
  const res = await api_client_1.apiClient.companyUnlock(companyId, areas, all);
@@ -577,8 +609,8 @@ exports.companyCommand
577
609
  });
578
610
  exports.companyCommand
579
611
  .command('request-unlock <company_id>')
580
- .description('Ask your agency to unlock one or more areas (client-side)')
581
- .requiredOption('--area <areas>', 'Comma-separated areas to request (e.g. "pages")')
612
+ .description('Ask your agency to unlock one or more keys (client-side)')
613
+ .requiredOption('--area <keys>', 'Comma-separated lock keys to request (e.g. "pages:update")')
582
614
  .requiredOption('--reason <reason>', 'Why you need this unlocked')
583
615
  .action(async (companyIdArg, options) => {
584
616
  if (!config_1.config.isLoggedIn()) {
@@ -597,7 +629,7 @@ exports.companyCommand
597
629
  const res = await api_client_1.apiClient.companyRequestUnlock(companyId, areas, options.reason);
598
630
  spinner.succeed(chalk_1.default.green('Request sent'));
599
631
  console.log(chalk_1.default.dim(` Agency owner: user_id=${res.data.agency_owner_user_id}`));
600
- console.log(chalk_1.default.dim(` Areas: ${res.data.areas.join(', ')}`));
632
+ console.log(chalk_1.default.dim(` Keys: ${res.data.areas.join(', ')}`));
601
633
  }
602
634
  catch (error) {
603
635
  spinner.fail(chalk_1.default.red('Request failed'));
@@ -606,11 +638,41 @@ exports.companyCommand
606
638
  process.exit(1);
607
639
  }
608
640
  });
641
+ exports.companyCommand
642
+ .command('lock-preset <company_id>')
643
+ .description('Apply a lock posture — REPLACES the whole map. Agency owner only')
644
+ .requiredOption('--profile <name>', `One of: ${LOCK_PRESETS.join(', ')}`)
645
+ .action(async (companyIdArg, options) => {
646
+ if (!config_1.config.isLoggedIn()) {
647
+ console.error(chalk_1.default.red('Not logged in. Run `solid auth login` first.'));
648
+ process.exit(1);
649
+ }
650
+ const companyId = parseInt(companyIdArg, 10);
651
+ const profile = String(options.profile);
652
+ if (!LOCK_PRESETS.includes(profile)) {
653
+ console.error(chalk_1.default.red(`Unknown preset '${profile}'. Valid: ${LOCK_PRESETS.join(', ')}`));
654
+ process.exit(1);
655
+ }
656
+ const spinner = (0, ora_1.default)(`Applying '${profile}' on company #${companyId}...`).start();
657
+ try {
658
+ const res = await api_client_1.apiClient.companyLockPreset(companyId, profile);
659
+ spinner.succeed(chalk_1.default.green(`Applied: ${profile}`));
660
+ printLocks(res.data.locks);
661
+ }
662
+ catch (error) {
663
+ spinner.fail(chalk_1.default.red('Preset failed'));
664
+ const apiError = (0, api_client_1.handleApiError)(error);
665
+ console.error(chalk_1.default.red(` ${apiError.message}`));
666
+ process.exit(1);
667
+ }
668
+ });
609
669
  const command_kit_1 = require("../lib/command-kit");
610
670
  (0, command_kit_1.appendExamples)(exports.companyCommand, [
611
671
  { cmd: 'solid company list', why: 'Companies you have access to' },
612
672
  { cmd: 'solid company current', why: 'Active company (same as whoami)' },
613
673
  { cmd: 'solid company info <id>', why: 'Settings, tier, domain' },
614
674
  { cmd: 'solid company create-for-client --name "..."', why: 'Agency: spin up a new tenant' },
675
+ { cmd: 'solid company lock-preset 47 --profile design-lock', why: 'Lock design + deletes; new pages and copy edits stay open' },
676
+ { cmd: 'solid company lock 47 --area design:write,pages:delete', why: 'Lock individual keys (area:verb)' },
615
677
  ]);
616
678
  //# sourceMappingURL=company.js.map