# @keystrokehq/core

The public authoring SDK for Keystroke primitives.

`@keystrokehq/core` is intentionally centered on things workflow authors instantiate, companion types for those primitives, primitive-owned manifest schemas, and `toManifest()`. Build, deploy, project config, testing, execution dispatch, and integration authoring subsystems are owned by other packages.

## Root Authoring Surface

Import primitives from the package root when writing workflows, agents, tasks, operations, credential sets, sandboxes, MCP servers, messaging gateways, and triggers:

- `Agent`
- `CredentialSet`
- `McpServer`
- `MessagingGateway`
- `Operation`, `Step`, `Tool`
- `Sandbox`
- `Task`
- `Workflow`
- `cronTrigger`, `pollingTrigger`, `webhookTrigger`

The root also exposes a small set of companion types that appear in portable inferred return types:

- `BoundTrigger`
- `CallableTrigger`
- `TriggerManifest`
- `TriggerBindOptions`
- `WebhookRequest`
- `PollingContext`
- `OperationConfig`

Everything else should come from a focused primitive subpath.

## Workflow Authoring Rules

- `Operation`, `Step`, and `Tool` are aliases. Use the name that matches the authoring context.
- Workflow bodies are replayed. Keep workflow-local code deterministic and put side effects behind execution boundaries.
- Treat `step.run`, `operation.run`, `childWorkflow.run`, and `agent.run` as execution boundaries.
- Do not nest step execution inside another step. Compose steps at the workflow level.
- Use one exported primitive per typed authoring file: `*.workflow.ts`, `*.agent.ts`, `*.step.ts`, `*.tool.ts`, `*.operation.ts`, `*.trigger.ts`, `*.credential-set.ts`, or `*.mcp-server.ts`.

## Primitive Subpaths

Use subpaths for companion types, primitive-owned manifest schemas, and explicit granular imports:

- `@keystrokehq/core/agent`
- `@keystrokehq/core/credential-set`
- `@keystrokehq/core/errors`
- `@keystrokehq/core/mcp-server`
- `@keystrokehq/core/messaging-gateway`
- `@keystrokehq/core/operation`
- `@keystrokehq/core/sandbox`
- `@keystrokehq/core/task`
- `@keystrokehq/core/trigger`
- `@keystrokehq/core/workflow`

`@keystrokehq/core/workflow` owns the `Workflow` companion contract:

- `Workflow`
- `WorkflowConfig`
- `WorkflowRun`
- `WorkflowRunContext`
- `WorkflowRunOptions`
- `WorkflowRuntime`
- `WorkflowManifest`
- `WorkflowManifestSchema`
- `Hook`

`WorkflowManifest` means the primitive-owned manifest returned by `workflow.toManifest()`. It is not the build-enriched workflow artifact.

## Manifest Ownership

Every primitive owns the manifest it can produce from its constructor-time definition:

```ts
const manifest = workflow.toManifest();
```

`Workflow.toManifest()` stays in core and returns the primitive-owned `WorkflowManifest`: workflow identity, declared schemas, trigger bindings, timeout metadata, and other data the `Workflow` instance knows about itself.

The build pipeline owns the enriched artifact as `WorkflowBuildManifest` in `@keystrokehq/workflow-build-contracts`. That artifact includes build-only data such as discovered steps, dependencies, credential requirements, source analysis, bundle metadata, and flow graph output.

## Removed Boundary Escape Hatches

Core no longer exposes compatibility subpaths for project config, build, testing, generic utility, or provider registry ownership. `@keystrokehq/config` is the public authoring package for `keystroke.config.ts`; do not add compatibility re-exports for old paths such as `@keystrokehq/core/config`, `@keystrokehq/core/utils`, `@keystrokehq/core/flow-graph-toolkit`, `@keystrokehq/core/test-runtime`, or `@keystrokehq/core/vitest`.

Integration package operation factories are owned by `@keystrokehq/integration-authoring`, not core. Builder-only flow enrichment helpers are owned by `@keystroke/workflow-builder`.

## Runtime Ownership

`@keystrokehq/core` does not expose platform runtime registries. Hosted-action dispatch is owned by `@keystroke/workflow-executor/internal/hosted-actions`, and official operation metadata registration/lookup is owned by `@keystrokehq/integration-authoring/official/runtime` for current first-party integrations.

The only runtime-facing core subpaths are primitive-scoped hooks used by the Keystroke test/runtime harness:

- `@keystrokehq/core/operation/runtime`
- `@keystrokehq/core/workflow/runtime`

## Companion Utility Placement

`@keystrokehq/core/trigger` is a first-class primitive companion subpath. Trigger factories, trigger classes, manifest types, `Schedule`, and `Duration` live there because they are part of the authored trigger contract.

Cross-cutting helpers are not exposed through a public `core/utils` grab bag. Schema helper aliases stay package-private unless a primitive subpath needs them for its own companion types, and error-normalizing helpers live on `@keystrokehq/core/errors`.

## Authoring Example

```ts
import { Step, Workflow } from '@keystrokehq/core';
import { z } from 'zod';

const createUser = new Step({
  id: 'create-user',
  name: 'Create User',
  description: 'Creates a user record from an email address.',
  input: z.object({
    email: z.email(),
  }),
  output: z.object({
    id: z.string(),
  }),
  run: async (input) => ({
    id: `user:${input.email}`,
  }),
});

export const signupWorkflow = new Workflow({
  id: 'signup',
  name: 'Signup',
  description: 'Creates a user and returns the new user id.',
  input: z.object({
    email: z.email(),
  }),
  output: z.object({
    userId: z.string(),
  }),
  run: async (input) => {
    const user = await createUser.run({ email: input.email });
    return { userId: user.id };
  },
});
```

## Non-Primitive Surfaces

The following concepts are intentionally outside the final `core` public contract:

- Project config authoring, loading, and validation (`@keystrokehq/config`)
- Workflow source analysis, flow graph extraction, dependency analysis, and build artifact creation (`@keystrokehq/workflow-builder`)
- Workflow execution, replay, scheduling, and runtime context construction (`@keystrokehq/workflow-executor`)
- Integration package authoring helpers (`@keystrokehq/integration-authoring`)
- OAuth connect/refresh lifecycle (platform host: `@keystroke/credentials/resolution`)
- Official provider catalogs and provider-specific metadata
- Test harnesses and Vitest plugin wiring (`@keystrokehq/testing`)

## Testing Authored Code

Use `@keystrokehq/testing` for the Vitest plugin and the workflow / step / tool test helpers.

Outside this package, keep each `*.test.ts` file adjacent to the source file it verifies.
