@f-o-h/cli 0.1.2 → 0.1.4
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 +5 -4
- package/dist/foh.js +183 -51
- package/package.json +39 -39
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ AI-operator provisioning CLI for Front Of House.
|
|
|
4
4
|
|
|
5
5
|
Public mirror: https://github.com/iiko38/front-of-house-cli
|
|
6
6
|
|
|
7
|
-
Current published baseline: `@f-o-h/cli@0.1.
|
|
7
|
+
Current published baseline: `@f-o-h/cli@0.1.4`
|
|
8
8
|
|
|
9
9
|
This mirror is a generated release artifact. The private product monorepo is not
|
|
10
10
|
published here, and no open-source license is granted unless stated separately.
|
|
@@ -51,8 +51,9 @@ foh setup --org <org-id> --agent-template <template-id> --agent-name "Demo Agent
|
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
`auth signup --web` opens the console signup page when possible and always
|
|
54
|
-
prints the fallback URL. `auth login --web`
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
prints the fallback URL. `auth login --web` starts browser device
|
|
55
|
+
authorization, opens `/cli-auth`, waits for console approval, and stores the
|
|
56
|
+
returned short-lived token. Credential auth remains available as fallback.
|
|
57
57
|
|
|
58
58
|
The CLI defaults to the production API at `https://api.frontofhouse.okii.uk`.
|
|
59
|
+
|
package/dist/foh.js
CHANGED
|
@@ -10163,11 +10163,11 @@ function buildCliAuthFallbackInstructions(signInUrl) {
|
|
|
10163
10163
|
human: [
|
|
10164
10164
|
`Open ${signInUrl}`,
|
|
10165
10165
|
"Sign in to Front Of House.",
|
|
10166
|
-
"Return to the terminal
|
|
10166
|
+
"Return to the terminal. If device approval is unavailable, authenticate the CLI with email/password."
|
|
10167
10167
|
],
|
|
10168
10168
|
ai_agent: [
|
|
10169
10169
|
"Show the sign_in_url to the user if browser opening is unavailable.",
|
|
10170
|
-
"
|
|
10170
|
+
"Prefer browser device approval. Ask for email/password only if device approval is unavailable.",
|
|
10171
10171
|
"Run the explicit CLI auth commands in next_commands.",
|
|
10172
10172
|
"Never scrape browser cookies or local storage."
|
|
10173
10173
|
]
|
|
@@ -10179,7 +10179,7 @@ function buildCliSignupFallbackInstructions(signUpUrl) {
|
|
|
10179
10179
|
`Open ${signUpUrl}`,
|
|
10180
10180
|
"Create a Front Of House account.",
|
|
10181
10181
|
"Confirm your email if prompted.",
|
|
10182
|
-
"Return to the terminal and run `foh auth login --web --json
|
|
10182
|
+
"Return to the terminal and run `foh auth login --web --json`."
|
|
10183
10183
|
],
|
|
10184
10184
|
ai_agent: [
|
|
10185
10185
|
"Show the sign_up_url to the user if browser opening is unavailable.",
|
|
@@ -10192,10 +10192,20 @@ function buildCliSignupFallbackInstructions(signUpUrl) {
|
|
|
10192
10192
|
|
|
10193
10193
|
// src/lib/open-url.ts
|
|
10194
10194
|
var import_child_process = require("child_process");
|
|
10195
|
+
function buildOpenUrlCommand(url2, platform = process.platform) {
|
|
10196
|
+
if (platform === "win32") {
|
|
10197
|
+
return {
|
|
10198
|
+
command: "rundll32.exe",
|
|
10199
|
+
args: ["url.dll,FileProtocolHandler", url2]
|
|
10200
|
+
};
|
|
10201
|
+
}
|
|
10202
|
+
if (platform === "darwin") {
|
|
10203
|
+
return { command: "open", args: [url2] };
|
|
10204
|
+
}
|
|
10205
|
+
return { command: "xdg-open", args: [url2] };
|
|
10206
|
+
}
|
|
10195
10207
|
function openUrl(url2) {
|
|
10196
|
-
const
|
|
10197
|
-
const command = platform === "win32" ? "cmd" : platform === "darwin" ? "open" : "xdg-open";
|
|
10198
|
-
const args = platform === "win32" ? ["/c", "start", "", url2] : [url2];
|
|
10208
|
+
const { command, args } = buildOpenUrlCommand(url2);
|
|
10199
10209
|
try {
|
|
10200
10210
|
const child = (0, import_child_process.spawn)(command, args, {
|
|
10201
10211
|
detached: true,
|
|
@@ -10227,11 +10237,22 @@ function emitBrowserAuthLink(opts) {
|
|
|
10227
10237
|
opener_command: openResult.command,
|
|
10228
10238
|
opener_error: openResult.error ?? null,
|
|
10229
10239
|
cli_auth_required: true,
|
|
10230
|
-
note: "Browser
|
|
10240
|
+
note: "Browser device auth is unavailable from this API. Authenticate this CLI with the explicit credential command after sign-in.",
|
|
10231
10241
|
next_commands: nextCommands,
|
|
10232
10242
|
text_fallback: buildCliAuthFallbackInstructions(signInUrl)
|
|
10233
10243
|
}, { json: opts.json ?? false });
|
|
10234
10244
|
}
|
|
10245
|
+
function writeDeviceProgress(event, jsonMode) {
|
|
10246
|
+
const line = jsonMode ? JSON.stringify({ event: "device_auth_started", ...event }, null, 2) : [
|
|
10247
|
+
"Browser auth started.",
|
|
10248
|
+
`Open: ${event["verification_uri_complete"]}`,
|
|
10249
|
+
`Code: ${event["user_code"]}`,
|
|
10250
|
+
"Waiting for browser approval..."
|
|
10251
|
+
].join("\n");
|
|
10252
|
+
const stream = jsonMode ? process.stderr : process.stdout;
|
|
10253
|
+
stream.write(`${line}
|
|
10254
|
+
`);
|
|
10255
|
+
}
|
|
10235
10256
|
function emitBrowserSignupLink(opts) {
|
|
10236
10257
|
const consoleUrl = resolveConsoleBaseUrl(opts.consoleUrl);
|
|
10237
10258
|
const signUpUrl = buildConsoleSignUpUrl(consoleUrl);
|
|
@@ -10307,13 +10328,154 @@ async function maybeSelectDefaultOrg(orgs, jsonMode) {
|
|
|
10307
10328
|
`);
|
|
10308
10329
|
}
|
|
10309
10330
|
}
|
|
10331
|
+
async function fetchOrgMemberships(apiUrl, token) {
|
|
10332
|
+
try {
|
|
10333
|
+
const orgsRes = await fetch(`${apiUrl}/v1/console/auth/my-orgs`, {
|
|
10334
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
10335
|
+
});
|
|
10336
|
+
if (orgsRes.ok) {
|
|
10337
|
+
const orgsData = await orgsRes.json();
|
|
10338
|
+
return {
|
|
10339
|
+
orgs: Array.isArray(orgsData.orgs) ? orgsData.orgs : [],
|
|
10340
|
+
available: true
|
|
10341
|
+
};
|
|
10342
|
+
}
|
|
10343
|
+
} catch {
|
|
10344
|
+
}
|
|
10345
|
+
return { orgs: [], available: false };
|
|
10346
|
+
}
|
|
10347
|
+
async function storeAuthenticatedSession(params) {
|
|
10348
|
+
const { orgs, available } = await fetchOrgMemberships(params.apiUrl, params.token);
|
|
10349
|
+
let autoOrgId;
|
|
10350
|
+
const usableOrgs = orgs.filter((org) => isUsableOrgId(org.org_id));
|
|
10351
|
+
if (usableOrgs.length === 1) {
|
|
10352
|
+
autoOrgId = usableOrgs[0].org_id;
|
|
10353
|
+
} else if (usableOrgs.length > 1) {
|
|
10354
|
+
autoOrgId = await maybeSelectDefaultOrg(orgs, params.jsonMode);
|
|
10355
|
+
}
|
|
10356
|
+
saveCredentials({
|
|
10357
|
+
apiUrl: params.apiUrl,
|
|
10358
|
+
token: params.token,
|
|
10359
|
+
expiresAt: params.expiresAt,
|
|
10360
|
+
orgId: autoOrgId
|
|
10361
|
+
});
|
|
10362
|
+
const output = {
|
|
10363
|
+
status: "authenticated",
|
|
10364
|
+
apiUrl: params.apiUrl,
|
|
10365
|
+
expires_at: params.expiresAt
|
|
10366
|
+
};
|
|
10367
|
+
if (autoOrgId) {
|
|
10368
|
+
output["default_org_id"] = autoOrgId;
|
|
10369
|
+
output["note"] = "Default org stored; --org flag is now optional.";
|
|
10370
|
+
} else if (orgs.length > 1) {
|
|
10371
|
+
output["note"] = `${orgs.length} orgs found. Run: foh org use --org <id> to set a default.`;
|
|
10372
|
+
} else if (orgs.length === 0 && available) {
|
|
10373
|
+
output["note"] = "No orgs found. Run: foh org create --name <name> to create one.";
|
|
10374
|
+
} else {
|
|
10375
|
+
output["note"] = "Authenticated, but org discovery is unavailable. Run: foh org list when API connectivity is healthy.";
|
|
10376
|
+
}
|
|
10377
|
+
return output;
|
|
10378
|
+
}
|
|
10379
|
+
function sleep(ms) {
|
|
10380
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
10381
|
+
}
|
|
10382
|
+
async function runDeviceLogin(opts) {
|
|
10383
|
+
const jsonMode = Boolean(opts.json);
|
|
10384
|
+
let startRes;
|
|
10385
|
+
try {
|
|
10386
|
+
startRes = await fetch(`${opts.apiUrl}/v1/console/auth/device/start`, {
|
|
10387
|
+
method: "POST",
|
|
10388
|
+
headers: { "Content-Type": "application/json" },
|
|
10389
|
+
body: JSON.stringify({ client: "foh-cli" })
|
|
10390
|
+
});
|
|
10391
|
+
} catch {
|
|
10392
|
+
emitBrowserAuthLink({
|
|
10393
|
+
consoleUrl: opts.consoleUrl,
|
|
10394
|
+
json: opts.json
|
|
10395
|
+
});
|
|
10396
|
+
return;
|
|
10397
|
+
}
|
|
10398
|
+
if (!startRes.ok) {
|
|
10399
|
+
emitBrowserAuthLink({
|
|
10400
|
+
consoleUrl: opts.consoleUrl,
|
|
10401
|
+
json: opts.json
|
|
10402
|
+
});
|
|
10403
|
+
return;
|
|
10404
|
+
}
|
|
10405
|
+
const start = await startRes.json();
|
|
10406
|
+
const openResult = openUrl(start.verification_uri_complete);
|
|
10407
|
+
const startedPacket = {
|
|
10408
|
+
status: "browser_device_auth_started",
|
|
10409
|
+
sign_in_url: start.verification_uri_complete,
|
|
10410
|
+
verification_uri: start.verification_uri,
|
|
10411
|
+
verification_uri_complete: start.verification_uri_complete,
|
|
10412
|
+
user_code: start.user_code,
|
|
10413
|
+
opened: openResult.attempted,
|
|
10414
|
+
opener_command: openResult.command,
|
|
10415
|
+
opener_error: openResult.error ?? null,
|
|
10416
|
+
expires_in: start.expires_in,
|
|
10417
|
+
poll_interval_seconds: start.interval
|
|
10418
|
+
};
|
|
10419
|
+
if (opts.wait === false) {
|
|
10420
|
+
format({
|
|
10421
|
+
...startedPacket,
|
|
10422
|
+
next_commands: [
|
|
10423
|
+
"Complete approval in the opened browser window.",
|
|
10424
|
+
"Then rerun: foh auth login --web --json"
|
|
10425
|
+
]
|
|
10426
|
+
}, { json: jsonMode });
|
|
10427
|
+
return;
|
|
10428
|
+
}
|
|
10429
|
+
writeDeviceProgress(startedPacket, jsonMode);
|
|
10430
|
+
const timeoutSeconds = Math.max(1, Number(opts.timeoutSeconds ?? start.expires_in) || start.expires_in);
|
|
10431
|
+
const deadline = Date.now() + Math.min(timeoutSeconds, start.expires_in) * 1e3;
|
|
10432
|
+
const intervalMs = Math.max(0.05, Number(start.interval) || 2) * 1e3;
|
|
10433
|
+
while (Date.now() < deadline) {
|
|
10434
|
+
await sleep(intervalMs);
|
|
10435
|
+
const pollRes = await fetch(`${opts.apiUrl}/v1/console/auth/device/poll`, {
|
|
10436
|
+
method: "POST",
|
|
10437
|
+
headers: { "Content-Type": "application/json" },
|
|
10438
|
+
body: JSON.stringify({ device_code: start.device_code })
|
|
10439
|
+
});
|
|
10440
|
+
const poll = await pollRes.json().catch(() => ({}));
|
|
10441
|
+
if (pollRes.status === 202 || poll.status === "authorization_pending") {
|
|
10442
|
+
continue;
|
|
10443
|
+
}
|
|
10444
|
+
if (pollRes.ok && poll.token && poll.expires_at) {
|
|
10445
|
+
const output = await storeAuthenticatedSession({
|
|
10446
|
+
apiUrl: opts.apiUrl,
|
|
10447
|
+
token: poll.token,
|
|
10448
|
+
expiresAt: poll.expires_at,
|
|
10449
|
+
jsonMode
|
|
10450
|
+
});
|
|
10451
|
+
format({
|
|
10452
|
+
...output,
|
|
10453
|
+
auth_method: "browser_device"
|
|
10454
|
+
}, { json: jsonMode });
|
|
10455
|
+
return;
|
|
10456
|
+
}
|
|
10457
|
+
throw new FohError({
|
|
10458
|
+
step: "auth.login.web",
|
|
10459
|
+
error: poll.error || poll.code || `HTTP ${pollRes.status}`,
|
|
10460
|
+
remediation: "Restart browser auth with: foh auth login --web"
|
|
10461
|
+
});
|
|
10462
|
+
}
|
|
10463
|
+
throw new FohError({
|
|
10464
|
+
step: "auth.login.web",
|
|
10465
|
+
error: "Timed out waiting for browser approval",
|
|
10466
|
+
remediation: "Complete browser approval faster, or rerun: foh auth login --web"
|
|
10467
|
+
});
|
|
10468
|
+
}
|
|
10310
10469
|
function registerAuth(program3) {
|
|
10311
10470
|
const auth = program3.command("auth").description("Manage CLI authentication");
|
|
10312
|
-
auth.command("login").description("Authenticate with the FOH API and store a token locally").option("--email <email>", "FOH account email").option("--password <password>", "FOH account password").option("--web", "Open browser sign-in and print text fallback commands").option("--browser", "Alias for --web").option("--wizard", "Run guided login wizard prompts").option("--console-url <url>", "Console sign-in URL override").option("--api-url <url>", "Internal API base URL override (operators only)").option("--json", "Output as JSON").action(async (opts) => withCommandErrorHandling(async () => {
|
|
10471
|
+
auth.command("login").description("Authenticate with the FOH API and store a token locally").option("--email <email>", "FOH account email").option("--password <password>", "FOH account password").option("--web", "Open browser sign-in and print text fallback commands").option("--browser", "Alias for --web").option("--wizard", "Run guided login wizard prompts").option("--console-url <url>", "Console sign-in URL override").option("--api-url <url>", "Internal API base URL override (operators only)").option("--timeout-seconds <seconds>", "Maximum seconds to wait for browser approval").option("--no-wait", "Only print/open the browser approval link; do not poll").option("--json", "Output as JSON").action(async (opts) => withCommandErrorHandling(async () => {
|
|
10313
10472
|
if ((opts.web || opts.browser) && !opts.email && !opts.password) {
|
|
10314
|
-
|
|
10473
|
+
await runDeviceLogin({
|
|
10474
|
+
apiUrl: resolveApiBaseUrl(opts.apiUrl),
|
|
10315
10475
|
consoleUrl: opts.consoleUrl,
|
|
10316
|
-
json: opts.json
|
|
10476
|
+
json: opts.json,
|
|
10477
|
+
wait: opts.wait,
|
|
10478
|
+
timeoutSeconds: opts.timeoutSeconds
|
|
10317
10479
|
});
|
|
10318
10480
|
return;
|
|
10319
10481
|
}
|
|
@@ -10347,42 +10509,12 @@ function registerAuth(program3) {
|
|
|
10347
10509
|
});
|
|
10348
10510
|
}
|
|
10349
10511
|
const data = await res.json();
|
|
10350
|
-
|
|
10351
|
-
let orgDiscoveryAvailable = false;
|
|
10352
|
-
try {
|
|
10353
|
-
const orgsRes = await fetch(`${apiUrl}/v1/console/auth/my-orgs`, {
|
|
10354
|
-
headers: { Authorization: `Bearer ${data.token}` }
|
|
10355
|
-
});
|
|
10356
|
-
if (orgsRes.ok) {
|
|
10357
|
-
const orgsData = await orgsRes.json();
|
|
10358
|
-
orgs = Array.isArray(orgsData.orgs) ? orgsData.orgs : [];
|
|
10359
|
-
orgDiscoveryAvailable = true;
|
|
10360
|
-
}
|
|
10361
|
-
} catch {
|
|
10362
|
-
}
|
|
10363
|
-
let autoOrgId;
|
|
10364
|
-
const usableOrgs = orgs.filter((org) => isUsableOrgId(org.org_id));
|
|
10365
|
-
if (usableOrgs.length === 1) {
|
|
10366
|
-
autoOrgId = usableOrgs[0].org_id;
|
|
10367
|
-
} else if (usableOrgs.length > 1) {
|
|
10368
|
-
autoOrgId = await maybeSelectDefaultOrg(orgs, Boolean(opts.json));
|
|
10369
|
-
}
|
|
10370
|
-
saveCredentials({ apiUrl, token: data.token, expiresAt: data.expires_at, orgId: autoOrgId });
|
|
10371
|
-
const output = {
|
|
10372
|
-
status: "authenticated",
|
|
10512
|
+
const output = await storeAuthenticatedSession({
|
|
10373
10513
|
apiUrl,
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
output["note"] = "Default org stored; --org flag is now optional.";
|
|
10379
|
-
} else if (orgs.length > 1) {
|
|
10380
|
-
output["note"] = `${orgs.length} orgs found. Run: foh org use --org <id> to set a default.`;
|
|
10381
|
-
} else if (orgs.length === 0 && orgDiscoveryAvailable) {
|
|
10382
|
-
output["note"] = "No orgs found. Run: foh org create --name <name> to create one.";
|
|
10383
|
-
} else {
|
|
10384
|
-
output["note"] = "Authenticated, but org discovery is unavailable. Run: foh org list when API connectivity is healthy.";
|
|
10385
|
-
}
|
|
10514
|
+
token: data.token,
|
|
10515
|
+
expiresAt: data.expires_at,
|
|
10516
|
+
jsonMode: Boolean(opts.json)
|
|
10517
|
+
});
|
|
10386
10518
|
format(output, { json: opts.json ?? false });
|
|
10387
10519
|
}));
|
|
10388
10520
|
auth.command("signup").description("Open account signup and print text fallback commands").option("--web", "Open browser signup and print text fallback commands", true).option("--browser", "Alias for --web").option("--console-url <url>", "Console signup URL override").option("--json", "Output as JSON").action((opts) => {
|
|
@@ -10779,10 +10911,10 @@ async function pollUntil(check2, opts) {
|
|
|
10779
10911
|
const label = opts.label ?? step;
|
|
10780
10912
|
process.stderr.write(import_picocolors2.default.dim(` ${label}: waiting... (${Math.round(elapsed / 1e3)}s)
|
|
10781
10913
|
`));
|
|
10782
|
-
await
|
|
10914
|
+
await sleep2(opts.intervalMs);
|
|
10783
10915
|
}
|
|
10784
10916
|
}
|
|
10785
|
-
function
|
|
10917
|
+
function sleep2(ms) {
|
|
10786
10918
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
10787
10919
|
}
|
|
10788
10920
|
|
|
@@ -32228,7 +32360,7 @@ var StdioServerTransport = class {
|
|
|
32228
32360
|
};
|
|
32229
32361
|
|
|
32230
32362
|
// src/lib/cli-version.ts
|
|
32231
|
-
var CLI_VERSION = "0.1.
|
|
32363
|
+
var CLI_VERSION = "0.1.4";
|
|
32232
32364
|
|
|
32233
32365
|
// src/commands/mcp-serve.ts
|
|
32234
32366
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
@@ -35848,7 +35980,7 @@ async function runGuidedStart(apiUrlOverride, executeCommand) {
|
|
|
35848
35980
|
}
|
|
35849
35981
|
if (!state.orgId) {
|
|
35850
35982
|
process.stdout.write("Step 2/3: Set default org\n");
|
|
35851
|
-
const orgs = await
|
|
35983
|
+
const orgs = await fetchOrgMemberships2(apiUrlOverride);
|
|
35852
35984
|
if (orgs.length === 1) {
|
|
35853
35985
|
const code = await executeCommand(["org", "use", "--org", orgs[0].org_id], apiUrlOverride);
|
|
35854
35986
|
if (code !== 0) process.stdout.write(`org use exited with code ${code}.
|
|
@@ -35874,7 +36006,7 @@ async function runGuidedStart(apiUrlOverride, executeCommand) {
|
|
|
35874
36006
|
process.stdout.write(`org create exited with code ${createCode}.
|
|
35875
36007
|
`);
|
|
35876
36008
|
} else {
|
|
35877
|
-
const refreshedOrgs = await
|
|
36009
|
+
const refreshedOrgs = await fetchOrgMemberships2(apiUrlOverride);
|
|
35878
36010
|
if (refreshedOrgs.length === 1) {
|
|
35879
36011
|
const useCode = await executeCommand(["org", "use", "--org", refreshedOrgs[0].org_id], apiUrlOverride);
|
|
35880
36012
|
if (useCode !== 0) process.stdout.write(`org use exited with code ${useCode}.
|
|
@@ -35904,7 +36036,7 @@ async function maybeRunTenantStatus(apiUrlOverride, executeCommand) {
|
|
|
35904
36036
|
`);
|
|
35905
36037
|
}
|
|
35906
36038
|
}
|
|
35907
|
-
async function
|
|
36039
|
+
async function fetchOrgMemberships2(apiUrlOverride) {
|
|
35908
36040
|
try {
|
|
35909
36041
|
const creds = loadCredentials(apiUrlOverride);
|
|
35910
36042
|
const res = await fetch(`${creds.apiUrl}/v1/console/auth/my-orgs`, {
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@f-o-h/cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "FOH CLI - AI-operator provisioning tool for Front Of House",
|
|
5
|
-
"license": "UNLICENSED",
|
|
6
|
-
"bin": {
|
|
7
|
-
"foh": "dist/foh.js"
|
|
8
|
-
},
|
|
9
|
-
"main": "dist/foh.js",
|
|
10
|
-
"files": [
|
|
11
|
-
"dist/",
|
|
12
|
-
"README.md",
|
|
13
|
-
"package.json"
|
|
14
|
-
],
|
|
15
|
-
"publishConfig": {
|
|
16
|
-
"access": "public"
|
|
17
|
-
},
|
|
18
|
-
"engines": {
|
|
19
|
-
"node": ">=18"
|
|
20
|
-
},
|
|
21
|
-
"scripts": {
|
|
22
|
-
"build": "node build.mjs",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"typecheck": "tsc --noEmit"
|
|
25
|
-
},
|
|
26
|
-
"dependencies": {
|
|
27
|
-
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
28
|
-
"commander": "^12.1.0",
|
|
29
|
-
"js-yaml": "^4.1.1",
|
|
30
|
-
"picocolors": "^1.1.1",
|
|
31
|
-
"zod": "^4.3.6"
|
|
32
|
-
},
|
|
33
|
-
"devDependencies": {
|
|
34
|
-
"@types/js-yaml": "^4.0.9",
|
|
35
|
-
"@types/node": "^22.0.0",
|
|
36
|
-
"esbuild": "^0.24.0",
|
|
37
|
-
"vitest": "^2.0.0"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@f-o-h/cli",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "FOH CLI - AI-operator provisioning tool for Front Of House",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"bin": {
|
|
7
|
+
"foh": "dist/foh.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/foh.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/",
|
|
12
|
+
"README.md",
|
|
13
|
+
"package.json"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=18"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "node build.mjs",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"typecheck": "tsc --noEmit"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
28
|
+
"commander": "^12.1.0",
|
|
29
|
+
"js-yaml": "^4.1.1",
|
|
30
|
+
"picocolors": "^1.1.1",
|
|
31
|
+
"zod": "^4.3.6"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/js-yaml": "^4.0.9",
|
|
35
|
+
"@types/node": "^22.0.0",
|
|
36
|
+
"esbuild": "^0.24.0",
|
|
37
|
+
"vitest": "^2.0.0"
|
|
38
|
+
}
|
|
39
|
+
}
|