aipctl 2026.9.11 → 2026.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.cjs +103 -41
- package/docs/api-contract-inventory.md +7 -6
- package/package.json +3 -3
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.
|
|
89673
|
+
const VERSION = "2026.10.2".length > 0 ? "2026.10.2" : "0.0.0";
|
|
89674
89674
|
const BUILD_ENV = injectedBuildEnv;
|
|
89675
89675
|
const INCLUDE_NATIVE_LOGS = BUILD_ENV !== "prod";
|
|
89676
89676
|
|
|
@@ -89732,6 +89732,19 @@ const isNativeCommandEnabled = (command, includeLogs = INCLUDE_NATIVE_LOGS) => {
|
|
|
89732
89732
|
const FORCED_ARGS_SEPARATOR = "--";
|
|
89733
89733
|
const NATIVE_ROOT_COMMANDS = new Set(nativeCommandNames);
|
|
89734
89734
|
const trailingOptionSpecs = [
|
|
89735
|
+
...["list", "get"].map((command) => ({
|
|
89736
|
+
command: ["automation", command],
|
|
89737
|
+
booleanOptions: /* @__PURE__ */ new Set(["--json"]),
|
|
89738
|
+
valueOptions: /* @__PURE__ */ new Set(["--org", ...command === "list" ? ["--name"] : []]),
|
|
89739
|
+
explicitBooleanValues: true
|
|
89740
|
+
})),
|
|
89741
|
+
{
|
|
89742
|
+
command: ["automation", "delete"],
|
|
89743
|
+
booleanOptions: /* @__PURE__ */ new Set(["--force", "-f"]),
|
|
89744
|
+
valueOptions: /* @__PURE__ */ new Set(["--org"]),
|
|
89745
|
+
explicitBooleanValues: true,
|
|
89746
|
+
booleanAliases: { "-f": "--force" }
|
|
89747
|
+
},
|
|
89735
89748
|
{
|
|
89736
89749
|
command: ["drive", "delete"],
|
|
89737
89750
|
booleanOptions: /* @__PURE__ */ new Set(["--force", "-f"]),
|
|
@@ -89766,6 +89779,19 @@ const normalizeTrailingOptions = (args, spec) => {
|
|
|
89766
89779
|
if (arg === void 0) {
|
|
89767
89780
|
continue;
|
|
89768
89781
|
}
|
|
89782
|
+
if (spec.explicitBooleanValues && spec.booleanOptions.has(getOptionName(arg))) {
|
|
89783
|
+
const nextArg = args[index + 1];
|
|
89784
|
+
const optionName = spec.booleanAliases?.[getOptionName(arg)] ?? getOptionName(arg);
|
|
89785
|
+
if (arg.includes("=")) {
|
|
89786
|
+
options.push(`${optionName}${arg.slice(arg.indexOf("="))}`);
|
|
89787
|
+
} else if (nextArg === "true" || nextArg === "false") {
|
|
89788
|
+
options.push(`${optionName}=${nextArg}`);
|
|
89789
|
+
index += 1;
|
|
89790
|
+
} else {
|
|
89791
|
+
options.push(`${optionName}=true`);
|
|
89792
|
+
}
|
|
89793
|
+
continue;
|
|
89794
|
+
}
|
|
89769
89795
|
if (isBooleanOption(arg, spec)) {
|
|
89770
89796
|
options.push(arg);
|
|
89771
89797
|
continue;
|
|
@@ -89844,7 +89870,22 @@ const implementedCommandOperationIds = /* @__PURE__ */ new Set([
|
|
|
89844
89870
|
"listCliIntegrations",
|
|
89845
89871
|
"listCliAvailableIntegrations",
|
|
89846
89872
|
"getCliAdminIntegration",
|
|
89847
|
-
"listCliIntegrationTools"
|
|
89873
|
+
"listCliIntegrationTools",
|
|
89874
|
+
"listCliAutomations",
|
|
89875
|
+
"getCliAutomation",
|
|
89876
|
+
"listCliAutomationTriggers",
|
|
89877
|
+
"listCliAutomationHistory",
|
|
89878
|
+
"createCliAutomation",
|
|
89879
|
+
"updateCliAutomation",
|
|
89880
|
+
"deleteCliAutomation",
|
|
89881
|
+
"updateCliAutomationStatus",
|
|
89882
|
+
"getCliCreditUsage",
|
|
89883
|
+
"listCliTopUsers",
|
|
89884
|
+
"getCliDailyUsageGraph",
|
|
89885
|
+
"listCliDailyUsers",
|
|
89886
|
+
"listCliTopMcpTools",
|
|
89887
|
+
"listCliAuditLogs",
|
|
89888
|
+
"listCliAuditEventTypes"
|
|
89848
89889
|
]);
|
|
89849
89890
|
const releaseEnabledCommandOperationIds = /* @__PURE__ */ new Set([
|
|
89850
89891
|
"listCliAgents",
|
|
@@ -89886,7 +89927,22 @@ const releaseEnabledCommandOperationIds = /* @__PURE__ */ new Set([
|
|
|
89886
89927
|
"listCliIntegrations",
|
|
89887
89928
|
"listCliAvailableIntegrations",
|
|
89888
89929
|
"getCliAdminIntegration",
|
|
89889
|
-
"listCliIntegrationTools"
|
|
89930
|
+
"listCliIntegrationTools",
|
|
89931
|
+
"listCliAutomations",
|
|
89932
|
+
"getCliAutomation",
|
|
89933
|
+
"listCliAutomationTriggers",
|
|
89934
|
+
"listCliAutomationHistory",
|
|
89935
|
+
"createCliAutomation",
|
|
89936
|
+
"updateCliAutomation",
|
|
89937
|
+
"deleteCliAutomation",
|
|
89938
|
+
"updateCliAutomationStatus",
|
|
89939
|
+
"getCliCreditUsage",
|
|
89940
|
+
"listCliTopUsers",
|
|
89941
|
+
"getCliDailyUsageGraph",
|
|
89942
|
+
"listCliDailyUsers",
|
|
89943
|
+
"listCliTopMcpTools",
|
|
89944
|
+
"listCliAuditLogs",
|
|
89945
|
+
"listCliAuditEventTypes"
|
|
89890
89946
|
]);
|
|
89891
89947
|
const direct = (commands, operation) => commands.map((command) => ({
|
|
89892
89948
|
command,
|
|
@@ -93891,6 +93947,10 @@ function maskSensitiveData(value, options = {}, context = {}) {
|
|
|
93891
93947
|
const shouldUseMaskedCommand = typeof record.command === "string" && typeof record.maskedCommand === "string";
|
|
93892
93948
|
for (const [key, entry] of Object.entries(record)) {
|
|
93893
93949
|
const normalizedKey = normalizeKey(key);
|
|
93950
|
+
if (normalizedKey === "secretconfigured" && typeof entry === "boolean" && !context.forceMaskPrimitives) {
|
|
93951
|
+
masked[key] = entry;
|
|
93952
|
+
continue;
|
|
93953
|
+
}
|
|
93894
93954
|
if (normalizedKey === COMMAND_KEY && shouldUseMaskedCommand) {
|
|
93895
93955
|
masked[key] = record.maskedCommand;
|
|
93896
93956
|
continue;
|
|
@@ -94622,24 +94682,8 @@ function resolveTriggerMetadataRequest(triggerProviderType, options = {}) {
|
|
|
94622
94682
|
}
|
|
94623
94683
|
}
|
|
94624
94684
|
function buildTriggerProviderMetadataPath(orgSlug, request) {
|
|
94625
|
-
const
|
|
94626
|
-
|
|
94627
|
-
case "GMAIL":
|
|
94628
|
-
case "OUTLOOK": {
|
|
94629
|
-
const params = new URLSearchParams({ accountId: request.options.accountId });
|
|
94630
|
-
return `${basePath}/${encodeURIComponent(request.triggerProviderType)}/metadata?${params.toString()}`;
|
|
94631
|
-
}
|
|
94632
|
-
case "google-drive":
|
|
94633
|
-
case "box": {
|
|
94634
|
-
const params = new URLSearchParams({
|
|
94635
|
-
accountId: request.options.accountId,
|
|
94636
|
-
folderId: request.options.folderId
|
|
94637
|
-
});
|
|
94638
|
-
return `${basePath}/${encodeURIComponent(request.triggerProviderType)}/metadata?${params.toString()}`;
|
|
94639
|
-
}
|
|
94640
|
-
case "webhook":
|
|
94641
|
-
return `${basePath}/webhook/${encodeURIComponent(request.options.serviceType)}/metadata`;
|
|
94642
|
-
}
|
|
94685
|
+
const params = new URLSearchParams({ type: request.triggerProviderType, ...request.options });
|
|
94686
|
+
return `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/automations/triggers?${params.toString()}`;
|
|
94643
94687
|
}
|
|
94644
94688
|
function normalizeSharedUserList(sharedUserList) {
|
|
94645
94689
|
return sharedUserList?.map((user, index) => {
|
|
@@ -95363,11 +95407,12 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95363
95407
|
// Phase 3: Automation
|
|
95364
95408
|
listAutomations: (orgSlug, options) => gen(function* () {
|
|
95365
95409
|
const token = yield* getAccessToken();
|
|
95410
|
+
yield* requireReleaseEnabledOperation("listCliAutomations");
|
|
95366
95411
|
const params = new URLSearchParams();
|
|
95367
95412
|
params.set("pageNumber", String(options?.pageNumber ?? 1));
|
|
95368
95413
|
params.set("pageSize", String(options?.pageSize ?? 50));
|
|
95369
95414
|
if (options?.name) params.set("name", options.name);
|
|
95370
|
-
const path = `/api/
|
|
95415
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/automations?${params.toString()}`;
|
|
95371
95416
|
const response = yield* makeRequest(baseUrl, path, token);
|
|
95372
95417
|
return {
|
|
95373
95418
|
...response,
|
|
@@ -95381,18 +95426,20 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95381
95426
|
}),
|
|
95382
95427
|
updateAutomationStatus: (orgSlug, automationId, status) => gen(function* () {
|
|
95383
95428
|
const token = yield* getAccessToken();
|
|
95384
|
-
|
|
95429
|
+
yield* requireReleaseEnabledOperation("updateCliAutomationStatus");
|
|
95430
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/automations/${encodeURIComponent(automationId)}/status`;
|
|
95385
95431
|
return yield* makeRequest(baseUrl, path, token, {
|
|
95386
|
-
method: "
|
|
95432
|
+
method: "PATCH",
|
|
95387
95433
|
body: { status }
|
|
95388
95434
|
});
|
|
95389
95435
|
}),
|
|
95390
95436
|
listAutomationHistories: (orgSlug, automationId, options) => gen(function* () {
|
|
95391
95437
|
const token = yield* getAccessToken();
|
|
95438
|
+
yield* requireReleaseEnabledOperation("listCliAutomationHistory");
|
|
95392
95439
|
const params = new URLSearchParams();
|
|
95393
95440
|
params.set("pageNumber", String(options?.pageNumber ?? 1));
|
|
95394
95441
|
params.set("pageSize", String(options?.pageSize ?? 20));
|
|
95395
|
-
const path = `/api/
|
|
95442
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/automations/${encodeURIComponent(automationId)}/history?${params.toString()}`;
|
|
95396
95443
|
const response = yield* makeRequest(baseUrl, path, token);
|
|
95397
95444
|
return {
|
|
95398
95445
|
...response,
|
|
@@ -95401,12 +95448,14 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95401
95448
|
}),
|
|
95402
95449
|
getAutomation: (orgSlug, automationId) => gen(function* () {
|
|
95403
95450
|
const token = yield* getAccessToken();
|
|
95404
|
-
|
|
95451
|
+
yield* requireReleaseEnabledOperation("getCliAutomation");
|
|
95452
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/automations/${encodeURIComponent(automationId)}`;
|
|
95405
95453
|
return yield* makeRequest(baseUrl, path, token);
|
|
95406
95454
|
}),
|
|
95407
95455
|
createAutomation: (orgSlug, body) => gen(function* () {
|
|
95408
95456
|
const token = yield* getAccessToken();
|
|
95409
|
-
|
|
95457
|
+
yield* requireReleaseEnabledOperation("createCliAutomation");
|
|
95458
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/automations`;
|
|
95410
95459
|
return yield* makeRequest(baseUrl, path, token, {
|
|
95411
95460
|
method: "POST",
|
|
95412
95461
|
body
|
|
@@ -95414,7 +95463,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95414
95463
|
}),
|
|
95415
95464
|
updateAutomation: (orgSlug, automationId, body) => gen(function* () {
|
|
95416
95465
|
const token = yield* getAccessToken();
|
|
95417
|
-
|
|
95466
|
+
yield* requireReleaseEnabledOperation("updateCliAutomation");
|
|
95467
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/automations/${encodeURIComponent(automationId)}`;
|
|
95418
95468
|
return yield* makeRequest(baseUrl, path, token, {
|
|
95419
95469
|
method: "PUT",
|
|
95420
95470
|
body
|
|
@@ -95422,7 +95472,8 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95422
95472
|
}),
|
|
95423
95473
|
deleteAutomation: (orgSlug, automationId) => gen(function* () {
|
|
95424
95474
|
const token = yield* getAccessToken();
|
|
95425
|
-
|
|
95475
|
+
yield* requireReleaseEnabledOperation("deleteCliAutomation");
|
|
95476
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/automations/${encodeURIComponent(automationId)}`;
|
|
95426
95477
|
return yield* makeRequest(baseUrl, path, token, { method: "DELETE" });
|
|
95427
95478
|
}),
|
|
95428
95479
|
cancelAutomationHistory: (orgSlug, automationId, historySeq) => gen(function* () {
|
|
@@ -95485,57 +95536,64 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95485
95536
|
}),
|
|
95486
95537
|
getCreditStatistics: (orgSlug, options) => gen(function* () {
|
|
95487
95538
|
const token = yield* getAccessToken();
|
|
95539
|
+
yield* requireReleaseEnabledOperation("getCliCreditUsage");
|
|
95488
95540
|
const params = new URLSearchParams();
|
|
95489
95541
|
params.set("startDt", options.startDt);
|
|
95490
95542
|
params.set("endDt", options.endDt);
|
|
95491
|
-
const path = `/api/
|
|
95543
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/usage/credit?${params.toString()}`;
|
|
95492
95544
|
return yield* makeRequest(baseUrl, path, token);
|
|
95493
95545
|
}),
|
|
95494
95546
|
getCreditTopUsers: (orgSlug, options) => gen(function* () {
|
|
95495
95547
|
const token = yield* getAccessToken();
|
|
95548
|
+
yield* requireReleaseEnabledOperation("listCliTopUsers");
|
|
95496
95549
|
const params = new URLSearchParams();
|
|
95497
95550
|
params.set("startDt", options.startDt);
|
|
95498
95551
|
params.set("endDt", options.endDt);
|
|
95499
95552
|
params.set("limit", String(options.limit));
|
|
95500
|
-
const path = `/api/
|
|
95553
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/usage/top-users?${params.toString()}`;
|
|
95501
95554
|
return yield* makeRequest(baseUrl, path, token);
|
|
95502
95555
|
}),
|
|
95503
95556
|
getCreditDailyGraph: (orgSlug, options) => gen(function* () {
|
|
95504
95557
|
const token = yield* getAccessToken();
|
|
95558
|
+
yield* requireReleaseEnabledOperation("getCliDailyUsageGraph");
|
|
95505
95559
|
const params = new URLSearchParams();
|
|
95506
95560
|
params.set("startDt", options.startDt);
|
|
95507
95561
|
params.set("endDt", options.endDt);
|
|
95508
|
-
const path = `/api/
|
|
95562
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/usage/daily-graph?${params.toString()}`;
|
|
95509
95563
|
return yield* makeRequest(baseUrl, path, token);
|
|
95510
95564
|
}),
|
|
95511
95565
|
getCreditDailyUsers: (orgSlug, options) => gen(function* () {
|
|
95512
95566
|
const token = yield* getAccessToken();
|
|
95567
|
+
yield* requireReleaseEnabledOperation("listCliDailyUsers");
|
|
95513
95568
|
const params = new URLSearchParams();
|
|
95514
95569
|
params.set("startDt", options.startDt);
|
|
95515
95570
|
params.set("endDt", options.endDt);
|
|
95516
95571
|
params.set("pageNumber", String(options.pageNumber ?? 1));
|
|
95517
95572
|
params.set("pageSize", String(options.pageSize ?? 20));
|
|
95518
95573
|
if (options.userId) params.set("userId", options.userId);
|
|
95519
|
-
const path = `/api/
|
|
95574
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/usage/daily-users?${params.toString()}`;
|
|
95520
95575
|
return yield* makeRequest(baseUrl, path, token);
|
|
95521
95576
|
}),
|
|
95522
95577
|
getMcpTopTools: (orgSlug, options) => gen(function* () {
|
|
95523
95578
|
const token = yield* getAccessToken();
|
|
95579
|
+
yield* requireReleaseEnabledOperation("listCliTopMcpTools");
|
|
95524
95580
|
const params = new URLSearchParams();
|
|
95525
95581
|
params.set("startDt", options.startDt);
|
|
95526
95582
|
params.set("endDt", options.endDt);
|
|
95527
95583
|
params.set("limit", String(options.limit));
|
|
95528
|
-
const path = `/api/
|
|
95584
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/usage/mcp-top?${params.toString()}`;
|
|
95529
95585
|
return yield* makeRequest(baseUrl, path, token);
|
|
95530
95586
|
}),
|
|
95531
95587
|
listAuditLogs: (orgSlug, options) => gen(function* () {
|
|
95532
95588
|
const token = yield* getAccessToken();
|
|
95589
|
+
yield* requireReleaseEnabledOperation("listCliAuditLogs");
|
|
95533
95590
|
const params = new URLSearchParams();
|
|
95534
95591
|
params.set("page", String(options?.page ?? 1));
|
|
95535
95592
|
params.set("pageSize", String(options?.pageSize ?? 20));
|
|
95536
95593
|
if (options?.eventType) params.set("eventType", options.eventType);
|
|
95537
|
-
const path = `/api/
|
|
95538
|
-
|
|
95594
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/audit?${params.toString()}`;
|
|
95595
|
+
const response = yield* makeRequest(baseUrl, path, token);
|
|
95596
|
+
return { ...response, pagination: normalizePageNumberPagination(response.pagination, response.list.length) };
|
|
95539
95597
|
}),
|
|
95540
95598
|
// Phase 5: Drive/Integration
|
|
95541
95599
|
listDriveEntries: (orgSlug) => gen(function* () {
|
|
@@ -95783,6 +95841,7 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95783
95841
|
}),
|
|
95784
95842
|
getTriggerProviderMetadata: (orgSlug, triggerProviderType, options) => gen(function* () {
|
|
95785
95843
|
const token = yield* getAccessToken();
|
|
95844
|
+
yield* requireReleaseEnabledOperation("listCliAutomationTriggers");
|
|
95786
95845
|
const request = yield* try_({
|
|
95787
95846
|
try: () => resolveTriggerMetadataRequest(triggerProviderType, options),
|
|
95788
95847
|
catch: (error) => apiErrorFromUnknown(error, "Invalid trigger provider metadata request")
|
|
@@ -95828,9 +95887,11 @@ const makeApiServiceLive = (buildEnv) => effect$1(
|
|
|
95828
95887
|
return yield* makeRequest(baseUrl, path, token);
|
|
95829
95888
|
}),
|
|
95830
95889
|
// Audit event types
|
|
95831
|
-
listAuditEventTypes: () => gen(function* () {
|
|
95890
|
+
listAuditEventTypes: (orgSlug) => gen(function* () {
|
|
95832
95891
|
const token = yield* getAccessToken();
|
|
95833
|
-
|
|
95892
|
+
yield* requireReleaseEnabledOperation("listCliAuditEventTypes");
|
|
95893
|
+
const path = `/api/cli/v1/organizations/${encodeURIComponent(orgSlug)}/admin/audit/types`;
|
|
95894
|
+
return yield* makeRequest(baseUrl, path, token);
|
|
95834
95895
|
}),
|
|
95835
95896
|
// Org capabilities & user settings
|
|
95836
95897
|
getOrgCapabilities: (orgSlug) => gen(function* () {
|
|
@@ -96352,10 +96413,11 @@ const listCommand$a = make$4(
|
|
|
96352
96413
|
|
|
96353
96414
|
const typesCommand = make$4(
|
|
96354
96415
|
"types",
|
|
96355
|
-
{},
|
|
96356
|
-
() => gen(function* () {
|
|
96416
|
+
{ org: orgOption },
|
|
96417
|
+
({ org }) => gen(function* () {
|
|
96357
96418
|
const api = yield* ApiService;
|
|
96358
|
-
const
|
|
96419
|
+
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
96420
|
+
const eventTypes = yield* api.listAuditEventTypes(orgSlug).pipe(
|
|
96359
96421
|
catchTag(
|
|
96360
96422
|
"NotLoggedInError",
|
|
96361
96423
|
(e) => gen(function* () {
|
|
@@ -53,7 +53,8 @@
|
|
|
53
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
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
|
-
| P1-AUTO-01 | automation | `aipctl automation list`, `get`, `create`, `update`, `delete`, `
|
|
56
|
+
| P1-AUTO-01 | automation | `aipctl automation list`, `get`, `create`, `update`, `delete`, `enable`, `disable`, `history`, `triggers` | `listAutomations`, `getAutomation`, `createAutomation`, `updateAutomation`, `deleteAutomation`, `updateAutomationStatus`, `listAutomationHistories`, `getTriggerProviderMetadata` | api | `GET`, `POST`, `PUT`, `DELETE`, `PATCH` | `/api/cli/v1/organizations/{organizationSlug}/automations`; `/{automationId}`; `/{automationId}/status`; `/{automationId}/history`; `/triggers?type=...` | one-based pageNumber/pageSize (1..100); status `{ status }`; exactly one matching trigger branch; metadata retains required accountId/folderId/serviceType input | existing list/history domain DTOs; dedicated `GetCliAutomationResponse` and ID DTO; webhook detail only serviceType/boolean secretConfigured | `resource/oas/modules/backend/cli/openapi.yaml` → `v1_automations*.yaml`; request/list/history aliases reuse Automation user schemas | `backend/api/.../cli/generated/api/CliAutomationApi.kt` | `generated-ready` | `P1` | `migrate` | owner=`CLI Automation adapter`; Schedule/Webhook/My Drive management enabled; external account provider metadata/mutations return 403 before provider side effects; stored external detail never enriches remotely or fabricates account/folder validity | `AI-6344`; external lifecycle gate `AI-6380`; large pagination gate `AI-6413` | `src/core/automation-contract.test.ts`, `src/core/api.test.ts`, Automation command tests, `redaction.test.ts`, Backend safe-read/controller/audit tests, Gateway parity; real mise servers + production CLI CRUD/ownership/pagination/quota/DB/audit |
|
|
57
|
+
| P1-AUTO-02 | automation-execution | `aipctl automation run`, `cancel`, `webhook-regen` (GA-CANDIDATE, production gated) | `runAutomation`, `cancelAutomationHistory`, `regenerateWebhookUrl` | api | `POST`, `DELETE`, `POST` | legacy `/api/web/organizations/slug/{organizationSlug}/automations/{automationId}/run`; `/histories/{seq}`; `/webhook-url/regen` | existing domain input | existing execution/history/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` | `legacy-exception` | owner=`Automation execution domain`; requires execution quota, idempotency/cancel lifetime, webhook secret rotation and safe output verification before customer enablement | `AI-6380` | existing legacy path/command tests; production availability keeps all three hidden |
|
|
57
58
|
| 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
59
|
| 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
60
|
| 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 |
|
|
@@ -61,10 +62,10 @@
|
|
|
61
62
|
| 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
63
|
| 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
64
|
| 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 |
|
|
64
|
-
| USAGE-01 | usage | `aipctl admin usage credit`, `top-users`, `daily-graph`, `daily-users`, `mcp-top` | `getCreditStatistics`, `getCreditTopUsers`, `getCreditDailyGraph`, `getCreditDailyUsers`, `getMcpTopTools` | api | `GET` | `/api/
|
|
65
|
-
| AUDIT-01 | audit | `aipctl admin audit list`, `types` | `listAuditLogs`, `listAuditEventTypes` | api | `GET` | `/api/
|
|
66
|
-
| TUNNEL-01 | tunnel | `aipctl admin tunnel status`, `config`, `token` | `getTunnelStatus`, `getTunnelConfig`, `createTunnelToken` | api | `GET`, `GET`, `POST` | `/api/web/edge-tunnel/v2/organizations/slug/{organizationSlug}/status`; `/config`; `/token` | none | local `TunnelStatus`, `TunnelConfig`, `void` | `resource/oas/modules/backend/tunnel/openapi.yaml
|
|
67
|
-
| P1-PRESET-01 | preset | `aipctl admin preset list`, `get`, `create`, `update`, `rename`, `delete`, `set-default`, `unset-default
|
|
65
|
+
| USAGE-01 | usage | `aipctl admin usage credit`, `top-users`, `daily-graph`, `daily-users`, `mcp-top` | `getCreditStatistics`, `getCreditTopUsers`, `getCreditDailyGraph`, `getCreditDailyUsers`, `getMcpTopTools` | api | `GET` | `/api/cli/v1/organizations/{organizationSlug}/admin/usage/credit`; `/admin/usage/top-users`; `/admin/usage/daily-graph`; `/admin/usage/daily-users`; `/admin/usage/mcp-top` | query `{ startDt,endDt,limit,pageNumber,pageSize,userId }`; daily-users uses one-based page/pageSize 1..100 | existing usage DTOs; `DailyUsageDetailsResponse.pagination { page,pageSize,total }` normalized to CLI output | `resource/oas/modules/backend/cli/openapi.yaml` → `paths/v1_admin_usage_*.yaml`; response aliases reuse `resource/oas/modules/backend/usage/components/schemas/*` | `backend/api/.../cli/generated/api/CliUsageApi.kt`; domain DTOs remain `com.querypie.duplo.api.usage.generated.model.*` | `generated-ready` | `P0` | `migrate` | none; dedicated adapter preserves organization admin authorization, three-month/future-date validation, and existing aggregation service | `AI-6344`; query/page workload bounds remain `AI-6413` | `src/core/usage-audit-contract.test.ts`, usage command tests, `CliUsageAuditApiControllerTest`, Gateway registry/contract parity; real production CLI verifies all five paths, 401/403/404/400 and future-date clamp |
|
|
66
|
+
| AUDIT-01 | audit | `aipctl admin audit list`, `types` | `listAuditLogs`, `listAuditEventTypes` | api | `GET` | `/api/cli/v1/organizations/{organizationSlug}/admin/audit`; `/api/cli/v1/organizations/{organizationSlug}/admin/audit/types` | query `{ eventType,page,pageSize }`; page is one-based and pageSize is 1..100 | existing `ListAuditResponse`/`AuditEventType[]`; page/total is normalized for CLI pagination output | `resource/oas/modules/backend/cli/openapi.yaml` → `paths/v1_admin_audit*.yaml`; response aliases reuse `resource/oas/modules/backend/audit/components/schemas/*` | `backend/api/.../cli/generated/api/CliAuditApi.kt`; domain DTOs remain `com.querypie.duplo.api.generated.models.*` | `generated-ready` | `P0` | `migrate` | none; dedicated adapter preserves AUDIT_LOGS capability, plan/retention/viewable-period and organization filters | `AI-6344`; audit volume/query workload bounds remain `AI-6413` | `src/core/usage-audit-contract.test.ts`, `commands/admin/audit/*.test.ts`, `CliUsageAuditApiControllerTest`, Gateway registry/contract parity; real production CLI verifies page 2/3, types, 401/403/404/400 |
|
|
67
|
+
| TUNNEL-01 | tunnel | `aipctl admin tunnel status`, `config`, `token` | `getTunnelStatus`, `getTunnelConfig`, `createTunnelToken` | api | `GET`, `GET`, `POST` | status target: `/api/cli/v1/organizations/{organizationSlug}/admin/tunnel/status`; current legacy `/api/web/edge-tunnel/v2/organizations/slug/{organizationSlug}/status`; `/config`; `/token` | none | local `TunnelStatus`, `TunnelConfig`, `void` | current: `resource/oas/modules/backend/tunnel/openapi.yaml`; target status: Backend CLI OAS | current tunnel generated reference; target CLI generated interface pending | `legacy-generated` | N/A | `migrate` | owner=`backend tunnel domain`; rationale=`status is safe GA-DIRECT but config/token expose sensitive material`; removal condition=`status receives its dedicated v1 contract`; incorporation plan=`migrate status only and keep config/token capability-disabled until --show-sensitive, TTL, redaction, and audit gates pass` | `AI-6344` task 3.3d; sensitive gate `AI-6380` | existing tunnel command tests; needed v1 status path/registry/permission/redaction and real CLI verification |
|
|
68
|
+
| P1-PRESET-01 | preset | `aipctl admin preset list`, `get`, `create`, `update`, `rename`, `delete`, `set-default`, `unset-default`; key rotation commands remain candidates | `listPresets`, `getPreset`, `createPreset`, `updatePreset`, `renamePreset`, `deletePreset`, `setPresetAsDefault`, `unsetPresetAsDefault`; `regenPresetKey`, `regenPresetStaticKey` | api | `GET`, `POST`, `PUT`, `PATCH`, `DELETE` mix | target `/api/cli/v1/organizations/{organizationSlug}/admin/presets/**`; current legacy `/api/web/presets/v2`; `/api/web/presets/{presetId}`; `/key`; `/static-key`; `/default` | dedicated v1 basic-management contract pending; current delete is contract-aligned to 204 and CLI tolerates deployed 200 empty only for that legacy void endpoint | local preset DTOs with installation/json command fields; delete returns `void`; key values must not enter the GA-DIRECT response | current `resource/oas/duplo-web.yaml`; target Backend CLI OAS | current legacy generated reference; target CLI generated interface pending | `legacy-generated` | `P1` | `migrate` | owner=`backend app PresetsApiController`/preset domain; rationale=`basic management is GA-DIRECT while key/static-key rotation requires a separate secret/rollback gate`; removal condition=`eight basic operations receive dedicated v1 contracts and actual CLI verification`; incorporation plan=`reuse domain authorization/audit, preserve endpoint-specific void handling, and keep key rotation gated` | `AI-6344` task 3.3b; key gate `AI-6380` | existing legacy tests plus needed v1 OAS/adapter/registry/manifest, permission/audit/idempotency/destructive UX and real mise CLI lifecycle |
|
|
68
69
|
|
|
69
70
|
## 공통 CLI request quota 오류 계약
|
|
70
71
|
|
|
@@ -96,7 +97,7 @@ CLI `ApiError`는 위 여섯 code에서 allowlist된 quota detail만 보존하
|
|
|
96
97
|
### P1 queue
|
|
97
98
|
|
|
98
99
|
- `P1-INT-01` integration legacy-exception documented; current/legacy path+DTO tests added
|
|
99
|
-
- `P1-AUTO-01`
|
|
100
|
+
- `P1-AUTO-01` Automation management uses eight dedicated v1 operations; Schedule/Webhook/My Drive lifecycle and stored safe reads are implemented. External provider metadata/mutations and `P1-AUTO-02` remain gated.
|
|
100
101
|
- `P1-PRESET-01` preset admin namespace/docs + legacy path tests done
|
|
101
102
|
- `P1-SKILL-01` skill JSON/help/docs field sync done
|
|
102
103
|
- `P1-CHAT-01` chat SSE fixture tests added for final/fallback/error cases
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aipctl",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.10.2",
|
|
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": "
|
|
26
|
-
"wrapperHash": "
|
|
25
|
+
"contentHash": "866cf35ffc9e44ebc83327f46bc0f77d229aec2f7b688bbdf0074ae937d41e7e",
|
|
26
|
+
"wrapperHash": "2081868ac4d9ac9204f9f168fc0f33afb220ce17fdaeceb1060e9376ed3b138f",
|
|
27
27
|
"nativeHash": "006b08c3e391f4571d9b7c0f12d684fe2448106259e7e0581b10f9be362452e9"
|
|
28
28
|
},
|
|
29
29
|
"optionalDependencies": {
|