@lotics/cli 0.49.0 → 0.51.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 +17 -0
- package/dist/app_commands.js +8 -3
- package/dist/app_commands.test.js +3 -0
- package/dist/client.d.ts +13 -0
- package/dist/generate_app_agents_dts.d.ts +16 -0
- package/dist/generate_app_agents_dts.js +62 -0
- package/dist/generate_app_agents_dts.test.d.ts +1 -0
- package/dist/generate_app_agents_dts.test.js +45 -0
- package/dist/src/cli.js +76 -9
- package/dist/starter_template.js +17 -1
- package/package.json +1 -1
package/dist/app_commands.d.ts
CHANGED
|
@@ -26,6 +26,22 @@ export type AppQueryDeclaration = {
|
|
|
26
26
|
ast: unknown;
|
|
27
27
|
params?: Record<string, unknown>;
|
|
28
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Manifest declaration for one streaming agent:
|
|
31
|
+
* `"alias": { instructions, tool_names, model_id, inputs?, outputs? }`
|
|
32
|
+
*
|
|
33
|
+
* A read-only reflection of the live App row (`apps.agents`, owned by
|
|
34
|
+
* `set_app_agent`), refreshed by `lotics app pull` and used only to codegen
|
|
35
|
+
* `useAgentRun` typings. `inputs`/`outputs` drive the typed call site; the rest
|
|
36
|
+
* is carried for fidelity.
|
|
37
|
+
*/
|
|
38
|
+
export type AppAgentDeclaration = {
|
|
39
|
+
instructions?: string;
|
|
40
|
+
tool_names?: string[];
|
|
41
|
+
model_id?: string;
|
|
42
|
+
inputs?: Record<string, unknown>;
|
|
43
|
+
outputs?: Record<string, unknown>;
|
|
44
|
+
};
|
|
29
45
|
/**
|
|
30
46
|
* Stamp the post-extraction manifest with server-authoritative meta. Called
|
|
31
47
|
* by `appPull` after the source archive lands on disk.
|
|
@@ -45,6 +61,7 @@ export declare function stampPulledManifest(projectDir: string, args: {
|
|
|
45
61
|
version_number: number;
|
|
46
62
|
workflows: Record<string, AppWorkflowDeclaration>;
|
|
47
63
|
queries: Record<string, AppQueryDeclaration>;
|
|
64
|
+
agents: Record<string, AppAgentDeclaration>;
|
|
48
65
|
}): void;
|
|
49
66
|
/**
|
|
50
67
|
* `lotics app create <name> [path]`
|
package/dist/app_commands.js
CHANGED
|
@@ -18,6 +18,7 @@ import { tmpdir } from "node:os";
|
|
|
18
18
|
import { buildStarterTemplate } from "./starter_template.js";
|
|
19
19
|
import { startDevServer, openBrowser } from "./dev/server.js";
|
|
20
20
|
import { generateAppWorkflowsDts } from "./generate_app_workflows_dts.js";
|
|
21
|
+
import { generateAppAgentsDts } from "./generate_app_agents_dts.js";
|
|
21
22
|
import { generateAppQueriesDts } from "./generate_app_queries_dts.js";
|
|
22
23
|
/**
|
|
23
24
|
* Resolve the latest published version of a package from the npm registry.
|
|
@@ -92,6 +93,7 @@ function readAppMeta(projectDir) {
|
|
|
92
93
|
version_number: pkg.lotics.version_number ?? null,
|
|
93
94
|
workflows: pkg.lotics.workflows ?? {},
|
|
94
95
|
queries: pkg.lotics.queries ?? {},
|
|
96
|
+
agents: pkg.lotics.agents ?? {},
|
|
95
97
|
capabilities: pkg.lotics.capabilities,
|
|
96
98
|
};
|
|
97
99
|
}
|
|
@@ -113,6 +115,7 @@ function writeAppDts(projectDir, manifest) {
|
|
|
113
115
|
fs.mkdirSync(dotLotics, { recursive: true });
|
|
114
116
|
fs.writeFileSync(path.join(dotLotics, "app_workflows.d.ts"), generateAppWorkflowsDts(manifest.workflows));
|
|
115
117
|
fs.writeFileSync(path.join(dotLotics, "app_queries.d.ts"), generateAppQueriesDts(manifest.queries));
|
|
118
|
+
fs.writeFileSync(path.join(dotLotics, "app_agents.d.ts"), generateAppAgentsDts(manifest.agents));
|
|
116
119
|
}
|
|
117
120
|
/**
|
|
118
121
|
* Stamp the post-extraction manifest with server-authoritative meta. Called
|
|
@@ -134,8 +137,9 @@ export function stampPulledManifest(projectDir, args) {
|
|
|
134
137
|
version_number: args.version_number,
|
|
135
138
|
workflows: args.workflows,
|
|
136
139
|
queries: args.queries,
|
|
140
|
+
agents: args.agents,
|
|
137
141
|
});
|
|
138
|
-
writeAppDts(projectDir, { workflows: args.workflows, queries: args.queries });
|
|
142
|
+
writeAppDts(projectDir, { workflows: args.workflows, queries: args.queries, agents: args.agents });
|
|
139
143
|
}
|
|
140
144
|
async function downloadToFile(url, destPath) {
|
|
141
145
|
const response = await fetch(url);
|
|
@@ -281,6 +285,7 @@ export async function appPull(client, args) {
|
|
|
281
285
|
version_number: version.version,
|
|
282
286
|
workflows: app.workflows ?? {},
|
|
283
287
|
queries: app.queries ?? {},
|
|
288
|
+
agents: app.agents ?? {},
|
|
284
289
|
});
|
|
285
290
|
console.error(`Installing npm dependencies...`);
|
|
286
291
|
await runNpm(["install"], targetPath);
|
|
@@ -355,7 +360,7 @@ export async function appDeploy(client, args) {
|
|
|
355
360
|
// Regenerate AppWorkflows typing before the build picks up source. Keeps
|
|
356
361
|
// .lotics/app_workflows.d.ts in sync with the manifest's workflows map
|
|
357
362
|
// every time the developer ships.
|
|
358
|
-
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries });
|
|
363
|
+
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries, agents: meta.agents });
|
|
359
364
|
// Build locally so the server doesn't need a build sandbox in v1.
|
|
360
365
|
console.error("Building...");
|
|
361
366
|
await runNpm(["run", "build"], projectDir);
|
|
@@ -469,7 +474,7 @@ export async function appDev(client, args) {
|
|
|
469
474
|
// Regenerate AppWorkflows typing before Vite spins up so the dev typecheck
|
|
470
475
|
// sees the current shape. Doesn't watch for manifest changes mid-session —
|
|
471
476
|
// re-running `lotics app dev` after editing the manifest is the loop.
|
|
472
|
-
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries });
|
|
477
|
+
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries, agents: meta.agents });
|
|
473
478
|
// Sanity: confirm the app exists in the workspace the CLI is auth'd into.
|
|
474
479
|
// Surfaces a clear error if the project's app_id has been deleted or the
|
|
475
480
|
// CLI is pointed at the wrong workspace.
|
|
@@ -57,6 +57,7 @@ describe("stampPulledManifest", () => {
|
|
|
57
57
|
renamed: { workflow_id: "wfl_renamed_on_server" },
|
|
58
58
|
},
|
|
59
59
|
queries: {},
|
|
60
|
+
agents: {},
|
|
60
61
|
});
|
|
61
62
|
const stamped = readStampedManifest();
|
|
62
63
|
expect(stamped.app_id).toBe("app_live");
|
|
@@ -82,6 +83,7 @@ describe("stampPulledManifest", () => {
|
|
|
82
83
|
version_number: 2,
|
|
83
84
|
workflows: {},
|
|
84
85
|
queries: {},
|
|
86
|
+
agents: {},
|
|
85
87
|
});
|
|
86
88
|
const stamped = readStampedManifest();
|
|
87
89
|
expect(stamped.workflows).toEqual({});
|
|
@@ -97,6 +99,7 @@ describe("stampPulledManifest", () => {
|
|
|
97
99
|
only_live: { workflow_id: "wfl_only_live" },
|
|
98
100
|
},
|
|
99
101
|
queries: {},
|
|
102
|
+
agents: {},
|
|
100
103
|
});
|
|
101
104
|
const dtsPath = path.join(workDir, ".lotics", "app_workflows.d.ts");
|
|
102
105
|
expect(fs.existsSync(dtsPath)).toBe(true);
|
package/dist/client.d.ts
CHANGED
|
@@ -130,6 +130,19 @@ export declare class LoticsClient {
|
|
|
130
130
|
ast: unknown;
|
|
131
131
|
params?: Record<string, unknown>;
|
|
132
132
|
}> | null;
|
|
133
|
+
/**
|
|
134
|
+
* Live alias → agent declaration map from `apps.agents`. Source of truth for
|
|
135
|
+
* `lotics app pull` — supersedes the source archive so `set_app_agent`
|
|
136
|
+
* authoring survives the pull. Null/undefined on apps with no declared
|
|
137
|
+
* agents. Drives `useAgentRun` typing.
|
|
138
|
+
*/
|
|
139
|
+
agents?: Record<string, {
|
|
140
|
+
instructions?: string;
|
|
141
|
+
tool_names?: string[];
|
|
142
|
+
model_id?: string;
|
|
143
|
+
inputs?: Record<string, unknown>;
|
|
144
|
+
outputs?: Record<string, unknown>;
|
|
145
|
+
}> | null;
|
|
133
146
|
}>;
|
|
134
147
|
createApp(body: {
|
|
135
148
|
name: string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codegen: emit `.lotics/app_agents.d.ts` from the app's manifest.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `generate_app_workflows_dts` — agents reuse the exact same typed
|
|
5
|
+
* input/output vocabulary, so the `inputsToType` / `objectFieldsToType` mappers
|
|
6
|
+
* are shared. The augmentation adds a typed entry to `AppAgents` for every alias
|
|
7
|
+
* declared in `package.json#lotics.agents`:
|
|
8
|
+
*
|
|
9
|
+
* - No declared `inputs` → `alias: Record<string, unknown>` (untyped payload)
|
|
10
|
+
* - Declared `inputs` → `alias: { …declared shape… }`
|
|
11
|
+
* - Declared `outputs` → an `AppAgentResults[alias]` entry → typed `output`
|
|
12
|
+
*
|
|
13
|
+
* Pure function. Same inputs → same output. Idempotent.
|
|
14
|
+
*/
|
|
15
|
+
import type { AppAgentDeclaration } from "./app_commands.js";
|
|
16
|
+
export declare function generateAppAgentsDts(agents: Record<string, AppAgentDeclaration> | undefined): string;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codegen: emit `.lotics/app_agents.d.ts` from the app's manifest.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `generate_app_workflows_dts` — agents reuse the exact same typed
|
|
5
|
+
* input/output vocabulary, so the `inputsToType` / `objectFieldsToType` mappers
|
|
6
|
+
* are shared. The augmentation adds a typed entry to `AppAgents` for every alias
|
|
7
|
+
* declared in `package.json#lotics.agents`:
|
|
8
|
+
*
|
|
9
|
+
* - No declared `inputs` → `alias: Record<string, unknown>` (untyped payload)
|
|
10
|
+
* - Declared `inputs` → `alias: { …declared shape… }`
|
|
11
|
+
* - Declared `outputs` → an `AppAgentResults[alias]` entry → typed `output`
|
|
12
|
+
*
|
|
13
|
+
* Pure function. Same inputs → same output. Idempotent.
|
|
14
|
+
*/
|
|
15
|
+
import { inputsToType, objectFieldsToType, isValidIdentifier } from "./generate_app_workflows_dts.js";
|
|
16
|
+
const HEADER = `// Auto-generated by 'lotics app pull/dev/deploy'.
|
|
17
|
+
// DO NOT EDIT — regenerated from package.json#lotics.agents.
|
|
18
|
+
//
|
|
19
|
+
// This file gives \`useAgentRun("alias")\` typed input + output at call sites by
|
|
20
|
+
// augmenting the @lotics/app-sdk \`AppAgents\` / \`AppAgentResults\` interfaces.
|
|
21
|
+
|
|
22
|
+
import "@lotics/app-sdk";
|
|
23
|
+
`;
|
|
24
|
+
export function generateAppAgentsDts(agents) {
|
|
25
|
+
const entries = Object.entries(agents ?? {});
|
|
26
|
+
if (entries.length === 0) {
|
|
27
|
+
return `${HEADER}
|
|
28
|
+
// No agents declared in package.json#lotics.agents.
|
|
29
|
+
// Add an entry to enable typed useAgentRun<"alias"> at call sites.
|
|
30
|
+
declare module "@lotics/app-sdk" {
|
|
31
|
+
interface AppAgents {}
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
}
|
|
35
|
+
// Sort alphabetically for deterministic output across regenerations.
|
|
36
|
+
entries.sort(([a], [b]) => a.localeCompare(b));
|
|
37
|
+
const inputLines = [];
|
|
38
|
+
const resultLines = [];
|
|
39
|
+
for (const [alias, declaration] of entries) {
|
|
40
|
+
const valueType = declaration.inputs
|
|
41
|
+
? inputsToType(declaration.inputs)
|
|
42
|
+
: "Record<string, unknown>";
|
|
43
|
+
const aliasKey = isValidIdentifier(alias) ? alias : JSON.stringify(alias);
|
|
44
|
+
inputLines.push(` ${aliasKey}: ${valueType};`);
|
|
45
|
+
if (declaration.outputs) {
|
|
46
|
+
resultLines.push(` ${aliasKey}: ${objectFieldsToType(declaration.outputs)};`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const resultsBlock = resultLines.length > 0
|
|
50
|
+
? `
|
|
51
|
+
interface AppAgentResults {
|
|
52
|
+
${resultLines.join("\n")}
|
|
53
|
+
}`
|
|
54
|
+
: "";
|
|
55
|
+
return `${HEADER}
|
|
56
|
+
declare module "@lotics/app-sdk" {
|
|
57
|
+
interface AppAgents {
|
|
58
|
+
${inputLines.join("\n")}
|
|
59
|
+
}${resultsBlock}
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { generateAppAgentsDts } from "./generate_app_agents_dts.js";
|
|
3
|
+
describe("generateAppAgentsDts", () => {
|
|
4
|
+
it("emits an empty AppAgents interface when no agents are declared", () => {
|
|
5
|
+
const out = generateAppAgentsDts(undefined);
|
|
6
|
+
expect(out).toContain("interface AppAgents {}");
|
|
7
|
+
expect(out).not.toContain("interface AppAgentResults");
|
|
8
|
+
});
|
|
9
|
+
it("types the input payload from declared inputs", () => {
|
|
10
|
+
const out = generateAppAgentsDts({
|
|
11
|
+
recognize: { inputs: { photo: { type: "file" }, prompt: { type: "text", required: false } } },
|
|
12
|
+
});
|
|
13
|
+
expect(out).toContain("recognize: {");
|
|
14
|
+
expect(out).toContain("photo: string;");
|
|
15
|
+
expect(out).toContain("prompt?: string;");
|
|
16
|
+
});
|
|
17
|
+
it("leaves an inputs-less agent as an untyped payload", () => {
|
|
18
|
+
const out = generateAppAgentsDts({ summarize: {} });
|
|
19
|
+
expect(out).toContain("summarize: Record<string, unknown>;");
|
|
20
|
+
});
|
|
21
|
+
it("emits AppAgentResults from declared outputs, including nested objects", () => {
|
|
22
|
+
const out = generateAppAgentsDts({
|
|
23
|
+
recognize: {
|
|
24
|
+
inputs: { photo: { type: "file" } },
|
|
25
|
+
outputs: {
|
|
26
|
+
style: { type: "text" },
|
|
27
|
+
dimensions: {
|
|
28
|
+
type: "object",
|
|
29
|
+
fields: { width_mm: { type: "number" }, height_mm: { type: "number" } },
|
|
30
|
+
},
|
|
31
|
+
confidence: { type: "number" },
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
expect(out).toContain("interface AppAgentResults {");
|
|
36
|
+
expect(out).toContain("style: string");
|
|
37
|
+
expect(out).toContain("width_mm: number");
|
|
38
|
+
expect(out).toContain("confidence: number");
|
|
39
|
+
});
|
|
40
|
+
it("is deterministic and sorts aliases", () => {
|
|
41
|
+
const a = generateAppAgentsDts({ zebra: {}, alpha: {} });
|
|
42
|
+
expect(a.indexOf("alpha:")).toBeLessThan(a.indexOf("zebra:"));
|
|
43
|
+
expect(generateAppAgentsDts({ zebra: {}, alpha: {} })).toBe(a);
|
|
44
|
+
});
|
|
45
|
+
});
|
package/dist/src/cli.js
CHANGED
|
@@ -30434,7 +30434,23 @@ export default defineConfig({
|
|
|
30434
30434
|
optimizer: {
|
|
30435
30435
|
web: {
|
|
30436
30436
|
enabled: true,
|
|
30437
|
-
|
|
30437
|
+
// react + react-dom + the @testing-library renderer must ride in the
|
|
30438
|
+
// SAME optimized chunk as react-native-web, so a rendered tree and the
|
|
30439
|
+
// renderer share ONE react instance. Without this, a test that renders a
|
|
30440
|
+
// non-trivial App tree hits a null hooks dispatcher ("Cannot read
|
|
30441
|
+
// properties of null (reading 'useState')") the moment it mounts.
|
|
30442
|
+
include: [
|
|
30443
|
+
"react",
|
|
30444
|
+
"react-dom",
|
|
30445
|
+
"react-dom/client",
|
|
30446
|
+
"react-dom/test-utils",
|
|
30447
|
+
"react-native",
|
|
30448
|
+
"react-native-web",
|
|
30449
|
+
"react-native-svg",
|
|
30450
|
+
"@react-native-picker/picker",
|
|
30451
|
+
"@testing-library/react",
|
|
30452
|
+
"@testing-library/dom",
|
|
30453
|
+
],
|
|
30438
30454
|
esbuildOptions: {
|
|
30439
30455
|
resolveExtensions: [".web.tsx", ".web.ts", ".web.js", ".tsx", ".ts", ".jsx", ".js", ".json"],
|
|
30440
30456
|
},
|
|
@@ -31358,8 +31374,52 @@ function isValidIdentifier(name) {
|
|
|
31358
31374
|
return IDENTIFIER_REGEX.test(name);
|
|
31359
31375
|
}
|
|
31360
31376
|
|
|
31361
|
-
// src/
|
|
31377
|
+
// src/generate_app_agents_dts.ts
|
|
31362
31378
|
var HEADER2 = `// Auto-generated by 'lotics app pull/dev/deploy'.
|
|
31379
|
+
// DO NOT EDIT \u2014 regenerated from package.json#lotics.agents.
|
|
31380
|
+
//
|
|
31381
|
+
// This file gives \`useAgentRun("alias")\` typed input + output at call sites by
|
|
31382
|
+
// augmenting the @lotics/app-sdk \`AppAgents\` / \`AppAgentResults\` interfaces.
|
|
31383
|
+
|
|
31384
|
+
import "@lotics/app-sdk";
|
|
31385
|
+
`;
|
|
31386
|
+
function generateAppAgentsDts(agents) {
|
|
31387
|
+
const entries = Object.entries(agents ?? {});
|
|
31388
|
+
if (entries.length === 0) {
|
|
31389
|
+
return `${HEADER2}
|
|
31390
|
+
// No agents declared in package.json#lotics.agents.
|
|
31391
|
+
// Add an entry to enable typed useAgentRun<"alias"> at call sites.
|
|
31392
|
+
declare module "@lotics/app-sdk" {
|
|
31393
|
+
interface AppAgents {}
|
|
31394
|
+
}
|
|
31395
|
+
`;
|
|
31396
|
+
}
|
|
31397
|
+
entries.sort(([a], [b]) => a.localeCompare(b));
|
|
31398
|
+
const inputLines = [];
|
|
31399
|
+
const resultLines = [];
|
|
31400
|
+
for (const [alias, declaration] of entries) {
|
|
31401
|
+
const valueType = declaration.inputs ? inputsToType(declaration.inputs) : "Record<string, unknown>";
|
|
31402
|
+
const aliasKey = isValidIdentifier(alias) ? alias : JSON.stringify(alias);
|
|
31403
|
+
inputLines.push(` ${aliasKey}: ${valueType};`);
|
|
31404
|
+
if (declaration.outputs) {
|
|
31405
|
+
resultLines.push(` ${aliasKey}: ${objectFieldsToType(declaration.outputs)};`);
|
|
31406
|
+
}
|
|
31407
|
+
}
|
|
31408
|
+
const resultsBlock = resultLines.length > 0 ? `
|
|
31409
|
+
interface AppAgentResults {
|
|
31410
|
+
${resultLines.join("\n")}
|
|
31411
|
+
}` : "";
|
|
31412
|
+
return `${HEADER2}
|
|
31413
|
+
declare module "@lotics/app-sdk" {
|
|
31414
|
+
interface AppAgents {
|
|
31415
|
+
${inputLines.join("\n")}
|
|
31416
|
+
}${resultsBlock}
|
|
31417
|
+
}
|
|
31418
|
+
`;
|
|
31419
|
+
}
|
|
31420
|
+
|
|
31421
|
+
// src/generate_app_queries_dts.ts
|
|
31422
|
+
var HEADER3 = `// Auto-generated by 'lotics app pull/dev/deploy'.
|
|
31363
31423
|
// DO NOT EDIT \u2014 regenerated from package.json#lotics.queries.
|
|
31364
31424
|
//
|
|
31365
31425
|
// This file gives \`useQuery("alias", params)\` typed params at call sites by
|
|
@@ -31370,7 +31430,7 @@ import "@lotics/app-sdk";
|
|
|
31370
31430
|
function generateAppQueriesDts(queries) {
|
|
31371
31431
|
const entries = Object.entries(queries ?? {});
|
|
31372
31432
|
if (entries.length === 0) {
|
|
31373
|
-
return `${
|
|
31433
|
+
return `${HEADER3}
|
|
31374
31434
|
// No queries declared in package.json#lotics.queries.
|
|
31375
31435
|
// Add an entry to enable typed useQuery("alias", params) at call sites.
|
|
31376
31436
|
declare module "@lotics/app-sdk" {
|
|
@@ -31385,7 +31445,7 @@ declare module "@lotics/app-sdk" {
|
|
|
31385
31445
|
const aliasKey = isValidIdentifier(alias) ? alias : JSON.stringify(alias);
|
|
31386
31446
|
lines.push(` ${aliasKey}: ${valueType};`);
|
|
31387
31447
|
}
|
|
31388
|
-
return `${
|
|
31448
|
+
return `${HEADER3}
|
|
31389
31449
|
declare module "@lotics/app-sdk" {
|
|
31390
31450
|
interface AppQueries {
|
|
31391
31451
|
${lines.join("\n")}
|
|
@@ -31453,6 +31513,7 @@ function readAppMeta(projectDir) {
|
|
|
31453
31513
|
version_number: pkg2.lotics.version_number ?? null,
|
|
31454
31514
|
workflows: pkg2.lotics.workflows ?? {},
|
|
31455
31515
|
queries: pkg2.lotics.queries ?? {},
|
|
31516
|
+
agents: pkg2.lotics.agents ?? {},
|
|
31456
31517
|
capabilities: pkg2.lotics.capabilities
|
|
31457
31518
|
};
|
|
31458
31519
|
}
|
|
@@ -31473,6 +31534,10 @@ function writeAppDts(projectDir, manifest) {
|
|
|
31473
31534
|
path4.join(dotLotics, "app_queries.d.ts"),
|
|
31474
31535
|
generateAppQueriesDts(manifest.queries)
|
|
31475
31536
|
);
|
|
31537
|
+
fs3.writeFileSync(
|
|
31538
|
+
path4.join(dotLotics, "app_agents.d.ts"),
|
|
31539
|
+
generateAppAgentsDts(manifest.agents)
|
|
31540
|
+
);
|
|
31476
31541
|
}
|
|
31477
31542
|
function stampPulledManifest(projectDir, args) {
|
|
31478
31543
|
writeAppMeta(projectDir, {
|
|
@@ -31481,9 +31546,10 @@ function stampPulledManifest(projectDir, args) {
|
|
|
31481
31546
|
current_version_id: args.current_version_id,
|
|
31482
31547
|
version_number: args.version_number,
|
|
31483
31548
|
workflows: args.workflows,
|
|
31484
|
-
queries: args.queries
|
|
31549
|
+
queries: args.queries,
|
|
31550
|
+
agents: args.agents
|
|
31485
31551
|
});
|
|
31486
|
-
writeAppDts(projectDir, { workflows: args.workflows, queries: args.queries });
|
|
31552
|
+
writeAppDts(projectDir, { workflows: args.workflows, queries: args.queries, agents: args.agents });
|
|
31487
31553
|
}
|
|
31488
31554
|
async function downloadToFile(url, destPath) {
|
|
31489
31555
|
const response = await fetch(url);
|
|
@@ -31572,7 +31638,8 @@ async function appPull(client, args) {
|
|
|
31572
31638
|
current_version_id: app.current_version_id,
|
|
31573
31639
|
version_number: version.version,
|
|
31574
31640
|
workflows: app.workflows ?? {},
|
|
31575
|
-
queries: app.queries ?? {}
|
|
31641
|
+
queries: app.queries ?? {},
|
|
31642
|
+
agents: app.agents ?? {}
|
|
31576
31643
|
});
|
|
31577
31644
|
console.error(`Installing npm dependencies...`);
|
|
31578
31645
|
await runNpm(["install"], targetPath);
|
|
@@ -31619,7 +31686,7 @@ async function appDeploy(client, args) {
|
|
|
31619
31686
|
Add to package.json#lotics.capabilities: ${block}`
|
|
31620
31687
|
);
|
|
31621
31688
|
}
|
|
31622
|
-
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries });
|
|
31689
|
+
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries, agents: meta.agents });
|
|
31623
31690
|
console.error("Building...");
|
|
31624
31691
|
await runNpm(["run", "build"], projectDir);
|
|
31625
31692
|
const distDir = path4.join(projectDir, "dist");
|
|
@@ -31710,7 +31777,7 @@ async function warnIfUnbranded(client, appId) {
|
|
|
31710
31777
|
async function appDev(client, args) {
|
|
31711
31778
|
const projectDir = path4.resolve(args.projectDir ?? process.cwd());
|
|
31712
31779
|
const meta = readAppMeta(projectDir);
|
|
31713
|
-
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries });
|
|
31780
|
+
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries, agents: meta.agents });
|
|
31714
31781
|
const app = await client.getApp(meta.app_id);
|
|
31715
31782
|
const handle = await startDevServer({
|
|
31716
31783
|
projectDir,
|
package/dist/starter_template.js
CHANGED
|
@@ -253,7 +253,23 @@ export default defineConfig({
|
|
|
253
253
|
optimizer: {
|
|
254
254
|
web: {
|
|
255
255
|
enabled: true,
|
|
256
|
-
|
|
256
|
+
// react + react-dom + the @testing-library renderer must ride in the
|
|
257
|
+
// SAME optimized chunk as react-native-web, so a rendered tree and the
|
|
258
|
+
// renderer share ONE react instance. Without this, a test that renders a
|
|
259
|
+
// non-trivial App tree hits a null hooks dispatcher ("Cannot read
|
|
260
|
+
// properties of null (reading 'useState')") the moment it mounts.
|
|
261
|
+
include: [
|
|
262
|
+
"react",
|
|
263
|
+
"react-dom",
|
|
264
|
+
"react-dom/client",
|
|
265
|
+
"react-dom/test-utils",
|
|
266
|
+
"react-native",
|
|
267
|
+
"react-native-web",
|
|
268
|
+
"react-native-svg",
|
|
269
|
+
"@react-native-picker/picker",
|
|
270
|
+
"@testing-library/react",
|
|
271
|
+
"@testing-library/dom",
|
|
272
|
+
],
|
|
257
273
|
esbuildOptions: {
|
|
258
274
|
resolveExtensions: [".web.tsx", ".web.ts", ".web.js", ".tsx", ".ts", ".jsx", ".js", ".json"],
|
|
259
275
|
},
|