@solidnumber/cli 2.18.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.
package/README.md CHANGED
@@ -118,6 +118,7 @@ solid agent mission "Create a Valentine's campaign for VIP customers"
118
118
  | `solid auth logout` | Clear stored credentials |
119
119
  | `solid auth whoami` | Show current session |
120
120
  | `solid status` | Company dashboard |
121
+ | `solid update` | Update the CLI — knows npm, Homebrew and scoop |
121
122
  | `solid pull` | Download pages, KB, settings as files |
122
123
  | `solid push` | Push local changes to production |
123
124
  | `solid diff` | Preview changes before pushing |
@@ -402,6 +403,20 @@ Full contract: see the [Scripting Contract doc](https://github.com/Adam-Camp-Kin
402
403
 
403
404
  ## Update notifier
404
405
 
406
+ When it says there's a new version, run:
407
+
408
+ ```bash
409
+ solid update # check, then upgrade this copy
410
+ solid update --check # say what would happen, change nothing
411
+ ```
412
+
413
+ It works out how this copy was installed and runs the right thing —
414
+ `npm install -g`, `brew upgrade`, or `scoop update`. It also warns when a
415
+ **second** `solid` is on your PATH at a different version: an npm global under
416
+ nvm in front of a Homebrew formula is easy to end up with, whichever comes
417
+ first in PATH wins, and upgrading one leaves the other lying in wait. The
418
+ notifier cannot see that — it only ever looks at the copy that is running.
419
+
405
420
  The CLI checks npm once every **4 hours** for a newer release and prints
406
421
  a boxed notice on the next run. Suppress it:
407
422
 
@@ -1,5 +1,14 @@
1
1
  /**
2
- * Accounting command for Solid CLI QuickBooks / Xero sync.
2
+ * `solid accounting` the OPTIONAL mirror of Solid#'s books into QuickBooks,
3
+ * Xero or FreshBooks. The books themselves are `solid books`, `solid invoices`
4
+ * and `solid expenses` (commands/books.ts) — every company has those, with or
5
+ * without an accounting system.
6
+ *
7
+ * ⛔ Fixed 2026-09-11 — all three commands spoke to an API that never existed:
8
+ * `sync` POSTed with no connection_id (the backend requires one → 422),
9
+ * `history` called /sync/history (only /sync/history/{connection_id} exists → 404),
10
+ * and `status` read provider/status/last_sync at the top level when the backend
11
+ * returns {connections: [...]}.
3
12
  */
4
13
  import { Command } from 'commander';
5
14
  export declare const accountingCommand: Command;
@@ -1 +1 @@
1
- {"version":3,"file":"accounting.d.ts","sourceRoot":"","sources":["../../src/commands/accounting.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,iBAAiB,SAE4B,CAAC"}
1
+ {"version":3,"file":"accounting.d.ts","sourceRoot":"","sources":["../../src/commands/accounting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BpC,eAAO,MAAM,iBAAiB,SAE4B,CAAC"}
@@ -38,36 +38,63 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.accountingCommand = void 0;
40
40
  /**
41
- * Accounting command for Solid CLI QuickBooks / Xero sync.
41
+ * `solid accounting` the OPTIONAL mirror of Solid#'s books into QuickBooks,
42
+ * Xero or FreshBooks. The books themselves are `solid books`, `solid invoices`
43
+ * and `solid expenses` (commands/books.ts) — every company has those, with or
44
+ * without an accounting system.
45
+ *
46
+ * ⛔ Fixed 2026-09-11 — all three commands spoke to an API that never existed:
47
+ * `sync` POSTed with no connection_id (the backend requires one → 422),
48
+ * `history` called /sync/history (only /sync/history/{connection_id} exists → 404),
49
+ * and `status` read provider/status/last_sync at the top level when the backend
50
+ * returns {connections: [...]}.
42
51
  */
43
52
  const commander_1 = require("commander");
44
53
  const chalk_1 = __importDefault(require("chalk"));
45
- const config_1 = require("../lib/config");
46
54
  const api_client_1 = require("../lib/api-client");
47
- const ui_1 = require("../lib/ui");
55
+ const command_kit_1 = require("../lib/command-kit");
48
56
  const json_output_1 = require("../lib/json-output");
57
+ const ui_1 = require("../lib/ui");
58
+ const dispatch_shortcuts_1 = require("./dispatch_shortcuts");
59
+ async function connectionFor(connectionId) {
60
+ const res = await api_client_1.apiClient.get('/api/v1/accounting/connections');
61
+ const list = ((res.data || {}).connections || []);
62
+ if (list.length === 0) {
63
+ throw new Error('No accounting system is connected — connect one in Integrations → Accounting.');
64
+ }
65
+ if (!connectionId)
66
+ return list[0];
67
+ const match = list.find((c) => c.id === Number(connectionId));
68
+ if (!match)
69
+ throw new Error(`No accounting connection ${connectionId} on this account.`);
70
+ return match;
71
+ }
49
72
  exports.accountingCommand = new commander_1.Command('accounting')
50
- .description('Accounting sync QuickBooks, Xero')
73
+ .description('Optional mirror of your books into QuickBooks / Xero / FreshBooks (the books: `solid books`)')
51
74
  .action(async () => { exports.accountingCommand.outputHelp(); });
52
- exports.accountingCommand.command('sync').description('Trigger a full accounting sync')
75
+ exports.accountingCommand.command('status').description('Each connected accounting system and how its last sync went')
53
76
  .option('--json', 'JSON output')
54
77
  .action(async (options) => {
55
- if (!config_1.config.isLoggedIn()) {
56
- console.error(chalk_1.default.red('Not logged in.'));
57
- process.exit(1);
58
- }
78
+ (0, command_kit_1.requireAuth)();
59
79
  const ora = (await Promise.resolve().then(() => __importStar(require('ora')))).default;
60
- const spinner = ora('Starting accounting sync...').start();
80
+ const spinner = ora('Loading...').start();
61
81
  try {
62
- const res = await api_client_1.apiClient.post('/api/v1/accounting/sync');
82
+ const res = await api_client_1.apiClient.get('/api/v1/accounting/sync/status');
63
83
  spinner.stop();
64
84
  if ((0, json_output_1.isJsonOutput)(options)) {
65
85
  console.log(JSON.stringify(res.data, null, 2));
66
86
  return;
67
87
  }
68
- const d = res.data;
88
+ const connections = ((res.data || {}).connections || []);
69
89
  console.log('');
70
- console.log(ui_1.ui.successBox('Sync Started', [`${chalk_1.default.dim('Status:')} ${d.status || 'running'}`, `${chalk_1.default.dim('Sync ID:')} ${d.sync_id || d.id || 'n/a'}`]));
90
+ console.log(ui_1.ui.header('Accounting'));
91
+ if (connections.length === 0)
92
+ console.log(chalk_1.default.dim(' Nothing connected — your books live in Solid# (`solid books summary`).'));
93
+ for (const c of connections) {
94
+ const status = c.last_status === 'success' ? chalk_1.default.green(c.last_status)
95
+ : c.last_status ? chalk_1.default.yellow(c.last_status) : chalk_1.default.dim('never synced');
96
+ console.log(ui_1.ui.label(`${c.provider} (#${c.connection_id})`, `${status}${c.last_sync ? chalk_1.default.dim(` ${c.last_sync}`) : ''}`));
97
+ }
71
98
  console.log('');
72
99
  }
73
100
  catch (e) {
@@ -76,33 +103,26 @@ exports.accountingCommand.command('sync').description('Trigger a full accounting
76
103
  process.exit(1);
77
104
  }
78
105
  });
79
- exports.accountingCommand.command('status').description('Check sync status')
106
+ exports.accountingCommand.command('sync').description('Send what is waiting to the connected accounting system now')
107
+ .option('--connection-id <id>', 'Which connection (default: the first)')
80
108
  .option('--json', 'JSON output')
81
109
  .action(async (options) => {
82
- if (!config_1.config.isLoggedIn()) {
83
- console.error(chalk_1.default.red('Not logged in.'));
84
- process.exit(1);
85
- }
110
+ (0, command_kit_1.requireAuth)();
86
111
  const ora = (await Promise.resolve().then(() => __importStar(require('ora')))).default;
87
- const spinner = ora('Loading...').start();
112
+ const spinner = ora('Starting sync...').start();
88
113
  try {
89
- const res = await api_client_1.apiClient.get('/api/v1/accounting/sync/status');
114
+ const connection = await connectionFor(options.connectionId);
115
+ const res = await api_client_1.apiClient.post('/api/v1/accounting/sync', { connection_id: connection.id });
90
116
  spinner.stop();
91
117
  if ((0, json_output_1.isJsonOutput)(options)) {
92
118
  console.log(JSON.stringify(res.data, null, 2));
93
119
  return;
94
120
  }
95
- const d = res.data;
96
121
  console.log('');
97
- console.log(ui_1.ui.header('Accounting Sync'));
98
- if (d.provider)
99
- console.log(ui_1.ui.label('Provider', d.provider));
100
- if (d.status)
101
- console.log(ui_1.ui.label('Status', d.status === 'connected' ? chalk_1.default.green(d.status) : chalk_1.default.yellow(d.status)));
102
- if (d.last_sync)
103
- console.log(ui_1.ui.label('Last Sync', d.last_sync));
104
- if (d.records_synced !== undefined)
105
- console.log(ui_1.ui.label('Records', String(d.records_synced)));
122
+ console.log(ui_1.ui.successBox('Sync started', [
123
+ `${chalk_1.default.dim('Provider:')} ${connection.provider}`,
124
+ chalk_1.default.dim('Each expense and invoice records how it landed — `solid accounting history`.'),
125
+ ]));
106
126
  console.log('');
107
127
  }
108
128
  catch (e) {
@@ -111,34 +131,31 @@ exports.accountingCommand.command('status').description('Check sync status')
111
131
  process.exit(1);
112
132
  }
113
133
  });
114
- exports.accountingCommand.command('history').description('View sync history')
115
- .option('--limit <n>', 'Entries', '10').option('--json', 'JSON output')
134
+ exports.accountingCommand.command('history').description('What was sent, and how each landed')
135
+ .option('--connection-id <id>', 'Which connection (default: the first)')
136
+ .option('--limit <n>', 'Entries', '20')
137
+ .option('--json', 'JSON output')
116
138
  .action(async (options) => {
117
- if (!config_1.config.isLoggedIn()) {
118
- console.error(chalk_1.default.red('Not logged in.'));
119
- process.exit(1);
120
- }
139
+ (0, command_kit_1.requireAuth)();
121
140
  const ora = (await Promise.resolve().then(() => __importStar(require('ora')))).default;
122
141
  const spinner = ora('Loading...').start();
123
142
  try {
124
- const res = await api_client_1.apiClient.get('/api/v1/accounting/sync/history', { params: { limit: options.limit } });
143
+ const connection = await connectionFor(options.connectionId);
144
+ const res = await api_client_1.apiClient.get(`/api/v1/accounting/sync/history/${connection.id}`, { params: { limit: options.limit } });
125
145
  spinner.stop();
126
146
  if ((0, json_output_1.isJsonOutput)(options)) {
127
147
  console.log(JSON.stringify(res.data, null, 2));
128
148
  return;
129
149
  }
130
- const d = res.data;
131
- const entries = d.history || d.syncs || [];
150
+ const items = ((res.data || {}).items || []);
132
151
  console.log('');
133
- console.log(ui_1.ui.header(`Sync History (${entries.length})`));
134
- if (entries.length === 0) {
135
- console.log(chalk_1.default.dim(' No sync history yet.'));
136
- }
137
- else {
138
- for (const e of entries) {
139
- const s = e.status === 'success' ? chalk_1.default.green('✓') : chalk_1.default.red('');
140
- console.log(` ${s} ${e.created_at || e.date} — ${e.records || 0} records`);
141
- }
152
+ console.log(ui_1.ui.header(`${connection.provider} sync history (${items.length})`));
153
+ if (items.length === 0)
154
+ console.log(chalk_1.default.dim(' Nothing sent yet.'));
155
+ for (const e of items) {
156
+ const mark = e.status === 'success' ? chalk_1.default.green('✓') : e.status === 'failed' ? chalk_1.default.red('✗') : chalk_1.default.yellow('…');
157
+ const where = e.remote_id ? ` → ${e.remote_id}` : '';
158
+ console.log(` ${mark} ${e.entity_type} ${e.solid_id}${where} ${chalk_1.default.dim(e.synced_at || '')}${e.error ? chalk_1.default.red(` ${e.error}`) : ''}`);
142
159
  }
143
160
  console.log('');
144
161
  }
@@ -148,10 +165,18 @@ exports.accountingCommand.command('history').description('View sync history')
148
165
  process.exit(1);
149
166
  }
150
167
  });
151
- const command_kit_1 = require("../lib/command-kit");
168
+ exports.accountingCommand.command('setup').description('Where money out and money in land in the connected books, and what is still missing')
169
+ .option('--accounts', 'Also list the accounts in their books to choose from')
170
+ .option('--json', 'JSON output')
171
+ .action(async (options) => {
172
+ const payload = { include_accounts: Boolean(options.accounts) };
173
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('integration.accounting_expense_setup', payload, options, 'Money out...');
174
+ await (0, dispatch_shortcuts_1.invokeAgentVerbShortcut)('integration.accounting_receivable_setup', payload, options, 'Money in...');
175
+ });
152
176
  (0, command_kit_1.appendExamples)(exports.accountingCommand, [
153
- { cmd: 'solid accounting sync', why: 'Sync orders QuickBooks/Xero now' },
154
- { cmd: 'solid accounting status', why: 'Connected provider + last sync time' },
155
- { cmd: 'solid accounting history', why: 'Sync attempts + failures' },
177
+ { cmd: 'solid accounting status', why: 'Connected systems + how the last sync went' },
178
+ { cmd: 'solid accounting setup --accounts', why: 'Where expenses and invoices land, what to choose' },
179
+ { cmd: 'solid accounting sync', why: 'Send what is waiting now' },
180
+ { cmd: 'solid accounting history', why: 'What was sent, and how each landed' },
156
181
  ]);
157
182
  //# sourceMappingURL=accounting.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"accounting.js","sourceRoot":"","sources":["../../src/commands/accounting.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"accounting.js","sourceRoot":"","sources":["../../src/commands/accounting.ts"],"names":[],"mappings":"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"}
@@ -1043,6 +1043,216 @@ exports.agentCommand
1043
1043
  catchError(spinner, 'Uninstall failed')(e);
1044
1044
  }
1045
1045
  });
1046
+ // ── SPRINT-AGENT-FIREWALL — identity, quarantine, reputation ─────────
1047
+ //
1048
+ // solid agent identity list|create|revoke|use|clear
1049
+ // solid agent quarantine <id> [--reason]
1050
+ // solid agent release <id>
1051
+ // solid agent reputation <id>
1052
+ // solid agent risk [--days 7]
1053
+ function printIdentity(i) {
1054
+ const status = String(i.status);
1055
+ const badge = status === 'active' ? chalk_1.default.green('active') : status === 'quarantined' ? chalk_1.default.red('quarantined') : chalk_1.default.dim('revoked');
1056
+ console.log(` #${String(i.id).padEnd(5)} ${badge.padEnd(20)} ${chalk_1.default.bold(String(i.agent_type)).padEnd(24)} tier=${String(i.trust_tier).padEnd(9)} rep=${Number(i.reputation ?? 1).toFixed(2)} ${chalk_1.default.dim(String(i.key_prefix))}… ${chalk_1.default.dim(String(i.label ?? ''))}`);
1057
+ }
1058
+ const identityCommand = new commander_1.Command('identity')
1059
+ .description('Agent identities — a revocable key that says WHICH agent acted (sent as X-Agent-Id)');
1060
+ identityCommand
1061
+ .command('list').alias('ls')
1062
+ .description('List agent identities on the current company')
1063
+ .option('--all', 'Include revoked identities', false)
1064
+ .option('--json', 'Output as JSON')
1065
+ .action(async (options) => {
1066
+ requireLogin();
1067
+ try {
1068
+ const res = await api_client_1.apiClient.agentIdentityList(Boolean(options.all));
1069
+ if ((0, json_output_1.isJsonOutput)(options)) {
1070
+ console.log(JSON.stringify(res.data, null, 2));
1071
+ return;
1072
+ }
1073
+ console.log('');
1074
+ if (!res.data.identities.length) {
1075
+ console.log(chalk_1.default.dim(' No agent identities. Create one: solid agent identity create --type custom-bot --tier custom'));
1076
+ return;
1077
+ }
1078
+ res.data.identities.forEach(printIdentity);
1079
+ const active = config_1.config.agentKey;
1080
+ console.log(active ? chalk_1.default.dim(`\n This CLI is sending X-Agent-Id (${active.slice(0, 12)}…)`) : chalk_1.default.dim('\n This CLI is not sending an agent identity. `solid agent identity use <key>` to attach one.'));
1081
+ }
1082
+ catch (error) {
1083
+ const apiError = (0, api_client_1.handleApiError)(error);
1084
+ console.error(chalk_1.default.red(` ${apiError.message}`));
1085
+ process.exit(1);
1086
+ }
1087
+ });
1088
+ identityCommand
1089
+ .command('create')
1090
+ .description('Create an agent identity — the key is shown ONCE')
1091
+ .requiredOption('--type <agent_type>', 'sarah | marcus | ada | cli | mcp | custom-<slug>')
1092
+ .option('--tier <trust_tier>', 'platform | agency | custom (rate-limit tier)', 'custom')
1093
+ .option('--label <label>', 'Human label')
1094
+ .option('--use', 'Attach the new key to this CLI immediately', false)
1095
+ .option('--json', 'Output as JSON')
1096
+ .action(async (options) => {
1097
+ requireLogin();
1098
+ const spinner = (0, ora_1.default)(`Creating identity ${options.type} (${options.tier})...`).start();
1099
+ try {
1100
+ const res = await api_client_1.apiClient.agentIdentityCreate({ agent_type: options.type, trust_tier: options.tier, label: options.label });
1101
+ spinner.succeed(chalk_1.default.green(`Created #${res.data.id}`));
1102
+ if ((0, json_output_1.isJsonOutput)(options)) {
1103
+ console.log(JSON.stringify(res.data, null, 2));
1104
+ return;
1105
+ }
1106
+ console.log('');
1107
+ console.log(` ${chalk_1.default.bold('Agent key (shown once):')} ${chalk_1.default.cyan(res.data.agent_key)}`);
1108
+ console.log(chalk_1.default.dim(' Attach it: solid agent identity use <key> or export SOLID_AGENT_KEY=<key>'));
1109
+ if (options.use) {
1110
+ config_1.config.agentKey = res.data.agent_key;
1111
+ console.log(chalk_1.default.green(' ✔ attached to this CLI'));
1112
+ }
1113
+ }
1114
+ catch (error) {
1115
+ spinner.fail(chalk_1.default.red('Create failed'));
1116
+ const apiError = (0, api_client_1.handleApiError)(error);
1117
+ console.error(chalk_1.default.red(` ${apiError.message}`));
1118
+ process.exit(1);
1119
+ }
1120
+ });
1121
+ identityCommand
1122
+ .command('revoke <id>')
1123
+ .description('Revoke an agent identity — its key stops resolving immediately (403 on every call)')
1124
+ .action(async (idArg) => {
1125
+ requireLogin();
1126
+ const spinner = (0, ora_1.default)(`Revoking #${idArg}...`).start();
1127
+ try {
1128
+ const res = await api_client_1.apiClient.agentIdentityRevoke(parseInt(idArg, 10));
1129
+ spinner.succeed(chalk_1.default.green(`Revoked #${idArg}`));
1130
+ printIdentity(res.data);
1131
+ }
1132
+ catch (error) {
1133
+ spinner.fail(chalk_1.default.red('Revoke failed'));
1134
+ const apiError = (0, api_client_1.handleApiError)(error);
1135
+ console.error(chalk_1.default.red(` ${apiError.message}`));
1136
+ process.exit(1);
1137
+ }
1138
+ });
1139
+ identityCommand
1140
+ .command('use <key>')
1141
+ .description('Attach an agent key to this CLI (sent as X-Agent-Id on every request)')
1142
+ .action((key) => {
1143
+ if (!String(key).startsWith('sak_')) {
1144
+ console.error(chalk_1.default.red('That is not an agent key (expected sak_…). Create one: solid agent identity create'));
1145
+ process.exit(1);
1146
+ }
1147
+ config_1.config.agentKey = String(key);
1148
+ console.log(chalk_1.default.green(`✔ This CLI now identifies as ${String(key).slice(0, 12)}…`));
1149
+ });
1150
+ identityCommand
1151
+ .command('clear')
1152
+ .description('Stop sending an agent identity from this CLI')
1153
+ .action(() => {
1154
+ config_1.config.agentKey = undefined;
1155
+ console.log(chalk_1.default.green('✔ Agent identity detached'));
1156
+ });
1157
+ exports.agentCommand.addCommand(identityCommand);
1158
+ exports.agentCommand
1159
+ .command('quarantine <id>')
1160
+ .description('Quarantine an agent identity — every write is denied until released')
1161
+ .option('--reason <reason>', 'Why', 'manual')
1162
+ .action(async (idArg, options) => {
1163
+ requireLogin();
1164
+ const spinner = (0, ora_1.default)(`Quarantining #${idArg}...`).start();
1165
+ try {
1166
+ const res = await api_client_1.apiClient.agentIdentityQuarantine(parseInt(idArg, 10), String(options.reason));
1167
+ spinner.succeed(chalk_1.default.red(`Quarantined #${idArg}`));
1168
+ printIdentity(res.data);
1169
+ }
1170
+ catch (error) {
1171
+ spinner.fail(chalk_1.default.red('Quarantine failed'));
1172
+ const apiError = (0, api_client_1.handleApiError)(error);
1173
+ console.error(chalk_1.default.red(` ${apiError.message}`));
1174
+ process.exit(1);
1175
+ }
1176
+ });
1177
+ exports.agentCommand
1178
+ .command('release <id>')
1179
+ .description('Release a quarantined agent identity')
1180
+ .action(async (idArg) => {
1181
+ requireLogin();
1182
+ const spinner = (0, ora_1.default)(`Releasing #${idArg}...`).start();
1183
+ try {
1184
+ const res = await api_client_1.apiClient.agentIdentityRelease(parseInt(idArg, 10));
1185
+ spinner.succeed(chalk_1.default.green(`Released #${idArg}`));
1186
+ printIdentity(res.data);
1187
+ }
1188
+ catch (error) {
1189
+ spinner.fail(chalk_1.default.red('Release failed'));
1190
+ const apiError = (0, api_client_1.handleApiError)(error);
1191
+ console.error(chalk_1.default.red(` ${apiError.message}`));
1192
+ process.exit(1);
1193
+ }
1194
+ });
1195
+ exports.agentCommand
1196
+ .command('reputation <id>')
1197
+ .description('Reputation score, effective rate limit and recent deductions for an agent identity')
1198
+ .option('--json', 'Output as JSON')
1199
+ .action(async (idArg, options) => {
1200
+ requireLogin();
1201
+ try {
1202
+ const res = await api_client_1.apiClient.agentIdentityReputation(parseInt(idArg, 10));
1203
+ if ((0, json_output_1.isJsonOutput)(options)) {
1204
+ console.log(JSON.stringify(res.data, null, 2));
1205
+ return;
1206
+ }
1207
+ const d = res.data;
1208
+ console.log('');
1209
+ printIdentity(d.identity);
1210
+ console.log(` ${chalk_1.default.bold('Reputation:')} ${d.reputation.toFixed(3)}`);
1211
+ console.log(` ${chalk_1.default.bold('Rate limit:')} ${d.effective_limit_per_min}/min effective (tier ${d.trust_tier} base ${d.base_limit_per_min}/min)`);
1212
+ if (!d.deductions.length) {
1213
+ console.log(chalk_1.default.dim(' No deductions in the window.'));
1214
+ return;
1215
+ }
1216
+ console.log(chalk_1.default.bold('\n Recent deductions:'));
1217
+ d.deductions.forEach((x) => {
1218
+ console.log(` ${chalk_1.default.dim(String(x.at ?? '').slice(0, 19))} -${Number(x.amount ?? 0).toFixed(3)} ${x.reason.padEnd(20)} ${chalk_1.default.dim(`${Number(x.before ?? 0).toFixed(2)} → ${Number(x.after ?? 0).toFixed(2)}`)}`);
1219
+ });
1220
+ }
1221
+ catch (error) {
1222
+ const apiError = (0, api_client_1.handleApiError)(error);
1223
+ console.error(chalk_1.default.red(` ${apiError.message}`));
1224
+ process.exit(1);
1225
+ }
1226
+ });
1227
+ exports.agentCommand
1228
+ .command('risk')
1229
+ .description('Trust Surface: agents with elevated risk this week, and who is quarantined')
1230
+ .option('--days <n>', 'Window in days', '7')
1231
+ .option('--json', 'Output as JSON')
1232
+ .action(async (options) => {
1233
+ requireLogin();
1234
+ try {
1235
+ const res = await api_client_1.apiClient.agentRisk(parseInt(String(options.days), 10) || 7);
1236
+ if ((0, json_output_1.isJsonOutput)(options)) {
1237
+ console.log(JSON.stringify(res.data, null, 2));
1238
+ return;
1239
+ }
1240
+ console.log('');
1241
+ if (!res.data.elevated.length && !res.data.quarantined.length) {
1242
+ console.log(chalk_1.default.green(` No elevated-risk agents in the last ${res.data.window_days} days.`));
1243
+ return;
1244
+ }
1245
+ res.data.elevated.forEach((a) => {
1246
+ console.log(` ${chalk_1.default.bold(String(a.agent_key)).padEnd(16)} max risk ${chalk_1.default.yellow(Number(a.max_risk).toFixed(2))} flagged=${a.flagged_actions} blocked=${a.blocked} approvals=${a.approvals_required} ${chalk_1.default.dim(a.reasons.join(', '))}`);
1247
+ });
1248
+ res.data.quarantined.forEach((i) => printIdentity(i));
1249
+ }
1250
+ catch (error) {
1251
+ const apiError = (0, api_client_1.handleApiError)(error);
1252
+ console.error(chalk_1.default.red(` ${apiError.message}`));
1253
+ process.exit(1);
1254
+ }
1255
+ });
1046
1256
  const command_kit_1 = require("../lib/command-kit");
1047
1257
  (0, command_kit_1.appendExamples)(exports.agentCommand, [
1048
1258
  { cmd: 'solid agent dashboard', why: 'All agents + telemetry' },
@@ -1055,6 +1265,10 @@ const command_kit_1 = require("../lib/command-kit");
1055
1265
  { cmd: 'solid agent grant <id> --scope kb:read', why: 'Grant scopes after install' },
1056
1266
  { cmd: 'solid agent call <id> "summarize pricing"', why: 'Invoke an installed agent' },
1057
1267
  { cmd: 'solid agent dispatch kb_entry_create --args \'{"title":"FAQ","content":"...","category_id":1}\' --confirm', why: 'Run any ADA verb directly' },
1268
+ { cmd: 'solid agent identity create --type custom-bot --tier custom --use', why: 'Issue a revocable agent key and attach it (X-Agent-Id)' },
1269
+ { cmd: 'solid agent reputation 5', why: 'Score, effective rate limit, deductions' },
1270
+ { cmd: 'solid agent quarantine 5 --reason "bulk delete"', why: 'Hard-block an agent until released' },
1271
+ { cmd: 'solid agent risk', why: 'Agents with elevated risk this week' },
1058
1272
  ]);
1059
1273
  // ── solid agent dispatch <verb> — generic verb dispatcher ────────────
1060
1274
  //