aipctl 2026.9.6 → 2026.9.8

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.6".length > 0 ? "2026.9.6" : "0.0.0";
89673
+ const VERSION = "2026.9.8".length > 0 ? "2026.9.8" : "0.0.0";
89674
89674
  const BUILD_ENV = injectedBuildEnv;
89675
89675
  const INCLUDE_NATIVE_LOGS = BUILD_ENV !== "prod";
89676
89676
 
@@ -89804,20 +89804,38 @@ const normalizeAipArgs = (args) => {
89804
89804
  };
89805
89805
 
89806
89806
  const implementedCommandOperationIds = /* @__PURE__ */ new Set([
89807
+ "listCliAgents",
89808
+ "getCliAgent",
89809
+ "listCliAgentTemplates",
89810
+ "createCliAgent",
89811
+ "updateCliAgent",
89812
+ "deleteCliAgent",
89813
+ "updateCliAgentStatus",
89814
+ "getCliAgentShare",
89807
89815
  "getCliMe",
89808
89816
  "getCliUserSettings",
89809
89817
  "listCliOrganizations",
89810
89818
  "getCliOrganizationCapabilities",
89811
89819
  "listCliOrganizationMembers",
89820
+ "listCliModels",
89812
89821
  "listCliModelExecModels",
89813
89822
  "createCliModelChatExecution"
89814
89823
  ]);
89815
89824
  const releaseEnabledCommandOperationIds = /* @__PURE__ */ new Set([
89825
+ "listCliAgents",
89826
+ "getCliAgent",
89827
+ "listCliAgentTemplates",
89828
+ "createCliAgent",
89829
+ "updateCliAgent",
89830
+ "deleteCliAgent",
89831
+ "updateCliAgentStatus",
89832
+ "getCliAgentShare",
89816
89833
  "getCliMe",
89817
89834
  "getCliUserSettings",
89818
89835
  "listCliOrganizations",
89819
89836
  "getCliOrganizationCapabilities",
89820
89837
  "listCliOrganizationMembers",
89838
+ "listCliModels",
89821
89839
  "listCliModelExecModels"
89822
89840
  ]);
89823
89841
  const direct = (commands, operation) => commands.map((command) => ({
@@ -95289,7 +95307,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95289
95307
  // Phase 2: Agent management
95290
95308
  listInstalledAgents: (orgSlug) => gen(function* () {
95291
95309
  const token = yield* getAccessToken();
95292
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/installed-agents`;
95310
+ yield* requireServerOperation("listCliAgents", token);
95311
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/agents`;
95293
95312
  const raw = yield* makeRequest(baseUrl, path, token);
95294
95313
  return {
95295
95314
  pagination: normalizePageNumberPagination(raw.pagination, raw.list.length),
@@ -95298,7 +95317,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95298
95317
  }),
95299
95318
  getInstalledAgent: (orgSlug, agentId) => gen(function* () {
95300
95319
  const token = yield* getAccessToken();
95301
- const path = `/api/web/organizations/slug/${encodeURIComponent(orgSlug)}/installed-agents/${encodeURIComponent(agentId)}`;
95320
+ yield* requireServerOperation("getCliAgent", token);
95321
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/agents/${encodeURIComponent(agentId)}`;
95302
95322
  const raw = yield* makeRequest(baseUrl, path, token);
95303
95323
  return {
95304
95324
  data: {
@@ -95310,7 +95330,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95310
95330
  }),
95311
95331
  updateInstalledAgentStatus: (orgSlug, agentId, status) => gen(function* () {
95312
95332
  const token = yield* getAccessToken();
95313
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/installed-agents/${encodeURIComponent(agentId)}/status`;
95333
+ yield* requireServerOperation("updateCliAgentStatus", token);
95334
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/agents/${encodeURIComponent(agentId)}/status`;
95314
95335
  return yield* makeRequest(baseUrl, path, token, {
95315
95336
  method: "PATCH",
95316
95337
  body: { status }
@@ -95405,7 +95426,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95405
95426
  listModels: (orgSlug) => gen(function* () {
95406
95427
  yield* requireChatBaseUrlEffect();
95407
95428
  const token = yield* getAccessToken();
95408
- const path = `/api/${encodeURIComponent(orgSlug)}/models`;
95429
+ yield* requireServerOperation("listCliModels", token);
95430
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/models`;
95409
95431
  const response = yield* makeRequest(chatBaseUrl, path, token);
95410
95432
  return response.models.map((id) => ({
95411
95433
  id,
@@ -95602,7 +95624,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95602
95624
  // Phase 8: Agent admin CRUD
95603
95625
  createInstalledAgent: (orgSlug, body) => gen(function* () {
95604
95626
  const token = yield* getAccessToken();
95605
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/installed-agents`;
95627
+ yield* requireServerOperation("createCliAgent", token);
95628
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/agents`;
95606
95629
  return yield* makeRequest(baseUrl, path, token, {
95607
95630
  method: "POST",
95608
95631
  body
@@ -95610,7 +95633,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95610
95633
  }),
95611
95634
  updateInstalledAgent: (orgSlug, agentId, body) => gen(function* () {
95612
95635
  const token = yield* getAccessToken();
95613
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/installed-agents/${encodeURIComponent(agentId)}`;
95636
+ yield* requireServerOperation("updateCliAgent", token);
95637
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/agents/${encodeURIComponent(agentId)}`;
95614
95638
  return yield* makeRequest(baseUrl, path, token, {
95615
95639
  method: "PATCH",
95616
95640
  body
@@ -95618,7 +95642,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95618
95642
  }),
95619
95643
  deleteInstalledAgent: (orgSlug, agentId) => gen(function* () {
95620
95644
  const token = yield* getAccessToken();
95621
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/installed-agents/${encodeURIComponent(agentId)}`;
95645
+ yield* requireServerOperation("deleteCliAgent", token);
95646
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/agents/${encodeURIComponent(agentId)}`;
95622
95647
  return yield* makeRequest(baseUrl, path, token, { method: "DELETE" });
95623
95648
  }),
95624
95649
  exportInstalledAgent: (orgSlug, agentId) => gen(function* () {
@@ -95644,7 +95669,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95644
95669
  }),
95645
95670
  getInstalledAgentShare: (orgSlug, agentId) => gen(function* () {
95646
95671
  const token = yield* getAccessToken();
95647
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/installed-agents/${encodeURIComponent(agentId)}/share`;
95672
+ yield* requireServerOperation("getCliAgentShare", token);
95673
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/agents/${encodeURIComponent(agentId)}/share`;
95648
95674
  const raw = yield* makeRequest(baseUrl, path, token);
95649
95675
  const sharedUserList = yield* try_({
95650
95676
  try: () => normalizeSharedUserList(raw.sharedUserList),
@@ -95657,11 +95683,19 @@ const makeApiServiceLive = (buildEnv) => effect$1(
95657
95683
  }),
95658
95684
  listAgentTemplates: (orgSlug) => gen(function* () {
95659
95685
  const token = yield* getAccessToken();
95660
- const path = `/api/web/admin/organizations/slug/${encodeURIComponent(orgSlug)}/agents`;
95661
- const raw = yield* makeRequest(baseUrl, path, token);
95686
+ yield* requireServerOperation("listCliAgentTemplates", token);
95687
+ const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/agents/templates`;
95688
+ const templates = [];
95689
+ let page = 1;
95690
+ while (true) {
95691
+ const raw = yield* makeRequest(baseUrl, page === 1 ? path : `${path}?page=${page}`, token);
95692
+ templates.push(...raw.list);
95693
+ if (raw.list.length === 0 || page * raw.pagination.pageSize >= raw.pagination.total) break;
95694
+ page += 1;
95695
+ }
95662
95696
  return {
95663
- pagination: { pageNumber: 1, pageSize: raw.length, totalCount: raw.length },
95664
- data: raw.map((item) => ({
95697
+ pagination: { pageNumber: 1, pageSize: templates.length, totalCount: templates.length },
95698
+ data: templates.map((item) => ({
95665
95699
  id: item.agentId,
95666
95700
  displayName: item.label,
95667
95701
  categories: item.categoryList,
@@ -49,15 +49,16 @@
49
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 |
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
- | P0-AGENT-01 | agent-user | `aipctl agent list`, `aipctl agent get` | `listInstalledAgents`, `getInstalledAgent` | api | `GET`, `GET` | `/api/web/organizations/slug/{organizationSlug}/installed-agents`; `/installed-agents/{installedAgentId}` | legacy implemented endpoint maps `list`/`installedAgentId` into CLI `data`/`id`; detail wraps legacy response in `{ data }` and maps `installedIntegrationList` fallback | local `ListInstalledAgentsResponse`, `{ data: InstalledAgentDetail }` | implemented: `resource/oas/duplo.yaml`; future v2 source: `resource/oas/modules/backend/agent/user/openapi.yaml` | legacy `frontend/packages/api/src/out/user-types.ts#paths["/api/web/organizations/slug/{organizationSlug}/installed-agents"]`, `#paths["/api/web/organizations/slug/{organizationSlug}/installed-agents/{installedAgentId}"]` | `legacy-generated` | `P0` | `keep legacy` | owner=`backend app AgentsApiController`; rationale=`agent v2 controllers currently throw NotImplementedError in this repo, so public beta must call implemented legacy endpoints`; removal condition=`AgentUserApiController v2 methods are implemented and deployed`; incorporation plan=`switch to agent v2 OAS/generated contract only after backend implementation lands` | `AIP-PUB-05` | updated `src/core/api.test.ts`, `commands/agent/agent.test.ts`; covers implemented legacy list/detail path and response mapping |
53
- | P0-AGENT-02 | agent-admin | `aipctl admin agent create`, `update`, `delete`, `export`, `share`, `templates`; `aipctl agent enable`, `disable` | `createInstalledAgent`, `updateInstalledAgent`, `deleteInstalledAgent`, `exportInstalledAgent`, `getInstalledAgentShare`, `listAgentTemplates`, `updateInstalledAgentStatus` | api | `POST`, `PATCH`, `DELETE`, `GET`, `GET`, `GET`, `PATCH` | `/api/web/admin/organizations/slug/{organizationSlug}/installed-agents`; `/{installedAgentId}`; export uses legacy direct `/web/admin/organizations/slug/{organizationSlug}/installed-agents/{installedAgentId}/export`; `/share`; `/agents`; `/{installedAgentId}/status` | create/update bodies follow implemented legacy admin request (`custom.iconKeyOrUrl`, `knowledgeBundleIdList`); export is YAML bytes from direct controller path; templates map legacy `agentId`/`label`/`categoryList`; status body `{ status }` | create/update return plain `{ id }`; local admin agent DTOs + `Buffer` export | implemented: `resource/oas/duplo.yaml`; export controller path: `backend/api/src/main/kotlin/com/querypie/duplo/api/app/controller/AgentExportController.kt`; future v2 source: `resource/oas/modules/backend/agent/admin/openapi.yaml` | legacy `frontend/packages/api/src/out/user-types.ts#paths["/api/web/admin/organizations/slug/{organizationSlug}/installed-agents"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/installed-agents/{installedAgentId}"]`, `#paths["/api/web/admin/organizations/slug/{organizationSlug}/agents"]`; export path intentionally OAS-codegen excluded | `legacy-generated` | `P0` | `keep legacy` | owner=`backend app AgentsApiController + AgentExportController`; rationale=`agent v2 admin controllers currently throw NotImplementedError and export is implemented only at /web/admin direct controller path in PROD`; removal condition=`AgentAdminApiController v2 and export path are implemented/deployed under versioned OAS path`; incorporation plan=`switch to agent v2 OAS/generated contract only after backend implementation lands, then remove direct export exception` | `AIP-PUB-05` | updated `src/core/api.test.ts`, `commands/agent/agent.test.ts`; covers implemented legacy CRUD/status/template path/body, direct export path, Buffer response, and 404 propagation |
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 |
53
+ | P0-AGENT-02 | agent-admin | `aipctl admin agent create`, `update`, `delete`, `share`, `templates`; `aipctl agent enable`, `disable` | `createInstalledAgent`, `updateInstalledAgent`, `deleteInstalledAgent`, `getInstalledAgentShare`, `listAgentTemplates`, `updateInstalledAgentStatus` | api | `POST`, `PATCH`, `DELETE`, `GET`, `GET`, `PATCH` | `/api/cli/v1/organizations/{organizationSlug}/agents`; `/{installedAgentId}`; `/{installedAgentId}/share`; `/templates`; `/{installedAgentId}/status` | existing create/update/status bodies; templates collect bounded pages and retain the full catalog; share is read-only | create/update `{ id }`, void mutation responses, existing CLI template/share mapping | `resource/oas/modules/backend/cli/openapi.yaml`; shared legacy DTO refs | `backend/api/.../cli/generated/api/CliAgentApi.kt` | `generated-ready` | `P0` | `migrate` | none; AI operator/workflow/audit policy stays in existing domain owner | `AI-6344` | all eight operations capability/path tests, mutation non-replay, template paging, real CLI lifecycle/DB/audit and metadata 429 verification |
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 |
54
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 |
55
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 |
56
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 |
57
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`) |
58
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 |
59
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
- | P0-MODEL-01 | model | `aipctl model list` | `listModels` | chat | `GET` | legacy `/api/{orgSlug}/models`; target `/api/cli/v1/organizations/{orgSlug}/models` | none | legacy `{ models: string[], defaultModel? }` is mapped into `Model[]` and preserves active standard, custom/BYOK, and `etc` catalog IDs | legacy source: `resource/oas/chat.yaml`; target CLI source not implemented | `frontend/packages/api/src/out/chat-types.ts#paths["/api/{orgSlug}/models"]` | `legacy-generated` | `P0` | `keep legacy until parity` | owner=`Chat ModelV1Controller/ModelInternalService`; rationale=`the current model-exec v1 catalog is backed by SharedModel and omits active custom/BYOK and etc models`; removal condition=`the dedicated CLI model catalog preserves legacy visible-model and default semantics with authorization and regression tests`; incorporation plan=`implement GET /api/cli/v1/organizations/{orgSlug}/models from the existing model domain, then mark model list IMPLEMENTED and retire the legacy path` | `AIP-PUB-05` | `src/core/api.test.ts` verifies the legacy path and preserves custom/BYOK and etc IDs; availability tests keep dev/local usable and prod disabled until parity |
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 |
61
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 |
62
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 |
63
64
  | USAGE-01 | usage | `aipctl admin usage credit`, `top-users`, `daily-graph`, `daily-users`, `mcp-top` | `getCreditStatistics`, `getCreditTopUsers`, `getCreditDailyGraph`, `getCreditDailyUsers`, `getMcpTopTools` | api | `GET` | `/api/web/admin/organizations/slug/{organizationSlug}/usage/...` | query `{ startDt,endDt,limit,pageNumber,pageSize,userId }` | local usage DTOs, `DailyUsageDetailsResponse.pagination { page,pageSize,total }` | `resource/oas/modules/backend/usage/openapi.yaml` | `frontend/packages/api/src/out/modules/usage-types.ts#paths[...]` | `generated-ready` | N/A | `keep` | none | N/A | existing `commands/usage/usage.test.ts`; needed generated path snapshots |
@@ -83,8 +84,8 @@ CLI `ApiError`는 위 세 code에서 allowlist된 quota detail만 보존하며
83
84
 
84
85
  - `P0-ORG-01` org member list/mutation legacy-exception aligned (done in `AIP-PUB-04`, independent contract follow-up remains)
85
86
  - `P0-ORG-02` org invite-link trio hidden from public beta (done in `AIP-PUB-04`)
86
- - `P0-AGENT-01` user agent remains on implemented legacy endpoints until v2 backend lands
87
- - `P0-AGENT-02` admin agent remains on implemented legacy endpoints until v2 backend lands
87
+ - `P0-AGENT-01` / `P0-AGENT-02` moved to dedicated CLI lifecycle endpoints with metadata quota and capability checks (`AI-6344`)
88
+ - `P0-AGENT-03` export remains a gated transfer candidate (`AI-6380`)
88
89
  - `P0-DRIVE-01` drive list/download/delete/mkdir/rename/usage contract migration (done in `AIP-PUB-04`)
89
90
  - `P0-DRIVE-02` drive upload contract migration (done in `AIP-PUB-04`)
90
91
  - `P0-MODEL-01` model list path/DTO migration (done in `AIP-PUB-04`)
@@ -101,6 +102,6 @@ CLI `ApiError`는 위 세 code에서 allowlist된 quota detail만 보존하며
101
102
  ## Manual notes
102
103
 
103
104
  - Generated reference files under `frontend/packages/api/src/out/**` are inventory links only. They are not imported by CLI source/build/test/lint.
104
- - `agent-user` / `agent-admin` modern OAS files exist under `resource/oas/modules/backend/agent/**`, but current backend v2 controllers throw `NotImplementedError`; current CLI intentionally uses implemented `AgentsApiController` endpoints until v2 implementation lands.
105
+ - Agent lifecycle uses the dedicated `CliAgentApiController` and CLI OAS, delegating internally to the implemented `AgentsApiController` bean. Future v2 implementation can replace that internal owner without changing the CLI endpoint. `agent chat` and `admin agent export` retain their separate candidate gates.
105
106
  - OAuth authorization-server metadata, dynamic client registration, authorize, and token endpoints used by `src/core/oauth.ts` were not found in current `resource/oas`; they need owner-backed contractization.
106
107
  - `config` commands intentionally excluded. local config surface has no network owner.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aipctl",
3
- "version": "2026.9.6",
3
+ "version": "2026.9.8",
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": "cbdcceeb10bb96331c9d30645354766c9172ca096bca981dd1130547ffa81d06",
26
- "wrapperHash": "1f3314676a7f45c0f4672c43eb2e22c1cce93846e6215e31bb9af756c2cd89db",
25
+ "contentHash": "fc535c50b1c26702237a8dbfd683f04ddaec6b84c369c308b9714d1e65c5fc69",
26
+ "wrapperHash": "69f4f9d9e2ed5283318f3b770870f094ae315b9cc579ad426203224c66624461",
27
27
  "nativeHash": "006b08c3e391f4571d9b7c0f12d684fe2448106259e7e0581b10f9be362452e9"
28
28
  },
29
29
  "optionalDependencies": {