@plasm_lang/vercel-agent 0.3.63

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.
Files changed (121) hide show
  1. package/README.md +235 -0
  2. package/agent/.plasm/archives/runs/runs/pr2d5c4a99707b4c19b650553d50229a1d600d28e3d98a9c58f18e5026cecc86ca.json +64 -0
  3. package/agent/.plasm/archives/runs/runs/pr2e0c0d8ad443c63c82da7435ee1a002b0e0fa718b640263c0a9d3e6e5944812f.json +64 -0
  4. package/agent/.plasm/archives/runs/runs/pr2faedb8354f40ee6d828e3af07b421fda9ccda973a4f7347fce3639f03a0a869.json +64 -0
  5. package/agent/.plasm/archives/runs/runs/pr586b47c55547b0702c572bce4255558b22dbe5e682d6359169577e0ea75fe98f.json +64 -0
  6. package/agent/.plasm/archives/runs/runs/pr76212356445e3b00fcf256835aaec18bac68576324b90d0be92d47f0b4a862a7.json +56 -0
  7. package/agent/.plasm/archives/runs/runs/pr9ec805d689e00db9270a9539858f2fb7216c24acbfea943d450e37b641149da1.json +64 -0
  8. package/agent/.plasm/archives/runs/runs/prc3c0c4ba2e28fc94ed6d37b6796e277a7997d9cb3184640d14c35c98bc6d136f.json +64 -0
  9. package/agent/.plasm/archives/runs/runs/prf04de32522f2fdcb17818907d91bccce7dcaecbd1259041cc448d447b6993244.json +64 -0
  10. package/agent/.plasm/archives/traces/traces/local/00000000000000000000000000000000/records.ndjson +1 -0
  11. package/agent/.plasm/archives/traces/traces/local/00000000000000000000000000000000/summary.json +13 -0
  12. package/agent/.plasm/discovery/manifest.json +126 -0
  13. package/agent/.plasm/sessions/TGlzdCBwcm9kdWN0cyBmcm9tIHRoZSBleGVjdXRlX3RpbnkgY2F0YWxvZw.json +44 -0
  14. package/agent/.plasm/sessions/TGlzdCBwcm9kdWN0cyBmcm9tIHRoZSBleGVjdXRlX3RpbnkgY2F0YWxvZw.teaching.tsv +23 -0
  15. package/agent/.plasm/sessions/bGlzdCBleGVjdXRlX3RpbnkgcHJvZHVjdHM.json +151 -0
  16. package/agent/.plasm/sessions/bGlzdCBleGVjdXRlX3RpbnkgcHJvZHVjdHM.teaching.tsv +131 -0
  17. package/agent/.plasm/sessions/bGlzdCBleGVjdXRlX3RpbnkgcHJvZHVjdHMgYXN5bmMgdHJhbnNwb3J0.json +44 -0
  18. package/agent/.plasm/sessions/bGlzdCBleGVjdXRlX3RpbnkgcHJvZHVjdHMgYXN5bmMgdHJhbnNwb3J0.teaching.tsv +23 -0
  19. package/agent/.plasm/stubs/.gitkeep +0 -0
  20. package/agent/.plasm/stubs/execute_tiny.ts +107 -0
  21. package/agent/agent.ts +52 -0
  22. package/agent/catalogs/README.md +15 -0
  23. package/agent/channels/.gitkeep +0 -0
  24. package/agent/channels/execute-tiny-webhook.ts +59 -0
  25. package/agent/channels/health.ts +16 -0
  26. package/agent/hooks/.gitkeep +0 -0
  27. package/agent/hooks/trace-log.ts +10 -0
  28. package/agent/instructions.md +25 -0
  29. package/agent/schedules/.gitkeep +0 -0
  30. package/agent/schedules/ping.ts +13 -0
  31. package/agent/skills/.gitkeep +0 -0
  32. package/agent/skills/plasm-authoring.md +8 -0
  33. package/agent/subagents/.gitkeep +0 -0
  34. package/agent/subagents/tiny/agent.ts +28 -0
  35. package/bin/plasm-agent.mjs +18 -0
  36. package/package.json +77 -0
  37. package/scripts/plasm-node.mjs +19 -0
  38. package/scripts/resolve-ts-extension.mjs +18 -0
  39. package/src/archive/adapters.ts +27 -0
  40. package/src/archive/index.ts +99 -0
  41. package/src/archive/local-run-archive.ts +90 -0
  42. package/src/archive/local-trace-archive.ts +91 -0
  43. package/src/archive/paths.ts +15 -0
  44. package/src/archive/postgres-kv-adapter.ts +72 -0
  45. package/src/archive/prod-archive-store.ts +143 -0
  46. package/src/archive/resolve-backend.ts +60 -0
  47. package/src/archive/run-id.ts +23 -0
  48. package/src/archive/types.ts +75 -0
  49. package/src/archive/vercel-blob-adapter.ts +21 -0
  50. package/src/archive/vercel-kv-adapter.ts +24 -0
  51. package/src/authoring/channel-dispatch.ts +44 -0
  52. package/src/authoring/context.ts +34 -0
  53. package/src/authoring/define-channel.ts +83 -0
  54. package/src/authoring/define-hook.ts +51 -0
  55. package/src/authoring/define-schedule.ts +64 -0
  56. package/src/authoring/define-skill.ts +38 -0
  57. package/src/authoring/hook-runner.ts +18 -0
  58. package/src/authoring/schedule-manager.ts +118 -0
  59. package/src/authoring/slot-loader.ts +253 -0
  60. package/src/authoring/subagent-loader.ts +121 -0
  61. package/src/catalog/loader.ts +71 -0
  62. package/src/cli/build.ts +54 -0
  63. package/src/cli/dev.ts +60 -0
  64. package/src/cli/info.ts +12 -0
  65. package/src/cli/init.ts +372 -0
  66. package/src/cli/link.ts +68 -0
  67. package/src/cli/project-root.ts +57 -0
  68. package/src/define-agent.ts +150 -0
  69. package/src/dev/client/ansi.ts +36 -0
  70. package/src/dev/client/http-session.ts +180 -0
  71. package/src/dev/client/repl.ts +92 -0
  72. package/src/dev/client/slash.ts +119 -0
  73. package/src/dev/dev-session.ts +153 -0
  74. package/src/dev/http.ts +29 -0
  75. package/src/dev/server.ts +147 -0
  76. package/src/dev/session-routes.ts +185 -0
  77. package/src/discovery/project-walker.ts +272 -0
  78. package/src/engine/connect-auth.ts +135 -0
  79. package/src/engine/create-host-transport.ts +7 -0
  80. package/src/engine/fixture-mock-transport.ts +54 -0
  81. package/src/engine/host-transport-bridge.ts +32 -0
  82. package/src/engine/host-transport.ts +84 -0
  83. package/src/engine/napi-binding.ts +265 -0
  84. package/src/evals/define-eval.ts +56 -0
  85. package/src/evals/run-eval.ts +136 -0
  86. package/src/gateway-model.ts +43 -0
  87. package/src/index.ts +296 -0
  88. package/src/instrumentation.ts +56 -0
  89. package/src/load-env.ts +63 -0
  90. package/src/operator/routes.ts +287 -0
  91. package/src/operator/types.ts +63 -0
  92. package/src/operator/ui-shell.ts +134 -0
  93. package/src/project-info.ts +229 -0
  94. package/src/runtime/agent-runtime.ts +469 -0
  95. package/src/runtime/compaction.ts +81 -0
  96. package/src/runtime/logical-session.ts +72 -0
  97. package/src/runtime/plasm-agent.ts +199 -0
  98. package/src/server/plasm-handler.ts +331 -0
  99. package/src/session-state.ts +135 -0
  100. package/src/state/define-state.ts +57 -0
  101. package/src/state/fs-state-adapter.ts +72 -0
  102. package/src/state/kv-state-adapter.ts +62 -0
  103. package/src/state/postgres-state-adapter.ts +116 -0
  104. package/src/stubs/capability-invoke-shape.ts +135 -0
  105. package/src/stubs/catalog-client.ts +170 -0
  106. package/src/stubs/catalog-hash.ts +11 -0
  107. package/src/stubs/catalog-introspection.ts +121 -0
  108. package/src/stubs/cgs-ts-types.ts +164 -0
  109. package/src/stubs/domain-parser.ts +203 -0
  110. package/src/stubs/generator.ts +390 -0
  111. package/src/stubs/input-type-to-ts.ts +233 -0
  112. package/src/stubs/plasm-value-emitter.ts +162 -0
  113. package/src/stubs/program-builder.ts +82 -0
  114. package/src/stubs/stub-symbols.ts +89 -0
  115. package/src/symbol-registry.ts +74 -0
  116. package/src/telemetry/plasm-spans.ts +83 -0
  117. package/src/tools/descriptions.ts +94 -0
  118. package/src/tools/format.ts +29 -0
  119. package/src/tools/harness-tools.ts +65 -0
  120. package/src/tools/plasm-tools.ts +104 -0
  121. package/src/workflow/world-bootstrap.ts +52 -0
@@ -0,0 +1,107 @@
1
+ /** @generated catalog_cgs_hash=aee3d865ff02b2ac8f0c168915a63dfe8f57c87f00fab3e03c87fcec72f5eb84 entry_id=execute_tiny generated_at=2026-06-21T20:30:39.128Z */
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ import {
6
+ createCatalogClient,
7
+ buildDottedArgs,
8
+ executeRows,
9
+ plasmBoolean,
10
+ plasmLiteral,
11
+ plasmNumber,
12
+ type StubInvokeOptions,
13
+ } from "@plasm_lang/vercel-agent";
14
+
15
+ export const catalogCgsHash = "aee3d865ff02b2ac8f0c168915a63dfe8f57c87f00fab3e03c87fcec72f5eb84";
16
+ export const entryId = "execute_tiny";
17
+
18
+ const catalogRoot = path.resolve(
19
+ path.dirname(fileURLToPath(import.meta.url)),
20
+ "../../catalogs/execute_tiny",
21
+ );
22
+
23
+ const stubEntities = ["Category","Product"] as const;
24
+
25
+ const builder = createCatalogClient({
26
+ entryId,
27
+ cgsHash: catalogCgsHash,
28
+ catalogRoot,
29
+ stubEntities: [...stubEntities],
30
+ });
31
+
32
+ type Brand<B extends string, T> = T & { readonly __brand: B };
33
+ export type CategoryId = Brand<"CategoryId", string>;
34
+ export type RefCategory = CategoryId;
35
+ export type ProductId = Brand<"ProductId", string>;
36
+ export type RefProduct = ProductId;
37
+
38
+ export type Category = {
39
+ id: string;
40
+ name?: string;
41
+ };
42
+
43
+ export type Product = {
44
+ id: string;
45
+ name?: string;
46
+ category_id?: string;
47
+ };
48
+
49
+ export type CategoryGetInput = {
50
+ id: RefCategory;
51
+ };
52
+
53
+ export type ProductGetInput = {
54
+ id: RefProduct;
55
+ };
56
+
57
+ export type ProductSearchInput = {
58
+ q: string;
59
+ };
60
+
61
+ /** category_get */
62
+ export async function category_get(input: CategoryGetInput, options?: StubInvokeOptions): Promise<Category> {
63
+ const program = `e1(${plasmLiteral(input.id)})`;
64
+ const result = await executeRows<Category>(builder, program, options);
65
+ const row = result.rows[0];
66
+ if (!row) throw new Error("category_get: empty result");
67
+ return row;
68
+ }
69
+
70
+ /** product_get */
71
+ export async function product_get(input: ProductGetInput, options?: StubInvokeOptions): Promise<Product> {
72
+ const program = `e2(${plasmLiteral(input.id)})`;
73
+ const result = await executeRows<Product>(builder, program, options);
74
+ const row = result.rows[0];
75
+ if (!row) throw new Error("product_get: empty result");
76
+ return row;
77
+ }
78
+
79
+ /** product_list */
80
+ export async function product_list(options?: StubInvokeOptions): Promise<Product[]> {
81
+ const program = "e2";
82
+ const result = await executeRows<Product>(builder, program, options);
83
+ return result.rows;
84
+ }
85
+
86
+ /** product_search */
87
+ export async function product_search(input: ProductSearchInput, options?: StubInvokeOptions): Promise<Product[]> {
88
+ const program = `e2~${plasmLiteral(input.q)}`;
89
+ const result = await executeRows<Product>(builder, program, options);
90
+ return result.rows;
91
+ }
92
+
93
+ export const execute_tiny = {
94
+ Category: {
95
+ category_get,
96
+ },
97
+ Product: {
98
+ product_get,
99
+ product_list,
100
+ product_search,
101
+ },
102
+ builder,
103
+ catalogCgsHash,
104
+ entryId,
105
+ } as const;
106
+
107
+ export default execute_tiny;
package/agent/agent.ts ADDED
@@ -0,0 +1,52 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+
4
+ import {
5
+ createAgentFromProject,
6
+ defineAgent,
7
+ } from "../src/define-agent.js";
8
+ import {
9
+ createFixtureMockTransport,
10
+ fixtureMockTransportEnabled,
11
+ } from "../src/engine/fixture-mock-transport.js";
12
+ import { createProductionHostTransport } from "../src/engine/create-host-transport.js";
13
+ import { loadAgentEnv } from "../src/load-env.js";
14
+
15
+ loadAgentEnv();
16
+
17
+ const agentRoot = path.dirname(fileURLToPath(import.meta.url));
18
+
19
+ const agentDefinition = defineAgent({
20
+ model: process.env.PLASM_AGENT_MODEL ?? "anthropic/claude-sonnet-4.6",
21
+ compaction: {
22
+ thresholdPercent: 0.75,
23
+ },
24
+ modelOptions: {
25
+ temperature: 0.2,
26
+ },
27
+ experimental: {
28
+ workflow: {
29
+ world: {
30
+ type: "local",
31
+ },
32
+ },
33
+ skills: true,
34
+ },
35
+ build: {
36
+ externalDependencies: ["@plasm_lang/engine"],
37
+ },
38
+ });
39
+
40
+ export default agentDefinition;
41
+
42
+ export async function createPlasmAgent() {
43
+ return createAgentFromProject(agentDefinition, {
44
+ agentRoot,
45
+ tenantScope: process.env.PLASM_TENANT_SCOPE ?? "local",
46
+ maxSteps: 20,
47
+ telemetry: process.env.PLASM_AGENT_TELEMETRY !== "0",
48
+ hostTransport: fixtureMockTransportEnabled()
49
+ ? createFixtureMockTransport()
50
+ : createProductionHostTransport(),
51
+ });
52
+ }
@@ -0,0 +1,15 @@
1
+ # Catalogs
2
+
3
+ Author CGS (`domain.yaml`) + CML (`mappings.yaml`) here — the **single source of capability**.
4
+
5
+ v1 layout: one subdirectory per API (`catalogs/<entry_id>/`).
6
+
7
+ For a working example, symlink or copy from the repo-wide catalog tree:
8
+
9
+ ```bash
10
+ ln -s ../../../apis/pokeapi catalogs/pokeapi
11
+ ```
12
+
13
+ Catalogs are **platform-independent data** (not native cdylib plugins). The framework loads YAML/JSON and pins `catalog_cgs_hash` at session open.
14
+
15
+ See `skills/plasm-authoring/` in the plasm-oss root for authoring doctrine.
File without changes
@@ -0,0 +1,59 @@
1
+ import { createFixtureMockTransport } from "../../src/engine/fixture-mock-transport.js";
2
+ import { defineChannel } from "../../src/authoring/define-channel.js";
3
+ import { dryRunProgram } from "../../src/stubs/catalog-client.js";
4
+
5
+ import executeTiny from "../.plasm/stubs/execute_tiny.js";
6
+
7
+ function readJsonBody(req: import("node:http").IncomingMessage): Promise<unknown> {
8
+ return new Promise((resolve, reject) => {
9
+ let body = "";
10
+ req.on("data", (chunk) => {
11
+ body += chunk;
12
+ });
13
+ req.on("end", () => {
14
+ if (!body.trim()) {
15
+ resolve({});
16
+ return;
17
+ }
18
+ try {
19
+ resolve(JSON.parse(body));
20
+ } catch (err) {
21
+ reject(err);
22
+ }
23
+ });
24
+ req.on("error", reject);
25
+ });
26
+ }
27
+
28
+ export default defineChannel({
29
+ name: "execute-tiny-webhook",
30
+ routes: [
31
+ {
32
+ method: "POST",
33
+ path: "/channel/execute-tiny/products",
34
+ handler: async (req, res) => {
35
+ const body = (await readJsonBody(req)) as { dryRun?: boolean };
36
+ const useDryRun = body.dryRun !== false;
37
+
38
+ if (useDryRun) {
39
+ const dry = await dryRunProgram(executeTiny.builder, "e2");
40
+ res.statusCode = 200;
41
+ res.setHeader("content-type", "application/json; charset=utf-8");
42
+ res.end(
43
+ JSON.stringify({
44
+ mode: "dry_run",
45
+ planCommitRef: dry.planCommitRef,
46
+ }),
47
+ );
48
+ return;
49
+ }
50
+
51
+ const mock = createFixtureMockTransport();
52
+ const rows = await executeTiny.Product.product_list({ transport: mock });
53
+ res.statusCode = 200;
54
+ res.setHeader("content-type", "application/json; charset=utf-8");
55
+ res.end(JSON.stringify({ mode: "live", count: rows.length, rows }));
56
+ },
57
+ },
58
+ ],
59
+ });
@@ -0,0 +1,16 @@
1
+ import { defineChannel } from "../../src/authoring/define-channel.js";
2
+
3
+ export default defineChannel({
4
+ name: "health",
5
+ routes: [
6
+ {
7
+ method: "GET",
8
+ path: "/channel/health",
9
+ handler: (_req, res) => {
10
+ res.statusCode = 200;
11
+ res.setHeader("content-type", "application/json; charset=utf-8");
12
+ res.end(JSON.stringify({ status: "ok", channel: "health" }));
13
+ },
14
+ },
15
+ ],
16
+ });
File without changes
@@ -0,0 +1,10 @@
1
+ import { defineHook } from "../../src/authoring/define-hook.js";
2
+
3
+ export default defineHook({
4
+ name: "trace-log",
5
+ on: ["run:complete", "plan:commit"],
6
+ handler: (_ctx, detail) => {
7
+ const event = detail?.planCommitRef ? "plan:commit" : "run:complete";
8
+ console.log(`[plasm:hook:trace-log] ${event}`, detail ?? {});
9
+ },
10
+ });
@@ -0,0 +1,25 @@
1
+ # Catalog-native Plasm agent
2
+
3
+ You operate external APIs through **Plasm catalogs**, not ad-hoc REST tools.
4
+
5
+ ## Tool order
6
+
7
+ 1. **`discover_capabilities`** — when you do not know which `api` / `entity` to use (optional).
8
+ 2. **`plasm_context`** — open or extend a session with `{api, entity}` seeds. Returns **`logical_session_ref`** + teaching TSV (`e#`, `m#`, `p#`, `r#`).
9
+ 3. **`plasm`** — dry-run a Plasm **program** using symbols from the teaching TSV. Returns **`plan_commit_ref`** (`pcN`).
10
+ 4. **`plasm_run`** — live execute the reviewed plan (`pcN` only — never resend the program).
11
+
12
+ ## Session discipline
13
+
14
+ - **One user goal → one stable `intent` string → one `logical_session_ref`.**
15
+ - Do not rotate `intent` per message (e.g. `"msg 3: sort moves"` breaks symbol reuse).
16
+ - Copy symbols from the **left column** of teaching TSV into programs — never invent `e#` / `p#` values.
17
+ - Federated catalogs: use opaque symbols from the table; never bare homonym wire names.
18
+
19
+ ## Programs
20
+
21
+ - Plasm source text, not JSON.
22
+ - Prefer bind → filter/sort/limit → few final roots.
23
+ - Pass `binding.content` to string/message params when row-to-text templates are used.
24
+
25
+ When the user asks a question, discover or extend context as needed, plan with `plasm`, then run with `plasm_run` after the plan looks correct.
File without changes
@@ -0,0 +1,13 @@
1
+ import { defineSchedule } from "../../src/authoring/define-schedule.js";
2
+ import { dryRunProgram } from "../../src/stubs/catalog-client.js";
3
+
4
+ import executeTiny from "../.plasm/stubs/execute_tiny.js";
5
+
6
+ export default defineSchedule({
7
+ name: "ping",
8
+ cron: "*/5 * * * *",
9
+ handler: async () => {
10
+ const dry = await dryRunProgram(executeTiny.builder, "e2");
11
+ console.log(`[plasm:schedule:ping] product_list dry-run ${dry.planCommitRef}`);
12
+ },
13
+ });
File without changes
@@ -0,0 +1,8 @@
1
+ # Plasm authoring
2
+
3
+ Progressive-disclosure skill for catalog-native agents.
4
+
5
+ - Author capability once in `catalogs/<api>/domain.yaml` + `mappings.yaml`.
6
+ - Run `npm run build:stubs` to emit typed clients under `.plasm/stubs/`.
7
+ - Channels and schedules call stubs directly (deterministic program API).
8
+ - The model loop uses `discover_capabilities` → `plasm_context` → `plasm` → `plasm_run`.
File without changes
@@ -0,0 +1,28 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+
4
+ import {
5
+ createAgentFromDefinition,
6
+ defineAgent,
7
+ } from "../../../src/define-agent.js";
8
+
9
+ const agentRoot = path.dirname(fileURLToPath(import.meta.url));
10
+
11
+ const agentDefinition = defineAgent({
12
+ model: process.env.PLASM_AGENT_MODEL ?? "anthropic/claude-sonnet-4.6",
13
+ modelOptions: { temperature: 0.1 },
14
+ experimental: {
15
+ workflow: { world: { type: "local" } },
16
+ },
17
+ });
18
+
19
+ export default agentDefinition;
20
+
21
+ export async function createTinySubagent() {
22
+ return createAgentFromDefinition(agentDefinition, {
23
+ agentRoot,
24
+ tenantScope: process.env.PLASM_TENANT_SCOPE ?? "local",
25
+ maxSteps: 10,
26
+ telemetry: false,
27
+ });
28
+ }
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from "node:child_process";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const packageRoot = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
7
+ const runner = path.join(packageRoot, "scripts", "plasm-node.mjs");
8
+ const cli = path.join(packageRoot, "scripts", "plasm-cli.ts");
9
+
10
+ const child = spawn(
11
+ process.execPath,
12
+ ["--experimental-strip-types", "--experimental-transform-types", runner, cli, ...process.argv.slice(2)],
13
+ { stdio: "inherit", env: process.env },
14
+ );
15
+
16
+ child.on("exit", (code) => {
17
+ process.exit(code ?? 0);
18
+ });
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@plasm_lang/vercel-agent",
3
+ "version": "0.3.63",
4
+ "description": "Catalog-native TypeScript agent framework (Plasm CGS/CML, Vercel AI SDK, Nitro-oriented)",
5
+ "license": "GPL-3.0-or-later",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/PlasmTools/plasm-core.git",
9
+ "directory": "packages/plasm-agent"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public",
13
+ "registry": "https://registry.npmjs.org/"
14
+ },
15
+ "type": "module",
16
+ "exports": {
17
+ ".": "./src/index.ts",
18
+ "./instrumentation": "./src/instrumentation.ts",
19
+ "./operator": "./src/operator/routes.ts",
20
+ "./agent": "./agent/agent.ts"
21
+ },
22
+ "bin": {
23
+ "plasm-agent": "./bin/plasm-agent.mjs"
24
+ },
25
+ "files": [
26
+ "src",
27
+ "bin",
28
+ "scripts/plasm-node.mjs",
29
+ "scripts/resolve-ts-extension.mjs",
30
+ "agent",
31
+ "README.md"
32
+ ],
33
+ "scripts": {
34
+ "typecheck": "tsc --noEmit",
35
+ "plasm-agent": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/plasm-cli.ts",
36
+ "build:engine": "npm run build --prefix ../plasm-engine",
37
+ "build:stubs": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/build-stubs.ts",
38
+ "smoke:tools": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-agent-tools.ts",
39
+ "smoke:async-transport": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-async-transport.ts",
40
+ "smoke:operator": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-operator.ts",
41
+ "smoke:stubs": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-stubs.ts",
42
+ "smoke:stubs:matrix": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-stubs-matrix.ts",
43
+ "eval": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/run-evals.ts",
44
+ "eval:catalog": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/run-catalog-eval.ts",
45
+ "smoke:hot-reload": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-hot-reload.ts",
46
+ "smoke:sessions": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-sessions.ts",
47
+ "smoke:tui-async": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-tui-async.ts",
48
+ "smoke:bootstrap": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-bootstrap-devx.ts",
49
+ "smoke:vercel-handler": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/smoke-vercel-handler.ts",
50
+ "agent": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/run-agent.ts",
51
+ "dev": "node --experimental-strip-types --experimental-transform-types scripts/plasm-node.mjs scripts/dev-server.ts",
52
+ "plasm:dev": "npm run dev"
53
+ },
54
+ "dependencies": {
55
+ "@ai-sdk/otel": "^1.0.0-beta.6",
56
+ "@opentelemetry/api": "^1.9.0",
57
+ "@plasm_lang/engine": "^0.3.63",
58
+ "@vercel/blob": "^0.27.3",
59
+ "@vercel/connect": "^0.2.6",
60
+ "@vercel/kv": "^3.0.0",
61
+ "@workflow/world-postgres": "^4.2.0",
62
+ "ai": "^6.0.0",
63
+ "js-yaml": "^4.1.0",
64
+ "pg": "^8.22.0",
65
+ "workflow": "^4.5.0",
66
+ "zod": "^3.24.0"
67
+ },
68
+ "devDependencies": {
69
+ "@types/js-yaml": "^4.0.9",
70
+ "@types/node": "^25.9.3",
71
+ "@types/pg": "^8.20.0",
72
+ "typescript": "^5.8.2"
73
+ },
74
+ "engines": {
75
+ "node": ">=20"
76
+ }
77
+ }
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import { register } from "node:module";
3
+ import path from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+
6
+ const scriptsDir = path.dirname(fileURLToPath(import.meta.url));
7
+
8
+ register(pathToFileURL(path.join(scriptsDir, "resolve-ts-extension.mjs")));
9
+
10
+ const entry = process.argv[2];
11
+ if (!entry) {
12
+ console.error("usage: plasm-node.mjs <entry.ts> [args...]");
13
+ process.exit(1);
14
+ }
15
+
16
+ // Forward CLI args to the entry script (argv[0]=node, argv[1]=entry path).
17
+ process.argv = [process.argv[0], path.resolve(process.cwd(), entry), ...process.argv.slice(3)];
18
+
19
+ await import(pathToFileURL(path.resolve(process.cwd(), entry)));
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Resolve `.js` import specifiers to sibling `.ts` sources for no-build dev runs.
3
+ */
4
+ export async function resolve(specifier, context, nextResolve) {
5
+ try {
6
+ return await nextResolve(specifier, context);
7
+ } catch (error) {
8
+ if (typeof specifier === "string" && specifier.endsWith(".js")) {
9
+ const tsSpecifier = `${specifier.slice(0, -3)}.ts`;
10
+ try {
11
+ return await nextResolve(tsSpecifier, context);
12
+ } catch {
13
+ // fall through
14
+ }
15
+ }
16
+ throw error;
17
+ }
18
+ }
@@ -0,0 +1,27 @@
1
+ import type { BlobArchiveAdapter, KvArchiveIndexAdapter } from "./types.js";
2
+
3
+ /** Stub Blob adapter for production wiring (Vercel Blob / object_store URL). */
4
+ export class UnimplementedBlobArchiveAdapter implements BlobArchiveAdapter {
5
+ async put(): Promise<void> {
6
+ throw new Error("BlobArchiveAdapter not configured — set PLASM_RUN_ARTIFACTS_URL in prod");
7
+ }
8
+
9
+ async get(): Promise<Uint8Array | null> {
10
+ throw new Error("BlobArchiveAdapter not configured — set PLASM_RUN_ARTIFACTS_URL in prod");
11
+ }
12
+ }
13
+
14
+ /** Stub KV index adapter for production archive listings. */
15
+ export class UnimplementedKvArchiveIndexAdapter implements KvArchiveIndexAdapter {
16
+ async set(): Promise<void> {
17
+ throw new Error("KvArchiveIndexAdapter not configured");
18
+ }
19
+
20
+ async get(): Promise<string | null> {
21
+ throw new Error("KvArchiveIndexAdapter not configured");
22
+ }
23
+
24
+ async list(): Promise<string[]> {
25
+ throw new Error("KvArchiveIndexAdapter not configured");
26
+ }
27
+ }
@@ -0,0 +1,99 @@
1
+ import { LocalRunArchive } from "./local-run-archive.js";
2
+ import { LocalTraceArchive } from "./local-trace-archive.js";
3
+ import { resolveArchivePaths } from "./paths.js";
4
+ import type {
5
+ ArchivePaths,
6
+ PlanArchiveSnapshot,
7
+ RunSnapshot,
8
+ TraceDetail,
9
+ TraceRecord,
10
+ TraceSummary,
11
+ } from "./types.js";
12
+
13
+ export class LocalArchiveStore {
14
+ readonly paths: ArchivePaths;
15
+ readonly traces: LocalTraceArchive;
16
+ readonly runs: LocalRunArchive;
17
+
18
+ constructor(agentRoot: string, paths?: ArchivePaths) {
19
+ this.paths = paths ?? resolveArchivePaths(agentRoot);
20
+ this.traces = new LocalTraceArchive(this.paths.traceRoot);
21
+ this.runs = new LocalRunArchive(this.paths.runRoot);
22
+ }
23
+
24
+ static fromAgentRoot(agentRoot: string, tenantId?: string): LocalArchiveStore {
25
+ void tenantId;
26
+ return new LocalArchiveStore(agentRoot);
27
+ }
28
+
29
+ async bootstrap(): Promise<void> {
30
+ await Promise.all([this.traces.ensureRoot(), this.runs.ensureRoot()]);
31
+ }
32
+
33
+ async recordToolEvent(
34
+ tenantId: string,
35
+ traceId: string,
36
+ kind: string,
37
+ name: string,
38
+ attributes?: Record<string, string | number | boolean>,
39
+ ): Promise<void> {
40
+ const record: TraceRecord = {
41
+ at_ms: Date.now(),
42
+ kind,
43
+ name,
44
+ attributes,
45
+ };
46
+ await this.traces.appendRecord(tenantId, traceId, record);
47
+ }
48
+
49
+ async finalizeTrace(detail: TraceDetail): Promise<void> {
50
+ await this.traces.persistTrace(detail);
51
+ }
52
+
53
+ async writePlanArchive(snapshot: PlanArchiveSnapshot): Promise<void> {
54
+ await this.runs.writePlanArchive(snapshot);
55
+ }
56
+
57
+ async writeRunSnapshot(snapshot: RunSnapshot): Promise<void> {
58
+ await this.runs.writeRunSnapshot(snapshot);
59
+ }
60
+
61
+ async listTraces(tenantId: string, limit?: number): Promise<TraceSummary[]> {
62
+ return this.traces.listTraces(tenantId, limit);
63
+ }
64
+
65
+ async getTrace(tenantId: string, traceId: string): Promise<TraceDetail | null> {
66
+ return this.traces.getTrace(tenantId, traceId);
67
+ }
68
+
69
+ async listPlans(limit?: number) {
70
+ return this.runs.listPlans(limit);
71
+ }
72
+
73
+ async listRuns(limit?: number) {
74
+ return this.runs.listRuns(limit);
75
+ }
76
+
77
+ async listArchives(limit?: number) {
78
+ const [plans, runs] = await Promise.all([this.listPlans(limit), this.listRuns(limit)]);
79
+ return { plans, runs, paths: this.paths };
80
+ }
81
+ }
82
+
83
+ export { resolveArchivePaths } from "./paths.js";
84
+ export { computeRunId } from "./run-id.js";
85
+ export type { RunIdBundle } from "./run-id.js";
86
+ export {
87
+ UnimplementedBlobArchiveAdapter,
88
+ UnimplementedKvArchiveIndexAdapter,
89
+ } from "./adapters.js";
90
+ export type {
91
+ ArchivePaths,
92
+ BlobArchiveAdapter,
93
+ KvArchiveIndexAdapter,
94
+ PlanArchiveSnapshot,
95
+ RunSnapshot,
96
+ TraceDetail,
97
+ TraceRecord,
98
+ TraceSummary,
99
+ } from "./types.js";