@lotics/cli 0.62.1 → 0.63.0
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 +2 -0
- package/dist/app_commands.d.ts +11 -0
- package/dist/app_commands.js +44 -0
- package/dist/app_commands.test.js +66 -1
- package/dist/cli.js +11 -1
- package/dist/client.d.ts +17 -0
- package/dist/client.js +10 -0
- package/dist/src/cli.js +58 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -156,6 +156,8 @@ Run `lotics xlsx` or `lotics docx` with no subcommand for the full list.
|
|
|
156
156
|
lotics app create "Sales Desk" # scaffold + deploy v1
|
|
157
157
|
lotics app pull app_... # bootstrap an existing app locally
|
|
158
158
|
lotics app deploy -m "Add quote drawer" # build + upload a new version
|
|
159
|
+
lotics app versions # deploy history: version, when, who, -m message (* = live)
|
|
160
|
+
lotics app versions app_... # ...for any app, without pulling it first
|
|
159
161
|
|
|
160
162
|
# Regenerate .lotics/* WITHOUT a deploy: the .d.ts type companions (always) +
|
|
161
163
|
# the runtime app_fields.ts (when authenticated) — F/OPT maps that address
|
package/dist/app_commands.d.ts
CHANGED
|
@@ -196,6 +196,17 @@ export declare function appSetSubdomain(client: LoticsClient, args: {
|
|
|
196
196
|
export declare function appRename(client: LoticsClient, args: {
|
|
197
197
|
name: string;
|
|
198
198
|
}): Promise<void>;
|
|
199
|
+
/**
|
|
200
|
+
* `lotics app versions [app_id]` — print the app's deploy history, newest
|
|
201
|
+
* first: version number, when, deployer, build status, and the `-m` message.
|
|
202
|
+
* With no `app_id`, reads it from the local `package.json` manifest (run inside
|
|
203
|
+
* the app dir); pass an explicit `app_id` to inspect any app without pulling it.
|
|
204
|
+
* The currently served version is marked with `*`. Admin-only server-side.
|
|
205
|
+
*/
|
|
206
|
+
export declare function appVersions(client: LoticsClient, args: {
|
|
207
|
+
app_id?: string;
|
|
208
|
+
limit?: number;
|
|
209
|
+
}): Promise<void>;
|
|
199
210
|
/**
|
|
200
211
|
* Where `lotics app pull <app_id>` lands when given NO explicit path. If the cwd
|
|
201
212
|
* IS already this app's own project (its manifest `app_id` matches), refresh in
|
package/dist/app_commands.js
CHANGED
|
@@ -630,6 +630,50 @@ export async function appRename(client, args) {
|
|
|
630
630
|
throw new Error(res.error);
|
|
631
631
|
console.error(`App renamed: "${args.name}" (${meta.app_id})`);
|
|
632
632
|
}
|
|
633
|
+
/**
|
|
634
|
+
* `lotics app versions [app_id]` — print the app's deploy history, newest
|
|
635
|
+
* first: version number, when, deployer, build status, and the `-m` message.
|
|
636
|
+
* With no `app_id`, reads it from the local `package.json` manifest (run inside
|
|
637
|
+
* the app dir); pass an explicit `app_id` to inspect any app without pulling it.
|
|
638
|
+
* The currently served version is marked with `*`. Admin-only server-side.
|
|
639
|
+
*/
|
|
640
|
+
export async function appVersions(client, args) {
|
|
641
|
+
const appId = args.app_id ?? readAppMeta(process.cwd()).app_id;
|
|
642
|
+
const { current_version_id, versions } = await client.listAppVersions(appId, {
|
|
643
|
+
limit: args.limit,
|
|
644
|
+
});
|
|
645
|
+
if (versions.length === 0) {
|
|
646
|
+
console.error(`No versions found for ${appId}.`);
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
const fmtWhen = (iso) => {
|
|
650
|
+
const d = new Date(iso);
|
|
651
|
+
if (Number.isNaN(d.getTime()))
|
|
652
|
+
return iso;
|
|
653
|
+
const p = (n) => String(n).padStart(2, "0");
|
|
654
|
+
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
|
|
655
|
+
};
|
|
656
|
+
const rows = versions.map((v) => ({
|
|
657
|
+
mark: v.id === current_version_id ? "*" : " ",
|
|
658
|
+
ver: `v${v.version}`,
|
|
659
|
+
when: fmtWhen(v.created_at),
|
|
660
|
+
by: v.created_by_name ?? v.created_by ?? "—",
|
|
661
|
+
status: v.build_status,
|
|
662
|
+
message: v.message ?? "",
|
|
663
|
+
}));
|
|
664
|
+
const colWidth = (key, header) => Math.max(header.length, ...rows.map((r) => r[key].length));
|
|
665
|
+
const wVer = colWidth("ver", "VER");
|
|
666
|
+
const wWhen = colWidth("when", "WHEN");
|
|
667
|
+
const wBy = colWidth("by", "DEPLOYER");
|
|
668
|
+
const wStatus = colWidth("status", "STATUS");
|
|
669
|
+
const pad = (s, n) => s.padEnd(n);
|
|
670
|
+
// Title → stderr (status); the table → stdout (data), so it stays pipeable.
|
|
671
|
+
console.error(`Deploy history — ${appId} (${versions.length} version${versions.length === 1 ? "" : "s"}, newest first; * = currently served)`);
|
|
672
|
+
console.log(` ${pad("VER", wVer)} ${pad("WHEN", wWhen)} ${pad("DEPLOYER", wBy)} ${pad("STATUS", wStatus)} MESSAGE`);
|
|
673
|
+
for (const r of rows) {
|
|
674
|
+
console.log(`${r.mark} ${pad(r.ver, wVer)} ${pad(r.when, wWhen)} ${pad(r.by, wBy)} ${pad(r.status, wStatus)} ${r.message}`.trimEnd());
|
|
675
|
+
}
|
|
676
|
+
}
|
|
633
677
|
/**
|
|
634
678
|
* Where `lotics app pull <app_id>` lands when given NO explicit path. If the cwd
|
|
635
679
|
* IS already this app's own project (its manifest `app_id` matches), refresh in
|
|
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
|
-
import { stampPulledManifest, undeclaredCapabilities, appDirName, defaultPullTarget, ensureWorkflowTsconfigExcludes, appCodegen, appUiLink, appWorkflowSet, appWorkflowPull, appExecuteWorkflow, writeWorkflowFile, writeWorkflowGlobals, stripWorkflowHeader, FALLBACK_ENVELOPE_PREFIX, FALLBACK_ENVELOPE_SUFFIX, } from "./app_commands.js";
|
|
5
|
+
import { stampPulledManifest, undeclaredCapabilities, appDirName, defaultPullTarget, ensureWorkflowTsconfigExcludes, appCodegen, appUiLink, appVersions, appWorkflowSet, appWorkflowPull, appExecuteWorkflow, writeWorkflowFile, writeWorkflowGlobals, stripWorkflowHeader, FALLBACK_ENVELOPE_PREFIX, FALLBACK_ENVELOPE_SUFFIX, } from "./app_commands.js";
|
|
6
6
|
/**
|
|
7
7
|
* `appPull` reads workflows from the live App row (server response), NOT from
|
|
8
8
|
* the manifest embedded in the extracted source archive. The frozen archive
|
|
@@ -724,3 +724,68 @@ describe("ensureWorkflowTsconfigExcludes", () => {
|
|
|
724
724
|
expect(fs.readFileSync(tsconfigPath(), "utf-8")).toBe("{ not json,, }");
|
|
725
725
|
});
|
|
726
726
|
});
|
|
727
|
+
describe("appVersions", () => {
|
|
728
|
+
let logLines;
|
|
729
|
+
let errLines;
|
|
730
|
+
beforeEach(() => {
|
|
731
|
+
logLines = [];
|
|
732
|
+
errLines = [];
|
|
733
|
+
vi.spyOn(console, "log").mockImplementation((...args) => {
|
|
734
|
+
logLines.push(String(args[0]));
|
|
735
|
+
});
|
|
736
|
+
vi.spyOn(console, "error").mockImplementation((...args) => {
|
|
737
|
+
errLines.push(String(args[0]));
|
|
738
|
+
});
|
|
739
|
+
});
|
|
740
|
+
afterEach(() => {
|
|
741
|
+
vi.restoreAllMocks();
|
|
742
|
+
});
|
|
743
|
+
const clientWith = (payload) => ({ listAppVersions: vi.fn().mockResolvedValue(payload) });
|
|
744
|
+
it("renders history newest-first, marks the current version, and prefers the deployer name", async () => {
|
|
745
|
+
const client = clientWith({
|
|
746
|
+
current_version_id: "apv_2",
|
|
747
|
+
versions: [
|
|
748
|
+
{
|
|
749
|
+
id: "apv_2",
|
|
750
|
+
version: 2,
|
|
751
|
+
message: "add receipt gate",
|
|
752
|
+
build_status: "success",
|
|
753
|
+
bundle_size_bytes: 1234,
|
|
754
|
+
created_at: "2026-06-24T03:04:41Z",
|
|
755
|
+
created_by: "mem_a",
|
|
756
|
+
created_by_name: "Minh Vu",
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
id: "apv_1",
|
|
760
|
+
version: 1,
|
|
761
|
+
message: "initial deploy",
|
|
762
|
+
build_status: "success",
|
|
763
|
+
bundle_size_bytes: 1000,
|
|
764
|
+
created_at: "2026-06-23T08:00:00Z",
|
|
765
|
+
created_by: "mem_b",
|
|
766
|
+
created_by_name: null,
|
|
767
|
+
},
|
|
768
|
+
],
|
|
769
|
+
});
|
|
770
|
+
// Explicit app_id → no manifest/package.json in cwd required.
|
|
771
|
+
await appVersions(client, { app_id: "app_x" });
|
|
772
|
+
// One header row + one row per version, all on stdout.
|
|
773
|
+
expect(logLines.length).toBe(3);
|
|
774
|
+
const v2Row = logLines.find((l) => l.includes("v2"));
|
|
775
|
+
const v1Row = logLines.find((l) => l.includes("v1"));
|
|
776
|
+
// Currently-served version is marked with `*`; the other is not.
|
|
777
|
+
expect(v2Row.startsWith("*")).toBe(true);
|
|
778
|
+
expect(v1Row.startsWith("*")).toBe(false);
|
|
779
|
+
// Messages render; the deployer name is preferred, falling back to the id.
|
|
780
|
+
expect(v2Row).toContain("add receipt gate");
|
|
781
|
+
expect(v2Row).toContain("Minh Vu");
|
|
782
|
+
expect(v1Row).toContain("initial deploy");
|
|
783
|
+
expect(v1Row).toContain("mem_b");
|
|
784
|
+
});
|
|
785
|
+
it("reports an empty history to stderr without printing a table", async () => {
|
|
786
|
+
const client = clientWith({ current_version_id: null, versions: [] });
|
|
787
|
+
await appVersions(client, { app_id: "app_empty" });
|
|
788
|
+
expect(logLines).toEqual([]);
|
|
789
|
+
expect(errLines.join("\n")).toContain("No versions found");
|
|
790
|
+
});
|
|
791
|
+
});
|
package/dist/cli.js
CHANGED
|
@@ -13,7 +13,7 @@ net.setDefaultAutoSelectFamilyAttemptTimeout(2000);
|
|
|
13
13
|
import { LoticsClient, API_BASE_URL } from "./client.js";
|
|
14
14
|
import { resolveContext, deleteConfig, getConfigPath, loadGlobalConfig, saveGlobalConfig, loadLocalConfig, upsertProfile, removeProfile, setActiveOrg, setSelectedWorkspace, resolveProfileByNameOrId, checkForUpdate, } from "./config.js";
|
|
15
15
|
import { VERSION } from "./version.js";
|
|
16
|
-
import { appCreate, appPull, appDeploy, appDev, appSetSubdomain, appRename, appCodegen, appExecuteWorkflow, appWorkflowSet, appWorkflowPull, appWorkflowCheck, appUiLink, } from "./app_commands.js";
|
|
16
|
+
import { appCreate, appPull, appDeploy, appDev, appSetSubdomain, appRename, appVersions, appCodegen, appExecuteWorkflow, appWorkflowSet, appWorkflowPull, appWorkflowCheck, appUiLink, } from "./app_commands.js";
|
|
17
17
|
import { parseArgs } from "./args.js";
|
|
18
18
|
import { ingestJsonArgs } from "./inputs.js";
|
|
19
19
|
import { runXlsxCommand } from "./xlsx.js";
|
|
@@ -74,6 +74,9 @@ COMMANDS
|
|
|
74
74
|
lotics app deploy [-m <message>] Build + upload current dir as a new version
|
|
75
75
|
(code + queries only — workflow bindings are
|
|
76
76
|
managed by set_app_workflow / remove_app_workflow)
|
|
77
|
+
lotics app versions [app_id] Show deploy history newest-first (version,
|
|
78
|
+
timestamp, deployer, build status, -m message;
|
|
79
|
+
* marks the currently served version)
|
|
77
80
|
lotics app codegen [path] Regenerate .lotics/* (types + field/option ids)
|
|
78
81
|
from the manifest + workspace schema — no deploy
|
|
79
82
|
lotics app workflow run <alias> '<json>' Execute a bound app workflow end-to-end
|
|
@@ -596,6 +599,7 @@ async function main() {
|
|
|
596
599
|
console.error(" lotics app create <name> [path] Scaffold a new app locally");
|
|
597
600
|
console.error(" lotics app pull <app_id> [path] Pull an existing app for local editing");
|
|
598
601
|
console.error(" lotics app deploy [-m <message>] Build + upload the current directory");
|
|
602
|
+
console.error(" lotics app versions [app_id] Show deploy history (version, when, who, message)");
|
|
599
603
|
console.error(" lotics app codegen [path] Regenerate .lotics/* (types + field ids) — no deploy");
|
|
600
604
|
console.error(" lotics app workflow run <alias> '<json>' Execute a bound app workflow end-to-end");
|
|
601
605
|
console.error(" lotics app workflow set <alias> Push the edited src/workflows/<alias>.ts body");
|
|
@@ -749,6 +753,12 @@ async function main() {
|
|
|
749
753
|
await appRename(client, { name: newName });
|
|
750
754
|
return;
|
|
751
755
|
}
|
|
756
|
+
if (subcommand === "versions") {
|
|
757
|
+
// Optional positional app_id (inspect any app); else read the local manifest.
|
|
758
|
+
const appId = toolArgs || undefined;
|
|
759
|
+
await appVersions(client, { app_id: appId });
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
752
762
|
if (subcommand === "workflow") {
|
|
753
763
|
// `lotics app workflow <run|set|pull> …` — disambiguated subcommands so an
|
|
754
764
|
// alias can never collide with the verb. `toolArgs` is the verb; `restArgs`
|
package/dist/client.d.ts
CHANGED
|
@@ -199,6 +199,23 @@ export declare class LoticsClient {
|
|
|
199
199
|
build_status: string;
|
|
200
200
|
}>;
|
|
201
201
|
getAppVersionSourceUrl(app_id: string, version_id: string): Promise<string>;
|
|
202
|
+
/** Deploy history for an app — newest first. Backs `lotics app versions`. */
|
|
203
|
+
listAppVersions(app_id: string, opts?: {
|
|
204
|
+
limit?: number;
|
|
205
|
+
offset?: number;
|
|
206
|
+
}): Promise<{
|
|
207
|
+
current_version_id: string | null;
|
|
208
|
+
versions: Array<{
|
|
209
|
+
id: string;
|
|
210
|
+
version: number;
|
|
211
|
+
message: string | null;
|
|
212
|
+
build_status: string;
|
|
213
|
+
bundle_size_bytes: number | null;
|
|
214
|
+
created_at: string;
|
|
215
|
+
created_by: string | null;
|
|
216
|
+
created_by_name: string | null;
|
|
217
|
+
}>;
|
|
218
|
+
}>;
|
|
202
219
|
/**
|
|
203
220
|
* Run a named query declared in the app's manifest, scoped to the app's IAM
|
|
204
221
|
* principal. Mirrors POST /v1/apps/{app_id}/query.
|
package/dist/client.js
CHANGED
|
@@ -244,6 +244,16 @@ export class LoticsClient {
|
|
|
244
244
|
const result = await this.request("GET", `/v1/apps/${encodeURIComponent(app_id)}/versions/${encodeURIComponent(version_id)}/source`);
|
|
245
245
|
return result.url;
|
|
246
246
|
}
|
|
247
|
+
/** Deploy history for an app — newest first. Backs `lotics app versions`. */
|
|
248
|
+
async listAppVersions(app_id, opts) {
|
|
249
|
+
const qs = new URLSearchParams();
|
|
250
|
+
if (opts?.limit != null)
|
|
251
|
+
qs.set("limit", String(opts.limit));
|
|
252
|
+
if (opts?.offset != null)
|
|
253
|
+
qs.set("offset", String(opts.offset));
|
|
254
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
255
|
+
return this.request("GET", `/v1/apps/${encodeURIComponent(app_id)}/versions${suffix}`);
|
|
256
|
+
}
|
|
247
257
|
// ── App iframe RPC endpoints ──────────────────────────────────────────────
|
|
248
258
|
// These mirror the two ops handled by frontend/features/app_ui/app_iframe_host.tsx.
|
|
249
259
|
// The deployed iframe sends postMessage to the parent frontend, which calls
|
package/dist/src/cli.js
CHANGED
|
@@ -29803,6 +29803,14 @@ var LoticsClient = class {
|
|
|
29803
29803
|
);
|
|
29804
29804
|
return result.url;
|
|
29805
29805
|
}
|
|
29806
|
+
/** Deploy history for an app — newest first. Backs `lotics app versions`. */
|
|
29807
|
+
async listAppVersions(app_id, opts) {
|
|
29808
|
+
const qs = new URLSearchParams();
|
|
29809
|
+
if (opts?.limit != null) qs.set("limit", String(opts.limit));
|
|
29810
|
+
if (opts?.offset != null) qs.set("offset", String(opts.offset));
|
|
29811
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
29812
|
+
return this.request("GET", `/v1/apps/${encodeURIComponent(app_id)}/versions${suffix}`);
|
|
29813
|
+
}
|
|
29806
29814
|
// ── App iframe RPC endpoints ──────────────────────────────────────────────
|
|
29807
29815
|
// These mirror the two ops handled by frontend/features/app_ui/app_iframe_host.tsx.
|
|
29808
29816
|
// The deployed iframe sends postMessage to the parent frontend, which calls
|
|
@@ -32529,6 +32537,47 @@ async function appRename(client, args) {
|
|
|
32529
32537
|
if (res.error) throw new Error(res.error);
|
|
32530
32538
|
console.error(`App renamed: "${args.name}" (${meta.app_id})`);
|
|
32531
32539
|
}
|
|
32540
|
+
async function appVersions(client, args) {
|
|
32541
|
+
const appId = args.app_id ?? readAppMeta(process.cwd()).app_id;
|
|
32542
|
+
const { current_version_id, versions } = await client.listAppVersions(appId, {
|
|
32543
|
+
limit: args.limit
|
|
32544
|
+
});
|
|
32545
|
+
if (versions.length === 0) {
|
|
32546
|
+
console.error(`No versions found for ${appId}.`);
|
|
32547
|
+
return;
|
|
32548
|
+
}
|
|
32549
|
+
const fmtWhen = (iso) => {
|
|
32550
|
+
const d = new Date(iso);
|
|
32551
|
+
if (Number.isNaN(d.getTime())) return iso;
|
|
32552
|
+
const p = (n) => String(n).padStart(2, "0");
|
|
32553
|
+
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
|
|
32554
|
+
};
|
|
32555
|
+
const rows = versions.map((v) => ({
|
|
32556
|
+
mark: v.id === current_version_id ? "*" : " ",
|
|
32557
|
+
ver: `v${v.version}`,
|
|
32558
|
+
when: fmtWhen(v.created_at),
|
|
32559
|
+
by: v.created_by_name ?? v.created_by ?? "\u2014",
|
|
32560
|
+
status: v.build_status,
|
|
32561
|
+
message: v.message ?? ""
|
|
32562
|
+
}));
|
|
32563
|
+
const colWidth = (key, header) => Math.max(header.length, ...rows.map((r) => r[key].length));
|
|
32564
|
+
const wVer = colWidth("ver", "VER");
|
|
32565
|
+
const wWhen = colWidth("when", "WHEN");
|
|
32566
|
+
const wBy = colWidth("by", "DEPLOYER");
|
|
32567
|
+
const wStatus = colWidth("status", "STATUS");
|
|
32568
|
+
const pad = (s, n) => s.padEnd(n);
|
|
32569
|
+
console.error(
|
|
32570
|
+
`Deploy history \u2014 ${appId} (${versions.length} version${versions.length === 1 ? "" : "s"}, newest first; * = currently served)`
|
|
32571
|
+
);
|
|
32572
|
+
console.log(
|
|
32573
|
+
` ${pad("VER", wVer)} ${pad("WHEN", wWhen)} ${pad("DEPLOYER", wBy)} ${pad("STATUS", wStatus)} MESSAGE`
|
|
32574
|
+
);
|
|
32575
|
+
for (const r of rows) {
|
|
32576
|
+
console.log(
|
|
32577
|
+
`${r.mark} ${pad(r.ver, wVer)} ${pad(r.when, wWhen)} ${pad(r.by, wBy)} ${pad(r.status, wStatus)} ${r.message}`.trimEnd()
|
|
32578
|
+
);
|
|
32579
|
+
}
|
|
32580
|
+
}
|
|
32532
32581
|
function defaultPullTarget(appId, appName) {
|
|
32533
32582
|
const cwdPkgPath = path5.join(process.cwd(), "package.json");
|
|
32534
32583
|
if (fs4.existsSync(cwdPkgPath)) {
|
|
@@ -49157,6 +49206,9 @@ COMMANDS
|
|
|
49157
49206
|
lotics app deploy [-m <message>] Build + upload current dir as a new version
|
|
49158
49207
|
(code + queries only \u2014 workflow bindings are
|
|
49159
49208
|
managed by set_app_workflow / remove_app_workflow)
|
|
49209
|
+
lotics app versions [app_id] Show deploy history newest-first (version,
|
|
49210
|
+
timestamp, deployer, build status, -m message;
|
|
49211
|
+
* marks the currently served version)
|
|
49160
49212
|
lotics app codegen [path] Regenerate .lotics/* (types + field/option ids)
|
|
49161
49213
|
from the manifest + workspace schema \u2014 no deploy
|
|
49162
49214
|
lotics app workflow run <alias> '<json>' Execute a bound app workflow end-to-end
|
|
@@ -49632,6 +49684,7 @@ async function main() {
|
|
|
49632
49684
|
console.error(" lotics app create <name> [path] Scaffold a new app locally");
|
|
49633
49685
|
console.error(" lotics app pull <app_id> [path] Pull an existing app for local editing");
|
|
49634
49686
|
console.error(" lotics app deploy [-m <message>] Build + upload the current directory");
|
|
49687
|
+
console.error(" lotics app versions [app_id] Show deploy history (version, when, who, message)");
|
|
49635
49688
|
console.error(" lotics app codegen [path] Regenerate .lotics/* (types + field ids) \u2014 no deploy");
|
|
49636
49689
|
console.error(" lotics app workflow run <alias> '<json>' Execute a bound app workflow end-to-end");
|
|
49637
49690
|
console.error(" lotics app workflow set <alias> Push the edited src/workflows/<alias>.ts body");
|
|
@@ -49778,6 +49831,11 @@ Available workspaces:`);
|
|
|
49778
49831
|
await appRename(client, { name: newName });
|
|
49779
49832
|
return;
|
|
49780
49833
|
}
|
|
49834
|
+
if (subcommand === "versions") {
|
|
49835
|
+
const appId = toolArgs || void 0;
|
|
49836
|
+
await appVersions(client, { app_id: appId });
|
|
49837
|
+
return;
|
|
49838
|
+
}
|
|
49781
49839
|
if (subcommand === "workflow") {
|
|
49782
49840
|
const action = toolArgs;
|
|
49783
49841
|
const workflowUsage = () => {
|