@lotics/cli 0.48.0 → 0.50.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 +4 -1
- 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/cli.js +22 -2
- 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 +75 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -102,7 +102,10 @@ lotics tools query_records # show full description + input schema
|
|
|
102
102
|
lotics run query_tables '{}'
|
|
103
103
|
lotics run query_records '{"table_id":"tbl_...","field_keys":["name"]}'
|
|
104
104
|
|
|
105
|
-
#
|
|
105
|
+
# Large args (a knowledge-doc `content`, a bulk update) exceed the OS arg limit —
|
|
106
|
+
# read them from a file or stdin instead of an inline arg:
|
|
107
|
+
lotics run create_knowledge @args.json
|
|
108
|
+
cat args.json | lotics run create_knowledge
|
|
106
109
|
echo '{"table_id":"tbl_..."}' | lotics run query_records
|
|
107
110
|
|
|
108
111
|
# Upload files (multiple files and directories supported)
|
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/cli.js
CHANGED
|
@@ -54,6 +54,8 @@ COMMANDS
|
|
|
54
54
|
lotics tools List all available tools
|
|
55
55
|
lotics tools <name> Show tool description and input schema
|
|
56
56
|
lotics run <tool> '<json>' Execute a tool
|
|
57
|
+
lotics run <tool> @args.json Read JSON args from a file (large payloads)
|
|
58
|
+
cat args.json | lotics run <tool> Read JSON args from stdin (large payloads)
|
|
57
59
|
lotics upload <file|dir...> Upload files (directories expand to their immediate files)
|
|
58
60
|
lotics download <file_id> Download a file by ID
|
|
59
61
|
lotics download record <record_id> <field_key>
|
|
@@ -533,7 +535,9 @@ async function main() {
|
|
|
533
535
|
process.exit(1);
|
|
534
536
|
}
|
|
535
537
|
if (command === "run" && !subcommand) {
|
|
536
|
-
console.error(
|
|
538
|
+
console.error("Usage: lotics run <tool> '<json_args>'\n" +
|
|
539
|
+
" lotics run <tool> @args.json (read args from a file — for large payloads)\n" +
|
|
540
|
+
" cat args.json | lotics run <tool> (read args from stdin)");
|
|
537
541
|
console.error('Run "lotics tools" to see available tools.');
|
|
538
542
|
process.exit(1);
|
|
539
543
|
}
|
|
@@ -779,7 +783,23 @@ async function main() {
|
|
|
779
783
|
if (command === "run") {
|
|
780
784
|
const toolName = subcommand;
|
|
781
785
|
let rawArgs = toolArgs;
|
|
782
|
-
if (
|
|
786
|
+
if (rawArgs && rawArgs.startsWith("@")) {
|
|
787
|
+
// `@<path>` — read the JSON args from a local file. JSON args always
|
|
788
|
+
// start with `{`, so a leading `@` is unambiguous. This (and piped
|
|
789
|
+
// stdin below) carries payloads too large for an inline arg, which the
|
|
790
|
+
// OS caps (ARG_MAX) — e.g. a knowledge doc's `content` or a bulk update.
|
|
791
|
+
// Reads only a file the caller explicitly named; no new trust boundary.
|
|
792
|
+
const argsPath = rawArgs.slice(1);
|
|
793
|
+
try {
|
|
794
|
+
rawArgs = fs.readFileSync(argsPath, "utf-8");
|
|
795
|
+
}
|
|
796
|
+
catch (err) {
|
|
797
|
+
console.error(`Cannot read args file "${argsPath}": ${err instanceof Error ? err.message : String(err)}`);
|
|
798
|
+
process.exit(1);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
else if (!rawArgs && !process.stdin.isTTY) {
|
|
802
|
+
// Piped/redirected stdin — `… | lotics run <tool>` or `< file.json`.
|
|
783
803
|
rawArgs = await readStdin();
|
|
784
804
|
}
|
|
785
805
|
let args = {};
|
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
|
@@ -31358,8 +31358,52 @@ function isValidIdentifier(name) {
|
|
|
31358
31358
|
return IDENTIFIER_REGEX.test(name);
|
|
31359
31359
|
}
|
|
31360
31360
|
|
|
31361
|
-
// src/
|
|
31361
|
+
// src/generate_app_agents_dts.ts
|
|
31362
31362
|
var HEADER2 = `// Auto-generated by 'lotics app pull/dev/deploy'.
|
|
31363
|
+
// DO NOT EDIT \u2014 regenerated from package.json#lotics.agents.
|
|
31364
|
+
//
|
|
31365
|
+
// This file gives \`useAgentRun("alias")\` typed input + output at call sites by
|
|
31366
|
+
// augmenting the @lotics/app-sdk \`AppAgents\` / \`AppAgentResults\` interfaces.
|
|
31367
|
+
|
|
31368
|
+
import "@lotics/app-sdk";
|
|
31369
|
+
`;
|
|
31370
|
+
function generateAppAgentsDts(agents) {
|
|
31371
|
+
const entries = Object.entries(agents ?? {});
|
|
31372
|
+
if (entries.length === 0) {
|
|
31373
|
+
return `${HEADER2}
|
|
31374
|
+
// No agents declared in package.json#lotics.agents.
|
|
31375
|
+
// Add an entry to enable typed useAgentRun<"alias"> at call sites.
|
|
31376
|
+
declare module "@lotics/app-sdk" {
|
|
31377
|
+
interface AppAgents {}
|
|
31378
|
+
}
|
|
31379
|
+
`;
|
|
31380
|
+
}
|
|
31381
|
+
entries.sort(([a], [b]) => a.localeCompare(b));
|
|
31382
|
+
const inputLines = [];
|
|
31383
|
+
const resultLines = [];
|
|
31384
|
+
for (const [alias, declaration] of entries) {
|
|
31385
|
+
const valueType = declaration.inputs ? inputsToType(declaration.inputs) : "Record<string, unknown>";
|
|
31386
|
+
const aliasKey = isValidIdentifier(alias) ? alias : JSON.stringify(alias);
|
|
31387
|
+
inputLines.push(` ${aliasKey}: ${valueType};`);
|
|
31388
|
+
if (declaration.outputs) {
|
|
31389
|
+
resultLines.push(` ${aliasKey}: ${objectFieldsToType(declaration.outputs)};`);
|
|
31390
|
+
}
|
|
31391
|
+
}
|
|
31392
|
+
const resultsBlock = resultLines.length > 0 ? `
|
|
31393
|
+
interface AppAgentResults {
|
|
31394
|
+
${resultLines.join("\n")}
|
|
31395
|
+
}` : "";
|
|
31396
|
+
return `${HEADER2}
|
|
31397
|
+
declare module "@lotics/app-sdk" {
|
|
31398
|
+
interface AppAgents {
|
|
31399
|
+
${inputLines.join("\n")}
|
|
31400
|
+
}${resultsBlock}
|
|
31401
|
+
}
|
|
31402
|
+
`;
|
|
31403
|
+
}
|
|
31404
|
+
|
|
31405
|
+
// src/generate_app_queries_dts.ts
|
|
31406
|
+
var HEADER3 = `// Auto-generated by 'lotics app pull/dev/deploy'.
|
|
31363
31407
|
// DO NOT EDIT \u2014 regenerated from package.json#lotics.queries.
|
|
31364
31408
|
//
|
|
31365
31409
|
// This file gives \`useQuery("alias", params)\` typed params at call sites by
|
|
@@ -31370,7 +31414,7 @@ import "@lotics/app-sdk";
|
|
|
31370
31414
|
function generateAppQueriesDts(queries) {
|
|
31371
31415
|
const entries = Object.entries(queries ?? {});
|
|
31372
31416
|
if (entries.length === 0) {
|
|
31373
|
-
return `${
|
|
31417
|
+
return `${HEADER3}
|
|
31374
31418
|
// No queries declared in package.json#lotics.queries.
|
|
31375
31419
|
// Add an entry to enable typed useQuery("alias", params) at call sites.
|
|
31376
31420
|
declare module "@lotics/app-sdk" {
|
|
@@ -31385,7 +31429,7 @@ declare module "@lotics/app-sdk" {
|
|
|
31385
31429
|
const aliasKey = isValidIdentifier(alias) ? alias : JSON.stringify(alias);
|
|
31386
31430
|
lines.push(` ${aliasKey}: ${valueType};`);
|
|
31387
31431
|
}
|
|
31388
|
-
return `${
|
|
31432
|
+
return `${HEADER3}
|
|
31389
31433
|
declare module "@lotics/app-sdk" {
|
|
31390
31434
|
interface AppQueries {
|
|
31391
31435
|
${lines.join("\n")}
|
|
@@ -31453,6 +31497,7 @@ function readAppMeta(projectDir) {
|
|
|
31453
31497
|
version_number: pkg2.lotics.version_number ?? null,
|
|
31454
31498
|
workflows: pkg2.lotics.workflows ?? {},
|
|
31455
31499
|
queries: pkg2.lotics.queries ?? {},
|
|
31500
|
+
agents: pkg2.lotics.agents ?? {},
|
|
31456
31501
|
capabilities: pkg2.lotics.capabilities
|
|
31457
31502
|
};
|
|
31458
31503
|
}
|
|
@@ -31473,6 +31518,10 @@ function writeAppDts(projectDir, manifest) {
|
|
|
31473
31518
|
path4.join(dotLotics, "app_queries.d.ts"),
|
|
31474
31519
|
generateAppQueriesDts(manifest.queries)
|
|
31475
31520
|
);
|
|
31521
|
+
fs3.writeFileSync(
|
|
31522
|
+
path4.join(dotLotics, "app_agents.d.ts"),
|
|
31523
|
+
generateAppAgentsDts(manifest.agents)
|
|
31524
|
+
);
|
|
31476
31525
|
}
|
|
31477
31526
|
function stampPulledManifest(projectDir, args) {
|
|
31478
31527
|
writeAppMeta(projectDir, {
|
|
@@ -31481,9 +31530,10 @@ function stampPulledManifest(projectDir, args) {
|
|
|
31481
31530
|
current_version_id: args.current_version_id,
|
|
31482
31531
|
version_number: args.version_number,
|
|
31483
31532
|
workflows: args.workflows,
|
|
31484
|
-
queries: args.queries
|
|
31533
|
+
queries: args.queries,
|
|
31534
|
+
agents: args.agents
|
|
31485
31535
|
});
|
|
31486
|
-
writeAppDts(projectDir, { workflows: args.workflows, queries: args.queries });
|
|
31536
|
+
writeAppDts(projectDir, { workflows: args.workflows, queries: args.queries, agents: args.agents });
|
|
31487
31537
|
}
|
|
31488
31538
|
async function downloadToFile(url, destPath) {
|
|
31489
31539
|
const response = await fetch(url);
|
|
@@ -31572,7 +31622,8 @@ async function appPull(client, args) {
|
|
|
31572
31622
|
current_version_id: app.current_version_id,
|
|
31573
31623
|
version_number: version.version,
|
|
31574
31624
|
workflows: app.workflows ?? {},
|
|
31575
|
-
queries: app.queries ?? {}
|
|
31625
|
+
queries: app.queries ?? {},
|
|
31626
|
+
agents: app.agents ?? {}
|
|
31576
31627
|
});
|
|
31577
31628
|
console.error(`Installing npm dependencies...`);
|
|
31578
31629
|
await runNpm(["install"], targetPath);
|
|
@@ -31619,7 +31670,7 @@ async function appDeploy(client, args) {
|
|
|
31619
31670
|
Add to package.json#lotics.capabilities: ${block}`
|
|
31620
31671
|
);
|
|
31621
31672
|
}
|
|
31622
|
-
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries });
|
|
31673
|
+
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries, agents: meta.agents });
|
|
31623
31674
|
console.error("Building...");
|
|
31624
31675
|
await runNpm(["run", "build"], projectDir);
|
|
31625
31676
|
const distDir = path4.join(projectDir, "dist");
|
|
@@ -31710,7 +31761,7 @@ async function warnIfUnbranded(client, appId) {
|
|
|
31710
31761
|
async function appDev(client, args) {
|
|
31711
31762
|
const projectDir = path4.resolve(args.projectDir ?? process.cwd());
|
|
31712
31763
|
const meta = readAppMeta(projectDir);
|
|
31713
|
-
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries });
|
|
31764
|
+
writeAppDts(projectDir, { workflows: meta.workflows, queries: meta.queries, agents: meta.agents });
|
|
31714
31765
|
const app = await client.getApp(meta.app_id);
|
|
31715
31766
|
const handle = await startDevServer({
|
|
31716
31767
|
projectDir,
|
|
@@ -47594,6 +47645,8 @@ COMMANDS
|
|
|
47594
47645
|
lotics tools List all available tools
|
|
47595
47646
|
lotics tools <name> Show tool description and input schema
|
|
47596
47647
|
lotics run <tool> '<json>' Execute a tool
|
|
47648
|
+
lotics run <tool> @args.json Read JSON args from a file (large payloads)
|
|
47649
|
+
cat args.json | lotics run <tool> Read JSON args from stdin (large payloads)
|
|
47597
47650
|
lotics upload <file|dir...> Upload files (directories expand to their immediate files)
|
|
47598
47651
|
lotics download <file_id> Download a file by ID
|
|
47599
47652
|
lotics download record <record_id> <field_key>
|
|
@@ -48038,7 +48091,9 @@ async function main() {
|
|
|
48038
48091
|
process.exit(1);
|
|
48039
48092
|
}
|
|
48040
48093
|
if (command === "run" && !subcommand) {
|
|
48041
|
-
console.error(
|
|
48094
|
+
console.error(
|
|
48095
|
+
"Usage: lotics run <tool> '<json_args>'\n lotics run <tool> @args.json (read args from a file \u2014 for large payloads)\n cat args.json | lotics run <tool> (read args from stdin)"
|
|
48096
|
+
);
|
|
48042
48097
|
console.error('Run "lotics tools" to see available tools.');
|
|
48043
48098
|
process.exit(1);
|
|
48044
48099
|
}
|
|
@@ -48270,7 +48325,17 @@ ${JSON.stringify(info.input_schema, null, 2)}`);
|
|
|
48270
48325
|
if (command === "run") {
|
|
48271
48326
|
const toolName = subcommand;
|
|
48272
48327
|
let rawArgs = toolArgs;
|
|
48273
|
-
if (
|
|
48328
|
+
if (rawArgs && rawArgs.startsWith("@")) {
|
|
48329
|
+
const argsPath = rawArgs.slice(1);
|
|
48330
|
+
try {
|
|
48331
|
+
rawArgs = fs7.readFileSync(argsPath, "utf-8");
|
|
48332
|
+
} catch (err2) {
|
|
48333
|
+
console.error(
|
|
48334
|
+
`Cannot read args file "${argsPath}": ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
48335
|
+
);
|
|
48336
|
+
process.exit(1);
|
|
48337
|
+
}
|
|
48338
|
+
} else if (!rawArgs && !process.stdin.isTTY) {
|
|
48274
48339
|
rawArgs = await readStdin();
|
|
48275
48340
|
}
|
|
48276
48341
|
let args = {};
|