apps 1.0.0-beta.1 → 1.0.0-beta.3

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 (48) hide show
  1. package/README.md +3 -2
  2. package/dist/authoring/index.d.ts +222 -34
  3. package/dist/authoring/index.js +11 -1
  4. package/dist/{chunk-NFLNA2SC.js → chunk-4OZFMCTT.js} +7 -1
  5. package/dist/{chunk-LWKQDDLZ.js → chunk-A3H32P2J.js} +46 -1
  6. package/dist/chunk-F7GZYEAC.js +41 -0
  7. package/dist/chunk-MUFMJRXR.js +308 -0
  8. package/dist/chunk-S5KFP4JQ.js +20 -0
  9. package/dist/chunk-Y6LLTN7W.js +99 -0
  10. package/dist/chunk-YUZ4TXOY.js +27 -0
  11. package/dist/http/index.d.ts +9 -0
  12. package/dist/http/index.js +6 -0
  13. package/dist/index.d.ts +3 -8
  14. package/dist/index.js +23 -1
  15. package/dist/manifest/contract.d.ts +8 -0
  16. package/dist/manifest/index.d.ts +8 -6
  17. package/dist/manifest/index.js +3 -3
  18. package/dist/mcp/client.d.ts +9 -0
  19. package/dist/mcp/index.d.ts +11 -0
  20. package/dist/mcp/index.js +7 -0
  21. package/dist/openapi/index.d.ts +14 -0
  22. package/dist/openapi/index.js +7 -0
  23. package/dist/openapi/mapper.d.ts +7 -0
  24. package/dist/runner/index.js +36 -51
  25. package/dist/runner/protocol.d.ts +20 -15
  26. package/dist/runner/protocol.js +5 -3
  27. package/dist/runtime/index.d.ts +83 -0
  28. package/dist/runtime/index.js +12 -0
  29. package/dist/workerd/index.d.ts +7 -2
  30. package/dist/workerd/index.js +7 -3
  31. package/package.json +18 -7
  32. package/src/authoring/index.ts +362 -44
  33. package/src/http/index.ts +26 -0
  34. package/src/index.ts +3 -8
  35. package/src/manifest/contract.ts +9 -0
  36. package/src/manifest/index.ts +89 -157
  37. package/src/mcp/client.ts +59 -0
  38. package/src/mcp/index.ts +42 -0
  39. package/src/openapi/index.ts +70 -0
  40. package/src/openapi/mapper.ts +25 -0
  41. package/src/runner/index.ts +50 -87
  42. package/src/runner/protocol.ts +34 -21
  43. package/src/runtime/index.ts +550 -0
  44. package/src/workerd/index.ts +17 -2
  45. package/dist/chunk-J5AVXTHA.js +0 -154
  46. package/dist/chunk-RZA7AXBK.js +0 -107
  47. package/dist/manifest/collect.d.ts +0 -64
  48. package/src/manifest/collect.ts +0 -198
@@ -1,39 +1,19 @@
1
1
  import {
2
2
  loadApp
3
- } from "../chunk-J5AVXTHA.js";
4
- import "../chunk-LWKQDDLZ.js";
3
+ } from "../chunk-Y6LLTN7W.js";
4
+ import {
5
+ callTool,
6
+ discoverTool
7
+ } from "../chunk-MUFMJRXR.js";
5
8
  import "../chunk-B7NEUIJL.js";
6
9
  import {
7
- CallError
8
- } from "../chunk-NFLNA2SC.js";
9
- import "../chunk-RZA7AXBK.js";
10
+ CallError,
11
+ DiscoverError
12
+ } from "../chunk-4OZFMCTT.js";
13
+ import "../chunk-A3H32P2J.js";
10
14
 
11
15
  // src/runner/index.ts
12
16
  import { Effect } from "effect";
13
- var hasStandardValidate = (input) => "~standard" in input && typeof input["~standard"].validate === "function";
14
- var parseInput = (name, spec, input) => {
15
- if (!hasStandardValidate(spec.input))
16
- return Effect.fail(
17
- new CallError({ target: name, reason: "input schema does not implement Standard Schema validate" })
18
- );
19
- const standard = spec.input["~standard"];
20
- return Effect.tryPromise({
21
- try: () => Promise.resolve(standard.validate(input)),
22
- catch: (error) => new CallError({
23
- target: name,
24
- reason: `input validation threw (${error instanceof Error ? error.message : String(error)})`
25
- })
26
- }).pipe(
27
- Effect.flatMap(
28
- (result) => result.issues === void 0 ? Effect.succeed(result.value) : Effect.fail(
29
- new CallError({
30
- target: name,
31
- reason: `invalid input (${result.issues.map((issue) => issue.message).join("; ")})`
32
- })
33
- )
34
- )
35
- );
36
- };
37
17
  var localRunner = (appDir) => {
38
18
  let cachedLoad;
39
19
  const loaded = () => Effect.suspend(() => {
@@ -46,36 +26,41 @@ var localRunner = (appDir) => {
46
26
  }).pipe(Effect.flatten)
47
27
  );
48
28
  });
49
- const loadedFor = (target) => loaded().pipe(
29
+ const registryFor = (target) => loaded().pipe(
30
+ Effect.map(({ registry }) => registry),
50
31
  Effect.mapError(
51
- (error) => new CallError({ target, reason: `app failed to load (${error.message})` })
32
+ (error) => new CallError({
33
+ target,
34
+ kind: "handler",
35
+ reason: `app failed to load (${error.message})`
36
+ })
52
37
  )
53
38
  );
39
+ const settle = (target, outcome) => outcome.ok ? Effect.succeed(outcome.value) : Effect.fail(new CallError({
40
+ target,
41
+ kind: outcome.kind,
42
+ reason: outcome.reason
43
+ }));
44
+ const settleDiscovery = (segment, outcome) => outcome.ok ? Effect.succeed(outcome.value) : Effect.fail(new DiscoverError({ segment, reason: outcome.reason }));
54
45
  return {
55
46
  manifest: () => Effect.map(loaded(), ({ result }) => result),
56
- call: (name, input, ctx) => Effect.gen(function* () {
57
- const { registry } = yield* loadedFor(name);
58
- const registered = registry.tools.get(name);
59
- if (registered === void 0)
60
- return yield* new CallError({ target: name, reason: "unknown tool" });
61
- const parsed = yield* parseInput(name, registered.spec, input);
62
- return yield* Effect.tryPromise({
63
- // SAFETY: ToolSpec intentionally erases authored handler inputs to keep
64
- // authoring generic-free; validation and ToolCtx establish this call boundary.
65
- try: () => registered.spec.handler(
66
- parsed,
67
- ctx
68
- ),
69
- catch: (error) => new CallError({
70
- target: name,
71
- reason: `handler failed (${error instanceof Error ? error.message : String(error)})`
72
- })
73
- });
74
- }),
75
- discover: (name, _binding) => Effect.fail(new CallError({ target: name, reason: "no dynamic tools yet" }))
47
+ call: (address, input, ctx, detail) => registryFor(address).pipe(
48
+ Effect.flatMap(
49
+ (registry) => Effect.promise(() => callTool(registry, address, input, ctx, detail))
50
+ ),
51
+ Effect.flatMap((outcome) => settle(address, outcome))
52
+ ),
53
+ discover: (segment, ctx) => registryFor(segment).pipe(
54
+ Effect.mapError((error) => new DiscoverError({ segment, reason: error.reason })),
55
+ Effect.flatMap(
56
+ (registry) => Effect.promise(() => discoverTool(registry, segment, ctx))
57
+ ),
58
+ Effect.flatMap((outcome) => settleDiscovery(segment, outcome))
59
+ )
76
60
  };
77
61
  };
78
62
  export {
79
63
  CallError,
64
+ DiscoverError,
80
65
  localRunner
81
66
  };
@@ -1,28 +1,33 @@
1
- import { Crypto, type Effect, FileSystem } from "effect";
1
+ import { type Effect, FileSystem } from "effect";
2
2
  import type { AppManifestResult, PublishError } from "../manifest/contract";
3
- /** The capability exposed to one tool requirement role. */
4
- export interface ToolCtxEntry {
5
- readonly grant: string;
6
- readonly token?: string;
7
- readonly secrets?: Readonly<Record<string, string>>;
8
- fetch(path: string, init?: RequestInit): Promise<Response>;
9
- }
10
- /** Tool capabilities keyed by requirement role. */
11
- export type ToolCtx = Readonly<Record<string, ToolCtxEntry>>;
3
+ import type { CallFailureKind, DiscoveredTool, ToolCtx } from "../runtime/index";
4
+ export type { DiscoveredTool, ToolCtx, ToolCtxEntry, ToolDescriptor, } from "../runtime/index";
5
+ /** Which invocation phase failed. */
6
+ export type CallErrorKind = CallFailureKind;
12
7
  declare const CallError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
13
8
  readonly _tag: "CallError";
14
9
  } & Readonly<A>;
15
- /** A runner operation failure associated with its target. */
10
+ /** A runner operation failure associated with its target and phase. */
16
11
  export declare class CallError extends CallError_base<{
17
12
  readonly target: string;
13
+ readonly kind: CallErrorKind;
14
+ readonly reason: string;
15
+ }> {
16
+ get message(): string;
17
+ }
18
+ declare const DiscoverError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
19
+ readonly _tag: "DiscoverError";
20
+ } & Readonly<A>;
21
+ /** A discovery failure associated with one dynamic segment. */
22
+ export declare class DiscoverError extends DiscoverError_base<{
23
+ readonly segment: string;
18
24
  readonly reason: string;
19
25
  }> {
20
26
  get message(): string;
21
27
  }
22
28
  /** The platform protocol implemented by an app execution environment. */
23
29
  export interface AppRunner {
24
- manifest(): Effect.Effect<AppManifestResult, PublishError, Crypto.Crypto | FileSystem.FileSystem>;
25
- call(name: string, input: unknown, ctx: ToolCtx): Effect.Effect<unknown, CallError, Crypto.Crypto | FileSystem.FileSystem>;
26
- discover(name: string, binding: unknown): Effect.Effect<unknown, CallError, Crypto.Crypto | FileSystem.FileSystem>;
30
+ manifest(): Effect.Effect<AppManifestResult, PublishError, FileSystem.FileSystem>;
31
+ call(address: string, input: unknown, ctx: ToolCtx, detail?: unknown): Effect.Effect<unknown, CallError, FileSystem.FileSystem>;
32
+ discover(segment: string, ctx: ToolCtx): Effect.Effect<readonly DiscoveredTool[], DiscoverError, FileSystem.FileSystem>;
27
33
  }
28
- export {};
@@ -1,6 +1,8 @@
1
1
  import {
2
- CallError
3
- } from "../chunk-NFLNA2SC.js";
2
+ CallError,
3
+ DiscoverError
4
+ } from "../chunk-4OZFMCTT.js";
4
5
  export {
5
- CallError
6
+ CallError,
7
+ DiscoverError
6
8
  };
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The execution core: everything that happens after authored modules
3
+ * load, in any environment. Project a registry into its deterministic
4
+ * manifest, validate a call's input, run the handler, shape the
5
+ * outcome. There is exactly one implementation of this logic; the
6
+ * local runner and the sandboxed workerd guest are both thin doors
7
+ * onto this module.
8
+ *
9
+ * Deliberately dependency-free (no effect, no node builtins): this
10
+ * module bundles into sandboxed guests, where every dependency is
11
+ * paid on each cold start. Digesting uses WebCrypto, which node, bun,
12
+ * and workerd all provide.
13
+ */
14
+ import type { Registry } from "../authoring/index";
15
+ import type { AppManifestResult, JsonSchemaObject } from "../manifest/contract";
16
+ /** The capability exposed to one tool requirement role. */
17
+ export interface ToolCtxEntry {
18
+ readonly grant: string;
19
+ readonly kind: "bearer" | "basic" | "secrets" | "oauth";
20
+ readonly token?: string;
21
+ readonly username?: string;
22
+ readonly password?: string;
23
+ readonly secrets?: Readonly<Record<string, string>>;
24
+ fetch(path: string, init?: RequestInit): Promise<Response>;
25
+ }
26
+ /** Tool capabilities keyed by requirement role. */
27
+ export type ToolCtx = Readonly<Record<string, ToolCtxEntry>>;
28
+ /** A manifest projection: the app's deterministic description, or why not. */
29
+ export type ManifestOutcome = {
30
+ readonly ok: true;
31
+ readonly result: AppManifestResult;
32
+ } | {
33
+ readonly ok: false;
34
+ readonly problems: readonly string[];
35
+ };
36
+ /** Which invocation phase failed. */
37
+ export type CallFailureKind = "input" | "handler";
38
+ /** One tool invocation's result envelope. */
39
+ export type CallOutcome = {
40
+ readonly ok: true;
41
+ readonly value: unknown;
42
+ } | {
43
+ readonly ok: false;
44
+ readonly kind: CallFailureKind;
45
+ readonly reason: string;
46
+ };
47
+ /** Agent-facing descriptor compiled from one discovery result. */
48
+ export interface ToolDescriptor {
49
+ readonly description: string;
50
+ readonly inputSchema: JsonSchemaObject;
51
+ readonly annotations: {
52
+ readonly readOnly?: boolean;
53
+ readonly destructive?: boolean;
54
+ };
55
+ }
56
+ /** One tool emitted by a dynamic segment discovery. */
57
+ export interface DiscoveredTool {
58
+ readonly segment: string;
59
+ readonly name: string;
60
+ readonly descriptor: ToolDescriptor;
61
+ readonly detail: unknown;
62
+ }
63
+ /** One dynamic discovery result envelope. */
64
+ export type DiscoverOutcome = {
65
+ readonly ok: true;
66
+ readonly value: readonly DiscoveredTool[];
67
+ } | {
68
+ readonly ok: false;
69
+ readonly reason: string;
70
+ };
71
+ type InputSchemaCompilation = {
72
+ readonly value: JsonSchemaObject;
73
+ } | {
74
+ readonly problem: string;
75
+ };
76
+ export declare const compileInputSchema: (input: object, where: string) => InputSchemaCompilation;
77
+ /** Project a loaded registry into the app's deterministic manifest. */
78
+ export declare const manifestOf: (registry: Registry) => Promise<ManifestOutcome>;
79
+ /** Validate input and run one static or dynamic tool handler. */
80
+ export declare const callTool: (registry: Registry, address: string, input: unknown, ctx: ToolCtx, detail?: unknown) => Promise<CallOutcome>;
81
+ /** Discover and compile one dynamic segment. */
82
+ export declare const discoverTool: (registry: Registry, segment: string, ctx: ToolCtx) => Promise<DiscoverOutcome>;
83
+ export {};
@@ -0,0 +1,12 @@
1
+ import {
2
+ callTool,
3
+ compileInputSchema,
4
+ discoverTool,
5
+ manifestOf
6
+ } from "../chunk-MUFMJRXR.js";
7
+ export {
8
+ callTool,
9
+ compileInputSchema,
10
+ discoverTool,
11
+ manifestOf
12
+ };
@@ -1,2 +1,7 @@
1
- /** Worker-safe registry projection injected into sandboxed app workers. @internal */
2
- export { collectRegistry } from "../manifest/collect";
1
+ /**
2
+ * The execution core re-exported for sandboxed guests. A generated
3
+ * guest module imports the authored files (filling the registry) and
4
+ * exposes these verbs over RPC; the logic itself lives in ../runtime
5
+ * and is identical to what the local runner executes. @internal
6
+ */
7
+ export { callTool, discoverTool, manifestOf, type CallOutcome, type DiscoverOutcome, type DiscoveredTool, type ManifestOutcome, type ToolCtx, type ToolCtxEntry, } from "../runtime/index";
@@ -1,6 +1,10 @@
1
1
  import {
2
- collectRegistry
3
- } from "../chunk-RZA7AXBK.js";
2
+ callTool,
3
+ discoverTool,
4
+ manifestOf
5
+ } from "../chunk-MUFMJRXR.js";
4
6
  export {
5
- collectRegistry
7
+ callTool,
8
+ discoverTool,
9
+ manifestOf
6
10
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apps",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.3",
4
4
  "description": "Author executor apps: declare services, auth, and tools in plain TypeScript; the executor platform runs, validates, and serves them.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -24,6 +24,10 @@
24
24
  "types": "./dist/authoring/index.d.ts",
25
25
  "default": "./dist/authoring/index.js"
26
26
  },
27
+ "./runtime": {
28
+ "types": "./dist/runtime/index.d.ts",
29
+ "default": "./dist/runtime/index.js"
30
+ },
27
31
  "./manifest": {
28
32
  "types": "./dist/manifest/index.d.ts",
29
33
  "default": "./dist/manifest/index.js"
@@ -40,6 +44,18 @@
40
44
  "types": "./dist/runner/protocol.d.ts",
41
45
  "default": "./dist/runner/protocol.js"
42
46
  },
47
+ "./mcp": {
48
+ "types": "./dist/mcp/index.d.ts",
49
+ "default": "./dist/mcp/index.js"
50
+ },
51
+ "./openapi": {
52
+ "types": "./dist/openapi/index.d.ts",
53
+ "default": "./dist/openapi/index.js"
54
+ },
55
+ "./http": {
56
+ "types": "./dist/http/index.d.ts",
57
+ "default": "./dist/http/index.js"
58
+ },
43
59
  "./workerd": {
44
60
  "types": "./dist/workerd/index.d.ts",
45
61
  "default": "./dist/workerd/index.js"
@@ -52,10 +68,5 @@
52
68
  "effect": {
53
69
  "optional": false
54
70
  }
55
- },
56
- "devDependencies": {
57
- "@types/node": "22",
58
- "esbuild": "0.25",
59
- "typescript": "5.9.3"
60
71
  }
61
- }
72
+ }