@nodetool-ai/cli-apps 0.0.0-stage → 0.8.9-beta.1
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 +12 -2
- package/dist/.nodetool-build-stamp +1 -0
- package/dist/app-build/bundle.d.ts +15 -0
- package/dist/app-build/bundle.d.ts.map +1 -0
- package/dist/app-build/bundle.js +44 -0
- package/dist/app-build/bundle.js.map +1 -0
- package/dist/app-build/watch.d.ts +13 -0
- package/dist/app-build/watch.d.ts.map +1 -0
- package/dist/app-build/watch.js +25 -0
- package/dist/app-build/watch.js.map +1 -0
- package/dist/app-debug/app-target.d.ts +14 -0
- package/dist/app-debug/app-target.d.ts.map +1 -0
- package/dist/app-debug/app-target.js +120 -0
- package/dist/app-debug/app-target.js.map +1 -0
- package/dist/app-debug/harness.d.ts +29 -0
- package/dist/app-debug/harness.d.ts.map +1 -0
- package/dist/app-debug/harness.js +115 -0
- package/dist/app-debug/harness.js.map +1 -0
- package/dist/app-debug/index.d.ts +12 -0
- package/dist/app-debug/index.d.ts.map +1 -0
- package/dist/app-debug/index.js +9 -0
- package/dist/app-debug/index.js.map +1 -0
- package/dist/commands/app.d.ts +3 -0
- package/dist/commands/app.d.ts.map +1 -0
- package/dist/commands/app.js +405 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/apps.d.ts +15 -0
- package/dist/commands/apps.d.ts.map +1 -0
- package/dist/commands/apps.js +274 -0
- package/dist/commands/apps.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/nodetool.d.ts +3 -0
- package/dist/nodetool.d.ts.map +1 -0
- package/dist/nodetool.js +4 -0
- package/dist/nodetool.js.map +1 -0
- package/package.json +69 -4
package/README.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Mini app commands
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Mini app authoring, debugging and application operations.
|
|
4
|
+
|
|
5
|
+
Install this independent command feature through the default CLI:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
nodetool packs add cli-apps --yes
|
|
9
|
+
nodetool app --help
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Commands do not install missing features automatically. See the
|
|
13
|
+
[command reference](../../docs/cli.md#install-command-features).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2026-10-31T09:12:05.089Z
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ProcessingMessage } from "@nodetool-ai/protocol";
|
|
2
|
+
import type { BuildReport } from "@nodetool-ai/agents";
|
|
3
|
+
/** Directory name for a target, mirroring `app debug`'s slug rule. */
|
|
4
|
+
export declare function defaultBuildOutDir(ref: string): string;
|
|
5
|
+
/** Where one interaction's runs are filed. */
|
|
6
|
+
export declare const interactionDir: (outDir: string, interaction: string) => string;
|
|
7
|
+
/** Write one run's raw message stream; returns the path recorded in the report. */
|
|
8
|
+
export declare function writeRunMessages(outDir: string, interaction: string, runIndex: number, messages: ProcessingMessage[]): Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Write the finished bundle. `app.bundle.json` is the deliverable, so it is
|
|
11
|
+
* written only for a build that produced one — a failed build's directory has
|
|
12
|
+
* the report and the evidence, and nothing importable.
|
|
13
|
+
*/
|
|
14
|
+
export declare function writeBuildBundle(outDir: string, report: BuildReport, markdown: string): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/app-build/bundle.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,sEAAsE;AACtE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,8CAA8C;AAC9C,eAAO,MAAM,cAAc,WAAY,MAAM,eAAe,MAAM,KAAG,MACO,CAAC;AAE7E,mFAAmF;AACnF,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAoBf"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `app build` debug bundle: everything one build produced, on disk.
|
|
3
|
+
*
|
|
4
|
+
* Same convention as `app debug` — a timestamped directory under
|
|
5
|
+
* `nodetool-debug/` holding the machine-readable report, its human summary, and
|
|
6
|
+
* the raw evidence — plus the two artifacts only a build has: the
|
|
7
|
+
* `ApplicationBundle` it produced and the spec it was measured against. Message
|
|
8
|
+
* streams are filed per interaction, because a build replays several.
|
|
9
|
+
*/
|
|
10
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
11
|
+
import { join, resolve } from "node:path";
|
|
12
|
+
import { trimHyphens } from "@nodetool-ai/cli-common/trimHyphens";
|
|
13
|
+
/** Directory name for a target, mirroring `app debug`'s slug rule. */
|
|
14
|
+
export function defaultBuildOutDir(ref) {
|
|
15
|
+
const slug = trimHyphens(ref.replace(/[^a-zA-Z0-9_-]+/g, "-"))
|
|
16
|
+
.slice(0, 40) || "app";
|
|
17
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
18
|
+
return resolve(`nodetool-debug/app-build-${slug}-${stamp}`);
|
|
19
|
+
}
|
|
20
|
+
/** Where one interaction's runs are filed. */
|
|
21
|
+
export const interactionDir = (outDir, interaction) => join(outDir, "interactions", interaction.replace(/[^a-zA-Z0-9_-]+/g, "-"));
|
|
22
|
+
/** Write one run's raw message stream; returns the path recorded in the report. */
|
|
23
|
+
export async function writeRunMessages(outDir, interaction, runIndex, messages) {
|
|
24
|
+
const dir = interactionDir(outDir, interaction);
|
|
25
|
+
await mkdir(dir, { recursive: true });
|
|
26
|
+
const relative = `interactions/${interaction.replace(/[^a-zA-Z0-9_-]+/g, "-")}/run-${runIndex + 1}.messages.jsonl`;
|
|
27
|
+
await writeFile(join(outDir, relative), messages.map((message) => JSON.stringify(message)).join("\n") + "\n", "utf8");
|
|
28
|
+
return relative;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Write the finished bundle. `app.bundle.json` is the deliverable, so it is
|
|
32
|
+
* written only for a build that produced one — a failed build's directory has
|
|
33
|
+
* the report and the evidence, and nothing importable.
|
|
34
|
+
*/
|
|
35
|
+
export async function writeBuildBundle(outDir, report, markdown) {
|
|
36
|
+
await mkdir(outDir, { recursive: true });
|
|
37
|
+
await writeFile(join(outDir, "report.json"), JSON.stringify(report, null, 2), "utf8");
|
|
38
|
+
await writeFile(join(outDir, "report.md"), markdown, "utf8");
|
|
39
|
+
await writeFile(join(outDir, "spec.json"), JSON.stringify(report.spec, null, 2), "utf8");
|
|
40
|
+
if (report.bundle) {
|
|
41
|
+
await writeFile(join(outDir, "app.bundle.json"), JSON.stringify(report.bundle, null, 2), "utf8");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/app-build/bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAElE,sEAAsE;AACtE,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,IAAI,GACR,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;SAC9C,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC;IAC3B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7D,OAAO,OAAO,CAAC,4BAA4B,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,8CAA8C;AAC9C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAc,EAAE,WAAmB,EAAU,EAAE,CAC5E,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC;AAE7E,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,WAAmB,EACnB,QAAgB,EAChB,QAA6B;IAE7B,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChD,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,gBAAgB,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,QAAQ,QAAQ,GAAG,CAAC,iBAAiB,CAAC;IACnH,MAAM,SAAS,CACb,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,EACtB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EACpE,MAAM,CACP,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,MAAmB,EACnB,QAAgB;IAEhB,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,SAAS,CACb,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,EAC3B,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAC/B,MAAM,CACP,CAAC;IACF,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7D,MAAM,SAAS,CACb,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EACzB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EACpC,MAAM,CACP,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,SAAS,CACb,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC/B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EACtC,MAAM,CACP,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `nodetool app build --watch` diffs between two builds of the same spec.
|
|
3
|
+
*
|
|
4
|
+
* The differ is the one `nodetool debug --watch` uses, so a build only has to
|
|
5
|
+
* say what its ok, its issues, its state, and its spend are. Issues come from
|
|
6
|
+
* the last repair round, which carries everything still wrong rather than a
|
|
7
|
+
* delta — the same set the command prints as "Outstanding issues" — so the
|
|
8
|
+
* diff's resolved/new lines line up with what a human just read.
|
|
9
|
+
*/
|
|
10
|
+
import type { BuildReport } from "@nodetool-ai/agents";
|
|
11
|
+
import type { RunSnapshot } from "@nodetool-ai/cli-execution/debug/diff";
|
|
12
|
+
export declare function snapshotBuildReport(report: BuildReport): RunSnapshot;
|
|
13
|
+
//# sourceMappingURL=watch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/app-build/watch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAqBzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CASpE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** One issue line, stable across rounds so the diff can match it. */
|
|
2
|
+
const issueLine = (issue) => `[${issue.stage}/${issue.code}] ${issue.message}`;
|
|
3
|
+
/** Everything still wrong at the end of the build. Empty on a green one. */
|
|
4
|
+
function outstandingIssues(report) {
|
|
5
|
+
if (report.verdict.ok)
|
|
6
|
+
return [];
|
|
7
|
+
const last = report.repairs[report.repairs.length - 1];
|
|
8
|
+
// A build that failed before the first repair round (spec, or a budget that
|
|
9
|
+
// ran out) has no complaint; its stage records are the only evidence.
|
|
10
|
+
const issues = last
|
|
11
|
+
? last.issues
|
|
12
|
+
: report.stages.flatMap((stage) => stage.issues);
|
|
13
|
+
return issues.map(issueLine);
|
|
14
|
+
}
|
|
15
|
+
export function snapshotBuildReport(report) {
|
|
16
|
+
const last = report.stages[report.stages.length - 1];
|
|
17
|
+
return {
|
|
18
|
+
ok: report.verdict.ok,
|
|
19
|
+
issues: outstandingIssues(report),
|
|
20
|
+
status: last ? `${last.stage}/${last.status}` : null,
|
|
21
|
+
tokens: null,
|
|
22
|
+
costUsd: report.cost.usd
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/app-build/watch.ts"],"names":[],"mappings":"AAYA,qEAAqE;AACrE,MAAM,SAAS,GAAG,CAAC,KAIlB,EAAU,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;AAEhE,4EAA4E;AAC5E,SAAS,iBAAiB,CAAC,MAAmB;IAC5C,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvD,4EAA4E;IAC5E,sEAAsE;IACtE,MAAM,MAAM,GAAG,IAAI;QACjB,CAAC,CAAC,IAAI,CAAC,MAAM;QACb,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnD,OAAO,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrD,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE;QACrB,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC;QACjC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI;QACpD,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG;KACzB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type AppApplicationRecord, type AppWorkflowRecord, type ResolvedAppTarget } from "@nodetool-ai/execution/app-debug";
|
|
2
|
+
export type { ResolvedAppTarget, AppApplicationRecord, AppWorkflowRecord };
|
|
3
|
+
export interface AppTargetDeps {
|
|
4
|
+
/** Load a workflow by DB id, including its legacy `app_doc`. */
|
|
5
|
+
loadFromDb: (id: string, version?: number) => Promise<AppWorkflowRecord | null>;
|
|
6
|
+
/** Load an application by DB id. Omitted when the caller has no DB. */
|
|
7
|
+
loadApplication?: (id: string) => Promise<AppApplicationRecord | null>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolve an app debug target: an application id, an ApplicationBundle JSON
|
|
11
|
+
* file, or a workflow id / workflow file carrying a legacy `app_doc`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveAppTarget(ref: string, deps: AppTargetDeps): Promise<ResolvedAppTarget>;
|
|
14
|
+
//# sourceMappingURL=app-target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-target.d.ts","sourceRoot":"","sources":["../../src/app-debug/app-target.ts"],"names":[],"mappings":"AA6BA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,kCAAkC,CAAC;AAM1C,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,CAAC;AAE3E,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAChF,uEAAuE;IACvE,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CACxE;AAuFD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAsB5B"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves an app debug target into an application document plus the graphs it
|
|
3
|
+
* runs.
|
|
4
|
+
*
|
|
5
|
+
* An app can be named three ways, and all three end up in the same shape:
|
|
6
|
+
*
|
|
7
|
+
* - an **application id** — the canonical form, read from the applications
|
|
8
|
+
* table through an injected loader (no server involved) and resolved by
|
|
9
|
+
* `applicationTarget`, which the server surface calls too;
|
|
10
|
+
* - an **ApplicationBundle JSON file** — an app together with the full graphs
|
|
11
|
+
* of every workflow it binds, where operations reference bundle-local keys;
|
|
12
|
+
* - a **workflow id or workflow JSON/DSL file** — the legacy form, where the
|
|
13
|
+
* document sits on `workflow.app_doc` and is lifted by `liftLegacyAppDoc`.
|
|
14
|
+
*
|
|
15
|
+
* The harness downstream sees one shape regardless: a raw document (for the
|
|
16
|
+
* bundle's `app.json` and persist-downgrade warnings), the parsed document, a
|
|
17
|
+
* host graph, and the graphs the target itself carries keyed by whatever id
|
|
18
|
+
* the operations reference.
|
|
19
|
+
*/
|
|
20
|
+
import { liftLegacyAppDoc, parseApplicationBundle } from "@nodetool-ai/app-runtime";
|
|
21
|
+
import { looksLikeFile, normalizeGraph, readFileTarget } from "@nodetool-ai/cli-execution/debug/target";
|
|
22
|
+
// The resolved shape is the simulator's input, and so is the resolution of an
|
|
23
|
+
// application row — both live with the simulator so the CLI and the server
|
|
24
|
+
// surfaces cannot drift.
|
|
25
|
+
import { applicationTarget, bundleTarget } from "@nodetool-ai/execution/app-debug";
|
|
26
|
+
import { isRecord, isString } from "@nodetool-ai/cli-common/predicates";
|
|
27
|
+
const EMPTY_GRAPH = { nodes: [], edges: [] };
|
|
28
|
+
const targetInfo = (ref, source, workflowId, graph) => ({
|
|
29
|
+
ref,
|
|
30
|
+
source,
|
|
31
|
+
workflowId,
|
|
32
|
+
nodeCount: graph.nodes.length,
|
|
33
|
+
edgeCount: graph.edges.length
|
|
34
|
+
});
|
|
35
|
+
/** A bundle file carries `app` and `workflows`; a workflow file carries neither. */
|
|
36
|
+
const looksLikeBundle = (raw) => isRecord(raw) && isRecord(raw.app) && Array.isArray(raw.workflows);
|
|
37
|
+
const graphOf = (value) => {
|
|
38
|
+
if (!isRecord(value))
|
|
39
|
+
return null;
|
|
40
|
+
const { nodes, edges } = value;
|
|
41
|
+
if (!Array.isArray(nodes) || !Array.isArray(edges))
|
|
42
|
+
return null;
|
|
43
|
+
return normalizeGraph({ nodes, edges });
|
|
44
|
+
};
|
|
45
|
+
/** Resolve an ApplicationBundle JSON file. */
|
|
46
|
+
function resolveBundle(ref, raw) {
|
|
47
|
+
const bundle = parseApplicationBundle(raw);
|
|
48
|
+
const rawApp = isRecord(raw) ? raw.app : null;
|
|
49
|
+
if (!bundle) {
|
|
50
|
+
return {
|
|
51
|
+
info: targetInfo(ref, "bundle", null, EMPTY_GRAPH),
|
|
52
|
+
graph: EMPTY_GRAPH,
|
|
53
|
+
fileParams: {},
|
|
54
|
+
appDoc: rawApp,
|
|
55
|
+
document: null,
|
|
56
|
+
issue: `${ref} is not a valid application bundle (no parsable \`app\` document).`,
|
|
57
|
+
graphs: new Map(),
|
|
58
|
+
operationsReferenceKeys: true,
|
|
59
|
+
appName: null
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// The bundle → target mapping lives with the simulator, so the file path
|
|
63
|
+
// here and the build harness's in-memory path cannot drift.
|
|
64
|
+
return bundleTarget(bundle, ref, rawApp);
|
|
65
|
+
}
|
|
66
|
+
/** Resolve a workflow target — id, JSON file, or DSL file — via its `app_doc`. */
|
|
67
|
+
function resolveWorkflow(ref, raw, source) {
|
|
68
|
+
const record = isRecord(raw) ? raw : {};
|
|
69
|
+
const workflowId = (isString(record.workflow_id) ? record.workflow_id : null) ??
|
|
70
|
+
(isString(record.id) ? record.id : null);
|
|
71
|
+
const rawGraph = graphOf(record.graph) ?? graphOf(record);
|
|
72
|
+
if (!rawGraph)
|
|
73
|
+
throw new Error("Invalid workflow: missing nodes or edges");
|
|
74
|
+
const appDoc = record.app_doc ?? null;
|
|
75
|
+
const document = liftLegacyAppDoc({ id: workflowId ?? "", app_doc: appDoc });
|
|
76
|
+
const graphs = new Map();
|
|
77
|
+
if (workflowId)
|
|
78
|
+
graphs.set(workflowId, rawGraph);
|
|
79
|
+
const issue = document
|
|
80
|
+
? null
|
|
81
|
+
: appDoc == null
|
|
82
|
+
? "Workflow has no app_doc — build the app in the App Builder first."
|
|
83
|
+
: "app_doc is not a valid application document (no `ui`/`data`).";
|
|
84
|
+
return {
|
|
85
|
+
info: targetInfo(ref, source, workflowId, rawGraph),
|
|
86
|
+
graph: rawGraph,
|
|
87
|
+
fileParams: isRecord(record.params) ? { ...record.params } : {},
|
|
88
|
+
appDoc,
|
|
89
|
+
document,
|
|
90
|
+
issue,
|
|
91
|
+
graphs,
|
|
92
|
+
operationsReferenceKeys: false,
|
|
93
|
+
appName: null
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve an app debug target: an application id, an ApplicationBundle JSON
|
|
98
|
+
* file, or a workflow id / workflow file carrying a legacy `app_doc`.
|
|
99
|
+
*/
|
|
100
|
+
export async function resolveAppTarget(ref, deps) {
|
|
101
|
+
if (looksLikeFile(ref)) {
|
|
102
|
+
const { raw, source } = await readFileTarget(ref);
|
|
103
|
+
return looksLikeBundle(raw)
|
|
104
|
+
? resolveBundle(ref, raw)
|
|
105
|
+
: resolveWorkflow(ref, raw, source);
|
|
106
|
+
}
|
|
107
|
+
if (deps.loadApplication) {
|
|
108
|
+
const application = await deps.loadApplication(ref);
|
|
109
|
+
if (application)
|
|
110
|
+
return applicationTarget(ref, application, deps.loadFromDb);
|
|
111
|
+
}
|
|
112
|
+
const workflow = await deps.loadFromDb(ref);
|
|
113
|
+
if (!workflow) {
|
|
114
|
+
throw new Error(deps.loadApplication
|
|
115
|
+
? `No application or workflow found: ${ref}`
|
|
116
|
+
: `Workflow not found: ${ref}`);
|
|
117
|
+
}
|
|
118
|
+
return resolveWorkflow(ref, { ...workflow, id: ref }, "id");
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=app-target.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-target.js","sourceRoot":"","sources":["../../src/app-debug/app-target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAExG,8EAA8E;AAC9E,2EAA2E;AAC3E,yBAAyB;AACzB,OAAO,EACL,iBAAiB,EACjB,YAAY,EAIb,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,QAAQ,EACR,QAAQ,EACT,MAAM,oCAAoC,CAAC;AAW5C,MAAM,WAAW,GAAe,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAEzD,MAAM,UAAU,GAAG,CACjB,GAAW,EACX,MAAiC,EACjC,UAAyB,EACzB,KAAiB,EACA,EAAE,CAAC,CAAC;IACrB,GAAG;IACH,MAAM;IACN,UAAU;IACV,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;IAC7B,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;CAC9B,CAAC,CAAC;AAEH,oFAAoF;AACpF,MAAM,eAAe,GAAG,CAAC,GAAY,EAAW,EAAE,CAChD,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAErE,MAAM,OAAO,GAAG,CAAC,KAAc,EAAqB,EAAE;IACpD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,OAAO,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF,8CAA8C;AAC9C,SAAS,aAAa,CAAC,GAAW,EAAE,GAAY;IAC9C,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,IAAI,EAAE,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC;YAClD,KAAK,EAAE,WAAW;YAClB,UAAU,EAAE,EAAE;YACd,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,GAAG,GAAG,oEAAoE;YACjF,MAAM,EAAE,IAAI,GAAG,EAAE;YACjB,uBAAuB,EAAE,IAAI;YAC7B,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IACD,yEAAyE;IACzE,4DAA4D;IAC5D,OAAO,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED,kFAAkF;AAClF,SAAS,eAAe,CACtB,GAAW,EACX,GAAY,EACZ,MAAiC;IAEjC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,MAAM,UAAU,GACd,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1D,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAE3E,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC;IACtC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,EAAE,EAAE,UAAU,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC7C,IAAI,UAAU;QAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAEjD,MAAM,KAAK,GAAG,QAAQ;QACpB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,MAAM,IAAI,IAAI;YACd,CAAC,CAAC,mEAAmE;YACrE,CAAC,CAAC,+DAA+D,CAAC;IAEtE,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC;QACnD,KAAK,EAAE,QAAQ;QACf,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;QAC/D,MAAM;QACN,QAAQ;QACR,KAAK;QACL,MAAM;QACN,uBAAuB,EAAE,KAAK;QAC9B,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,IAAmB;IAEnB,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QAClD,OAAO,eAAe,CAAC,GAAG,CAAC;YACzB,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC;YACzB,CAAC,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,WAAW;YAAE,OAAO,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,IAAI,CAAC,eAAe;YAClB,CAAC,CAAC,qCAAqC,GAAG,EAAE;YAC5C,CAAC,CAAC,uBAAuB,GAAG,EAAE,CACjC,CAAC;IACJ,CAAC;IACD,OAAO,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type AppDebugOptions, type AppDebugReport, type JsScriptOperationLoader, type JsScriptOperationRunner } from "@nodetool-ai/execution/app-debug";
|
|
2
|
+
import type { NodeRegistry } from "@nodetool-ai/node-sdk";
|
|
3
|
+
import { type AppTargetDeps } from "./app-target.js";
|
|
4
|
+
import type { DebugGraph } from "@nodetool-ai/cli-execution/debug/types";
|
|
5
|
+
import type { ServerRunInput, ServerRunOutcome } from "@nodetool-ai/cli-execution/debug/server-runner";
|
|
6
|
+
export { defaultInteractions } from "@nodetool-ai/execution/app-debug";
|
|
7
|
+
export interface AppDebugDeps {
|
|
8
|
+
/** Load a workflow by DB id, including its legacy `app_doc`. */
|
|
9
|
+
loadFromDb: (id: string, version?: number) => Promise<{
|
|
10
|
+
graph: DebugGraph;
|
|
11
|
+
app_doc?: unknown;
|
|
12
|
+
} | null>;
|
|
13
|
+
/**
|
|
14
|
+
* Load an application by DB id. Without it a bare id is only ever read as a
|
|
15
|
+
* workflow, which is what a caller with no database wants.
|
|
16
|
+
*/
|
|
17
|
+
loadApplication?: AppTargetDeps["loadApplication"];
|
|
18
|
+
/** Progress/log sink. */
|
|
19
|
+
onLog?: (line: string) => void;
|
|
20
|
+
/** Injected for tests; defaults to the kernel server runner. */
|
|
21
|
+
runOnServer?: (input: ServerRunInput) => Promise<ServerRunOutcome>;
|
|
22
|
+
/** Injected for tests; defaults to the sandbox script runner. */
|
|
23
|
+
runScript?: JsScriptOperationRunner;
|
|
24
|
+
/** Resolve a pinned script version an operation targets but the target lacks. */
|
|
25
|
+
loadScript?: JsScriptOperationLoader;
|
|
26
|
+
registry?: NodeRegistry;
|
|
27
|
+
}
|
|
28
|
+
export declare function runAppDebug(ref: string, options: AppDebugOptions, deps: AppDebugDeps): Promise<AppDebugReport>;
|
|
29
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../src/app-debug/harness.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC7B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1D,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACzE,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EACjB,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAKvE,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,UAAU,EAAE,CACV,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC9D;;;OAGG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACnD,yBAAyB;IACzB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,gEAAgE;IAChE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnE,iEAAiE;IACjE,SAAS,CAAC,EAAE,uBAAuB,CAAC;IACpC,iFAAiF;IACjF,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAUD,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,cAAc,CAAC,CAyHzB"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app-builder debug harness: the CLI host around the shared simulator.
|
|
3
|
+
*
|
|
4
|
+
* Resolves the target (application id, `ApplicationBundle` file, or workflow
|
|
5
|
+
* carrying a legacy `app_doc`), runs `simulateApp` from
|
|
6
|
+
* `@nodetool-ai/execution` — which owns every simulation rule — and writes the
|
|
7
|
+
* self-contained bundle: the graph, the app document, each run's raw message
|
|
8
|
+
* stream, and the report in both JSON and Markdown. The `AppDebugReport` comes
|
|
9
|
+
* back so an agent can iterate without re-reading the bundle.
|
|
10
|
+
*/
|
|
11
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
12
|
+
import { join, resolve } from "node:path";
|
|
13
|
+
import { renderAppReportMarkdown, simulateApp } from "@nodetool-ai/execution/app-debug";
|
|
14
|
+
import { resolveAppTarget } from "./app-target.js";
|
|
15
|
+
import { formatRunJson } from "@nodetool-ai/cli-execution/run-json";
|
|
16
|
+
import { trimHyphens } from "@nodetool-ai/cli-common/trimHyphens";
|
|
17
|
+
export { defaultInteractions } from "@nodetool-ai/execution/app-debug";
|
|
18
|
+
/** The local single-user id every direct-DB CLI command runs as. */
|
|
19
|
+
const LOCAL_USER_ID = "1";
|
|
20
|
+
function defaultOutDir(ref) {
|
|
21
|
+
const slug = trimHyphens(ref.replace(/[^a-zA-Z0-9_-]+/g, "-"))
|
|
22
|
+
.slice(0, 40) || "workflow";
|
|
23
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
24
|
+
return resolve(`nodetool-debug/app-${slug}-${stamp}`);
|
|
25
|
+
}
|
|
26
|
+
export async function runAppDebug(ref, options, deps) {
|
|
27
|
+
const targetDeps = {
|
|
28
|
+
loadFromDb: deps.loadFromDb
|
|
29
|
+
};
|
|
30
|
+
if (deps.loadApplication) {
|
|
31
|
+
targetDeps.loadApplication = deps.loadApplication;
|
|
32
|
+
}
|
|
33
|
+
const resolved = await resolveAppTarget(ref, targetDeps);
|
|
34
|
+
const outDir = options.outDir ? resolve(options.outDir) : defaultOutDir(ref);
|
|
35
|
+
await mkdir(join(outDir, "server"), { recursive: true });
|
|
36
|
+
await writeFile(join(outDir, "workflow.json"), JSON.stringify(resolved.graph, null, 2), "utf8");
|
|
37
|
+
if (resolved.appDoc != null) {
|
|
38
|
+
await writeFile(join(outDir, "app.json"), JSON.stringify(resolved.appDoc, null, 2), "utf8");
|
|
39
|
+
}
|
|
40
|
+
// Loaded on first run, not up front: a `--no-run` check must not pull in the
|
|
41
|
+
// node registries the server runner boots.
|
|
42
|
+
const runOnServer = deps.runOnServer ??
|
|
43
|
+
(async (input) => (await import("@nodetool-ai/cli-execution/debug/server-runner")).runOnServer(input));
|
|
44
|
+
// Both load lazily for the same reason `runOnServer` does: a `--no-run`
|
|
45
|
+
// check must not pull in the sandbox or the database.
|
|
46
|
+
const runScript = deps.runScript ??
|
|
47
|
+
(async (input) => {
|
|
48
|
+
const { createJsScriptAppRunner } = await import("@nodetool-ai/agents");
|
|
49
|
+
const { getSecret } = await import("@nodetool-ai/models");
|
|
50
|
+
return createJsScriptAppRunner(LOCAL_USER_ID, {
|
|
51
|
+
secretResolver: getSecret
|
|
52
|
+
})(input);
|
|
53
|
+
});
|
|
54
|
+
const loadScript = deps.loadScript ??
|
|
55
|
+
(async (scriptId, scriptVersion) => {
|
|
56
|
+
const { createJsScriptResolver } = await import("@nodetool-ai/models");
|
|
57
|
+
const resolved = await createJsScriptResolver().resolve({
|
|
58
|
+
id: scriptId,
|
|
59
|
+
version: scriptVersion
|
|
60
|
+
});
|
|
61
|
+
return resolved
|
|
62
|
+
? { name: resolved.name, document: resolved.document }
|
|
63
|
+
: null;
|
|
64
|
+
});
|
|
65
|
+
const simulateDeps = {
|
|
66
|
+
loadFromDb: deps.loadFromDb,
|
|
67
|
+
runOnServer,
|
|
68
|
+
runScript,
|
|
69
|
+
loadScript,
|
|
70
|
+
onRunMessages: async (runIndex, messages) => {
|
|
71
|
+
const messagesFile = `server/run-${runIndex + 1}.messages.jsonl`;
|
|
72
|
+
const lines = [];
|
|
73
|
+
for (const [messageIndex, message] of messages.entries()) {
|
|
74
|
+
const { json } = await formatRunJson(message, {
|
|
75
|
+
outputDir: join(outDir, "server", `run-${runIndex + 1}-payloads`, `message-${messageIndex + 1}`)
|
|
76
|
+
});
|
|
77
|
+
lines.push(JSON.stringify(JSON.parse(json)));
|
|
78
|
+
}
|
|
79
|
+
await writeFile(join(outDir, messagesFile), `${lines.join("\n")}\n`, "utf8");
|
|
80
|
+
return messagesFile;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
if (deps.onLog) {
|
|
84
|
+
simulateDeps.onLog = deps.onLog;
|
|
85
|
+
}
|
|
86
|
+
const runIds = new Set();
|
|
87
|
+
if (options.run !== false) {
|
|
88
|
+
const [{ createAppDebugRunRecording }, { ProcessingContext: Context }, { buildFullRegistry }, { getSecret }, { FileStorageAdapter }, { getDefaultAssetsPath }] = await Promise.all([
|
|
89
|
+
import("@nodetool-ai/execution/app-debug"), import("@nodetool-ai/runtime"), import("@nodetool-ai/cli-execution/node-registry"),
|
|
90
|
+
import("@nodetool-ai/models"), import("@nodetool-ai/storage"), import("@nodetool-ai/config")
|
|
91
|
+
]);
|
|
92
|
+
const context = new Context({ userId: LOCAL_USER_ID, jobId: `app-debug-${Date.now()}`,
|
|
93
|
+
secretResolver: getSecret, storage: new FileStorageAdapter(getDefaultAssetsPath()) });
|
|
94
|
+
const recording = createAppDebugRunRecording({ userId: LOCAL_USER_ID, target: resolved,
|
|
95
|
+
context, registry: deps.registry ?? await buildFullRegistry(), loadWorkflow: deps.loadFromDb, loadScript,
|
|
96
|
+
onRunCreated: (id) => { runIds.add(id); },
|
|
97
|
+
applicationId: resolved.info.source === "application" ? resolved.info.ref : undefined,
|
|
98
|
+
runWorkflow: (parent, input) => runOnServer({ ...input, context: parent }),
|
|
99
|
+
runScript: async (parent, input) => {
|
|
100
|
+
if (deps.runScript) {
|
|
101
|
+
return deps.runScript(input);
|
|
102
|
+
}
|
|
103
|
+
const { createJsScriptAppRunner } = await import("@nodetool-ai/agents");
|
|
104
|
+
return createJsScriptAppRunner(LOCAL_USER_ID, { context: parent, secretResolver: getSecret })(input);
|
|
105
|
+
} });
|
|
106
|
+
Object.assign(simulateDeps, recording);
|
|
107
|
+
}
|
|
108
|
+
const report = await simulateApp(resolved, options, simulateDeps);
|
|
109
|
+
report.run_ids = [...runIds];
|
|
110
|
+
report.bundleDir = outDir;
|
|
111
|
+
await writeFile(join(outDir, "report.json"), JSON.stringify(report, null, 2), "utf8");
|
|
112
|
+
await writeFile(join(outDir, "report.md"), renderAppReportMarkdown(report), "utf8");
|
|
113
|
+
return report;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/app-debug/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's app-debug surface: target resolution plus the bundle-writing
|
|
3
|
+
* harness, over the simulator in `@nodetool-ai/execution/app-debug`. The
|
|
4
|
+
* simulator's exports are re-exported here so importers keep one entry point.
|
|
5
|
+
*/
|
|
6
|
+
export { runAppDebug, defaultInteractions } from "./harness.js";
|
|
7
|
+
export type { AppDebugDeps } from "./harness.js";
|
|
8
|
+
export { resolveAppTarget } from "./app-target.js";
|
|
9
|
+
export type { AppApplicationRecord, AppTargetDeps, AppWorkflowRecord } from "./app-target.js";
|
|
10
|
+
export { bindingScopeFor, documentOperations, effectiveTimeoutMs, extractAppIO, HeadlessAppRuntime, InMemoryResourceProvider, operationSpec, parseAppDocument, parseAppSpec, renderAppReportMarkdown, seedResourceHint, simulateApp, validateApp } from "@nodetool-ai/execution/app-debug";
|
|
11
|
+
export type * from "@nodetool-ai/execution/app-debug";
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/app-debug/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,wBAAwB,EACxB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,uBAAuB,EACvB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACZ,MAAM,kCAAkC,CAAC;AAC1C,mBAAmB,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's app-debug surface: target resolution plus the bundle-writing
|
|
3
|
+
* harness, over the simulator in `@nodetool-ai/execution/app-debug`. The
|
|
4
|
+
* simulator's exports are re-exported here so importers keep one entry point.
|
|
5
|
+
*/
|
|
6
|
+
export { runAppDebug, defaultInteractions } from "./harness.js";
|
|
7
|
+
export { resolveAppTarget } from "./app-target.js";
|
|
8
|
+
export { bindingScopeFor, documentOperations, effectiveTimeoutMs, extractAppIO, HeadlessAppRuntime, InMemoryResourceProvider, operationSpec, parseAppDocument, parseAppSpec, renderAppReportMarkdown, seedResourceHint, simulateApp, validateApp } from "@nodetool-ai/execution/app-debug";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/app-debug/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAMnD,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,wBAAwB,EACxB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,uBAAuB,EACvB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACZ,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/commands/app.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyCzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyJ1D"}
|