feat: add protocol runtime validators#315
Merged
rbadillap merged 1 commit intofeat/vision-2026from Mar 12, 2026
Merged
Conversation
a25d8a1 to
fe5f96c
Compare
Runtime type guards for osprotocol types: validateContext, validateAction, validateVerification, validateResult. Zero external dependencies — pure field and type checking. Closes #270 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fe5f96c to
8372bc1
Compare
rbadillap
added a commit
that referenced
this pull request
Mar 19, 2026
* feat: add Vision 2026 workflow section to CLAUDE.md
Enables any new Claude session to automatically find, claim, and
implement vision-2026 issues by following the documented workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: scaffold @syner/osprotocol package (#307)
Foundation package for the agent execution protocol — context, action,
verification lifecycle. Follows monorepo conventions from packages/syner.
Closes #263
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add SKILL.md v2 schema type (#311)
Define SkillManifestV2 extending current SKILL.md fields with
preconditions, effects, verification, inputs, outputs, visibility,
and notFor. All new fields are optional — v1 SKILL.md still valid.
Closes #268
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: scaffold @syner/ops package (#312)
Operational layer package for friction logging, self-development,
and supervisor contracts. Depends on @syner/osprotocol.
Closes #271
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add OspAction core type (#309)
Define OspAction, Precondition, and Effect interfaces with createAction
and checkPreconditions helpers. Actions declare what an agent is about
to do with pre-conditions and expected effects.
Closes #265
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add OspVerification core type (#310)
Define OspVerification, Assertion, and Escalation interfaces with verify
and escalate helpers. Verification checks whether an action produced its
intended effects and supports rollback/escalation on failure.
Closes #266
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add OspContext core type (#308)
Define OspContext and ContextSource interfaces with createContext helper.
Context captures what an agent knows before acting — loaded sources,
missing data, and chain linkage via parentContext.
Closes #264
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add change category types for self-development (#316)
Define ChangeCategory (skill-tweak | new-skill | structural),
MetricThreshold, and ChangeProposal types per DEC-001. These types
govern the self-development loop's proposal system.
Closes #272
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add SKILL.md v2 parser (#314)
Parse SKILL.md files into SkillManifestV2 via gray-matter frontmatter
plus structured markdown sections (Preconditions, Effects, Inputs,
Outputs, I am NOT). Backwards compatible — parses all 62 existing
v1 SKILL.md files without error.
Closes #269
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add OspResult protocol lifecycle type (#313)
Define OspResult<T> — the complete lifecycle of one agent action,
composing context, action, and verification. Includes createResult
helper and chain field for linking handoff sequences.
Closes #267
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add protocol runtime validators (#315)
Runtime type guards for osprotocol types: validateContext, validateAction,
validateVerification, validateResult. Zero external dependencies — pure
field and type checking.
Closes #270
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add supervisor contract types (#317)
Define SupervisorDecision and DecisionCorpus types per DEC-001.
Decisions require reason + reviewer. JSDoc enforces that the
supervisor must be a separate entity from the agent being evaluated.
Closes #273
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: integrate osprotocol manifest into skills loader (#319)
Replace raw frontmatter parsing with parseSkillManifest() from
@syner/osprotocol. Adds manifest: SkillManifestV2 field to Skill type.
Backwards compatible — existing code using Skill unchanged.
Closes #276
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add protocol field to AgentCard (#320)
Add optional protocol field with version and capabilities to AgentCard.
Existing agents without protocol field load unchanged.
Closes #277
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add withSyner() Next.js config wrapper (#321)
Makes any Next.js app a discoverable agent. Reads SKILL.md from project
root via parseSkillManifest(), adds /agent rewrite to /api/agent.
Zero breaking changes to existing config.
Closes #278
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add friction logger (#318)
Log failed OspResults as structured FrictionEvents to .syner/ops/friction.jsonl.
Tracks skillRef, failureType, frequency, and temporal range. Reads existing
log to update frequency counts for recurring failures.
Closes #274
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: session.generate() returns OspResult (#322)
Wrap session generation in osprotocol lifecycle: context, action,
verification. GenerateResult preserved as result.output. All handlers
(Slack, GitHub, Chat API) updated to access result.output.
Also fixes .js import extensions across osprotocol and ops packages
for webpack/Next.js compatibility.
Closes #282
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: wrap skill tool in osprotocol lifecycle (#324)
feat: wrap skill tool invocation in osprotocol lifecycle
Skill tool now returns OspResult with context, action, and verification.
Raw text output available via result.output. Tracks duration and
verification status per skill invocation.
Closes #280
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add createAgentHandler for osprotocol lifecycle (#323)
Request handler that wraps execution in full osprotocol lifecycle:
context → check preconditions → action → execute → verify → result.
Returns 412 with unmet list on precondition failure.
Closes #279
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: optional osprotocol wrapping for sandbox tools (#326)
Tools work as before by default. When osprotocol: true is passed to
createTools(), each tool invocation is wrapped in context → action →
verification lifecycle with duration tracking.
Closes #281
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: make bot discoverable as agent (#327)
Add SKILL.md v2 with preconditions, effects, inputs/outputs, and
visibility. Add /agent route that returns SkillManifestV2 JSON.
Closes #286
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: make dev app discoverable as agent (#328)
Add SKILL.md v2 with preconditions, effects, inputs/outputs, and
visibility. Add /agent route that returns SkillManifestV2 JSON.
Closes #287
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Slack handler v2 with verification logging (#330)
feat: add verification and failure logging to Slack handler
Log verification status, duration, and failed assertions when
session.generate() returns a failed OspResult.
Closes #284
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add verified handoff chain (#329)
Chain of steps producing linked OspResults that break on failure.
Results linked via chain UUID. Failed steps escalate to caller
and halt the chain.
Closes #283
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add friction analyzer (#325)
Groups friction events by skill+failure type and detects recurring
patterns within a configurable time window. Assigns severity levels
and suggests change categories based on frequency thresholds.
Closes #275
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): GitHub handler v2 — osprotocol verification (#331)
feat(bot): add osprotocol verification to GitHub webhook handler
Wraps generateText with context/action/verification lifecycle,
logs OspResult status and duration, warns on failed assertions.
Closes #285
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: wrap session.generate() in OspResult lifecycle (#332)
session.generate() now returns OspResult<GenerateResult> with full
context, action, verification, and duration tracking. GenerateResult
is preserved as result.output. Updated Slack webhook and command
handlers to use result.output.text.
Also fixes osprotocol barrel imports to drop .js extensions for
Next.js transpilePackages compatibility.
Closes #282
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): GET /agent returns public SkillManifestV2 listing (#334)
feat(bot): GET /agent returns public SkillManifestV2 listing (#290)
Enhance agent route to aggregate all public skills from the registry
and return them alongside the bot's own manifest.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: skill visibility control (#292) (#335)
feat: add skill visibility filtering (public/instance/private)
Filter skills by visibility field from SkillManifestV2. Default: instance.
New helpers: getPublicSkills(), getInstanceSkills(), getPrivateSkills(app).
Closes #292
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: candidate generator (#293) (#336)
feat: add candidate generator for self-development loop
Generates typed ChangeProposal from FrictionPattern. Categorizes changes
(skill-tweak/new-skill/structural) and estimates metric thresholds.
Closes #293
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): add /.well-known/agent.json A2A Agent Card (#337)
feat(bot): add /.well-known/agent.json A2A Agent Card (#291)
Dynamic Agent Card endpoint that reads public skills per request.
Compatible with A2A discovery — the instance presents itself as a
single agent with its public skills listed.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add create-syner-agent scaffolding CLI (#338)
feat: add create-syner-agent scaffolding CLI (#289)
Interactive CLI that scaffolds new syner agents with SKILL.md template,
app/agent/route.ts, and next.config.ts with withSyner(). Supports both
interactive prompts and --name/--description/--author flags.
Also adds step 10 to Vision 2026 workflow: manual issue close after PR
merge since `Closes #N` doesn't auto-close on non-default branch targets.
Closes #289
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: decision corpus (#296) (#340)
feat: add decision corpus for supervisor decisions
Persist and query supervisor decisions via JSONL storage.
logDecision(), getCorpus(), findSimilar() for the self-development loop.
Closes #296
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: sandbox evaluator (#294) (#339)
feat: add sandbox evaluator for change proposals
Evaluator logic in packages/ops (not in skill being evaluated).
evaluate(proposal, testCases, runner) returns EvalResult with
regression detection and metric validation.
Closes #294
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): instance-as-agent with getInstanceCard() (#342)
feat(bot): add getInstanceCard() for instance-as-agent (#299)
Centralize instance presentation in lib/instance.ts. The instance
presents as a single agent externally, aggregating public skills
and hiding internals. Refactors /agent and /.well-known/agent.json
routes to use the shared getInstanceCard().
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: /agent listing — public skills array (#343)
feat: GET /agent returns array of public SkillManifestV2 summaries
Replaces bot manifest + embedded skills with a clean JSON array of all
public skill manifests using getPublicSkills() from the skills loader.
Closes #290
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): enforce skill visibility on /agent route (#346)
feat(bot): enforce skill visibility on /agent route (#300)
External requests see only public skills. Internal requests (with
valid x-syner-internal header) see instance + public skills.
Private/instance skills are hidden from external callers.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: supervisor gate (#295) (#345)
* feat: enforce skill visibility on agent route
External requests see only public skills. Internal requests (with
SYNER_INTERNAL_TOKEN) see instance + public skills.
Closes #300
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add supervisor gate for change proposals
Human-in-the-loop approval via Slack. requestApproval() sends proposal +
eval result to syner.bot, returns SupervisorDecision, logs to corpus.
Closes #295
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: cross-instance invocation via invokeRemote() (#347)
feat: add cross-instance invocation via invokeRemote()
Adds packages/ops/src/remote.ts with:
- fetchRemoteAgent(url) — fetches remote agent card and public skills
- invokeRemote(url, input) — full osprotocol lifecycle for remote skill
invocation: fetch agent.json, check skill exists, send task, validate
response, return OspResult
Closes #301
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: verified boundary crossing (#302) (#349)
feat: add verified boundary crossing for remote results
validateRemoteResult() performs local verification of remote OspResult:
structural validation, context/action/verification integrity, cross-check
assertions against declared effects, and duration sanity check.
Closes #302
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: verified boundary crossing for remote results (#350)
feat: add verified boundary crossing for remote results
Adds packages/ops/src/boundary.ts with validateRemoteResult() that
locally verifies remote OspResult output. Checks: structural validity,
context/action/verification well-formedness, effects-assertions
consistency, and duration sanity. Never trust remote verification alone.
Closes #302
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: deploy pipeline (#297) (#351)
feat: add deploy pipeline for approved change proposals
deploy(proposal, decision) only proceeds if decision.approved === true.
Writes approved diffs as patch artifacts to .syner/ops/deploys/.
Rejected proposals return deployed: false with reviewer reason.
Closes #297
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: metric tracker (#298) (#353)
feat: add metric tracker for skill performance (#298)
Rolling window tracking with regression detection. Records metric
entries to .syner/ops/metrics.jsonl and compares first vs second
half averages to detect improving/stable/regressing trends.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(create-syner-agent): tsconfig module mismatch (#354)
fix(create-syner-agent): set module to nodenext to match moduleResolution
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(create-syner-skill): Agent Skills spec migration (#416)
feat(create-syner-skill): migrate SKILL.md to Agent Skills spec
Move `agent` inside `metadata` (syner extension), rename `tools` to
`allowed-tools` (spec field name), and update scaffold template +
conventions to match agentskills.io spec.
Closes #408
Closes #409
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): migrate SKILL.md to Agent Skills spec (#417)
feat(bot): migrate SKILL.md to Agent Skills spec format
Move to agentskills.io-compliant frontmatter: top-level name,
description, version, and allowed-tools. Skills listed under
metadata. Preserves syner extensions (preconditions, effects,
inputs, outputs).
Closes #399
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(create-syner-agent): scaffold route to app/api/agent (#418)
fix(create-syner-agent): scaffold route to app/api/agent instead of app/agent
withSyner() rewrites /agent → /api/agent, but the scaffold was generating
the route at app/agent/route.ts — so the rewrite destination had no handler.
Now generates to app/api/agent/route.ts to match the rewrite.
Closes #372
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(create-syner-agent): SKILL.md template Agent Skills spec (#420)
feat(create-syner-agent): SKILL.md template follows Agent Skills spec
Move preconditions, effects, visibility into metadata block. Keep standard
fields (name, description, license, compatibility) at top level per
agentskills.io spec. Add metadata.author: synerops.
Closes #373
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(syner): name validation + cache invalidation (#419)
feat(syner): name validation warning + cache invalidation APIs
Add warning in buildRegistry() when skill manifest.name doesn't match
directory slug (Agent Skills spec compliance). Add invalidateSkillsCache()
and invalidateAgentsCache() to reset singleton caches, allowing next
registry call to rebuild from disk.
Closes #366
Closes #367
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: rename wiki → vaults across codebase (#422)
fix: rename wiki → vaults across agents, skills, and app docs
The app formerly known as "wiki" was renamed to "vaults" but 9 files
still referenced the old name, breaking agent delegation routing and
vault path resolution.
Closes #387
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(syner): VaultStore interface + FileSystemVaultStore (#421)
feat(syner): VaultStore interface + FileSystemVaultStore (#386)
Add CRUD interface for vault storage with local filesystem implementation.
- VaultStore: list, read, write, delete operations
- FileSystemVaultStore: fs/promises-based implementation
- Exported via syner/context subpath
Closes #386
Part of #355
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(create-syner-agent): add POST handler to scaffold (#423)
feat(create-syner-agent): add POST handler to scaffold route
Add POST export using createAgentHandler() from @syner/vercel with agentId
and skillRef from template vars, manifest from getManifest(), and a stub
handler. Also wire up replaceVars for the route template so {{name}} gets
substituted.
Closes #377
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(syner): BlobVaultStore — Vercel Blob CRUD (#424)
feat(syner): BlobVaultStore — Vercel Blob CRUD implementation (#390)
Add BlobVaultStore implementing VaultStore interface for serverless environments.
- Uses @vercel/blob list/put/del for CRUD operations
- Client-side glob filtering via picomatch (Blob only supports prefix)
- @vercel/blob is an optional peer dependency
- No manifest, no sync CLI — direct Blob access
Closes #390
Part of #355
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(vercel): Vault AI tools (#425)
feat(vercel): Vault AI tools — VaultRead, VaultWrite, VaultDelete, VaultList, VaultGlob (#393)
Add 5 AI SDK tools for vault manipulation via tool calls.
Each is a factory function taking a VaultStore instance — no direct
@vercel/blob import in packages/vercel.
- VaultRead: read vault file content
- VaultWrite: write/create vault files
- VaultDelete: delete vault files
- VaultList: list files with content preview
- VaultGlob: list file paths only
Closes #393
Part of #355
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(dev): skill resolution endpoint (#426)
feat(dev): add skill resolution endpoint
POST /api/skills/resolve accepts an intent string and returns the
best-matching skill using keyword overlap scoring. GET returns the
full skill list for discovery. This gives syner.bot's router a way
to resolve user intents to specific skills.
Closes #413
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(osprotocol): rename primitives to clean names (#427)
fix(osprotocol): rename primitives to clean names (#360)
Rename all Osp-prefixed interfaces to clean names:
- OspContext → Context
- OspAction → Action
- OspVerification → Verification
- OspResult → Result
- SkillManifestV2 → SkillManifest
Deprecated type aliases preserved for backwards compatibility.
All internal references updated (helpers, validators, parser).
Closes #360
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ops): rename primitives to clean names (#429)
Rename all exported types to shorter, cleaner names per vision-2026 plan:
- ChangeCategory → Category, ChangeProposal → Proposal, MetricThreshold → Threshold
- DecisionCorpus → Decisions
- FrictionEvent → Friction, FrictionPattern → Pattern
- EvalResult → Evaluation, TestCase → Test, MetricResult → Metric
- RemoteInstanceCard → Instance, RemoteInvokeInput → Invoke
All old names preserved as deprecated aliases with JSDoc. Updated osprotocol
imports to use new names (Result, Context, Verification).
Closes #370
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(syner): Brief type + context types (#430)
feat(syner): Brief type + context types (#388)
Add context resolution types:
- ContextScope: 'none' | 'targeted' | 'app' | 'full'
- ContextRequest: input to resolveContext()
- Brief: output with content, sources, scope, gaps
Types only — no runtime dependencies.
Closes #388
Part of #355
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(syner): rename SkillManifestV2 to SkillManifest (#432)
Replace deprecated SkillManifestV2 import with the canonical
SkillManifest type from @syner/osprotocol.
Closes #368
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(vercel): agent handler onResult hook (#431)
feat(vercel): add onResult hook to agent handler
Add onResult callback to AgentHandlerConfig that fires after each handler
execution (success, failure, or precondition failure). Update osprotocol
imports to use new primitive names (Result, Context, Action, SkillManifest).
Closes #371
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ui): Satori font export + slide types (#380, #381) (#428)
* feat(ui): add Satori font export and slide types (#380, #381)
Add foundation for slide generation in @syner/ui:
- Satori font loaders (loadGeistSans, loadGeistMono) as ArrayBuffer
for OG image generation via next/og ImageResponse
- Core slide type system (Style, Slide, Deck, Template) compatible
with Satori JSX rendering
- New package.json exports: ./fonts/satori, ./slides/types
Closes #380
Closes #381
Ref #355
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ui): use static font files instead of resolving from node_modules
Per @rbadillap review: copy Geist .ttf files to src/fonts/static/
and load from there. No runtime dependency on geist package structure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(syner): resolveContext() (#433)
feat(syner): resolveContext() — context resolution engine
Maps ContextScope to vault content via VaultStore. Supports none/app/targeted/full
scopes with keyword-based relevance filtering and gap detection.
Closes #392
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(osprotocol): parser 3-tier priority for Agent Skills spec (#436)
feat(osprotocol): parser 3-tier priority for Agent Skills spec (#363)
parseSkillManifest now returns ParseResult { skill, warnings }.
Extension fields read from metadata.* (spec), top-level frontmatter (legacy + warning),
or markdown body (tertiary). Standard fields always from top-level per spec.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ui): slide template registry (#382) (#435)
feat(ui): add slide template registry (#382)
Register, retrieve, list, and render slide templates by name.
Exports registerTemplate(), getTemplate(), listTemplates(), renderSlide().
Closes #382
Ref #355
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ops): remote invocation timeout + parentContext (#437)
feat(ops): add timeout and parentContext to invokeRemote
Add InvokeOptions interface with optional timeout (default 30s) and
parentContext. Timeout uses AbortController + setTimeout on the fetch call.
parentContext is passed through to createContext() for chain tracing.
Closes #375
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(osprotocol): Run lifecycle types (#434)
feat(osprotocol): add Run lifecycle types (#361)
Add Run, RunStatus, Progress, Timeout, Retry, Approval types.
createRun helper with defaults, updateRunStatus with strict state machine.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ops): invokeAndVerify() convenience function (#438)
* feat(ops): add timeout and parentContext to invokeRemote
Add InvokeOptions interface with optional timeout (default 30s) and
parentContext. Timeout uses AbortController + setTimeout on the fetch call.
parentContext is passed through to createContext() for chain tracing.
Closes #375
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ops): add invokeAndVerify() convenience function
Combines invokeRemote() + validateRemoteResult() in a single call,
returning both the remote Result and local Verification.
Closes #376
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): add onResult hook to session layer (#439)
Add optional onResult callback to SessionOptions that fires after
generation completes (both success and error paths). Enables
downstream consumers (Slack webhook, /agent route) to react to
results for logging, storage, or follow-up chains.
Closes #400
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(bot): populate Context.loaded with vault sources (#440)
resolveContext() now feeds brief.sources into Context.loaded and
brief.gaps into Context.missing, so consumers can audit what context
informed each generation.
Closes #395
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ui): barrel export for @syner/ui/slides (#384) (#441)
Add index.ts barrel export and ./slides entry in package.json exports.
Consumers can now import types and registry from a single entrypoint.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): add POST handler to /agent route (#442)
Add programmatic agent invocation endpoint. Accepts JSON body with
prompt, creates session with onResult hook, returns Result as JSON.
Enables orchestrator, supervisor gate, and chain steps to invoke
the bot agent via HTTP.
Closes #401
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ops): Approval migration from osprotocol (#445)
feat(ops): migrate supervisor types to osprotocol Approval
Replace SupervisorDecision with osprotocol's Approval type.
Decisions.decisions is now typed as Approval[]. Old names
kept as deprecated aliases for backwards compatibility.
Closes #378
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(design): POST /api/slides/generate (#389) (#444)
* feat(design): POST /api/slides/generate route (#389)
Edge runtime route that renders slides via Satori/next-og and stores
PNGs in Vercel Blob. Accepts { slides, style? } payload, renders each
slide using the @syner/ui template registry, and returns a RenderedDeck
with public Blob URLs.
- Uses @syner/ui/slides/registry for renderSlide()
- Uses @syner/ui/fonts/satori for Geist Sans + Mono (.ttf for Satori)
- Stores images at slides/{deckId}/{index}.png in Vercel Blob
- 1200x630 PNG output per slide
Closes #389
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ui): slide templates — title, metrics, highlights, outlook, custom (#383)
5 built-in Satori-compatible slide templates, each self-registering
via registerTemplate(). Dark theme using brand colors.
- title: Full-screen headline + subtitle
- metrics: Large numbers with labels (Record content)
- highlights: Bullet-point list (string[] content)
- outlook: Forward-looking summary with body text
- custom: Freeform passthrough for all content types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(dev): self-dev type renames (#443)
feat(ops): migrate supervisor types to osprotocol Approval
Replace SupervisorDecision with osprotocol's Approval type.
Decisions.decisions is now typed as Approval[]. Old names
kept as deprecated aliases for backwards compatibility.
Closes #378
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(vaults): Deck Fumadocs collection + OG routes (#448)
Adds Fumadocs content pipeline for decks:
- source.config.ts with decks collection
- /decks/[slug] page route rendering MDX content
- /decks/[slug]/[slide]/og OG image route using @syner/ui template registry
- Example deck MDX in content/decks/
Closes #394
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(dev): automated SKILL.md review gate (#447)
feat(dev): add automated SKILL.md review gate
POST /api/review/skill accepts skill content and validates:
- Frontmatter parsing via parseSkillManifest
- Agent Skills spec compliance (name, description limits)
- Voice check (no first-person)
Returns issues array with pass/fail for CI and orchestrator use.
Also includes ParseResult fixes for loader and agent route
(same as PR #443, needed here since that hasn't merged yet).
Closes #414
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): router + chain dispatch (#446)
feat(bot): add router and chain dispatch
Create apps/bot/lib/router.ts with intent classification (direct,
chain, delegate) and dispatch. Update Slack webhook to route through
classifyAndRoute() instead of direct session creation. Simple
messages still get fast direct responses (backwards compatible).
Closes #404
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): rename osprotocol + ops imports to clean names (#449)
Replace all Osp-prefixed types with clean names across apps/bot/:
- OspResult → Result (session.ts, handoff.ts)
- SkillManifestV2 → SkillManifest (instance.ts)
- Fix instance.ts to use ParseResult from parseSkillManifest()
No Osp-prefixed or V2-suffixed type names remain in apps/bot/.
Closes #406
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): supervisor gate route (#452)
feat(bot): add supervisor gate route
Create /api/supervisor endpoint for approval workflows.
GET returns pending approvals, POST submits decisions
(approved/rejected). Uses Approval type from @syner/osprotocol.
Includes registerApproval() and getApprovalStatus() helpers
for chain step integration.
Closes #402
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(vaults): Deck parser — MDX to Deck objects (#451)
Parses MDX deck files into typed Deck/Slide objects from @syner/ui/slides.
Splits content by --- separators, extracts per-slide frontmatter for
template, heading, subtitle, and style fields.
Closes #396
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(design): GET /api/slides/[deckId]/[index] (#391) (#450)
feat(design): GET /api/slides/[deckId]/[index] serving route (#391)
CDN-cacheable edge route that serves rendered slide PNGs from Vercel
Blob. Returns 404 for non-existent decks, immutable cache headers for
existing slides (new deck = new deckId, slides never mutate).
Closes #391
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(osprotocol): Run and Approval validators (#453)
feat(osprotocol): add Run and Approval validators (#362)
validateRun checks id, status, results, startedAt, plus optional
approval/timeout/retry sub-objects. validateApproval checks required
boolean and optional typed fields.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): Slack interactive actions handler (#455)
feat(bot): add Slack interactive actions handler
Create /api/webhooks/slack/actions endpoint for processing
approval button clicks. Verifies Slack request signature,
routes supervisor_approve/reject actions to /api/supervisor
gate, and updates the original Slack message with the decision.
Closes #403
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(bot): delete handoff.ts (#454)
Remove legacy executeChain() implementation superseded by router
dispatch (#404). Update router.ts to remove handoff import and
use clean type names.
Closes #405
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(dev): monorepo import sweep (#457)
feat(dev): monorepo import sweep — remove all deprecated type names
Sweeps the entire monorepo for stale type references:
- OspResult → Result (packages/vercel)
- SkillManifestV2 → SkillManifest/ParseResult (packages/vercel, create-syner-agent)
- ChangeProposal → Proposal, EvalResult → Evaluation (apps/bot, apps/dev)
- SupervisorDecision → Approval (apps/dev self-dev)
- DecisionCorpus → Decisions (apps/dev corpus)
Introduces SelfDevDecision to bridge Proposal + Approval in the
self-dev pipeline, since osprotocol Approval has different fields
than the old ops SupervisorDecision.
Closes #412
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(osprotocol): heartbeat fields on Run (#462) (#466)
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(syner): resolveSkill() intent-to-skill matching (#459) (#465)
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(github): token cache + readThread (#460, #461) (#467)
* feat(github): token caching with 55min TTL (#460)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(github): readThread() paginated comment reader (#461)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(github): concurrent token dedup + clearTokenCache (#460)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(vercel): add executeSkill() (#464)
* feat(vercel): add executeSkill() for standalone skill invocation
Extract core skill execution logic from createSkillTool() into a standalone
executeSkill(ref, input, options) function that returns OspResult<string>.
This enables the orchestrator and other consumers to invoke skills directly
without wrapping in a Vercel AI SDK tool.
createSkillTool() now delegates to the same internal execution path,
maintaining backward compatibility.
Closes #458
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(vercel): schema compat + abortSignal cleanup (#458)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(monorepo): eliminate packages/create-syner-agent (#484)
fix(monorepo): eliminate packages/create-syner-agent (#468)
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(github): add getIssue, listIssues, removeLabel, closeIssue (#483)
feat(github): add getIssue, listIssues, removeLabel, closeIssue (#471)
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(sdk): rename packages/syner to @syner/sdk (#486)
refactor(sdk): rename packages/syner to @syner/sdk (#469)
- Directory: packages/syner/ → packages/sdk/
- Package name: syner → @syner/sdk
- Updates 19 import sites across apps/bot, apps/dev, packages/vercel
- Updates 3 consumer package.json dependencies
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(bot): model provisioning for executeSkill (#490)
* feat(bot): model provisioning for executeSkill (#474)
Adds resolveModel(agentName) that returns a LanguageModel from AI SDK.
Orchestrator (syner) gets Opus, all other agents get Sonnet.
API key from ANTHROPIC_API_KEY environment variable.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(bot): delete redundant models.ts — use SDK getModel() (#490)
SDK already exports getModel(config: AgentCard) from @syner/sdk/agents.
Bot should import it directly instead of maintaining a parallel copy.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(bot): POST /agent lead-aware routing (#489)
* feat(bot): POST /agent lead-aware routing (#472)
Adds POST /agent endpoint that accepts {agentName, task}, resolves
the agent definition via @syner/sdk, and returns an osprotocol-compatible
response. Separate route from GET /agents (different caching strategy).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(bot): auth + validation + router body schema (#489)
- Add x-vercel-protection-bypass auth (same as GET /agents)
- Validate agentName regex /^[a-z0-9-]+$/ (path traversal prevention)
- Use PROJECT_ROOT env var with cwd fallback
- Fix router.ts: send {agentName, task} not {prompt}
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(sdk): execution bridge — resolve to executeSkill (#488)
* feat(sdk): execution bridge — resolve to executeSkill (#473)
Adds execute() that bridges resolveSkill() + resolveContext() to an
external executor (typically executeSkill from @syner/vercel).
Uses dependency injection (SkillExecutor type) to avoid circular
dependency between sdk and vercel packages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(sdk): generic type parameter + OspResult→Result (#488)
- execute<T>() now accepts generic for type-safe executor options
- SkillExecutor<T> preserves type safety at call site without circular deps
- OspResult replaced with Result (deprecated type)
- resolveContext wrapped in try/catch
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(bot): E2E orchestration loop — POST /agent executes (#492)
* feat(vercel): implement Edit tool for sandbox (#499)
Adds Edit tool following the Write tool pattern — supports exact string
replacement with optional replace_all. Eliminates the `[Tools] Unknown
tool: Edit` warning when agents request edit capabilities.
Closes #495
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: Slack E2E orchestration with lazy sandbox (#494) (#502)
* feat(sdk): add agents, context, and skills modules
Adds the missing SDK source modules that bot depends on:
- agents/: loader with metadata.channel support, model routing via AI Gateway
- context/: vault context resolution
- skills/: skill loading and resolution
- logger.ts, errors.ts: shared utilities
Part of #494
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(vercel): export tool schemas and sandbox-bound execute functions
Exports inputSchema and executeWithSandbox for each tool, enabling
lazy tool initialization — tools can be defined with real schemas
before the sandbox exists.
Part of #494
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(slack): strip bot self-mention from message text
Chat SDK normalizes Slack mentions to @UXXXXX but doesn't remove them.
Clean the bot self-mention before passing to the handler so the router
doesn't misclassify it as a delegate intent.
Part of #494
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(bot): Slack E2E with lazy sandbox and AI Gateway fallbacks
- Webhook route: inline AgentCard type (removes @syner/sdk/agents import)
- Session: lazy sandbox initialization — tools defined with real schemas,
sandbox created only on first tool call. Conversational messages skip
sandbox entirely.
- Router: clean two-phase removed, session handles tool decision
- Tools registry: createLazyToolSession() using real zod schemas and
sandbox-bound execute functions
- AI Gateway: model routing with fallback tiers (opus→sonnet→haiku)
- Env: AI_GATEWAY_API_KEY added
Closes #500, closes #501
Part of #494
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(agents): add channel mapping via metadata convention
Maps agents to Slack channels using metadata.channel:
- syner → C0ALD7U6ALB (#general)
- dev → C0AKAPUAGJF (#dev)
- vaults → C0AKWADSSTW (#notes)
Follows ADR: custom frontmatter fields go under metadata.
Closes #496
Part of #494
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: update lockfile and next-env declarations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR #502 review feedback
- slack: constrain self-mention regex to Slack user ID format (@U...)
- sdk: fix haiku fallback ID (claude-3.5-haiku), add intermediate versions
- bot/route: remove index signature from AgentCard, add missing fields
- bot/registry: clear initPromise on failure to allow retry
- bot/router: add warning log for unimplemented chain intent
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(slack): README.md + AGENTS.md (#531)
* docs(slack): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(slack): correct docs to match source — addresses PR #531 review
- Create AGENTS.md with complete export reference matching all source files
- Add usage examples to README.md with correct function signatures
- sendReply takes (client, channel, threadTs, text), not options object
- Use MentionContext (not SlackMentionContext), threadId is required
- Use SlackSlashCommand (not SlackCommandPayload)
- Include import { after } from 'next/server' in all Next.js examples
- Document all exports: addReaction, removeReaction, type guards, etc.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(slack): correct webhook endpoint URL in README
api/chat-poc → api/webhooks/slack to match actual route.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(slack): rewrite agent definition to describe capabilities (#533)
fix(slack): rewrite agent definition to describe capabilities, not workflow
Remove ticket-assignment workflow and worktree sections (orchestrator's
responsibility, not the agent's). Replace with capabilities organized by
source module and concrete invocation scenarios.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: add agent PR template (#537)
* chore: add agent PR template
Adds specialized template for new agent PRs with agent metadata,
capabilities, invocation scenarios, and agent-specific test plan.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: apply Syner branding to agent PR template
Add logo header, metadata table, and syner/{author} signature.
Consistent look & feel with #520 template.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: apply Syner branding to default PR template (#538)
Add logo header, metadata table, and syner/{author} signature.
Consistent look & feel with #520 template.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: add skill PR template (#536)
* chore: add skill PR template
Adds specialized template for new skill PRs with skill metadata,
trigger conditions, and skill-specific test plan.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: apply Syner branding to skill PR template
Add logo header, metadata table, and syner/{author} signature.
Consistent look & feel with #520 template.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: add fix PR template (#535)
* chore: add fix PR template
Adds specialized template for bug fix PRs with root cause analysis,
fix description, and reproduction steps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: apply Syner branding to fix PR template
Add logo header, metadata table, and syner/{author} signature.
Consistent look & feel with #520 template.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: add feature PR template (#534)
* chore: add feature PR template
Adds specialized template for new feature PRs with motivation,
approach explanation, and breaking changes sections.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: apply Syner branding to feature PR template
Add logo header, metadata table, and syner/{author} signature.
Consistent look & feel with #520 template.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use syner/{author} in PR template headers (#540)
fix: use syner/{author} instead of {title} in PR templates
The logo subtitle identifies WHO is presenting the PR (syner/{component}),
not what the PR does. Aligns with #520 convention.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(code-reviewer): add accuracy standards from lead feedback (#539)
8 patterns where code-reviewer produced false positives or low-value
suggestions, distilled from 10 leads reviewing their own PRs.
Generalist rules — no domain-specific guards yet.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(design): README.md + AGENTS.md (#530)
* docs(design): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(design): address code review feedback on README + AGENTS
- Fix title → heading in slide generation example
- Clarify GET route redirects to Blob URL (not streaming)
- Annotate components/page.tsx as usage example, not canonical spec
-- syner/design
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(dev): README.md + AGENTS.md (#529)
* docs(dev): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(dev): address code review feedback on README + AGENTS
- Fix skill count from 19 to 18 (excludes _find-ideas with _ prefix)
- Fix category casing: "dev" → "Dev" to match SDK source
-- syner/dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(ui): README.md + AGENTS.md (#528)
* docs(ui): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(ui): address code review feedback on README + AGENTS
- Fix install command to workspace pattern
- Clarify font aliases (geistSans is alias for GeistSans)
- Add lucide-react to AGENTS.md Dependencies table
- Fix constraint 6: undefined behavior, not silent failure
- Add theme provider note for dynamic dark mode switching
- Note Radix WAI-ARIA accessibility defaults
-- syner/ui
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(vaults): README.md + AGENTS.md (#527)
* docs(vaults): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(vaults): address code review feedback on AGENTS.md
- Fix channel nesting: move under metadata: to match agents/vaults.md
- Add user-invoked note for vaults-grow-specialist
- Add state file initialization note for fresh machines
-- syner/vaults
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(bot): README.md + AGENTS.md (#526)
* docs(bot): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(bot): address code review feedback — delegate URL bug + docs
- Fix delegate URL: /agent → /api/agent (blocking production bug)
- Note step count difference in README (15 webhook vs 10 createSession)
- Document chain intent silent fallback in AGENTS.md Status table
-- syner/bot
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(ops): README.md + AGENTS.md (#525)
* docs(ops): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(ops): address code review feedback on README + AGENTS
- Correct logFriction frequency description (append-per-call, not in-place update)
- Change "6 checks" to "up to 6 checks" for validateRemoteResult
- Fix install command to workspace pattern
- Note empty-test-suite vacuous truth in evaluate()
- Add unbounded growth warning for friction JSONL
-- syner/ops
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(github): README.md + AGENTS.md (#524)
docs(github): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(vercel): README.md + AGENTS.md (#523)
* docs(vercel): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(vercel): address code review feedback on README + AGENTS
- Fix errors table source: executeEditWithSandbox → createEditTool
- Fix missing-entry string to use em dash matching source
- Rewrite constraint #10 as known limitation (preconditions always met)
- Add default comment to SkillConfig.context
- Document $N 0-based indexing in buildSkillInstructions
- Add createToolsByName pointer in README
-- syner/vercel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(osprotocol): README.md + AGENTS.md (#522)
* docs(osprotocol): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(osprotocol): address code review feedback on README + AGENTS
- Mark reason/timestamp as optional in validateApproval table
- Note verify() vacuous truth with empty effects
- Fix install command to workspace pattern
-- syner/osprotocol
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(sdk): README.md + AGENTS.md (#521)
* docs(sdk): split proposal into README.md + AGENTS.md
Split the dual-audience proposal into developer-facing README.md
and agent-facing AGENTS.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(sdk): address code review feedback on README + AGENTS
- Add anthropic/ prefix to FALLBACK_MODELS values
- Note getPrivateSkills returns [] for apps with no private skills
- Clarify SkillsRegistry is not exported as a type
- Clarify targeted scope query source in constraint #10
- Fix install command to workspace pattern
-- syner/sdk
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: ignore Claude Code runtime artifacts (#542)
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: resolve build errors across monorepo (#544)
fix: resolve build errors across bot, design, vaults, and sdk
- vaults: add createMDX() wrapper for Turbopack MDX support
- design: switch /api/slides/generate from edge to nodejs runtime
- bot: extract registerApproval from route to lib/supervisor.ts
- bot: fix ToolSet type and inputSchema union inference
- bot: move providerOptions from generate() to ToolLoopAgent constructor
- bot: import AgentSandbox from @syner/vercel instead of @vercel/sandbox
- sdk: refactor getModel/getModelFallbacks into resolveModel(tier)
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(osprotocol): rename SkillManifest → Skill (#555) (#576)
* feat(osprotocol): rename SkillManifest → Skill (#555)
Primitives first — the protocol type gets the clean name.
- Rename SkillManifest to Skill in types/skill.ts
- Remove SkillManifestV2 deprecated alias
- Update parser.ts and index.ts internal references
- Consumers update in their own issues
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(osprotocol): align Skill interface with agentskills.io spec
Strip invented fields nobody uses (preconditions, effects, verification,
inputs, outputs, notFor, category, visibility). Align with the official
Agent Skills spec: name, description, license, compatibility, metadata.
metadata is now Record<string, string> — the spec's extension point.
Parser simplified from 143 to 30 lines — no more 3-tier priority
parsing for fields that never existed in any SKILL.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(vercel): remove BlobVaultStore vault tools (local-first) (#577)
Delete vault-{read,write,delete,list,glob}.ts and their exports.
Vaults are filesystem-only — no Blob storage needed.
Closes #558
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(osprotocol): align Run lifecycle with Vercel Workflow spec (#578)
* feat(osprotocol): align Run lifecycle with Vercel Workflow spec
RunStatus 9→6 states, rewrite Approval shape, add Cancel interface,
update validTransitions and validators to match osprotocol.dev spec.
Closes #556
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(osprotocol): migrate validators to zod schemas
Zod schemas become the single source of truth — types are inferred via
z.infer, validators use .safeParse(), and deprecated Osp* aliases are
removed. ~240 lines of manual validation replaced by ~140 lines of
declarative schemas.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(sdk): remove BlobVaultStore (local-first) (#581)
Delete blob-vault-store.ts, clean exports, remove @vercel/blob
and picomatch deps. FileSystemVaultStore is the only vault store.
Closes #560
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(osprotocol,vercel): RunAdapter + VercelRunAdapter (#575) (#582)
feat(osprotocol,vercel): RunAdapter interface + VercelRunAdapter implementation
OSProtocol defines the RunAdapter contract (start, get, cancel, approve)
plus RunRequest and RunEvent types. @syner/vercel implements it as
VercelRunAdapter with adapter helpers for approval tokens, timeout
strategies, retry/backoff, beforeCancel veto, and progress events.
Closes #575
Co-authored-by: Ronny Badilla <info@ronnybadilla.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: wire Workflow + skills architecture prerequisites (#584)
* feat(vercel,sdk): wire Workflow + clean SDK imports
- Install workflow + @workflow/ai in @syner/vercel
- Wire VercelRunAdapter to real workflow/api primitives (start, Run.status, Run.cancel)
- Re-export DurableAgent from @workflow/ai/agent
- Fix SkillManifest → Skill across agent-handler.ts, with-syner.ts
- Fix OspResult → Result in tools/skill.ts
- Fix SDK SkillManifest → Skill as OspSkill in skills/types.ts
- Fix visibility read from manifest.metadata in skills/loader.ts
- Remove BlobVaultStore reference from vault-store.ts comment
Closes #583
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(sdk): unify Skill type — use osprotocol Skill with metadata
Eliminate the SDK's duplicate Skill interface. The osprotocol Skill type
is the standard (agentskills.io compatible). Runtime enrichment fields
(slug, category, visibility, version, author) now live in metadata.
- Remove SDK Skill interface, re-export osprotocol Skill
- SkillContent becomes Skill & { content: string }
- Loader populates metadata with slug, category, visibility
- Update all consumers: skill.slug → skill.name, skill.category → skill.metadata?.category
- Fix SkillManifest → Skill in apps/dev candidate.ts and apps/bot instance.ts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: skills architecture prerequisites (#585, #586, #587, #588, #589)
Pre-Epic 2 skills architecture — LLM-driven routing replaces regex classification.
- sdk: buildSkillsManifest() scans skill dirs, outputs index.json (#585)
- osprotocol: remove RunRequest.tools field (no consumer) (#586)
- vercel: remove createTools/createToolsByName (tools imported standalone) (#586)
- vercel: redesign Skill tool — context injection, not subagent (#587)
- vercel: create Run tool — agent starts durable workflows via RunAdapter (#589)
- bot: delete router.ts regex classifier, LLM decides via tools (#588)
- bot: update Slack handler to use session directly
- bot: add routing guidance to agents/bot.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: rename Run tool → Workflow per #588/#589 feedback
Tool naming convention from @rbadillap: Skill, Agent, Workflow.
- Rename run.ts → workflow.ts
- createRunTool → createWorkflowTool
- CreateRunToolOptions → CreateWorkflowToolOptions
- Update SpecialToolName to include Workflow
- Update bot agent routing table
- Update skip list i…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
validateContext,validateAction,validateVerification,validateResultCloses #270
Test plan
bun run buildpasses🤖 Generated with Claude Code