aipctl 2026.7.14 → 2026.7.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -23
- package/build/index.cjs +53 -593
- package/docs/api-contract-inventory.md +0 -2
- package/docs/architecture.md +1 -1
- package/docs/desktop-cli-go-coding-guidelines.md +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -34,29 +34,6 @@ aipctl tunnel link <token>
|
|
|
34
34
|
|
|
35
35
|
`install`, `run`, `tunnel`, `logs`는 Go native binary로 lazy dispatch됩니다. `prod` build에서는 `logs` command가 help와 command tree에서 제외됩니다.
|
|
36
36
|
|
|
37
|
-
## Experimental model execution
|
|
38
|
-
|
|
39
|
-
`aipctl model-exec`은 CLI 전용 one-shot 모델 실행 namespace입니다. Conversation을 만들지 않고, 사용자가 선택한 모델을 한 번 호출해 stdout 또는 파일로 결과를 받습니다.
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
aipctl model-exec models [--type chat|image-generation] [--json]
|
|
43
|
-
aipctl model-exec get <model-id> [--json]
|
|
44
|
-
aipctl model-exec sample <model-id> [--save input.json]
|
|
45
|
-
aipctl model-exec chat --model <chat-model-id> -m "hello" [--json]
|
|
46
|
-
aipctl model-exec image generate --model <image-model-id> --prompt "cat" --output ./cat.png [--json]
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
대화형 터미널에서는 `model-exec chat`과 `model-exec image generate`가 완료될 때까지 spinner와 경과 시간을 stderr에 표시합니다. JSON을 포함한 최종 결과는 기존처럼 stdout에만 출력됩니다.
|
|
50
|
-
|
|
51
|
-
`model-exec image generate`의 이미지 생성 요청 timeout은 최대 5분입니다. 5분 안에 provider 응답이 완료되지 않으면 명령은 실패하며, 이 제한은 one-shot image-generation 요청에만 적용됩니다. `aipctl model-exec image generate --help`와 실행 중 spinner에서도 제한을 확인할 수 있습니다.
|
|
52
|
-
|
|
53
|
-
Conversation을 유지하는 일반 채팅은 `chat send`를 사용합니다.
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
aipctl chat send -m "hello" --json
|
|
57
|
-
aipctl chat send --conversation <conversation-id> -m "continue" --json
|
|
58
|
-
```
|
|
59
|
-
|
|
60
37
|
## Development
|
|
61
38
|
|
|
62
39
|
```bash
|
package/build/index.cjs
CHANGED
|
@@ -89670,7 +89670,7 @@ const injectedBuildEnv = "prod".length > 0 ? "prod" : "local";
|
|
|
89670
89670
|
if (!isBuildEnv(injectedBuildEnv)) {
|
|
89671
89671
|
throw new Error(`Invalid AIPCTL_BUILD_ENV: ${injectedBuildEnv}`);
|
|
89672
89672
|
}
|
|
89673
|
-
const VERSION = "2026.7.
|
|
89673
|
+
const VERSION = "2026.7.16".length > 0 ? "2026.7.16" : "0.0.0";
|
|
89674
89674
|
const BUILD_ENV = injectedBuildEnv;
|
|
89675
89675
|
const INCLUDE_NATIVE_LOGS = BUILD_ENV !== "prod";
|
|
89676
89676
|
|
|
@@ -94487,30 +94487,6 @@ const ApiServiceLive = effect$1(
|
|
|
94487
94487
|
...res.defaultModel === id ? { isDefault: true } : {}
|
|
94488
94488
|
}));
|
|
94489
94489
|
}),
|
|
94490
|
-
listModelExecModels: (orgSlug) => gen(function* () {
|
|
94491
|
-
yield* requireChatBaseUrlEffect();
|
|
94492
|
-
const token = yield* getAccessToken();
|
|
94493
|
-
const path = `/api/${encodeURIComponent(orgSlug)}/cli/model-exec/models`;
|
|
94494
|
-
return yield* makeRequest(chatBaseUrl, path, token);
|
|
94495
|
-
}),
|
|
94496
|
-
executeModelExecChat: (orgSlug, body) => gen(function* () {
|
|
94497
|
-
yield* requireChatBaseUrlEffect();
|
|
94498
|
-
const token = yield* getAccessToken();
|
|
94499
|
-
const path = `/api/${encodeURIComponent(orgSlug)}/cli/model-exec/chat`;
|
|
94500
|
-
return yield* makeRequest(chatBaseUrl, path, token, {
|
|
94501
|
-
method: "POST",
|
|
94502
|
-
body
|
|
94503
|
-
});
|
|
94504
|
-
}),
|
|
94505
|
-
executeModelExecImageGeneration: (orgSlug, body) => gen(function* () {
|
|
94506
|
-
yield* requireChatBaseUrlEffect();
|
|
94507
|
-
const token = yield* getAccessToken();
|
|
94508
|
-
const path = `/api/${encodeURIComponent(orgSlug)}/cli/model-exec/images/generations`;
|
|
94509
|
-
return yield* makeRequest(chatBaseUrl, path, token, {
|
|
94510
|
-
method: "POST",
|
|
94511
|
-
body
|
|
94512
|
-
});
|
|
94513
|
-
}),
|
|
94514
94490
|
getCreditStatistics: (orgSlug, options) => gen(function* () {
|
|
94515
94491
|
const token = yield* getAccessToken();
|
|
94516
94492
|
const params = new URLSearchParams();
|
|
@@ -94662,15 +94638,6 @@ const ApiServiceLive = effect$1(
|
|
|
94662
94638
|
const path = `/librechat/api/${encodeURIComponent(orgSlug)}/messages/${encodeURIComponent(conversationId)}`;
|
|
94663
94639
|
return yield* makeRequest(chatBaseUrl, path, token);
|
|
94664
94640
|
}),
|
|
94665
|
-
sendChatMessage: (orgSlug, body) => gen(function* () {
|
|
94666
|
-
yield* requireChatBaseUrlEffect();
|
|
94667
|
-
const token = yield* getAccessToken();
|
|
94668
|
-
const path = `/api/${encodeURIComponent(orgSlug)}/cli/chats/messages`;
|
|
94669
|
-
return yield* makeRequest(chatBaseUrl, path, token, {
|
|
94670
|
-
method: "POST",
|
|
94671
|
-
body
|
|
94672
|
-
});
|
|
94673
|
-
}),
|
|
94674
94641
|
// Phase 8: Agent admin CRUD
|
|
94675
94642
|
createInstalledAgent: (orgSlug, body) => gen(function* () {
|
|
94676
94643
|
const token = yield* getAccessToken();
|
|
@@ -95078,14 +95045,14 @@ function jsonFormat(data, options = {}) {
|
|
|
95078
95045
|
}
|
|
95079
95046
|
|
|
95080
95047
|
const agentIdArg$4 = text$2({ name: "id" }).pipe(withDescription$5("Agent ID to export"));
|
|
95081
|
-
const outputOption$
|
|
95048
|
+
const outputOption$2 = text("output").pipe(
|
|
95082
95049
|
withAlias("o"),
|
|
95083
95050
|
withDescription$3("Output file path (defaults to {agentId}.yaml)"),
|
|
95084
95051
|
optional
|
|
95085
95052
|
);
|
|
95086
95053
|
const exportCommand = make$4(
|
|
95087
95054
|
"export",
|
|
95088
|
-
{ agentId: agentIdArg$4, org: orgOption, output: outputOption$
|
|
95055
|
+
{ agentId: agentIdArg$4, org: orgOption, output: outputOption$2 },
|
|
95089
95056
|
({ agentId, org, output }) => gen(function* () {
|
|
95090
95057
|
const api = yield* ApiService;
|
|
95091
95058
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -95278,7 +95245,7 @@ const adminAgentCommand = make$4("agent", {}).pipe(
|
|
|
95278
95245
|
withSubcommands(adminAgentSubcommands)
|
|
95279
95246
|
);
|
|
95280
95247
|
|
|
95281
|
-
const typeOption
|
|
95248
|
+
const typeOption = text("type").pipe(
|
|
95282
95249
|
withDescription$3("Filter by event type"),
|
|
95283
95250
|
optional
|
|
95284
95251
|
);
|
|
@@ -95288,7 +95255,7 @@ const pageOption$3 = integer("page").pipe(
|
|
|
95288
95255
|
);
|
|
95289
95256
|
const listCommand$a = make$4(
|
|
95290
95257
|
"list",
|
|
95291
|
-
{ org: orgOption, type: typeOption
|
|
95258
|
+
{ org: orgOption, type: typeOption, page: pageOption$3 },
|
|
95292
95259
|
({ org, type, page }) => gen(function* () {
|
|
95293
95260
|
const api = yield* ApiService;
|
|
95294
95261
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -95452,7 +95419,7 @@ const deleteCommand$5 = make$4(
|
|
|
95452
95419
|
).pipe(withDescription("Delete an integration by ID (requires --force to confirm)"));
|
|
95453
95420
|
|
|
95454
95421
|
const integrationIdArg$3 = text$2({ name: "id" }).pipe(withDescription$5("Integration ID"));
|
|
95455
|
-
const getCommand$
|
|
95422
|
+
const getCommand$6 = make$4(
|
|
95456
95423
|
"get",
|
|
95457
95424
|
{ integrationId: integrationIdArg$3, org: orgOption },
|
|
95458
95425
|
({ integrationId, org }) => gen(function* () {
|
|
@@ -95596,7 +95563,7 @@ const updateCommand$2 = make$4(
|
|
|
95596
95563
|
|
|
95597
95564
|
const adminIntegrationCommandDescription = "Admin integration management (get, update, delete, tools, available)";
|
|
95598
95565
|
const adminIntegrationSubcommands = [
|
|
95599
|
-
getCommand$
|
|
95566
|
+
getCommand$6,
|
|
95600
95567
|
updateCommand$2,
|
|
95601
95568
|
deleteCommand$5,
|
|
95602
95569
|
toolsCommand,
|
|
@@ -95906,14 +95873,14 @@ const deleteCommand$4 = make$4(
|
|
|
95906
95873
|
const idArg$6 = text$2({ name: "id" }).pipe(
|
|
95907
95874
|
withDescription$5("Preset ID")
|
|
95908
95875
|
);
|
|
95909
|
-
const jsonOption$
|
|
95876
|
+
const jsonOption$c = boolean("json").pipe(
|
|
95910
95877
|
withDescription$3("Output in JSON format"),
|
|
95911
95878
|
withDefault(false)
|
|
95912
95879
|
);
|
|
95913
95880
|
const formatPresetPrompt = maskSensitiveText;
|
|
95914
|
-
const getCommand$
|
|
95881
|
+
const getCommand$5 = make$4(
|
|
95915
95882
|
"get",
|
|
95916
|
-
{ id: idArg$6, org: orgOption, json: jsonOption$
|
|
95883
|
+
{ id: idArg$6, org: orgOption, json: jsonOption$c },
|
|
95917
95884
|
({ id, org, json }) => gen(function* () {
|
|
95918
95885
|
const api = yield* ApiService;
|
|
95919
95886
|
yield* resolveOrgSlug(org, api);
|
|
@@ -95960,7 +95927,7 @@ const getCommand$6 = make$4(
|
|
|
95960
95927
|
})
|
|
95961
95928
|
).pipe(withDescription("Get preset details by ID"));
|
|
95962
95929
|
|
|
95963
|
-
const jsonOption$
|
|
95930
|
+
const jsonOption$b = boolean("json").pipe(
|
|
95964
95931
|
withDescription$3(
|
|
95965
95932
|
'Output in JSON format: [{"id":"string","name":"string","isDefault":"boolean","prompt":"string|null","createdAt":"ISO-8601","updatedAt":"ISO-8601"}]'
|
|
95966
95933
|
),
|
|
@@ -95972,7 +95939,7 @@ function formatPresetListPrompt(prompt) {
|
|
|
95972
95939
|
}
|
|
95973
95940
|
const listCommand$9 = make$4(
|
|
95974
95941
|
"list",
|
|
95975
|
-
{ org: orgOption, json: jsonOption$
|
|
95942
|
+
{ org: orgOption, json: jsonOption$b },
|
|
95976
95943
|
({ org, json }) => gen(function* () {
|
|
95977
95944
|
const api = yield* ApiService;
|
|
95978
95945
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96198,7 +96165,7 @@ const updateCommand$1 = make$4(
|
|
|
96198
96165
|
const presetCommandDescription = "Manage presets (list, get, create, update, rename, delete, set-default, unset-default, regen-key, regen-static-key)";
|
|
96199
96166
|
const presetSubcommands = [
|
|
96200
96167
|
listCommand$9,
|
|
96201
|
-
getCommand$
|
|
96168
|
+
getCommand$5,
|
|
96202
96169
|
createCommand$1,
|
|
96203
96170
|
updateCommand$1,
|
|
96204
96171
|
renameCommand$1,
|
|
@@ -96319,14 +96286,14 @@ const cloneBuiltInCommand = make$4(
|
|
|
96319
96286
|
).pipe(withDescription("Clone built-in skills from the library to your organization"));
|
|
96320
96287
|
|
|
96321
96288
|
const skillIdArg$4 = text$2({ name: "id" }).pipe(withDescription$5("Skill ID to download"));
|
|
96322
|
-
const outputOption$
|
|
96289
|
+
const outputOption$1 = text("output").pipe(
|
|
96323
96290
|
withAlias("o"),
|
|
96324
96291
|
withDescription$3("Output file path (defaults to original filename)"),
|
|
96325
96292
|
optional
|
|
96326
96293
|
);
|
|
96327
96294
|
const downloadCommand$1 = make$4(
|
|
96328
96295
|
"download",
|
|
96329
|
-
{ skillId: skillIdArg$4, org: orgOption, output: outputOption$
|
|
96296
|
+
{ skillId: skillIdArg$4, org: orgOption, output: outputOption$1 },
|
|
96330
96297
|
({ skillId, org, output }) => gen(function* () {
|
|
96331
96298
|
const api = yield* ApiService;
|
|
96332
96299
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96405,7 +96372,7 @@ const applyOption = boolean("apply").pipe(
|
|
|
96405
96372
|
withDescription$3("Apply the prepared GitHub update immediately"),
|
|
96406
96373
|
withDefault(false)
|
|
96407
96374
|
);
|
|
96408
|
-
const jsonOption$
|
|
96375
|
+
const jsonOption$a = boolean("json").pipe(
|
|
96409
96376
|
withDescription$3("Output in JSON format"),
|
|
96410
96377
|
withDefault(false)
|
|
96411
96378
|
);
|
|
@@ -96444,7 +96411,7 @@ const discardPreparedSkill = (api, orgSlug, preparedSkillId) => api.abortAdminUp
|
|
|
96444
96411
|
);
|
|
96445
96412
|
const inspectCommand = make$4(
|
|
96446
96413
|
"inspect",
|
|
96447
|
-
{ githubUrl: githubUrlArg, org: orgOption, patEnv: patEnvOption, json: jsonOption$
|
|
96414
|
+
{ githubUrl: githubUrlArg, org: orgOption, patEnv: patEnvOption, json: jsonOption$a },
|
|
96448
96415
|
({ githubUrl, org, patEnv, json }) => gen(function* () {
|
|
96449
96416
|
const api = yield* ApiService;
|
|
96450
96417
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96476,7 +96443,7 @@ const inspectCommand = make$4(
|
|
|
96476
96443
|
).pipe(withDescription("Inspect a GitHub repository for skill import"));
|
|
96477
96444
|
const importCommand = make$4(
|
|
96478
96445
|
"import",
|
|
96479
|
-
{ githubUrl: githubUrlArg, org: orgOption, patEnv: patEnvOption, overwrite: overwriteOption$2, json: jsonOption$
|
|
96446
|
+
{ githubUrl: githubUrlArg, org: orgOption, patEnv: patEnvOption, overwrite: overwriteOption$2, json: jsonOption$a },
|
|
96480
96447
|
({ githubUrl, org, patEnv, overwrite, json }) => gen(function* () {
|
|
96481
96448
|
const api = yield* ApiService;
|
|
96482
96449
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96514,7 +96481,7 @@ const importCommand = make$4(
|
|
|
96514
96481
|
).pipe(withDescription("Import a skill from GitHub"));
|
|
96515
96482
|
const syncCommand = make$4(
|
|
96516
96483
|
"sync",
|
|
96517
|
-
{ skillId: skillIdArg$3, org: orgOption, apply: applyOption, json: jsonOption$
|
|
96484
|
+
{ skillId: skillIdArg$3, org: orgOption, apply: applyOption, json: jsonOption$a },
|
|
96518
96485
|
({ skillId, org, apply, json }) => gen(function* () {
|
|
96519
96486
|
const api = yield* ApiService;
|
|
96520
96487
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96627,7 +96594,7 @@ const pageSizeOption = integer("page-size").pipe(
|
|
|
96627
96594
|
withDescription$3("Page size (default: 20)"),
|
|
96628
96595
|
optional
|
|
96629
96596
|
);
|
|
96630
|
-
const jsonOption$
|
|
96597
|
+
const jsonOption$9 = boolean("json").pipe(
|
|
96631
96598
|
withDescription$3("Output in JSON format"),
|
|
96632
96599
|
withDefault(false)
|
|
96633
96600
|
);
|
|
@@ -96644,7 +96611,7 @@ const overwriteOption$1 = boolean("overwrite").pipe(
|
|
|
96644
96611
|
);
|
|
96645
96612
|
const listCommand$8 = make$4(
|
|
96646
96613
|
"list",
|
|
96647
|
-
{ org: orgOption, search: searchOption$2, page: pageOption$2, pageSize: pageSizeOption, json: jsonOption$
|
|
96614
|
+
{ org: orgOption, search: searchOption$2, page: pageOption$2, pageSize: pageSizeOption, json: jsonOption$9 },
|
|
96648
96615
|
({ org, search, page, pageSize, json }) => gen(function* () {
|
|
96649
96616
|
const api = yield* ApiService;
|
|
96650
96617
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96703,9 +96670,9 @@ const listCommand$8 = make$4(
|
|
|
96703
96670
|
}
|
|
96704
96671
|
})
|
|
96705
96672
|
).pipe(withDescription("List organization-wide skills"));
|
|
96706
|
-
const getCommand$
|
|
96673
|
+
const getCommand$4 = make$4(
|
|
96707
96674
|
"get",
|
|
96708
|
-
{ skillId: skillIdArg$2, org: orgOption, json: jsonOption$
|
|
96675
|
+
{ skillId: skillIdArg$2, org: orgOption, json: jsonOption$9 },
|
|
96709
96676
|
({ skillId, org, json }) => gen(function* () {
|
|
96710
96677
|
const api = yield* ApiService;
|
|
96711
96678
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96896,7 +96863,7 @@ const unpublishCommand = make$4(
|
|
|
96896
96863
|
const adminSkillCommandDescription = "Admin skill management (list, get, upload, download, delete, publish, unpublish, built-in, clone-built-in, github)";
|
|
96897
96864
|
const adminSkillSubcommands = [
|
|
96898
96865
|
listCommand$8,
|
|
96899
|
-
getCommand$
|
|
96866
|
+
getCommand$4,
|
|
96900
96867
|
uploadCommand$2,
|
|
96901
96868
|
downloadCommand$1,
|
|
96902
96869
|
deleteCommand$3,
|
|
@@ -97316,7 +97283,7 @@ const agentIdOption = optional(
|
|
|
97316
97283
|
withDescription$3("Agent installation ID (UUID) to chat with. Required when starting a new chat.")
|
|
97317
97284
|
)
|
|
97318
97285
|
);
|
|
97319
|
-
const messageOption
|
|
97286
|
+
const messageOption = optional(
|
|
97320
97287
|
text("message").pipe(
|
|
97321
97288
|
withAlias("m"),
|
|
97322
97289
|
withDescription$3("Message to send to the agent (if not provided, reads from stdin when piped)")
|
|
@@ -97327,7 +97294,7 @@ const conversationIdOption = optional(
|
|
|
97327
97294
|
withDescription$3("Continue an existing conversation by ID (from a previous --json result)")
|
|
97328
97295
|
)
|
|
97329
97296
|
);
|
|
97330
|
-
const jsonOption$
|
|
97297
|
+
const jsonOption$8 = boolean("json").pipe(
|
|
97331
97298
|
withDescription$3('Output in JSON format: {"text":"string","conversationId":"string"}'),
|
|
97332
97299
|
withDefault(false)
|
|
97333
97300
|
);
|
|
@@ -97341,7 +97308,7 @@ const readStdin = () => tryPromise({
|
|
|
97341
97308
|
},
|
|
97342
97309
|
catch: (e) => new ApiError({ message: `Failed to read stdin: ${e instanceof Error ? e.message : String(e)}` })
|
|
97343
97310
|
});
|
|
97344
|
-
const SPINNER_FRAMES
|
|
97311
|
+
const SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
97345
97312
|
const SPINNER_MESSAGES = ["thinking", "churning", "processing", "pondering", "working", "computing"];
|
|
97346
97313
|
const formatAgentChatTextOutput = maskSensitiveText;
|
|
97347
97314
|
const startSpinner = () => {
|
|
@@ -97349,22 +97316,22 @@ const startSpinner = () => {
|
|
|
97349
97316
|
let frameIdx = 0;
|
|
97350
97317
|
let msgIdx = 0;
|
|
97351
97318
|
const timer = setInterval(() => {
|
|
97352
|
-
frameIdx = (frameIdx + 1) % SPINNER_FRAMES
|
|
97319
|
+
frameIdx = (frameIdx + 1) % SPINNER_FRAMES.length;
|
|
97353
97320
|
if (frameIdx === 0) msgIdx = (msgIdx + 1) % SPINNER_MESSAGES.length;
|
|
97354
|
-
process.stderr.write(`\r${SPINNER_FRAMES
|
|
97321
|
+
process.stderr.write(`\r${SPINNER_FRAMES[frameIdx]} ${SPINNER_MESSAGES[msgIdx]}... `);
|
|
97355
97322
|
}, 80);
|
|
97356
97323
|
return () => {
|
|
97357
97324
|
clearInterval(timer);
|
|
97358
97325
|
process.stderr.write("\r" + " ".repeat(30) + "\r");
|
|
97359
97326
|
};
|
|
97360
97327
|
};
|
|
97361
|
-
const chatCommand$
|
|
97328
|
+
const chatCommand$1 = make$4(
|
|
97362
97329
|
"chat",
|
|
97363
97330
|
{
|
|
97364
97331
|
agentId: agentIdOption,
|
|
97365
|
-
message: messageOption
|
|
97332
|
+
message: messageOption,
|
|
97366
97333
|
conversationId: conversationIdOption,
|
|
97367
|
-
json: jsonOption$
|
|
97334
|
+
json: jsonOption$8,
|
|
97368
97335
|
org: orgOption
|
|
97369
97336
|
},
|
|
97370
97337
|
({ agentId, message, conversationId, json, org }) => gen(function* () {
|
|
@@ -97444,15 +97411,15 @@ const resolveAgentChatTarget = (agentId, conversationId) => {
|
|
|
97444
97411
|
const isContinuationTarget = (target) => target.conversationId !== void 0;
|
|
97445
97412
|
|
|
97446
97413
|
const agentIdArg$1 = text$2({ name: "id" }).pipe(withDescription$5("Agent ID"));
|
|
97447
|
-
const jsonOption$
|
|
97414
|
+
const jsonOption$7 = boolean("json").pipe(
|
|
97448
97415
|
withDescription$3(
|
|
97449
97416
|
'Output in JSON format: {"id":"string","displayName":"string","shortDescription":"string","description":"string|null","createdBy":"string","createdAt":"ISO-8601","updatedAt":"ISO-8601","configRequiredIntegrations":["string"]}'
|
|
97450
97417
|
),
|
|
97451
97418
|
withDefault(false)
|
|
97452
97419
|
);
|
|
97453
|
-
const getCommand$
|
|
97420
|
+
const getCommand$3 = make$4(
|
|
97454
97421
|
"get",
|
|
97455
|
-
{ agentId: agentIdArg$1, org: orgOption, json: jsonOption$
|
|
97422
|
+
{ agentId: agentIdArg$1, org: orgOption, json: jsonOption$7 },
|
|
97456
97423
|
({ agentId, org, json }) => gen(function* () {
|
|
97457
97424
|
const api = yield* ApiService;
|
|
97458
97425
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -97496,7 +97463,7 @@ const getCommand$4 = make$4(
|
|
|
97496
97463
|
})
|
|
97497
97464
|
).pipe(withDescription("Get agent details by ID"));
|
|
97498
97465
|
|
|
97499
|
-
const jsonOption$
|
|
97466
|
+
const jsonOption$6 = boolean("json").pipe(
|
|
97500
97467
|
withDescription$3(
|
|
97501
97468
|
'Output in JSON format: [{"id":"string","displayName":"string","agentType":"string","shortDescription":"string","createdBy":"string","createdAt":"ISO-8601"}]'
|
|
97502
97469
|
),
|
|
@@ -97504,7 +97471,7 @@ const jsonOption$b = boolean("json").pipe(
|
|
|
97504
97471
|
);
|
|
97505
97472
|
const listCommand$7 = make$4(
|
|
97506
97473
|
"list",
|
|
97507
|
-
{ org: orgOption, json: jsonOption$
|
|
97474
|
+
{ org: orgOption, json: jsonOption$6 },
|
|
97508
97475
|
({ org, json }) => gen(function* () {
|
|
97509
97476
|
const api = yield* ApiService;
|
|
97510
97477
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -97611,7 +97578,7 @@ const disableCommand$1 = make$4(
|
|
|
97611
97578
|
).pipe(withDescription("Disable an agent"));
|
|
97612
97579
|
|
|
97613
97580
|
const agentCommandDescription = "Manage agents (list, get, chat, enable, disable)";
|
|
97614
|
-
const agentSubcommands = [listCommand$7, getCommand$
|
|
97581
|
+
const agentSubcommands = [listCommand$7, getCommand$3, enableCommand$1, disableCommand$1, chatCommand$1];
|
|
97615
97582
|
const agentCommand = make$4("agent", {}).pipe(
|
|
97616
97583
|
withDescription(agentCommandDescription),
|
|
97617
97584
|
withSubcommands(agentSubcommands)
|
|
@@ -98166,16 +98133,16 @@ const deleteCommand$2 = make$4(
|
|
|
98166
98133
|
).pipe(withDescription("Delete an automation by ID (requires --force to confirm)"));
|
|
98167
98134
|
|
|
98168
98135
|
const automationIdArg$5 = text$2({ name: "id" }).pipe(withDescription$5("Automation ID"));
|
|
98169
|
-
const jsonOption$
|
|
98136
|
+
const jsonOption$5 = boolean("json").pipe(
|
|
98170
98137
|
withDescription$3(
|
|
98171
98138
|
'Output in JSON format: {"id":"string","name":"string","status":"string","triggerType":"string","triggerProviderType":"string","agentId":"string","prompt":"string","lastExecutionTime":"ISO-8601|null","lastExecutionStatus":"string|null","lastExecutionChatThreadUrl":"string|null","nextExecutionTime":"ISO-8601|null","trigger":"object","createdAt":"ISO-8601","updatedAt":"ISO-8601"}'
|
|
98172
98139
|
),
|
|
98173
98140
|
withDefault(false)
|
|
98174
98141
|
);
|
|
98175
98142
|
const formatAutomationTextOutput = maskSensitiveText;
|
|
98176
|
-
const getCommand$
|
|
98143
|
+
const getCommand$2 = make$4(
|
|
98177
98144
|
"get",
|
|
98178
|
-
{ automationId: automationIdArg$5, org: orgOption, json: jsonOption$
|
|
98145
|
+
{ automationId: automationIdArg$5, org: orgOption, json: jsonOption$5 },
|
|
98179
98146
|
({ automationId, org, json }) => gen(function* () {
|
|
98180
98147
|
const api = yield* ApiService;
|
|
98181
98148
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -98286,7 +98253,7 @@ const nameOption = text("name").pipe(
|
|
|
98286
98253
|
withDescription$3("Filter automations by name"),
|
|
98287
98254
|
optional
|
|
98288
98255
|
);
|
|
98289
|
-
const jsonOption$
|
|
98256
|
+
const jsonOption$4 = boolean("json").pipe(
|
|
98290
98257
|
withDescription$3(
|
|
98291
98258
|
'Output in JSON format: [{"id":"string","name":"string","status":"string","triggerType":"string","nextExecutionTime":"ISO-8601|null","createdAt":"ISO-8601"}]'
|
|
98292
98259
|
),
|
|
@@ -98294,7 +98261,7 @@ const jsonOption$9 = boolean("json").pipe(
|
|
|
98294
98261
|
);
|
|
98295
98262
|
const listCommand$6 = make$4(
|
|
98296
98263
|
"list",
|
|
98297
|
-
{ org: orgOption, name: nameOption, json: jsonOption$
|
|
98264
|
+
{ org: orgOption, name: nameOption, json: jsonOption$4 },
|
|
98298
98265
|
({ org, name, json }) => gen(function* () {
|
|
98299
98266
|
const api = yield* ApiService;
|
|
98300
98267
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -98597,7 +98564,7 @@ const webhookRegenCommand = make$4(
|
|
|
98597
98564
|
const automationCommandDescription = "Manage automations (list, get, create, update, delete, run, enable, disable, history, cancel, webhook-regen, triggers)";
|
|
98598
98565
|
const automationSubcommands = [
|
|
98599
98566
|
listCommand$6,
|
|
98600
|
-
getCommand$
|
|
98567
|
+
getCommand$2,
|
|
98601
98568
|
createCommand,
|
|
98602
98569
|
updateCommand,
|
|
98603
98570
|
deleteCommand$2,
|
|
@@ -98617,7 +98584,7 @@ const automationCommand = make$4("automation", {}).pipe(
|
|
|
98617
98584
|
const conversationIdArg$1 = text$2({ name: "conversationId" }).pipe(
|
|
98618
98585
|
withDescription$5("Conversation ID")
|
|
98619
98586
|
);
|
|
98620
|
-
const getCommand$
|
|
98587
|
+
const getCommand$1 = make$4(
|
|
98621
98588
|
"get",
|
|
98622
98589
|
{ conversationId: conversationIdArg$1, org: orgOption },
|
|
98623
98590
|
({ conversationId, org }) => gen(function* () {
|
|
@@ -98656,7 +98623,7 @@ const getCommand$2 = make$4(
|
|
|
98656
98623
|
})
|
|
98657
98624
|
).pipe(withDescription("Get conversation details by ID"));
|
|
98658
98625
|
|
|
98659
|
-
const jsonOption$
|
|
98626
|
+
const jsonOption$3 = boolean("json").pipe(
|
|
98660
98627
|
withDescription$3(
|
|
98661
98628
|
'Output in JSON format: [{"conversationId":"string","title":"string","type":"string","updatedAt":"ISO-8601"}]'
|
|
98662
98629
|
),
|
|
@@ -98664,7 +98631,7 @@ const jsonOption$8 = boolean("json").pipe(
|
|
|
98664
98631
|
);
|
|
98665
98632
|
const listCommand$5 = make$4(
|
|
98666
98633
|
"list",
|
|
98667
|
-
{ org: orgOption, json: jsonOption$
|
|
98634
|
+
{ org: orgOption, json: jsonOption$3 },
|
|
98668
98635
|
({ org, json }) => gen(function* () {
|
|
98669
98636
|
const api = yield* ApiService;
|
|
98670
98637
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -98756,174 +98723,9 @@ const messagesCommand = make$4(
|
|
|
98756
98723
|
})
|
|
98757
98724
|
).pipe(withDescription("List messages in a conversation"));
|
|
98758
98725
|
|
|
98759
|
-
const
|
|
98760
|
-
|
|
98761
|
-
|
|
98762
|
-
}
|
|
98763
|
-
return catalog.models.filter((model) => model.type === type);
|
|
98764
|
-
};
|
|
98765
|
-
const getModelExecInputSchema = (model) => {
|
|
98766
|
-
if (model.inputSchema) {
|
|
98767
|
-
return model.inputSchema;
|
|
98768
|
-
}
|
|
98769
|
-
if (model.type === "image-generation") {
|
|
98770
|
-
return {
|
|
98771
|
-
type: "object",
|
|
98772
|
-
required: ["prompt"],
|
|
98773
|
-
properties: {
|
|
98774
|
-
prompt: { type: "string" },
|
|
98775
|
-
options: {
|
|
98776
|
-
type: "object",
|
|
98777
|
-
properties: {
|
|
98778
|
-
size: { type: "string" },
|
|
98779
|
-
n: { type: "integer" }
|
|
98780
|
-
}
|
|
98781
|
-
}
|
|
98782
|
-
}
|
|
98783
|
-
};
|
|
98784
|
-
}
|
|
98785
|
-
return {
|
|
98786
|
-
type: "object",
|
|
98787
|
-
required: ["input"],
|
|
98788
|
-
properties: {
|
|
98789
|
-
input: {
|
|
98790
|
-
type: "object",
|
|
98791
|
-
required: ["text"],
|
|
98792
|
-
properties: {
|
|
98793
|
-
text: { type: "string" }
|
|
98794
|
-
}
|
|
98795
|
-
},
|
|
98796
|
-
options: { type: "object" }
|
|
98797
|
-
}
|
|
98798
|
-
};
|
|
98799
|
-
};
|
|
98800
|
-
const buildModelExecSampleInput = (model) => {
|
|
98801
|
-
if (model.type === "image-generation") {
|
|
98802
|
-
return {
|
|
98803
|
-
prompt: "A small robot reading a book",
|
|
98804
|
-
options: { size: "1024x1024", n: 1 }
|
|
98805
|
-
};
|
|
98806
|
-
}
|
|
98807
|
-
return {
|
|
98808
|
-
input: { text: "Say hello in one sentence." },
|
|
98809
|
-
options: {}
|
|
98810
|
-
};
|
|
98811
|
-
};
|
|
98812
|
-
const buildModelExecChatRequest = (model, input) => ({
|
|
98813
|
-
model,
|
|
98814
|
-
input
|
|
98815
|
-
});
|
|
98816
|
-
const buildModelExecImageGenerationRequest = (model, input) => ({
|
|
98817
|
-
model,
|
|
98818
|
-
prompt: input.prompt,
|
|
98819
|
-
...input.options ? { options: input.options } : {}
|
|
98820
|
-
});
|
|
98821
|
-
const readJsonInputFile = (path) => tryPromise({
|
|
98822
|
-
try: async () => JSON.parse(await fs$1.readFile(path, "utf8")),
|
|
98823
|
-
catch: (error) => new ApiError({
|
|
98824
|
-
message: `Failed to read JSON input "${path}": ${error instanceof Error ? error.message : String(error)}`
|
|
98825
|
-
})
|
|
98826
|
-
});
|
|
98827
|
-
const saveJsonFile = (path, value) => tryPromise({
|
|
98828
|
-
try: async () => {
|
|
98829
|
-
await fs$1.writeFile(path, `${JSON.stringify(value, null, 2)}
|
|
98830
|
-
`, "utf8");
|
|
98831
|
-
},
|
|
98832
|
-
catch: (error) => new ApiError({
|
|
98833
|
-
message: `Failed to write "${path}": ${error instanceof Error ? error.message : String(error)}`
|
|
98834
|
-
})
|
|
98835
|
-
});
|
|
98836
|
-
const readStdinText = () => tryPromise({
|
|
98837
|
-
try: async () => {
|
|
98838
|
-
const chunks = [];
|
|
98839
|
-
for await (const chunk of process.stdin) {
|
|
98840
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
98841
|
-
}
|
|
98842
|
-
return Buffer.concat(chunks).toString("utf8").trim();
|
|
98843
|
-
},
|
|
98844
|
-
catch: (error) => new ApiError({
|
|
98845
|
-
message: `Failed to read stdin: ${error instanceof Error ? error.message : String(error)}`
|
|
98846
|
-
})
|
|
98847
|
-
});
|
|
98848
|
-
|
|
98849
|
-
const messageOption$1 = optional(
|
|
98850
|
-
text("message").pipe(
|
|
98851
|
-
withAlias("m"),
|
|
98852
|
-
withDescription$3("Message text. If omitted, stdin is used when piped.")
|
|
98853
|
-
)
|
|
98854
|
-
);
|
|
98855
|
-
const conversationOption = optional(
|
|
98856
|
-
text("conversation").pipe(
|
|
98857
|
-
withDescription$3("Conversation ID to continue")
|
|
98858
|
-
)
|
|
98859
|
-
);
|
|
98860
|
-
const modelOption$2 = optional(
|
|
98861
|
-
text("model").pipe(withDescription$3("Chat model ID for a new or continued conversation"))
|
|
98862
|
-
);
|
|
98863
|
-
const jsonOption$7 = boolean("json").pipe(
|
|
98864
|
-
withDescription$3("Output full response as JSON"),
|
|
98865
|
-
withDefault(false)
|
|
98866
|
-
);
|
|
98867
|
-
const buildSendChatMessageRequest = (input) => ({
|
|
98868
|
-
conversationId: getOrUndefined(input.conversationId),
|
|
98869
|
-
model: getOrUndefined(input.model),
|
|
98870
|
-
message: { text: input.text }
|
|
98871
|
-
});
|
|
98872
|
-
const sendCommand = make$4(
|
|
98873
|
-
"send",
|
|
98874
|
-
{
|
|
98875
|
-
message: messageOption$1,
|
|
98876
|
-
conversation: conversationOption,
|
|
98877
|
-
model: modelOption$2,
|
|
98878
|
-
json: jsonOption$7,
|
|
98879
|
-
org: orgOption
|
|
98880
|
-
},
|
|
98881
|
-
({ message, conversation, model, json, org }) => gen(function* () {
|
|
98882
|
-
const api = yield* ApiService;
|
|
98883
|
-
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
98884
|
-
const text = yield* resolveMessageText(message);
|
|
98885
|
-
const request = buildSendChatMessageRequest({ conversationId: conversation, model, text });
|
|
98886
|
-
const result = yield* api.sendChatMessage(orgSlug, request).pipe(
|
|
98887
|
-
catchTag(
|
|
98888
|
-
"NotLoggedInError",
|
|
98889
|
-
(error) => gen(function* () {
|
|
98890
|
-
yield* error$1(error.message);
|
|
98891
|
-
return yield* fail$3(error);
|
|
98892
|
-
})
|
|
98893
|
-
),
|
|
98894
|
-
catchTag(
|
|
98895
|
-
"ApiError",
|
|
98896
|
-
(error) => gen(function* () {
|
|
98897
|
-
yield* error$1(`Chat send failed: ${error.message}`);
|
|
98898
|
-
return yield* fail$3(error);
|
|
98899
|
-
})
|
|
98900
|
-
)
|
|
98901
|
-
);
|
|
98902
|
-
if (json) {
|
|
98903
|
-
yield* log(jsonFormat(result));
|
|
98904
|
-
return;
|
|
98905
|
-
}
|
|
98906
|
-
yield* log(maskSensitiveText(result.output.text));
|
|
98907
|
-
yield* log(`
|
|
98908
|
-
Conversation: ${result.conversationId}`);
|
|
98909
|
-
})
|
|
98910
|
-
).pipe(withDescription("Send a conversation-based chat message and print the assistant response"));
|
|
98911
|
-
const resolveMessageText = (message) => gen(function* () {
|
|
98912
|
-
if (isSome(message)) {
|
|
98913
|
-
return message.value;
|
|
98914
|
-
}
|
|
98915
|
-
if (!process.stdin.isTTY) {
|
|
98916
|
-
const text = yield* readStdinText();
|
|
98917
|
-
if (text) {
|
|
98918
|
-
return text;
|
|
98919
|
-
}
|
|
98920
|
-
}
|
|
98921
|
-
return yield* fail$3(new ApiError({ message: "Provide --message/-m or pipe text through stdin." }));
|
|
98922
|
-
});
|
|
98923
|
-
|
|
98924
|
-
const chatCommandDescription = "Manage conversations (list, get, messages, send)";
|
|
98925
|
-
const chatSubcommands = [listCommand$5, getCommand$2, messagesCommand, sendCommand];
|
|
98926
|
-
const chatCommand$1 = make$4("chat", {}).pipe(
|
|
98726
|
+
const chatCommandDescription = "Manage conversations (list, get, messages)";
|
|
98727
|
+
const chatSubcommands = [listCommand$5, getCommand$1, messagesCommand];
|
|
98728
|
+
const chatCommand = make$4("chat", {}).pipe(
|
|
98927
98729
|
withDescription(chatCommandDescription),
|
|
98928
98730
|
withSubcommands(chatSubcommands)
|
|
98929
98731
|
);
|
|
@@ -99080,13 +98882,13 @@ const deleteCommand$1 = make$4(
|
|
|
99080
98882
|
).pipe(withDescription("Delete drive entries by ID (requires --force to confirm)"));
|
|
99081
98883
|
|
|
99082
98884
|
const entryIdArg$1 = text$2({ name: "id" }).pipe(withDescription$5("Drive entry ID"));
|
|
99083
|
-
const outputOption
|
|
98885
|
+
const outputOption = text("output").pipe(
|
|
99084
98886
|
withAlias("o"),
|
|
99085
98887
|
withDescription$3("Output file path (required, as the API does not return the original filename)")
|
|
99086
98888
|
);
|
|
99087
98889
|
const downloadCommand = make$4(
|
|
99088
98890
|
"download",
|
|
99089
|
-
{ entryId: entryIdArg$1, org: orgOption, output: outputOption
|
|
98891
|
+
{ entryId: entryIdArg$1, org: orgOption, output: outputOption },
|
|
99090
98892
|
({ entryId, org, output }) => gen(function* () {
|
|
99091
98893
|
const api = yield* ApiService;
|
|
99092
98894
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -99507,347 +99309,6 @@ const modelCommand = make$4("model", {}).pipe(
|
|
|
99507
99309
|
withSubcommands(modelSubcommands)
|
|
99508
99310
|
);
|
|
99509
99311
|
|
|
99510
|
-
const SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
99511
|
-
const SPINNER_INTERVAL_MS = 80;
|
|
99512
|
-
const CLEAR_WIDTH = 80;
|
|
99513
|
-
const startModelExecProgress = (message, options = {}) => {
|
|
99514
|
-
const stream = options.stream ?? process.stderr;
|
|
99515
|
-
if (!stream.isTTY) return () => void 0;
|
|
99516
|
-
const now = options.now ?? Date.now;
|
|
99517
|
-
const startedAt = now();
|
|
99518
|
-
let frameIndex = 0;
|
|
99519
|
-
let stopped = false;
|
|
99520
|
-
const render = () => {
|
|
99521
|
-
const elapsedSeconds = Math.floor((now() - startedAt) / 1e3);
|
|
99522
|
-
stream.write(`\r${SPINNER_FRAMES[frameIndex]} ${message}... ${elapsedSeconds}s`);
|
|
99523
|
-
frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;
|
|
99524
|
-
};
|
|
99525
|
-
render();
|
|
99526
|
-
const timer = setInterval(render, SPINNER_INTERVAL_MS);
|
|
99527
|
-
return () => {
|
|
99528
|
-
if (stopped) return;
|
|
99529
|
-
stopped = true;
|
|
99530
|
-
clearInterval(timer);
|
|
99531
|
-
stream.write(`\r${" ".repeat(CLEAR_WIDTH)}\r`);
|
|
99532
|
-
};
|
|
99533
|
-
};
|
|
99534
|
-
|
|
99535
|
-
const modelOption$1 = text("model").pipe(withDescription$3("Chat model ID"));
|
|
99536
|
-
const messageOption = optional(
|
|
99537
|
-
text("message").pipe(
|
|
99538
|
-
withAlias("m"),
|
|
99539
|
-
withDescription$3("Message text. If omitted, stdin is used when piped.")
|
|
99540
|
-
)
|
|
99541
|
-
);
|
|
99542
|
-
const inputOption$1 = optional(
|
|
99543
|
-
text("input").pipe(withDescription$3("JSON input file generated by model-exec sample"))
|
|
99544
|
-
);
|
|
99545
|
-
const jsonOption$6 = boolean("json").pipe(
|
|
99546
|
-
withDescription$3("Output full response as JSON"),
|
|
99547
|
-
withDefault(false)
|
|
99548
|
-
);
|
|
99549
|
-
const chatCommand = make$4(
|
|
99550
|
-
"chat",
|
|
99551
|
-
{ model: modelOption$1, message: messageOption, input: inputOption$1, json: jsonOption$6, org: orgOption },
|
|
99552
|
-
({ model, message, input, json, org }) => gen(function* () {
|
|
99553
|
-
const api = yield* ApiService;
|
|
99554
|
-
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
99555
|
-
const request = yield* resolveChatRequest(model, message, input);
|
|
99556
|
-
const stopProgress = startModelExecProgress("Waiting for model response");
|
|
99557
|
-
const result = yield* api.executeModelExecChat(orgSlug, request).pipe(
|
|
99558
|
-
ensuring$1(sync$1(stopProgress)),
|
|
99559
|
-
catchTag(
|
|
99560
|
-
"NotLoggedInError",
|
|
99561
|
-
(error) => gen(function* () {
|
|
99562
|
-
yield* error$1(error.message);
|
|
99563
|
-
return yield* fail$3(error);
|
|
99564
|
-
})
|
|
99565
|
-
),
|
|
99566
|
-
catchTag(
|
|
99567
|
-
"ApiError",
|
|
99568
|
-
(error) => gen(function* () {
|
|
99569
|
-
yield* error$1(`Model-exec chat failed: ${error.message}`);
|
|
99570
|
-
return yield* fail$3(error);
|
|
99571
|
-
})
|
|
99572
|
-
)
|
|
99573
|
-
);
|
|
99574
|
-
if (json) {
|
|
99575
|
-
yield* log(jsonFormat(result));
|
|
99576
|
-
return;
|
|
99577
|
-
}
|
|
99578
|
-
yield* log(maskSensitiveText(result.output.text));
|
|
99579
|
-
})
|
|
99580
|
-
).pipe(withDescription("Execute a chat model once without creating a conversation"));
|
|
99581
|
-
const resolveChatRequest = (model, message, input) => gen(function* () {
|
|
99582
|
-
if (isSome(input)) {
|
|
99583
|
-
const parsed = yield* readJsonInputFile(input.value);
|
|
99584
|
-
const text = parsed.input?.text;
|
|
99585
|
-
if (!text) {
|
|
99586
|
-
return yield* fail$3(new ApiError({ message: "Chat input JSON must include input.text" }));
|
|
99587
|
-
}
|
|
99588
|
-
return {
|
|
99589
|
-
model,
|
|
99590
|
-
input: { ...parsed.input, text },
|
|
99591
|
-
...parsed.options ? { options: parsed.options } : {}
|
|
99592
|
-
};
|
|
99593
|
-
}
|
|
99594
|
-
if (isSome(message)) {
|
|
99595
|
-
return buildModelExecChatRequest(model, { text: message.value });
|
|
99596
|
-
}
|
|
99597
|
-
if (!process.stdin.isTTY) {
|
|
99598
|
-
const text = yield* readStdinText();
|
|
99599
|
-
if (text) {
|
|
99600
|
-
return buildModelExecChatRequest(model, { text });
|
|
99601
|
-
}
|
|
99602
|
-
}
|
|
99603
|
-
return yield* fail$3(new ApiError({ message: "Provide --message/-m, --input, or pipe text through stdin." }));
|
|
99604
|
-
});
|
|
99605
|
-
|
|
99606
|
-
const modelIdArg$1 = text$2({ name: "model-id" }).pipe(withDescription$5("Model ID"));
|
|
99607
|
-
const jsonOption$5 = boolean("json").pipe(
|
|
99608
|
-
withDescription$3("Output model detail as JSON"),
|
|
99609
|
-
withDefault(false)
|
|
99610
|
-
);
|
|
99611
|
-
const getCommand$1 = make$4(
|
|
99612
|
-
"get",
|
|
99613
|
-
{ modelId: modelIdArg$1, org: orgOption, json: jsonOption$5 },
|
|
99614
|
-
({ modelId, org, json }) => gen(function* () {
|
|
99615
|
-
const api = yield* ApiService;
|
|
99616
|
-
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
99617
|
-
const catalog = yield* api.listModelExecModels(orgSlug).pipe(
|
|
99618
|
-
catchTag(
|
|
99619
|
-
"NotLoggedInError",
|
|
99620
|
-
(error) => gen(function* () {
|
|
99621
|
-
yield* error$1(error.message);
|
|
99622
|
-
return yield* fail$3(error);
|
|
99623
|
-
})
|
|
99624
|
-
),
|
|
99625
|
-
catchTag(
|
|
99626
|
-
"ApiError",
|
|
99627
|
-
(error) => gen(function* () {
|
|
99628
|
-
yield* error$1(`Failed to fetch model "${modelId}": ${error.message}`);
|
|
99629
|
-
return yield* fail$3(error);
|
|
99630
|
-
})
|
|
99631
|
-
)
|
|
99632
|
-
);
|
|
99633
|
-
const model = catalog.models.find((item) => item.id === modelId);
|
|
99634
|
-
if (!model) {
|
|
99635
|
-
const error = new ApiError({ message: `Model "${modelId}" not found.`, statusCode: 404 });
|
|
99636
|
-
yield* error$1(error.message);
|
|
99637
|
-
return yield* fail$3(error);
|
|
99638
|
-
}
|
|
99639
|
-
const detail = { ...model, inputSchema: getModelExecInputSchema(model) };
|
|
99640
|
-
if (json) {
|
|
99641
|
-
yield* log(jsonFormat(detail));
|
|
99642
|
-
return;
|
|
99643
|
-
}
|
|
99644
|
-
yield* log(`Model: ${detail.id}`);
|
|
99645
|
-
yield* log(` Type: ${detail.type}`);
|
|
99646
|
-
if (detail.displayName) yield* log(` Name: ${detail.displayName}`);
|
|
99647
|
-
yield* log(" Input schema:");
|
|
99648
|
-
yield* log(jsonFormat(detail.inputSchema));
|
|
99649
|
-
})
|
|
99650
|
-
).pipe(withDescription("Show model-exec model detail and input schema"));
|
|
99651
|
-
|
|
99652
|
-
const modelOption = text("model").pipe(withDescription$3("Image-generation model ID"));
|
|
99653
|
-
const promptOption = optional(
|
|
99654
|
-
text("prompt").pipe(withDescription$3("Image prompt"))
|
|
99655
|
-
);
|
|
99656
|
-
const inputOption = optional(
|
|
99657
|
-
text("input").pipe(withDescription$3("JSON input file generated by model-exec sample"))
|
|
99658
|
-
);
|
|
99659
|
-
const outputOption = text("output").pipe(withDescription$3("Output image file path"));
|
|
99660
|
-
const jsonOption$4 = boolean("json").pipe(
|
|
99661
|
-
withDescription$3("Output full response as JSON after saving the image"),
|
|
99662
|
-
withDefault(false)
|
|
99663
|
-
);
|
|
99664
|
-
const generateCommand = make$4(
|
|
99665
|
-
"generate",
|
|
99666
|
-
{
|
|
99667
|
-
model: modelOption,
|
|
99668
|
-
prompt: promptOption,
|
|
99669
|
-
input: inputOption,
|
|
99670
|
-
output: outputOption,
|
|
99671
|
-
json: jsonOption$4,
|
|
99672
|
-
org: orgOption
|
|
99673
|
-
},
|
|
99674
|
-
({ model, prompt, input, output, json, org }) => gen(function* () {
|
|
99675
|
-
const api = yield* ApiService;
|
|
99676
|
-
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
99677
|
-
const request = yield* resolveImageRequest(model, prompt, input);
|
|
99678
|
-
const stopProgress = startModelExecProgress("Generating image (timeout: 5m)");
|
|
99679
|
-
const result = yield* gen(function* () {
|
|
99680
|
-
const response = yield* api.executeModelExecImageGeneration(orgSlug, request);
|
|
99681
|
-
const first = response.outputs[0];
|
|
99682
|
-
if (!first) {
|
|
99683
|
-
return yield* fail$3(new ApiError({ message: "Image generation returned no outputs." }));
|
|
99684
|
-
}
|
|
99685
|
-
const buffer = yield* api.downloadFromUrl(first.downloadUrl);
|
|
99686
|
-
yield* writeImageFile(output, buffer);
|
|
99687
|
-
return response;
|
|
99688
|
-
}).pipe(
|
|
99689
|
-
ensuring$1(sync$1(stopProgress)),
|
|
99690
|
-
catchTag(
|
|
99691
|
-
"NotLoggedInError",
|
|
99692
|
-
(error) => gen(function* () {
|
|
99693
|
-
yield* error$1(error.message);
|
|
99694
|
-
return yield* fail$3(error);
|
|
99695
|
-
})
|
|
99696
|
-
),
|
|
99697
|
-
catchTag(
|
|
99698
|
-
"ApiError",
|
|
99699
|
-
(error) => gen(function* () {
|
|
99700
|
-
yield* error$1(`Image generation failed: ${error.message}`);
|
|
99701
|
-
return yield* fail$3(error);
|
|
99702
|
-
})
|
|
99703
|
-
)
|
|
99704
|
-
);
|
|
99705
|
-
if (json) {
|
|
99706
|
-
yield* log(jsonFormat({ ...result, savedPath: output }));
|
|
99707
|
-
return;
|
|
99708
|
-
}
|
|
99709
|
-
yield* log(`Saved image to ${output}`);
|
|
99710
|
-
})
|
|
99711
|
-
).pipe(
|
|
99712
|
-
withDescription(
|
|
99713
|
-
"Generate an image once and save the first output artifact (5-minute timeout)"
|
|
99714
|
-
)
|
|
99715
|
-
);
|
|
99716
|
-
const imageCommand = make$4("image", {}).pipe(
|
|
99717
|
-
withDescription("Run image-generation model-exec commands"),
|
|
99718
|
-
withSubcommands([generateCommand])
|
|
99719
|
-
);
|
|
99720
|
-
const resolveImageRequest = (model, prompt, input) => gen(function* () {
|
|
99721
|
-
if (isSome(input)) {
|
|
99722
|
-
const parsed = yield* readJsonInputFile(input.value);
|
|
99723
|
-
if (!parsed.prompt) {
|
|
99724
|
-
return yield* fail$3(new ApiError({ message: "Image input JSON must include prompt" }));
|
|
99725
|
-
}
|
|
99726
|
-
return buildModelExecImageGenerationRequest(model, {
|
|
99727
|
-
prompt: parsed.prompt,
|
|
99728
|
-
...parsed.options ? { options: parsed.options } : {}
|
|
99729
|
-
});
|
|
99730
|
-
}
|
|
99731
|
-
if (isSome(prompt)) {
|
|
99732
|
-
return buildModelExecImageGenerationRequest(model, { prompt: prompt.value });
|
|
99733
|
-
}
|
|
99734
|
-
return yield* fail$3(new ApiError({ message: "Provide --prompt or --input." }));
|
|
99735
|
-
});
|
|
99736
|
-
const writeImageFile = (path, buffer) => tryPromise({
|
|
99737
|
-
try: async () => {
|
|
99738
|
-
await fs$1.writeFile(path, buffer);
|
|
99739
|
-
},
|
|
99740
|
-
catch: (error) => new ApiError({
|
|
99741
|
-
message: `Failed to write image "${path}": ${error instanceof Error ? error.message : String(error)}`
|
|
99742
|
-
})
|
|
99743
|
-
});
|
|
99744
|
-
|
|
99745
|
-
const typeOption = optional(
|
|
99746
|
-
text("type").pipe(
|
|
99747
|
-
withDescription$3("Filter by model type: chat, image-generation, embedding")
|
|
99748
|
-
)
|
|
99749
|
-
);
|
|
99750
|
-
const jsonOption$3 = boolean("json").pipe(
|
|
99751
|
-
withDescription$3("Output model catalog as JSON"),
|
|
99752
|
-
withDefault(false)
|
|
99753
|
-
);
|
|
99754
|
-
const modelsCommand = make$4(
|
|
99755
|
-
"models",
|
|
99756
|
-
{ org: orgOption, type: typeOption, json: jsonOption$3 },
|
|
99757
|
-
({ org, type, json }) => gen(function* () {
|
|
99758
|
-
const api = yield* ApiService;
|
|
99759
|
-
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
99760
|
-
const catalog = yield* api.listModelExecModels(orgSlug).pipe(
|
|
99761
|
-
catchTag(
|
|
99762
|
-
"NotLoggedInError",
|
|
99763
|
-
(error) => gen(function* () {
|
|
99764
|
-
yield* error$1(error.message);
|
|
99765
|
-
return yield* fail$3(error);
|
|
99766
|
-
})
|
|
99767
|
-
),
|
|
99768
|
-
catchTag(
|
|
99769
|
-
"ApiError",
|
|
99770
|
-
(error) => gen(function* () {
|
|
99771
|
-
yield* error$1(`Failed to fetch model-exec models: ${error.message}`);
|
|
99772
|
-
return yield* fail$3(error);
|
|
99773
|
-
})
|
|
99774
|
-
)
|
|
99775
|
-
);
|
|
99776
|
-
const models = filterModelExecModels(catalog, getOrUndefined(type));
|
|
99777
|
-
if (json) {
|
|
99778
|
-
yield* log(jsonFormat({ ...catalog, models }));
|
|
99779
|
-
return;
|
|
99780
|
-
}
|
|
99781
|
-
if (models.length === 0) {
|
|
99782
|
-
yield* log("No model-exec models available.");
|
|
99783
|
-
return;
|
|
99784
|
-
}
|
|
99785
|
-
yield* log(`Model-exec models in organization "${orgSlug}":
|
|
99786
|
-
`);
|
|
99787
|
-
for (const model of models) {
|
|
99788
|
-
const name = model.displayName ? ` (${model.displayName})` : "";
|
|
99789
|
-
const marker = model.default ? " default" : "";
|
|
99790
|
-
yield* log(` ${model.id}${name}`);
|
|
99791
|
-
yield* log(` Type: ${model.type}${marker}`);
|
|
99792
|
-
}
|
|
99793
|
-
})
|
|
99794
|
-
).pipe(withDescription("List experimental model-exec models by capability"));
|
|
99795
|
-
|
|
99796
|
-
const modelIdArg = text$2({ name: "model-id" }).pipe(withDescription$5("Model ID"));
|
|
99797
|
-
const saveOption = optional(
|
|
99798
|
-
text("save").pipe(withDescription$3("Save sample JSON to a file"))
|
|
99799
|
-
);
|
|
99800
|
-
const sampleCommand = make$4(
|
|
99801
|
-
"sample",
|
|
99802
|
-
{ modelId: modelIdArg, org: orgOption, save: saveOption },
|
|
99803
|
-
({ modelId, org, save }) => gen(function* () {
|
|
99804
|
-
const api = yield* ApiService;
|
|
99805
|
-
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
99806
|
-
const catalog = yield* api.listModelExecModels(orgSlug).pipe(
|
|
99807
|
-
catchTag(
|
|
99808
|
-
"NotLoggedInError",
|
|
99809
|
-
(error) => gen(function* () {
|
|
99810
|
-
yield* error$1(error.message);
|
|
99811
|
-
return yield* fail$3(error);
|
|
99812
|
-
})
|
|
99813
|
-
),
|
|
99814
|
-
catchTag(
|
|
99815
|
-
"ApiError",
|
|
99816
|
-
(error) => gen(function* () {
|
|
99817
|
-
yield* error$1(`Failed to fetch model "${modelId}": ${error.message}`);
|
|
99818
|
-
return yield* fail$3(error);
|
|
99819
|
-
})
|
|
99820
|
-
)
|
|
99821
|
-
);
|
|
99822
|
-
const model = catalog.models.find((item) => item.id === modelId);
|
|
99823
|
-
if (!model) {
|
|
99824
|
-
const error = new ApiError({ message: `Model "${modelId}" not found.`, statusCode: 404 });
|
|
99825
|
-
yield* error$1(error.message);
|
|
99826
|
-
return yield* fail$3(error);
|
|
99827
|
-
}
|
|
99828
|
-
const sample = buildModelExecSampleInput(model);
|
|
99829
|
-
if (isSome(save)) {
|
|
99830
|
-
yield* saveJsonFile(save.value, sample);
|
|
99831
|
-
yield* log(`Saved sample input to ${save.value}`);
|
|
99832
|
-
return;
|
|
99833
|
-
}
|
|
99834
|
-
yield* log(jsonFormat(sample));
|
|
99835
|
-
})
|
|
99836
|
-
).pipe(withDescription("Generate sample JSON input for a model-exec model"));
|
|
99837
|
-
|
|
99838
|
-
const modelExecCommandDescription = "Experimental one-shot model execution for chat and image-generation models";
|
|
99839
|
-
const modelExecSubcommands = [
|
|
99840
|
-
modelsCommand,
|
|
99841
|
-
getCommand$1,
|
|
99842
|
-
sampleCommand,
|
|
99843
|
-
chatCommand,
|
|
99844
|
-
imageCommand
|
|
99845
|
-
];
|
|
99846
|
-
const modelExecCommand = make$4("model-exec", {}).pipe(
|
|
99847
|
-
withDescription(modelExecCommandDescription),
|
|
99848
|
-
withSubcommands(modelExecSubcommands)
|
|
99849
|
-
);
|
|
99850
|
-
|
|
99851
99312
|
const capabilitiesCommand = make$4(
|
|
99852
99313
|
"capabilities",
|
|
99853
99314
|
{ org: orgOption },
|
|
@@ -100540,12 +100001,11 @@ const rootSubcommands = [
|
|
|
100540
100001
|
agentCommand,
|
|
100541
100002
|
authCommand,
|
|
100542
100003
|
automationCommand,
|
|
100543
|
-
chatCommand
|
|
100004
|
+
chatCommand,
|
|
100544
100005
|
configCommand,
|
|
100545
100006
|
driveCommand,
|
|
100546
100007
|
integrationCommand,
|
|
100547
100008
|
modelCommand,
|
|
100548
|
-
modelExecCommand,
|
|
100549
100009
|
orgCommand,
|
|
100550
100010
|
skillCommand,
|
|
100551
100011
|
...nativeSubcommands
|
|
@@ -58,7 +58,6 @@
|
|
|
58
58
|
| 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
59
|
| 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
60
|
| P0-MODEL-01 | model | `aipctl model list` | `listModels` | chat | `GET` | `/api/{orgSlug}/models` | none | CLI maps official `{ models: string[], defaultModel? }` into `Model[]` with optional `isDefault` | `resource/oas/chat.yaml` | `frontend/packages/api/src/out/chat-types.ts#paths["/api/{orgSlug}/models"]` | `legacy-generated` | `P0` | `migrate` | none | `AIP-PUB-05` | updated `src/core/api.test.ts`, `commands/model/model.test.ts`; covers official path and string-array response mapping |
|
|
61
|
-
| P1-MODEL-EXEC-01 | model-exec | `aipctl model-exec models`, `get`, `sample`, `chat`, `image generate` | `listModelExecModels`, `executeModelExecChat`, `executeModelExecImageGeneration`; image output uses `downloadFromUrl` | chat + external artifact URL | `GET`, `POST`, `POST`, external `GET` | `/api/{orgSlug}/cli/model-exec/models`; `/chat`; `/images/generations`; response `downloadUrl` | local `ModelExecChatRequest`, `ModelExecImageGenerationRequest`; Chat DTO source `chat/packages/chat/src/modules/cli-model-exec/interface/dto/cli-model-exec.dto.ts` | local `ModelExecModelCatalog`, `ModelExecChatResponse`, `ModelExecImageGenerationResponse`; image bytes from external URL | not found in current `resource/oas`; implemented by `chat/packages/chat/src/modules/cli-model-exec/interface/cli-model-exec.interface.controller.ts` | none | `oas-missing` | `P1` | `legacy-exception` | owner=`chat CLI Model Exec API`; rationale=`experimental public command is implemented with Chat zod DTOs but no current OAS path`; removal condition=`CLI model-exec paths and DTOs are published in the Chat contract`; incorporation plan=`add the three paths and schemas to the Chat OAS, generate an independent reference, then bind CLI DTO/tests` | `AIP-PUB-05` | existing `src/core/api.test.ts`, `commands/model-exec/model-exec.test.ts`, `commands/model-exec/progress.test.ts`; covers three paths, request bodies, required Chat DTO response fields, helper/progress behavior. Needed: image command response → external download → file write regression test |
|
|
62
61
|
| 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 |
|
|
63
62
|
| AUDIT-01 | audit | `aipctl admin audit list`, `types` | `listAuditLogs`, `listAuditEventTypes` | api | `GET` | `/api/web/audit/organization/slug/{organizationSlug}`; `/api/web/audit/event/types` | query `{ eventType,page,pageSize }` | local `ListAuditResponse`, `AuditEventType[]` | `resource/oas/modules/backend/audit/openapi.yaml` | `frontend/packages/api/src/out/modules/backend-audit-types.ts#paths[...]` | `generated-ready` | N/A | `keep` | none | N/A | existing `commands/audit/audit.test.ts`; needed generated path snapshots |
|
|
64
63
|
| 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` | `frontend/packages/api/src/out/modules/tunnel-types.ts#paths[...]` | `generated-ready` | N/A | `keep` | none | N/A | existing `commands/tunnel/tunnel.test.ts`; needed v2 path snapshot |
|
|
@@ -83,7 +82,6 @@
|
|
|
83
82
|
- `P1-PRESET-01` preset admin namespace/docs + legacy path tests done
|
|
84
83
|
- `P1-SKILL-01` skill JSON/help/docs field sync done
|
|
85
84
|
- `P1-CHAT-01` chat SSE fixture tests added for final/fallback/error cases
|
|
86
|
-
- `P1-MODEL-EXEC-01` experimental CLI model-exec contract remains OAS-missing; current Chat controller/DTO and CLI path tests are recorded
|
|
87
85
|
|
|
88
86
|
## Manual notes
|
|
89
87
|
|
package/docs/architecture.md
CHANGED
|
@@ -59,7 +59,7 @@ desktop/packages/cli/
|
|
|
59
59
|
|
|
60
60
|
- package base version: `0.0.0`
|
|
61
61
|
- publish-time CalVer가 `AIPCTL_VERSION`으로 TS bundle과 Go ldflags에 주입됩니다.
|
|
62
|
-
- `AIPCTL_BUILD_ENV`는 `local|dev|
|
|
62
|
+
- `AIPCTL_BUILD_ENV`는 `local|dev|stage|prod|test` 중 하나이며 `logs` gating에 사용됩니다.
|
|
63
63
|
- native input hash가 이전 발행본과 같으면 platform package를 새로 빌드하지 않고 기존 version을 재사용합니다.
|
|
64
64
|
|
|
65
65
|
## Dependency direction
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aipctl",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.16",
|
|
4
4
|
"description": "QueryPie AIP and MCP CLI tool",
|
|
5
5
|
"author": "QueryPie",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
"node": ">=24.18.0"
|
|
23
23
|
},
|
|
24
24
|
"metadata": {
|
|
25
|
-
"contentHash": "
|
|
26
|
-
"wrapperHash": "
|
|
25
|
+
"contentHash": "156db2615eb6ffb678be96f2e25f38d9628decf8121bcbf638755924ef6fe6ca",
|
|
26
|
+
"wrapperHash": "bf02d1a5ff6b11af9ea359c0e5996a361d47b0f9f5414b7e590477deae7cfe9f",
|
|
27
27
|
"nativeHash": "bfaa115ac53b30ba141fbe842585a0ed0fca487e2eb356cda219516e53c8b4c0"
|
|
28
28
|
},
|
|
29
29
|
"optionalDependencies": {
|
|
30
|
-
"aipctl-darwin-x64": "2026.7.
|
|
31
|
-
"aipctl-darwin-arm64": "2026.7.
|
|
32
|
-
"aipctl-linux-x64": "2026.7.
|
|
33
|
-
"aipctl-linux-arm64": "2026.7.
|
|
34
|
-
"aipctl-windows-x64": "2026.7.
|
|
35
|
-
"aipctl-windows-arm64": "2026.7.
|
|
30
|
+
"aipctl-darwin-x64": "2026.7.16",
|
|
31
|
+
"aipctl-darwin-arm64": "2026.7.16",
|
|
32
|
+
"aipctl-linux-x64": "2026.7.16",
|
|
33
|
+
"aipctl-linux-arm64": "2026.7.16",
|
|
34
|
+
"aipctl-windows-x64": "2026.7.16",
|
|
35
|
+
"aipctl-windows-arm64": "2026.7.16"
|
|
36
36
|
}
|
|
37
37
|
}
|