aipctl 2026.8.4 → 2026.8.6
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 +23 -0
- package/build/index.cjs +593 -53
- package/docs/api-contract-inventory.md +2 -0
- 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,6 +34,29 @@ 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
|
+
|
|
37
60
|
## Development
|
|
38
61
|
|
|
39
62
|
```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.8.
|
|
89673
|
+
const VERSION = "2026.8.6".length > 0 ? "2026.8.6" : "0.0.0";
|
|
89674
89674
|
const BUILD_ENV = injectedBuildEnv;
|
|
89675
89675
|
const INCLUDE_NATIVE_LOGS = BUILD_ENV !== "prod";
|
|
89676
89676
|
|
|
@@ -94487,6 +94487,30 @@ 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
|
+
}),
|
|
94490
94514
|
getCreditStatistics: (orgSlug, options) => gen(function* () {
|
|
94491
94515
|
const token = yield* getAccessToken();
|
|
94492
94516
|
const params = new URLSearchParams();
|
|
@@ -94638,6 +94662,15 @@ const ApiServiceLive = effect$1(
|
|
|
94638
94662
|
const path = `/librechat/api/${encodeURIComponent(orgSlug)}/messages/${encodeURIComponent(conversationId)}`;
|
|
94639
94663
|
return yield* makeRequest(chatBaseUrl, path, token);
|
|
94640
94664
|
}),
|
|
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
|
+
}),
|
|
94641
94674
|
// Phase 8: Agent admin CRUD
|
|
94642
94675
|
createInstalledAgent: (orgSlug, body) => gen(function* () {
|
|
94643
94676
|
const token = yield* getAccessToken();
|
|
@@ -95045,14 +95078,14 @@ function jsonFormat(data, options = {}) {
|
|
|
95045
95078
|
}
|
|
95046
95079
|
|
|
95047
95080
|
const agentIdArg$4 = text$2({ name: "id" }).pipe(withDescription$5("Agent ID to export"));
|
|
95048
|
-
const outputOption$
|
|
95081
|
+
const outputOption$3 = text("output").pipe(
|
|
95049
95082
|
withAlias("o"),
|
|
95050
95083
|
withDescription$3("Output file path (defaults to {agentId}.yaml)"),
|
|
95051
95084
|
optional
|
|
95052
95085
|
);
|
|
95053
95086
|
const exportCommand = make$4(
|
|
95054
95087
|
"export",
|
|
95055
|
-
{ agentId: agentIdArg$4, org: orgOption, output: outputOption$
|
|
95088
|
+
{ agentId: agentIdArg$4, org: orgOption, output: outputOption$3 },
|
|
95056
95089
|
({ agentId, org, output }) => gen(function* () {
|
|
95057
95090
|
const api = yield* ApiService;
|
|
95058
95091
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -95245,7 +95278,7 @@ const adminAgentCommand = make$4("agent", {}).pipe(
|
|
|
95245
95278
|
withSubcommands(adminAgentSubcommands)
|
|
95246
95279
|
);
|
|
95247
95280
|
|
|
95248
|
-
const typeOption = text("type").pipe(
|
|
95281
|
+
const typeOption$1 = text("type").pipe(
|
|
95249
95282
|
withDescription$3("Filter by event type"),
|
|
95250
95283
|
optional
|
|
95251
95284
|
);
|
|
@@ -95255,7 +95288,7 @@ const pageOption$3 = integer("page").pipe(
|
|
|
95255
95288
|
);
|
|
95256
95289
|
const listCommand$a = make$4(
|
|
95257
95290
|
"list",
|
|
95258
|
-
{ org: orgOption, type: typeOption, page: pageOption$3 },
|
|
95291
|
+
{ org: orgOption, type: typeOption$1, page: pageOption$3 },
|
|
95259
95292
|
({ org, type, page }) => gen(function* () {
|
|
95260
95293
|
const api = yield* ApiService;
|
|
95261
95294
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -95419,7 +95452,7 @@ const deleteCommand$5 = make$4(
|
|
|
95419
95452
|
).pipe(withDescription("Delete an integration by ID (requires --force to confirm)"));
|
|
95420
95453
|
|
|
95421
95454
|
const integrationIdArg$3 = text$2({ name: "id" }).pipe(withDescription$5("Integration ID"));
|
|
95422
|
-
const getCommand$
|
|
95455
|
+
const getCommand$7 = make$4(
|
|
95423
95456
|
"get",
|
|
95424
95457
|
{ integrationId: integrationIdArg$3, org: orgOption },
|
|
95425
95458
|
({ integrationId, org }) => gen(function* () {
|
|
@@ -95563,7 +95596,7 @@ const updateCommand$2 = make$4(
|
|
|
95563
95596
|
|
|
95564
95597
|
const adminIntegrationCommandDescription = "Admin integration management (get, update, delete, tools, available)";
|
|
95565
95598
|
const adminIntegrationSubcommands = [
|
|
95566
|
-
getCommand$
|
|
95599
|
+
getCommand$7,
|
|
95567
95600
|
updateCommand$2,
|
|
95568
95601
|
deleteCommand$5,
|
|
95569
95602
|
toolsCommand,
|
|
@@ -95873,14 +95906,14 @@ const deleteCommand$4 = make$4(
|
|
|
95873
95906
|
const idArg$6 = text$2({ name: "id" }).pipe(
|
|
95874
95907
|
withDescription$5("Preset ID")
|
|
95875
95908
|
);
|
|
95876
|
-
const jsonOption$
|
|
95909
|
+
const jsonOption$h = boolean("json").pipe(
|
|
95877
95910
|
withDescription$3("Output in JSON format"),
|
|
95878
95911
|
withDefault(false)
|
|
95879
95912
|
);
|
|
95880
95913
|
const formatPresetPrompt = maskSensitiveText;
|
|
95881
|
-
const getCommand$
|
|
95914
|
+
const getCommand$6 = make$4(
|
|
95882
95915
|
"get",
|
|
95883
|
-
{ id: idArg$6, org: orgOption, json: jsonOption$
|
|
95916
|
+
{ id: idArg$6, org: orgOption, json: jsonOption$h },
|
|
95884
95917
|
({ id, org, json }) => gen(function* () {
|
|
95885
95918
|
const api = yield* ApiService;
|
|
95886
95919
|
yield* resolveOrgSlug(org, api);
|
|
@@ -95927,7 +95960,7 @@ const getCommand$5 = make$4(
|
|
|
95927
95960
|
})
|
|
95928
95961
|
).pipe(withDescription("Get preset details by ID"));
|
|
95929
95962
|
|
|
95930
|
-
const jsonOption$
|
|
95963
|
+
const jsonOption$g = boolean("json").pipe(
|
|
95931
95964
|
withDescription$3(
|
|
95932
95965
|
'Output in JSON format: [{"id":"string","name":"string","isDefault":"boolean","prompt":"string|null","createdAt":"ISO-8601","updatedAt":"ISO-8601"}]'
|
|
95933
95966
|
),
|
|
@@ -95939,7 +95972,7 @@ function formatPresetListPrompt(prompt) {
|
|
|
95939
95972
|
}
|
|
95940
95973
|
const listCommand$9 = make$4(
|
|
95941
95974
|
"list",
|
|
95942
|
-
{ org: orgOption, json: jsonOption$
|
|
95975
|
+
{ org: orgOption, json: jsonOption$g },
|
|
95943
95976
|
({ org, json }) => gen(function* () {
|
|
95944
95977
|
const api = yield* ApiService;
|
|
95945
95978
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96165,7 +96198,7 @@ const updateCommand$1 = make$4(
|
|
|
96165
96198
|
const presetCommandDescription = "Manage presets (list, get, create, update, rename, delete, set-default, unset-default, regen-key, regen-static-key)";
|
|
96166
96199
|
const presetSubcommands = [
|
|
96167
96200
|
listCommand$9,
|
|
96168
|
-
getCommand$
|
|
96201
|
+
getCommand$6,
|
|
96169
96202
|
createCommand$1,
|
|
96170
96203
|
updateCommand$1,
|
|
96171
96204
|
renameCommand$1,
|
|
@@ -96286,14 +96319,14 @@ const cloneBuiltInCommand = make$4(
|
|
|
96286
96319
|
).pipe(withDescription("Clone built-in skills from the library to your organization"));
|
|
96287
96320
|
|
|
96288
96321
|
const skillIdArg$4 = text$2({ name: "id" }).pipe(withDescription$5("Skill ID to download"));
|
|
96289
|
-
const outputOption$
|
|
96322
|
+
const outputOption$2 = text("output").pipe(
|
|
96290
96323
|
withAlias("o"),
|
|
96291
96324
|
withDescription$3("Output file path (defaults to original filename)"),
|
|
96292
96325
|
optional
|
|
96293
96326
|
);
|
|
96294
96327
|
const downloadCommand$1 = make$4(
|
|
96295
96328
|
"download",
|
|
96296
|
-
{ skillId: skillIdArg$4, org: orgOption, output: outputOption$
|
|
96329
|
+
{ skillId: skillIdArg$4, org: orgOption, output: outputOption$2 },
|
|
96297
96330
|
({ skillId, org, output }) => gen(function* () {
|
|
96298
96331
|
const api = yield* ApiService;
|
|
96299
96332
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96372,7 +96405,7 @@ const applyOption = boolean("apply").pipe(
|
|
|
96372
96405
|
withDescription$3("Apply the prepared GitHub update immediately"),
|
|
96373
96406
|
withDefault(false)
|
|
96374
96407
|
);
|
|
96375
|
-
const jsonOption$
|
|
96408
|
+
const jsonOption$f = boolean("json").pipe(
|
|
96376
96409
|
withDescription$3("Output in JSON format"),
|
|
96377
96410
|
withDefault(false)
|
|
96378
96411
|
);
|
|
@@ -96411,7 +96444,7 @@ const discardPreparedSkill = (api, orgSlug, preparedSkillId) => api.abortAdminUp
|
|
|
96411
96444
|
);
|
|
96412
96445
|
const inspectCommand = make$4(
|
|
96413
96446
|
"inspect",
|
|
96414
|
-
{ githubUrl: githubUrlArg, org: orgOption, patEnv: patEnvOption, json: jsonOption$
|
|
96447
|
+
{ githubUrl: githubUrlArg, org: orgOption, patEnv: patEnvOption, json: jsonOption$f },
|
|
96415
96448
|
({ githubUrl, org, patEnv, json }) => gen(function* () {
|
|
96416
96449
|
const api = yield* ApiService;
|
|
96417
96450
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96443,7 +96476,7 @@ const inspectCommand = make$4(
|
|
|
96443
96476
|
).pipe(withDescription("Inspect a GitHub repository for skill import"));
|
|
96444
96477
|
const importCommand = make$4(
|
|
96445
96478
|
"import",
|
|
96446
|
-
{ githubUrl: githubUrlArg, org: orgOption, patEnv: patEnvOption, overwrite: overwriteOption$2, json: jsonOption$
|
|
96479
|
+
{ githubUrl: githubUrlArg, org: orgOption, patEnv: patEnvOption, overwrite: overwriteOption$2, json: jsonOption$f },
|
|
96447
96480
|
({ githubUrl, org, patEnv, overwrite, json }) => gen(function* () {
|
|
96448
96481
|
const api = yield* ApiService;
|
|
96449
96482
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96481,7 +96514,7 @@ const importCommand = make$4(
|
|
|
96481
96514
|
).pipe(withDescription("Import a skill from GitHub"));
|
|
96482
96515
|
const syncCommand = make$4(
|
|
96483
96516
|
"sync",
|
|
96484
|
-
{ skillId: skillIdArg$3, org: orgOption, apply: applyOption, json: jsonOption$
|
|
96517
|
+
{ skillId: skillIdArg$3, org: orgOption, apply: applyOption, json: jsonOption$f },
|
|
96485
96518
|
({ skillId, org, apply, json }) => gen(function* () {
|
|
96486
96519
|
const api = yield* ApiService;
|
|
96487
96520
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96594,7 +96627,7 @@ const pageSizeOption = integer("page-size").pipe(
|
|
|
96594
96627
|
withDescription$3("Page size (default: 20)"),
|
|
96595
96628
|
optional
|
|
96596
96629
|
);
|
|
96597
|
-
const jsonOption$
|
|
96630
|
+
const jsonOption$e = boolean("json").pipe(
|
|
96598
96631
|
withDescription$3("Output in JSON format"),
|
|
96599
96632
|
withDefault(false)
|
|
96600
96633
|
);
|
|
@@ -96611,7 +96644,7 @@ const overwriteOption$1 = boolean("overwrite").pipe(
|
|
|
96611
96644
|
);
|
|
96612
96645
|
const listCommand$8 = make$4(
|
|
96613
96646
|
"list",
|
|
96614
|
-
{ org: orgOption, search: searchOption$2, page: pageOption$2, pageSize: pageSizeOption, json: jsonOption$
|
|
96647
|
+
{ org: orgOption, search: searchOption$2, page: pageOption$2, pageSize: pageSizeOption, json: jsonOption$e },
|
|
96615
96648
|
({ org, search, page, pageSize, json }) => gen(function* () {
|
|
96616
96649
|
const api = yield* ApiService;
|
|
96617
96650
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96670,9 +96703,9 @@ const listCommand$8 = make$4(
|
|
|
96670
96703
|
}
|
|
96671
96704
|
})
|
|
96672
96705
|
).pipe(withDescription("List organization-wide skills"));
|
|
96673
|
-
const getCommand$
|
|
96706
|
+
const getCommand$5 = make$4(
|
|
96674
96707
|
"get",
|
|
96675
|
-
{ skillId: skillIdArg$2, org: orgOption, json: jsonOption$
|
|
96708
|
+
{ skillId: skillIdArg$2, org: orgOption, json: jsonOption$e },
|
|
96676
96709
|
({ skillId, org, json }) => gen(function* () {
|
|
96677
96710
|
const api = yield* ApiService;
|
|
96678
96711
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -96863,7 +96896,7 @@ const unpublishCommand = make$4(
|
|
|
96863
96896
|
const adminSkillCommandDescription = "Admin skill management (list, get, upload, download, delete, publish, unpublish, built-in, clone-built-in, github)";
|
|
96864
96897
|
const adminSkillSubcommands = [
|
|
96865
96898
|
listCommand$8,
|
|
96866
|
-
getCommand$
|
|
96899
|
+
getCommand$5,
|
|
96867
96900
|
uploadCommand$2,
|
|
96868
96901
|
downloadCommand$1,
|
|
96869
96902
|
deleteCommand$3,
|
|
@@ -97283,7 +97316,7 @@ const agentIdOption = optional(
|
|
|
97283
97316
|
withDescription$3("Agent installation ID (UUID) to chat with. Required when starting a new chat.")
|
|
97284
97317
|
)
|
|
97285
97318
|
);
|
|
97286
|
-
const messageOption = optional(
|
|
97319
|
+
const messageOption$2 = optional(
|
|
97287
97320
|
text("message").pipe(
|
|
97288
97321
|
withAlias("m"),
|
|
97289
97322
|
withDescription$3("Message to send to the agent (if not provided, reads from stdin when piped)")
|
|
@@ -97294,7 +97327,7 @@ const conversationIdOption = optional(
|
|
|
97294
97327
|
withDescription$3("Continue an existing conversation by ID (from a previous --json result)")
|
|
97295
97328
|
)
|
|
97296
97329
|
);
|
|
97297
|
-
const jsonOption$
|
|
97330
|
+
const jsonOption$d = boolean("json").pipe(
|
|
97298
97331
|
withDescription$3('Output in JSON format: {"text":"string","conversationId":"string"}'),
|
|
97299
97332
|
withDefault(false)
|
|
97300
97333
|
);
|
|
@@ -97308,7 +97341,7 @@ const readStdin = () => tryPromise({
|
|
|
97308
97341
|
},
|
|
97309
97342
|
catch: (e) => new ApiError({ message: `Failed to read stdin: ${e instanceof Error ? e.message : String(e)}` })
|
|
97310
97343
|
});
|
|
97311
|
-
const SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
97344
|
+
const SPINNER_FRAMES$1 = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
97312
97345
|
const SPINNER_MESSAGES = ["thinking", "churning", "processing", "pondering", "working", "computing"];
|
|
97313
97346
|
const formatAgentChatTextOutput = maskSensitiveText;
|
|
97314
97347
|
const startSpinner = () => {
|
|
@@ -97316,22 +97349,22 @@ const startSpinner = () => {
|
|
|
97316
97349
|
let frameIdx = 0;
|
|
97317
97350
|
let msgIdx = 0;
|
|
97318
97351
|
const timer = setInterval(() => {
|
|
97319
|
-
frameIdx = (frameIdx + 1) % SPINNER_FRAMES.length;
|
|
97352
|
+
frameIdx = (frameIdx + 1) % SPINNER_FRAMES$1.length;
|
|
97320
97353
|
if (frameIdx === 0) msgIdx = (msgIdx + 1) % SPINNER_MESSAGES.length;
|
|
97321
|
-
process.stderr.write(`\r${SPINNER_FRAMES[frameIdx]} ${SPINNER_MESSAGES[msgIdx]}... `);
|
|
97354
|
+
process.stderr.write(`\r${SPINNER_FRAMES$1[frameIdx]} ${SPINNER_MESSAGES[msgIdx]}... `);
|
|
97322
97355
|
}, 80);
|
|
97323
97356
|
return () => {
|
|
97324
97357
|
clearInterval(timer);
|
|
97325
97358
|
process.stderr.write("\r" + " ".repeat(30) + "\r");
|
|
97326
97359
|
};
|
|
97327
97360
|
};
|
|
97328
|
-
const chatCommand$
|
|
97361
|
+
const chatCommand$2 = make$4(
|
|
97329
97362
|
"chat",
|
|
97330
97363
|
{
|
|
97331
97364
|
agentId: agentIdOption,
|
|
97332
|
-
message: messageOption,
|
|
97365
|
+
message: messageOption$2,
|
|
97333
97366
|
conversationId: conversationIdOption,
|
|
97334
|
-
json: jsonOption$
|
|
97367
|
+
json: jsonOption$d,
|
|
97335
97368
|
org: orgOption
|
|
97336
97369
|
},
|
|
97337
97370
|
({ agentId, message, conversationId, json, org }) => gen(function* () {
|
|
@@ -97411,15 +97444,15 @@ const resolveAgentChatTarget = (agentId, conversationId) => {
|
|
|
97411
97444
|
const isContinuationTarget = (target) => target.conversationId !== void 0;
|
|
97412
97445
|
|
|
97413
97446
|
const agentIdArg$1 = text$2({ name: "id" }).pipe(withDescription$5("Agent ID"));
|
|
97414
|
-
const jsonOption$
|
|
97447
|
+
const jsonOption$c = boolean("json").pipe(
|
|
97415
97448
|
withDescription$3(
|
|
97416
97449
|
'Output in JSON format: {"id":"string","displayName":"string","shortDescription":"string","description":"string|null","createdBy":"string","createdAt":"ISO-8601","updatedAt":"ISO-8601","configRequiredIntegrations":["string"]}'
|
|
97417
97450
|
),
|
|
97418
97451
|
withDefault(false)
|
|
97419
97452
|
);
|
|
97420
|
-
const getCommand$
|
|
97453
|
+
const getCommand$4 = make$4(
|
|
97421
97454
|
"get",
|
|
97422
|
-
{ agentId: agentIdArg$1, org: orgOption, json: jsonOption$
|
|
97455
|
+
{ agentId: agentIdArg$1, org: orgOption, json: jsonOption$c },
|
|
97423
97456
|
({ agentId, org, json }) => gen(function* () {
|
|
97424
97457
|
const api = yield* ApiService;
|
|
97425
97458
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -97463,7 +97496,7 @@ const getCommand$3 = make$4(
|
|
|
97463
97496
|
})
|
|
97464
97497
|
).pipe(withDescription("Get agent details by ID"));
|
|
97465
97498
|
|
|
97466
|
-
const jsonOption$
|
|
97499
|
+
const jsonOption$b = boolean("json").pipe(
|
|
97467
97500
|
withDescription$3(
|
|
97468
97501
|
'Output in JSON format: [{"id":"string","displayName":"string","agentType":"string","shortDescription":"string","createdBy":"string","createdAt":"ISO-8601"}]'
|
|
97469
97502
|
),
|
|
@@ -97471,7 +97504,7 @@ const jsonOption$6 = boolean("json").pipe(
|
|
|
97471
97504
|
);
|
|
97472
97505
|
const listCommand$7 = make$4(
|
|
97473
97506
|
"list",
|
|
97474
|
-
{ org: orgOption, json: jsonOption$
|
|
97507
|
+
{ org: orgOption, json: jsonOption$b },
|
|
97475
97508
|
({ org, json }) => gen(function* () {
|
|
97476
97509
|
const api = yield* ApiService;
|
|
97477
97510
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -97578,7 +97611,7 @@ const disableCommand$1 = make$4(
|
|
|
97578
97611
|
).pipe(withDescription("Disable an agent"));
|
|
97579
97612
|
|
|
97580
97613
|
const agentCommandDescription = "Manage agents (list, get, chat, enable, disable)";
|
|
97581
|
-
const agentSubcommands = [listCommand$7, getCommand$
|
|
97614
|
+
const agentSubcommands = [listCommand$7, getCommand$4, enableCommand$1, disableCommand$1, chatCommand$2];
|
|
97582
97615
|
const agentCommand = make$4("agent", {}).pipe(
|
|
97583
97616
|
withDescription(agentCommandDescription),
|
|
97584
97617
|
withSubcommands(agentSubcommands)
|
|
@@ -98133,16 +98166,16 @@ const deleteCommand$2 = make$4(
|
|
|
98133
98166
|
).pipe(withDescription("Delete an automation by ID (requires --force to confirm)"));
|
|
98134
98167
|
|
|
98135
98168
|
const automationIdArg$5 = text$2({ name: "id" }).pipe(withDescription$5("Automation ID"));
|
|
98136
|
-
const jsonOption$
|
|
98169
|
+
const jsonOption$a = boolean("json").pipe(
|
|
98137
98170
|
withDescription$3(
|
|
98138
98171
|
'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"}'
|
|
98139
98172
|
),
|
|
98140
98173
|
withDefault(false)
|
|
98141
98174
|
);
|
|
98142
98175
|
const formatAutomationTextOutput = maskSensitiveText;
|
|
98143
|
-
const getCommand$
|
|
98176
|
+
const getCommand$3 = make$4(
|
|
98144
98177
|
"get",
|
|
98145
|
-
{ automationId: automationIdArg$5, org: orgOption, json: jsonOption$
|
|
98178
|
+
{ automationId: automationIdArg$5, org: orgOption, json: jsonOption$a },
|
|
98146
98179
|
({ automationId, org, json }) => gen(function* () {
|
|
98147
98180
|
const api = yield* ApiService;
|
|
98148
98181
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -98253,7 +98286,7 @@ const nameOption = text("name").pipe(
|
|
|
98253
98286
|
withDescription$3("Filter automations by name"),
|
|
98254
98287
|
optional
|
|
98255
98288
|
);
|
|
98256
|
-
const jsonOption$
|
|
98289
|
+
const jsonOption$9 = boolean("json").pipe(
|
|
98257
98290
|
withDescription$3(
|
|
98258
98291
|
'Output in JSON format: [{"id":"string","name":"string","status":"string","triggerType":"string","nextExecutionTime":"ISO-8601|null","createdAt":"ISO-8601"}]'
|
|
98259
98292
|
),
|
|
@@ -98261,7 +98294,7 @@ const jsonOption$4 = boolean("json").pipe(
|
|
|
98261
98294
|
);
|
|
98262
98295
|
const listCommand$6 = make$4(
|
|
98263
98296
|
"list",
|
|
98264
|
-
{ org: orgOption, name: nameOption, json: jsonOption$
|
|
98297
|
+
{ org: orgOption, name: nameOption, json: jsonOption$9 },
|
|
98265
98298
|
({ org, name, json }) => gen(function* () {
|
|
98266
98299
|
const api = yield* ApiService;
|
|
98267
98300
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -98564,7 +98597,7 @@ const webhookRegenCommand = make$4(
|
|
|
98564
98597
|
const automationCommandDescription = "Manage automations (list, get, create, update, delete, run, enable, disable, history, cancel, webhook-regen, triggers)";
|
|
98565
98598
|
const automationSubcommands = [
|
|
98566
98599
|
listCommand$6,
|
|
98567
|
-
getCommand$
|
|
98600
|
+
getCommand$3,
|
|
98568
98601
|
createCommand,
|
|
98569
98602
|
updateCommand,
|
|
98570
98603
|
deleteCommand$2,
|
|
@@ -98584,7 +98617,7 @@ const automationCommand = make$4("automation", {}).pipe(
|
|
|
98584
98617
|
const conversationIdArg$1 = text$2({ name: "conversationId" }).pipe(
|
|
98585
98618
|
withDescription$5("Conversation ID")
|
|
98586
98619
|
);
|
|
98587
|
-
const getCommand$
|
|
98620
|
+
const getCommand$2 = make$4(
|
|
98588
98621
|
"get",
|
|
98589
98622
|
{ conversationId: conversationIdArg$1, org: orgOption },
|
|
98590
98623
|
({ conversationId, org }) => gen(function* () {
|
|
@@ -98623,7 +98656,7 @@ const getCommand$1 = make$4(
|
|
|
98623
98656
|
})
|
|
98624
98657
|
).pipe(withDescription("Get conversation details by ID"));
|
|
98625
98658
|
|
|
98626
|
-
const jsonOption$
|
|
98659
|
+
const jsonOption$8 = boolean("json").pipe(
|
|
98627
98660
|
withDescription$3(
|
|
98628
98661
|
'Output in JSON format: [{"conversationId":"string","title":"string","type":"string","updatedAt":"ISO-8601"}]'
|
|
98629
98662
|
),
|
|
@@ -98631,7 +98664,7 @@ const jsonOption$3 = boolean("json").pipe(
|
|
|
98631
98664
|
);
|
|
98632
98665
|
const listCommand$5 = make$4(
|
|
98633
98666
|
"list",
|
|
98634
|
-
{ org: orgOption, json: jsonOption$
|
|
98667
|
+
{ org: orgOption, json: jsonOption$8 },
|
|
98635
98668
|
({ org, json }) => gen(function* () {
|
|
98636
98669
|
const api = yield* ApiService;
|
|
98637
98670
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -98723,9 +98756,174 @@ const messagesCommand = make$4(
|
|
|
98723
98756
|
})
|
|
98724
98757
|
).pipe(withDescription("List messages in a conversation"));
|
|
98725
98758
|
|
|
98726
|
-
const
|
|
98727
|
-
|
|
98728
|
-
|
|
98759
|
+
const filterModelExecModels = (catalog, type) => {
|
|
98760
|
+
if (!type) {
|
|
98761
|
+
return catalog.models;
|
|
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(
|
|
98729
98927
|
withDescription(chatCommandDescription),
|
|
98730
98928
|
withSubcommands(chatSubcommands)
|
|
98731
98929
|
);
|
|
@@ -98882,13 +99080,13 @@ const deleteCommand$1 = make$4(
|
|
|
98882
99080
|
).pipe(withDescription("Delete drive entries by ID (requires --force to confirm)"));
|
|
98883
99081
|
|
|
98884
99082
|
const entryIdArg$1 = text$2({ name: "id" }).pipe(withDescription$5("Drive entry ID"));
|
|
98885
|
-
const outputOption = text("output").pipe(
|
|
99083
|
+
const outputOption$1 = text("output").pipe(
|
|
98886
99084
|
withAlias("o"),
|
|
98887
99085
|
withDescription$3("Output file path (required, as the API does not return the original filename)")
|
|
98888
99086
|
);
|
|
98889
99087
|
const downloadCommand = make$4(
|
|
98890
99088
|
"download",
|
|
98891
|
-
{ entryId: entryIdArg$1, org: orgOption, output: outputOption },
|
|
99089
|
+
{ entryId: entryIdArg$1, org: orgOption, output: outputOption$1 },
|
|
98892
99090
|
({ entryId, org, output }) => gen(function* () {
|
|
98893
99091
|
const api = yield* ApiService;
|
|
98894
99092
|
const orgSlug = yield* resolveOrgSlug(org, api);
|
|
@@ -99309,6 +99507,347 @@ const modelCommand = make$4("model", {}).pipe(
|
|
|
99309
99507
|
withSubcommands(modelSubcommands)
|
|
99310
99508
|
);
|
|
99311
99509
|
|
|
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
|
+
|
|
99312
99851
|
const capabilitiesCommand = make$4(
|
|
99313
99852
|
"capabilities",
|
|
99314
99853
|
{ org: orgOption },
|
|
@@ -100001,11 +100540,12 @@ const rootSubcommands = [
|
|
|
100001
100540
|
agentCommand,
|
|
100002
100541
|
authCommand,
|
|
100003
100542
|
automationCommand,
|
|
100004
|
-
chatCommand,
|
|
100543
|
+
chatCommand$1,
|
|
100005
100544
|
configCommand,
|
|
100006
100545
|
driveCommand,
|
|
100007
100546
|
integrationCommand,
|
|
100008
100547
|
modelCommand,
|
|
100548
|
+
modelExecCommand,
|
|
100009
100549
|
orgCommand,
|
|
100010
100550
|
skillCommand,
|
|
100011
100551
|
...nativeSubcommands
|
|
@@ -58,6 +58,7 @@
|
|
|
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 |
|
|
61
62
|
| 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 |
|
|
62
63
|
| 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 |
|
|
63
64
|
| 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 |
|
|
@@ -82,6 +83,7 @@
|
|
|
82
83
|
- `P1-PRESET-01` preset admin namespace/docs + legacy path tests done
|
|
83
84
|
- `P1-SKILL-01` skill JSON/help/docs field sync done
|
|
84
85
|
- `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
|
|
85
87
|
|
|
86
88
|
## Manual notes
|
|
87
89
|
|
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|stage|prod|test` 중 하나이며 `logs` gating에 사용됩니다.
|
|
62
|
+
- `AIPCTL_BUILD_ENV`는 `local|dev|qa|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.8.
|
|
3
|
+
"version": "2026.8.6",
|
|
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": "12a38c7debad3bfb52aca611319439410508b894852126f06e9e3bd337b39fc3",
|
|
26
|
+
"wrapperHash": "bf67d4c747818e036614ed04e2e492ba4d5c1f125ee2a4f73d1329a63a5c32a8",
|
|
27
27
|
"nativeHash": "bfaa115ac53b30ba141fbe842585a0ed0fca487e2eb356cda219516e53c8b4c0"
|
|
28
28
|
},
|
|
29
29
|
"optionalDependencies": {
|
|
30
|
-
"aipctl-darwin-x64": "2026.8.
|
|
31
|
-
"aipctl-darwin-arm64": "2026.8.
|
|
32
|
-
"aipctl-linux-x64": "2026.8.
|
|
33
|
-
"aipctl-linux-arm64": "2026.8.
|
|
34
|
-
"aipctl-windows-x64": "2026.8.
|
|
35
|
-
"aipctl-windows-arm64": "2026.8.
|
|
30
|
+
"aipctl-darwin-x64": "2026.8.5",
|
|
31
|
+
"aipctl-darwin-arm64": "2026.8.5",
|
|
32
|
+
"aipctl-linux-x64": "2026.8.5",
|
|
33
|
+
"aipctl-linux-arm64": "2026.8.5",
|
|
34
|
+
"aipctl-windows-x64": "2026.8.5",
|
|
35
|
+
"aipctl-windows-arm64": "2026.8.5"
|
|
36
36
|
}
|
|
37
37
|
}
|