aipctl 2026.9.9 → 2026.9.11

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/build/index.cjs CHANGED
@@ -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.9".length > 0 ? "2026.9.9" : "0.0.0";
89673
+ const VERSION = "2026.9.11".length > 0 ? "2026.9.11" : "0.0.0";
89674
89674
  const BUILD_ENV = injectedBuildEnv;
89675
89675
  const INCLUDE_NATIVE_LOGS = BUILD_ENV !== "prod";
89676
89676
 
@@ -89819,7 +89819,32 @@ const implementedCommandOperationIds = /* @__PURE__ */ new Set([
89819
89819
  "listCliOrganizationMembers",
89820
89820
  "listCliModels",
89821
89821
  "listCliModelExecModels",
89822
- "createCliModelChatExecution"
89822
+ "createCliModelChatExecution",
89823
+ "listCliSkills",
89824
+ "getCliSkill",
89825
+ "deleteCliSkill",
89826
+ "listCliSkillLibrary",
89827
+ "createCliSkillClones",
89828
+ "listCliBuiltInSkills",
89829
+ "createCliBuiltInSkillClones",
89830
+ "listCliAdminSkills",
89831
+ "getCliAdminSkill",
89832
+ "deleteCliAdminSkill",
89833
+ "updateCliAdminSkill",
89834
+ "listCliAdminBuiltInSkills",
89835
+ "createCliAdminBuiltInSkillClones",
89836
+ "listCliDriveEntries",
89837
+ "getCliDriveUsage",
89838
+ "createCliDriveFolder",
89839
+ "updateCliDriveEntryName",
89840
+ "deleteCliDriveEntries",
89841
+ "listCliChats",
89842
+ "getCliChat",
89843
+ "listCliChatMessages",
89844
+ "listCliIntegrations",
89845
+ "listCliAvailableIntegrations",
89846
+ "getCliAdminIntegration",
89847
+ "listCliIntegrationTools"
89823
89848
  ]);
89824
89849
  const releaseEnabledCommandOperationIds = /* @__PURE__ */ new Set([
89825
89850
  "listCliAgents",
@@ -89836,7 +89861,32 @@ const releaseEnabledCommandOperationIds = /* @__PURE__ */ new Set([
89836
89861
  "getCliOrganizationCapabilities",
89837
89862
  "listCliOrganizationMembers",
89838
89863
  "listCliModels",
89839
- "listCliModelExecModels"
89864
+ "listCliModelExecModels",
89865
+ "listCliSkills",
89866
+ "getCliSkill",
89867
+ "deleteCliSkill",
89868
+ "listCliSkillLibrary",
89869
+ "createCliSkillClones",
89870
+ "listCliBuiltInSkills",
89871
+ "createCliBuiltInSkillClones",
89872
+ "listCliAdminSkills",
89873
+ "getCliAdminSkill",
89874
+ "deleteCliAdminSkill",
89875
+ "updateCliAdminSkill",
89876
+ "listCliAdminBuiltInSkills",
89877
+ "createCliAdminBuiltInSkillClones",
89878
+ "listCliDriveEntries",
89879
+ "getCliDriveUsage",
89880
+ "createCliDriveFolder",
89881
+ "updateCliDriveEntryName",
89882
+ "deleteCliDriveEntries",
89883
+ "listCliChats",
89884
+ "getCliChat",
89885
+ "listCliChatMessages",
89886
+ "listCliIntegrations",
89887
+ "listCliAvailableIntegrations",
89888
+ "getCliAdminIntegration",
89889
+ "listCliIntegrationTools"
89840
89890
  ]);
89841
89891
  const direct = (commands, operation) => commands.map((command) => ({
89842
89892
  command,
@@ -95046,11 +95096,12 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95046
95096
  }),
95047
95097
  listSkills: (orgSlug, options) => gen(function* () {
95048
95098
  const token = yield* getAccessToken();
95099
+ yield* requireReleaseEnabledOperation("listCliSkills");
95049
95100
  const params = new URLSearchParams();
95050
95101
  params.set("count", String(options?.count ?? 50));
95051
95102
  if (options?.cursor) params.set("cursor", options.cursor);
95052
95103
  if (options?.search) params.set("search", options.search);
95053
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/skills?${params.toString()}`;
95104
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/skills?${params.toString()}`;
95054
95105
  const response = yield* makeRequest(baseUrl, path, token);
95055
95106
  return {
95056
95107
  ...response,
@@ -95067,11 +95118,12 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95067
95118
  }),
95068
95119
  listAdminSkills: (orgSlug, options) => gen(function* () {
95069
95120
  const token = yield* getAccessToken();
95121
+ yield* requireReleaseEnabledOperation("listCliAdminSkills");
95070
95122
  const params = new URLSearchParams();
95071
95123
  params.set("pageNumber", String(options?.pageNumber ?? 1));
95072
95124
  params.set("pageSize", String(options?.pageSize ?? 20));
95073
95125
  if (options?.search) params.set("search", options.search);
95074
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/skills?${params.toString()}`;
95126
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/skills?${params.toString()}`;
95075
95127
  const response = yield* makeRequest(baseUrl, path, token);
95076
95128
  return {
95077
95129
  ...response,
@@ -95141,12 +95193,14 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95141
95193
  }),
95142
95194
  deleteSkill: (orgSlug, skillId) => gen(function* () {
95143
95195
  const token = yield* getAccessToken();
95144
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/skills/${encodeURIComponent(skillId)}`;
95196
+ yield* requireReleaseEnabledOperation("deleteCliSkill");
95197
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/skills/${encodeURIComponent(skillId)}`;
95145
95198
  return yield* makeRequest(baseUrl, path, token, { method: "DELETE" });
95146
95199
  }),
95147
95200
  deleteAdminSkill: (orgSlug, skillId) => gen(function* () {
95148
95201
  const token = yield* getAccessToken();
95149
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/skills/${encodeURIComponent(skillId)}`;
95202
+ yield* requireReleaseEnabledOperation("deleteCliAdminSkill");
95203
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/skills/${encodeURIComponent(skillId)}`;
95150
95204
  return yield* makeRequest(baseUrl, path, token, { method: "DELETE" });
95151
95205
  }),
95152
95206
  getCurrentOrganization: () => gen(function* () {
@@ -95163,10 +95217,11 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95163
95217
  // Phase 1: Skill detail/download/library/clone
95164
95218
  getSkill: (orgSlug, skillId, options) => gen(function* () {
95165
95219
  const token = yield* getAccessToken();
95220
+ yield* requireReleaseEnabledOperation("getCliSkill");
95166
95221
  const params = new URLSearchParams();
95167
95222
  if (options?.maxFiles) params.set("maxFiles", String(options.maxFiles));
95168
95223
  const qs = params.toString();
95169
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/skills/${encodeURIComponent(skillId)}${qs ? `?${qs}` : ""}`;
95224
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/skills/${encodeURIComponent(skillId)}${qs ? `?${qs}` : ""}`;
95170
95225
  const response = yield* makeRequest(baseUrl, path, token);
95171
95226
  return {
95172
95227
  ...response,
@@ -95178,10 +95233,11 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95178
95233
  }),
95179
95234
  getAdminSkill: (orgSlug, skillId, options) => gen(function* () {
95180
95235
  const token = yield* getAccessToken();
95236
+ yield* requireReleaseEnabledOperation("getCliAdminSkill");
95181
95237
  const params = new URLSearchParams();
95182
95238
  if (options?.maxFiles) params.set("maxFiles", String(options.maxFiles));
95183
95239
  const qs = params.toString();
95184
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/skills/${encodeURIComponent(skillId)}${qs ? `?${qs}` : ""}`;
95240
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/skills/${encodeURIComponent(skillId)}${qs ? `?${qs}` : ""}`;
95185
95241
  const response = yield* makeRequest(baseUrl, path, token);
95186
95242
  return {
95187
95243
  ...response,
@@ -95193,7 +95249,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95193
95249
  }),
95194
95250
  updateAdminSkill: (orgSlug, skillId, body) => gen(function* () {
95195
95251
  const token = yield* getAccessToken();
95196
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/skills/${encodeURIComponent(skillId)}`;
95252
+ yield* requireReleaseEnabledOperation("updateCliAdminSkill");
95253
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/skills/${encodeURIComponent(skillId)}`;
95197
95254
  return yield* makeRequest(baseUrl, path, token, {
95198
95255
  method: "PATCH",
95199
95256
  body
@@ -95253,16 +95310,18 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95253
95310
  }),
95254
95311
  listLibrarySkills: (orgSlug, options) => gen(function* () {
95255
95312
  const token = yield* getAccessToken();
95313
+ yield* requireReleaseEnabledOperation("listCliSkillLibrary");
95256
95314
  const params = new URLSearchParams();
95257
95315
  params.set("count", String(options?.count ?? 50));
95258
95316
  if (options?.cursor) params.set("cursor", options.cursor);
95259
95317
  if (options?.search) params.set("search", options.search);
95260
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/skills/library?${params.toString()}`;
95318
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/skills/library?${params.toString()}`;
95261
95319
  return yield* makeRequest(baseUrl, path, token);
95262
95320
  }),
95263
95321
  cloneSkills: (orgSlug, sourceSkillIds) => gen(function* () {
95264
95322
  const token = yield* getAccessToken();
95265
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/skills/library/clone`;
95323
+ yield* requireReleaseEnabledOperation("createCliSkillClones");
95324
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/skills/library/clone`;
95266
95325
  return yield* makeRequest(baseUrl, path, token, {
95267
95326
  method: "POST",
95268
95327
  body: { sourceSkillIds }
@@ -95481,8 +95540,9 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95481
95540
  // Phase 5: Drive/Integration
95482
95541
  listDriveEntries: (orgSlug) => gen(function* () {
95483
95542
  const token = yield* getAccessToken();
95543
+ yield* requireReleaseEnabledOperation("listCliDriveEntries");
95484
95544
  const params = new URLSearchParams({ count: "200" });
95485
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/drive/entries?${params.toString()}`;
95545
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/drive/entries?${params.toString()}`;
95486
95546
  return yield* makeRequest(baseUrl, path, token);
95487
95547
  }),
95488
95548
  getDriveDownloadUrl: (orgSlug, entryId) => gen(function* () {
@@ -95516,27 +95576,32 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95516
95576
  }),
95517
95577
  deleteDriveEntries: (orgSlug, entryIds) => gen(function* () {
95518
95578
  const token = yield* getAccessToken();
95519
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/drive/entries/delete`;
95579
+ yield* requireReleaseEnabledOperation("deleteCliDriveEntries");
95580
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/drive/entries/delete`;
95520
95581
  return yield* makeRequest(baseUrl, path, token, { method: "POST", body: { entryIds } });
95521
95582
  }),
95522
95583
  createDriveFolder: (orgSlug, name) => gen(function* () {
95523
95584
  const token = yield* getAccessToken();
95524
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/drive/entries`;
95585
+ yield* requireReleaseEnabledOperation("createCliDriveFolder");
95586
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/drive/folders`;
95525
95587
  return yield* makeRequest(baseUrl, path, token, { method: "POST", body: { name } });
95526
95588
  }),
95527
95589
  renameDriveEntry: (orgSlug, entryId, newName) => gen(function* () {
95528
95590
  const token = yield* getAccessToken();
95529
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/drive/entries/${encodeURIComponent(entryId)}`;
95591
+ yield* requireReleaseEnabledOperation("updateCliDriveEntryName");
95592
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/drive/entries/${encodeURIComponent(entryId)}`;
95530
95593
  return yield* makeRequest(baseUrl, path, token, { method: "PATCH", body: { newName } });
95531
95594
  }),
95532
95595
  getDriveUsage: (orgSlug) => gen(function* () {
95533
95596
  const token = yield* getAccessToken();
95534
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/drive/usage`;
95597
+ yield* requireReleaseEnabledOperation("getCliDriveUsage");
95598
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/drive/usage`;
95535
95599
  return yield* makeRequest(baseUrl, path, token);
95536
95600
  }),
95537
95601
  listIntegrations: (orgSlug) => gen(function* () {
95538
95602
  const token = yield* getAccessToken();
95539
- const path = `/api/web/integrations/v2?organizationSlug=${encodeURIComponent(orgSlug)}`;
95603
+ yield* requireReleaseEnabledOperation("listCliIntegrations");
95604
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/integrations`;
95540
95605
  return yield* makeRequest(baseUrl, path, token);
95541
95606
  }),
95542
95607
  testIntegration: (orgSlug, integrationId) => gen(function* () {
@@ -95558,22 +95623,25 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95558
95623
  listConversations: (orgSlug, options) => gen(function* () {
95559
95624
  yield* requireChatBaseUrlEffect();
95560
95625
  const token = yield* getAccessToken();
95626
+ yield* requireReleaseEnabledOperation("listCliChats");
95561
95627
  const params = new URLSearchParams();
95562
95628
  if (options?.cursor) params.set("cursor", options.cursor);
95563
95629
  const query = params.toString();
95564
- const path = `/librechat/api/${encodeURIComponent(orgSlug)}/convos${query ? `?${query}` : ""}`;
95630
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/chats${query ? `?${query}` : ""}`;
95565
95631
  return yield* makeRequest(chatBaseUrl, path, token);
95566
95632
  }),
95567
95633
  getConversation: (orgSlug, conversationId) => gen(function* () {
95568
95634
  yield* requireChatBaseUrlEffect();
95569
95635
  const token = yield* getAccessToken();
95570
- const path = `/librechat/api/${encodeURIComponent(orgSlug)}/convos/${encodeURIComponent(conversationId)}`;
95636
+ yield* requireReleaseEnabledOperation("getCliChat");
95637
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/chats/${encodeURIComponent(conversationId)}`;
95571
95638
  return yield* makeRequest(chatBaseUrl, path, token);
95572
95639
  }),
95573
95640
  listMessages: (orgSlug, conversationId) => gen(function* () {
95574
95641
  yield* requireChatBaseUrlEffect();
95575
95642
  const token = yield* getAccessToken();
95576
- const path = `/librechat/api/${encodeURIComponent(orgSlug)}/messages/${encodeURIComponent(conversationId)}`;
95643
+ yield* requireReleaseEnabledOperation("listCliChatMessages");
95644
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/chats/${encodeURIComponent(conversationId)}/messages`;
95577
95645
  return yield* makeRequest(chatBaseUrl, path, token);
95578
95646
  }),
95579
95647
  sendChatMessage: (orgSlug, body) => gen(function* () {
@@ -95671,16 +95739,37 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95671
95739
  // Built-in skill library
95672
95740
  listBuiltInSkills: (orgSlug, options) => gen(function* () {
95673
95741
  const token = yield* getAccessToken();
95742
+ yield* requireReleaseEnabledOperation("listCliBuiltInSkills");
95674
95743
  const params = new URLSearchParams();
95675
95744
  params.set("limit", String(options?.limit ?? 50));
95676
95745
  if (options?.cursor) params.set("cursor", options.cursor);
95677
95746
  if (options?.search) params.set("search", options.search);
95678
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/skills/built-in-library?${params.toString()}`;
95747
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/skills/built-in?${params.toString()}`;
95679
95748
  return yield* makeRequest(baseUrl, path, token);
95680
95749
  }),
95681
95750
  cloneBuiltInSkills: (orgSlug, sourceSkillIds) => gen(function* () {
95682
95751
  const token = yield* getAccessToken();
95683
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/skills/built-in-library/clone`;
95752
+ yield* requireReleaseEnabledOperation("createCliBuiltInSkillClones");
95753
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/skills/built-in/clone`;
95754
+ return yield* makeRequest(baseUrl, path, token, {
95755
+ method: "POST",
95756
+ body: { sourceSkillIds }
95757
+ });
95758
+ }),
95759
+ listAdminBuiltInSkills: (orgSlug, options) => gen(function* () {
95760
+ const token = yield* getAccessToken();
95761
+ yield* requireReleaseEnabledOperation("listCliAdminBuiltInSkills");
95762
+ const params = new URLSearchParams();
95763
+ params.set("limit", String(options?.limit ?? 50));
95764
+ if (options?.cursor) params.set("cursor", options.cursor);
95765
+ if (options?.search) params.set("search", options.search);
95766
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/skills/built-in?${params.toString()}`;
95767
+ return yield* makeRequest(baseUrl, path, token);
95768
+ }),
95769
+ cloneAdminBuiltInSkills: (orgSlug, sourceSkillIds) => gen(function* () {
95770
+ const token = yield* getAccessToken();
95771
+ yield* requireReleaseEnabledOperation("createCliAdminBuiltInSkillClones");
95772
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/skills/built-in/clone`;
95684
95773
  return yield* makeRequest(baseUrl, path, token, {
95685
95774
  method: "POST",
95686
95775
  body: { sourceSkillIds }
@@ -95707,7 +95796,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95707
95796
  // Integration CRUD
95708
95797
  getIntegration: (orgSlug, id) => gen(function* () {
95709
95798
  const token = yield* getAccessToken();
95710
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/integrations/${encodeURIComponent(id)}`;
95799
+ yield* requireReleaseEnabledOperation("getCliAdminIntegration");
95800
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/integrations/${encodeURIComponent(id)}`;
95711
95801
  const response = yield* makeRequest(baseUrl, path, token);
95712
95802
  return {
95713
95803
  ...response,
@@ -95727,14 +95817,15 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95727
95817
  }),
95728
95818
  listIntegrationTools: (orgSlug, id) => gen(function* () {
95729
95819
  const token = yield* getAccessToken();
95730
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/integrations/${encodeURIComponent(id)}/tools`;
95820
+ yield* requireReleaseEnabledOperation("listCliIntegrationTools");
95821
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/integrations/${encodeURIComponent(id)}/tools`;
95731
95822
  return yield* makeRequest(baseUrl, path, token);
95732
95823
  }),
95733
95824
  listConfigurableIntegrations: (orgSlug) => gen(function* () {
95734
95825
  const token = yield* getAccessToken();
95735
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/configurable-integrations`;
95736
- const response = yield* makeRequest(baseUrl, path, token);
95737
- return response.integrations;
95826
+ yield* requireReleaseEnabledOperation("listCliAvailableIntegrations");
95827
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/integrations/available`;
95828
+ return yield* makeRequest(baseUrl, path, token);
95738
95829
  }),
95739
95830
  // Audit event types
95740
95831
  listAuditEventTypes: () => gen(function* () {
@@ -97146,14 +97237,14 @@ const searchOption$3 = text("search").pipe(
97146
97237
  withDescription$3("Search built-in skills by name"),
97147
97238
  optional
97148
97239
  );
97149
- const builtInCommand = make$4(
97240
+ const makeBuiltInCommand = (listSkills = (api, orgSlug, options) => api.listBuiltInSkills(orgSlug, options), description = "List built-in skills from the library") => make$4(
97150
97241
  "built-in",
97151
97242
  { org: orgOption, search: searchOption$3 },
97152
97243
  ({ org, search }) => gen(function* () {
97153
97244
  const api = yield* ApiService;
97154
97245
  const orgSlug = yield* resolveOrgSlug(org, api);
97155
97246
  const searchValue = search._tag === "Some" ? search.value : void 0;
97156
- const result = yield* api.listBuiltInSkills(orgSlug, { search: searchValue }).pipe(
97247
+ const result = yield* listSkills(api, orgSlug, { search: searchValue }).pipe(
97157
97248
  catchTag(
97158
97249
  "NotLoggedInError",
97159
97250
  (e) => gen(function* () {
@@ -97191,7 +97282,8 @@ const builtInCommand = make$4(
97191
97282
  yield* log("(More built-in skills available.)");
97192
97283
  }
97193
97284
  })
97194
- ).pipe(withDescription("List built-in skills from the library"));
97285
+ ).pipe(withDescription(description));
97286
+ const builtInCommand = makeBuiltInCommand();
97195
97287
 
97196
97288
  const MAX_CLONE_SKILLS$1 = 5;
97197
97289
  const formatCloneBuiltInFailureMessage = maskSensitiveText;
@@ -97199,7 +97291,7 @@ const skillIdsArg$1 = text$2({ name: "id" }).pipe(
97199
97291
  withDescription$5(`Built-in skill ID(s) to clone (max ${MAX_CLONE_SKILLS$1})`),
97200
97292
  repeated
97201
97293
  );
97202
- const cloneBuiltInCommand = make$4(
97294
+ const makeCloneBuiltInCommand = (cloneSkills = (api, orgSlug, sourceSkillIds) => api.cloneBuiltInSkills(orgSlug, sourceSkillIds), description = "Clone built-in skills from the library to your organization") => make$4(
97203
97295
  "clone-built-in",
97204
97296
  { skillIds: skillIdsArg$1, org: orgOption },
97205
97297
  ({ skillIds, org }) => gen(function* () {
@@ -97215,7 +97307,7 @@ const cloneBuiltInCommand = make$4(
97215
97307
  return;
97216
97308
  }
97217
97309
  yield* log(`Cloning ${ids.length} built-in skill(s) to organization "${orgSlug}"...`);
97218
- const result = yield* api.cloneBuiltInSkills(orgSlug, ids).pipe(
97310
+ const result = yield* cloneSkills(api, orgSlug, ids).pipe(
97219
97311
  catchTag(
97220
97312
  "NotLoggedInError",
97221
97313
  (e) => gen(function* () {
@@ -97245,7 +97337,8 @@ const cloneBuiltInCommand = make$4(
97245
97337
  }
97246
97338
  }
97247
97339
  })
97248
- ).pipe(withDescription("Clone built-in skills from the library to your organization"));
97340
+ ).pipe(withDescription(description));
97341
+ const cloneBuiltInCommand = makeCloneBuiltInCommand();
97249
97342
 
97250
97343
  const skillIdArg$4 = text$2({ name: "id" }).pipe(withDescription$5("Skill ID to download"));
97251
97344
  const outputOption$2 = text("output").pipe(
@@ -97822,6 +97915,14 @@ const unpublishCommand = make$4(
97822
97915
  yield* log(`Organization skill "${skillId}" was removed from the shared library.`);
97823
97916
  })
97824
97917
  ).pipe(withDescription("Remove an organization skill from the shared library"));
97918
+ const adminBuiltInCommand = makeBuiltInCommand(
97919
+ (api, orgSlug, options) => api.listAdminBuiltInSkills(orgSlug, options),
97920
+ "List built-in skills available to an AI operator"
97921
+ );
97922
+ const adminCloneBuiltInCommand = makeCloneBuiltInCommand(
97923
+ (api, orgSlug, sourceSkillIds) => api.cloneAdminBuiltInSkills(orgSlug, sourceSkillIds),
97924
+ "Clone built-in skills as an AI operator"
97925
+ );
97825
97926
  const adminSkillCommandDescription = "Admin skill management (list, get, upload, download, delete, publish, unpublish, built-in, clone-built-in, github)";
97826
97927
  const adminSkillSubcommands = [
97827
97928
  listCommand$8,
@@ -97831,8 +97932,8 @@ const adminSkillSubcommands = [
97831
97932
  deleteCommand$3,
97832
97933
  publishCommand,
97833
97934
  unpublishCommand,
97834
- builtInCommand,
97835
- cloneBuiltInCommand,
97935
+ adminBuiltInCommand,
97936
+ adminCloneBuiltInCommand,
97836
97937
  githubSkillCommand
97837
97938
  ];
97838
97939
  const adminSkillCommand = make$4("skill", {}).pipe(
@@ -43,10 +43,10 @@
43
43
  | ORG-02 | org | `aipctl org capabilities`, `aipctl org settings`, `aipctl org exit` | `getOrgCapabilities`, `getUserSettings`, `exitOrg` | api | `GET`, `GET`, `POST` | organization v1 `/api/cli/v1/organizations/{organizationSlug}/capabilities`; user-global v1 `/api/cli/v1/me/settings`; legacy `/api/web/organizations/slug/{organizationSlug}/exit` | none | local `OrgCapabilities`, `UserSettings`, `void` | read paths: `resource/oas/modules/backend/cli/openapi.yaml`; exit: `resource/oas/duplo-web.yaml` | read generated `CliOrganizationApi`/`CliV1Api`; exit legacy generated | `legacy-generated` | N/A | `migrate` | owner=`backend`; rationale=`capabilities is organization-owned, settings remains user-global, and exit remains a Wave B mutation`; removal condition=`exit receives its dedicated v1 mutation contract`; incorporation plan=`preserve current membership authorization and non-replay behavior` | task 3.3 | `src/core/api.test.ts` verifies v1 read paths and settings ownership; org tests cover response/error behavior |
44
44
  | P0-ORG-01 | org-member | `aipctl org members`; `aipctl admin org invite`, `aipctl admin org remove-member`, `aipctl admin org update-member-role` | `listOrgMembers`, `inviteOrgMembers`, `removeOrgMembers`, `updateOrgMemberRoles` | api | `GET`, `POST`, `DELETE`, `PUT` | list v1 `/api/cli/v1/organizations/{organizationSlug}/members`; mutations remain legacy `/invite`; `/members` | list uses stable CLI member response; mutation bodies preserve `{ emails, role }` and `{ members, role? }` | local `ListMembersResponse`, `InviteOrgMembersResponse`, `void` | list: `resource/oas/modules/backend/cli/openapi.yaml`; mutation: `resource/oas/duplo-web.yaml` | list generated `CliOrganizationApi`; mutation legacy generated | `legacy-generated` | `P0` | `legacy-exception` | owner=`backend`; rationale=`member read is migrated while admin mutations remain Wave B`; removal condition=`invite/remove/role receive dedicated v1 contracts`; incorporation plan=`reuse current admin authorization, audit, stale target validation, and non-replay semantics` | task 3.3 | `src/core/api.test.ts`, `commands/org/members.test.ts`, `commands/org/org-member.test.ts`; covers v1 member read and legacy mutation bodies |
45
45
  | P0-ORG-02 | org-admin | hidden from public beta (`aipctl admin org invite-link`, `gen-invite-link`, `revoke-invite-link` removed from command tree) | removed from public surface | api | `GET`, `POST`, `DELETE` | previously `/api/web/organizations/slug/{organizationSlug}/invite/link` | none | hidden | latest: `resource/oas/modules/backend/organization/openapi.yaml` (`/invite/link/v2`); legacy: `resource/oas/duplo-web.yaml` (`/invite/link`) | latest `frontend/packages/api/src/out/modules/organization-types.ts#paths["/api/web/organizations/slug/{organizationSlug}/invite/link/v2"]`; legacy `frontend/packages/api/src/out/user-types.ts#paths["/api/web/organizations/slug/{organizationSlug}/invite/link"]` | `oas-source-only` | `P0` | `hide` | owner=`backend organization module`; rationale=`v2 exists but current CLI UX contract for GET/DELETE parity is not approved for public beta`; removal condition=`public beta continues hiding until a reviewed v2 CLI UX contract exists`; incorporation plan=`reintroduce only after independent organization contract/build and public UX review` | N/A | updated admin org help smoke + command-tree regression to ensure trio is absent |
46
- | SKILL-01 | skill | `aipctl skill list`, `aipctl skill get`, `aipctl skill delete` | `listSkills`, `getSkill`, `deleteSkill` | api | `GET`, `GET`, `DELETE` | `/api/web/organizations/slug/{organizationSlug}/skills`; `/skills/{skillId}` | query `{ count,cursor,search }`; detail query `{ maxFiles }` | local `ListSkillsResponse`, `SkillDetail`, `void` | `resource/oas/modules/backend/organization/skills/openapi.yaml` | `frontend/packages/api/src/out/modules/organization-skills-types.ts#paths["/api/web/organizations/slug/{organizationSlug}/skills"]`, `#paths["/api/web/organizations/slug/{organizationSlug}/skills/{skillId}"]` | `generated-ready` | N/A | `keep` | none | N/A | existing `commands/skill/*.test.ts`; needed path/type snapshot once independent generation exists |
46
+ | SKILL-01 | skill | `aipctl skill list`, `aipctl skill get`, `aipctl skill delete` | `listSkills`, `getSkill`, `deleteSkill` | api | `GET`, `GET`, `DELETE` | `/api/cli/v1/organizations/{organizationSlug}/skills`; `/api/cli/v1/organizations/{organizationSlug}/skills/{skillId}` | query `{ count,cursor,search }`; detail query `{ maxFiles }` | local `ListSkillsResponse`, `SkillDetail`, `void` | `resource/oas/modules/backend/cli/openapi.yaml` → `v1_skills*.yaml` (DTO aliases to organization Skills OAS) | `backend/api/.../cli/generated/api/CliSkillApi.kt`; domain DTOs remain `com.querypie.duplo.api.skills.generated.model.*` | `generated-ready` | `P0` | `migrate` | none; `CliSkillApiController` delegates to the existing member authorization/audit controller | `AI-6344` | `src/core/api.test.ts`, `CliSkillDriveApiControllerTest`, Gateway registry/contract parity; production CLI and local 403/404 checks (401/429 remain common gates) |
47
47
  | SKILL-02 | skill | `aipctl skill upload` | `createUploadUrl` → `uploadToS3` → `completeUpload` (`abortUpload` on failure) | api + external | `POST` → `PUT` → `POST` | `/skills/upload-url`; external presigned `uploadUrl`; `/skills/{skillId}/complete` | local upload request `{ filename,fileSize,mimeType }`, file buffer, complete body `{ overwrite }` | `CreateSkillUploadUrlResponse`, external `void`, `CompleteSkillUploadResponse` | `resource/oas/modules/backend/organization/skills/openapi.yaml` | `frontend/packages/api/src/out/modules/organization-skills-types.ts#paths["/api/web/organizations/slug/{organizationSlug}/skills/upload-url"]`, `#paths["/api/web/organizations/slug/{organizationSlug}/skills/{skillId}/complete"]` | `external-presigned` | N/A | `keep` | none | N/A | existing skill upload tests; needed presigned URL + complete path snapshot |
48
- | SKILL-03 | skill | `aipctl skill library`, `aipctl skill clone`, `aipctl skill built-in`, `aipctl skill clone-built-in`; `aipctl admin skill built-in`, `aipctl admin skill clone-built-in` | `listLibrarySkills`, `cloneSkills`, `listBuiltInSkills`, `cloneBuiltInSkills` | api | `GET`, `POST`, `GET`, `POST` | `/skills/library`; `/skills/library/clone`; `/admin/.../skills/built-in-library`; `/built-in-library/clone` | list query `{ count,cursor,search/limit }`; clone body `{ sourceSkillIds[] }` | local list/clone DTOs | `resource/oas/modules/backend/organization/skills/openapi.yaml` | `frontend/packages/api/src/out/modules/organization-skills-types.ts#paths["/api/web/organizations/slug/{organizationSlug}/skills/library"]`, `#paths["/api/web/organizations/slug/{organizationSlug}/skills/library/clone"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills/built-in-library"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills/built-in-library/clone"]` | `generated-ready` | N/A | `keep` | none | N/A | existing skill extended tests; needed built-in/library path snapshot |
49
- | SKILL-04 | skill-admin | `aipctl admin skill list`, `get`, `delete`, `publish`, `unpublish` | `listAdminSkills`, `getAdminSkill`, `deleteAdminSkill`, `updateAdminSkill` | api | `GET`, `GET`, `DELETE`, `PATCH` | `/api/web/admin/organizations/slug/{organizationSlug}/skills`; `/skills/{skillId}` | list query `{ pageNumber,pageSize,search }`; publish toggle body `{ availableInLibrary: boolean }` | local `ListAdminSkillsResponse`, `SkillDetail`, `void` | `resource/oas/modules/backend/organization/skills/openapi.yaml` | `frontend/packages/api/src/out/modules/organization-skills-types.ts#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills/{skillId}"]` | `generated-ready` | N/A | `keep` | none | N/A | existing `commands/admin/skill.test.ts`; needed admin list/detail/update path snapshot |
48
+ | SKILL-03 | skill | `aipctl skill library`, `aipctl skill clone`, `aipctl skill built-in`, `aipctl skill clone-built-in`; `aipctl admin skill built-in`, `aipctl admin skill clone-built-in` | `listLibrarySkills`, `cloneSkills`, `listBuiltInSkills`, `cloneBuiltInSkills`, `listAdminBuiltInSkills`, `cloneAdminBuiltInSkills` | api | `GET`, `POST`, `GET`, `POST`, `GET`, `POST` | `/api/cli/v1/organizations/{organizationSlug}/skills/library`; `/skills/library/clone`; `/skills/built-in`; `/skills/built-in/clone`; `/admin/skills/built-in`; `/admin/skills/built-in/clone` | list query `{ count,cursor,search/limit }`; clone body `{ sourceSkillIds[] }` | local list/clone DTOs | `resource/oas/modules/backend/cli/openapi.yaml` → `v1_skills_library*`, `v1_skills_built-in*`, `v1_admin_skills_built-in*` (aliases to organization Skills OAS) | `backend/api/.../cli/generated/api/CliSkillApi.kt`; domain DTOs remain `com.querypie.duplo.api.skills.generated.model.*` | `generated-ready` | `P0` | `migrate` | none; built-in execution reuses the existing AI-operator authorization owner while CLI API methods preserve general/admin operation identity | `AI-6344` | existing skill extended/admin tests, API path tests, adapter test, Gateway registry/contract parity and production CLI clone/list checks |
49
+ | SKILL-04 | skill-admin | `aipctl admin skill list`, `get`, `delete`, `publish`, `unpublish` | `listAdminSkills`, `getAdminSkill`, `deleteAdminSkill`, `updateAdminSkill` | api | `GET`, `GET`, `DELETE`, `PATCH` | `/api/cli/v1/organizations/{organizationSlug}/admin/skills`; `/admin/skills/{skillId}` | list query `{ pageNumber,pageSize,search }`; publish toggle body `{ availableInLibrary: boolean }` | local `ListAdminSkillsResponse`, `SkillDetail`, `void` | `resource/oas/modules/backend/cli/openapi.yaml` → `v1_admin_skills*.yaml` (DTO aliases to organization Skills OAS) | `backend/api/.../cli/generated/api/CliSkillApi.kt`; domain DTOs remain `com.querypie.duplo.api.skills.generated.model.*` | `generated-ready` | `P0` | `migrate` | none; `CliSkillApiController` delegates AI-operator authorization, workflow and audit owner | `AI-6344` | existing `commands/admin/skill.test.ts`, adapter test, Gateway parity; production admin list/publish/delete and 403/429 checks |
50
50
  | SKILL-05 | skill-admin | `aipctl skill download`; `aipctl admin skill upload`, `aipctl admin skill download`, `aipctl admin skill github inspect/import/sync/credentials set/clear` | `createAdminUploadUrl` → `uploadToS3` → `completeAdminUpload` (`abortAdminUpload` on failure); `getSkillDownloadUrl` → `downloadFromUrl`; `inspectGitHubSkillSource`, `prepareGitHubSkill`, `syncPrepareGitHubSkill`, `updateGitHubSkillCredentials` | api + external | `POST`/`PUT`/`POST`; `POST`/`GET`; `POST`, `POST`, `POST`, `PATCH` | `/admin/.../skills/upload-url`; `/admin/.../skills/download-url`; `/admin/.../skills/github-repo-inspect`; `/github-prepare`; `/{skillId}/sync-prepare`; `/{skillId}/github-credentials` | upload/download local bodies; GitHub inspect/prepare `{ url, pat? }`; credentials `{ pat or null }` | upload/download/GitHub admin skill DTOs | `resource/oas/modules/backend/organization/skills/openapi.yaml` | `frontend/packages/api/src/out/modules/organization-skills-types.ts#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills/upload-url"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills/download-url"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills/github-repo-inspect"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills/github-prepare"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills/{skillId}/sync-prepare"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/skills/{skillId}/github-credentials"]` | `external-presigned` | N/A | `keep` | none | N/A | existing `commands/admin/skill.test.ts`, `commands/skill/skill-extended.test.ts`; needed GitHub admin skill contract fixtures |
51
51
  | P1-SKILL-01 | skill-docs | `aipctl skill get --json`, `aipctl admin skill get --json`, `aipctl admin skill github import/sync --json` | same owners as `SKILL-01`/`SKILL-05` | api | same as upstream rows | same as upstream rows | runtime/JSON/help/docs now align on `source`, `origin`, `updateAvailable`, `secretsAvailable`, GitHub metadata, `secretKeys`; stale `version` and file `size` removed | JSON/help/docs contract for skill objects | `resource/oas/modules/backend/organization/skills/openapi.yaml` | `frontend/packages/api/src/out/modules/organization-skills-types.ts#components[...]` | `generated-ready` | `P1` | `keep` | none | N/A | updated `src/core/api.test.ts`, `commands/skill/skill.test.ts`, `commands/skill/skill-extended.test.ts`, `commands/admin/skill.test.ts`, `commands/json-format.test.ts`, `../docs/how-to/aip-cli-usage.md`; covers JSON/help/docs field sync |
52
52
  | P0-AGENT-01 | agent-user | `aipctl agent list`, `aipctl agent get` | `listInstalledAgents`, `getInstalledAgent` | api | `GET`, `GET` | `/api/cli/v1/organizations/{organizationSlug}/agents`; `/{installedAgentId}` | preserves user read semantics and maps `list`/`installedAgentId` to local `data`/`id` | local `ListInstalledAgentsResponse`, `{ data: InstalledAgentDetail }` | `resource/oas/modules/backend/cli/openapi.yaml`; shared DTO refs from `resource/oas/duplo.yaml` | `backend/api/.../cli/generated/api/CliAgentApi.kt` | `generated-ready` | `P0` | `migrate` | none; dedicated adapter delegates to the working `AgentsApiController` bean | `AI-6344` | `src/core/api.test.ts`, `CliAgentApiControllerTest`, Gateway registry/admission parity; real local production CLI list/get JSON |
@@ -54,10 +54,10 @@
54
54
  | P0-AGENT-03 | agent-export | `aipctl admin agent export` (GA-CANDIDATE, production gated) | `exportInstalledAgent` | api | `GET` | `/web/admin/organizations/slug/{organizationSlug}/installed-agents/{installedAgentId}/export` | existing direct controller request | YAML `Buffer` | `backend/api/.../app/controller/AgentExportController.kt`; intentionally OAS-codegen excluded | none | `legacy-generated` | `P0` | `legacy-exception` | owner=`AgentExportController`; dedicated transfer contract, size/timeout/partial-file/authorization/audit gates remain | `AI-6380` | existing direct export path/Buffer/404 tests; production help remains hidden |
55
55
  | P1-CHAT-01 | agent-chat | `aipctl agent chat` | `agentNewChat`, `agentChat`, local `parseSseStream` | chat | `POST` + SSE | `/librechat/api/{orgSlug}/agent/new-chat`; `/librechat/api/{orgSlug}/agent/chat` | request body `{ agentInstallationId or conversationId, text, files: [] }` | local `AgentChatResult { text, conversationId }` parsed from SSE event fields `final`, `conversation.conversationId`, `responseMessage` | path source: `resource/oas/chat.yaml` | `frontend/packages/api/src/out/chat-types.ts#paths["/librechat/api/{orgSlug}/agent/new-chat"]`, `#paths["/librechat/api/{orgSlug}/agent/chat"]` | `stream-exception` | `P1` | `legacy-exception` | owner=`chat backend agent SSE stream contract`; rationale=`path exists in OpenAPI but final SSE event payload is still out-of-band`; removal condition=`official SSE event schema or versioned fixture is published with the chat contract`; incorporation plan=`bind CLI parser/tests to the published SSE fixture and drop local-only stream assumptions` | N/A | updated `src/core/api.test.ts`; covers content[] text, fallback text, malformed event skip, and no-final-event failure |
56
56
  | P1-AUTO-01 | automation | `aipctl automation list`, `get`, `create`, `update`, `delete`, `run`, `enable`, `disable`, `history`, `cancel`, `webhook-regen`, `triggers` | `listAutomations`, `getAutomation`, `createAutomation`, `updateAutomation`, `deleteAutomation`, `runAutomation`, `updateAutomationStatus`, `listAutomationHistories`, `cancelAutomationHistory`, `regenerateWebhookUrl`, `getTriggerProviderMetadata` | api | `GET`, `POST`, `PUT`, `DELETE` mix | `/api/web/organizations/slug/{organizationSlug}/automations...`; `/automation-trigger-providers/.../metadata` | automation pagination normalized to `{ page, pageSize, total }`; metadata calls now use provider-specific OAS paths and required args (`accountId`, `folderId`, `serviceType`) | local automation DTOs + webhook URL DTO | `resource/oas/modules/backend/automation/user/openapi.yaml` | `frontend/packages/api/src/out/modules/automation-user-types.ts#paths[...]` | `generated-ready` | `P1` | `keep` | none | N/A | updated `src/core/api.test.ts`, `commands/automation/automation.test.ts`, `commands/json-format.test.ts`; covers official pagination fields, provider-specific metadata routes, and unsupported-provider preflight failure |
57
- | CHAT-01 | chat-readonly | `aipctl chat list`, `aipctl chat get`, `aipctl chat messages` | `listConversations`, `getConversation`, `listMessages` | chat | `GET` | `/librechat/api/{orgSlug}/convos`; `/convos/{conversationId}`; `/messages/{conversationId}` | list sends no default query; optional cursor only (`?cursor=...`). `pageSize`/`sortBy`/`sortDirection` defaults removed due deployed Chat validation drift | local `ListConversationsResponse`, `ConversationDetail`, `ChatMessage[]` | `resource/oas/chat.yaml` | `frontend/packages/api/src/out/chat-types.ts#paths["/librechat/api/{orgSlug}/convos"]`, `#paths["/librechat/api/{orgSlug}/convos/{conversationId}"]`, `#paths["/librechat/api/{orgSlug}/messages/{conversationId}"]` | `legacy-generated` | N/A | `keep` | owner=`chat backend`; rationale=`PROD rejects CLI default pageSize/sort query while no-query and cursor-only read path are safe`; removal condition=`chat deployed contract publishes and accepts explicit pagination query for public CLI`; incorporation plan=`reintroduce explicit pagination only after OAS/source/deployed validation align` | N/A | updated `src/core/api.test.ts`, existing `commands/chat/chat.test.ts`; covers default no-query and cursor-only URL |
58
- | P0-DRIVE-01 | drive | `aipctl drive list`, `download`, `delete`, `mkdir`, `rename`, `usage` | `listDriveEntries`, `getDriveDownloadUrl`, `deleteDriveEntries`, `createDriveFolder`, `renameDriveEntry`, `getDriveUsage`, `downloadFromUrl` | api + external | `GET`, `POST`, `POST`, `POST`, `PATCH`, `GET`, external `GET` | `/drive/entries?count=200`; `/drive/entries/download-url`; `/drive/entries/delete`; `/drive/entries/{entryId}`; `/drive/usage` | official list `{ path, hasNext, nextCursor, items }`; delete body `{ entryIds[] }`; rename body `{ newName }`; download body `{ entryIds: [id] }` | official drive list/download DTOs + external file buffer | `resource/oas/modules/backend/organization/storage/openapi.yaml` | `frontend/packages/api/src/out/modules/organization-storage-types.ts#paths["/api/web/organizations/slug/{organizationSlug}/drive/entries"]`, `#paths["/api/web/organizations/slug/{organizationSlug}/drive/entries/download-url"]`, `#paths["/api/web/organizations/slug/{organizationSlug}/drive/entries/{entryId}"]`, `#paths["/api/web/organizations/slug/{organizationSlug}/drive/entries/delete"]`, `#paths["/api/web/organizations/slug/{organizationSlug}/drive/usage"]` | `generated-ready` | `P0` | `migrate` | none | `AIP-PUB-05` | updated `src/core/api.test.ts`, `commands/drive/drive.test.ts`; covers paged list shape, batch download-url request, DTO field rename (`sizeBytes`, `modifiedAt`) |
57
+ | CHAT-01 | chat-readonly | `aipctl chat list`, `aipctl chat get`, `aipctl chat messages` | `listConversations`, `getConversation`, `listMessages` | chat | `GET` | `/api/cli/v1/organizations/{orgSlug}/chats`; `/chats/{conversationId}`; `/chats/{conversationId}/messages` | list sends optional cursor; server fixes bounded `updatedAt desc` page size; detail/messages preserve organization and user ownership | local `ListConversationsResponse`, `ConversationDetail`, `ChatMessage[]` | `chat/packages/chat/src/modules/cli-chat/interface/cli-chat-read-v1.interface.controller.ts` | code-first controller contract with `operationId`/quota/capability extensions; no generated backend artifact | `oas-source-only` | `P0` | `migrate` | none; `CliChatReadInterfaceService` reuses the existing conversation/message ownership services and returns CLI-safe fields only | `AI-6344` | updated `src/core/api.test.ts`, Chat read service spec, Gateway registry/contract parity; local CLI/Chat verification covers cursor and no legacy fallback |
58
+ | P0-DRIVE-01 | drive | `aipctl drive list`, `download`, `delete`, `mkdir`, `rename`, `usage` | `listDriveEntries`, `getDriveDownloadUrl`, `deleteDriveEntries`, `createDriveFolder`, `renameDriveEntry`, `getDriveUsage`, `downloadFromUrl` | api + external | `GET`, `POST`, `POST`, `POST`, `PATCH`, `GET`, external `GET` | CLI-managed basic CRUD: `/api/cli/v1/organizations/{organizationSlug}/drive/entries?count=200`, `/drive/entries/delete`, `/drive/folders`, `/drive/entries/{entryId}`, `/drive/usage`; download/upload remain Web/presigned | official list `{ path, hasNext, nextCursor, items }`; delete body `{ entryIds[] }`; mkdir optional `parentId`; rename body `{ newName }`; download body `{ entryIds: [id] }` | official drive list/download DTOs + external file buffer | `resource/oas/modules/backend/cli/openapi.yaml` → `v1_drive_*.yaml` (DTO aliases to organization Storage OAS); download/upload remain `resource/oas/modules/backend/organization/storage/openapi.yaml` | `backend/api/.../cli/generated/api/CliDriveApi.kt`; domain DTOs remain `com.querypie.duplo.api.drive.controller.generated.model.*` | `generated-ready` | `P0` | `migrate` | none; `CliDriveApiController` delegates membership, capacity and audit owner | `AI-6344` | `src/core/api.test.ts`, `CliSkillDriveApiControllerTest`, Gateway registry/contract parity; production CRUD/usage and local 403/404 checks (401/429 remain common gates) |
59
59
  | P0-DRIVE-02 | drive | `aipctl drive upload` | `createDriveUploadUrl` → `uploadToS3` → `completeDriveUpload` | api + external | `POST` → `PUT` → `POST` | `/drive/entries/upload-url`; external presigned `uploadUrl`; `/drive/entries/{entryId}/complete` | official upload request `{ parentId: null, filename, fileSize, mimeType }` | official `CreateDriveUploadUrlResponse { id, filename, uploadUrl, headers }` then `void` | `resource/oas/modules/backend/organization/storage/openapi.yaml` | `frontend/packages/api/src/out/modules/organization-storage-types.ts#paths["/api/web/organizations/slug/{organizationSlug}/drive/entries/upload-url"]`, `#paths["/api/web/organizations/slug/{organizationSlug}/drive/entries/{entryId}/complete"]` | `generated-ready` | `P0` | `migrate` | none | `AIP-PUB-05` | updated `src/core/api.test.ts`, `commands/drive/drive.test.ts`; covers `parentId: null` request and response `id`/`filename` usage |
60
- | P1-INT-01 | integration | `aipctl integration list`, `test`; `aipctl admin integration get`, `update`, `delete`, `tools`, `available` | `listIntegrations`, `testIntegration`, `getIntegration`, `updateIntegration`, `deleteIntegration`, `listIntegrationTools`, `listConfigurableIntegrations` | api | `GET`, `POST`, `GET`, `PUT`, `DELETE`, `GET`, `GET` | `/api/web/integrations/v2`; `/api/web/integration/{integrationId}/test`; `/api/web/admin/organizations/slug/{organizationSlug}/integrations/{integrationId}`; `/{integrationId}/tools`; `/configurable-integrations` | top-level list/test and admin detail/available now follow current/legacy OAS path+body+DTO where available; admin update/delete still accept untyped legacy mutation body/path until admin mutation contract lands | local `Integration`, `IntegrationDetail`, `IntegrationToolsResponse`, `ConfigurableIntegration[]` | legacy admin paths: `resource/oas/duplo-web.yaml`; partial modern source: `resource/oas/modules/backend/integration/openapi.yaml` (does not cover these admin list/CRUD/tools paths) | legacy `frontend/packages/api/src/out/user-types.ts#paths["/api/web/admin/organizations/slug/{organizationSlug}/integrations"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/configurable-integrations"]`; partial current `frontend/packages/api/src/out/modules/integration-types.ts` lacks these admin list/CRUD/tools paths | `legacy-generated` | `P1` | `legacy-exception` | owner=`backend app Integrations / duplo-web legacy OAS`; rationale=`public beta keeps integration list/test/admin detail/tools/available, but admin update/delete still lack an approved current contract outside legacy duplo-web`; removal condition=`independent contract covers user list/test plus admin CRUD/tools/available`; incorporation plan=`extend integration module or independent contract for list/test/admin CRUD/tools/available, then retire legacy path/body mappings and delete/update exception` | N/A | updated `src/core/api.test.ts`, `commands/integration/integration.test.ts`; covers v2 list query, test body `{ organizationSlug }`, admin detail/tools DTO fields, configurable wrapper unwrap, and pinned update/delete legacy paths |
60
+ | P1-INT-01 | integration | `aipctl integration list`, `test`; `aipctl admin integration get`, `update`, `delete`, `tools`, `available` | `listIntegrations`, `testIntegration`, `getIntegration`, `updateIntegration`, `deleteIntegration`, `listIntegrationTools`, `listConfigurableIntegrations` | api | `GET`, `POST`, `GET`, `PUT`, `DELETE`, `GET`, `GET` | read operations use `/api/cli/v1/organizations/{organizationSlug}/integrations`; `/admin/integrations/available`; `/admin/integrations/{integrationId}`; `/tools`; mutations/test remain legacy candidate paths | read responses use dedicated CLI DTOs; admin detail maps only metadata and configured boolean, never property descriptors or credential values; update/delete/test remain unchanged | local `Integration`, `IntegrationDetail`, `IntegrationToolsResponse`, `ConfigurableIntegration[]` | `resource/oas/modules/backend/cli/openapi.yaml` → `v1_integrations*.yaml` | `backend/api/.../cli/generated/api/CliIntegrationApi.kt`; generated `Cli*Integration*` models | `generated-ready` | `P1` | `migrate` | owner=`backend CLI integration adapter`; rationale=`read-only operations now have a stable v1 contract while external test and mutations retain candidate gates`; removal condition=`dedicated test/mutation contracts pass timeout, redaction and idempotency gates`; incorporation plan=`follow AI-6380 candidate work` | `AI-6344` | updated `src/core/api.test.ts`, Backend adapter/security tests, Gateway registry/contract parity; local CLI read verification and legacy mutation path regression |
61
61
  | P0-MODEL-01 | model | `aipctl model list` | `listModels` | chat | `GET` | `/api/cli/v1/organizations/{orgSlug}/models` | none | `{ models: string[], defaultModel? }` is mapped into `Model[]` and preserves active standard, custom/BYOK, and `etc` catalog IDs | code-first OAS: `chat/packages/chat/src/modules/cli-model-exec/interface/cli-model-exec-v1.interface.controller.ts` | runtime Swagger contract; the existing Web model endpoint remains an independent compatibility reference | `oas-source-only` | `P0` | `migrate` | owner=`Chat CliModelExecV1InterfaceController/ModelInternalService`; rationale=`the dedicated route reuses the existing organization-authorized model domain catalog instead of the narrowed model-exec SharedModel catalog`; removal condition=`none for the CLI route; Web migration is a separate work item`; incorporation plan=`keep the CLI path and capability/registry parity tests aligned with the code-first Chat contract` | `AIP-PUB-05` | `src/core/api.test.ts` verifies the dedicated path, production capability gate, default mapping, and preservation of custom/BYOK and `etc` IDs; Chat service/controller tests verify domain delegation and Swagger extensions |
62
62
  | P1-MODEL-EXEC-01 | model-exec | `aipctl model-exec models`, `get`, `sample`, `chat` | `listModelExecModels`, `executeModelExecChat` | chat | `GET`, `POST` | `/api/cli/v1/organizations/{orgSlug}/model-exec/models`; `/chat` | local `ModelExecChatRequest`; Chat Zod/Swagger DTO source `chat/packages/chat/src/modules/cli-model-exec/interface/dto/cli-model-exec.dto.ts` | local `ModelExecModelCatalog`, `ModelExecChatResponse` | code-first OAS: `chat/packages/chat/src/modules/cli-model-exec/interface/cli-model-exec-v1.interface.controller.ts` | runtime Swagger contract | `oas-source-only` | `P1` | `migrate` | none | `AIP-PUB-05` | `src/core/api.test.ts` verifies both v1 paths; Chat controller contract test verifies operation IDs, request/response schemas, delegation to the existing service, and absence of a v1 image route |
63
63
  | P1-MODEL-EXEC-02 | model-exec-image | `aipctl model-exec image generate` | `executeModelExecImageGeneration`; output uses `downloadFromUrl` | chat + external artifact URL | `POST`, external `GET` | legacy `/api/{orgSlug}/cli/model-exec/images/generations`; response `downloadUrl` | local `ModelExecImageGenerationRequest`; Chat DTO source `chat/packages/chat/src/modules/cli-model-exec/interface/dto/cli-model-exec.dto.ts` | local `ModelExecImageGenerationResponse`; image bytes from external URL | no GA OAS; legacy controller only | none | `oas-missing` | deferred | `hide` | owner=`chat CLI Model Exec API`; rationale=`synchronous image execution, external artifact lifetime, and cost recovery require the deferred async design`; removal condition=`image job/artifact/TTL/My Drive/cost gates pass`; incorporation plan=`publish a separate v1 image job contract only after the deferred design is implemented` | follow-up image hardening | existing image request/path test remains on the legacy route; customer capability must stay disabled |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aipctl",
3
- "version": "2026.9.9",
3
+ "version": "2026.9.11",
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": "95bfb896d5e0e21910685b39eff86f3d35ee5c1b0ef28854912f78fdbc7bee58",
26
- "wrapperHash": "a4ef2565f44cb9eb4a3706246f59427bf40a5275dc7bea030fb30024be6f5ab8",
25
+ "contentHash": "3ba1c423da1af4ecb2cfea8ed116569d9a97e579727ca173bd87fd17a77cdd32",
26
+ "wrapperHash": "40c7bf7e201612bd3435325d09cd6eebe577f5e56184f8e2c0f0a0b0bfa58368",
27
27
  "nativeHash": "006b08c3e391f4571d9b7c0f12d684fe2448106259e7e0581b10f9be362452e9"
28
28
  },
29
29
  "optionalDependencies": {