Skip to content

Latest commit

 

History

History
152 lines (116 loc) · 8.56 KB

File metadata and controls

152 lines (116 loc) · 8.56 KB

Plugin Architecture: Essential Files

A quick map of the opencode authoring plugin's essential files and what they do.

Entry Point

src/index.ts — Plugin entry. Exports CodioAuthoringPlugin async factory. Responsibilities:

  • Loads plugin config from workspace codio-authoring.json
  • Creates agent and tool definitions
  • config hook: sets default_agent = codio-orchestrator, auto-registers AWS Bedrock models, registers /validate-guide slash command
  • chat.message hook: tracks sessionID → agent for prompt injection
  • experimental.chat.system.transform hook: injects orchestrator prompt in serve-mode sessions

Configuration

src/config/index.ts — Config loading. Responsibilities:

  • Loads optional codio-authoring.json from workspace root
  • Parses and validates with zod
  • Provides defaults: defaultModels.primary = 'amazon-bedrock/sonnet-4-6', cheap = 'amazon-bedrock/haiku-4-5'
  • Exports PluginConfig type and loadPluginConfig(directory)

src/config/bedrock-models.ts — AWS Bedrock model mappings. Responsibilities:

  • Defines DEFAULT_BEDROCK_MODELS: sonnet-4-6 → us.anthropic.claude-sonnet-4-6, haiku-4-5 → us.anthropic.claude-haiku-4-5-20251001-v1:0
  • Auto-registered by config hook if user hasn't supplied custom Bedrock models

Agents

src/agents/index.ts — Agent factory. Responsibilities:

  • createAgents(config): builds six agent definitions (orchestrator + five subagents)
  • getAgentConfigs(agentDefs): extracts config for opencode registration
  • Pulls model tier from config; defaults to primary (Sonnet) for most agents

src/agents/orchestrator.ts — Primary orchestrator. Responsibilities:

  • buildOrchestratorPrompt(disabledAgents): XML-tagged prompt with Role, Domain, Agents, Tools, Workflow, Approval Gates, Communication
  • createCodioOrchestratorAgent(model?): factory with mode: 'primary', temperature: 0.1, permission.question: 'allow'

src/agents/{outline-architect,page-author,assessment-author,source-ingester,validator}.ts — Subagents. Each file:

  • Exports factory function with name, description, system prompt
  • Uses amazon-bedrock/sonnet-4-6 or -haiku-4-5 per agent role
  • Defines permissions (read/write/edit/bash/question/webfetch)

src/agents/page-author.ts — Extended with 5 Codio Cardinal Rules in the system prompt:

  1. Freeze code directives — language-correct FREEZE CODE BEGIN/END around scaffold code
  2. Try It buttons — {Try it}(command) on every executable unfrozen code block
  3. Adaptive file instructions — checks layoutConfig.openFiles; uses "Look at" vs "Open" accordingly
  4. No duplicate page title — body must not start with an H1 that repeats the JSON title
  5. Visualizer file references — local file paths only, not URLs

Draft mode now accepts an optional layoutConfig: { openFiles: string[] } input from the orchestrator.

Tools

src/tools/index.ts — Tool aggregation. Responsibilities:

  • create_page: stamped Codio page JSON + markdown body to .guides/content/
  • create_assessment: discriminated union (multiple-choice, code-output-compare, fill-in-the-blanks, parsons-puzzle, llm-based-auto-rubric)
  • validate_guide: structural validation (UUIDs, order arrays, assessment references, taskId consistency)
  • Exports tools: Record<string, unknown> for opencode

src/tools/create-page.ts — Page creation. Responsibilities:

  • Validates input schema (workspace, chapterFolder, pageName, stem, learningObjectives, files)
  • Builds Codio page JSON shape: { type: 'page', contentType: 'markdown', teacherOnly: false, ... }
  • Atomic write via wx flag; kebab-case regex on chapterFolder (path traversal guard)
  • validateFreezeDirectives(markdownBody) — exported helper that checks all fenced code blocks for unmatched FREEZE CODE BEGIN/END pairs and correct language-specific comment prefix (# Python, // JS/Java, -- SQL). Called before write; throws on violation.

src/tools/create-assessment.ts — Assessment creation. Responsibilities:

  • Discriminated union: type-specific validation and handling per assessment type
  • Handles taskId generation, atomic file writes, solution files for auto-rubric
  • Returns taskId, jsonPath, embedLine for orchestrator

src/tools/validate-guide.ts — Structural + quality validator. Responsibilities:

  • Structural checks (error severity): invalid_uuid, orphan_order_stem, broken_assessment_ref, taskid_filename_mismatch, missing_content_dir, freeze_syntax_error, try_it_syntax_error
  • Quality checks (warning severity): double_header, missing_referenced_file
  • Type-agnostic assessment validation via ANY_TASKID_RE
  • Returns findings[] + passed boolean — passed fails only on error-severity findings; warnings surface without blocking

Utilities

src/utils/uuid.ts — UUID generation and validation. Exports:

  • generateUuidV4(): wraps node:crypto.randomUUID
  • isUuidV4(s): validator regex

src/utils/taskid.ts — TaskID generation and parsing. Exports:

  • AssessmentType: 5-entry union (multiple-choice, code-output-compare, fill-in-the-blanks, parsons-puzzle, llm-based-auto-rubric)
  • generateTaskId(type): produces <type>_<randomId>
  • parseTaskIdType(taskId): extracts assessment type
  • ANY_TASKID_RE: type-agnostic regex for validation

src/utils/codio-paths.ts — Codio workspace path resolution. Exports:

  • resolveCodioPaths(directory): returns workspace, guides, content, assessments, secure, materials, pluginDir

Skills

src/skills/ — 12 markdown skills (no code). Two categories:

Workflow skills (6):

  • workflow-new-assignment.md
  • workflow-add-page.md
  • workflow-add-assessment.md
  • workflow-import-source.md
  • workflow-reorder.md
  • workflow-revise-page.md

Reference skills (6):

  • guide-json-shape.md
  • assessment-types.md
  • task-id-format.md
  • page-titles.md
  • learning-objectives.md
  • markdown-conventions.md

Copied to ~/.config/opencode/skills/ by postinstall script.

Plugin Lifecycle

bin/codio-authoring-register.js — Called by npm postinstall. Responsibilities:

  • Writes wrapper at ~/.config/opencode/plugins/codio-authoring.js (re-exports from installed dist/index.js)
  • Copies src/skills/~/.config/opencode/skills/

bin/codio-authoring-unregister.js — Called by npm preuninstall. Responsibilities:

  • Removes wrapper and skills bundled in this package

Tests

All test files are colocated with their subjects (e.g., src/index.test.ts tests src/index.ts). Run via bun test. 127 tests covering:

  • Plugin registration and agent creation
  • Config loading and model defaults
  • Tool execution (page, assessment, validation)
  • Freeze directive validation (matched pairs, correct comment prefix per language)
  • UUID/taskId generation and validation
  • Skill availability and structure
  • Validate-guide quality checks (double_header, freeze_syntax_error, try_it_syntax_error, missing_referenced_file)

Test fixtures for validate-guide live in src/tools/test/fixtures/: valid-guide, broken-uuids, orphan-order, broken-embed, taskid-mismatch, double-header, bad-freeze, bad-try-it, missing-file.

Key Invariants

  • UUIDs: v4, generated per page/assessment, validated but never invented by LLM
  • Flat or single-chapter: guides are either flat (no chapters) or single-chapter only
  • Atomic file writes: all tool outputs use writeFileSync(..., { flag: 'wx' }) to prevent TOCTOU races
  • Type-agnostic assessment validation: validator uses ANY_TASKID_RE to validate all assessment types generically
  • Path traversal guard: create-page.ts validates chapterFolder against kebab-case regex
  • Bearer token + region: AWS Bedrock SDK needs a region even with AWS_BEARER_TOKEN_BEDROCK; users must set AWS_REGION env var
  • Freeze directives: FREEZE CODE BEGIN/END must be paired and use the correct comment prefix for the code block language — enforced by validateFreezeDirectives at write time and by validate_guide at scan time
  • No duplicate H1: page markdown body must not open with an H1 that matches the page title — enforced as a double_header warning in validate_guide
  • Warnings vs. errors: validate_guide passed field is true when there are zero error-severity findings; warning-severity findings (double_header, missing_referenced_file) surface in findings[] but do not fail the gate

Build and Publish

  • Build: bun run build → bundles with esbuild, emits types with tsc
  • Test: bun test → runs all .test.ts files
  • Publish: npm publish --otp=<code> (requires npm login + 2FA)
  • Install: npm install -g @codio-ai/opencode-authoring-agent (postinstall auto-registers)