@facilio/cli 0.3.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/LICENSE +21 -0
- package/README.md +120 -0
- package/dist/commands/login.js +75 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +41 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/whoami.js +26 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/core/api.js +158 -0
- package/dist/core/api.js.map +1 -0
- package/dist/core/constants.js +53 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/credentials.js +209 -0
- package/dist/core/credentials.js.map +1 -0
- package/dist/core/identity.js +162 -0
- package/dist/core/identity.js.map +1 -0
- package/dist/core/logger.js +9 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/prompt.js +29 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/regions.js +45 -0
- package/dist/core/regions.js.map +1 -0
- package/dist/core/secretStore.js +251 -0
- package/dist/core/secretStore.js.map +1 -0
- package/dist/core/wrap.js +17 -0
- package/dist/core/wrap.js.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/products/connections/client.js +125 -0
- package/dist/products/connections/client.js.map +1 -0
- package/dist/products/connections/commands.js +324 -0
- package/dist/products/connections/commands.js.map +1 -0
- package/dist/products/connections/index.js +63 -0
- package/dist/products/connections/index.js.map +1 -0
- package/dist/products/connections/state.js +44 -0
- package/dist/products/connections/state.js.map +1 -0
- package/dist/products/types.js +2 -0
- package/dist/products/types.js.map +1 -0
- package/dist/products/vibe/app.js +97 -0
- package/dist/products/vibe/app.js.map +1 -0
- package/dist/products/vibe/config.js +57 -0
- package/dist/products/vibe/config.js.map +1 -0
- package/dist/products/vibe/db.js +155 -0
- package/dist/products/vibe/db.js.map +1 -0
- package/dist/products/vibe/deploy.js +92 -0
- package/dist/products/vibe/deploy.js.map +1 -0
- package/dist/products/vibe/function.js +240 -0
- package/dist/products/vibe/function.js.map +1 -0
- package/dist/products/vibe/index.js +112 -0
- package/dist/products/vibe/index.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `facilio connections …` command implementations. Each command is one call
|
|
3
|
+
* to a Facilio Connections meta-tool over MCP; see the server repo
|
|
4
|
+
* (facilio-connections-mcp) for the authoritative tool contracts.
|
|
5
|
+
*/
|
|
6
|
+
import { promises as fs } from 'node:fs';
|
|
7
|
+
import { stdin } from 'node:process';
|
|
8
|
+
import open from 'open';
|
|
9
|
+
import { logger } from '../../core/logger.js';
|
|
10
|
+
import { prompt } from '../../core/prompt.js';
|
|
11
|
+
import { callConnectionsTool } from './client.js';
|
|
12
|
+
import { loadSessionId, saveSessionId } from './state.js';
|
|
13
|
+
export function cmdCtx(opts, version) {
|
|
14
|
+
return { mcpUrl: opts.mcpUrl, app: opts.app, version, json: !!opts.json };
|
|
15
|
+
}
|
|
16
|
+
function printJson(payload) {
|
|
17
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
18
|
+
}
|
|
19
|
+
function sessionArg() {
|
|
20
|
+
const id = loadSessionId();
|
|
21
|
+
return id ? { session_id: id } : {};
|
|
22
|
+
}
|
|
23
|
+
/* ---------- search ---------- */
|
|
24
|
+
export async function searchCommand(queryWords, ctx) {
|
|
25
|
+
const query = queryWords.join(' ').trim();
|
|
26
|
+
if (!query)
|
|
27
|
+
throw new Error('A search query is required, e.g. `facilio connections search create xero invoice`.');
|
|
28
|
+
const existing = loadSessionId();
|
|
29
|
+
const out = await callConnectionsTool(ctx, 'FACILIO_SEARCH_ACTIONS', {
|
|
30
|
+
queries: [query],
|
|
31
|
+
session: existing ? { id: existing } : { generate_id: true },
|
|
32
|
+
});
|
|
33
|
+
if (out.session?.id)
|
|
34
|
+
saveSessionId(out.session.id);
|
|
35
|
+
if (ctx.json)
|
|
36
|
+
return printJson(out);
|
|
37
|
+
for (const r of out.results ?? []) {
|
|
38
|
+
logger.success(`Actions for: ${r.use_case}`);
|
|
39
|
+
for (const slug of r.primary_action_slugs) {
|
|
40
|
+
const meta = out.action_schemas?.[slug];
|
|
41
|
+
logger.step(`${slug}${meta?.description ? ` — ${meta.description}` : ''}`);
|
|
42
|
+
}
|
|
43
|
+
if (r.related_action_slugs.length) {
|
|
44
|
+
logger.info(`Related: ${r.related_action_slugs.join(', ')}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
for (const s of out.connection_statuses ?? []) {
|
|
48
|
+
const mark = s.has_active_connection ? '✓ connected' : '○ not connected';
|
|
49
|
+
logger.step(`${s.connection}: ${mark}${s.status_message ? ` — ${s.status_message}` : ''}`);
|
|
50
|
+
}
|
|
51
|
+
const foundAny = (out.results ?? []).some((r) => r.primary_action_slugs.length > 0);
|
|
52
|
+
if (!foundAny && out.next_steps_guidance?.length) {
|
|
53
|
+
// Degraded response (e.g. catalog fetch failed) — the server explains why.
|
|
54
|
+
for (const line of out.next_steps_guidance)
|
|
55
|
+
logger.warn(line);
|
|
56
|
+
process.exitCode = 1;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
logger.info('Next: `facilio connections schemas <action_slug>` then `facilio connections execute <action_slug> --params <json>`.');
|
|
60
|
+
}
|
|
61
|
+
/* ---------- schemas ---------- */
|
|
62
|
+
export async function schemasCommand(slugs, withOutput, ctx) {
|
|
63
|
+
const out = await callConnectionsTool(ctx, 'FACILIO_GET_ACTION_SCHEMAS', {
|
|
64
|
+
action_slugs: slugs,
|
|
65
|
+
include: withOutput ? ['input_schema', 'output_schema'] : ['input_schema'],
|
|
66
|
+
...sessionArg(),
|
|
67
|
+
});
|
|
68
|
+
// Schemas are JSON either way; human mode is just pretty-printed JSON.
|
|
69
|
+
printJson(out);
|
|
70
|
+
}
|
|
71
|
+
/* ---------- manage: list / link / unlink ---------- */
|
|
72
|
+
async function manage(ctx, items) {
|
|
73
|
+
const out = await callConnectionsTool(ctx, 'FACILIO_MANAGE_CONNECTIONS', {
|
|
74
|
+
connections: items,
|
|
75
|
+
...sessionArg(),
|
|
76
|
+
});
|
|
77
|
+
return out.results ?? [];
|
|
78
|
+
}
|
|
79
|
+
function renderResult(r) {
|
|
80
|
+
if (!r.ok) {
|
|
81
|
+
logger.error(`${r.name}: ${JSON.stringify(r.error ?? 'failed')}`);
|
|
82
|
+
process.exitCode = 1;
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (r.accounts?.length) {
|
|
86
|
+
logger.success(`${r.name}: ${r.accounts.length} connected account(s)`);
|
|
87
|
+
for (const a of r.accounts) {
|
|
88
|
+
const flags = [a.is_default ? 'default' : null, a.status].filter(Boolean).join(', ');
|
|
89
|
+
logger.step(`${a.account_slug}${a.display_name ? ` — ${a.display_name}` : ''}${flags ? ` (${flags})` : ''}`);
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (r.redirect_url) {
|
|
94
|
+
logger.info(`${r.name}: authorize in the browser:`);
|
|
95
|
+
logger.step(r.redirect_url);
|
|
96
|
+
if (r.note)
|
|
97
|
+
logger.step(r.note);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
logger.success(`${r.name}: ${r.action} ok${r.note ? ` — ${r.note}` : ''}`);
|
|
101
|
+
}
|
|
102
|
+
export async function listCommand(names, ctx) {
|
|
103
|
+
const results = await manage(ctx, names.map((name) => ({ name, action: 'list' })));
|
|
104
|
+
if (ctx.json)
|
|
105
|
+
return printJson({ results });
|
|
106
|
+
results.forEach(renderResult);
|
|
107
|
+
}
|
|
108
|
+
export async function linkCommand(name, opts, ctx) {
|
|
109
|
+
const [result] = await manage(ctx, [{ name, action: 'add' }]);
|
|
110
|
+
if (ctx.json && !opts.wait)
|
|
111
|
+
return printJson({ result });
|
|
112
|
+
if (!result?.ok) {
|
|
113
|
+
throw new Error(`Could not start authorization for ${name}: ${JSON.stringify(result?.error ?? 'unknown error')}`);
|
|
114
|
+
}
|
|
115
|
+
if (result.redirect_url) {
|
|
116
|
+
logger.info(`Authorize ${name} in the browser:`);
|
|
117
|
+
logger.step(result.redirect_url);
|
|
118
|
+
if (opts.open !== false) {
|
|
119
|
+
await open(result.redirect_url).catch(() => {
|
|
120
|
+
logger.warn('Could not auto-open browser. Open the URL above manually.');
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (opts.wait) {
|
|
124
|
+
await waitCommand([name], { mode: 'any', timeout: opts.timeout }, ctx);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
logger.info(`Then run \`facilio connections wait ${name}\` to confirm it becomes ACTIVE.`);
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Already authorized (server returns accounts instead of a redirect).
|
|
132
|
+
renderResult(result);
|
|
133
|
+
}
|
|
134
|
+
export async function unlinkCommand(name, opts, ctx) {
|
|
135
|
+
// Removing an authorization is destructive — confirm unless told otherwise.
|
|
136
|
+
if (!opts.yes && !ctx.json) {
|
|
137
|
+
if (!stdin.isTTY) {
|
|
138
|
+
throw new Error(`Refusing to unlink '${name}' non-interactively. Re-run with --yes to confirm.`);
|
|
139
|
+
}
|
|
140
|
+
const answer = await prompt(`Remove your authorization for '${name}'? Type 'yes' to confirm`, {
|
|
141
|
+
optional: true,
|
|
142
|
+
});
|
|
143
|
+
if ((answer ?? '').toLowerCase() !== 'yes') {
|
|
144
|
+
logger.info('Aborted — nothing changed.');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const [result] = await manage(ctx, [{ name, action: 'remove' }]);
|
|
149
|
+
if (ctx.json)
|
|
150
|
+
return printJson({ result });
|
|
151
|
+
renderResult(result);
|
|
152
|
+
}
|
|
153
|
+
/* ---------- wait ---------- */
|
|
154
|
+
export async function waitCommand(names, opts, ctx) {
|
|
155
|
+
const timeoutS = opts.timeout ? Number(opts.timeout) : undefined;
|
|
156
|
+
if (opts.timeout && (!Number.isFinite(timeoutS) || timeoutS <= 0)) {
|
|
157
|
+
throw new Error('--timeout must be a positive number of seconds.');
|
|
158
|
+
}
|
|
159
|
+
logger.info(`Waiting for ${names.join(', ')} to become ACTIVE…`);
|
|
160
|
+
const out = await callConnectionsTool(ctx, 'FACILIO_WAIT_FOR_CONNECTIONS', {
|
|
161
|
+
connections: names,
|
|
162
|
+
mode: opts.mode === 'all' ? 'all' : 'any',
|
|
163
|
+
...(timeoutS ? { timeout_s: Math.round(timeoutS) } : {}),
|
|
164
|
+
...sessionArg(),
|
|
165
|
+
});
|
|
166
|
+
if (ctx.json)
|
|
167
|
+
return printJson(out);
|
|
168
|
+
for (const [conn, status] of Object.entries(out.statuses ?? {})) {
|
|
169
|
+
(status === 'ACTIVE' ? logger.success : logger.warn)(`${conn}: ${status}`);
|
|
170
|
+
}
|
|
171
|
+
if (!out.satisfied) {
|
|
172
|
+
logger.error(`Not satisfied after ${Math.round(out.waited_s)}s.`);
|
|
173
|
+
process.exitCode = 1;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/* ---------- execute ---------- */
|
|
177
|
+
/** Parse one `--params` value into a JSON object. Throws on non-objects. */
|
|
178
|
+
export function parseParamsObject(raw) {
|
|
179
|
+
if (raw === undefined)
|
|
180
|
+
return {};
|
|
181
|
+
try {
|
|
182
|
+
const parsed = JSON.parse(raw);
|
|
183
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
184
|
+
throw new Error('not an object');
|
|
185
|
+
}
|
|
186
|
+
return parsed;
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
throw new Error('--params must be a JSON object, e.g. \'{"amount": 100}\'.');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async function readStdin() {
|
|
193
|
+
if (stdin.isTTY) {
|
|
194
|
+
throw new Error('`--params -` requested but stdin is a TTY. Pipe the JSON in or pass it inline.');
|
|
195
|
+
}
|
|
196
|
+
const chunks = [];
|
|
197
|
+
for await (const chunk of stdin)
|
|
198
|
+
chunks.push(chunk);
|
|
199
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Pair positional action slugs with their `--params` (by order) into the
|
|
203
|
+
* action rows the multi-execute tool expects. One `--params` per slug for
|
|
204
|
+
* parallel runs, or none at all (every action gets `{}`). `--account`, when
|
|
205
|
+
* given, applies to every action.
|
|
206
|
+
*/
|
|
207
|
+
export function buildInlineActions(slugs, rawParamsList, account) {
|
|
208
|
+
if (slugs.length === 0) {
|
|
209
|
+
throw new Error('An action slug is required, e.g. `facilio connections execute xero.create_invoice --params …` (or use --file for a batch).');
|
|
210
|
+
}
|
|
211
|
+
if (rawParamsList.length > slugs.length) {
|
|
212
|
+
throw new Error(`Got ${rawParamsList.length} --params but only ${slugs.length} action slug(s). Pass one --params per slug (in order), or none.`);
|
|
213
|
+
}
|
|
214
|
+
if (rawParamsList.length && rawParamsList.length !== slugs.length) {
|
|
215
|
+
throw new Error('Pass one --params per action slug (in the same order), or omit --params entirely.');
|
|
216
|
+
}
|
|
217
|
+
return slugs.map((slug, i) => ({
|
|
218
|
+
action_slug: slug,
|
|
219
|
+
arguments: parseParamsObject(rawParamsList[i]),
|
|
220
|
+
...(account ? { account_slug: account } : {}),
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
/** Required input keys that are absent (or empty) in the supplied arguments. */
|
|
224
|
+
export function requiredMissing(inputSchema, args) {
|
|
225
|
+
const required = inputSchema?.required;
|
|
226
|
+
if (!Array.isArray(required))
|
|
227
|
+
return [];
|
|
228
|
+
return required.filter((k) => args[k] === undefined || args[k] === null || args[k] === '');
|
|
229
|
+
}
|
|
230
|
+
/** Validate arguments against fetched schemas and print the request; no call. */
|
|
231
|
+
async function dryRunPreview(actions, ctx) {
|
|
232
|
+
const slugs = [...new Set(actions.map((a) => String(a.action_slug)))];
|
|
233
|
+
let schemas = {};
|
|
234
|
+
try {
|
|
235
|
+
const out = await callConnectionsTool(ctx, 'FACILIO_GET_ACTION_SCHEMAS', {
|
|
236
|
+
action_slugs: slugs,
|
|
237
|
+
include: ['input_schema'],
|
|
238
|
+
...sessionArg(),
|
|
239
|
+
});
|
|
240
|
+
schemas = out.action_schemas ?? {};
|
|
241
|
+
}
|
|
242
|
+
catch (err) {
|
|
243
|
+
logger.warn(`Could not fetch schemas for validation (${err instanceof Error ? err.message : String(err)}). Previewing without validation.`);
|
|
244
|
+
}
|
|
245
|
+
const report = actions.map((a) => {
|
|
246
|
+
const slug = String(a.action_slug);
|
|
247
|
+
const args = (a.arguments ?? {});
|
|
248
|
+
return {
|
|
249
|
+
action_slug: slug,
|
|
250
|
+
account_slug: a.account_slug,
|
|
251
|
+
arguments: args,
|
|
252
|
+
missing_required: requiredMissing(schemas[slug]?.input_schema, args),
|
|
253
|
+
};
|
|
254
|
+
});
|
|
255
|
+
if (ctx.json) {
|
|
256
|
+
printJson({ dry_run: true, actions: report });
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
logger.info('Dry run — no actions executed.');
|
|
260
|
+
for (const r of report) {
|
|
261
|
+
logger.step(`${r.action_slug}${r.account_slug ? ` (account: ${r.account_slug})` : ''}`);
|
|
262
|
+
console.log(JSON.stringify(r.arguments, null, 2));
|
|
263
|
+
if (r.missing_required.length) {
|
|
264
|
+
logger.error(` missing required: ${r.missing_required.join(', ')}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (report.some((r) => r.missing_required.length))
|
|
269
|
+
process.exitCode = 1;
|
|
270
|
+
}
|
|
271
|
+
export async function executeCommand(actionSlugs, opts, ctx) {
|
|
272
|
+
// --get-schema: inspect input schema(s) without executing anything.
|
|
273
|
+
if (opts.getSchema) {
|
|
274
|
+
if (!actionSlugs.length) {
|
|
275
|
+
throw new Error('Pass at least one action slug with --get-schema.');
|
|
276
|
+
}
|
|
277
|
+
return schemasCommand(actionSlugs, false, ctx);
|
|
278
|
+
}
|
|
279
|
+
let actions;
|
|
280
|
+
if (opts.file) {
|
|
281
|
+
if (actionSlugs.length) {
|
|
282
|
+
throw new Error('Pass either action slug(s) or --file for a batch, not both.');
|
|
283
|
+
}
|
|
284
|
+
// Batch mode: a JSON array of {action_slug, arguments, account_slug?}.
|
|
285
|
+
const raw = await fs.readFile(opts.file, 'utf8');
|
|
286
|
+
const parsed = JSON.parse(raw);
|
|
287
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
288
|
+
throw new Error(`${opts.file} must contain a non-empty JSON array of {action_slug, arguments} rows.`);
|
|
289
|
+
}
|
|
290
|
+
actions = parsed;
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
let rawParams = opts.params ?? [];
|
|
294
|
+
// Single-action stdin support: `--params -`.
|
|
295
|
+
if (rawParams.length === 1 && rawParams[0].trim() === '-') {
|
|
296
|
+
if (actionSlugs.length > 1) {
|
|
297
|
+
throw new Error('`--params -` (stdin) is only valid with a single action slug.');
|
|
298
|
+
}
|
|
299
|
+
rawParams = [await readStdin()];
|
|
300
|
+
}
|
|
301
|
+
actions = buildInlineActions(actionSlugs, rawParams, opts.account);
|
|
302
|
+
}
|
|
303
|
+
// --dry-run: validate + preview, do not execute.
|
|
304
|
+
if (opts.dryRun)
|
|
305
|
+
return dryRunPreview(actions, ctx);
|
|
306
|
+
const out = await callConnectionsTool(ctx, 'FACILIO_MULTI_EXECUTE_ACTION', {
|
|
307
|
+
actions,
|
|
308
|
+
...sessionArg(),
|
|
309
|
+
});
|
|
310
|
+
if (ctx.json)
|
|
311
|
+
return printJson(out);
|
|
312
|
+
for (const r of out.results ?? []) {
|
|
313
|
+
if (r.ok) {
|
|
314
|
+
logger.success(`${r.action_slug}: ok`);
|
|
315
|
+
if (r.result !== undefined)
|
|
316
|
+
console.log(JSON.stringify(r.result, null, 2));
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
logger.error(`${r.action_slug}: ${JSON.stringify(r.error ?? 'failed')}`);
|
|
320
|
+
process.exitCode = 1;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../src/products/connections/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { wrap } from '../../core/wrap.js';
|
|
2
|
+
import { cmdCtx, searchCommand, schemasCommand, listCommand, linkCommand, unlinkCommand, waitCommand, executeCommand, } from './commands.js';
|
|
3
|
+
/**
|
|
4
|
+
* `facilio connections …` — discover and run actions across 1000+ connected
|
|
5
|
+
* apps (Xero, Salesforce, …) via the Facilio Connections MCP server, using
|
|
6
|
+
* the universal `facilio login` session as a direct bearer.
|
|
7
|
+
*/
|
|
8
|
+
export const connectionsProduct = {
|
|
9
|
+
name: 'connections',
|
|
10
|
+
description: 'Search, connect, and execute actions across 1000+ integrated apps',
|
|
11
|
+
register(parent, ctx) {
|
|
12
|
+
const conn = parent
|
|
13
|
+
.command('connections')
|
|
14
|
+
.description(this.description)
|
|
15
|
+
.option('--mcp-url <url>', 'Override the Connections MCP endpoint (default: FACILIO_MCP_URL)')
|
|
16
|
+
.option('--app <slug>', 'Scope every call to one connection (uses the /<slug>/mcp endpoint)')
|
|
17
|
+
.option('--json', 'Print raw JSON payloads (for scripts and agents)');
|
|
18
|
+
const globals = (cmd) => cmdCtx(cmd.optsWithGlobals(), ctx.version);
|
|
19
|
+
conn
|
|
20
|
+
.command('search <query...>')
|
|
21
|
+
.description('Find actions by use case, e.g. `facilio connections search create xero invoice`')
|
|
22
|
+
.action(wrap(async (query, _opts, cmd) => searchCommand(query, globals(cmd))));
|
|
23
|
+
conn
|
|
24
|
+
.command('schemas <action_slugs...>')
|
|
25
|
+
.description('Show the input (and optionally output) JSON Schemas for actions')
|
|
26
|
+
.option('--with-output', 'Also fetch output schemas')
|
|
27
|
+
.action(wrap(async (slugs, opts, cmd) => schemasCommand(slugs, !!opts.withOutput, globals(cmd))));
|
|
28
|
+
conn
|
|
29
|
+
.command('list <connections...>')
|
|
30
|
+
.alias('ls')
|
|
31
|
+
.description("Show your connected accounts for one or more connections (e.g. 'xero salesforce')")
|
|
32
|
+
.action(wrap(async (names, _opts, cmd) => listCommand(names, globals(cmd))));
|
|
33
|
+
conn
|
|
34
|
+
.command('link <connection>')
|
|
35
|
+
.description('Authorize a connection — prints (and opens) the OAuth URL for the target app')
|
|
36
|
+
.option('--no-open', "Don't auto-open the browser")
|
|
37
|
+
.option('--wait', 'Block until the connection becomes ACTIVE')
|
|
38
|
+
.option('--timeout <seconds>', 'Wait timeout (with --wait)')
|
|
39
|
+
.action(wrap(async (name, opts, cmd) => linkCommand(name, opts, globals(cmd))));
|
|
40
|
+
conn
|
|
41
|
+
.command('unlink <connection>')
|
|
42
|
+
.description("Remove your authorization for a connection")
|
|
43
|
+
.option('-y, --yes', 'Skip the confirmation prompt')
|
|
44
|
+
.action(wrap(async (name, opts, cmd) => unlinkCommand(name, opts, globals(cmd))));
|
|
45
|
+
conn
|
|
46
|
+
.command('wait <connections...>')
|
|
47
|
+
.description('Poll until connection(s) become ACTIVE after browser authorization')
|
|
48
|
+
.option('--mode <mode>', "'any' (default) or 'all'")
|
|
49
|
+
.option('--timeout <seconds>', 'Give up after this many seconds')
|
|
50
|
+
.action(wrap(async (names, opts, cmd) => waitCommand(names, opts, globals(cmd))));
|
|
51
|
+
conn
|
|
52
|
+
.command('execute [action_slugs...]')
|
|
53
|
+
.alias('exec')
|
|
54
|
+
.description('Run one or more actions, e.g. `facilio connections execute xero.create_invoice --params \'{"amount":100}\'`')
|
|
55
|
+
.option('--params <json>', "Action arguments as a JSON object; use '-' to read from stdin. Repeat once per slug to run several actions in parallel.", (value, prev) => prev.concat([value]), [])
|
|
56
|
+
.option('--account <slug>', 'Target a specific connected account (from `connections list`)')
|
|
57
|
+
.option('--file <path>', 'Batch mode: JSON array of {action_slug, arguments, account_slug?}')
|
|
58
|
+
.option('--dry-run', 'Validate arguments against the action schema and print the request without executing')
|
|
59
|
+
.option('--get-schema', 'Print the input schema(s) for the given action slug(s) and exit')
|
|
60
|
+
.action(wrap(async (slugs, opts, cmd) => executeCommand(slugs, opts, globals(cmd))));
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/products/connections/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow-session persistence for the connections meta-tools. The server's
|
|
3
|
+
* FACILIO_SEARCH_ACTIONS mints a `session_id` that must be threaded through
|
|
4
|
+
* every subsequent meta-tool call; since each CLI invocation is a fresh
|
|
5
|
+
* process, the id lives in ~/.facilio/connections-state.json between runs.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { stateDir } from '../../core/secretStore.js';
|
|
10
|
+
/** Don't resume sessions older than this — stale ids only pollute server logs. */
|
|
11
|
+
const SESSION_TTL_MS = 24 * 60 * 60 * 1000;
|
|
12
|
+
function stateFile() {
|
|
13
|
+
return path.join(stateDir(), 'connections-state.json');
|
|
14
|
+
}
|
|
15
|
+
export function loadSessionId() {
|
|
16
|
+
try {
|
|
17
|
+
const file = stateFile();
|
|
18
|
+
if (!existsSync(file))
|
|
19
|
+
return undefined;
|
|
20
|
+
const state = JSON.parse(readFileSync(file, 'utf8'));
|
|
21
|
+
if (!state.sessionId)
|
|
22
|
+
return undefined;
|
|
23
|
+
if (state.savedAt && Date.now() - state.savedAt > SESSION_TTL_MS)
|
|
24
|
+
return undefined;
|
|
25
|
+
return state.sessionId;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function saveSessionId(sessionId) {
|
|
32
|
+
const state = { sessionId, savedAt: Date.now() };
|
|
33
|
+
writeFileSync(stateFile(), JSON.stringify(state) + '\n', { mode: 0o600 });
|
|
34
|
+
}
|
|
35
|
+
export function clearSessionId() {
|
|
36
|
+
try {
|
|
37
|
+
if (existsSync(stateFile()))
|
|
38
|
+
unlinkSync(stateFile());
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
/* best effort */
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/products/connections/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,kFAAkF;AAClF,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAO3C,SAAS,SAAS;IAChB,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,wBAAwB,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAqB,CAAC;QACzE,IAAI,CAAC,KAAK,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QACvC,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,cAAc;YAAE,OAAO,SAAS,CAAC;QACnF,OAAO,KAAK,CAAC,SAAS,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,MAAM,KAAK,GAAqB,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACnE,aAAa,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;YAAE,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/products/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { logger } from '../../core/logger.js';
|
|
4
|
+
import { loadCredentials } from '../../core/credentials.js';
|
|
5
|
+
import { apiFromCredentials, ApiError } from '../../core/api.js';
|
|
6
|
+
import { loadConfig, writeConfig } from './config.js';
|
|
7
|
+
import { prompt } from '../../core/prompt.js';
|
|
8
|
+
/** `facilio vibe app create` — interactive (prompts) unless all flags are provided. */
|
|
9
|
+
export async function appCreateCommand(opts) {
|
|
10
|
+
const creds = await loadCredentials();
|
|
11
|
+
if (!creds)
|
|
12
|
+
throw new Error('Not logged in. Run `facilio login` first.');
|
|
13
|
+
// 1. Gather inputs (prompt for anything not provided via flags)
|
|
14
|
+
const name = opts.name ?? (await prompt('Name'));
|
|
15
|
+
const description = opts.description ?? (await prompt('Description', { optional: true }));
|
|
16
|
+
const logoUrl = opts.logo ?? (await prompt('Logo URL', { optional: true }));
|
|
17
|
+
const outputDir = (await prompt('Output directory (folder containing your built static files)', {
|
|
18
|
+
default: 'dist',
|
|
19
|
+
}));
|
|
20
|
+
// 2. Send
|
|
21
|
+
const api = await apiFromCredentials(creds);
|
|
22
|
+
const payload = { name };
|
|
23
|
+
if (description)
|
|
24
|
+
payload.description = description;
|
|
25
|
+
if (logoUrl)
|
|
26
|
+
payload.logoUrl = logoUrl;
|
|
27
|
+
let app;
|
|
28
|
+
try {
|
|
29
|
+
app = await api.postJson('/api/cli/apps', payload);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
if (err instanceof ApiError && err.statusCode === 409) {
|
|
33
|
+
const body = err.body;
|
|
34
|
+
const existing = body?.app;
|
|
35
|
+
throw new Error(`An app with linkName "${existing?.linkName ?? '(derived from name)'}" already exists.` +
|
|
36
|
+
(existing ? ` URL: ${existing.url}` : ''));
|
|
37
|
+
}
|
|
38
|
+
throw err;
|
|
39
|
+
}
|
|
40
|
+
logger.success(`Created app "${app.name}"`);
|
|
41
|
+
logger.step(`linkName: ${app.linkName}`);
|
|
42
|
+
logger.step(`URL: ${app.url}`);
|
|
43
|
+
if (app.logoUrl)
|
|
44
|
+
logger.step(`Logo: ${app.logoUrl}`);
|
|
45
|
+
// 4. Write/patch local vibe.json so subsequent `facilio vibe deploy` targets this app
|
|
46
|
+
const configPath = path.join(process.cwd(), 'vibe.json');
|
|
47
|
+
const exists = await fs
|
|
48
|
+
.access(configPath)
|
|
49
|
+
.then(() => true)
|
|
50
|
+
.catch(() => false);
|
|
51
|
+
if (exists) {
|
|
52
|
+
const config = await loadConfig();
|
|
53
|
+
await writeConfig({
|
|
54
|
+
...config,
|
|
55
|
+
app: app.linkName,
|
|
56
|
+
name: config.name ?? app.name,
|
|
57
|
+
build: { publish: outputDir },
|
|
58
|
+
});
|
|
59
|
+
logger.step(`Updated vibe.json with "app": "${app.linkName}", "build.publish": "${outputDir}"`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
await writeConfig({
|
|
63
|
+
name: app.name,
|
|
64
|
+
app: app.linkName,
|
|
65
|
+
build: { publish: outputDir },
|
|
66
|
+
});
|
|
67
|
+
logger.step(`Created vibe.json with "app": "${app.linkName}", "build.publish": "${outputDir}"`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** `facilio vibe app list` */
|
|
71
|
+
export async function appListCommand() {
|
|
72
|
+
const creds = await loadCredentials();
|
|
73
|
+
if (!creds)
|
|
74
|
+
throw new Error('Not logged in. Run `facilio login` first.');
|
|
75
|
+
const api = await apiFromCredentials(creds);
|
|
76
|
+
const resp = await api.getJson('/api/cli/apps');
|
|
77
|
+
const apps = resp.apps ?? [];
|
|
78
|
+
if (apps.length === 0) {
|
|
79
|
+
logger.info('No apps yet. Create one with `facilio vibe app create`.');
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const rows = apps.map((a) => ({
|
|
83
|
+
linkName: a.linkName,
|
|
84
|
+
name: a.name,
|
|
85
|
+
url: a.url,
|
|
86
|
+
status: a.status,
|
|
87
|
+
published: a.publishedAt ? new Date(a.publishedAt).toISOString().slice(0, 19).replace('T', ' ') : '—',
|
|
88
|
+
}));
|
|
89
|
+
const cols = ['linkName', 'name', 'url', 'status', 'published'];
|
|
90
|
+
const widths = cols.map((c) => Math.max(c.length, ...rows.map((r) => String(r[c]).length)));
|
|
91
|
+
const fmt = (vals) => vals.map((v, i) => v.padEnd(widths[i])).join(' ');
|
|
92
|
+
console.log(fmt(cols.map((c) => String(c).toUpperCase())));
|
|
93
|
+
console.log(fmt(widths.map((w) => '-'.repeat(w))));
|
|
94
|
+
for (const r of rows)
|
|
95
|
+
console.log(fmt(cols.map((c) => String(r[c]))));
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/products/vibe/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
/**
|
|
5
|
+
* Project-level config that lives next to the user's source tree (vibe.json).
|
|
6
|
+
*
|
|
7
|
+
* Fields:
|
|
8
|
+
* - app: the app linkName (subdomain) — populated by `facilio vibe app create`.
|
|
9
|
+
* Backward compat: if absent, falls back to `siteId`.
|
|
10
|
+
* - name: human-readable name shown in `facilio vibe app list`.
|
|
11
|
+
* - build.publish: folder containing the built static files to deploy.
|
|
12
|
+
* The user builds their app however they want; this just
|
|
13
|
+
* points at the resulting folder.
|
|
14
|
+
*/
|
|
15
|
+
const VibeConfigSchema = z.object({
|
|
16
|
+
name: z.string().min(1).optional(),
|
|
17
|
+
app: z.string().optional(),
|
|
18
|
+
siteId: z.string().optional(), // legacy alias for `app`
|
|
19
|
+
build: z
|
|
20
|
+
.object({
|
|
21
|
+
publish: z.string().default('dist'),
|
|
22
|
+
})
|
|
23
|
+
.default({ publish: 'dist' }),
|
|
24
|
+
server: z
|
|
25
|
+
.object({
|
|
26
|
+
url: z.string().url().optional(),
|
|
27
|
+
})
|
|
28
|
+
.optional(),
|
|
29
|
+
});
|
|
30
|
+
const FILENAME = 'vibe.json';
|
|
31
|
+
export async function loadConfig(cwd = process.cwd()) {
|
|
32
|
+
const file = path.join(cwd, FILENAME);
|
|
33
|
+
let raw;
|
|
34
|
+
try {
|
|
35
|
+
raw = await fs.readFile(file, 'utf8');
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err.code === 'ENOENT') {
|
|
39
|
+
throw new Error(`No ${FILENAME} found in ${cwd}. Run \`facilio vibe app create <name>\` to create one.`);
|
|
40
|
+
}
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
const parsed = VibeConfigSchema.safeParse(JSON.parse(raw));
|
|
44
|
+
if (!parsed.success) {
|
|
45
|
+
throw new Error(`Invalid ${FILENAME}: ${parsed.error.message}`);
|
|
46
|
+
}
|
|
47
|
+
return parsed.data;
|
|
48
|
+
}
|
|
49
|
+
export async function writeConfig(config, cwd = process.cwd()) {
|
|
50
|
+
const file = path.join(cwd, FILENAME);
|
|
51
|
+
await fs.writeFile(file, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
52
|
+
}
|
|
53
|
+
/** Resolve the effective app linkName, supporting the legacy `siteId` field. */
|
|
54
|
+
export function resolveAppLinkName(config) {
|
|
55
|
+
return config.app ?? config.siteId;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/products/vibe/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;GAUG;AACH,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,yBAAyB;IACxD,KAAK,EAAE,CAAC;SACL,MAAM,CAAC;QACN,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC;SACD,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC/B,MAAM,EAAE,CAAC;SACN,MAAM,CAAC;QACN,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;KACjC,CAAC;SACD,QAAQ,EAAE;CACd,CAAC,CAAC;AAIH,MAAM,QAAQ,GAAG,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACtC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,MAAM,QAAQ,aAAa,GAAG,yDAAyD,CAAC,CAAC;QAC3G,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,WAAW,QAAQ,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAkB,EAAE,MAAc,OAAO,CAAC,GAAG,EAAE;IAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACtC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3E,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,kBAAkB,CAAC,MAAkB;IACnD,OAAO,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC;AACrC,CAAC"}
|