@plico-ai/cli 0.0.0-reserved.0 → 0.1.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/NOTICE +4 -0
- package/README.md +33 -3
- package/dist/args.d.ts +25 -0
- package/dist/args.js +58 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +50 -0
- package/dist/commands/cancel.d.ts +1 -0
- package/dist/commands/cancel.js +42 -0
- package/dist/commands/eval-promote.d.ts +2 -0
- package/dist/commands/eval-promote.js +26 -0
- package/dist/commands/eval.d.ts +1 -0
- package/dist/commands/eval.js +46 -0
- package/dist/commands/events.d.ts +1 -0
- package/dist/commands/events.js +46 -0
- package/dist/commands/interrupt.d.ts +9 -0
- package/dist/commands/interrupt.js +38 -0
- package/dist/commands/live-output.d.ts +3 -0
- package/dist/commands/live-output.js +18 -0
- package/dist/commands/model-provider.d.ts +4 -0
- package/dist/commands/model-provider.js +21 -0
- package/dist/commands/readiness.d.ts +1 -0
- package/dist/commands/readiness.js +31 -0
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.js +152 -0
- package/dist/commands/runs.d.ts +1 -0
- package/dist/commands/runs.js +52 -0
- package/dist/commands/serve.d.ts +1 -0
- package/dist/commands/serve.js +61 -0
- package/dist/commands/usage.d.ts +1 -0
- package/dist/commands/usage.js +18 -0
- package/dist/commands/validate.d.ts +1 -0
- package/dist/commands/validate.js +38 -0
- package/dist/direct-run.d.ts +5 -0
- package/dist/direct-run.js +16 -0
- package/dist/errors.d.ts +1 -0
- package/dist/errors.js +6 -0
- package/dist/format/eval.d.ts +2 -0
- package/dist/format/eval.js +18 -0
- package/dist/format/events.d.ts +2 -0
- package/dist/format/events.js +7 -0
- package/dist/format/readiness.d.ts +2 -0
- package/dist/format/readiness.js +18 -0
- package/dist/format/run.d.ts +2 -0
- package/dist/format/run.js +69 -0
- package/dist/format/runs.d.ts +2 -0
- package/dist/format/runs.js +17 -0
- package/dist/format/values.d.ts +2 -0
- package/dist/format/values.js +6 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/paths.d.ts +5 -0
- package/dist/paths.js +35 -0
- package/dist/quiet-sqlite-warning.d.ts +6 -0
- package/dist/quiet-sqlite-warning.js +15 -0
- package/dist/script-file.d.ts +2 -0
- package/dist/script-file.js +13 -0
- package/dist/studio/THIRD_PARTY_NOTICES.txt +2319 -0
- package/dist/studio/assets/index-CAj4ULhw.js +40 -0
- package/dist/studio/assets/index-COrtYruy.css +1 -0
- package/dist/studio/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/studio/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/studio/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/studio/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/studio/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/studio/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/studio/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/studio/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/dist/studio/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/dist/studio/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/dist/studio/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/dist/studio/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/dist/studio/index.html +18 -0
- package/package.json +44 -8
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { createSqliteEventStore } from "@plico-ai/runtime";
|
|
3
|
+
import { lastPositional, parseArgs, readStringOption } from "../args.js";
|
|
4
|
+
import { errorMessage } from "../errors.js";
|
|
5
|
+
import { formatRunSummaries } from "../format/runs.js";
|
|
6
|
+
import { resolveDatabasePath } from "../paths.js";
|
|
7
|
+
export async function runsCommand(args) {
|
|
8
|
+
try {
|
|
9
|
+
const parsed = parseArgs(args, {
|
|
10
|
+
flags: ["--json"],
|
|
11
|
+
values: { "--db": { missing: "Missing database path after --db" } },
|
|
12
|
+
rejectUnknown: true,
|
|
13
|
+
});
|
|
14
|
+
const json = parsed.flags.has("--json");
|
|
15
|
+
const target = lastPositional(parsed, process.cwd());
|
|
16
|
+
const dbPath = readStringOption(parsed, "--db");
|
|
17
|
+
const databasePath = resolveDatabasePath(target, dbPath);
|
|
18
|
+
try {
|
|
19
|
+
await access(databasePath);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) {
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
if (dbPath !== undefined)
|
|
26
|
+
throw new Error(`Missing database: ${databasePath}`);
|
|
27
|
+
if (parsed.flags.has("--json"))
|
|
28
|
+
console.log("[]");
|
|
29
|
+
else
|
|
30
|
+
console.log("No saved runs found.");
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
const eventStore = createSqliteEventStore({ databasePath });
|
|
34
|
+
const runs = await eventStore.listRuns();
|
|
35
|
+
if (json) {
|
|
36
|
+
console.log(JSON.stringify(runs));
|
|
37
|
+
}
|
|
38
|
+
else if (runs.length === 0) {
|
|
39
|
+
console.log("No saved runs found.");
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
for (const line of formatRunSummaries(target, databasePath, runs)) {
|
|
43
|
+
console.log(line);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error(errorMessage(error));
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function serveCommand(args: string[]): Promise<number>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { isIPv4 } from "node:net";
|
|
2
|
+
import { loadProjectEnv } from "@plico-ai/runtime";
|
|
3
|
+
import { lastPositional, parseArgs, parsePort, readNumberOption, readStringOption, } from "../args.js";
|
|
4
|
+
import { errorMessage } from "../errors.js";
|
|
5
|
+
import { findStudioPath, normalizeDisplayHost, resolveDatabasePath } from "../paths.js";
|
|
6
|
+
export async function serveCommand(args) {
|
|
7
|
+
try {
|
|
8
|
+
const parsed = parseArgs(args, {
|
|
9
|
+
flags: ["--studio", "--allow-remote", "--allow-script", "--inspect"],
|
|
10
|
+
values: {
|
|
11
|
+
"--host": { missing: "Missing host after --host" },
|
|
12
|
+
"--port": { missing: "Missing port after --port", parse: parsePort },
|
|
13
|
+
"--db": { missing: "Missing database path after --db" },
|
|
14
|
+
},
|
|
15
|
+
rejectUnknown: true,
|
|
16
|
+
});
|
|
17
|
+
const target = lastPositional(parsed, process.cwd());
|
|
18
|
+
loadProjectEnv(target);
|
|
19
|
+
const host = readStringOption(parsed, "--host");
|
|
20
|
+
const port = readNumberOption(parsed, "--port");
|
|
21
|
+
if (host !== undefined && !isLoopbackHost(host) && !parsed.flags.has("--allow-remote")) {
|
|
22
|
+
throw new Error(`Refusing to listen on ${host}: Plico has no authentication. Pass --allow-remote to expose it.`);
|
|
23
|
+
}
|
|
24
|
+
const databasePath = resolveDatabasePath(target, readStringOption(parsed, "--db"));
|
|
25
|
+
const studioPath = parsed.flags.has("--studio") ? resolveStudioPath() : undefined;
|
|
26
|
+
const { servePlico } = await import("@plico-ai/server");
|
|
27
|
+
const server = await servePlico({
|
|
28
|
+
projectRoot: target,
|
|
29
|
+
databasePath,
|
|
30
|
+
...(host === undefined ? {} : { host }),
|
|
31
|
+
...(port === undefined ? {} : { port }),
|
|
32
|
+
...(studioPath === undefined ? {} : { studioPath }),
|
|
33
|
+
...(parsed.flags.has("--allow-remote") ? { allowRemote: true } : {}),
|
|
34
|
+
...(parsed.flags.has("--allow-script") ? { allowScript: true } : {}),
|
|
35
|
+
...(parsed.flags.has("--inspect") ? { inspect: true } : {}),
|
|
36
|
+
});
|
|
37
|
+
const address = server.address();
|
|
38
|
+
if (!address || typeof address === "string") {
|
|
39
|
+
throw new Error("Unable to determine the listening address.");
|
|
40
|
+
}
|
|
41
|
+
const resolvedHost = normalizeDisplayHost(host ?? "127.0.0.1");
|
|
42
|
+
const urlHost = resolvedHost.includes(":") ? `[${resolvedHost}]` : resolvedHost;
|
|
43
|
+
console.log(`Serving Plico at http://${urlHost}:${address.port}`);
|
|
44
|
+
console.log(`Database: ${databasePath}`);
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error(errorMessage(error));
|
|
49
|
+
return 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function resolveStudioPath() {
|
|
53
|
+
const studioPath = findStudioPath();
|
|
54
|
+
if (studioPath === undefined) {
|
|
55
|
+
throw new Error("Cannot find the Studio assets. From a source checkout, build them with: pnpm --filter @plico-ai/studio build");
|
|
56
|
+
}
|
|
57
|
+
return studioPath;
|
|
58
|
+
}
|
|
59
|
+
function isLoopbackHost(host) {
|
|
60
|
+
return host === "localhost" || host === "::1" || (isIPv4(host) && host.startsWith("127."));
|
|
61
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function usageCommand(stream?: "stdout" | "stderr"): number;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const USAGE_LINES = [
|
|
2
|
+
"Usage: plico validate [path]",
|
|
3
|
+
"Usage: plico run [--db <path>] [--json] [--message <text>] [path]",
|
|
4
|
+
"Usage: plico run --dry [--persist] [--db <path>] [--json] [--script <file>] [--message <text>] [path]",
|
|
5
|
+
"Usage: plico cancel <runId> [--db <path>] [--json] [path]",
|
|
6
|
+
"Usage: plico runs [--db <path>] [--json] [path]",
|
|
7
|
+
"Usage: plico events <runId> [--after <sequence>] [--db <path>] [--json] [path]",
|
|
8
|
+
"Usage: plico eval [--json] [--allow-empty] [--from-run <run-id> [--name <name>]] [--db <path>] [path]",
|
|
9
|
+
"Usage: plico readiness [--json] [--db <path>] [path]",
|
|
10
|
+
"Usage: plico serve [--host <host>] [--port <port>] [--db <path>] [--studio] [--allow-remote] [--allow-script] [--inspect] [path]",
|
|
11
|
+
];
|
|
12
|
+
export function usageCommand(stream = "stdout") {
|
|
13
|
+
const write = stream === "stdout" ? console.log : console.error;
|
|
14
|
+
for (const line of USAGE_LINES) {
|
|
15
|
+
write(line);
|
|
16
|
+
}
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function validateCommand(args: string[]): Promise<number>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { validateProject } from "@plico-ai/core";
|
|
2
|
+
import { lastPositional, parseArgs } from "../args.js";
|
|
3
|
+
import { errorMessage } from "../errors.js";
|
|
4
|
+
export async function validateCommand(args) {
|
|
5
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
6
|
+
console.log("Usage: plico validate [path]");
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
let parsed;
|
|
10
|
+
try {
|
|
11
|
+
parsed = parseArgs(args, { flags: ["--json"], values: {}, rejectUnknown: true });
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
console.error(errorMessage(error));
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
const json = parsed.flags.has("--json");
|
|
18
|
+
const target = lastPositional(parsed, process.cwd());
|
|
19
|
+
const result = await validateProject(target);
|
|
20
|
+
if (json) {
|
|
21
|
+
console.log(JSON.stringify(result));
|
|
22
|
+
return result.ok ? 0 : 1;
|
|
23
|
+
}
|
|
24
|
+
if (result.ok) {
|
|
25
|
+
for (const warning of result.warnings) {
|
|
26
|
+
console.warn(`${warning.path}: ${warning.message}`);
|
|
27
|
+
}
|
|
28
|
+
console.log(`Valid Plico project: ${target}`);
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
for (const error of result.errors) {
|
|
32
|
+
console.error(`${error.path}: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
for (const warning of result.warnings) {
|
|
35
|
+
console.warn(`${warning.path}: ${warning.message}`);
|
|
36
|
+
}
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when this module is the script node was started with. npm and pnpm reach a bin through a
|
|
3
|
+
* symlink, so compare resolved paths rather than the raw `argv[1]` and module URL.
|
|
4
|
+
*/
|
|
5
|
+
export declare function isDirectRun(moduleUrl: string, entry: string | undefined): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
/**
|
|
4
|
+
* True when this module is the script node was started with. npm and pnpm reach a bin through a
|
|
5
|
+
* symlink, so compare resolved paths rather than the raw `argv[1]` and module URL.
|
|
6
|
+
*/
|
|
7
|
+
export function isDirectRun(moduleUrl, entry) {
|
|
8
|
+
if (!entry)
|
|
9
|
+
return false;
|
|
10
|
+
try {
|
|
11
|
+
return realpathSync.native(entry) === realpathSync.native(fileURLToPath(moduleUrl));
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function errorMessage(error: unknown): string;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function formatEvalSummary(target, summary) {
|
|
2
|
+
const lines = [`Eval results for ${target}`];
|
|
3
|
+
if (summary.total === 0) {
|
|
4
|
+
lines.push("No eval cases found.");
|
|
5
|
+
return lines;
|
|
6
|
+
}
|
|
7
|
+
for (const result of summary.results) {
|
|
8
|
+
const statusSymbol = result.status === "pass" ? "PASS" : "FAIL";
|
|
9
|
+
lines.push(` ${statusSymbol} ${result.name} (${result.runId})`);
|
|
10
|
+
if (result.diagnostics?.length) {
|
|
11
|
+
for (const diag of result.diagnostics) {
|
|
12
|
+
lines.push(` ${diag}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
lines.push(`\n${summary.passed}/${summary.total} passed, ${summary.failed} failed`);
|
|
17
|
+
return lines;
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function formatReadinessReport(report) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
const subsystems = new Set(report.diagnostics.map((d) => d.subsystem));
|
|
4
|
+
for (const sub of subsystems) {
|
|
5
|
+
const items = report.diagnostics.filter((d) => d.subsystem === sub);
|
|
6
|
+
const hasError = items.some((d) => d.severity === "error");
|
|
7
|
+
const hasWarning = items.some((d) => d.severity === "warning");
|
|
8
|
+
const symbol = hasError ? "✗" : hasWarning ? "!" : "✓";
|
|
9
|
+
lines.push(`${symbol} ${sub}`);
|
|
10
|
+
for (const item of items) {
|
|
11
|
+
const prefix = item.severity === "error" ? " ERROR" : item.severity === "warning" ? " WARN " : " OK ";
|
|
12
|
+
const pathInfo = item.path ? ` [${item.path}]` : "";
|
|
13
|
+
lines.push(`${prefix}${pathInfo} ${item.message}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
lines.push(`\n${report.summary.ok} ok, ${report.summary.warning} warning(s), ${report.summary.error} error(s)`);
|
|
17
|
+
return lines;
|
|
18
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { readCount, readString } from "./values.js";
|
|
2
|
+
export function formatRunResult(target, result, dry = true) {
|
|
3
|
+
const lines = [`Running ${dry ? "dry runtime" : "model"} for ${target}`];
|
|
4
|
+
for (const event of result.events) {
|
|
5
|
+
if (event.type === "run.started") {
|
|
6
|
+
lines.push(`run.started: ${readString(event.payload.projectName) ?? "unknown project"}`);
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
if (event.type === "instructions.composed") {
|
|
10
|
+
lines.push(`instructions.composed: ${readCount(event.payload.sources)} source(s)`);
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (event.type === "tools.discovered") {
|
|
14
|
+
lines.push(`tools.discovered: ${readCount(event.payload.tools)} tool(s)`);
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (event.type === "model.request") {
|
|
18
|
+
lines.push(`model.request: ${readCount(event.payload.messages)} message(s)`);
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (event.type === "model.response") {
|
|
22
|
+
const content = readString(event.payload.content);
|
|
23
|
+
lines.push(`model.response: ${content?.slice(0, 80) ?? "no content"}`);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (event.type === "assistant.output") {
|
|
27
|
+
lines.push(`assistant.output: ${readString(event.payload.content) ?? ""}`);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (event.type === "tool.call") {
|
|
31
|
+
lines.push(`tool.call: ${readString(event.payload.toolName) ?? "unknown tool"}`);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (event.type === "tool.result") {
|
|
35
|
+
lines.push(`tool.result: ${readString(event.payload.toolName) ?? "unknown tool"}`);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (event.type === "approval.requested") {
|
|
39
|
+
lines.push(`approval.requested: ${readString(event.payload.toolName) ?? "unknown tool"}`);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (event.type === "run.waiting") {
|
|
43
|
+
lines.push("run.waiting: approval required");
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (event.type === "run.completed") {
|
|
47
|
+
lines.push("run.completed: completed");
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (event.type === "run.failed") {
|
|
51
|
+
lines.push("run.failed: failed");
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (event.type === "run.cancelled") {
|
|
55
|
+
lines.push("run.cancelled: cancelled");
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (event.type === "run.error") {
|
|
59
|
+
lines.push(`run.error: ${readString(event.payload.message) ?? "runtime error"}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (result.status === "waiting") {
|
|
63
|
+
lines.push(dry ? "Dry run waiting for approval." : "Run waiting for approval.");
|
|
64
|
+
}
|
|
65
|
+
else if (result.status === "failed") {
|
|
66
|
+
lines.push(dry ? "Dry run failed." : "Run failed.");
|
|
67
|
+
}
|
|
68
|
+
return lines;
|
|
69
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function formatRunSummaries(target, databasePath, runs) {
|
|
2
|
+
const lines = [`Persisted runs for ${target} (${databasePath})`];
|
|
3
|
+
if (runs.length === 0) {
|
|
4
|
+
lines.push("No persisted runs found.");
|
|
5
|
+
return lines;
|
|
6
|
+
}
|
|
7
|
+
for (const run of runs) {
|
|
8
|
+
const summary = [
|
|
9
|
+
run.runId,
|
|
10
|
+
run.status,
|
|
11
|
+
run.projectName || "unknown project",
|
|
12
|
+
run.endedAt ?? "not ended",
|
|
13
|
+
].join(" | ");
|
|
14
|
+
lines.push(summary);
|
|
15
|
+
}
|
|
16
|
+
return lines;
|
|
17
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { validateProject } from "@plico-ai/core";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { validateProject } from "@plico-ai/core";
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function resolveDatabasePath(target: string, dbPath: string | undefined): string;
|
|
2
|
+
/** The Studio copied into the published package, else the workspace build when running from source. */
|
|
3
|
+
export declare function findStudioPath(): string | undefined;
|
|
4
|
+
export declare function ensureDatabaseExists(databasePath: string): Promise<void>;
|
|
5
|
+
export declare function normalizeDisplayHost(host: string): string;
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { existsSync, constants as fsConstants } from "node:fs";
|
|
2
|
+
import { access } from "node:fs/promises";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
export function resolveDatabasePath(target, dbPath) {
|
|
7
|
+
return dbPath ?? join(target, ".plico", "plico.sqlite");
|
|
8
|
+
}
|
|
9
|
+
/** The Studio copied into the published package, else the workspace build when running from source. */
|
|
10
|
+
export function findStudioPath() {
|
|
11
|
+
const bundled = join(dirname(fileURLToPath(import.meta.url)), "studio");
|
|
12
|
+
if (existsSync(join(bundled, "index.html")))
|
|
13
|
+
return bundled;
|
|
14
|
+
try {
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
return join(dirname(require.resolve("@plico-ai/studio/package.json")), "dist");
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export async function ensureDatabaseExists(databasePath) {
|
|
23
|
+
try {
|
|
24
|
+
await access(databasePath, fsConstants.F_OK);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
throw new Error(`Missing database: ${databasePath}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function normalizeDisplayHost(host) {
|
|
31
|
+
if (host === "0.0.0.0" || host === "::") {
|
|
32
|
+
return "127.0.0.1";
|
|
33
|
+
}
|
|
34
|
+
return host;
|
|
35
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides Node's one-line "SQLite is an experimental feature" notice from the `plico` command, so
|
|
3
|
+
* the commands that open the run database do not print it. Every other warning still prints.
|
|
4
|
+
* Only the bin calls this: a host app that mounts Plico owns its own process warnings.
|
|
5
|
+
*/
|
|
6
|
+
export declare function quietSqliteWarning(): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides Node's one-line "SQLite is an experimental feature" notice from the `plico` command, so
|
|
3
|
+
* the commands that open the run database do not print it. Every other warning still prints.
|
|
4
|
+
* Only the bin calls this: a host app that mounts Plico owns its own process warnings.
|
|
5
|
+
*/
|
|
6
|
+
export function quietSqliteWarning() {
|
|
7
|
+
const emitWarning = process.emitWarning.bind(process);
|
|
8
|
+
process.emitWarning = ((warning, ...rest) => {
|
|
9
|
+
const message = typeof warning === "string" ? warning : warning.message;
|
|
10
|
+
const type = typeof rest[0] === "string" ? rest[0] : warning.name;
|
|
11
|
+
if (type === "ExperimentalWarning" && /^SQLite is an experimental feature/.test(message))
|
|
12
|
+
return;
|
|
13
|
+
emitWarning(warning, ...rest);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { normalizeScript } from "@plico-ai/runtime";
|
|
3
|
+
import { errorMessage } from "./errors.js";
|
|
4
|
+
export async function loadDryRunScript(scriptPath) {
|
|
5
|
+
try {
|
|
6
|
+
const raw = await readFile(scriptPath, "utf8");
|
|
7
|
+
const parsed = JSON.parse(raw);
|
|
8
|
+
return normalizeScript(parsed);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
throw new Error(`Unable to parse dry run script ${scriptPath}: ${errorMessage(error)}`);
|
|
12
|
+
}
|
|
13
|
+
}
|