aipctl 2026.10.4 → 2026.10.5
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 +37 -11
- package/build/index.cjs +704 -315
- package/docs/api-contract-inventory.md +23 -1
- package/package.json +3 -3
package/build/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ var require$$0$1 = require('buffer');
|
|
|
26
26
|
var require$$2 = require('util');
|
|
27
27
|
require('node:net');
|
|
28
28
|
require('node:worker_threads');
|
|
29
|
+
var promises = require('node:timers/promises');
|
|
29
30
|
var require$$0$6 = require('path');
|
|
30
31
|
var require$$0$5 = require('fs');
|
|
31
32
|
var require$$0$4 = require('constants');
|
|
@@ -89693,8 +89694,6 @@ const SESSION_EXPIRED_MESSAGE = 'Session expired. Run "aipctl auth login" to con
|
|
|
89693
89694
|
|
|
89694
89695
|
const CONFIG_SET_HINT = "aipctl config set --app-url https://app.example.com";
|
|
89695
89696
|
const CONFIG_DIR$2 = path__namespace.join(os__namespace.homedir(), ".config", "aip");
|
|
89696
|
-
const CONFIG_FILE = path__namespace.join(CONFIG_DIR$2, "config.json");
|
|
89697
|
-
let cachedConfig;
|
|
89698
89697
|
class ConfigServiceTag extends Tag$1("ConfigService")() {
|
|
89699
89698
|
}
|
|
89700
89699
|
class AppUrlNotConfiguredError extends Error {
|
|
@@ -89744,9 +89743,9 @@ function cloneConfig(config) {
|
|
|
89744
89743
|
currentOrganization: config.currentOrganization ? { ...config.currentOrganization } : void 0
|
|
89745
89744
|
};
|
|
89746
89745
|
}
|
|
89747
|
-
function readConfigFile() {
|
|
89746
|
+
function readConfigFile(configFile) {
|
|
89748
89747
|
try {
|
|
89749
|
-
const content = fs__namespace.readFileSync(
|
|
89748
|
+
const content = fs__namespace.readFileSync(configFile, "utf-8");
|
|
89750
89749
|
return normalizeLoadedConfig(JSON.parse(content));
|
|
89751
89750
|
} catch {
|
|
89752
89751
|
return {};
|
|
@@ -89831,25 +89830,33 @@ function requireApiBaseUrl(config) {
|
|
|
89831
89830
|
function requireChatBaseUrl(config) {
|
|
89832
89831
|
return deriveInternalBaseUrls(requireAppBaseUrl(config)).chatBaseUrl;
|
|
89833
89832
|
}
|
|
89834
|
-
|
|
89835
|
-
|
|
89836
|
-
|
|
89837
|
-
|
|
89838
|
-
|
|
89839
|
-
|
|
89840
|
-
|
|
89841
|
-
|
|
89842
|
-
|
|
89843
|
-
|
|
89844
|
-
|
|
89845
|
-
|
|
89846
|
-
|
|
89847
|
-
|
|
89833
|
+
function makeConfigService(directory) {
|
|
89834
|
+
const configFile = path__namespace.join(directory, "config.json");
|
|
89835
|
+
return {
|
|
89836
|
+
load: () => {
|
|
89837
|
+
return cloneConfig(readConfigFile(configFile));
|
|
89838
|
+
},
|
|
89839
|
+
save: (config, currentConfig) => {
|
|
89840
|
+
const current = currentConfig ?? readConfigFile(configFile);
|
|
89841
|
+
const merged = cloneConfig({
|
|
89842
|
+
...current,
|
|
89843
|
+
...config
|
|
89844
|
+
});
|
|
89845
|
+
if (isSameConfig(current, merged)) {
|
|
89846
|
+
return;
|
|
89847
|
+
}
|
|
89848
|
+
fs__namespace.mkdirSync(directory, { recursive: true, mode: 448 });
|
|
89849
|
+
const temporaryFile = `${configFile}.${crypto.randomUUID()}.tmp`;
|
|
89850
|
+
try {
|
|
89851
|
+
fs__namespace.writeFileSync(temporaryFile, JSON.stringify(merged, null, 2), { mode: 384 });
|
|
89852
|
+
fs__namespace.renameSync(temporaryFile, configFile);
|
|
89853
|
+
} finally {
|
|
89854
|
+
if (fs__namespace.existsSync(temporaryFile)) fs__namespace.unlinkSync(temporaryFile);
|
|
89855
|
+
}
|
|
89848
89856
|
}
|
|
89849
|
-
|
|
89850
|
-
|
|
89851
|
-
|
|
89852
|
-
});
|
|
89857
|
+
};
|
|
89858
|
+
}
|
|
89859
|
+
const ConfigServiceLive = succeed$2(ConfigServiceTag, makeConfigService(CONFIG_DIR$2));
|
|
89853
89860
|
const ConfigService = ConfigServiceTag;
|
|
89854
89861
|
|
|
89855
89862
|
var properLockfile = {exports: {}};
|
|
@@ -91959,9 +91966,10 @@ var lockfile = /*@__PURE__*/getDefaultExportFromCjs(properLockfileExports);
|
|
|
91959
91966
|
|
|
91960
91967
|
const ACCESS_TOKEN_FALLBACK_TTL_MS = 12 * 60 * 60 * 1e3;
|
|
91961
91968
|
const REFRESH_TOKEN_FALLBACK_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
91969
|
+
const REFRESH_LOCK_WAIT_MS = 7e4;
|
|
91970
|
+
class RefreshLockWaitError extends TaggedError$1("RefreshLockWaitError") {
|
|
91971
|
+
}
|
|
91962
91972
|
const CONFIG_DIR$1 = path__namespace.join(os__namespace.homedir(), ".config", "aip");
|
|
91963
|
-
const CREDENTIALS_FILE = path__namespace.join(CONFIG_DIR$1, "credentials.json");
|
|
91964
|
-
const CREDENTIALS_LOCK_FILE = path__namespace.join(CONFIG_DIR$1, "credentials.lock");
|
|
91965
91973
|
class CredentialServiceTag extends Tag$1("CredentialService")() {
|
|
91966
91974
|
}
|
|
91967
91975
|
function isNonEmptyString(value) {
|
|
@@ -91996,28 +92004,30 @@ function hasUsableCredentialSession(credentials, now = Date.now()) {
|
|
|
91996
92004
|
const status = getCredentialAuthStatus(credentials, now);
|
|
91997
92005
|
return status === "authenticated" || status === "refreshable";
|
|
91998
92006
|
}
|
|
91999
|
-
const loadCredentials = () => {
|
|
92007
|
+
const loadCredentials = (directory) => {
|
|
92008
|
+
const credentialsFile = path__namespace.join(directory, "credentials.json");
|
|
92000
92009
|
try {
|
|
92001
|
-
if (fs__namespace.existsSync(
|
|
92002
|
-
const content = fs__namespace.readFileSync(
|
|
92010
|
+
if (fs__namespace.existsSync(credentialsFile)) {
|
|
92011
|
+
const content = fs__namespace.readFileSync(credentialsFile, "utf-8");
|
|
92003
92012
|
return JSON.parse(content);
|
|
92004
92013
|
}
|
|
92005
92014
|
} catch {
|
|
92006
92015
|
}
|
|
92007
92016
|
return null;
|
|
92008
92017
|
};
|
|
92009
|
-
function ensureConfigDir$1() {
|
|
92010
|
-
fs__namespace.mkdirSync(
|
|
92018
|
+
function ensureConfigDir$1(directory) {
|
|
92019
|
+
fs__namespace.mkdirSync(directory, { recursive: true, mode: 448 });
|
|
92011
92020
|
}
|
|
92012
|
-
function ensureLockFile() {
|
|
92013
|
-
ensureConfigDir$1();
|
|
92014
|
-
|
|
92015
|
-
|
|
92021
|
+
function ensureLockFile(directory, name) {
|
|
92022
|
+
ensureConfigDir$1(directory);
|
|
92023
|
+
const lockFile = path__namespace.join(directory, name);
|
|
92024
|
+
if (!fs__namespace.existsSync(lockFile)) {
|
|
92025
|
+
fs__namespace.writeFileSync(lockFile, "", { mode: 384 });
|
|
92016
92026
|
}
|
|
92017
92027
|
}
|
|
92018
|
-
async function withCredentialLock(fn) {
|
|
92019
|
-
ensureLockFile();
|
|
92020
|
-
const release = await lockfile.lock(
|
|
92028
|
+
async function withCredentialLock(directory, fn, name = "credentials.lock") {
|
|
92029
|
+
ensureLockFile(directory, name);
|
|
92030
|
+
const release = await lockfile.lock(path__namespace.join(directory, name), {
|
|
92021
92031
|
retries: { retries: 20, minTimeout: 50, maxTimeout: 200 },
|
|
92022
92032
|
stale: 5e3
|
|
92023
92033
|
});
|
|
@@ -92027,26 +92037,89 @@ async function withCredentialLock(fn) {
|
|
|
92027
92037
|
await release();
|
|
92028
92038
|
}
|
|
92029
92039
|
}
|
|
92030
|
-
|
|
92031
|
-
|
|
92032
|
-
|
|
92033
|
-
|
|
92034
|
-
|
|
92035
|
-
|
|
92036
|
-
|
|
92040
|
+
async function withRefreshLock(directory, fn, options = {}) {
|
|
92041
|
+
const checkCancelled = () => {
|
|
92042
|
+
if (options.signal?.aborted)
|
|
92043
|
+
throw new RefreshLockWaitError({
|
|
92044
|
+
code: "CLI_REQUEST_CANCELLED",
|
|
92045
|
+
message: "Authentication refresh wait was cancelled."
|
|
92046
|
+
});
|
|
92047
|
+
};
|
|
92048
|
+
checkCancelled();
|
|
92049
|
+
ensureLockFile(directory, "refresh.lock");
|
|
92050
|
+
const deadline = performance.now() + (options.timeoutMs ?? REFRESH_LOCK_WAIT_MS);
|
|
92051
|
+
const checkDeadline = () => {
|
|
92052
|
+
if (performance.now() >= deadline)
|
|
92053
|
+
throw new RefreshLockWaitError({
|
|
92054
|
+
code: "CLI_AUTH_REFRESH_WAIT_TIMEOUT",
|
|
92055
|
+
message: 'Timed out waiting for another command to refresh authentication. Check "aipctl auth status" before trying again.'
|
|
92056
|
+
});
|
|
92057
|
+
};
|
|
92058
|
+
let release;
|
|
92059
|
+
while (!release) {
|
|
92060
|
+
checkCancelled();
|
|
92061
|
+
checkDeadline();
|
|
92037
92062
|
try {
|
|
92038
|
-
|
|
92039
|
-
|
|
92063
|
+
release = await lockfile.lock(path__namespace.join(directory, "refresh.lock"), { retries: 0, stale: 5e3 });
|
|
92064
|
+
} catch (error) {
|
|
92065
|
+
checkCancelled();
|
|
92066
|
+
if (error.code !== "ELOCKED") throw error;
|
|
92067
|
+
try {
|
|
92068
|
+
await promises.setTimeout(Math.max(0, Math.min(100, deadline - performance.now())), void 0, { signal: options.signal });
|
|
92069
|
+
} catch (error2) {
|
|
92070
|
+
checkCancelled();
|
|
92071
|
+
throw error2;
|
|
92040
92072
|
}
|
|
92041
|
-
} catch {
|
|
92042
92073
|
}
|
|
92043
|
-
}
|
|
92044
|
-
|
|
92045
|
-
|
|
92046
|
-
|
|
92047
|
-
|
|
92048
|
-
|
|
92049
|
-
|
|
92074
|
+
}
|
|
92075
|
+
try {
|
|
92076
|
+
checkCancelled();
|
|
92077
|
+
checkDeadline();
|
|
92078
|
+
return await fn();
|
|
92079
|
+
} finally {
|
|
92080
|
+
await release();
|
|
92081
|
+
}
|
|
92082
|
+
}
|
|
92083
|
+
function makeCredentialService(directory) {
|
|
92084
|
+
const credentialsFile = path__namespace.join(directory, "credentials.json");
|
|
92085
|
+
const revisionFile = path__namespace.join(directory, "session-revision");
|
|
92086
|
+
return {
|
|
92087
|
+
load: () => loadCredentials(directory),
|
|
92088
|
+
getRevision: () => {
|
|
92089
|
+
try {
|
|
92090
|
+
return fs__namespace.readFileSync(revisionFile, "utf-8");
|
|
92091
|
+
} catch (error) {
|
|
92092
|
+
if (error.code === "ENOENT") return "legacy";
|
|
92093
|
+
throw error;
|
|
92094
|
+
}
|
|
92095
|
+
},
|
|
92096
|
+
save: (credentials, options) => {
|
|
92097
|
+
ensureConfigDir$1(directory);
|
|
92098
|
+
if (!options?.preserveSession) fs__namespace.writeFileSync(revisionFile, crypto.randomUUID(), { mode: 384 });
|
|
92099
|
+
const temporaryFile = `${credentialsFile}.${crypto.randomUUID()}.tmp`;
|
|
92100
|
+
try {
|
|
92101
|
+
fs__namespace.writeFileSync(temporaryFile, JSON.stringify(credentials, null, 2), {
|
|
92102
|
+
mode: 384
|
|
92103
|
+
});
|
|
92104
|
+
fs__namespace.renameSync(temporaryFile, credentialsFile);
|
|
92105
|
+
} finally {
|
|
92106
|
+
if (fs__namespace.existsSync(temporaryFile)) fs__namespace.unlinkSync(temporaryFile);
|
|
92107
|
+
}
|
|
92108
|
+
},
|
|
92109
|
+
clear: () => {
|
|
92110
|
+
ensureConfigDir$1(directory);
|
|
92111
|
+
fs__namespace.writeFileSync(revisionFile, crypto.randomUUID(), { mode: 384 });
|
|
92112
|
+
if (fs__namespace.existsSync(credentialsFile)) fs__namespace.unlinkSync(credentialsFile);
|
|
92113
|
+
},
|
|
92114
|
+
isLoggedIn: () => {
|
|
92115
|
+
const creds = loadCredentials(directory);
|
|
92116
|
+
return hasUsableCredentialSession(creds);
|
|
92117
|
+
},
|
|
92118
|
+
withLock: (fn) => withCredentialLock(directory, fn),
|
|
92119
|
+
withRefreshLock: (fn, options) => withRefreshLock(directory, fn, options)
|
|
92120
|
+
};
|
|
92121
|
+
}
|
|
92122
|
+
const CredentialServiceLive = succeed$2(CredentialServiceTag, makeCredentialService(CONFIG_DIR$1));
|
|
92050
92123
|
const CredentialService = CredentialServiceTag;
|
|
92051
92124
|
|
|
92052
92125
|
let isDockerCached;
|
|
@@ -93134,6 +93207,7 @@ async function performHttpResponse(input, init, consume, options) {
|
|
|
93134
93207
|
}
|
|
93135
93208
|
}
|
|
93136
93209
|
controller.signal.throwIfAborted();
|
|
93210
|
+
options.beforeDispatch?.();
|
|
93137
93211
|
dispatched = true;
|
|
93138
93212
|
response = await fetch(input, { ...init, signal: controller.signal });
|
|
93139
93213
|
controller.signal.throwIfAborted();
|
|
@@ -93186,6 +93260,30 @@ async function performHttpResponse(input, init, consume, options) {
|
|
|
93186
93260
|
}
|
|
93187
93261
|
}
|
|
93188
93262
|
|
|
93263
|
+
class AuthSessionChangedError extends TaggedError$1("AuthSessionChangedError") {
|
|
93264
|
+
}
|
|
93265
|
+
function captureAuthSession(config, credentials) {
|
|
93266
|
+
return {
|
|
93267
|
+
revision: credentials.getRevision(),
|
|
93268
|
+
appBaseUrl: requireAppBaseUrl(config.load())
|
|
93269
|
+
};
|
|
93270
|
+
}
|
|
93271
|
+
function isCurrentAuthSession(snapshot, config, credentials) {
|
|
93272
|
+
try {
|
|
93273
|
+
return credentials.getRevision() === snapshot.revision && requireAppBaseUrl(config.load()) === snapshot.appBaseUrl;
|
|
93274
|
+
} catch {
|
|
93275
|
+
return false;
|
|
93276
|
+
}
|
|
93277
|
+
}
|
|
93278
|
+
function assertAuthSession(snapshot, config, credentials) {
|
|
93279
|
+
if (!isCurrentAuthSession(snapshot, config, credentials)) {
|
|
93280
|
+
throw new AuthSessionChangedError({
|
|
93281
|
+
code: "CLI_AUTH_SESSION_CHANGED",
|
|
93282
|
+
message: 'Authentication or App URL changed. Check "aipctl auth status" before trying again.'
|
|
93283
|
+
});
|
|
93284
|
+
}
|
|
93285
|
+
}
|
|
93286
|
+
|
|
93189
93287
|
const CALLBACK_HOST = "127.0.0.1";
|
|
93190
93288
|
const CALLBACK_PORT = 8484;
|
|
93191
93289
|
const CALLBACK_PATH = "/callback";
|
|
@@ -93228,6 +93326,7 @@ function trimTrailingSlash(value) {
|
|
|
93228
93326
|
}
|
|
93229
93327
|
function toError$1(error, fallbackMessage) {
|
|
93230
93328
|
if (error instanceof OAuthRequestError) return error;
|
|
93329
|
+
if (error instanceof AuthSessionChangedError) return new OAuthRequestError(error.message, void 0, error.code);
|
|
93231
93330
|
return error instanceof Error ? new Error(maskSensitiveText(error.message)) : new Error(maskSensitiveText(fallbackMessage));
|
|
93232
93331
|
}
|
|
93233
93332
|
function isRecord(value) {
|
|
@@ -93301,7 +93400,7 @@ async function fetchJson(input, init, parse = (value) => value) {
|
|
|
93301
93400
|
);
|
|
93302
93401
|
}
|
|
93303
93402
|
}
|
|
93304
|
-
async function discoverOAuthMetadata(apiBaseUrl) {
|
|
93403
|
+
async function discoverOAuthMetadata(apiBaseUrl, signal) {
|
|
93305
93404
|
const normalizedBaseUrl = trimTrailingSlash(apiBaseUrl);
|
|
93306
93405
|
const fallback = {
|
|
93307
93406
|
authorizationEndpoint: `${normalizedBaseUrl}/oauth2/authorize`,
|
|
@@ -93311,7 +93410,7 @@ async function discoverOAuthMetadata(apiBaseUrl) {
|
|
|
93311
93410
|
};
|
|
93312
93411
|
const metadataUrl = `${normalizedBaseUrl}/.well-known/oauth-authorization-server`;
|
|
93313
93412
|
try {
|
|
93314
|
-
const metadata = await fetchJson(metadataUrl);
|
|
93413
|
+
const metadata = await fetchJson(metadataUrl, { signal });
|
|
93315
93414
|
return {
|
|
93316
93415
|
authorizationEndpoint: metadata.authorization_endpoint ?? fallback.authorizationEndpoint,
|
|
93317
93416
|
tokenEndpoint: metadata.token_endpoint ?? fallback.tokenEndpoint,
|
|
@@ -93399,13 +93498,18 @@ async function refreshOAuthToken(input) {
|
|
|
93399
93498
|
client_id: input.clientId,
|
|
93400
93499
|
refresh_token: input.refreshToken
|
|
93401
93500
|
});
|
|
93402
|
-
return fetchJson(
|
|
93403
|
-
|
|
93404
|
-
|
|
93405
|
-
|
|
93501
|
+
return fetchJson(
|
|
93502
|
+
input.tokenEndpoint,
|
|
93503
|
+
{
|
|
93504
|
+
method: "POST",
|
|
93505
|
+
signal: input.signal,
|
|
93506
|
+
headers: {
|
|
93507
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
93508
|
+
},
|
|
93509
|
+
body
|
|
93406
93510
|
},
|
|
93407
|
-
|
|
93408
|
-
|
|
93511
|
+
parseOAuthTokenResponse
|
|
93512
|
+
);
|
|
93409
93513
|
}
|
|
93410
93514
|
function tokenExpiresAt(now, expiresInSeconds, fallbackMs) {
|
|
93411
93515
|
return now + (expiresInSeconds === void 0 ? fallbackMs : expiresInSeconds * 1e3);
|
|
@@ -93580,10 +93684,11 @@ async function listenOnCallbackPort$1(server) {
|
|
|
93580
93684
|
const startOAuthFlow = gen(function* () {
|
|
93581
93685
|
const config = yield* ConfigService;
|
|
93582
93686
|
const credentials = yield* CredentialService;
|
|
93583
|
-
const
|
|
93584
|
-
try: () =>
|
|
93585
|
-
catch: (error) => toError$1(error, "
|
|
93687
|
+
const session = yield* tryPromise({
|
|
93688
|
+
try: () => credentials.withLock(() => captureAuthSession(config, credentials)),
|
|
93689
|
+
catch: (error) => toError$1(error, "Could not read authentication state")
|
|
93586
93690
|
});
|
|
93691
|
+
const apiBaseUrl = deriveInternalBaseUrls(session.appBaseUrl).apiBaseUrl;
|
|
93587
93692
|
const pkce = generatePkcePair();
|
|
93588
93693
|
const state = generateState$1();
|
|
93589
93694
|
const deferred = yield* make$m();
|
|
@@ -93640,12 +93745,15 @@ const startOAuthFlow = gen(function* () {
|
|
|
93640
93745
|
console.log("Authorization received. Exchanging token...");
|
|
93641
93746
|
});
|
|
93642
93747
|
const tokenResponse = yield* tryPromise({
|
|
93643
|
-
try: () =>
|
|
93644
|
-
|
|
93645
|
-
|
|
93646
|
-
|
|
93647
|
-
|
|
93648
|
-
|
|
93748
|
+
try: () => {
|
|
93749
|
+
assertAuthSession(session, config, credentials);
|
|
93750
|
+
return exchangeAuthorizationCode({
|
|
93751
|
+
tokenEndpoint: metadata.tokenEndpoint,
|
|
93752
|
+
clientId: registration.clientId,
|
|
93753
|
+
code: callback.code,
|
|
93754
|
+
codeVerifier: pkce.verifier
|
|
93755
|
+
});
|
|
93756
|
+
},
|
|
93649
93757
|
catch: (error) => toError$1(error, "OAuth token exchange failed")
|
|
93650
93758
|
});
|
|
93651
93759
|
const nextCredentials = toCredentialsFromTokenResponse({
|
|
@@ -93653,7 +93761,13 @@ const startOAuthFlow = gen(function* () {
|
|
|
93653
93761
|
clientId: registration.clientId,
|
|
93654
93762
|
issuer: metadata.issuer
|
|
93655
93763
|
});
|
|
93656
|
-
|
|
93764
|
+
yield* tryPromise({
|
|
93765
|
+
try: () => credentials.withLock(() => {
|
|
93766
|
+
assertAuthSession(session, config, credentials);
|
|
93767
|
+
credentials.save(nextCredentials);
|
|
93768
|
+
}),
|
|
93769
|
+
catch: (error) => toError$1(error, "Could not save authentication state")
|
|
93770
|
+
});
|
|
93657
93771
|
return nextCredentials;
|
|
93658
93772
|
}).pipe(ensuring$1(promise$1(() => closeServer())));
|
|
93659
93773
|
});
|
|
@@ -93665,7 +93779,7 @@ const injectedBuildEnv = "dev".length > 0 ? "dev" : "local";
|
|
|
93665
93779
|
if (!isBuildEnv(injectedBuildEnv)) {
|
|
93666
93780
|
throw new Error(`Invalid AIPCTL_BUILD_ENV: ${injectedBuildEnv}`);
|
|
93667
93781
|
}
|
|
93668
|
-
const VERSION = "2026.10.
|
|
93782
|
+
const VERSION = "2026.10.5".length > 0 ? "2026.10.5" : "0.0.0";
|
|
93669
93783
|
const BUILD_ENV = injectedBuildEnv;
|
|
93670
93784
|
const INCLUDE_NATIVE_LOGS = BUILD_ENV !== "prod";
|
|
93671
93785
|
|
|
@@ -94617,7 +94731,7 @@ const JSON_CONTENT_TYPE = "application/json";
|
|
|
94617
94731
|
const AGENT_CHAT_STREAM_RETRY_DELAY_MS = 1e3;
|
|
94618
94732
|
const AGENT_CHAT_STREAM_MAX_ATTEMPTS = 4;
|
|
94619
94733
|
function bearerHeaders(accessToken) {
|
|
94620
|
-
return { Authorization: `Bearer ${accessToken}` };
|
|
94734
|
+
return { Authorization: `Bearer ${accessToken.value}` };
|
|
94621
94735
|
}
|
|
94622
94736
|
function jsonBearerHeaders(accessToken) {
|
|
94623
94737
|
return {
|
|
@@ -94635,6 +94749,13 @@ function apiErrorFromUnknown(error, fallbackMessage) {
|
|
|
94635
94749
|
if (error instanceof ApiError) {
|
|
94636
94750
|
return error;
|
|
94637
94751
|
}
|
|
94752
|
+
if (error instanceof AuthSessionChangedError) {
|
|
94753
|
+
return createApiError({
|
|
94754
|
+
message: error.message,
|
|
94755
|
+
code: error.code,
|
|
94756
|
+
outcome: "not-dispatched"
|
|
94757
|
+
});
|
|
94758
|
+
}
|
|
94638
94759
|
if (error instanceof HttpRequestError) {
|
|
94639
94760
|
return createApiError({
|
|
94640
94761
|
message: error.message + (error.outcome === "unknown" ? " The server may have completed the action. Check its state before running it again." : ""),
|
|
@@ -94833,19 +94954,29 @@ function parseRetryAfterSeconds(value) {
|
|
|
94833
94954
|
const makeRequest = (baseUrl, path, accessToken, options) => tryPromise({
|
|
94834
94955
|
try: async (signal) => {
|
|
94835
94956
|
const resolvedBaseUrl = typeof baseUrl === "function" ? baseUrl() : baseUrl;
|
|
94836
|
-
return withHttpResponse(
|
|
94837
|
-
|
|
94838
|
-
|
|
94839
|
-
|
|
94840
|
-
|
|
94841
|
-
|
|
94842
|
-
|
|
94843
|
-
|
|
94844
|
-
|
|
94845
|
-
|
|
94957
|
+
return withHttpResponse(
|
|
94958
|
+
`${resolvedBaseUrl}${path}`,
|
|
94959
|
+
{
|
|
94960
|
+
method: options?.method || "GET",
|
|
94961
|
+
headers: jsonBearerHeaders(accessToken),
|
|
94962
|
+
body: options?.body ? JSON.stringify(options.body) : void 0
|
|
94963
|
+
},
|
|
94964
|
+
async (response) => {
|
|
94965
|
+
if (!response.ok) {
|
|
94966
|
+
throw await toApiError(response);
|
|
94967
|
+
}
|
|
94968
|
+
if (options?.skipJsonParse || response.status === 202 || response.status === 204) {
|
|
94969
|
+
return void 0;
|
|
94970
|
+
}
|
|
94971
|
+
return await response.json();
|
|
94972
|
+
},
|
|
94973
|
+
{
|
|
94974
|
+
signal,
|
|
94975
|
+
beforeDispatch: () => accessToken.assertCurrent(resolvedBaseUrl),
|
|
94976
|
+
...options?.timeoutMs ? { timeoutMs: options.timeoutMs } : {},
|
|
94977
|
+
...options?.responseBudget ? { responseBudget: options.responseBudget } : {}
|
|
94846
94978
|
}
|
|
94847
|
-
|
|
94848
|
-
}, { signal, ...options?.timeoutMs ? { timeoutMs: options.timeoutMs } : {}, ...options?.responseBudget ? { responseBudget: options.responseBudget } : {} });
|
|
94979
|
+
);
|
|
94849
94980
|
},
|
|
94850
94981
|
catch: (error) => apiErrorFromUnknown(error, "The request could not be completed.")
|
|
94851
94982
|
});
|
|
@@ -94994,6 +95125,12 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
94994
95125
|
if (error instanceof ApiError || error instanceof NotLoggedInError) {
|
|
94995
95126
|
return error;
|
|
94996
95127
|
}
|
|
95128
|
+
if (error instanceof AuthSessionChangedError) {
|
|
95129
|
+
return createApiError({ message: error.message, code: error.code });
|
|
95130
|
+
}
|
|
95131
|
+
if (error instanceof RefreshLockWaitError) {
|
|
95132
|
+
return createApiError({ message: error.message, code: error.code, outcome: "not-dispatched" });
|
|
95133
|
+
}
|
|
94997
95134
|
if (error instanceof OAuthRequestError) {
|
|
94998
95135
|
if (error.statusCode === 401 || error.code === "invalid_grant") {
|
|
94999
95136
|
return sessionExpired();
|
|
@@ -95010,18 +95147,20 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95010
95147
|
message: error instanceof Error ? error.message : "OAuth token refresh failed"
|
|
95011
95148
|
});
|
|
95012
95149
|
};
|
|
95013
|
-
const performOAuthRefresh = async (lockedCreds) => {
|
|
95150
|
+
const performOAuthRefresh = async (lockedCreds, session, signal) => {
|
|
95014
95151
|
const clientId = lockedCreds.clientId;
|
|
95015
95152
|
const refreshToken = lockedCreds.refreshToken;
|
|
95016
95153
|
if (!clientId || !refreshToken) {
|
|
95017
|
-
throw
|
|
95154
|
+
throw sessionExpired();
|
|
95018
95155
|
}
|
|
95019
|
-
const metadata = await discoverOAuthMetadata(
|
|
95156
|
+
const metadata = await discoverOAuthMetadata(deriveInternalBaseUrls(session.appBaseUrl).apiBaseUrl, signal);
|
|
95157
|
+
assertAuthSession(session, configService, credentialService);
|
|
95020
95158
|
try {
|
|
95021
95159
|
const tokenResponse = await refreshOAuthToken({
|
|
95022
95160
|
tokenEndpoint: metadata.tokenEndpoint,
|
|
95023
95161
|
clientId,
|
|
95024
|
-
refreshToken
|
|
95162
|
+
refreshToken,
|
|
95163
|
+
signal
|
|
95025
95164
|
});
|
|
95026
95165
|
const nextCredentials = toCredentialsFromTokenResponse({
|
|
95027
95166
|
tokenResponse,
|
|
@@ -95030,11 +95169,17 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95030
95169
|
previousRefreshToken: refreshToken,
|
|
95031
95170
|
previousRefreshExpiresAt: lockedCreds.refreshExpiresAt
|
|
95032
95171
|
});
|
|
95033
|
-
credentialService.
|
|
95172
|
+
await credentialService.withLock(() => {
|
|
95173
|
+
signal.throwIfAborted();
|
|
95174
|
+
assertAuthSession(session, configService, credentialService);
|
|
95175
|
+
credentialService.save(nextCredentials, { preserveSession: true });
|
|
95176
|
+
});
|
|
95034
95177
|
return nextCredentials;
|
|
95035
95178
|
} catch (error) {
|
|
95036
95179
|
if (error instanceof OAuthRequestError && (error.statusCode === 401 || error.code === "invalid_grant")) {
|
|
95037
|
-
credentialService.
|
|
95180
|
+
await credentialService.withLock(() => {
|
|
95181
|
+
if (isCurrentAuthSession(session, configService, credentialService)) credentialService.clear();
|
|
95182
|
+
});
|
|
95038
95183
|
}
|
|
95039
95184
|
throw error;
|
|
95040
95185
|
}
|
|
@@ -95042,28 +95187,57 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95042
95187
|
const refreshAccessToken = (options) => gen(function* () {
|
|
95043
95188
|
yield* requireApiBaseUrlEffect();
|
|
95044
95189
|
return yield* tryPromise({
|
|
95045
|
-
try: async () => credentialService.
|
|
95046
|
-
|
|
95047
|
-
|
|
95048
|
-
|
|
95049
|
-
|
|
95050
|
-
|
|
95051
|
-
|
|
95052
|
-
|
|
95053
|
-
|
|
95054
|
-
|
|
95055
|
-
|
|
95056
|
-
|
|
95057
|
-
|
|
95058
|
-
|
|
95059
|
-
|
|
95060
|
-
|
|
95061
|
-
|
|
95062
|
-
|
|
95063
|
-
|
|
95190
|
+
try: async (signal) => credentialService.withRefreshLock(
|
|
95191
|
+
async () => {
|
|
95192
|
+
const state = await credentialService.withLock(() => {
|
|
95193
|
+
signal.throwIfAborted();
|
|
95194
|
+
const session = captureAuthSession(configService, credentialService);
|
|
95195
|
+
const lockedCreds = credentialService.load();
|
|
95196
|
+
if (!lockedCreds) {
|
|
95197
|
+
throw notLoggedIn();
|
|
95198
|
+
}
|
|
95199
|
+
const status = getCredentialAuthStatus(lockedCreds, Date.now(), {
|
|
95200
|
+
accessExpiryBufferMs: REFRESH_BUFFER_MS,
|
|
95201
|
+
forceRefresh: options?.force
|
|
95202
|
+
});
|
|
95203
|
+
switch (status) {
|
|
95204
|
+
case "authenticated":
|
|
95205
|
+
case "refreshable":
|
|
95206
|
+
return { lockedCreds, session, status };
|
|
95207
|
+
case "missing":
|
|
95208
|
+
case "expired":
|
|
95209
|
+
throw clearInvalidSession();
|
|
95210
|
+
}
|
|
95211
|
+
});
|
|
95212
|
+
return state.status === "authenticated" ? state.lockedCreds : performOAuthRefresh(state.lockedCreds, state.session, signal);
|
|
95213
|
+
},
|
|
95214
|
+
{ signal }
|
|
95215
|
+
),
|
|
95064
95216
|
catch: toRefreshFailure
|
|
95065
95217
|
});
|
|
95066
95218
|
});
|
|
95219
|
+
const bindAccessToken = (creds) => {
|
|
95220
|
+
const session = captureAuthSession(configService, credentialService);
|
|
95221
|
+
const urls = deriveInternalBaseUrls(session.appBaseUrl);
|
|
95222
|
+
const destinations = [urls.apiBaseUrl, urls.chatBaseUrl].map((url) => new URL(url).origin);
|
|
95223
|
+
return {
|
|
95224
|
+
value: creds.accessToken,
|
|
95225
|
+
assertCurrent: (destination) => {
|
|
95226
|
+
assertAuthSession(session, configService, credentialService);
|
|
95227
|
+
if (!destinations.includes(new URL(destination).origin)) {
|
|
95228
|
+
throw new AuthSessionChangedError({
|
|
95229
|
+
code: "CLI_AUTH_SESSION_CHANGED",
|
|
95230
|
+
message: 'App URL changed. Check "aipctl config status" before trying again.'
|
|
95231
|
+
});
|
|
95232
|
+
}
|
|
95233
|
+
if (credentialService.load()?.accessToken !== creds.accessToken) throw notLoggedIn();
|
|
95234
|
+
}
|
|
95235
|
+
};
|
|
95236
|
+
};
|
|
95237
|
+
const bindAccessTokenEffect = (creds) => try_({
|
|
95238
|
+
try: () => bindAccessToken(creds),
|
|
95239
|
+
catch: toRefreshFailure
|
|
95240
|
+
});
|
|
95067
95241
|
const getAccessToken = () => gen(function* () {
|
|
95068
95242
|
yield* requireApiBaseUrlEffect();
|
|
95069
95243
|
const creds = credentialService.load();
|
|
@@ -95075,14 +95249,14 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95075
95249
|
});
|
|
95076
95250
|
switch (status) {
|
|
95077
95251
|
case "authenticated":
|
|
95078
|
-
return creds
|
|
95252
|
+
return yield* bindAccessTokenEffect(creds);
|
|
95079
95253
|
case "refreshable": {
|
|
95080
95254
|
const refreshedCredentials = yield* refreshAccessToken();
|
|
95081
|
-
return refreshedCredentials
|
|
95255
|
+
return yield* bindAccessTokenEffect(refreshedCredentials);
|
|
95082
95256
|
}
|
|
95083
95257
|
case "missing":
|
|
95084
95258
|
case "expired":
|
|
95085
|
-
return yield*
|
|
95259
|
+
return yield* refreshAccessToken().pipe(flatMap$5(bindAccessTokenEffect));
|
|
95086
95260
|
}
|
|
95087
95261
|
});
|
|
95088
95262
|
const baseUrl = () => loadConfiguredApiBaseUrl();
|
|
@@ -95090,11 +95264,13 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95090
95264
|
const requireReleaseEnabledOperation = (operationId) => {
|
|
95091
95265
|
if (buildEnv !== "prod") return _void;
|
|
95092
95266
|
if (!releaseEnabledCommandOperationIds.has(operationId)) {
|
|
95093
|
-
return fail$3(
|
|
95094
|
-
|
|
95095
|
-
|
|
95096
|
-
|
|
95097
|
-
|
|
95267
|
+
return fail$3(
|
|
95268
|
+
createApiError({
|
|
95269
|
+
message: `CLI operation "${operationId}" is not enabled in this aipctl release.`,
|
|
95270
|
+
statusCode: 404,
|
|
95271
|
+
code: "CLI_OPERATION_NOT_ENABLED"
|
|
95272
|
+
})
|
|
95273
|
+
);
|
|
95098
95274
|
}
|
|
95099
95275
|
return _void;
|
|
95100
95276
|
};
|
|
@@ -95106,19 +95282,30 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95106
95282
|
const deadline = Date.now() + TRANSFER_DEADLINE_MS;
|
|
95107
95283
|
for (let attempt = 1; attempt <= AGENT_CHAT_STREAM_MAX_ATTEMPTS; attempt += 1) {
|
|
95108
95284
|
try {
|
|
95109
|
-
return await withHttpResponse(
|
|
95110
|
-
|
|
95111
|
-
|
|
95112
|
-
|
|
95113
|
-
|
|
95114
|
-
|
|
95115
|
-
|
|
95116
|
-
|
|
95117
|
-
|
|
95118
|
-
|
|
95285
|
+
return await withHttpResponse(
|
|
95286
|
+
`${resolvedChatBaseUrl}${path}`,
|
|
95287
|
+
{
|
|
95288
|
+
method: "POST",
|
|
95289
|
+
headers: jsonBearerHeaders(token),
|
|
95290
|
+
body: JSON.stringify({})
|
|
95291
|
+
},
|
|
95292
|
+
async (response) => {
|
|
95293
|
+
if (!response.ok) {
|
|
95294
|
+
throw await toApiError(response);
|
|
95295
|
+
}
|
|
95296
|
+
if (!response.body) {
|
|
95297
|
+
throw createApiError({
|
|
95298
|
+
message: "No response body from agent chat stream endpoint"
|
|
95299
|
+
});
|
|
95300
|
+
}
|
|
95301
|
+
return await parseSseStream(response.body);
|
|
95302
|
+
},
|
|
95303
|
+
{
|
|
95304
|
+
signal,
|
|
95305
|
+
beforeDispatch: () => token.assertCurrent(resolvedChatBaseUrl),
|
|
95306
|
+
timeoutMs: Math.max(1, deadline - Date.now())
|
|
95119
95307
|
}
|
|
95120
|
-
|
|
95121
|
-
}, { signal, timeoutMs: Math.max(1, deadline - Date.now()) });
|
|
95308
|
+
);
|
|
95122
95309
|
} catch (error) {
|
|
95123
95310
|
if (error instanceof AgentChatStreamIncompleteError && error.sawOnlyTerminalEnvelope && attempt < AGENT_CHAT_STREAM_MAX_ATTEMPTS) {
|
|
95124
95311
|
await sleep(AGENT_CHAT_STREAM_RETRY_DELAY_MS);
|
|
@@ -95158,10 +95345,12 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95158
95345
|
token
|
|
95159
95346
|
);
|
|
95160
95347
|
if (!conversation?.agentInstallationId) {
|
|
95161
|
-
return yield* fail$3(
|
|
95162
|
-
|
|
95163
|
-
|
|
95164
|
-
|
|
95348
|
+
return yield* fail$3(
|
|
95349
|
+
createApiError({
|
|
95350
|
+
message: `Conversation "${conversationId}" is missing an agent installation id.`,
|
|
95351
|
+
statusCode: 400
|
|
95352
|
+
})
|
|
95353
|
+
);
|
|
95165
95354
|
}
|
|
95166
95355
|
return conversation.agentInstallationId;
|
|
95167
95356
|
});
|
|
@@ -95647,10 +95836,14 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95647
95836
|
return { ...response, pagination: normalizePageNumberPagination(response.pagination, response.list.length) };
|
|
95648
95837
|
}),
|
|
95649
95838
|
// Phase 5: Drive/Integration
|
|
95650
|
-
listDriveEntries: (orgSlug) => gen(function* () {
|
|
95839
|
+
listDriveEntries: (orgSlug, options) => gen(function* () {
|
|
95651
95840
|
const token = yield* getAccessToken();
|
|
95652
95841
|
yield* requireReleaseEnabledOperation("listCliDriveEntries");
|
|
95653
|
-
const params = new URLSearchParams({
|
|
95842
|
+
const params = new URLSearchParams({
|
|
95843
|
+
count: String(options?.count ?? 200)
|
|
95844
|
+
});
|
|
95845
|
+
if (options?.cursor !== void 0) params.set("cursor", options.cursor);
|
|
95846
|
+
if (options?.parentId !== void 0) params.set("parentId", options.parentId);
|
|
95654
95847
|
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/drive/entries?${params.toString()}`;
|
|
95655
95848
|
return yield* makeRequest(baseUrl, path, token);
|
|
95656
95849
|
}),
|
|
@@ -95792,15 +95985,25 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95792
95985
|
const token = yield* getAccessToken();
|
|
95793
95986
|
const path = `/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/installed-agents/${encodeURIComponent(agentId)}/export`;
|
|
95794
95987
|
return yield* tryPromise({
|
|
95795
|
-
try: async (signal) => withHttpResponse(
|
|
95796
|
-
|
|
95797
|
-
|
|
95798
|
-
|
|
95799
|
-
|
|
95988
|
+
try: async (signal) => withHttpResponse(
|
|
95989
|
+
`${resolvedApiBaseUrl}${path}`,
|
|
95990
|
+
{
|
|
95991
|
+
headers: bearerHeaders(token)
|
|
95992
|
+
},
|
|
95993
|
+
async (response) => {
|
|
95994
|
+
if (!response.ok) {
|
|
95995
|
+
throw await toApiError(response);
|
|
95996
|
+
}
|
|
95997
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
95998
|
+
return Buffer.from(arrayBuffer);
|
|
95999
|
+
},
|
|
96000
|
+
{
|
|
96001
|
+
signal,
|
|
96002
|
+
beforeDispatch: () => token.assertCurrent(resolvedApiBaseUrl),
|
|
96003
|
+
timeoutMs: TRANSFER_DEADLINE_MS,
|
|
96004
|
+
maxResponseBytes: TRANSFER_MAX_RESPONSE_BYTES
|
|
95800
96005
|
}
|
|
95801
|
-
|
|
95802
|
-
return Buffer.from(arrayBuffer);
|
|
95803
|
-
}, { signal, timeoutMs: TRANSFER_DEADLINE_MS, maxResponseBytes: TRANSFER_MAX_RESPONSE_BYTES }),
|
|
96006
|
+
),
|
|
95804
96007
|
catch: (error) => apiErrorFromUnknown(error, "Export failed")
|
|
95805
96008
|
});
|
|
95806
96009
|
}),
|
|
@@ -96119,7 +96322,9 @@ const ApiService = ApiServiceTag;
|
|
|
96119
96322
|
function jsonOutputRequested(args) {
|
|
96120
96323
|
const forced = args.indexOf("--");
|
|
96121
96324
|
const options = forced === -1 ? args : args.slice(0, forced);
|
|
96122
|
-
return options.some(
|
|
96325
|
+
return options.some(
|
|
96326
|
+
(arg, index) => ["--json=true", "--json-page=true"].includes(arg) || ["--json", "--json-page"].includes(arg) && options[index + 1] !== "false"
|
|
96327
|
+
);
|
|
96123
96328
|
}
|
|
96124
96329
|
function reportInterruption(json) {
|
|
96125
96330
|
const message = "The command was interrupted. Check the status of any change or execution before running it again.";
|
|
@@ -96170,9 +96375,21 @@ function withCliFailureOutput(program, json) {
|
|
|
96170
96375
|
});
|
|
96171
96376
|
}
|
|
96172
96377
|
function formatCliFailure(error, json) {
|
|
96173
|
-
if (
|
|
96378
|
+
if (error instanceof AuthSessionChangedError)
|
|
96379
|
+
return json ? JSON.stringify({
|
|
96380
|
+
error: {
|
|
96381
|
+
code: error.code,
|
|
96382
|
+
message: error.message,
|
|
96383
|
+
outcome: "not-dispatched"
|
|
96384
|
+
}
|
|
96385
|
+
}) : error.message;
|
|
96386
|
+
if (!(error instanceof ApiError || error instanceof OAuthRequestError || error instanceof NotLoggedInError || error instanceof NoOrganizationSelectedError))
|
|
96387
|
+
return void 0;
|
|
96174
96388
|
const diagnosticError = error instanceof ApiError || error instanceof OAuthRequestError;
|
|
96175
|
-
if (!json)
|
|
96389
|
+
if (!json)
|
|
96390
|
+
return maskSensitiveText(
|
|
96391
|
+
error.message + (diagnosticError && error.requestId ? ` Request ID: ${error.requestId}` : "")
|
|
96392
|
+
);
|
|
96176
96393
|
return JSON.stringify({ error: {
|
|
96177
96394
|
code: diagnosticError ? error.code ?? (error instanceof OAuthRequestError ? "CLI_OAUTH_ERROR" : "CLI_API_ERROR") : error._tag === "NotLoggedInError" ? "CLI_AUTH_REQUIRED" : "CLI_ORGANIZATION_REQUIRED",
|
|
96178
96395
|
message: maskSensitiveText(error.message),
|
|
@@ -96244,21 +96461,101 @@ const isNativeCommandEnabled = (command, includeLogs = INCLUDE_NATIVE_LOGS) => {
|
|
|
96244
96461
|
const FORCED_ARGS_SEPARATOR = "--";
|
|
96245
96462
|
const NATIVE_ROOT_COMMANDS = new Set(nativeCommandNames);
|
|
96246
96463
|
const trailingOptionSpecs = [
|
|
96464
|
+
...[
|
|
96465
|
+
["skill", "library"],
|
|
96466
|
+
["skill", "built-in"],
|
|
96467
|
+
["admin", "skill", "built-in"],
|
|
96468
|
+
["admin", "skill", "list"]
|
|
96469
|
+
].map(
|
|
96470
|
+
(command) => ({
|
|
96471
|
+
command,
|
|
96472
|
+
booleanOptions: new Set(command.at(-1) === "list" ? ["--json", "--json-page"] : ["--json-page"]),
|
|
96473
|
+
valueOptions: /* @__PURE__ */ new Set([
|
|
96474
|
+
"--org",
|
|
96475
|
+
"--search",
|
|
96476
|
+
...command.at(-1) === "list" ? ["--page", "--page-size"] : ["--cursor", command.at(-1) === "library" ? "--count" : "--limit"]
|
|
96477
|
+
]),
|
|
96478
|
+
explicitBooleanValues: true
|
|
96479
|
+
})
|
|
96480
|
+
),
|
|
96481
|
+
...["skill", "chat", "drive"].map(
|
|
96482
|
+
(domain) => ({
|
|
96483
|
+
command: [domain, "list"],
|
|
96484
|
+
booleanOptions: new Set(domain === "drive" ? ["--json-page"] : ["--json", "--json-page"]),
|
|
96485
|
+
valueOptions: /* @__PURE__ */ new Set([
|
|
96486
|
+
"--org",
|
|
96487
|
+
"--cursor",
|
|
96488
|
+
...domain === "chat" ? [] : ["--count"],
|
|
96489
|
+
...domain === "skill" ? ["--search"] : domain === "drive" ? ["--parent-id"] : []
|
|
96490
|
+
]),
|
|
96491
|
+
explicitBooleanValues: true
|
|
96492
|
+
})
|
|
96493
|
+
),
|
|
96494
|
+
...[
|
|
96495
|
+
["skill", "delete"],
|
|
96496
|
+
["admin", "skill", "delete"],
|
|
96497
|
+
["admin", "integration", "delete"]
|
|
96498
|
+
].map(
|
|
96499
|
+
(command) => ({
|
|
96500
|
+
command,
|
|
96501
|
+
booleanOptions: /* @__PURE__ */ new Set(["--force", "-f"]),
|
|
96502
|
+
valueOptions: /* @__PURE__ */ new Set(["--org"]),
|
|
96503
|
+
explicitBooleanValues: true,
|
|
96504
|
+
booleanAliases: { "-f": "--force" }
|
|
96505
|
+
})
|
|
96506
|
+
),
|
|
96247
96507
|
{ command: ["quota", "status"], booleanOptions: /* @__PURE__ */ new Set(["--json"]), valueOptions: /* @__PURE__ */ new Set(["--org"]), explicitBooleanValues: true },
|
|
96248
|
-
...["list", "get", "
|
|
96249
|
-
command
|
|
96250
|
-
|
|
96251
|
-
|
|
96252
|
-
|
|
96253
|
-
|
|
96254
|
-
|
|
96255
|
-
|
|
96256
|
-
|
|
96257
|
-
|
|
96258
|
-
|
|
96259
|
-
|
|
96260
|
-
|
|
96261
|
-
|
|
96508
|
+
...["list", "get", "enable", "disable"].map(
|
|
96509
|
+
(command) => ({
|
|
96510
|
+
command: ["agent", command],
|
|
96511
|
+
booleanOptions: new Set(["list", "get"].includes(command) ? ["--json"] : []),
|
|
96512
|
+
valueOptions: /* @__PURE__ */ new Set(["--org"]),
|
|
96513
|
+
explicitBooleanValues: true
|
|
96514
|
+
})
|
|
96515
|
+
),
|
|
96516
|
+
...["create", "update", "delete", "share", "templates"].map(
|
|
96517
|
+
(command) => ({
|
|
96518
|
+
command: ["admin", "agent", command],
|
|
96519
|
+
booleanOptions: new Set(command === "delete" ? ["--force", "-f"] : []),
|
|
96520
|
+
valueOptions: /* @__PURE__ */ new Set(["--org"]),
|
|
96521
|
+
explicitBooleanValues: true,
|
|
96522
|
+
booleanAliases: { "-f": "--force" }
|
|
96523
|
+
})
|
|
96524
|
+
),
|
|
96525
|
+
...["mkdir", "rename"].map(
|
|
96526
|
+
(command) => ({
|
|
96527
|
+
command: ["drive", command],
|
|
96528
|
+
booleanOptions: /* @__PURE__ */ new Set(),
|
|
96529
|
+
valueOptions: /* @__PURE__ */ new Set(["--org"])
|
|
96530
|
+
})
|
|
96531
|
+
),
|
|
96532
|
+
...["create", "update", "enable", "disable"].map(
|
|
96533
|
+
(command) => ({
|
|
96534
|
+
command: ["automation", command],
|
|
96535
|
+
booleanOptions: /* @__PURE__ */ new Set(),
|
|
96536
|
+
valueOptions: /* @__PURE__ */ new Set(["--org"])
|
|
96537
|
+
})
|
|
96538
|
+
),
|
|
96539
|
+
...["list", "get", "create", "update", "rename", "delete", "set-default", "unset-default"].map(
|
|
96540
|
+
(command) => ({
|
|
96541
|
+
command: ["admin", "preset", command],
|
|
96542
|
+
booleanOptions: new Set(
|
|
96543
|
+
command === "delete" ? ["--force", "-f"] : ["list", "get"].includes(command) ? ["--json"] : []
|
|
96544
|
+
),
|
|
96545
|
+
valueOptions: /* @__PURE__ */ new Set(["--org", ...command === "list" ? ["--page", "--pageSize"] : []]),
|
|
96546
|
+
explicitBooleanValues: true,
|
|
96547
|
+
booleanAliases: { "-f": "--force" }
|
|
96548
|
+
})
|
|
96549
|
+
),
|
|
96550
|
+
...["invite", "remove-member", "update-member-role"].map(
|
|
96551
|
+
(command) => ({
|
|
96552
|
+
command: ["admin", "org", command],
|
|
96553
|
+
booleanOptions: new Set(command === "remove-member" ? ["--force", "-f"] : []),
|
|
96554
|
+
valueOptions: /* @__PURE__ */ new Set(["--org", ...command !== "remove-member" ? ["--role"] : []]),
|
|
96555
|
+
explicitBooleanValues: true,
|
|
96556
|
+
booleanAliases: { "-f": "--force" }
|
|
96557
|
+
})
|
|
96558
|
+
),
|
|
96262
96559
|
{
|
|
96263
96560
|
command: ["org", "exit"],
|
|
96264
96561
|
booleanOptions: /* @__PURE__ */ new Set(["--force", "-f"]),
|
|
@@ -96266,12 +96563,14 @@ const trailingOptionSpecs = [
|
|
|
96266
96563
|
explicitBooleanValues: true,
|
|
96267
96564
|
booleanAliases: { "-f": "--force" }
|
|
96268
96565
|
},
|
|
96269
|
-
...["list", "get"].map(
|
|
96270
|
-
command
|
|
96271
|
-
|
|
96272
|
-
|
|
96273
|
-
|
|
96274
|
-
|
|
96566
|
+
...["list", "get"].map(
|
|
96567
|
+
(command) => ({
|
|
96568
|
+
command: ["automation", command],
|
|
96569
|
+
booleanOptions: /* @__PURE__ */ new Set(["--json"]),
|
|
96570
|
+
valueOptions: /* @__PURE__ */ new Set(["--org", ...command === "list" ? ["--name"] : []]),
|
|
96571
|
+
explicitBooleanValues: true
|
|
96572
|
+
})
|
|
96573
|
+
),
|
|
96275
96574
|
{
|
|
96276
96575
|
command: ["automation", "delete"],
|
|
96277
96576
|
booleanOptions: /* @__PURE__ */ new Set(["--force", "-f"]),
|
|
@@ -96282,7 +96581,9 @@ const trailingOptionSpecs = [
|
|
|
96282
96581
|
{
|
|
96283
96582
|
command: ["drive", "delete"],
|
|
96284
96583
|
booleanOptions: /* @__PURE__ */ new Set(["--force", "-f"]),
|
|
96285
|
-
valueOptions: /* @__PURE__ */ new Set(["--org"])
|
|
96584
|
+
valueOptions: /* @__PURE__ */ new Set(["--org"]),
|
|
96585
|
+
explicitBooleanValues: true,
|
|
96586
|
+
booleanAliases: { "-f": "--force" }
|
|
96286
96587
|
},
|
|
96287
96588
|
{
|
|
96288
96589
|
command: ["automation", "history"],
|
|
@@ -96331,8 +96632,11 @@ const normalizeTrailingOptions = (args, spec) => {
|
|
|
96331
96632
|
continue;
|
|
96332
96633
|
}
|
|
96333
96634
|
if (isValueOption(arg, spec)) {
|
|
96334
|
-
options.push(arg);
|
|
96335
96635
|
const nextArg = args[index + 1];
|
|
96636
|
+
if (!arg.includes("=") && (nextArg === void 0 || nextArg.startsWith("-"))) {
|
|
96637
|
+
return [...args];
|
|
96638
|
+
}
|
|
96639
|
+
options.push(arg);
|
|
96336
96640
|
if (!arg.includes("=") && nextArg !== void 0 && !nextArg.startsWith("-")) {
|
|
96337
96641
|
index += 1;
|
|
96338
96642
|
options.push(nextArg);
|
|
@@ -96483,22 +96787,26 @@ const createCommand$2 = make$4(
|
|
|
96483
96787
|
})
|
|
96484
96788
|
).pipe(withDescription("Create an installed agent from a JSON file"));
|
|
96485
96789
|
|
|
96790
|
+
const requireConfirmation = (force, action) => force ? _void : fail$3(
|
|
96791
|
+
new ApiError({
|
|
96792
|
+
code: "CLI_CONFIRMATION_REQUIRED",
|
|
96793
|
+
outcome: "not-dispatched",
|
|
96794
|
+
message: `${action} was not performed. Use --force (-f) to confirm.`
|
|
96795
|
+
})
|
|
96796
|
+
);
|
|
96797
|
+
|
|
96486
96798
|
const agentIdArg$5 = text$2({ name: "id" }).pipe(withDescription$5("Agent ID to delete"));
|
|
96487
96799
|
const forceOption$8 = boolean("force").pipe(
|
|
96488
96800
|
withAlias("f"),
|
|
96489
|
-
withDescription$3("
|
|
96801
|
+
withDescription$3("Confirm permanent deletion")
|
|
96490
96802
|
);
|
|
96491
96803
|
const deleteCommand$6 = make$4(
|
|
96492
96804
|
"delete",
|
|
96493
96805
|
{ agentId: agentIdArg$5, org: orgOption, force: forceOption$8 },
|
|
96494
96806
|
({ agentId, org, force }) => gen(function* () {
|
|
96807
|
+
yield* requireConfirmation(force, "Agent deletion");
|
|
96495
96808
|
const api = yield* ApiService;
|
|
96496
96809
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
96497
|
-
if (!force) {
|
|
96498
|
-
yield* log(`Warning: This will permanently delete agent "${agentId}".`);
|
|
96499
|
-
yield* log("Use --force to skip this confirmation.");
|
|
96500
|
-
return;
|
|
96501
|
-
}
|
|
96502
96810
|
yield* log(`Deleting agent ${agentId}...`);
|
|
96503
96811
|
yield* api.deleteInstalledAgent(orgSlug, agentId).pipe(
|
|
96504
96812
|
catchTag(
|
|
@@ -96887,19 +97195,15 @@ const availableCommand = make$4(
|
|
|
96887
97195
|
const integrationIdArg$4 = text$2({ name: "id" }).pipe(withDescription$5("Integration ID to delete"));
|
|
96888
97196
|
const forceOption$7 = boolean("force").pipe(
|
|
96889
97197
|
withAlias("f"),
|
|
96890
|
-
withDescription$3("
|
|
97198
|
+
withDescription$3("Confirm permanent deletion")
|
|
96891
97199
|
);
|
|
96892
97200
|
const deleteCommand$5 = make$4(
|
|
96893
97201
|
"delete",
|
|
96894
97202
|
{ integrationId: integrationIdArg$4, org: orgOption, force: forceOption$7 },
|
|
96895
97203
|
({ integrationId, org, force }) => gen(function* () {
|
|
97204
|
+
yield* requireConfirmation(force, "Integration deletion");
|
|
96896
97205
|
const api = yield* ApiService;
|
|
96897
97206
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
96898
|
-
if (!force) {
|
|
96899
|
-
yield* log(`Warning: This will permanently delete integration "${integrationId}".`);
|
|
96900
|
-
yield* log("Use --force to skip this confirmation.");
|
|
96901
|
-
return;
|
|
96902
|
-
}
|
|
96903
97207
|
yield* log(`Deleting integration ${integrationId}...`);
|
|
96904
97208
|
yield* api.deleteIntegration(orgSlug, integrationId).pipe(
|
|
96905
97209
|
catchTag(
|
|
@@ -97158,13 +97462,14 @@ const emailsArg$1 = text$2({ name: "email" }).pipe(
|
|
|
97158
97462
|
);
|
|
97159
97463
|
const forceOption$6 = boolean("force").pipe(
|
|
97160
97464
|
withAlias("f"),
|
|
97161
|
-
withDescription$3("
|
|
97465
|
+
withDescription$3("Confirm member removal"),
|
|
97162
97466
|
withDefault(false)
|
|
97163
97467
|
);
|
|
97164
97468
|
const removeMemberCommand = make$4(
|
|
97165
97469
|
"remove-member",
|
|
97166
97470
|
{ emails: emailsArg$1, org: orgOption, force: forceOption$6 },
|
|
97167
97471
|
({ emails, org, force }) => gen(function* () {
|
|
97472
|
+
yield* requireConfirmation(force, "Member removal");
|
|
97168
97473
|
const api = yield* ApiService;
|
|
97169
97474
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
97170
97475
|
const emailList = Array.from(emails);
|
|
@@ -97172,11 +97477,6 @@ const removeMemberCommand = make$4(
|
|
|
97172
97477
|
yield* error$1("Please provide at least one email address to remove.");
|
|
97173
97478
|
return yield* fail$3(new Error("No email addresses provided"));
|
|
97174
97479
|
}
|
|
97175
|
-
if (!force) {
|
|
97176
|
-
yield* log(`Warning: This will remove ${emailList.join(", ")} from the organization.`);
|
|
97177
|
-
yield* log("Use --force (-f) to confirm.");
|
|
97178
|
-
return;
|
|
97179
|
-
}
|
|
97180
97480
|
const membersResult = yield* api.listOrgMembers(orgSlug).pipe(
|
|
97181
97481
|
catchTag(
|
|
97182
97482
|
"NotLoggedInError",
|
|
@@ -97342,7 +97642,7 @@ const createCommand$1 = make$4(
|
|
|
97342
97642
|
|
|
97343
97643
|
const idArg$7 = text$2({ name: "id" }).pipe(withDescription$5("Preset ID"));
|
|
97344
97644
|
const forceOption$5 = boolean("force").pipe(
|
|
97345
|
-
withDescription$3("
|
|
97645
|
+
withDescription$3("Confirm permanent deletion"),
|
|
97346
97646
|
withAlias("f"),
|
|
97347
97647
|
withDefault(false)
|
|
97348
97648
|
);
|
|
@@ -97350,13 +97650,9 @@ const deleteCommand$4 = make$4(
|
|
|
97350
97650
|
"delete",
|
|
97351
97651
|
{ id: idArg$7, org: orgOption, force: forceOption$5 },
|
|
97352
97652
|
({ id, org, force }) => gen(function* () {
|
|
97653
|
+
yield* requireConfirmation(force, "Preset deletion");
|
|
97353
97654
|
const api = yield* ApiService;
|
|
97354
97655
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
97355
|
-
if (!force) {
|
|
97356
|
-
yield* log(`Warning: This will permanently delete preset "${id}".`);
|
|
97357
|
-
yield* log("Use --force (-f) to skip this confirmation.");
|
|
97358
|
-
return;
|
|
97359
|
-
}
|
|
97360
97656
|
yield* api.deletePreset(id, orgSlug).pipe(
|
|
97361
97657
|
catchTag(
|
|
97362
97658
|
"NotLoggedInError",
|
|
@@ -97695,18 +97991,62 @@ const presetCommand = make$4("preset", {}).pipe(
|
|
|
97695
97991
|
withSubcommands(presetSubcommands)
|
|
97696
97992
|
);
|
|
97697
97993
|
|
|
97994
|
+
const cursorOption = text("cursor").pipe(
|
|
97995
|
+
withDescription$3("Continue from the previous page nextCursor"),
|
|
97996
|
+
optional
|
|
97997
|
+
);
|
|
97998
|
+
const countOption = integer("count").pipe(
|
|
97999
|
+
withDescription$3("Items per page (1\u2013200)"),
|
|
98000
|
+
optional
|
|
98001
|
+
);
|
|
98002
|
+
const jsonPageOption = boolean("json-page").pipe(
|
|
98003
|
+
withDescription$3("Output the full page, including pagination metadata"),
|
|
98004
|
+
withDefault(false)
|
|
98005
|
+
);
|
|
98006
|
+
function validatePageOptions(count, json, jsonPage, maximum = 200, option = "--count") {
|
|
98007
|
+
if (count !== void 0 && (count < 1 || count > maximum)) {
|
|
98008
|
+
return fail$3(
|
|
98009
|
+
new ApiError({
|
|
98010
|
+
message: `${option} must be between 1 and ${maximum}.`,
|
|
98011
|
+
code: "CLI_INVALID_ARGUMENT",
|
|
98012
|
+
outcome: "not-dispatched"
|
|
98013
|
+
})
|
|
98014
|
+
);
|
|
98015
|
+
}
|
|
98016
|
+
if (json && jsonPage) {
|
|
98017
|
+
return fail$3(
|
|
98018
|
+
new ApiError({
|
|
98019
|
+
message: "Choose either --json or --json-page.",
|
|
98020
|
+
code: "CLI_INVALID_ARGUMENT",
|
|
98021
|
+
outcome: "not-dispatched"
|
|
98022
|
+
})
|
|
98023
|
+
);
|
|
98024
|
+
}
|
|
98025
|
+
return _void;
|
|
98026
|
+
}
|
|
98027
|
+
const reportNextPage = (hasNext) => hasNext ? error$1(
|
|
98028
|
+
"More results are available. Use --json-page to read nextCursor, then pass it with --cursor using the same filters."
|
|
98029
|
+
) : _void;
|
|
98030
|
+
|
|
98031
|
+
const limitOption$2 = integer("limit").pipe(withDescription$3("Items per page (1\u2013100)"), optional);
|
|
97698
98032
|
const searchOption$3 = text("search").pipe(
|
|
97699
98033
|
withDescription$3("Search built-in skills by name"),
|
|
97700
98034
|
optional
|
|
97701
98035
|
);
|
|
97702
98036
|
const makeBuiltInCommand = (listSkills = (api, orgSlug, options) => api.listBuiltInSkills(orgSlug, options), description = "List built-in skills from the library") => make$4(
|
|
97703
98037
|
"built-in",
|
|
97704
|
-
{ org: orgOption, search: searchOption$3 },
|
|
97705
|
-
({ org, search }) => gen(function* () {
|
|
98038
|
+
{ org: orgOption, search: searchOption$3, limit: limitOption$2, cursor: cursorOption, jsonPage: jsonPageOption },
|
|
98039
|
+
({ org, search, limit, cursor, jsonPage }) => gen(function* () {
|
|
98040
|
+
const limitValue = limit._tag === "Some" ? limit.value : void 0;
|
|
98041
|
+
yield* validatePageOptions(limitValue, false, jsonPage, 100, "--limit");
|
|
97706
98042
|
const api = yield* ApiService;
|
|
97707
98043
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
97708
98044
|
const searchValue = search._tag === "Some" ? search.value : void 0;
|
|
97709
|
-
const result = yield* listSkills(api, orgSlug, {
|
|
98045
|
+
const result = yield* listSkills(api, orgSlug, {
|
|
98046
|
+
search: searchValue,
|
|
98047
|
+
limit: limitValue,
|
|
98048
|
+
cursor: cursor._tag === "Some" ? cursor.value : void 0
|
|
98049
|
+
}).pipe(
|
|
97710
98050
|
catchTag(
|
|
97711
98051
|
"NotLoggedInError",
|
|
97712
98052
|
(e) => gen(function* () {
|
|
@@ -97722,6 +98062,11 @@ const makeBuiltInCommand = (listSkills = (api, orgSlug, options) => api.listBuil
|
|
|
97722
98062
|
})
|
|
97723
98063
|
)
|
|
97724
98064
|
);
|
|
98065
|
+
if (jsonPage) {
|
|
98066
|
+
yield* log(jsonFormat({ ...result, nextCursor: result.nextCursor ?? null }));
|
|
98067
|
+
return;
|
|
98068
|
+
}
|
|
98069
|
+
yield* reportNextPage(result.hasNext);
|
|
97725
98070
|
if (result.items.length === 0) {
|
|
97726
98071
|
yield* log("No built-in skills found.");
|
|
97727
98072
|
return;
|
|
@@ -97740,9 +98085,6 @@ const makeBuiltInCommand = (listSkills = (api, orgSlug, options) => api.listBuil
|
|
|
97740
98085
|
yield* log(` Updated: ${formatDate(skill.updatedAt)}`);
|
|
97741
98086
|
yield* log("");
|
|
97742
98087
|
}
|
|
97743
|
-
if (result.hasNext) {
|
|
97744
|
-
yield* log("(More built-in skills available.)");
|
|
97745
|
-
}
|
|
97746
98088
|
})
|
|
97747
98089
|
).pipe(withDescription(description));
|
|
97748
98090
|
const builtInCommand = makeBuiltInCommand();
|
|
@@ -98118,7 +98460,7 @@ const jsonOption$e = boolean("json").pipe(
|
|
|
98118
98460
|
const skillIdArg$2 = text$2({ name: "id" }).pipe(withDescription$5("Skill ID"));
|
|
98119
98461
|
const forceOption$4 = boolean("force").pipe(
|
|
98120
98462
|
withAlias("f"),
|
|
98121
|
-
withDescription$3("
|
|
98463
|
+
withDescription$3("Confirm permanent deletion")
|
|
98122
98464
|
);
|
|
98123
98465
|
const fileArg$2 = file({ name: "file", exists: "yes" }).pipe(
|
|
98124
98466
|
withDescription$5("Path to the skill file (.zip or .skill)")
|
|
@@ -98128,8 +98470,16 @@ const overwriteOption$1 = boolean("overwrite").pipe(
|
|
|
98128
98470
|
);
|
|
98129
98471
|
const listCommand$8 = make$4(
|
|
98130
98472
|
"list",
|
|
98131
|
-
{
|
|
98132
|
-
|
|
98473
|
+
{
|
|
98474
|
+
org: orgOption,
|
|
98475
|
+
search: searchOption$2,
|
|
98476
|
+
page: pageOption$2,
|
|
98477
|
+
pageSize: pageSizeOption,
|
|
98478
|
+
json: jsonOption$e,
|
|
98479
|
+
jsonPage: jsonPageOption
|
|
98480
|
+
},
|
|
98481
|
+
({ org, search, page, pageSize, json, jsonPage }) => gen(function* () {
|
|
98482
|
+
yield* validatePageOptions(void 0, json, jsonPage);
|
|
98133
98483
|
const api = yield* ApiService;
|
|
98134
98484
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
98135
98485
|
const result = yield* api.listAdminSkills(orgSlug, {
|
|
@@ -98152,6 +98502,15 @@ const listCommand$8 = make$4(
|
|
|
98152
98502
|
})
|
|
98153
98503
|
)
|
|
98154
98504
|
);
|
|
98505
|
+
if (jsonPage) {
|
|
98506
|
+
yield* log(jsonFormat(result));
|
|
98507
|
+
return;
|
|
98508
|
+
}
|
|
98509
|
+
if (result.pagination.page * result.pagination.pageSize < result.pagination.total) {
|
|
98510
|
+
yield* error$1(
|
|
98511
|
+
"More results are available. Use --json-page to read pagination, then pass --page using the same filters."
|
|
98512
|
+
);
|
|
98513
|
+
}
|
|
98155
98514
|
if (json) {
|
|
98156
98515
|
yield* log(jsonFormat(result.list));
|
|
98157
98516
|
return;
|
|
@@ -98338,13 +98697,9 @@ const deleteCommand$3 = make$4(
|
|
|
98338
98697
|
"delete",
|
|
98339
98698
|
{ skillId: skillIdArg$2, org: orgOption, force: forceOption$4 },
|
|
98340
98699
|
({ skillId, org, force }) => gen(function* () {
|
|
98700
|
+
yield* requireConfirmation(force, "Organization skill deletion");
|
|
98341
98701
|
const api = yield* ApiService;
|
|
98342
98702
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
98343
|
-
if (!force) {
|
|
98344
|
-
yield* log(`Warning: This will permanently delete organization skill "${skillId}".`);
|
|
98345
|
-
yield* log("Use --force to skip this confirmation.");
|
|
98346
|
-
return;
|
|
98347
|
-
}
|
|
98348
98703
|
yield* api.deleteAdminSkill(orgSlug, skillId).pipe(
|
|
98349
98704
|
catchTag(
|
|
98350
98705
|
"ApiError",
|
|
@@ -99274,7 +99629,7 @@ function saveOrganization(org, configService) {
|
|
|
99274
99629
|
});
|
|
99275
99630
|
}
|
|
99276
99631
|
function toSelectionError(error) {
|
|
99277
|
-
return
|
|
99632
|
+
return error;
|
|
99278
99633
|
}
|
|
99279
99634
|
function findOrganizationBySlug(organizations, slug) {
|
|
99280
99635
|
return organizations?.find((org) => org.slug === slug);
|
|
@@ -99286,17 +99641,27 @@ const getOrganizationBySlug = (slug) => gen(function* () {
|
|
|
99286
99641
|
catchTag("ApiError", (e) => fail$3(toSelectionError(e)))
|
|
99287
99642
|
);
|
|
99288
99643
|
});
|
|
99289
|
-
const saveSelectedOrganization = (slug, knownOrganizations) => gen(function* () {
|
|
99644
|
+
const saveSelectedOrganization = (slug, knownOrganizations, initialSession) => gen(function* () {
|
|
99290
99645
|
const configService = yield* ConfigService;
|
|
99646
|
+
const credentials = yield* CredentialService;
|
|
99647
|
+
const session = initialSession ?? (yield* promise$1(() => credentials.withLock(() => captureAuthSession(configService, credentials))));
|
|
99291
99648
|
const org = findOrganizationBySlug(knownOrganizations, slug) ?? (yield* getOrganizationBySlug(slug));
|
|
99292
99649
|
if (org.ipBlocked) {
|
|
99293
99650
|
return yield* fail$3(new Error(`Organization "${slug}" is blocked due to IP restrictions.`));
|
|
99294
99651
|
}
|
|
99295
|
-
|
|
99652
|
+
yield* tryPromise({
|
|
99653
|
+
try: () => credentials.withLock(() => {
|
|
99654
|
+
assertAuthSession(session, configService, credentials);
|
|
99655
|
+
saveOrganization(org, configService);
|
|
99656
|
+
}),
|
|
99657
|
+
catch: (error) => toError(error, "Organization selection failed")
|
|
99658
|
+
});
|
|
99296
99659
|
return org;
|
|
99297
99660
|
});
|
|
99298
|
-
const startOrganizationSelectionBrowserFlow = (knownOrganizations) => gen(function* () {
|
|
99661
|
+
const startOrganizationSelectionBrowserFlow = (knownOrganizations, initialSession) => gen(function* () {
|
|
99299
99662
|
const config = yield* ConfigService;
|
|
99663
|
+
const credentials = yield* CredentialService;
|
|
99664
|
+
const session = initialSession ?? (yield* promise$1(() => credentials.withLock(() => captureAuthSession(config, credentials))));
|
|
99300
99665
|
const appBaseUrl = yield* try_({
|
|
99301
99666
|
try: () => requireAppBaseUrl(config.load()),
|
|
99302
99667
|
catch: (error) => toError(error, "App URL validation failed")
|
|
@@ -99338,11 +99703,14 @@ const startOrganizationSelectionBrowserFlow = (knownOrganizations) => gen(functi
|
|
|
99338
99703
|
_await(deferred),
|
|
99339
99704
|
sleep$1("5 minutes").pipe(flatMap$5(() => fail$3(new Error(ORG_SELECTION_TIMEOUT_MESSAGE))))
|
|
99340
99705
|
);
|
|
99341
|
-
return yield* saveSelectedOrganization(callback.slug, knownOrganizations);
|
|
99706
|
+
return yield* saveSelectedOrganization(callback.slug, knownOrganizations, session);
|
|
99342
99707
|
}).pipe(ensuring$1(promise$1(() => closeServer())));
|
|
99343
99708
|
});
|
|
99344
99709
|
const selectOrganizationAfterLogin = gen(function* () {
|
|
99345
99710
|
const api = yield* ApiService;
|
|
99711
|
+
const config = yield* ConfigService;
|
|
99712
|
+
const credentials = yield* CredentialService;
|
|
99713
|
+
const session = yield* promise$1(() => credentials.withLock(() => captureAuthSession(config, credentials)));
|
|
99346
99714
|
yield* log("Selecting organization...");
|
|
99347
99715
|
const organizations = yield* api.listOrganizations().pipe(
|
|
99348
99716
|
catchTag("NotLoggedInError", (e) => fail$3(toSelectionError(e))),
|
|
@@ -99356,11 +99724,11 @@ const selectOrganizationAfterLogin = gen(function* () {
|
|
|
99356
99724
|
if (!org2) {
|
|
99357
99725
|
return yield* fail$3(new Error(NO_ORGANIZATIONS_LOGIN_MESSAGE));
|
|
99358
99726
|
}
|
|
99359
|
-
const selectedOrg = yield* saveSelectedOrganization(org2.slug, organizations);
|
|
99727
|
+
const selectedOrg = yield* saveSelectedOrganization(org2.slug, organizations, session);
|
|
99360
99728
|
yield* log(`\u2713 Selected organization: ${selectedOrg.name} (${selectedOrg.slug})`);
|
|
99361
99729
|
return selectedOrg;
|
|
99362
99730
|
}
|
|
99363
|
-
const org = yield* startOrganizationSelectionBrowserFlow(organizations).pipe(
|
|
99731
|
+
const org = yield* startOrganizationSelectionBrowserFlow(organizations, session).pipe(
|
|
99364
99732
|
catchAll((error) => {
|
|
99365
99733
|
if (error.message === ORG_SELECTION_TIMEOUT_MESSAGE) {
|
|
99366
99734
|
return fail$3(new Error(`${ORG_SELECTION_TIMEOUT_MESSAGE}
|
|
@@ -99425,19 +99793,25 @@ const loginCommand = make$4(
|
|
|
99425
99793
|
() => loginEffect(startOAuthFlow, selectOrganizationAfterLogin)
|
|
99426
99794
|
).pipe(withDescription("Log in to AIP via browser-based OAuth"));
|
|
99427
99795
|
|
|
99428
|
-
const
|
|
99429
|
-
|
|
99430
|
-
{
|
|
99431
|
-
|
|
99432
|
-
|
|
99433
|
-
|
|
99434
|
-
|
|
99435
|
-
|
|
99436
|
-
|
|
99437
|
-
|
|
99438
|
-
|
|
99439
|
-
|
|
99440
|
-
|
|
99796
|
+
const logoutEffect = gen(function* () {
|
|
99797
|
+
const credentials = yield* CredentialService;
|
|
99798
|
+
const hadCredentials = yield* tryPromise({
|
|
99799
|
+
try: () => credentials.withLock(() => {
|
|
99800
|
+
const existed = credentials.load() !== null;
|
|
99801
|
+
credentials.clear();
|
|
99802
|
+
return existed;
|
|
99803
|
+
}),
|
|
99804
|
+
catch: (error) => error instanceof Error ? error : new Error("Could not clear saved credentials.")
|
|
99805
|
+
});
|
|
99806
|
+
if (!hadCredentials) {
|
|
99807
|
+
yield* log("Not logged in.");
|
|
99808
|
+
return;
|
|
99809
|
+
}
|
|
99810
|
+
yield* log("\u2713 Logged out successfully.");
|
|
99811
|
+
});
|
|
99812
|
+
const logoutCommand = make$4("logout", {}, () => logoutEffect).pipe(
|
|
99813
|
+
withDescription("Log out and clear stored credentials")
|
|
99814
|
+
);
|
|
99441
99815
|
|
|
99442
99816
|
const refreshEffect = () => gen(function* () {
|
|
99443
99817
|
const api = yield* ApiService;
|
|
@@ -99618,19 +99992,15 @@ const createCommand = make$4(
|
|
|
99618
99992
|
const automationIdArg$6 = text$2({ name: "id" }).pipe(withDescription$5("Automation ID to delete"));
|
|
99619
99993
|
const forceOption$3 = boolean("force").pipe(
|
|
99620
99994
|
withAlias("f"),
|
|
99621
|
-
withDescription$3("
|
|
99995
|
+
withDescription$3("Confirm permanent deletion")
|
|
99622
99996
|
);
|
|
99623
99997
|
const deleteCommand$2 = make$4(
|
|
99624
99998
|
"delete",
|
|
99625
99999
|
{ automationId: automationIdArg$6, org: orgOption, force: forceOption$3 },
|
|
99626
100000
|
({ automationId, org, force }) => gen(function* () {
|
|
100001
|
+
yield* requireConfirmation(force, "Automation deletion");
|
|
99627
100002
|
const api = yield* ApiService;
|
|
99628
100003
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
99629
|
-
if (!force) {
|
|
99630
|
-
yield* log(`Warning: This will permanently delete automation "${automationId}".`);
|
|
99631
|
-
yield* log("Use --force to skip this confirmation.");
|
|
99632
|
-
return;
|
|
99633
|
-
}
|
|
99634
100004
|
yield* log(`Deleting automation ${automationId}...`);
|
|
99635
100005
|
yield* api.deleteAutomation(orgSlug, automationId).pipe(
|
|
99636
100006
|
catchTag(
|
|
@@ -100157,11 +100527,19 @@ const jsonOption$8 = boolean("json").pipe(
|
|
|
100157
100527
|
);
|
|
100158
100528
|
const listCommand$5 = make$4(
|
|
100159
100529
|
"list",
|
|
100160
|
-
{
|
|
100161
|
-
|
|
100530
|
+
{
|
|
100531
|
+
org: orgOption,
|
|
100532
|
+
json: jsonOption$8,
|
|
100533
|
+
cursor: cursorOption,
|
|
100534
|
+
jsonPage: jsonPageOption
|
|
100535
|
+
},
|
|
100536
|
+
({ org, json, cursor, jsonPage }) => gen(function* () {
|
|
100537
|
+
yield* validatePageOptions(void 0, json, jsonPage);
|
|
100162
100538
|
const api = yield* ApiService;
|
|
100163
100539
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
100164
|
-
const result = yield* api.listConversations(orgSlug
|
|
100540
|
+
const result = yield* api.listConversations(orgSlug, {
|
|
100541
|
+
cursor: cursor._tag === "Some" ? cursor.value : void 0
|
|
100542
|
+
}).pipe(
|
|
100165
100543
|
catchTag(
|
|
100166
100544
|
"NotLoggedInError",
|
|
100167
100545
|
(e) => gen(function* () {
|
|
@@ -100177,10 +100555,16 @@ const listCommand$5 = make$4(
|
|
|
100177
100555
|
})
|
|
100178
100556
|
)
|
|
100179
100557
|
);
|
|
100558
|
+
if (jsonPage) {
|
|
100559
|
+
yield* log(jsonFormat({ ...result, nextCursor: result.nextCursor ?? null }));
|
|
100560
|
+
return;
|
|
100561
|
+
}
|
|
100180
100562
|
if (json) {
|
|
100181
100563
|
yield* log(jsonFormat(result.conversations));
|
|
100564
|
+
yield* reportNextPage(result.nextCursor != null);
|
|
100182
100565
|
return;
|
|
100183
100566
|
}
|
|
100567
|
+
yield* reportNextPage(result.nextCursor != null);
|
|
100184
100568
|
if (result.conversations.length === 0) {
|
|
100185
100569
|
yield* log("No conversations found.");
|
|
100186
100570
|
return;
|
|
@@ -100194,9 +100578,6 @@ const listCommand$5 = make$4(
|
|
|
100194
100578
|
yield* log(` Updated: ${formatDate(conv.updatedAt)}`);
|
|
100195
100579
|
yield* log("");
|
|
100196
100580
|
}
|
|
100197
|
-
if (result.nextCursor) {
|
|
100198
|
-
yield* log("(more available)");
|
|
100199
|
-
}
|
|
100200
100581
|
})
|
|
100201
100582
|
).pipe(withDescription("List conversations"));
|
|
100202
100583
|
|
|
@@ -100427,20 +100808,24 @@ const appUrlOption = text("app-url").pipe(
|
|
|
100427
100808
|
const setConfigEffect = (input) => gen(function* () {
|
|
100428
100809
|
const configService = yield* ConfigService;
|
|
100429
100810
|
const credentials = yield* CredentialService;
|
|
100430
|
-
const currentConfig = yield* sync$1(() => configService.load());
|
|
100431
100811
|
const appBaseUrl = yield* try_({
|
|
100432
100812
|
try: () => normalizeAppUrl(input.appUrl),
|
|
100433
100813
|
catch: (error) => error instanceof Error ? error : new Error(String(error))
|
|
100434
100814
|
});
|
|
100435
|
-
const shouldClearSession =
|
|
100436
|
-
|
|
100437
|
-
|
|
100438
|
-
|
|
100439
|
-
|
|
100440
|
-
|
|
100441
|
-
|
|
100442
|
-
|
|
100443
|
-
|
|
100815
|
+
const { shouldClearSession, savedConfig } = yield* tryPromise({
|
|
100816
|
+
try: () => credentials.withLock(() => {
|
|
100817
|
+
const currentConfig = configService.load();
|
|
100818
|
+
const shouldClearSession2 = currentConfig.appBaseUrl !== appBaseUrl;
|
|
100819
|
+
const savedConfig2 = {
|
|
100820
|
+
appBaseUrl,
|
|
100821
|
+
currentOrganization: shouldClearSession2 ? void 0 : currentConfig.currentOrganization
|
|
100822
|
+
};
|
|
100823
|
+
if (shouldClearSession2) credentials.clear();
|
|
100824
|
+
configService.save(savedConfig2, currentConfig);
|
|
100825
|
+
return { shouldClearSession: shouldClearSession2, savedConfig: savedConfig2 };
|
|
100826
|
+
}),
|
|
100827
|
+
catch: (error) => error instanceof Error ? error : new Error("Could not save app configuration.")
|
|
100828
|
+
});
|
|
100444
100829
|
yield* log("\n\u2713 Saved app configuration");
|
|
100445
100830
|
yield* log(` App URL: ${appBaseUrl}`);
|
|
100446
100831
|
if (shouldClearSession) {
|
|
@@ -100533,23 +100918,18 @@ const entryIdsArg = text$2({ name: "id" }).pipe(
|
|
|
100533
100918
|
);
|
|
100534
100919
|
const forceOption$2 = boolean("force").pipe(
|
|
100535
100920
|
withAlias("f"),
|
|
100536
|
-
withDescription$3("
|
|
100921
|
+
withDescription$3("Confirm permanent deletion")
|
|
100537
100922
|
);
|
|
100538
100923
|
const deleteCommand$1 = make$4(
|
|
100539
100924
|
"delete",
|
|
100540
100925
|
{ entryIds: entryIdsArg, org: orgOption, force: forceOption$2 },
|
|
100541
100926
|
({ entryIds, org, force }) => gen(function* () {
|
|
100927
|
+
yield* requireConfirmation(force, "Drive entry deletion");
|
|
100542
100928
|
const api = yield* ApiService;
|
|
100543
100929
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
100544
100930
|
const ids = Array.from(entryIds);
|
|
100545
100931
|
if (ids.length === 0) {
|
|
100546
|
-
yield*
|
|
100547
|
-
return;
|
|
100548
|
-
}
|
|
100549
|
-
if (!force) {
|
|
100550
|
-
yield* log(`Warning: This will permanently delete ${ids.length} drive entry/entries.`);
|
|
100551
|
-
yield* log("Use --force to skip this confirmation.");
|
|
100552
|
-
return;
|
|
100932
|
+
return yield* fail$3(new ApiError({ message: "Provide at least one entry ID to delete.", code: "CLI_INVALID_ARGUMENT", outcome: "not-dispatched" }));
|
|
100553
100933
|
}
|
|
100554
100934
|
yield* log(`Deleting ${ids.length} drive entry/entries...`);
|
|
100555
100935
|
yield* api.deleteDriveEntries(orgSlug, ids).pipe(
|
|
@@ -100637,13 +101017,29 @@ File downloaded successfully!`);
|
|
|
100637
101017
|
})
|
|
100638
101018
|
).pipe(withDescription("Download a file from My Drive"));
|
|
100639
101019
|
|
|
101020
|
+
const parentOption = text("parent-id").pipe(
|
|
101021
|
+
withDescription$3("List entries in this folder (default: root)"),
|
|
101022
|
+
optional
|
|
101023
|
+
);
|
|
100640
101024
|
const listCommand$4 = make$4(
|
|
100641
101025
|
"list",
|
|
100642
|
-
{
|
|
100643
|
-
|
|
101026
|
+
{
|
|
101027
|
+
org: orgOption,
|
|
101028
|
+
count: countOption,
|
|
101029
|
+
cursor: cursorOption,
|
|
101030
|
+
parentId: parentOption,
|
|
101031
|
+
jsonPage: jsonPageOption
|
|
101032
|
+
},
|
|
101033
|
+
({ org, count, cursor, parentId, jsonPage }) => gen(function* () {
|
|
101034
|
+
const countValue = count._tag === "Some" ? count.value : void 0;
|
|
101035
|
+
yield* validatePageOptions(countValue, false, jsonPage);
|
|
100644
101036
|
const api = yield* ApiService;
|
|
100645
101037
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
100646
|
-
const result = yield* api.listDriveEntries(orgSlug
|
|
101038
|
+
const result = yield* api.listDriveEntries(orgSlug, {
|
|
101039
|
+
count: countValue,
|
|
101040
|
+
cursor: cursor._tag === "Some" ? cursor.value : void 0,
|
|
101041
|
+
parentId: parentId._tag === "Some" ? parentId.value : void 0
|
|
101042
|
+
}).pipe(
|
|
100647
101043
|
catchTag(
|
|
100648
101044
|
"NotLoggedInError",
|
|
100649
101045
|
(e) => gen(function* () {
|
|
@@ -100659,6 +101055,11 @@ const listCommand$4 = make$4(
|
|
|
100659
101055
|
})
|
|
100660
101056
|
)
|
|
100661
101057
|
);
|
|
101058
|
+
if (jsonPage) {
|
|
101059
|
+
yield* log(jsonFormat({ ...result, nextCursor: result.nextCursor ?? null }));
|
|
101060
|
+
return;
|
|
101061
|
+
}
|
|
101062
|
+
yield* reportNextPage(result.hasNext);
|
|
100662
101063
|
if (result.items.length === 0) {
|
|
100663
101064
|
yield* log("No files found in drive.");
|
|
100664
101065
|
return;
|
|
@@ -100672,9 +101073,6 @@ const listCommand$4 = make$4(
|
|
|
100672
101073
|
yield* log(` Modified: ${formatDate(entry.modifiedAt)}`);
|
|
100673
101074
|
yield* log("");
|
|
100674
101075
|
}
|
|
100675
|
-
if (result.hasNext) {
|
|
100676
|
-
yield* log("More drive entries are available. Re-run with future pagination support to continue.");
|
|
100677
|
-
}
|
|
100678
101076
|
})
|
|
100679
101077
|
).pipe(withDescription("List files in My Drive"));
|
|
100680
101078
|
|
|
@@ -101412,12 +101810,9 @@ const exitCommand = make$4(
|
|
|
101412
101810
|
"exit",
|
|
101413
101811
|
{ org: orgOption, force: forceOption$1 },
|
|
101414
101812
|
({ org, force }) => gen(function* () {
|
|
101813
|
+
yield* requireConfirmation(force, "Leaving the organization");
|
|
101415
101814
|
const api = yield* ApiService;
|
|
101416
101815
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
101417
|
-
if (!force) {
|
|
101418
|
-
yield* log("Use --force (-f) to confirm leaving the organization.");
|
|
101419
|
-
return;
|
|
101420
|
-
}
|
|
101421
101816
|
yield* api.exitOrg(orgSlug).pipe(
|
|
101422
101817
|
catchTag(
|
|
101423
101818
|
"NotLoggedInError",
|
|
@@ -101567,40 +101962,14 @@ const useCommand = make$4(
|
|
|
101567
101962
|
"use",
|
|
101568
101963
|
{ slug: slugArg },
|
|
101569
101964
|
({ slug }) => gen(function* () {
|
|
101570
|
-
const api = yield* ApiService;
|
|
101571
|
-
const configService = yield* ConfigService;
|
|
101572
101965
|
yield* log(`Selecting organization: ${slug}`);
|
|
101573
|
-
const org = yield*
|
|
101574
|
-
catchTag(
|
|
101575
|
-
"NotLoggedInError",
|
|
101576
|
-
(e) => gen(function* () {
|
|
101577
|
-
yield* error$1(e.message);
|
|
101578
|
-
return yield* fail$3(e);
|
|
101579
|
-
})
|
|
101580
|
-
),
|
|
101581
|
-
catchTag(
|
|
101582
|
-
"ApiError",
|
|
101583
|
-
(e) => gen(function* () {
|
|
101584
|
-
yield* error$1(`Failed to select organization: ${e.message}`);
|
|
101585
|
-
return yield* fail$3(e);
|
|
101586
|
-
})
|
|
101587
|
-
)
|
|
101588
|
-
);
|
|
101589
|
-
if (org.ipBlocked) {
|
|
101590
|
-
yield* error$1(`Organization "${slug}" is blocked due to IP restrictions.`);
|
|
101591
|
-
return;
|
|
101592
|
-
}
|
|
101593
|
-
configService.save({
|
|
101594
|
-
currentOrganization: {
|
|
101595
|
-
id: org.id,
|
|
101596
|
-
slug: org.slug,
|
|
101597
|
-
name: org.name
|
|
101598
|
-
}
|
|
101599
|
-
});
|
|
101966
|
+
const org = yield* saveSelectedOrganization(slug);
|
|
101600
101967
|
yield* log(`
|
|
101601
101968
|
Switched to organization: ${org.name} (${org.slug})`);
|
|
101602
101969
|
})
|
|
101603
|
-
).pipe(
|
|
101970
|
+
).pipe(
|
|
101971
|
+
withDescription('Select an organization by slug for subsequent commands. Use "aipctl org select" if you do not know the slug.')
|
|
101972
|
+
);
|
|
101604
101973
|
|
|
101605
101974
|
const orgCommandDescription = "Organization (list, current, use, select, members, capabilities, settings, exit)";
|
|
101606
101975
|
const orgSubcommands = [
|
|
@@ -101671,19 +102040,15 @@ const cloneCommand = make$4(
|
|
|
101671
102040
|
const skillIdArg$1 = text$2({ name: "id" }).pipe(withDescription$5("Skill ID to delete"));
|
|
101672
102041
|
const forceOption = boolean("force").pipe(
|
|
101673
102042
|
withAlias("f"),
|
|
101674
|
-
withDescription$3("
|
|
102043
|
+
withDescription$3("Confirm permanent deletion")
|
|
101675
102044
|
);
|
|
101676
102045
|
const deleteCommand = make$4(
|
|
101677
102046
|
"delete",
|
|
101678
102047
|
{ skillId: skillIdArg$1, org: orgOption, force: forceOption },
|
|
101679
102048
|
({ skillId, org, force }) => gen(function* () {
|
|
102049
|
+
yield* requireConfirmation(force, "Skill deletion");
|
|
101680
102050
|
const api = yield* ApiService;
|
|
101681
102051
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
101682
|
-
if (!force) {
|
|
101683
|
-
yield* log(`Warning: This will permanently delete skill "${skillId}".`);
|
|
101684
|
-
yield* log("Use --force to skip this confirmation.");
|
|
101685
|
-
return;
|
|
101686
|
-
}
|
|
101687
102052
|
yield* log(`Deleting skill ${skillId}...`);
|
|
101688
102053
|
yield* api.deleteSkill(orgSlug, skillId).pipe(
|
|
101689
102054
|
catchTag(
|
|
@@ -101792,12 +102157,18 @@ const searchOption$1 = text("search").pipe(
|
|
|
101792
102157
|
);
|
|
101793
102158
|
const libraryCommand = make$4(
|
|
101794
102159
|
"library",
|
|
101795
|
-
{ org: orgOption, search: searchOption$1 },
|
|
101796
|
-
({ org, search }) => gen(function* () {
|
|
102160
|
+
{ org: orgOption, search: searchOption$1, count: countOption, cursor: cursorOption, jsonPage: jsonPageOption },
|
|
102161
|
+
({ org, search, count, cursor, jsonPage }) => gen(function* () {
|
|
102162
|
+
const countValue = count._tag === "Some" ? count.value : void 0;
|
|
102163
|
+
yield* validatePageOptions(countValue, false, jsonPage);
|
|
101797
102164
|
const api = yield* ApiService;
|
|
101798
102165
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
101799
102166
|
const searchValue = search._tag === "Some" ? search.value : void 0;
|
|
101800
|
-
const result = yield* api.listLibrarySkills(orgSlug, {
|
|
102167
|
+
const result = yield* api.listLibrarySkills(orgSlug, {
|
|
102168
|
+
search: searchValue,
|
|
102169
|
+
count: countValue,
|
|
102170
|
+
cursor: cursor._tag === "Some" ? cursor.value : void 0
|
|
102171
|
+
}).pipe(
|
|
101801
102172
|
catchTag(
|
|
101802
102173
|
"NotLoggedInError",
|
|
101803
102174
|
(e) => gen(function* () {
|
|
@@ -101813,6 +102184,11 @@ const libraryCommand = make$4(
|
|
|
101813
102184
|
})
|
|
101814
102185
|
)
|
|
101815
102186
|
);
|
|
102187
|
+
if (jsonPage) {
|
|
102188
|
+
yield* log(jsonFormat({ ...result, nextCursor: result.nextCursor ?? null }));
|
|
102189
|
+
return;
|
|
102190
|
+
}
|
|
102191
|
+
yield* reportNextPage(result.hasNext);
|
|
101816
102192
|
if (result.items.length === 0) {
|
|
101817
102193
|
yield* log("No shared skills found.");
|
|
101818
102194
|
return;
|
|
@@ -101830,9 +102206,6 @@ const libraryCommand = make$4(
|
|
|
101830
102206
|
yield* log(` Uploaded: ${formatDate(skill.uploadedAt)}`);
|
|
101831
102207
|
yield* log("");
|
|
101832
102208
|
}
|
|
101833
|
-
if (result.hasNext) {
|
|
101834
|
-
yield* log("(More shared skills available.)");
|
|
101835
|
-
}
|
|
101836
102209
|
})
|
|
101837
102210
|
).pipe(withDescription("List shared skills from the library"));
|
|
101838
102211
|
|
|
@@ -101848,12 +102221,25 @@ const jsonOption = boolean("json").pipe(
|
|
|
101848
102221
|
);
|
|
101849
102222
|
const listCommand = make$4(
|
|
101850
102223
|
"list",
|
|
101851
|
-
{
|
|
101852
|
-
|
|
102224
|
+
{
|
|
102225
|
+
org: orgOption,
|
|
102226
|
+
search: searchOption,
|
|
102227
|
+
json: jsonOption,
|
|
102228
|
+
count: countOption,
|
|
102229
|
+
cursor: cursorOption,
|
|
102230
|
+
jsonPage: jsonPageOption
|
|
102231
|
+
},
|
|
102232
|
+
({ org, search, json, count, cursor, jsonPage }) => gen(function* () {
|
|
102233
|
+
const countValue = count._tag === "Some" ? count.value : void 0;
|
|
102234
|
+
yield* validatePageOptions(countValue, json, jsonPage);
|
|
101853
102235
|
const api = yield* ApiService;
|
|
101854
102236
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
101855
102237
|
const searchValue = search._tag === "Some" ? search.value : void 0;
|
|
101856
|
-
const result = yield* api.listSkills(orgSlug, {
|
|
102238
|
+
const result = yield* api.listSkills(orgSlug, {
|
|
102239
|
+
search: searchValue,
|
|
102240
|
+
count: countValue,
|
|
102241
|
+
cursor: cursor._tag === "Some" ? cursor.value : void 0
|
|
102242
|
+
}).pipe(
|
|
101857
102243
|
catchTag(
|
|
101858
102244
|
"NotLoggedInError",
|
|
101859
102245
|
(e) => gen(function* () {
|
|
@@ -101869,10 +102255,16 @@ const listCommand = make$4(
|
|
|
101869
102255
|
})
|
|
101870
102256
|
)
|
|
101871
102257
|
);
|
|
102258
|
+
if (jsonPage) {
|
|
102259
|
+
yield* log(jsonFormat({ ...result, nextCursor: result.nextCursor ?? null }));
|
|
102260
|
+
return;
|
|
102261
|
+
}
|
|
101872
102262
|
if (json) {
|
|
101873
102263
|
yield* log(jsonFormat(result.items));
|
|
102264
|
+
yield* reportNextPage(result.hasNext);
|
|
101874
102265
|
return;
|
|
101875
102266
|
}
|
|
102267
|
+
yield* reportNextPage(result.hasNext);
|
|
101876
102268
|
if (result.items.length === 0) {
|
|
101877
102269
|
yield* log("No skills found.");
|
|
101878
102270
|
return;
|
|
@@ -101905,9 +102297,6 @@ const listCommand = make$4(
|
|
|
101905
102297
|
}
|
|
101906
102298
|
yield* log("");
|
|
101907
102299
|
}
|
|
101908
|
-
if (result.hasNext) {
|
|
101909
|
-
yield* log("(More skills available. Use pagination to see all.)");
|
|
101910
|
-
}
|
|
101911
102300
|
})
|
|
101912
102301
|
).pipe(withDescription("List skills in the current (or specified) organization"));
|
|
101913
102302
|
|