@lotics/cli 0.33.0 → 0.35.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/dist/app_commands.d.ts +9 -0
- package/dist/app_commands.js +13 -0
- package/dist/cli.js +13 -1
- package/dist/client.js +9 -4
- package/dist/dev/wrapper_page.d.ts +6 -4
- package/dist/dev/wrapper_page.js +7 -5
- package/dist/src/cli.js +27 -6
- package/dist/starter_template.d.ts +1 -1
- package/dist/starter_template.js +1 -1
- package/package.json +1 -1
package/dist/app_commands.d.ts
CHANGED
|
@@ -86,6 +86,15 @@ export declare function appCreate(client: LoticsClient, args: {
|
|
|
86
86
|
export declare function appSetSubdomain(client: LoticsClient, args: {
|
|
87
87
|
subdomain: string;
|
|
88
88
|
}): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* `lotics app rename <name>` — change the current app's display name (the
|
|
91
|
+
* launcher/title shown in the workspace). The app_id comes from the local
|
|
92
|
+
* `package.json` manifest. Wraps the `update_app` tool — the public address
|
|
93
|
+
* (`lotics app subdomain`) and the code (`lotics app deploy`) are unchanged.
|
|
94
|
+
*/
|
|
95
|
+
export declare function appRename(client: LoticsClient, args: {
|
|
96
|
+
name: string;
|
|
97
|
+
}): Promise<void>;
|
|
89
98
|
export declare function appPull(client: LoticsClient, args: {
|
|
90
99
|
app_id: string;
|
|
91
100
|
targetPath?: string;
|
package/dist/app_commands.js
CHANGED
|
@@ -238,6 +238,19 @@ export async function appSetSubdomain(client, args) {
|
|
|
238
238
|
const result = await client.setAppSubdomain(meta.app_id, args.subdomain);
|
|
239
239
|
console.error(`Public address set: https://${result.public_subdomain}.lotics.app`);
|
|
240
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* `lotics app rename <name>` — change the current app's display name (the
|
|
243
|
+
* launcher/title shown in the workspace). The app_id comes from the local
|
|
244
|
+
* `package.json` manifest. Wraps the `update_app` tool — the public address
|
|
245
|
+
* (`lotics app subdomain`) and the code (`lotics app deploy`) are unchanged.
|
|
246
|
+
*/
|
|
247
|
+
export async function appRename(client, args) {
|
|
248
|
+
const meta = readAppMeta(process.cwd());
|
|
249
|
+
const res = await client.execute("update_app", { app_id: meta.app_id, name: args.name });
|
|
250
|
+
if (res.error)
|
|
251
|
+
throw new Error(res.error);
|
|
252
|
+
console.error(`App renamed: "${args.name}" (${meta.app_id})`);
|
|
253
|
+
}
|
|
241
254
|
export async function appPull(client, args) {
|
|
242
255
|
const app = await client.getApp(args.app_id);
|
|
243
256
|
if (!app.current_version_id) {
|
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import readline from "node:readline";
|
|
|
5
5
|
import { LoticsClient, API_BASE_URL } from "./client.js";
|
|
6
6
|
import { resolveAuth, loadConfig, saveConfig, deleteConfig, getConfigPath, checkForUpdate } from "./config.js";
|
|
7
7
|
import { VERSION } from "./version.js";
|
|
8
|
-
import { appCreate, appPull, appDeploy, appDev, appSetSubdomain } from "./app_commands.js";
|
|
8
|
+
import { appCreate, appPull, appDeploy, appDev, appSetSubdomain, appRename } from "./app_commands.js";
|
|
9
9
|
import { parseArgs } from "./args.js";
|
|
10
10
|
import { runXlsxCommand } from "./xlsx.js";
|
|
11
11
|
import { runDocxCommand } from "./docx.js";
|
|
@@ -54,6 +54,7 @@ COMMANDS
|
|
|
54
54
|
(--force-workflow-sync wipes server-only
|
|
55
55
|
workflow aliases; default refuses)
|
|
56
56
|
lotics app subdomain <new-subdomain> Rename the app's public <slug>.lotics.app address
|
|
57
|
+
lotics app rename "<new name>" Rename the app's display name (launcher title)
|
|
57
58
|
lotics app dev [path] Run the app locally with HMR (RPC forwarded to prod)
|
|
58
59
|
lotics xlsx <subcommand> ... Read/write/edit .xlsx files on your local filesystem
|
|
59
60
|
(uses the bundled Lotics xlsx engine; prefer over
|
|
@@ -378,6 +379,7 @@ async function main() {
|
|
|
378
379
|
console.error(" lotics app deploy [-m <message>] [--force-workflow-sync]");
|
|
379
380
|
console.error(" Build + upload the current directory");
|
|
380
381
|
console.error(" lotics app subdomain <new-subdomain> Rename the app's public <slug>.lotics.app address");
|
|
382
|
+
console.error(" lotics app rename \"<new name>\" Rename the app's display name (launcher title)");
|
|
381
383
|
console.error(" lotics app dev [path] Run the app locally with HMR + RPC forwarding");
|
|
382
384
|
process.exit(1);
|
|
383
385
|
}
|
|
@@ -510,6 +512,16 @@ async function main() {
|
|
|
510
512
|
await appSetSubdomain(client, { subdomain: newSubdomain });
|
|
511
513
|
return;
|
|
512
514
|
}
|
|
515
|
+
if (subcommand === "rename") {
|
|
516
|
+
const newName = toolArgs;
|
|
517
|
+
if (!newName) {
|
|
518
|
+
console.error('Usage: lotics app rename "<new name>"');
|
|
519
|
+
console.error("Changes the app's display name (run inside the app directory).");
|
|
520
|
+
process.exit(1);
|
|
521
|
+
}
|
|
522
|
+
await appRename(client, { name: newName });
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
513
525
|
if (subcommand === "dev") {
|
|
514
526
|
// First positional is an optional project path (defaults to cwd).
|
|
515
527
|
// --port and --vite-port can override the wrapper / Vite ports.
|
package/dist/client.js
CHANGED
|
@@ -262,10 +262,15 @@ export class LoticsClient {
|
|
|
262
262
|
return absolutePath;
|
|
263
263
|
}
|
|
264
264
|
async downloadFileById(fileId, outputDir, options) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
265
|
+
// Resolve a presigned URL (the file proxy is auth-gated and served by an
|
|
266
|
+
// edge Worker that doesn't accept the API key). The signed_url endpoint
|
|
267
|
+
// takes the API key and returns a short-lived, directly-fetchable URL
|
|
268
|
+
// whose Content-Disposition carries the original filename.
|
|
269
|
+
const signedUrlRes = await fetch(`${this.baseUrl}/v1/files/${encodeURIComponent(fileId)}/signed_url`, { headers: this.buildHeaders() });
|
|
270
|
+
if (!signedUrlRes.ok)
|
|
271
|
+
await this.throwResponseError(signedUrlRes);
|
|
272
|
+
const { url } = (await signedUrlRes.json());
|
|
273
|
+
const response = await fetch(url);
|
|
269
274
|
if (!response.ok)
|
|
270
275
|
await this.throwResponseError(response);
|
|
271
276
|
const disposition = response.headers.get("content-disposition") ?? "";
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The wrapper page is served at http://localhost:<port>/ and embeds the
|
|
5
5
|
* project's Vite dev server in an iframe with the same
|
|
6
|
-
* sandbox="allow-scripts allow-same-origin" attribute
|
|
7
|
-
* safe because the Vite iframe is cross-origin to this
|
|
8
|
-
* port), so the app gets its own real origin (and Web
|
|
9
|
-
* being able to reach the wrapper.
|
|
6
|
+
* sandbox="allow-scripts allow-same-origin allow-downloads" attribute
|
|
7
|
+
* production uses — safe because the Vite iframe is cross-origin to this
|
|
8
|
+
* wrapper (different port), so the app gets its own real origin (and Web
|
|
9
|
+
* Storage) without being able to reach the wrapper. `allow-downloads` lets
|
|
10
|
+
* apps trigger file downloads (generated xlsx / pdf etc.) — Chrome blocks
|
|
11
|
+
* every download path from sandboxed iframes without it. The iframe sends postMessage RPCs to
|
|
10
12
|
* this wrapper, which forwards them to the local /_rpc endpoint, which
|
|
11
13
|
* dispatches to api.lotics.ai with the CLI's API key.
|
|
12
14
|
*
|
package/dist/dev/wrapper_page.js
CHANGED
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The wrapper page is served at http://localhost:<port>/ and embeds the
|
|
5
5
|
* project's Vite dev server in an iframe with the same
|
|
6
|
-
* sandbox="allow-scripts allow-same-origin" attribute
|
|
7
|
-
* safe because the Vite iframe is cross-origin to this
|
|
8
|
-
* port), so the app gets its own real origin (and Web
|
|
9
|
-
* being able to reach the wrapper.
|
|
6
|
+
* sandbox="allow-scripts allow-same-origin allow-downloads" attribute
|
|
7
|
+
* production uses — safe because the Vite iframe is cross-origin to this
|
|
8
|
+
* wrapper (different port), so the app gets its own real origin (and Web
|
|
9
|
+
* Storage) without being able to reach the wrapper. `allow-downloads` lets
|
|
10
|
+
* apps trigger file downloads (generated xlsx / pdf etc.) — Chrome blocks
|
|
11
|
+
* every download path from sandboxed iframes without it. The iframe sends postMessage RPCs to
|
|
10
12
|
* this wrapper, which forwards them to the local /_rpc endpoint, which
|
|
11
13
|
* dispatches to api.lotics.ai with the CLI's API key.
|
|
12
14
|
*
|
|
@@ -58,7 +60,7 @@ export function buildWrapperPage(args) {
|
|
|
58
60
|
<span>workspace <code>${escapeHtml(workspace_id)}</code></span>
|
|
59
61
|
<span>RPC → <code>${escapeHtml(api_url)}</code></span>
|
|
60
62
|
</header>
|
|
61
|
-
<iframe id="app" sandbox="allow-scripts allow-same-origin" allow="clipboard-write"></iframe>
|
|
63
|
+
<iframe id="app" sandbox="allow-scripts allow-same-origin allow-downloads" allow="clipboard-write"></iframe>
|
|
62
64
|
<script>
|
|
63
65
|
(function () {
|
|
64
66
|
const APP_ID = ${JSON.stringify(app_id)};
|
package/dist/src/cli.js
CHANGED
|
@@ -31504,10 +31504,13 @@ var LoticsClient = class {
|
|
|
31504
31504
|
return absolutePath;
|
|
31505
31505
|
}
|
|
31506
31506
|
async downloadFileById(fileId, outputDir, options) {
|
|
31507
|
-
const
|
|
31508
|
-
|
|
31509
|
-
headers: this.buildHeaders()
|
|
31510
|
-
|
|
31507
|
+
const signedUrlRes = await fetch(
|
|
31508
|
+
`${this.baseUrl}/v1/files/${encodeURIComponent(fileId)}/signed_url`,
|
|
31509
|
+
{ headers: this.buildHeaders() }
|
|
31510
|
+
);
|
|
31511
|
+
if (!signedUrlRes.ok) await this.throwResponseError(signedUrlRes);
|
|
31512
|
+
const { url } = await signedUrlRes.json();
|
|
31513
|
+
const response = await fetch(url);
|
|
31511
31514
|
if (!response.ok) await this.throwResponseError(response);
|
|
31512
31515
|
const disposition = response.headers.get("content-disposition") ?? "";
|
|
31513
31516
|
const match = disposition.match(/filename="?([^";\n]+)"?/);
|
|
@@ -31678,7 +31681,7 @@ import { tmpdir } from "node:os";
|
|
|
31678
31681
|
|
|
31679
31682
|
// src/starter_template.ts
|
|
31680
31683
|
var STARTER_FALLBACK_UI_VERSION = "1.8.0";
|
|
31681
|
-
var STARTER_FALLBACK_SDK_VERSION = "0.
|
|
31684
|
+
var STARTER_FALLBACK_SDK_VERSION = "0.11.0";
|
|
31682
31685
|
function buildStarterTemplate(args) {
|
|
31683
31686
|
const uiVersion = args.ui_version ?? `^${STARTER_FALLBACK_UI_VERSION}`;
|
|
31684
31687
|
const sdkVersion = args.sdk_version ?? `^${STARTER_FALLBACK_SDK_VERSION}`;
|
|
@@ -32217,7 +32220,7 @@ function buildWrapperPage(args) {
|
|
|
32217
32220
|
<span>workspace <code>${escapeHtml2(workspace_id)}</code></span>
|
|
32218
32221
|
<span>RPC \u2192 <code>${escapeHtml2(api_url)}</code></span>
|
|
32219
32222
|
</header>
|
|
32220
|
-
<iframe id="app" sandbox="allow-scripts allow-same-origin" allow="clipboard-write"></iframe>
|
|
32223
|
+
<iframe id="app" sandbox="allow-scripts allow-same-origin allow-downloads" allow="clipboard-write"></iframe>
|
|
32221
32224
|
<script>
|
|
32222
32225
|
(function () {
|
|
32223
32226
|
const APP_ID = ${JSON.stringify(app_id)};
|
|
@@ -32773,6 +32776,12 @@ async function appSetSubdomain(client, args) {
|
|
|
32773
32776
|
const result = await client.setAppSubdomain(meta.app_id, args.subdomain);
|
|
32774
32777
|
console.error(`Public address set: https://${result.public_subdomain}.lotics.app`);
|
|
32775
32778
|
}
|
|
32779
|
+
async function appRename(client, args) {
|
|
32780
|
+
const meta = readAppMeta(process.cwd());
|
|
32781
|
+
const res = await client.execute("update_app", { app_id: meta.app_id, name: args.name });
|
|
32782
|
+
if (res.error) throw new Error(res.error);
|
|
32783
|
+
console.error(`App renamed: "${args.name}" (${meta.app_id})`);
|
|
32784
|
+
}
|
|
32776
32785
|
async function appPull(client, args) {
|
|
32777
32786
|
const app = await client.getApp(args.app_id);
|
|
32778
32787
|
if (!app.current_version_id) {
|
|
@@ -46334,6 +46343,7 @@ COMMANDS
|
|
|
46334
46343
|
(--force-workflow-sync wipes server-only
|
|
46335
46344
|
workflow aliases; default refuses)
|
|
46336
46345
|
lotics app subdomain <new-subdomain> Rename the app's public <slug>.lotics.app address
|
|
46346
|
+
lotics app rename "<new name>" Rename the app's display name (launcher title)
|
|
46337
46347
|
lotics app dev [path] Run the app locally with HMR (RPC forwarded to prod)
|
|
46338
46348
|
lotics xlsx <subcommand> ... Read/write/edit .xlsx files on your local filesystem
|
|
46339
46349
|
(uses the bundled Lotics xlsx engine; prefer over
|
|
@@ -46642,6 +46652,7 @@ async function main() {
|
|
|
46642
46652
|
console.error(" lotics app deploy [-m <message>] [--force-workflow-sync]");
|
|
46643
46653
|
console.error(" Build + upload the current directory");
|
|
46644
46654
|
console.error(" lotics app subdomain <new-subdomain> Rename the app's public <slug>.lotics.app address");
|
|
46655
|
+
console.error(` lotics app rename "<new name>" Rename the app's display name (launcher title)`);
|
|
46645
46656
|
console.error(" lotics app dev [path] Run the app locally with HMR + RPC forwarding");
|
|
46646
46657
|
process.exit(1);
|
|
46647
46658
|
}
|
|
@@ -46766,6 +46777,16 @@ Available workspaces:`);
|
|
|
46766
46777
|
await appSetSubdomain(client, { subdomain: newSubdomain });
|
|
46767
46778
|
return;
|
|
46768
46779
|
}
|
|
46780
|
+
if (subcommand === "rename") {
|
|
46781
|
+
const newName = toolArgs;
|
|
46782
|
+
if (!newName) {
|
|
46783
|
+
console.error('Usage: lotics app rename "<new name>"');
|
|
46784
|
+
console.error("Changes the app's display name (run inside the app directory).");
|
|
46785
|
+
process.exit(1);
|
|
46786
|
+
}
|
|
46787
|
+
await appRename(client, { name: newName });
|
|
46788
|
+
return;
|
|
46789
|
+
}
|
|
46769
46790
|
if (subcommand === "dev") {
|
|
46770
46791
|
const projectDir = toolArgs;
|
|
46771
46792
|
let port;
|
|
@@ -40,7 +40,7 @@ export interface StarterFile {
|
|
|
40
40
|
* fall back here when the lookup fails.
|
|
41
41
|
*/
|
|
42
42
|
export declare const STARTER_FALLBACK_UI_VERSION = "1.8.0";
|
|
43
|
-
export declare const STARTER_FALLBACK_SDK_VERSION = "0.
|
|
43
|
+
export declare const STARTER_FALLBACK_SDK_VERSION = "0.11.0";
|
|
44
44
|
export declare function buildStarterTemplate(args: {
|
|
45
45
|
app_name: string;
|
|
46
46
|
app_id: string;
|
package/dist/starter_template.js
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
* fall back here when the lookup fails.
|
|
37
37
|
*/
|
|
38
38
|
export const STARTER_FALLBACK_UI_VERSION = "1.8.0";
|
|
39
|
-
export const STARTER_FALLBACK_SDK_VERSION = "0.
|
|
39
|
+
export const STARTER_FALLBACK_SDK_VERSION = "0.11.0";
|
|
40
40
|
export function buildStarterTemplate(args) {
|
|
41
41
|
const uiVersion = args.ui_version ?? `^${STARTER_FALLBACK_UI_VERSION}`;
|
|
42
42
|
const sdkVersion = args.sdk_version ?? `^${STARTER_FALLBACK_SDK_VERSION}`;
|