@velaro/cli 1.4.102 → 1.4.103
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 +19 -0
- package/bin/velaro.js +12 -0
- package/lib/api.js +2 -1
- package/lib/apple-pay.js +32 -0
- package/lib/apple-pay.test.js +32 -0
- package/lib/avatar-switch.js +42 -0
- package/lib/avatar-switch.test.js +49 -0
- package/lib/build-info.js +28 -0
- package/lib/build-info.test.js +24 -0
- package/lib/commands/apple-pay.js +73 -0
- package/lib/commands/avatar.js +60 -2
- package/lib/commands/billing-automation.js +172 -0
- package/lib/commands/copilotstudio.js +14 -1
- package/lib/commands/enterprise-reports.js +1 -0
- package/lib/commands/entitlement.js +29 -1
- package/lib/commands/focus.js +1 -1
- package/lib/commands/index.js +38 -2
- package/lib/commands/logs-insights.js +342 -0
- package/lib/commands/logs.js +313 -3
- package/lib/commands/magento.js +16 -0
- package/lib/commands/mcp-key.js +23 -1
- package/lib/commands/netsuite.js +67 -2
- package/lib/commands/notifications.js +34 -1
- package/lib/commands/ops.js +23 -54
- package/lib/commands/report-backfill.js +23 -5
- package/lib/commands/report.js +77 -14
- package/lib/commands/salesforce.js +101 -0
- package/lib/commands/shopify.js +84 -0
- package/lib/commands/signature.js +79 -0
- package/lib/commands/site-builder.js +30 -0
- package/lib/commands/support.js +22 -0
- package/lib/commands/teams.js +11 -1
- package/lib/commands/workflow.js +33 -0
- package/lib/commands/zoom-phone.js +15 -0
- package/lib/enterprise-reports.test.js +1 -1
- package/lib/entitlement-report-packages.test.js +47 -0
- package/lib/logs-insights.test.js +146 -0
- package/lib/mcp-key.test.js +11 -0
- package/lib/messaging-routes.test.js +10 -1
- package/lib/oauth.js +14 -2
- package/lib/report-range.js +21 -0
- package/lib/report-range.test.js +38 -0
- package/lib/shopify-write-policy.test.js +34 -0
- package/lib/signature-policy.js +70 -0
- package/lib/signature-policy.test.js +48 -0
- package/package.json +1 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// velaro billing-automation — review-hold and dry-run switches for invoice emails and charges
|
|
2
|
+
// (BillingAutomationController, /api/BillingAutomation). Staff only.
|
|
3
|
+
import { request } from '../api.js';
|
|
4
|
+
|
|
5
|
+
const MODES = ['auto', 'review', 'dry_run'];
|
|
6
|
+
const GATES = ['send', 'charge', 'both'];
|
|
7
|
+
|
|
8
|
+
function money(cents) {
|
|
9
|
+
if (cents == null) return '';
|
|
10
|
+
return `$${(cents / 100).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function fail(message) {
|
|
14
|
+
console.error(message);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function listRules() {
|
|
19
|
+
const rules = await request('GET', '/api/BillingAutomation/rules');
|
|
20
|
+
if (!rules.length) {
|
|
21
|
+
console.log('No rules. With no rules, every invoice runs automatically.');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
for (const r of rules) {
|
|
25
|
+
const scope = [
|
|
26
|
+
r.accountType ? `account=${r.accountType}` : null,
|
|
27
|
+
r.paymentMethod ? `method=${r.paymentMethod}` : null,
|
|
28
|
+
r.minAmountCents != null ? `from=${money(r.minAmountCents)}` : null,
|
|
29
|
+
r.maxAmountCents != null ? `to=${money(r.maxAmountCents)}` : null,
|
|
30
|
+
].filter(Boolean).join(' ') || 'global default';
|
|
31
|
+
console.log(`#${r.id} ${r.enabled ? 'on ' : 'off'} ${r.appliesTo.padEnd(6)} ${r.mode.padEnd(8)} ${scope} ${r.name}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function setGlobal(appliesTo, mode) {
|
|
36
|
+
if (!GATES.includes(appliesTo)) fail(`appliesTo must be one of: ${GATES.join(', ')}`);
|
|
37
|
+
if (!MODES.includes(mode)) fail(`mode must be one of: ${MODES.join(', ')}`);
|
|
38
|
+
await request('PUT', `/api/BillingAutomation/global/${appliesTo}`, { mode });
|
|
39
|
+
console.log(`Global ${appliesTo} set to ${mode}.`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function addRule(args) {
|
|
43
|
+
if (!args.name) fail('Usage: velaro billing-automation rule-add --name "Review big ACH" --applies-to charge --mode review [--account-type enterprise] [--min-cents 100000] [--max-cents 500000] [--payment-method ach]');
|
|
44
|
+
const body = {
|
|
45
|
+
name: args.name,
|
|
46
|
+
appliesTo: args.appliesTo ?? 'both',
|
|
47
|
+
mode: args.mode,
|
|
48
|
+
accountType: args.accountType ?? null,
|
|
49
|
+
minAmountCents: args.minCents ?? null,
|
|
50
|
+
maxAmountCents: args.maxCents ?? null,
|
|
51
|
+
paymentMethod: args.paymentMethod ?? null,
|
|
52
|
+
enabled: true,
|
|
53
|
+
};
|
|
54
|
+
const r = await request('POST', '/api/BillingAutomation/rules', body);
|
|
55
|
+
console.log(`Rule #${r.id} added: ${r.name} (${r.appliesTo} -> ${r.mode}).`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function setRuleEnabled(id, enabled) {
|
|
59
|
+
const rules = await request('GET', '/api/BillingAutomation/rules');
|
|
60
|
+
const rule = rules.find((r) => r.id === Number(id));
|
|
61
|
+
if (!rule) fail(`No rule #${id}.`);
|
|
62
|
+
await request('PUT', `/api/BillingAutomation/rules/${rule.id}`, {
|
|
63
|
+
name: rule.name,
|
|
64
|
+
appliesTo: rule.appliesTo,
|
|
65
|
+
mode: rule.mode,
|
|
66
|
+
accountType: rule.accountType,
|
|
67
|
+
minAmountCents: rule.minAmountCents,
|
|
68
|
+
maxAmountCents: rule.maxAmountCents,
|
|
69
|
+
paymentMethod: rule.paymentMethod,
|
|
70
|
+
enabled,
|
|
71
|
+
});
|
|
72
|
+
console.log(`Rule #${rule.id} ${enabled ? 'turned on' : 'turned off'}.`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function deleteRule(id) {
|
|
76
|
+
await request('DELETE', `/api/BillingAutomation/rules/${id}`);
|
|
77
|
+
console.log(`Rule #${id} deleted.`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function printDecisions(rows, emptyText) {
|
|
81
|
+
if (!rows.length) {
|
|
82
|
+
console.log(emptyText);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
for (const d of rows) {
|
|
86
|
+
const label = d.outcome === 'dry_run' ? 'WOULD' : 'HELD ';
|
|
87
|
+
const state = d.resolution ? ` [${d.resolution}]` : '';
|
|
88
|
+
console.log(`#${d.id} ${label} ${d.action.padEnd(6)} invoice ${d.invoiceId} ${money(d.amountCents)} ${d.paymentMethod ?? '-'} ${d.createdAt}${state}`);
|
|
89
|
+
console.log(` ${d.reason}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function queue() {
|
|
94
|
+
printDecisions(await request('GET', '/api/BillingAutomation/decisions?status=open&take=200'), 'Nothing is waiting for review.');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function dryRuns() {
|
|
98
|
+
printDecisions(await request('GET', '/api/BillingAutomation/decisions?status=dry_run&take=100'), 'No dry-run entries.');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function approve(id) {
|
|
102
|
+
const res = await request('POST', `/api/BillingAutomation/decisions/${id}/approve`, {});
|
|
103
|
+
console.log(`Approved #${id}. Released: ${res.released}.`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function dismiss(id) {
|
|
107
|
+
await request('POST', `/api/BillingAutomation/decisions/${id}/dismiss`, {});
|
|
108
|
+
console.log(`Dismissed #${id}. It stays on hold until approved.`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function setAccountType(subscriptionId, value) {
|
|
112
|
+
const res = await request('PUT', `/api/BillingAutomation/subscription/${subscriptionId}/account-type`, { accountType: value ?? null });
|
|
113
|
+
console.log(`Subscription ${res.id} account type: ${res.accountType ?? '(unset)'}.`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function notifySettings() {
|
|
117
|
+
const all = await request('GET', '/api/BillingNotifications/settings');
|
|
118
|
+
for (const [key, value] of Object.entries(all)) {
|
|
119
|
+
console.log(`${key.padEnd(20)} ${value ?? '(not set: code default)'}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function notifySet(key, value) {
|
|
124
|
+
await request('PUT', `/api/BillingNotifications/settings/${key}`, { value });
|
|
125
|
+
console.log(`${key} set to ${value}.`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Only the channels you pass change. The others keep their current override (the API replaces all three).
|
|
129
|
+
async function setReceipts(subscriptionId, args) {
|
|
130
|
+
const sub = await request('GET', `/api/BillingSubscription/${subscriptionId}`);
|
|
131
|
+
const res = await request('PUT', `/api/BillingNotifications/subscriptions/${subscriptionId}/receipts`, {
|
|
132
|
+
card: args.card ?? sub.receiptCardOverride ?? null,
|
|
133
|
+
ach: args.ach ?? sub.receiptAchOverride ?? null,
|
|
134
|
+
other: args.other ?? sub.receiptOtherOverride ?? null,
|
|
135
|
+
});
|
|
136
|
+
console.log(`Subscription ${res.id} receipts: card=${res.card ?? 'inherit'} ach=${res.ach ?? 'inherit'} other=${res.other ?? 'inherit'}.`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const billingAutomationCommand = {
|
|
140
|
+
command: 'billing-automation <subcommand>',
|
|
141
|
+
describe: 'Review-hold and dry-run switches for invoice emails and charges, the review queue, and account types',
|
|
142
|
+
builder: (yargs) =>
|
|
143
|
+
yargs
|
|
144
|
+
.command('rules', 'List every automation rule and global switch', {}, () => listRules())
|
|
145
|
+
.command('global <appliesTo> <mode>', 'Set the global default: appliesTo = send | charge | both; mode = auto | review | dry_run', {}, (args) => setGlobal(args.appliesTo, args.mode))
|
|
146
|
+
.command('rule-add', 'Add a scoped rule (--name required; filters are optional)', {
|
|
147
|
+
name: { type: 'string' },
|
|
148
|
+
appliesTo: { type: 'string', choices: GATES, default: 'both' },
|
|
149
|
+
mode: { type: 'string', choices: MODES, demandOption: true },
|
|
150
|
+
accountType: { type: 'string' },
|
|
151
|
+
minCents: { type: 'number' },
|
|
152
|
+
maxCents: { type: 'number' },
|
|
153
|
+
paymentMethod: { type: 'string', choices: ['cash', 'check', 'ach', 'wire', 'card'] },
|
|
154
|
+
}, (args) => addRule(args))
|
|
155
|
+
.command('rule-on <id>', 'Turn a rule on', {}, (args) => setRuleEnabled(args.id, true))
|
|
156
|
+
.command('rule-off <id>', 'Turn a rule off', {}, (args) => setRuleEnabled(args.id, false))
|
|
157
|
+
.command('rule-delete <id>', 'Delete a rule (queue entries keep their rule name)', {}, (args) => deleteRule(args.id))
|
|
158
|
+
.command('queue', 'Show held sends and charges waiting for review', {}, () => queue())
|
|
159
|
+
.command('dry-runs', 'Show what the dry-run switches would have sent or charged', {}, () => dryRuns())
|
|
160
|
+
.command('approve <id>', 'Approve a held entry and release its send or charge now', {}, (args) => approve(args.id))
|
|
161
|
+
.command('dismiss <id>', 'Dismiss a held entry (it stays on hold, alerts stop)', {}, (args) => dismiss(args.id))
|
|
162
|
+
.command('account-type <subscriptionId> [value]', 'Set a subscription account type that rules match on (omit value to clear)', {}, (args) => setAccountType(args.subscriptionId, args.value))
|
|
163
|
+
.command('notify-settings', 'Show the global notification settings (receipts, invoice BCC, digest recipients)', {}, () => notifySettings())
|
|
164
|
+
.command('notify-set <key> <value>', 'Set a global notification setting: receipts.card|receipts.ach|receipts.other = never|send; invoices.bcc = emails (blank = none); digest.recipients = emails', {}, (args) => notifySet(args.key, args.value))
|
|
165
|
+
.command('receipts <subscriptionId>', 'Set receipt overrides on one subscription (--card/--ach/--other = never|send). Channels you omit keep their current override.', {
|
|
166
|
+
card: { type: 'string', choices: ['never', 'send'] },
|
|
167
|
+
ach: { type: 'string', choices: ['never', 'send'] },
|
|
168
|
+
other: { type: 'string', choices: ['never', 'send'] },
|
|
169
|
+
}, (args) => setReceipts(args.subscriptionId, args))
|
|
170
|
+
.demandCommand(1, 'Specify a subcommand: rules | global | rule-add | rule-on | rule-off | rule-delete | queue | dry-runs | approve | dismiss | account-type'),
|
|
171
|
+
handler: () => {},
|
|
172
|
+
};
|
|
@@ -110,5 +110,18 @@ export const copilotStudioCommand = {
|
|
|
110
110
|
}
|
|
111
111
|
}),
|
|
112
112
|
})
|
|
113
|
-
.
|
|
113
|
+
.command({
|
|
114
|
+
command: 'ask <id> <question>',
|
|
115
|
+
describe: 'Live diagnostic: ask the agent a real question and classify the reply (answered | vendor_limit | no_answer). Exit 1 unless answered.',
|
|
116
|
+
builder: y => y.positional('id', { type: 'number' }).positional('question', { type: 'string' }),
|
|
117
|
+
handler: runCommand(async argv => {
|
|
118
|
+
const r = await request('POST', '/CopilotStudio/message', { configId: argv.id, message: argv.question });
|
|
119
|
+
console.log(`
|
|
120
|
+
kind: ${r?.kind}
|
|
121
|
+
reply: ${r?.reply}
|
|
122
|
+
`);
|
|
123
|
+
if (r?.kind !== 'answered') process.exitCode = 1;
|
|
124
|
+
}),
|
|
125
|
+
})
|
|
126
|
+
.demandCommand(1, 'Specify a subcommand: list | add | update | remove | test | ask'),
|
|
114
127
|
};
|
|
@@ -19,6 +19,7 @@ const REPORTS = {
|
|
|
19
19
|
'bot-containment': 'Claimed vs true bot containment and handoff regret',
|
|
20
20
|
'effort-index': 'Inferred 0-100 customer effort by topic, program and team (not a survey CES)',
|
|
21
21
|
'promise-ledger': 'Agent commitments made in chat and whether a follow-up appeared; overdue list',
|
|
22
|
+
'new-agent-ramp': 'Agents whose first chat is in --from/--to: week-by-week ramp (chats, first response, QA, rating) against tenured agents',
|
|
22
23
|
'promise-dismiss': 'Dismiss one promise by --id (managers only)',
|
|
23
24
|
'weekly-brief-send-test': 'Email this week\'s brief to the signed-in user',
|
|
24
25
|
'year-in-review': 'Build the 12-month Year in review document: --from/--to (default last 12 whole Pacific months) starts a build and prints its id; --id <id> checks status and the download link',
|
|
@@ -39,6 +39,31 @@ ${pkg.displayName} (${pkg.packageKey}) - plan ${pkg.plan}, default OFF${pkg.site
|
|
|
39
39
|
console.log('');
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
// Formats the GET Entitlements/report-packages payload (five category packages nested under Enterprise Reports). Exported for the unit test.
|
|
43
|
+
export function formatReportPackages(pkg) {
|
|
44
|
+
const lines = [];
|
|
45
|
+
const site = pkg.siteId ? `, site ${pkg.siteId}` : '';
|
|
46
|
+
lines.push(`${pkg.top.name} (${pkg.top.slug}) - plan ${pkg.plan}, default OFF${site}${pkg.siteId ? (pkg.top.enabled ? ' [ALL ON]' : '') : ''}`);
|
|
47
|
+
lines.push(` ${pkg.top.tagline}`);
|
|
48
|
+
for (const c of pkg.categories) {
|
|
49
|
+
const state = pkg.siteId ? ` [${c.enabled ? 'ON ' : 'off'}] ${c.enabledCount}/${c.reportCount} reports` : ` ${c.reportCount} reports`;
|
|
50
|
+
lines.push('');
|
|
51
|
+
lines.push(`${c.name} (${c.slug})${state}`);
|
|
52
|
+
lines.push(` ${c.tagline}`);
|
|
53
|
+
for (const r of c.reports) {
|
|
54
|
+
const mark = pkg.siteId ? (r.enabled ? '[ON ] ' : '[off] ') : '';
|
|
55
|
+
lines.push(` ${mark}${r.name} (${r.id}) - package ${r.packageSlug}, key ${r.packageKey}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return lines.join('\n');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function reportPackages(args) {
|
|
62
|
+
const q = args.site ? `?siteId=${encodeURIComponent(args.site)}` : '';
|
|
63
|
+
const pkg = await request('GET', `Entitlements/report-packages${q}`);
|
|
64
|
+
console.log(`\n${formatReportPackages(pkg)}\n`);
|
|
65
|
+
}
|
|
66
|
+
|
|
42
67
|
async function listFeatures() {
|
|
43
68
|
const features = await request('GET', 'Entitlements/features');
|
|
44
69
|
|
|
@@ -193,6 +218,9 @@ export function entitlementCommand(yargs) {
|
|
|
193
218
|
.command('enterprise-reports', 'Show the Enterprise Reports package items (with --site, which are ON for that site)', y => y
|
|
194
219
|
.option('site', { type: 'number', desc: 'Site ID' })
|
|
195
220
|
, a => enterpriseReportsPackage(a))
|
|
221
|
+
.command('report-packages', 'Show the five report category packages and every report in them (with --site, which are ON for that site)', y => y
|
|
222
|
+
.option('site', { type: 'number', desc: 'Site ID' })
|
|
223
|
+
, a => reportPackages(a))
|
|
196
224
|
.command('set-override', 'Enable or disable a feature for a specific site (overrides plan)', y => y
|
|
197
225
|
.option('site', { type: 'number', demandOption: true, desc: 'Site ID' })
|
|
198
226
|
.option('key', { type: 'string', demandOption: true, desc: 'Feature key, e.g. EnableIvr' })
|
|
@@ -227,5 +255,5 @@ export function entitlementCommand(yargs) {
|
|
|
227
255
|
.option('key', { type: 'string', demandOption: true, desc: 'Feature key, e.g. EnableIvr' })
|
|
228
256
|
.option('rollback', { type: 'boolean', desc: 'Pass to roll back this flag to Subscription.cs (default: go live)' })
|
|
229
257
|
, a => setCutover(a))
|
|
230
|
-
.demandCommand(1, 'Specify a subcommand: get | list-features | enterprise-reports | set-override | remove-override | seed | seed-plans | backfill | backfill-sap-tiers | backfill-legacy-write-tiers | reconcile | comp | set-lock | list-cutover | set-cutover');
|
|
258
|
+
.demandCommand(1, 'Specify a subcommand: get | list-features | enterprise-reports | report-packages | set-override | remove-override | seed | seed-plans | backfill | backfill-sap-tiers | backfill-legacy-write-tiers | reconcile | comp | set-lock | list-cutover | set-cutover');
|
|
231
259
|
}
|
package/lib/commands/focus.js
CHANGED
|
@@ -225,7 +225,7 @@ const setTriageRuleCommand = {
|
|
|
225
225
|
builder: (y) => y
|
|
226
226
|
.positional('label', { type: 'string', describe: `Label: ${VALID_LABELS.join(', ')}` })
|
|
227
227
|
.positional('enabled', { type: 'string', describe: 'true or false', choices: ['true', 'false'] })
|
|
228
|
-
.option('triage-mode', { type: 'string', choices: ['off', 'economy'], describe: 'off (
|
|
228
|
+
.option('triage-mode', { type: 'string', choices: ['off', 'economy'], describe: 'off (this site always uses the AI call) or economy (skip the AI call for obvious messages). Unset = platform default (economy)' }),
|
|
229
229
|
handler: async (argv) => {
|
|
230
230
|
const { label, enabled } = argv;
|
|
231
231
|
const mode = argv['triage-mode'];
|
package/lib/commands/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { get, post, getCredentials, messagingGet, messagingPost } from '../api.js';
|
|
1
|
+
import { get, post, getCredentials, messagingGet, messagingPost, messagingPut } from '../api.js';
|
|
2
2
|
|
|
3
3
|
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
4
4
|
|
|
@@ -266,6 +266,41 @@ Index ready on site ${argv.site}: ${idx.name} (id: ${idx.id}, purpose: ${idx.pur
|
|
|
266
266
|
},
|
|
267
267
|
};
|
|
268
268
|
|
|
269
|
+
// -- profile (Velaro staff only) --------------------------------------------------
|
|
270
|
+
// PUT KnowledgeSetup/Staff/{siteId}/index-profile on velaro-messaging. Apply-if-present: only the
|
|
271
|
+
// flags you pass are changed. The index is addressed by name (the endpoint looks up siteId+name).
|
|
272
|
+
|
|
273
|
+
const profileCommand = {
|
|
274
|
+
command: 'profile',
|
|
275
|
+
describe: 'Set the ingestion profile of one index on any site (Velaro staff only; only passed flags change)',
|
|
276
|
+
builder: (y) =>
|
|
277
|
+
y
|
|
278
|
+
.option('site', { type: 'number', demandOption: true, describe: 'Target site ID' })
|
|
279
|
+
.option('index', { type: 'string', demandOption: true, describe: 'Index name, e.g. 100140-troubleshooting' })
|
|
280
|
+
.option('strategy', { type: 'string', choices: ['procedure', 'section'], describe: 'Chunk strategy' })
|
|
281
|
+
.option('chunk-size', { type: 'number', describe: 'Chunk size' })
|
|
282
|
+
.option('chunk-overlap', { type: 'number', describe: 'Chunk overlap' })
|
|
283
|
+
.option('purpose', { type: 'string', choices: ['general', 'troubleshooting', 'catalog'], describe: 'Index purpose' })
|
|
284
|
+
.option('search-size', { type: 'number', describe: 'Results per search' })
|
|
285
|
+
.option('exclude-from-all-sources', { type: 'boolean', describe: 'Keep this index out of the ["*"] all-sources search' })
|
|
286
|
+
.option('json', { type: 'boolean', describe: 'Print raw JSON' }),
|
|
287
|
+
handler: async (argv) => {
|
|
288
|
+
const body = { indexName: argv.index };
|
|
289
|
+
if (argv.strategy !== undefined) body.chunkStrategy = argv.strategy;
|
|
290
|
+
if (argv['chunk-size'] !== undefined) body.chunkSize = argv['chunk-size'];
|
|
291
|
+
if (argv['chunk-overlap'] !== undefined) body.chunkOverlap = argv['chunk-overlap'];
|
|
292
|
+
if (argv.purpose !== undefined) body.purpose = argv.purpose;
|
|
293
|
+
if (argv['search-size'] !== undefined) body.searchSize = argv['search-size'];
|
|
294
|
+
if (argv['exclude-from-all-sources'] !== undefined) body.excludeFromAllSources = argv['exclude-from-all-sources'];
|
|
295
|
+
const idx = await messagingPut(`/KnowledgeSetup/Staff/${encodeURIComponent(argv.site)}/index-profile`, body);
|
|
296
|
+
if (argv.json) { console.log(JSON.stringify(idx, null, 2)); return; }
|
|
297
|
+
console.log(`
|
|
298
|
+
Profile updated on site ${argv.site}: ${idx.name} (purpose: ${idx.purpose}, strategy: ${idx.chunkStrategy}, size: ${idx.chunkSize}, overlap: ${idx.chunkOverlap}, searchSize: ${idx.searchSize}, excludeFromAllSources: ${!!idx.excludeFromAllSources})
|
|
299
|
+
Re-ingest to apply the new chunking to existing content.
|
|
300
|
+
`);
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
|
|
269
304
|
export const indexCommand = {
|
|
270
305
|
command: 'index <subcommand>',
|
|
271
306
|
describe: 'Manage search indexes — view quota, physical index health, and reingest content',
|
|
@@ -277,6 +312,7 @@ export const indexCommand = {
|
|
|
277
312
|
.command(reingestCommand)
|
|
278
313
|
.command(testCommand)
|
|
279
314
|
.command(createCommand)
|
|
280
|
-
.
|
|
315
|
+
.command(profileCommand)
|
|
316
|
+
.demandCommand(1, 'Specify a subcommand: list, site, provision, reingest, test, create, profile'),
|
|
281
317
|
handler: () => {},
|
|
282
318
|
};
|