Skip to content

feat(persona-kit): typed persona.ts authoring that compiles to persona.json#138

Closed
khaliqgant wants to merge 1 commit into
mainfrom
feat/typed-persona-authoring
Closed

feat(persona-kit): typed persona.ts authoring that compiles to persona.json#138
khaliqgant wants to merge 1 commit into
mainfrom
feat/typed-persona-authoring

Conversation

@khaliqgant

@khaliqgant khaliqgant commented May 25, 2026

Copy link
Copy Markdown
Member

What

Lets authors write a typed persona.ts instead of hand-writing persona.json, with full IDE autocomplete — including integration trigger event names.

import { definePersona } from '@agentworkforce/persona-kit';

export default definePersona({
  id: 'review-agent',
  intent: 'review',
  integrations: {
    github: { triggers: [{ on: 'pull_request.opened' }] }, // ← autocompletes
    linear: { triggers: [{ on: 'issue.created' }] },
    // any other provider/event is also valid (see below)
  },
  // ...
});

Then: agentworkforce persona compile examples/review-agent/persona.ts → writes the sibling persona.json.

Trigger typing — not a cap at 5

The on field is typed KnownTriggerName<P> | (string & {}), and the integrations map has a string index signature. That means any provider key and any event string already type-check — the runtime / lintTriggers stay the source of truth (an unknown event is a lint warning, never a type error).

What's typed today is just where autocomplete suggestions exist: the curated KNOWN_TRIGGERS registry, which currently covers the Tier-1 providers (github, linear, slack, notion, jira). The platform supports webhooks across many more integrations — those keys/events are fully usable now, they just don't surface autocomplete yet.

Follow-up (separate PR): codegen KNOWN_TRIGGERS from the canonical adapter event catalogs in relayfile-adapters (~40 providers) so autocomplete covers the full webhook surface and stays in sync. Tracked separately; this PR delivers the typed-authoring mechanism and the curated baseline.

How

  • definePersona() + typed authoring types in packages/persona-kit/src/define.ts (exported from the barrel). Per-provider trigger autocomplete is driven off the KNOWN_TRIGGERS registry.
  • agentworkforce persona compile <persona.ts> (packages/cli/src/persona-compile.ts) esbuild-bundles the file, imports the default export, validates it with parsePersonaSpec, and writes the raw authored spec to a sibling persona.json (raw, not the normalized parse output — preserves parity with hand-authored JSON).
  • persona.json stays the runtime artifact. Loaders (local-personas.ts) and the deploy bundler (bundle.ts, require('./persona.json')) are unchanged — persona.ts is purely an authoring layer that compiles down. esbuild is added to the cli package only; the published persona-kit stays dependency-light.
  • examples/review-agent converted to persona.ts as the demo (regenerated persona.json is semantically identical) and wired into typecheck:examples.

Tests

  • Typed-helper test: the curated providers + an off-registry event + an unknown provider key all type-check and parse.
  • Compiler test: round-trip (bundle → validate → write) plus a validation-failure case.

Verification

pnpm -C packages/persona-kit test (223) · pnpm -C packages/cli test (202) · root pnpm typecheck incl. typecheck:examples — all green.

Implemented by codex-2 and reviewed before merge.

🤖 Generated with Claude Code

…a.json

Add definePersona() + typed authoring types in persona-kit, giving
IDE autocomplete for integration trigger event names across all five
known providers (github, linear, slack, notion, jira) via the existing
KNOWN_TRIGGERS registry. The `KnownTriggerName<P> | (string & {})`
pattern keeps off-registry events and unknown providers valid, so the
runtime stays the source of truth.

Add an `agentworkforce persona compile <persona.ts>` CLI command that
esbuild-bundles the file, imports the default export, validates it with
parsePersonaSpec, and writes the raw authored spec to a sibling
persona.json. persona.json remains the runtime artifact — loaders and
the deploy bundler are unchanged.

Convert examples/review-agent to persona.ts as the demo (regenerated
persona.json is semantically identical) and add tests for the typed
helper and the compiler round-trip.

Implemented by codex-2; reviewed and verified (persona-kit + cli tests,
root typecheck incl. examples) before commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This pull request adds a TypeScript-based persona authoring system and CLI compilation pipeline. It introduces typed contracts for defining personas with handler or interactive modes, a bundler that compiles TypeScript persona definitions to JSON, and an example review-agent persona demonstrating GitHub and Slack integration triggers with Claude model configuration.

Changes

Persona Authoring and Compilation

Layer / File(s) Summary
Persona authoring type system
packages/persona-kit/src/define.ts, packages/persona-kit/src/index.ts
Defines TriggerNameFor, TypedTrigger, TypedIntegrationConfig, and TypedIntegrations for provider-aware trigger configuration. Introduces PersonaDefinitionBase with shared fields, then splits PersonaDefinition into an InteractivePersonaDefinition (requiring harness, model, systemPrompt without onEvent) and HandlerPersonaDefinition (requiring onEvent with optional harness/model/systemPrompt). Exports definePersona identity function to preserve const type inference.
Persona type validation and parsing
packages/persona-kit/src/define.test.ts
Tests that definePersona integrates with parsePersonaSpec for handler personas, verifying parsed id, skill count, input defaults, and integration trigger identifiers. Also validates that interactive personas without onEvent are accepted when harness/model/systemPrompt are provided.
Persona file compilation and bundling
packages/cli/package.json, packages/cli/src/persona-compile.ts
Adds esbuild dependency and implements compilePersonaFile, which resolves and validates input persona paths, bundles TypeScript to temporary .mjs via esbuild with Node externals, dynamically imports the bundled spec, validates default export shape (object with valid string intent), parses persona spec to extract personaId, writes compiled persona.json to output path, and cleans up temp files. Helper functions provide file validation and node_modules path discovery for the bundler.
Compilation tests and CLI command integration
packages/cli/src/persona-compile.test.ts, packages/cli/src/cli.ts
Tests successful compilation with realistic persona fixtures (multiple integrations, off-registry triggers) and validates failure on malformed harnessSettings. Wires persona compile <path> subcommand into CLI main dispatch with -h/--help support, error handling via die(), and success output.
Example review-agent persona definition and output
examples/review-agent/persona.ts, examples/review-agent/persona.json
Defines review-agent persona with intent review, GitHub/Slack integration triggers (PR opened, comment mentions, failed checks, Slack app mentions), workspace-scoped memory, codex harness, gpt-5.4 model, medium reasoning, 1200s timeout, and workspace-write sandbox permissions. Compiled JSON output reformatted with multi-line trigger arrays for readability.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Personas now compile with TypeScript grace,
From define to bundled JSON in their place,
Handler or interactive, types keep them tight,
esbuild weaves them into the night,
A review-agent awaits to be quite right! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding typed persona.ts authoring with compilation support to persona.json.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description clearly details the feature (typed persona.ts authoring), explains the implementation across multiple packages, describes the compilation workflow, and provides verification details.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/typed-persona-authoring

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 10 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/persona-kit/src/define.ts">

<violation number="1" location="packages/persona-kit/src/define.ts:83">
P2: This helper skips excess-property checking, so typos in `persona.ts` can compile and be silently discarded later. Make the authoring surface exact (or require `satisfies` at the call site) so unknown fields fail fast.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

| InteractivePersonaDefinition
| HandlerPersonaDefinition;

export function definePersona<const T extends PersonaDefinition>(input: T): T {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This helper skips excess-property checking, so typos in persona.ts can compile and be silently discarded later. Make the authoring surface exact (or require satisfies at the call site) so unknown fields fail fast.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/persona-kit/src/define.ts, line 83:

<comment>This helper skips excess-property checking, so typos in `persona.ts` can compile and be silently discarded later. Make the authoring surface exact (or require `satisfies` at the call site) so unknown fields fail fast.</comment>

<file context>
@@ -0,0 +1,85 @@
+  | InteractivePersonaDefinition
+  | HandlerPersonaDefinition;
+
+export function definePersona<const T extends PersonaDefinition>(input: T): T {
+  return input;
+}
</file context>

@khaliqgant

Copy link
Copy Markdown
Member Author

Subsumed by #139, which merged as bdec845#139 contained this branch's exact commit (595358d) plus the trigger-catalog consumption, and squash-merged both together. The typed persona.ts authoring is now on main. Closing as redundant.

@khaliqgant khaliqgant closed this May 25, 2026
@khaliqgant khaliqgant deleted the feat/typed-persona-authoring branch May 25, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant