@outlit/cli 3.2.1 → 3.2.2
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/dist/cli.js +158 -40
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -104,7 +104,7 @@ var package_default;
|
|
|
104
104
|
var init_package = __esm(() => {
|
|
105
105
|
package_default = {
|
|
106
106
|
name: "@outlit/cli",
|
|
107
|
-
version: "3.2.
|
|
107
|
+
version: "3.2.2",
|
|
108
108
|
description: "CLI for querying Outlit customer context and installing agent skills",
|
|
109
109
|
license: "Apache-2.0",
|
|
110
110
|
repository: {
|
|
@@ -19252,10 +19252,12 @@ function readCommandOutput2(command, args) {
|
|
|
19252
19252
|
return null;
|
|
19253
19253
|
}
|
|
19254
19254
|
}
|
|
19255
|
-
function
|
|
19255
|
+
function isStandaloneInstall2(argv = process.argv) {
|
|
19256
19256
|
const scriptPath = argv[1];
|
|
19257
19257
|
if (!scriptPath)
|
|
19258
19258
|
return true;
|
|
19259
|
+
if (scriptPath.startsWith("/$bunfs/") || scriptPath.startsWith("~bunfs"))
|
|
19260
|
+
return true;
|
|
19259
19261
|
const resolved = safeRealPath2(scriptPath) ?? scriptPath;
|
|
19260
19262
|
return !/\.(?:cjs|mjs|jsx?|tsx?)$/.test(resolved);
|
|
19261
19263
|
}
|
|
@@ -19281,8 +19283,11 @@ function safeRealPath2(filePath) {
|
|
|
19281
19283
|
return null;
|
|
19282
19284
|
}
|
|
19283
19285
|
}
|
|
19284
|
-
function formatUpdateCommand2(installer =
|
|
19285
|
-
|
|
19286
|
+
function formatUpdateCommand2(installer, argv = process.argv) {
|
|
19287
|
+
if (isStandaloneInstall2(argv))
|
|
19288
|
+
return STANDALONE_UPDATE_HINT2;
|
|
19289
|
+
const resolved = installer === undefined ? inferInstaller2() : installer;
|
|
19290
|
+
switch (resolved) {
|
|
19286
19291
|
case "bun":
|
|
19287
19292
|
return "bun add -g @outlit/cli";
|
|
19288
19293
|
case "npm":
|
|
@@ -19343,7 +19348,7 @@ function runUpgradeCommand(command, opts) {
|
|
|
19343
19348
|
throw new Error(`Upgrade command failed: ${command.displayCommand}`);
|
|
19344
19349
|
}
|
|
19345
19350
|
}
|
|
19346
|
-
var UPDATE_CHECK_INTERVAL_MS2, PACKAGE_NAME2 = "@outlit/cli", LATEST_VERSION_URL2 = "https://registry.npmjs.org/@outlit%2Fcli/latest";
|
|
19351
|
+
var UPDATE_CHECK_INTERVAL_MS2, PACKAGE_NAME2 = "@outlit/cli", LATEST_VERSION_URL2 = "https://registry.npmjs.org/@outlit%2Fcli/latest", STANDALONE_UPDATE_HINT2 = "re-run your original install method (for example `curl -fsSL https://outlit.ai/install.sh | bash` or `brew upgrade outlitai/tap/outlit`), or download the latest release from https://github.com/OutlitAI/outlit-sdk/releases";
|
|
19347
19352
|
var init_update2 = __esm(() => {
|
|
19348
19353
|
init_config();
|
|
19349
19354
|
init_tty();
|
|
@@ -19704,26 +19709,77 @@ function checkApiKeyPresence(credential) {
|
|
|
19704
19709
|
}
|
|
19705
19710
|
async function validateApiKey(apiKey) {
|
|
19706
19711
|
try {
|
|
19707
|
-
await pingApiKey(apiKey);
|
|
19708
|
-
|
|
19712
|
+
const validation = await pingApiKey(apiKey);
|
|
19713
|
+
const org = validation.organization?.name ?? validation.organization?.slug ?? validation.organizationId;
|
|
19714
|
+
const keyDetail = validation.apiKey ? ` · key "${validation.apiKey.name}" (${validation.apiKey.keyType})` : "";
|
|
19715
|
+
return {
|
|
19716
|
+
check: {
|
|
19717
|
+
name: "API validation",
|
|
19718
|
+
status: "pass",
|
|
19719
|
+
message: "Key is valid",
|
|
19720
|
+
detail: `Org: ${org}${keyDetail}`
|
|
19721
|
+
},
|
|
19722
|
+
validation
|
|
19723
|
+
};
|
|
19709
19724
|
} catch (err) {
|
|
19710
19725
|
if (isApiKeyValidationUnavailableError(err)) {
|
|
19711
19726
|
return {
|
|
19712
|
-
|
|
19713
|
-
|
|
19714
|
-
|
|
19715
|
-
|
|
19727
|
+
check: {
|
|
19728
|
+
name: "API validation",
|
|
19729
|
+
status: "warn",
|
|
19730
|
+
message: "API validation is temporarily unavailable",
|
|
19731
|
+
detail: "Try again shortly"
|
|
19732
|
+
},
|
|
19733
|
+
validation: null
|
|
19716
19734
|
};
|
|
19717
19735
|
}
|
|
19718
19736
|
return {
|
|
19719
|
-
|
|
19720
|
-
|
|
19721
|
-
|
|
19722
|
-
|
|
19737
|
+
check: {
|
|
19738
|
+
name: "API validation",
|
|
19739
|
+
status: "fail",
|
|
19740
|
+
message: `API rejected key: ${errorMessage(err, "unknown error")}`,
|
|
19741
|
+
detail: `Check your key at ${OUTLIT_DASHBOARD_URL}`
|
|
19742
|
+
},
|
|
19743
|
+
validation: null
|
|
19723
19744
|
};
|
|
19724
19745
|
}
|
|
19725
19746
|
}
|
|
19726
|
-
|
|
19747
|
+
function grantUsable(grant, grants, createdById) {
|
|
19748
|
+
if (!grants.includes(grant))
|
|
19749
|
+
return false;
|
|
19750
|
+
if (grant === "integrations:connect_own" && !createdById)
|
|
19751
|
+
return false;
|
|
19752
|
+
return true;
|
|
19753
|
+
}
|
|
19754
|
+
function checkPermissions(validation) {
|
|
19755
|
+
const grants = validation.authorization.grants;
|
|
19756
|
+
const createdById = validation.createdById?.trim() || null;
|
|
19757
|
+
const unavailable = COMMAND_GRANTS.filter((family) => !family.anyOf.some((grant) => grantUsable(grant, grants, createdById)));
|
|
19758
|
+
const detail = [
|
|
19759
|
+
grants.length > 0 ? `grants: ${grants.join(", ")}` : null,
|
|
19760
|
+
unavailable.length > 0 ? `unavailable to this key: ${unavailable.map((family) => family.commands).join("; ")}` : null
|
|
19761
|
+
].filter((part) => part !== null).join(" · ");
|
|
19762
|
+
return {
|
|
19763
|
+
name: "Permissions",
|
|
19764
|
+
status: unavailable.length > 0 ? "warn" : "pass",
|
|
19765
|
+
message: `${grants.length} key grant${grants.length === 1 ? "" : "s"}`,
|
|
19766
|
+
detail: detail || undefined
|
|
19767
|
+
};
|
|
19768
|
+
}
|
|
19769
|
+
async function checkIntegrations(apiKey, validation) {
|
|
19770
|
+
const grants = validation?.authorization.grants;
|
|
19771
|
+
if (grants) {
|
|
19772
|
+
const createdById = validation?.createdById?.trim() || null;
|
|
19773
|
+
const canRead = grantUsable("integrations:manage", grants, createdById) || grantUsable("integrations:connect_own", grants, createdById);
|
|
19774
|
+
if (!canRead) {
|
|
19775
|
+
return {
|
|
19776
|
+
name: "Integrations",
|
|
19777
|
+
status: "warn",
|
|
19778
|
+
message: "API key does not grant integrations access",
|
|
19779
|
+
detail: "Requires the integrations:manage grant, or integrations:connect_own on a user-created key"
|
|
19780
|
+
};
|
|
19781
|
+
}
|
|
19782
|
+
}
|
|
19727
19783
|
try {
|
|
19728
19784
|
const client = await createClient(apiKey);
|
|
19729
19785
|
const timeout = new Promise((_2, reject) => setTimeout(() => reject(new Error("Integrations check timed out")), 1e4));
|
|
@@ -19755,7 +19811,15 @@ async function checkIntegrations(apiKey) {
|
|
|
19755
19811
|
status: "pass",
|
|
19756
19812
|
message: `${ready} integration(s) ready`
|
|
19757
19813
|
};
|
|
19758
|
-
} catch {
|
|
19814
|
+
} catch (err) {
|
|
19815
|
+
if (isOutlitToolsApiError(err) && err.envelope?.code === "TOOL_CALL_FORBIDDEN") {
|
|
19816
|
+
return {
|
|
19817
|
+
name: "Integrations",
|
|
19818
|
+
status: "warn",
|
|
19819
|
+
message: "API key was denied integrations access",
|
|
19820
|
+
detail: "Requires the integrations:manage grant, or integrations:connect_own on a user-created key"
|
|
19821
|
+
};
|
|
19822
|
+
}
|
|
19759
19823
|
return {
|
|
19760
19824
|
name: "Integrations",
|
|
19761
19825
|
status: "warn",
|
|
@@ -19843,8 +19907,9 @@ function printChecks(checks) {
|
|
|
19843
19907
|
}
|
|
19844
19908
|
console.log("");
|
|
19845
19909
|
}
|
|
19846
|
-
var FAIL_SYMBOL2, STATUS_ICONS, doctor_default, agentChecks;
|
|
19910
|
+
var FAIL_SYMBOL2, STATUS_ICONS, doctor_default, COMMAND_GRANTS, agentChecks;
|
|
19847
19911
|
var init_doctor = __esm(() => {
|
|
19912
|
+
init_dist4();
|
|
19848
19913
|
init_dist();
|
|
19849
19914
|
init_auth();
|
|
19850
19915
|
init_output2();
|
|
@@ -19867,11 +19932,13 @@ var init_doctor = __esm(() => {
|
|
|
19867
19932
|
description: [
|
|
19868
19933
|
"Check CLI version, API key, connectivity, and agent detection.",
|
|
19869
19934
|
"",
|
|
19870
|
-
"Runs
|
|
19935
|
+
"Runs six checks in sequence:",
|
|
19871
19936
|
" 1. CLI version -- compares against npm registry",
|
|
19872
19937
|
" 2. API key -- checks presence and format (ok_ prefix)",
|
|
19873
19938
|
" 3. API validation -- makes a live test call to verify the key works",
|
|
19874
|
-
" 4.
|
|
19939
|
+
" 4. Permissions -- shows key grants and unavailable commands",
|
|
19940
|
+
" 5. Integrations -- checks integration readiness or explains missing access",
|
|
19941
|
+
" 6. Agent detection -- detects supported coding agents and whether the Outlit skill is installed",
|
|
19875
19942
|
"",
|
|
19876
19943
|
"Exit code: 0 if all checks pass or warn, 1 if any check fails.",
|
|
19877
19944
|
"",
|
|
@@ -19896,9 +19963,12 @@ var init_doctor = __esm(() => {
|
|
|
19896
19963
|
checks.push(checkApiKeyPresence(credential));
|
|
19897
19964
|
if (credential) {
|
|
19898
19965
|
const apiCheck = await validateApiKey(credential.key);
|
|
19899
|
-
checks.push(apiCheck);
|
|
19900
|
-
if (apiCheck.
|
|
19901
|
-
checks.push(
|
|
19966
|
+
checks.push(apiCheck.check);
|
|
19967
|
+
if (apiCheck.validation) {
|
|
19968
|
+
checks.push(checkPermissions(apiCheck.validation));
|
|
19969
|
+
}
|
|
19970
|
+
if (apiCheck.check.status !== "fail") {
|
|
19971
|
+
checks.push(await checkIntegrations(credential.key, apiCheck.validation));
|
|
19902
19972
|
}
|
|
19903
19973
|
} else {
|
|
19904
19974
|
checks.push({
|
|
@@ -19918,6 +19988,38 @@ var init_doctor = __esm(() => {
|
|
|
19918
19988
|
process.exit(1);
|
|
19919
19989
|
}
|
|
19920
19990
|
});
|
|
19991
|
+
COMMAND_GRANTS = [
|
|
19992
|
+
{
|
|
19993
|
+
commands: "customers (read), users, facts, sources, search, attention",
|
|
19994
|
+
anyOf: ["customer_intelligence:read"]
|
|
19995
|
+
},
|
|
19996
|
+
{ commands: "ws-users", anyOf: ["workspace_members:read"] },
|
|
19997
|
+
{ commands: "sql, schema", anyOf: ["analytics:read"] },
|
|
19998
|
+
{ commands: "destinations", anyOf: ["destinations:manage"] },
|
|
19999
|
+
{ commands: "features", anyOf: ["behavior_metrics:manage"] },
|
|
20000
|
+
{
|
|
20001
|
+
commands: "integrations",
|
|
20002
|
+
anyOf: ["integrations:manage", "integrations:connect_own"]
|
|
20003
|
+
},
|
|
20004
|
+
{ commands: "activation get, preview", anyOf: ["activation:read"] },
|
|
20005
|
+
{ commands: "activation update, disable", anyOf: ["activation:manage"] },
|
|
20006
|
+
{ commands: "settings get", anyOf: ["workspace_settings:read"] },
|
|
20007
|
+
{ commands: "settings update", anyOf: ["workspace_settings:manage"] },
|
|
20008
|
+
{ commands: "customers grant, revoke, owner", anyOf: ["customer_access:manage"] },
|
|
20009
|
+
{
|
|
20010
|
+
commands: "identity suggestions list",
|
|
20011
|
+
anyOf: ["customer_intelligence:read"]
|
|
20012
|
+
},
|
|
20013
|
+
{
|
|
20014
|
+
commands: "identity suggestions reject",
|
|
20015
|
+
anyOf: ["customer_identity:review"]
|
|
20016
|
+
},
|
|
20017
|
+
{
|
|
20018
|
+
commands: "customers merge (preview), customers merge-status",
|
|
20019
|
+
anyOf: ["customer_intelligence:read"]
|
|
20020
|
+
},
|
|
20021
|
+
{ commands: "customers merge --execute", anyOf: ["customer_identity:merge"] }
|
|
20022
|
+
];
|
|
19921
20023
|
agentChecks = {
|
|
19922
20024
|
"claude-code": {
|
|
19923
20025
|
name: "Claude Code",
|
|
@@ -19955,7 +20057,7 @@ var exports_upgrade = {};
|
|
|
19955
20057
|
__export(exports_upgrade, {
|
|
19956
20058
|
default: () => upgrade_default
|
|
19957
20059
|
});
|
|
19958
|
-
var
|
|
20060
|
+
var upgrade_default;
|
|
19959
20061
|
var init_upgrade = __esm(() => {
|
|
19960
20062
|
init_dist();
|
|
19961
20063
|
init_output2();
|
|
@@ -19996,10 +20098,10 @@ var init_upgrade = __esm(() => {
|
|
|
19996
20098
|
console.log(`Outlit CLI is already up to date (v${CLI_VERSION2})`);
|
|
19997
20099
|
return;
|
|
19998
20100
|
}
|
|
19999
|
-
const standalone =
|
|
20101
|
+
const standalone = isStandaloneInstall2();
|
|
20000
20102
|
const upgradeCommand = standalone ? null : getUpgradeCommand();
|
|
20001
20103
|
if (!upgradeCommand) {
|
|
20002
|
-
const message = standalone ? `Outlit CLI v${latestVersion} is available. This standalone binary cannot update itself — ${
|
|
20104
|
+
const message = standalone ? `Outlit CLI v${latestVersion} is available. This standalone binary cannot update itself — ${STANDALONE_UPDATE_HINT2}.` : `Outlit CLI v${latestVersion} is available. Could not determine how Outlit CLI was installed. Update it manually with your package manager, for example \`bun add -g @outlit/cli\` or \`npm install -g @outlit/cli\`.`;
|
|
20003
20105
|
return outputError({ message, code: standalone ? "manual_update_required" : "unknown_installer" }, json);
|
|
20004
20106
|
}
|
|
20005
20107
|
try {
|
|
@@ -23476,6 +23578,7 @@ var UPDATE_CHECK_INTERVAL_MS = 12 * 60 * 60 * 1000;
|
|
|
23476
23578
|
var PACKAGE_NAME = "@outlit/cli";
|
|
23477
23579
|
var LATEST_VERSION_URL = "https://registry.npmjs.org/@outlit%2Fcli/latest";
|
|
23478
23580
|
var INTERNAL_UPDATE_FLAG = "--internal-update-check";
|
|
23581
|
+
var STANDALONE_UPDATE_HINT = "re-run your original install method (for example `curl -fsSL https://outlit.ai/install.sh | bash` or `brew upgrade outlitai/tap/outlit`), or download the latest release from https://github.com/OutlitAI/outlit-sdk/releases";
|
|
23479
23582
|
function getUpdateCachePath() {
|
|
23480
23583
|
return join2(getConfigDir(), "update-check.json");
|
|
23481
23584
|
}
|
|
@@ -23562,6 +23665,15 @@ function readCommandOutput(command, args) {
|
|
|
23562
23665
|
return null;
|
|
23563
23666
|
}
|
|
23564
23667
|
}
|
|
23668
|
+
function isStandaloneInstall(argv = process.argv) {
|
|
23669
|
+
const scriptPath = argv[1];
|
|
23670
|
+
if (!scriptPath)
|
|
23671
|
+
return true;
|
|
23672
|
+
if (scriptPath.startsWith("/$bunfs/") || scriptPath.startsWith("~bunfs"))
|
|
23673
|
+
return true;
|
|
23674
|
+
const resolved = safeRealPath(scriptPath) ?? scriptPath;
|
|
23675
|
+
return !/\.(?:cjs|mjs|jsx?|tsx?)$/.test(resolved);
|
|
23676
|
+
}
|
|
23565
23677
|
function inferInstaller() {
|
|
23566
23678
|
const fromAgent = inferInstallerFromUserAgent(process.env.npm_config_user_agent ?? "");
|
|
23567
23679
|
if (fromAgent)
|
|
@@ -23584,8 +23696,11 @@ function safeRealPath(filePath) {
|
|
|
23584
23696
|
return null;
|
|
23585
23697
|
}
|
|
23586
23698
|
}
|
|
23587
|
-
function formatUpdateCommand(installer =
|
|
23588
|
-
|
|
23699
|
+
function formatUpdateCommand(installer, argv = process.argv) {
|
|
23700
|
+
if (isStandaloneInstall(argv))
|
|
23701
|
+
return STANDALONE_UPDATE_HINT;
|
|
23702
|
+
const resolved = installer === undefined ? inferInstaller() : installer;
|
|
23703
|
+
switch (resolved) {
|
|
23589
23704
|
case "bun":
|
|
23590
23705
|
return "bun add -g @outlit/cli";
|
|
23591
23706
|
case "npm":
|
|
@@ -23627,26 +23742,29 @@ function printCachedUpdateNotice(argv = process.argv, notify = console.error) {
|
|
|
23627
23742
|
Update with: ${notice.command}`);
|
|
23628
23743
|
return true;
|
|
23629
23744
|
}
|
|
23630
|
-
function scheduleBackgroundUpdateCheck(argv = process.argv, spawnProcess = spawn) {
|
|
23745
|
+
function scheduleBackgroundUpdateCheck(argv = process.argv, spawnProcess = spawn, execPath = process.execPath) {
|
|
23631
23746
|
if (!shouldShowUpdateNotice(argv))
|
|
23632
23747
|
return false;
|
|
23633
23748
|
if (!isUpdateCheckDue(readCachedUpdateState()))
|
|
23634
23749
|
return false;
|
|
23635
|
-
const
|
|
23636
|
-
const
|
|
23637
|
-
|
|
23750
|
+
const standalone = isStandaloneInstall(argv);
|
|
23751
|
+
const command = standalone ? execPath : argv[0];
|
|
23752
|
+
const scriptPath = standalone ? null : argv[1];
|
|
23753
|
+
if (!command || !standalone && !scriptPath)
|
|
23638
23754
|
return false;
|
|
23639
|
-
|
|
23640
|
-
detached: true,
|
|
23641
|
-
|
|
23642
|
-
|
|
23643
|
-
|
|
23644
|
-
|
|
23755
|
+
try {
|
|
23756
|
+
const child = spawnProcess(command, [...scriptPath ? [scriptPath] : [], INTERNAL_UPDATE_FLAG], { detached: true, stdio: "ignore" });
|
|
23757
|
+
child.on?.("error", () => {});
|
|
23758
|
+
child.unref?.();
|
|
23759
|
+
return true;
|
|
23760
|
+
} catch {
|
|
23761
|
+
return false;
|
|
23762
|
+
}
|
|
23645
23763
|
}
|
|
23646
23764
|
function initializeUpdateNotifier(opts) {
|
|
23647
23765
|
const argv = opts?.argv ?? process.argv;
|
|
23648
23766
|
printCachedUpdateNotice(argv, opts?.notify);
|
|
23649
|
-
scheduleBackgroundUpdateCheck(argv, opts?.spawn);
|
|
23767
|
+
scheduleBackgroundUpdateCheck(argv, opts?.spawn, opts?.execPath);
|
|
23650
23768
|
}
|
|
23651
23769
|
async function fetchLatestCliVersion() {
|
|
23652
23770
|
const response = await fetch(LATEST_VERSION_URL, { signal: AbortSignal.timeout(5000) });
|
|
@@ -23659,7 +23777,7 @@ async function fetchLatestCliVersion() {
|
|
|
23659
23777
|
}
|
|
23660
23778
|
async function runInternalUpdateCheck(opts) {
|
|
23661
23779
|
const fetchLatestVersion = opts?.fetchLatestVersion ?? fetchLatestCliVersion;
|
|
23662
|
-
const installer = opts?.installer ?? inferInstaller();
|
|
23780
|
+
const installer = isStandaloneInstall() ? null : opts?.installer ?? inferInstaller();
|
|
23663
23781
|
try {
|
|
23664
23782
|
const latestVersion = await fetchLatestVersion();
|
|
23665
23783
|
writeCachedUpdateState({
|