@m4ike1/ion-cue
v0.1.1
Published
Behavior-steering preprocessor: scans user messages for cue directives, scope statements, and marks, then resolves them into prompt injections and harness actions.
Readme
@m4ike1/ion-cue
Behavior-steering preprocessor: scans user messages for cue directives, scope statements, and marks, then resolves them into prompt injections and harness actions.
Install
npm install @m4ike1/ion-cueEntrypoint: @m4ike1/ion-cue → src/index.ts.
Quick start
import { cueDispatcher } from "@m4ike1/ion-cue";
const dispatcher = cueDispatcher({ projectRoot: process.cwd(), skipHome: true });
const result = dispatcher.process("Review {@src/foo.ts} [Review: Technical]");
for (const injection of result.injections) console.log(injection.text);
if (result.error) console.error(result.error);
for (const action of result.harnessActions) console.log(action.handler, action.args);
console.log(result.rewrittenInput);Syntax
| Form | Example | Meaning |
|------|---------|---------|
| Cue directive | [Review: Technical > Brief] | Behavioral steering: element Review, tags Technical, Brief. Max 3 tags. Text stays in the message; behavior is injected alongside. |
| File scope | {@src/foo.ts}, {src/foo.ts:10-20} | Inject file content. Range forms: 10-20, 10-, -20, 10 (single line). @ optional. |
| Glob scope | {@src/*.ts} | Inject every match, one --- path --- block per file. |
| Directory scope | {@src/} | Injects the directory's absolute path only. |
| Mark definition | own-line {#id} + content lines | Defines a reusable content block; content is stripped from the message and injected as --- #id ---\n<content>. |
| Mark reference | {#id} (own-line header with no content, or inline) | Injects the matching mark's content. Errors if undefined. |
| Skill reference | {$name} | Passed through; expanded by agent-session, not cue. |
| System command | :quit arg (first line starts with :) | Short-circuits: returns a harness::quit harness action, no injections. |
| Alias | /quick (first line starts with /) | Expanded from cue.toml [aliases] or DispatcherOptions.aliases before scanning. Unknown aliases are ignored. |
Directives inside fenced code blocks (```, ~~~) and inline `code` are not scanned. Mark content blocks are also excluded from scanning.
Pipeline
process(input) runs: alias expansion → collectMarks → scanDirectives (with mark spans excluded) → system-nav short-circuit → element resolution (resolveDirective) → buildAdditionalContext / buildScopeInjection → position-ordered, content-deduped injections + rewrittenInput.
- Unknown elements are errors (
Element 'X' not defined), except known harness names (theme), which route as harness actions. class: "harness"elements route as harness actions (element.handler), never injections.- Duplicate marks and undefined mark references are errors. Missing files / empty globs inject
[warning: ...]markers instead of failing. - Identical directives coalesce; same element with distinct tag chains resolves independently.
refresh(disabledElements?)re-runs discovery and reloads aliases without restart.
Element layout
Elements are discovered from ~/.ion/agent/cue/elements/ (user scope, unless skipHome) and <projectRoot>/.ion/cue/elements/ (project scope), plus additionalRoots. Each element is a <name>.toml + <name>.md pair, optionally nested under an author directory. Shared tag bodies live in sibling tags/*.md and are used via [[uses]] fallback.
name = "Review"
description = "Review code"
version = "1.0.0"
class = "model" # or "harness" (requires handler)
[tags.technical]
description = "Technical review"
overrides = ["tone"]
exclusive = false # when true, suppresses the Default Behavior section## Default Behavior
Review the code thoroughly.
## Tag: Technical
Focus on technical correctness.Aliases live in cue.toml next to the elements roots:
[aliases]
quick = "[Review: Technical]"Docs
- Reference — full API of every exported symbol.
- How-to — setup and common tasks.
- Explanation — why cues, scopes, and marks are separate.
License
MIT
