aipctl 2026.9.4 → 2026.9.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.
Files changed (2) hide show
  1. package/build/index.cjs +114 -18
  2. package/package.json +3 -3
package/build/index.cjs CHANGED
@@ -778,7 +778,7 @@ const isIterable = input => typeof input === "string" || hasProperty(input, Symb
778
778
  * @since 2.0.0
779
779
  * @see isObject
780
780
  */
781
- const isRecord$2 = input => isRecordOrArray(input) && !Array.isArray(input);
781
+ const isRecord$3 = input => isRecordOrArray(input) && !Array.isArray(input);
782
782
  /**
783
783
  * A refinement that checks if a value is `PromiseLike`. It performs a duck-typing
784
784
  * check for a `.then` method.
@@ -25158,7 +25158,7 @@ const go = (ast, isDecoding) => {
25158
25158
  const concurrency = getConcurrency(ast);
25159
25159
  const batching = getBatching(ast);
25160
25160
  return (input, options) => {
25161
- if (!isRecord$2(input)) {
25161
+ if (!isRecord$3(input)) {
25162
25162
  return left(new Type(ast, input));
25163
25163
  }
25164
25164
  const allErrors = options?.errors === "all";
@@ -89670,7 +89670,7 @@ const injectedBuildEnv = "dev".length > 0 ? "dev" : "local";
89670
89670
  if (!isBuildEnv(injectedBuildEnv)) {
89671
89671
  throw new Error(`Invalid AIPCTL_BUILD_ENV: ${injectedBuildEnv}`);
89672
89672
  }
89673
- const VERSION = "2026.9.4".length > 0 ? "2026.9.4" : "0.0.0";
89673
+ const VERSION = "2026.9.5".length > 0 ? "2026.9.5" : "0.0.0";
89674
89674
  const BUILD_ENV = injectedBuildEnv;
89675
89675
  const INCLUDE_NATIVE_LOGS = BUILD_ENV !== "prod";
89676
89676
 
@@ -89812,10 +89812,18 @@ const implementedCommandOperationIds = /* @__PURE__ */ new Set([
89812
89812
  "listCliModelExecModels",
89813
89813
  "createCliModelChatExecution"
89814
89814
  ]);
89815
+ const releaseEnabledCommandOperationIds = /* @__PURE__ */ new Set([
89816
+ "getCliMe",
89817
+ "getCliUserSettings",
89818
+ "listCliOrganizations",
89819
+ "getCliOrganizationCapabilities",
89820
+ "listCliOrganizationMembers",
89821
+ "listCliModelExecModels"
89822
+ ]);
89815
89823
  const direct = (commands, operation) => commands.map((command) => ({
89816
89824
  command,
89817
89825
  tier: "GA_DIRECT",
89818
- availability: implementedCommandOperationIds.has(operation.operationId ?? "") ? "IMPLEMENTED" : "PLANNED",
89826
+ availability: !implementedCommandOperationIds.has(operation.operationId ?? "") ? "PLANNED" : releaseEnabledCommandOperationIds.has(operation.operationId ?? "") ? "IMPLEMENTED" : "GATED",
89819
89827
  ...operation
89820
89828
  }));
89821
89829
  const candidate = (commands, owner, authBoundary, requiredGates) => commands.map((command) => ({
@@ -90554,6 +90562,7 @@ const CUSTOMER_AVAILABILITIES = /* @__PURE__ */ new Set([
90554
90562
  "AVAILABLE"
90555
90563
  ]);
90556
90564
  const isCustomerAvailable = (entry) => CUSTOMER_AVAILABILITIES.has(entry.availability);
90565
+ const normalizeCliArgCase = (arg) => arg.toLowerCase();
90557
90566
  const commandSegments = (command) => command.split(" ");
90558
90567
  const PROD_DISABLED_BUILT_INS = /* @__PURE__ */ new Set(["--completions", "--wizard"]);
90559
90568
  const isCommandPrefix = (entry, args) => {
@@ -90579,11 +90588,12 @@ const getUnavailableCommandMessage = (args, buildEnv) => {
90579
90588
  if (buildEnv !== "prod" || args.length === 0) {
90580
90589
  return null;
90581
90590
  }
90582
- const disabledBuiltIn = args.find((arg) => PROD_DISABLED_BUILT_INS.has(arg));
90591
+ const normalizedArgs = args.map(normalizeCliArgCase);
90592
+ const disabledBuiltIn = normalizedArgs.find((arg) => PROD_DISABLED_BUILT_INS.has(arg));
90583
90593
  if (disabledBuiltIn) {
90584
90594
  return formatUnavailableOptionMessage(disabledBuiltIn);
90585
90595
  }
90586
- const commandArgs = commandArgsForAvailability(args);
90596
+ const commandArgs = commandArgsForAvailability(normalizedArgs);
90587
90597
  const entry = commandManifest.filter((candidate) => isCommandPrefix(candidate, commandArgs)).sort((left, right) => commandSegments(right.command).length - commandSegments(left.command).length).at(0);
90588
90598
  if (entry) {
90589
90599
  return isCustomerAvailable(entry) ? null : formatUnavailableMessage(entry.command);
@@ -90622,14 +90632,14 @@ class InvalidAppUrlError extends Error {
90622
90632
  this.rawValue = rawValue;
90623
90633
  }
90624
90634
  }
90625
- function isRecord$1(value) {
90635
+ function isRecord$2(value) {
90626
90636
  return typeof value === "object" && value !== null;
90627
90637
  }
90628
90638
  function optionalString$1(value) {
90629
90639
  return typeof value === "string" ? value : void 0;
90630
90640
  }
90631
90641
  function parseCurrentOrganization(value) {
90632
- if (!isRecord$1(value)) {
90642
+ if (!isRecord$2(value)) {
90633
90643
  return void 0;
90634
90644
  }
90635
90645
  const id = optionalString$1(value["id"]);
@@ -90641,7 +90651,7 @@ function parseCurrentOrganization(value) {
90641
90651
  return { id, slug, name };
90642
90652
  }
90643
90653
  function normalizeLoadedConfig(value) {
90644
- if (!isRecord$1(value)) {
90654
+ if (!isRecord$2(value)) {
90645
90655
  return {};
90646
90656
  }
90647
90657
  return {
@@ -92875,11 +92885,11 @@ const CREDENTIALS_FILE = path__namespace.join(CONFIG_DIR$1, "credentials.json");
92875
92885
  const CREDENTIALS_LOCK_FILE = path__namespace.join(CONFIG_DIR$1, "credentials.lock");
92876
92886
  class CredentialServiceTag extends Tag$1("CredentialService")() {
92877
92887
  }
92878
- function isNonEmptyString(value) {
92888
+ function isNonEmptyString$1(value) {
92879
92889
  return typeof value === "string" && value.length > 0;
92880
92890
  }
92881
92891
  function hasOAuthClient(credentials) {
92882
- return isNonEmptyString(credentials?.clientId);
92892
+ return isNonEmptyString$1(credentials?.clientId);
92883
92893
  }
92884
92894
  function isAccessTokenExpired(credentials, bufferMs = 0, now = Date.now()) {
92885
92895
  if (!credentials?.expiresAt) {
@@ -92888,13 +92898,13 @@ function isAccessTokenExpired(credentials, bufferMs = 0, now = Date.now()) {
92888
92898
  return credentials.expiresAt - bufferMs <= now;
92889
92899
  }
92890
92900
  function hasValidRefreshToken(credentials, now) {
92891
- return isNonEmptyString(credentials.refreshToken) && (credentials.refreshExpiresAt === void 0 || credentials.refreshExpiresAt > now);
92901
+ return isNonEmptyString$1(credentials.refreshToken) && (credentials.refreshExpiresAt === void 0 || credentials.refreshExpiresAt > now);
92892
92902
  }
92893
92903
  function getCredentialAuthStatus(credentials, now = Date.now(), options = {}) {
92894
92904
  if (!hasOAuthClient(credentials)) {
92895
92905
  return "missing";
92896
92906
  }
92897
- const needsAccessRefresh = options.forceRefresh || !isNonEmptyString(credentials.accessToken) || isAccessTokenExpired(credentials, options.accessExpiryBufferMs ?? 0, now);
92907
+ const needsAccessRefresh = options.forceRefresh || !isNonEmptyString$1(credentials.accessToken) || isAccessTokenExpired(credentials, options.accessExpiryBufferMs ?? 0, now);
92898
92908
  if (!needsAccessRefresh) {
92899
92909
  return "authenticated";
92900
92910
  }
@@ -93890,7 +93900,7 @@ function trimTrailingSlash(value) {
93890
93900
  function toError$1(error, fallbackMessage) {
93891
93901
  return error instanceof Error ? new Error(maskSensitiveText(error.message)) : new Error(maskSensitiveText(fallbackMessage));
93892
93902
  }
93893
- function isRecord(value) {
93903
+ function isRecord$1(value) {
93894
93904
  return typeof value === "object" && value !== null;
93895
93905
  }
93896
93906
  function optionalString(value) {
@@ -93900,7 +93910,7 @@ function optionalNumber(value) {
93900
93910
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
93901
93911
  }
93902
93912
  function parseOAuthTokenResponse(value) {
93903
- if (!isRecord(value)) {
93913
+ if (!isRecord$1(value)) {
93904
93914
  throw new OAuthRequestError("OAuth token response was not a JSON object", void 0, "invalid_token_response");
93905
93915
  }
93906
93916
  const accessToken = optionalString(value["access_token"]);
@@ -94429,6 +94439,55 @@ async function acquire() {
94429
94439
  }
94430
94440
  }
94431
94441
 
94442
+ const SERVER_CAPABILITY_SCHEMA_VERSION = 1;
94443
+ class ServerCapabilityError extends Error {
94444
+ code;
94445
+ constructor(code, message) {
94446
+ super(message);
94447
+ this.name = "ServerCapabilityError";
94448
+ this.code = code;
94449
+ }
94450
+ }
94451
+ function parseEnabledServerOperations(value) {
94452
+ if (!isRecord(value) || value["schemaVersion"] !== SERVER_CAPABILITY_SCHEMA_VERSION) {
94453
+ throw new ServerCapabilityError(
94454
+ "CLI_CAPABILITIES_INCOMPATIBLE",
94455
+ "The server returned an unsupported CLI capability schema."
94456
+ );
94457
+ }
94458
+ const enabledOperations = value["enabledOperations"];
94459
+ if (!Array.isArray(enabledOperations)) {
94460
+ throw new ServerCapabilityError(
94461
+ "CLI_CAPABILITIES_INCOMPATIBLE",
94462
+ "The server returned an invalid CLI capability operation list."
94463
+ );
94464
+ }
94465
+ const operationIds = /* @__PURE__ */ new Set();
94466
+ for (const operation of enabledOperations) {
94467
+ if (!isRecord(operation) || !isNonEmptyString(operation["operationId"]) || !isNonEmptyString(operation["capability"]) || operationIds.has(operation["operationId"])) {
94468
+ throw new ServerCapabilityError(
94469
+ "CLI_CAPABILITIES_INCOMPATIBLE",
94470
+ "The server returned an invalid CLI capability operation."
94471
+ );
94472
+ }
94473
+ operationIds.add(operation["operationId"]);
94474
+ }
94475
+ return operationIds;
94476
+ }
94477
+ function requireEnabledServerOperation(enabledOperations, operationId) {
94478
+ if (enabledOperations.has(operationId)) return;
94479
+ throw new ServerCapabilityError(
94480
+ "CLI_OPERATION_NOT_ENABLED",
94481
+ `CLI operation "${operationId}" is not enabled by the server.`
94482
+ );
94483
+ }
94484
+ function isRecord(value) {
94485
+ return typeof value === "object" && value !== null && !Array.isArray(value);
94486
+ }
94487
+ function isNonEmptyString(value) {
94488
+ return typeof value === "string" && value.length > 0;
94489
+ }
94490
+
94432
94491
  class ApiError extends TaggedError$1("ApiError") {
94433
94492
  }
94434
94493
  class NotLoggedInError extends TaggedError$1("NotLoggedInError") {
@@ -94735,7 +94794,7 @@ const parseSseStream = async (body) => {
94735
94794
  }
94736
94795
  throw new AgentChatStreamIncompleteError(hasDataEvent && sawOnlyTerminalEnvelope);
94737
94796
  };
94738
- const ApiServiceLive = effect$1(
94797
+ const makeApiServiceLive = (buildEnv) => effect$1(
94739
94798
  ApiServiceTag,
94740
94799
  gen(function* () {
94741
94800
  const configService = yield* ConfigService;
@@ -94852,6 +94911,34 @@ const ApiServiceLive = effect$1(
94852
94911
  });
94853
94912
  const baseUrl = () => loadConfiguredApiBaseUrl();
94854
94913
  const chatBaseUrl = () => loadConfiguredChatBaseUrl();
94914
+ const requireServerOperation = (operationId, token) => {
94915
+ if (buildEnv !== "prod") return _void;
94916
+ if (!releaseEnabledCommandOperationIds.has(operationId)) {
94917
+ return fail$3(createApiError({
94918
+ message: `CLI operation "${operationId}" is not enabled in this aipctl release.`,
94919
+ statusCode: 404,
94920
+ code: "CLI_OPERATION_NOT_ENABLED"
94921
+ }));
94922
+ }
94923
+ return gen(function* () {
94924
+ const response = yield* makeRequest(
94925
+ baseUrl,
94926
+ "/api/cli/v1/capabilities",
94927
+ token
94928
+ );
94929
+ yield* try_({
94930
+ try: () => {
94931
+ const enabledOperations = parseEnabledServerOperations(response);
94932
+ requireEnabledServerOperation(enabledOperations, operationId);
94933
+ },
94934
+ catch: (error) => createApiError({
94935
+ message: error instanceof Error ? error.message : "CLI server capability validation failed",
94936
+ statusCode: error instanceof ServerCapabilityError && error.code === "CLI_OPERATION_NOT_ENABLED" ? 404 : 503,
94937
+ code: error instanceof ServerCapabilityError ? error.code : "CLI_CAPABILITIES_INCOMPATIBLE"
94938
+ })
94939
+ });
94940
+ });
94941
+ };
94855
94942
  const subscribeAgentChatStream = (orgSlug, conversationId, token) => gen(function* () {
94856
94943
  const resolvedChatBaseUrl = yield* requireChatBaseUrlEffect();
94857
94944
  const path = `/api/${encodeURIComponent(orgSlug)}/conversations/${encodeURIComponent(conversationId)}/stream`;
@@ -94918,10 +95005,12 @@ const ApiServiceLive = effect$1(
94918
95005
  return {
94919
95006
  listOrganizations: () => gen(function* () {
94920
95007
  const token = yield* getAccessToken();
95008
+ yield* requireServerOperation("listCliOrganizations", token);
94921
95009
  return yield* makeRequest(baseUrl, "/api/cli/v1/organizations", token);
94922
95010
  }),
94923
95011
  getOrganization: (slug) => gen(function* () {
94924
95012
  const token = yield* getAccessToken();
95013
+ yield* requireServerOperation("listCliOrganizations", token);
94925
95014
  const orgs = yield* makeRequest(baseUrl, "/api/cli/v1/organizations", token);
94926
95015
  const org = orgs.find((o) => o.slug === slug);
94927
95016
  if (!org) {
@@ -95261,6 +95350,7 @@ const ApiServiceLive = effect$1(
95261
95350
  // Phase 4: Monitoring
95262
95351
  listOrgMembers: (orgSlug) => gen(function* () {
95263
95352
  const token = yield* getAccessToken();
95353
+ yield* requireServerOperation("listCliOrganizationMembers", token);
95264
95354
  const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/members`;
95265
95355
  const raw = yield* makeRequest(baseUrl, path, token);
95266
95356
  return {
@@ -95286,12 +95376,14 @@ const ApiServiceLive = effect$1(
95286
95376
  listModelExecModels: (orgSlug) => gen(function* () {
95287
95377
  yield* requireChatBaseUrlEffect();
95288
95378
  const token = yield* getAccessToken();
95379
+ yield* requireServerOperation("listCliModelExecModels", token);
95289
95380
  const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/model-exec/models`;
95290
95381
  return yield* makeRequest(chatBaseUrl, path, token);
95291
95382
  }),
95292
95383
  executeModelExecChat: (orgSlug, body) => gen(function* () {
95293
95384
  yield* requireChatBaseUrlEffect();
95294
95385
  const token = yield* getAccessToken();
95386
+ yield* requireServerOperation("createCliModelChatExecution", token);
95295
95387
  const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/model-exec/chat`;
95296
95388
  return yield* makeRequest(chatBaseUrl, path, token, {
95297
95389
  method: "POST",
@@ -95433,6 +95525,7 @@ const ApiServiceLive = effect$1(
95433
95525
  // Phase 6: Auth enhancements
95434
95526
  getMe: () => gen(function* () {
95435
95527
  const token = yield* getAccessToken();
95528
+ yield* requireServerOperation("getCliMe", token);
95436
95529
  return yield* makeRequest(baseUrl, "/api/cli/v1/me", token);
95437
95530
  }),
95438
95531
  refreshToken: () => refreshAccessToken({ force: true }),
@@ -95614,11 +95707,13 @@ const ApiServiceLive = effect$1(
95614
95707
  // Org capabilities & user settings
95615
95708
  getOrgCapabilities: (orgSlug) => gen(function* () {
95616
95709
  const token = yield* getAccessToken();
95710
+ yield* requireServerOperation("getCliOrganizationCapabilities", token);
95617
95711
  const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/capabilities`;
95618
95712
  return yield* makeRequest(baseUrl, path, token);
95619
95713
  }),
95620
95714
  getUserSettings: () => gen(function* () {
95621
95715
  const token = yield* getAccessToken();
95716
+ yield* requireServerOperation("getCliUserSettings", token);
95622
95717
  return yield* makeRequest(baseUrl, "/api/cli/v1/me/settings", token);
95623
95718
  }),
95624
95719
  // Tunnel management
@@ -95736,6 +95831,7 @@ const ApiServiceLive = effect$1(
95736
95831
  };
95737
95832
  })
95738
95833
  );
95834
+ const ApiServiceLive = makeApiServiceLive(BUILD_ENV);
95739
95835
  const ApiService = ApiServiceTag;
95740
95836
 
95741
95837
  const orgOption = text("org").pipe(
@@ -101402,10 +101498,10 @@ const hasCustomerAvailableCommand = (path) => {
101402
101498
  const formatCommandList = (path, subcommands, options) => subcommands.map((command) => [...path, getCommandName(command)]).filter((commandPath) => !options.customerOnly || hasCustomerAvailableCommand(commandPath)).map((commandPath) => ` - ${formatCanonicalPath(commandPath)}`).join("\n");
101403
101499
  const getHelpPath = (args) => {
101404
101500
  const lastArg = args.at(-1);
101405
- if (!lastArg || !HELP_FLAGS$1.has(lastArg)) {
101501
+ if (!lastArg || !HELP_FLAGS$1.has(normalizeCliArgCase(lastArg))) {
101406
101502
  return null;
101407
101503
  }
101408
- const path = args.slice(0, -1);
101504
+ const path = args.slice(0, -1).map(normalizeCliArgCase);
101409
101505
  return path.every((segment) => !segment.startsWith("-")) ? path : null;
101410
101506
  };
101411
101507
  const renderGroupHelp = ({ path, description, subcommands }, options) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aipctl",
3
- "version": "2026.9.4",
3
+ "version": "2026.9.5",
4
4
  "description": "QueryPie AIP and MCP CLI tool",
5
5
  "author": "QueryPie",
6
6
  "license": "UNLICENSED",
@@ -22,8 +22,8 @@
22
22
  "node": ">=24.18.0"
23
23
  },
24
24
  "metadata": {
25
- "contentHash": "324de7cea8dc3fde3a838c4aadd5029fb56b526a8139e7be35b08a3e7de824e4",
26
- "wrapperHash": "bc687edf26af6780466e1818b26030068995fd234be8ebd80e960121df783158",
25
+ "contentHash": "41009029ba4ff1bb3ad17157d8af3499f5545ddf860fb1ea4803005b6a6ca026",
26
+ "wrapperHash": "15330253c506008f0676946c51659e0dfc616d42e8931180f47080a03b966203",
27
27
  "nativeHash": "006b08c3e391f4571d9b7c0f12d684fe2448106259e7e0581b10f9be362452e9"
28
28
  },
29
29
  "optionalDependencies": {