skillscript-runtime 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,346 +1,283 @@
1
1
  # Skillscript
2
2
 
3
- > A small declarative language for authoring agent workflows.
4
-
5
- **Status: v1 in progress (current release: 0.2.4).** The public API, language syntax, and connector contracts may change before v1.0.0. Expect breakage until then.
6
-
7
- A skillscript is a declarative recipe — a small program with a dependency DAG of named targets, each composed of typed operations. Skills are authored once and executed many times, either by the interpreter (autonomous, cron-fired) or by an agent reading a compiled prompt artifact.
8
-
9
- The runtime is substrate-neutral. Bundled reference connectors back filesystem, SQLite, Ollama, and an MCP scaffold; adapter implementations against other backings (cloud key-value stores, hosted LLMs, vector DBs) live in separate packages that consume the public connector contracts exported here.
10
-
11
- ---
12
-
13
- ## Table of contents
14
-
15
- 1. [Installation](#installation)
16
- 2. [Quickstart: author and run a skill](#quickstart-author-and-run-a-skill)
17
- 3. [CLI reference](#cli-reference)
18
- 4. [Browser dashboard](#browser-dashboard)
19
- 5. [Container deployment](#container-deployment)
20
- 6. [Language overview](#language-overview)
21
- 7. [Connector model](#connector-model)
22
- 8. [External adapters](#external-adapters)
23
- 9. [Library API](#library-api)
24
- 10. [Contributing](#contributing)
25
- 11. [License](#license)
3
+ *A language for agents to write themselves in.*
4
+
5
+ [![npm version](https://img.shields.io/npm/v/skillscript-runtime.svg)](https://www.npmjs.com/package/skillscript-runtime)
6
+ [![tests](https://img.shields.io/badge/tests-600%2F600-green)](#)
7
+ [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
8
+ [![status](https://img.shields.io/badge/status-pre--1.0-orange)](#status)
9
+
10
+ > **TL;DR** — `npm install -g skillscript-runtime`, then `skillfile dashboard`. See [Quickstart](#quickstart).
11
+
12
+ ## Contents
13
+
14
+ - [The problem](#the-problem)
15
+ - [The frame](#the-frame)
16
+ - [Why a new language](#why-a-new-language)
17
+ - [Why not just have the agent write a Skill?](#why-not-just-have-the-agent-write-a-skill)
18
+ - [Three kinds of skill](#three-kinds-of-skill)
19
+ - [Waking agents](#waking-agents)
20
+ - [Local models as tools for the frontier](#local-models-as-tools-for-the-frontier)
21
+ - [What you get](#what-you-get)
22
+ - [The bet](#the-bet)
23
+ - [Quickstart](#quickstart)
24
+ - [Connector model](#connector-model)
25
+ - [CLI](#cli)
26
+ - [MCP server surface](#mcp-server-surface)
27
+ - [Examples](#examples)
28
+ - [Architecture and deep documentation](#architecture-and-deep-documentation)
29
+ - [Status](#status)
30
+ - [Contributing](#contributing)
31
+ - [License](#license)
26
32
 
27
33
  ---
28
34
 
29
- ## Installation
30
-
31
- ### npm (recommended)
35
+ ## The problem
32
36
 
33
- ```sh
34
- npm install -g skillscript-runtime
35
- skillfile --version
36
- ```
37
-
38
- This installs the `skillfile` binary globally. Requires Node.js ≥ 22.5 (the runtime uses `node:sqlite` and other features that landed in 22.5+).
39
-
40
- ### From source
37
+ AI agents are mostly transient. Every routine task is re-derived from prose reasoning. The agent that summarized a thread yesterday will summarize one tomorrow by reasoning from scratch about how to summarize threads, burning frontier inference on a procedure with a known shape, a known output format, and known failure modes.
41
38
 
42
- ```sh
43
- git clone https://github.com/sshwarts/skillscript-runtime.git
44
- cd skillscript-runtime
45
- pnpm install
46
- pnpm run build
47
- node dist/cli.js --help
48
- ```
39
+ The waste compounds in three directions: **cost** (every routine operation runs through the most expensive reasoning layer in the system), **latency** (every operation pays the full inference cost), and **drift** (the same task produces slightly different results each invocation because nothing crystallizes).
49
40
 
50
- The repo uses pnpm for reproducible installs. `pnpm run build` compiles TypeScript to `dist/` and copies dashboard assets into place.
41
+ The deeper problem is that *agents have no substrate to write themselves down in*. Agents are partly defined by what they can do and what they can do is currently held entirely in a soft, transient form of reasoning at inference time. There's no hard form. No place for an agent to crystallize a learned procedure into something cheap to execute, cheap to inspect, and cheap to improve.
51
42
 
52
- ---
43
+ Most agent infrastructure projects today focus on **memory** — episodic recall, retrieval-augmented context, conversation summarization. Those projects answer *"what does the agent know."* They don't answer *"what can the agent do"* in any persistent, executable, inspectable form.
53
44
 
54
- ## Quickstart: author and run a skill
45
+ Skillscript intends to answer the second question.
55
46
 
56
- ```sh
57
- # 1. Scaffold the config tree
58
- skillfile init
47
+ ## The frame
59
48
 
60
- # 2. Inspect the bundled hello example
61
- cat ~/.skillscript/examples/hello.skill.md
49
+ **Agents are code, and skillscript is the language they write themselves in.** Not memory in the recall sense. Not prompt templates. Not configuration. Code, in the strict sense of named, typed, composable, executable artifacts that constitute capability.
62
50
 
63
- # 3. Run it (no Ollama, no MCP, no external state required)
64
- skillfile run examples/hello.skill.md
65
- # → Hello, world!
51
+ A skillscript skill is a declarative recipe, a small program with a dependency DAG of typed operations — that an agent authors once and the runtime fires many times. Where typical agent code is procedural (Python scripts, TypeScript handlers), skillscript is **orchestration-only**: it composes calls into tools, models, and memory stores through swappable connector contracts. Computation lives in tools; coordination lives in skills.
66
52
 
67
- # 4. Override an input
68
- skillfile run hello --input WHO=Scott
69
- # → Hello, Scott!
70
53
  ```
71
-
72
- A minimal `.skill.md` looks like:
73
-
74
- ```skillscript
75
- # Skill: greet
76
- # Status: Draft
54
+ # Skill: hello
55
+ # Status: Approved
56
+ # Description: The canonical first-run example.
77
57
  # Vars: WHO=world
78
58
 
79
59
  greet:
80
60
  ! Hello, $(WHO)!
61
+ ! Welcome to Skillscript.
81
62
 
82
63
  default: greet
83
64
  ```
84
65
 
85
- Save that as `greet.skill.md` and run `skillfile run ./greet.skill.md`. The `!` op emits a message; the dispatcher walks the dependency DAG from `default:` backward.
86
-
87
- Lint as you go:
88
-
89
- ```sh
90
- skillfile lint ./greet.skill.md
91
- ```
66
+ That's a complete, runnable skill. Five lines, no dependencies, no boilerplate. The same shape scales to multi-stage DAGs that classify inputs, dispatch to local models, write to memory, branch on conditions, and orchestrate sub-agents, all in the same declarative grammar.
92
67
 
93
- Compile to a prompt artifact (the form an agent consumes when it dispatches a skill mid-conversation):
68
+ ## Why a new language
94
69
 
95
- ```sh
96
- skillfile compile ./greet.skill.md
97
- # Writes greet.skill.provenance.json sidecar with content hashes
98
- ```
70
+ The obvious alternative is "let the agent write Python." Python is Turing-complete, has mature tooling, and models write it well. For one-shot exploratory work or where computation matters, Python is the right tool, and we're not proposing anyone stop using it for that.
99
71
 
100
- ---
72
+ But agent-authored *persistent* automation has a different shape:
101
73
 
102
- ## CLI reference
74
+ - An **agent** (not a human) writes the code.
75
+ - The code runs **autonomously** — cron-fired, event-triggered — with no human in the loop at execution time.
76
+ - The work is **dispatch-shaped**: call a tool, classify a result, branch, call another tool. Not algorithmic computation.
77
+ - The code needs to be **auditable by humans at human tempo** even though it's authored at agent tempo.
103
78
 
104
- All 13 commands. Run `skillfile <command> --help` for per-command options + examples.
79
+ For this shape, Python's strengths invert into liabilities:
105
80
 
106
- | Command | Purpose |
107
- |---|---|
108
- | `init` | Scaffold `~/.skillscript/` tree + bundled example |
109
- | `run <path\|name>` | Compile + execute a skill end-to-end |
110
- | `compile <path\|name>` | Render the compiled artifact (no execution) |
111
- | `audit <provenance-path>` | Detect recompile-staleness via `.provenance.json` sidecar |
112
- | `lint <path\|name>` | Run static validation, print findings |
113
- | `list` | List available skills in the configured SkillStore |
114
- | `fires <skill>` | List recent trace records for a skill |
115
- | `diagram <path\|name>` | Emit mermaid graph of the skill's control flow |
116
- | `sign <path\|name>` | Content-hash sign the skill source (SHA-256) |
117
- | `verify <path\|name> <hash>` | Verify the skill matches a signature |
118
- | `replay <trace_id>` | Re-run a recorded trace mechanically |
119
- | `health` | Aggregate runtime metrics across all traces |
120
- | `dashboard` | Start the runtime host: scheduler + MCP server + browser dashboard SPA |
121
-
122
- > Trigger registration is handled through the MCP server exposed by `skillfile dashboard` (`register_trigger` / `unregister_trigger` / `list_triggers` tools). The v0.2.0 CLI register-trigger family was removed in v0.2.1 — those commands constructed throwaway in-memory schedulers and never fired.
123
-
124
- Environment variables:
125
-
126
- | Var | Default | Purpose |
127
- |---|---|---|
128
- | `SKILLSCRIPT_HOME` | `~/.skillscript` | Config + data root |
129
- | `OLLAMA_BASE_URL` | `http://localhost:11434` | Ollama endpoint for LocalModel dispatch |
81
+ - **Turing completeness becomes a liability.** An agent-authored script can do anything including things the agent didn't realize were dangerous. `subprocess.run`, arbitrary network calls, file writes. None of these are gated. The blast radius of a buggy agent-authored script is the whole host.
82
+ - **Mature tooling doesn't help when the author isn't human.** Debuggers and REPLs are for human iteration. Agents don't iterate that way.
83
+ - **Direct execution magnifies failure.** When an agent ships a broken Python script to production cron, there's no validation layer. The script fails silently at 3am and the human discovers it the next day.
84
+ - **The package ecosystem becomes an unbounded attack surface.** Agents that can `pip install` anything can install anything including supply-chain-compromised packages. The package ecosystem assumes human review before adoption; agent adoption breaks that assumption.
130
85
 
131
- ---
86
+ Skillscript deliberately constrains expressiveness. It's not Turing complete. It can't `eval`, can't `subprocess`, can't import arbitrary code. **The constraint *is* the safety story** — enforced at the language level, not as an aspiration. In exchange:
132
87
 
133
- ## Browser dashboard
88
+ - **Sandboxed grammar.** The language can only do what configured connectors permit.
89
+ - **Declarative legibility.** Skills are DAGs of typed dispatches. A human reading a skill sees exactly which tools get called, which memory writes happen, which model prompts fire. The same source produces the same audit diagram every time.
90
+ - **Connector-mediated capability.** Skills don't import packages, they invoke connectors, gated artifacts with curated tool surfaces. Python doesn't disappear from the system; it moves out of the agent's hands and into the connector implementations adopters write deliberately. The safety boundary moves to the connector edge.
91
+ - **Static validation before admission.** A skill that fails the linter can't enter the library. Structural issues , missing dependencies, undeclared variables, mutation paths without confirmation gates are caught at authorship time, not at 3am.
92
+ - **Asymmetric cost.** Routine work (classify, dispatch, transform) costs local-model tokens. The frontier model is reserved for the small fraction of work that actually needs frontier judgment.
134
93
 
135
- The runtime ships with a browser dashboard for non-CLI operators. Five views: overview, skills, triggers, connectors, plus a skill detail drilldown. 30-second polling; write paths for status transitions and trigger CRUD. Localhost-only by default — no authentication in v1.
94
+ ## Why not just have the agent write a Skill?
136
95
 
137
- ```sh
138
- skillfile dashboard
139
- # → http://127.0.0.1:7878
140
- ```
96
+ Skills (Anthropic/OpenAI) are the existing convention for giving agents named, reusable capabilities, hand-authored markdown that loads instructions into the model's context. They work, and skillscript is complementary to them, not competing.
141
97
 
142
- Options:
98
+ The problem with hand-authoring is that **both authoring populations produce badly-shaped artifacts when working in prose:**
143
99
 
144
- ```sh
145
- skillfile dashboard --port 8080 # custom port
146
- skillfile dashboard --host 0.0.0.0 # bind all interfaces (container only)
147
- ```
100
+ - **Agents authoring markdown produce artifacts shaped for humans, not agents** — verbose explanations, hedging language, redundant context-setting, prose where structure would do. The result is expensive to load, noisy to parse, and hard to maintain.
101
+ - **Humans authoring markdown produce the opposite failure modes**. Either ultra-terse and missing context, or kitchen-sink comprehensive in ways that bury the actual procedure under hedges and edge cases.
148
102
 
149
- The dashboard talks to the runtime via an MCP server contract (JSON-RPC 2.0 over HTTP at `/rpc`). Real MCP clients (Claude Desktop, Cursor, future tools) can consume the same endpoint — the SPA is one of several possible UIs over the same contract. **Eleven tools** today: `skill_list`, `skill_metadata`, `skill_status` (write), `list_triggers`, `register_trigger` (write), `unregister_trigger` (write), `health_metrics`, `runtime_capabilities`, `lint_skill`, `compile_skill`, `skill_write` (write). The last three (v0.2.3) close the over-the-wire authoring lifecycle — foreign clients can lint → compile → write → status → register_trigger end-to-end without filesystem access.
103
+ Making this a programming problem disciplines both populations into the right shape. The grammar doesn't permit rambling. The compiler emits structure, not prose-pretending-to-be-structure.
150
104
 
151
- ---
105
+ A skillscript skill **compiles** into an artifact of the same shape as a hand-authored Skill — `# Skill: <name>` header, instructional markdown body — and that artifact can be loaded into an agent's context the same way. Skillscript is what you author *in*; the compiled Skill is what runs. Mature deployments use both: Skills as agent-facing capability descriptions, skillscript as the higher-leverage authoring layer underneath.
152
106
 
153
- ## Container deployment
107
+ ## Three kinds of skill
154
108
 
155
- The repo ships a multi-stage Dockerfile + `docker-compose.yml`. The image bundles the runtime, CLI, and dashboard SPA in one Node process.
109
+ Every skillscript skill is one of three shapes, determined by the relationship to a frontier agent:
156
110
 
157
- ```sh
158
- docker compose up --build # default profile: dashboard
159
- # http://127.0.0.1:7878
160
- ```
111
+ | Kind | Output goes to | Use case |
112
+ |---|---|---|
113
+ | **Headless** | a downstream system or human, consumed asynchronously | Cron-fired monitors, batch processors, autonomous workflows |
114
+ | **Augmenting** | a frontier agent's reasoning context, immediately at session start or wake | Session-start briefings, alerts, prepared context |
115
+ | **Template** | a frontier agent's execution loop, as a prompt the agent runs itself | Reusable recipes the agent fetches and follows |
161
116
 
162
- Profiles:
117
+ The kinds compose. A Headless monitor fires on cron, evaluates a condition, and routes into an Augmenting skill that wakes an agent with context, which itself references a Template skill for the agent to execute. See the [Language Reference](https://github.com/sshwarts/skillscript-runtime/blob/main/docs/language-reference.md) §1 for the full taxonomy.
163
118
 
164
- ```sh
165
- docker compose --profile tools run --rm tools lint my-skill.skill.md
166
- docker compose --profile ollama up # adds Ollama for LocalModel
167
- ```
119
+ ### Waking agents
168
120
 
169
- Persistent state (`SKILLSCRIPT_HOME=/data`) mounts as a volume so skills + traces survive restarts. The host port mapping (`127.0.0.1:7878:7878`) keeps the dashboard reachable only from localhost even though the container itself binds `0.0.0.0` internally.
121
+ Augmenting and Template skills don't just write somewhere; they deliver to a frontier agent through `AgentConnector`. The contract is substrate-neutral: a Headless monitor detects a condition, evaluates whether action is warranted, and either resolves silently or calls `AgentConnector.deliver(agent_id, payload)`. The implementation might write a memory the agent reads at next session, post to a chat thread the agent monitors, send a push notification, write to a tmux pane, or invoke a webhook. All the adopter's call.
170
122
 
171
- ### Pulling from a registry
123
+ The runtime ships `NoOpAgentConnector` by default; production deployments wire their own.
172
124
 
173
- Images publish to GitHub Container Registry:
125
+ This is what makes *"Headless monitor → wake agent with context"* a real composition primitive, not just a pattern adopters bolt on. Skills don't know what substrate they're waking into; the substrate doesn't know what skill triggered it. The contract handles the seam.
174
126
 
175
- ```sh
176
- docker pull ghcr.io/sshwarts/skillscript-runtime:latest
177
- # or pin to a specific version
178
- docker pull ghcr.io/sshwarts/skillscript-runtime:v0.2.4
179
- ```
127
+ ### Local models as tools for the frontier
180
128
 
181
- Authentication (`gh auth login` then `gh auth token | docker login ghcr.io -u sshwarts --password-stdin`) is only required for pushes; pulls are public.
129
+ Most agent systems treat local models as *substitutes* for frontier inference. Call them instead of the frontier when latency or cost matters. Skillscript treats them as something different: *delegation targets the frontier orchestrates*. The frontier composes the workflow; each `~` op is the frontier dispatching a bounded sub-task (classify a message, extract a field, judge whether two strings refer to the same thing, summarize a chunk, format a response) to a local model and consuming the result.
182
130
 
183
- ---
131
+ In skillscript, this isn't a separate "local-model interplay" pattern adopters bolt on — it's a *first-class language operation*. `~ prompt="..." model="qwen" -> RESULT` lives next to `$ tool.call args="..." -> RESULT` in the skill body, with the same op-level discipline, the same trace surface, the same lint coverage. Local models become tools the frontier model can wield through skills, on the same footing as MCP tools and memory reads.
184
132
 
185
- ## Language overview
133
+ The cost shape that follows: routine work runs at local-model cost (free at scale, fast, private to the host); the frontier model intervenes only at orchestration boundaries and ambiguous cases. Customer data flowing through `~` ops never reaches an external API. The local-model layer becomes the privacy boundary, not a separate add-on.
186
134
 
187
- A skill is markdown with structured headers and a body of named targets:
135
+ ## What you get
188
136
 
189
- ```skillscript
190
- # Skill: weather-brief
191
- # Status: Approved
192
- # Vars: CITY=Asheville
193
- # Requires: user-var:home_location -> CITY (fallback: Asheville)
194
- # Triggers: cron: */30 * * * *
137
+ **For operators:**
195
138
 
196
- fetch needs:
197
- ~ memory-store.get key="weather:$(CITY|url)" -> CACHED
139
+ - *Cost reduction at scale.* Routine operations stop hitting frontier inference. As the library matures, an increasing fraction of agent work executes on cheaper substrate, with the frontier model invoked only for orchestration and judgment.
140
+ - *Auditability.* Agent behavior becomes inspectable by reading skills, not by trusting agent narration. Renderer, linter, and conformance tests operate on parsed skillscript regardless of where it's stored.
141
+ - *Safety boundaries that scale.* The runtime bounds what skills can do via connector configuration, independent of what the authoring agent's tool surface looks like. Mutating operations require explicit user confirmation as a language primitive — visible to static analysis, not dependent on author discipline.
142
+ - *Behavioral consistency.* Procedures don't drift across invocations because the procedure is stored, not re-derived. When the procedure needs to change, the change is a versioned edit, not a hope that the agent reasons identically next time.
198
143
 
199
- forecast: fetch
200
- if $(CACHED):
201
- $set FORECAST = $(CACHED)
202
- else:
203
- > local-model.complete prompt="Brief weather for $(CITY)" -> FORECAST
204
- ~ memory-store.set key="weather:$(CITY|url)" value=$(FORECAST)
144
+ **For agent capability:**
205
145
 
206
- emit: forecast
207
- ! Weather for $(CITY): $(FORECAST)
146
+ - *Reduced token budget on routine work.* Authoring a skill is a one-time cost paid against an indefinite stream of cheap executions.
147
+ - *Composition over re-derivation.* New tasks built by orchestrating existing skills rather than starting from scratch. Capability accumulates rather than evaporating at the end of each invocation.
208
148
 
209
- default: emit
210
- ```
149
+ ## The bet
211
150
 
212
- Eight typed operations (`!` emit, `?` ask, `??` ask-for-input, `$` set, `~` retrieve, `>` complete, `@` shell, `&` invoke-skill), three control-flow constructs (`if`/`elif`/`else`, `foreach`, `needs:`), and a small set of headers (`# Skill:`, `# Status:`, `# Vars:`, `# Requires:`, `# Triggers:`, `# Output:`, `# Timeout:`, `# OnError:`, `# Type:`).
151
+ Skillscript bets that **the majority of agent-authored automation work is dispatch-shaped, not computation-shaped**. Neither agents nor humans produce well-shaped procedural artifacts when authoring in prose. Both populations need the structural discipline of a programming language to converge on the right shape for the work, the audience that runs it, and the audit tooling that has to operate on it.
213
152
 
214
- **Full canonical reference**: [`docs/language-reference.md`](./docs/language-reference.md) syntax, ops, semantics, lifecycle, connectors, error handling, all 1500+ lines.
153
+ If that bet is wrong, skillscript stays a nice niche tool. If it's right, skillscript becomes a default substrate for agent-fired automation in the same way SQL became the default substrate for data access: declarative, composable, auditable, and outliving any specific runtime underneath it.
215
154
 
216
155
  ---
217
156
 
218
- ## Connector model
219
-
220
- The runtime depends on five pluggable connector contracts:
157
+ ## Quickstart
221
158
 
222
- | Contract | Purpose | Bundled reference impl |
223
- |---|---|---|
224
- | `SkillStore` | Persist + version + filter skills | `FilesystemSkillStore` (filesystem) |
225
- | `MemoryStore` | Cache + query memory data with TTL | `SqliteMemoryStore` (`node:sqlite`) |
226
- | `LocalModel` | Dispatch `>` and `~` ops to a local LLM | `OllamaLocalModel` (HTTP to Ollama) |
227
- | `McpConnector` | Dispatch `$` and `~` ops via MCP tools | `CallbackMcpConnector` (in-process) |
228
- | `AgentConnector` | Deliver to / wake a frontier agent (T7.1) | `NoOpAgentConnector` (warns + discards) |
229
-
230
- Wire your own impls through `Registry`:
231
-
232
- ```typescript
233
- import { Registry } from "skillscript-runtime";
234
- import { MyRedisSkillStore } from "./my-adapter.js";
235
-
236
- const registry = new Registry();
237
- registry.registerSkillStore(new MyRedisSkillStore({ url: "redis://..." }));
238
- registry.registerLocalModel(new OllamaLocalModel());
239
- // ... use with execute() or Scheduler
240
- ```
159
+ ```bash
160
+ # Install
161
+ npm install -g skillscript-runtime
241
162
 
242
- The connector resolution cascade (`# Requires:` → static capability check → runtime dispatch) is described in detail in [`docs/ERD.md`](./docs/ERD.md) §3 and the [language reference](./docs/language-reference.md).
163
+ # Author your first skill
164
+ mkdir -p ./skills && cat > ./skills/hello.skill.md <<'EOF'
165
+ # Skill: hello
166
+ # Status: Approved
167
+ # Vars: WHO=world
243
168
 
244
- ---
169
+ greet:
170
+ ! Hello, $(WHO)!
245
171
 
246
- ## External adapters
172
+ default: greet
173
+ EOF
247
174
 
248
- The connector contracts are exported under `skillscript-runtime/connectors`:
175
+ # Start the runtime + dashboard
176
+ SKILLSCRIPT_HOME=./skills skillfile dashboard --port 7878
249
177
 
250
- ```typescript
251
- import type {
252
- SkillStore, MemoryStore, LocalModel, McpConnector, AgentConnector,
253
- StaticCapabilities, ManifestInfo,
254
- } from "skillscript-runtime/connectors";
178
+ # In another terminal, run the skill
179
+ skillfile run hello
255
180
 
256
- export class MyCloudMemoryStore implements MemoryStore {
257
- staticCapabilities(): StaticCapabilities {
258
- return { connector_type: "memory-store", features: { ttl: true, query: true } };
259
- }
260
- // ... implement get / set / delete / query / snapshot / manifestInfo
261
- }
181
+ # Open the dashboard
182
+ open http://localhost:7878
262
183
  ```
263
184
 
264
- Adapter packages can ship publicly (npm) or privately (internal registries). The runtime treats all adapters identically as long as they conform to the typed contract. The `skillscript-runtime/testing` entry point exports `SkillStoreConformance`, `MemoryStoreConformance`, `LocalModelConformance`, `McpConnectorConformance`, and `AgentConnectorConformance` — drop-in test suites that adapter authors run against their implementation to verify contract conformance before shipping.
185
+ Or via Docker / GHCR:
186
+
187
+ ```bash
188
+ docker run -p 7878:7878 -v $(pwd)/skills:/skills \
189
+ -e SKILLSCRIPT_HOME=/skills \
190
+ ghcr.io/sshwarts/skillscript-runtime:latest
191
+ ```
265
192
 
266
- ### AgentConnector — delivery to frontier agents
193
+ ## Connector model
267
194
 
268
- Augmenting and Template skill outputs (`# Output: prompt-context: <agent>` and `# Output: template: <agent>`) deliver through `AgentConnector.deliver`. The contract surfaces three verbs (`list_agents`, `deliver`, `wake`) plus an optional `agent_status` probe. Substrate examples:
195
+ Skills don't know what they're talking to. Five contracts decouple language from substrate:
269
196
 
270
- | Substrate | `deliver` impl | `wake` impl |
197
+ | Contract | Purpose | Routes |
271
198
  |---|---|---|
272
- | tmux session | `tmux send-keys` to a pane | `tmux send-keys` with wake prompt |
273
- | webhook | POST to `/augment` or `/template` endpoint | POST to `/wake` endpoint |
274
- | file-watch | write to `<path>/augment-<id>.txt` | write to `<path>/wake-<id>.txt` |
275
- | Slack thread | post to monitored thread | post + @mention |
276
- | IPC named pipe | write to delivery pipe | write to wake pipe |
199
+ | `SkillStore` | Skill source persistence | `.skill.md` files (filesystem default) |
200
+ | `MemoryStore` | Retrieval over an external knowledge store | `>` ops |
201
+ | `LocalModel` | Local LLM dispatch (Ollama default) | `~` ops |
202
+ | `McpConnector` | MCP tool invocation | `$` ops |
203
+ | `AgentConnector` | Delivery to a frontier agent | `prompt-context:` and `template:` outputs |
277
204
 
278
- The bundled `NoOpAgentConnector` is the default — it logs a one-line warning and discards the payload, so the runtime starts cleanly when no agent substrate is wired. Production deployments wire a real impl through `Registry.registerAgentConnector()`.
205
+ Wire your own by implementing the interface and registering in `connectors.json`. See [`docs/language-reference.md`](docs/language-reference.md) §10 for full contracts.
279
206
 
207
+ ## CLI
280
208
 
281
- ```typescript
282
- import { describe } from "vitest";
283
- import { SkillStoreConformance } from "skillscript-runtime/testing";
284
- import { MyCloudSkillStore } from "./my-cloud-skill-store.js";
209
+ 13 commands cover the full authoring + ops lifecycle:
285
210
 
286
- describe("MyCloudSkillStore", () => {
287
- SkillStoreConformance(() => new MyCloudSkillStore({ /* fixture config */ }));
288
- });
289
- ```
211
+ | Command | Purpose |
212
+ |---|---|
213
+ | `skillfile compile <path\|name>` | Compile a skill to its rendered artifact |
214
+ | `skillfile audit <path\|name>` | Compile + content-hash check |
215
+ | `skillfile lint <path\|name>` | Tier-1/2/3 lint diagnostics |
216
+ | `skillfile run <path\|name>` | Execute a skill against configured connectors |
217
+ | `skillfile fires <skill>` | Recent fire history with trace IDs |
218
+ | `skillfile diagram <path\|name>` | Mermaid DAG visualization |
219
+ | `skillfile sign <path\|name>` | Generate content-hash signature |
220
+ | `skillfile verify <path\|name> <hash>` | Verify against a known signature |
221
+ | `skillfile replay <trace_id>` | Re-run from a captured trace |
222
+ | `skillfile health` | Aggregate runtime health metrics |
223
+ | `skillfile dashboard [--port N]` | Boot browser dashboard + MCP server |
224
+ | (Trigger management lives in the MCP surface, not the CLI) | |
225
+
226
+ Run `skillfile <command> --help` for per-command flags.
227
+
228
+ ## MCP server surface
229
+
230
+ The runtime exposes 11 tools over MCP (HTTP at `/rpc`) for cold-client authoring + observability:
231
+
232
+ | Category | Tools |
233
+ |---|---|
234
+ | Skill management | `skill_list`, `skill_metadata`, `skill_status`, `skill_write` |
235
+ | Authoring | `lint_skill`, `compile_skill` |
236
+ | Triggers | `list_triggers`, `register_trigger`, `unregister_trigger` |
237
+ | Observability | `health_metrics` |
238
+ | Discovery | `runtime_capabilities` |
290
239
 
291
- ---
240
+ This is the "agent reaches MCP" path — an external agent (Claude, GPT, anything that speaks MCP) can author, validate, and deploy skills entirely over the wire.
292
241
 
293
- ## Library API
242
+ ## Examples
294
243
 
295
- Embedders consume the runtime as a library rather than via CLI:
244
+ Seven curated example skills in [`examples/`](examples/), covering:
296
245
 
297
- ```typescript
298
- import { compile, execute, lint, Registry, Scheduler } from "skillscript-runtime";
299
- import { FilesystemSkillStore } from "skillscript-runtime/connectors";
300
- import { FilesystemTraceStore } from "skillscript-runtime/trace";
246
+ - Multi-target DAG with `needs:` dependencies
247
+ - Cron triggers with `# OnError:` fallback
248
+ - Session-start `prompt-context:` delivery
249
+ - `??` interactive ask-user pattern
250
+ - `# Requires:` cascade for compile-time data
251
+ - `&` skill composition
301
252
 
302
- const skillStore = new FilesystemSkillStore("./skills");
303
- const traceStore = new FilesystemTraceStore("./traces");
304
- const registry = new Registry();
305
- registry.registerSkillStore(skillStore);
253
+ Each example is annotated with the language pattern it demonstrates. Authored from spec by cold-context sub-agents — they double as conformance fixtures.
306
254
 
307
- const scheduler = new Scheduler({ registry, skillStore, traceStore });
308
- const result = await scheduler.dispatchSkill("hello", { WHO: "Scott" });
309
- console.log(result.emissions);
310
- ```
255
+ ## Architecture and deep documentation
311
256
 
312
- Subpath exports for adapter authors and embedders who want narrower imports:
257
+ - **[Language Reference](docs/language-reference.md)** canonical spec (1600+ lines, 13 sections). The single source of truth on syntax + semantics.
258
+ - **ROADMAP** — *coming soon to docs/*
313
259
 
314
- | Path | Content |
315
- |---|---|
316
- | `skillscript-runtime` | Main barrel — everything |
317
- | `skillscript-runtime/connectors` | Connector contracts + Registry + bundled impls |
318
- | `skillscript-runtime/errors` | `OpError` + subclasses, `LintFailureError`, `ConnectorError` |
319
- | `skillscript-runtime/runtime` | `execute()` + helpers |
320
- | `skillscript-runtime/trace` | `TraceStore`, `FilesystemTraceStore`, sampling |
321
- | `skillscript-runtime/metrics` | `healthMetrics()` aggregator |
322
- | `skillscript-runtime/scheduler` | `Scheduler` + `TriggerRegistration` |
323
- | `skillscript-runtime/mcp-server` | `McpServer` + JSON-RPC types |
324
- | `skillscript-runtime/testing` | Contract conformance suites |
260
+ ## Status
325
261
 
326
- ---
262
+ **v0.2.6** — pre-1.0, breaking changes expected. The language is stable enough to author production skills; the surrounding tooling (CLI, dashboard, MCP server contract) may evolve before v1.0.
263
+
264
+ Test coverage: 549/549 passing. Narrow-core LOC under the 5000/20-file ceiling per ERD.
265
+
266
+ What's coming next:
267
+ - Comparison operators (`<`, `>`, `<=`, `>=`) and `|length` filter — orchestration carve-out for numeric thresholds
268
+ - Persistent trigger registry on disk — imperative triggers survive process restart
269
+ - `skillfile serve` headless command — scheduler + MCP server without the SPA
327
270
 
328
271
  ## Contributing
329
272
 
330
- The codebase prioritizes a small, agent-modifiable core. The narrow runtime + compiler + lint + connectors set lives under 5K LOC; CLI, dashboard, MCP server, and observability surfaces are tracked separately. See [`ARCHITECTURE.md`](./ARCHITECTURE.md) for a file-by-file map and [`docs/ERD.md`](./docs/ERD.md) for the engineering requirements.
273
+ Bug reports and feature requests welcome via Issues. PRs accepted but please open an Issue first to discuss the design skillscript's value proposition rests on a constrained grammar, and not every "small extension" earns its keep.
331
274
 
332
- Pre-flight checks:
275
+ For language design questions, see the cold-agent-driven precedent in [Open spec questions](docs/language-reference.md#open-spec-questions): if cold-context sub-agents writing skills from spec alone hit the same syntactic friction across multiple authors, that's a signal to extend the language.
333
276
 
334
- ```sh
335
- pnpm run typecheck
336
- pnpm run loc-check # enforces ERD §1 LOC ceiling
337
- pnpm test # 473+ tests
338
- ```
277
+ ## License
339
278
 
340
- Full `CONTRIBUTING.md` lands in v1.x.
279
+ MIT. See [LICENSE](LICENSE).
341
280
 
342
281
  ---
343
282
 
344
- ## License
345
-
346
- MIT. See [`LICENSE`](./LICENSE).
283
+ *"Made by agents, for agents."* Skills are the agent's programming language.
package/dist/cli.js CHANGED
@@ -30,7 +30,7 @@ const MEMORY_DB = join(HOME_DIR, "memory.db");
30
30
  const EXAMPLES_DIR = join(HOME_DIR, "examples");
31
31
  const PLUGINS_DIR = join(HOME_DIR, "plugins");
32
32
  const TRACE_DIR = join(HOME_DIR, "traces");
33
- const VERSION = "0.2.4";
33
+ const VERSION = "0.2.6";
34
34
  const COMMAND_HELP = {
35
35
  init: {
36
36
  description: "Scaffold ~/.skillscript/ tree + bundled example",
@@ -1,18 +1,42 @@
1
1
  import type { StaticCapabilities, ManifestInfo } from "./types.js";
2
+ /**
3
+ * Provenance record threaded onto every `DeliveryPayload` so the receiving
4
+ * agent can disambiguate "what fired this delivery" — was it cron-scheduled?
5
+ * a session boundary? a user-triggered manual run? v0.2.6 addition per the
6
+ * AgentConnector polish in Perry's thread `f75477a4`.
7
+ */
8
+ export interface TriggerProvenance {
9
+ source: "cron" | "session" | "event" | "agent-event" | "file-watch" | "sensor" | "manual";
10
+ /** Source-specific value: cron expression, session phase, event name, etc. */
11
+ name: string;
12
+ /** Unix-ms timestamp the trigger fired. */
13
+ fired_at_ms: number;
14
+ }
2
15
  /**
3
16
  * Discriminated payload union for `deliver`. The runtime picks `kind`
4
17
  * based on the source declaration:
5
18
  * - `# Output: prompt-context: <agent>` → `{ kind: "augment", ... }`
6
19
  * - `# Output: template: <agent>` → `{ kind: "template", ... }`
20
+ *
21
+ * Common-shaped provenance + augmenting-context fields apply to both
22
+ * variants (v0.2.6 addition). `source_skill` was template-only in T7.1;
23
+ * now lives on both.
7
24
  */
8
25
  export type DeliveryPayload = {
9
26
  kind: "augment";
10
27
  content: string;
11
28
  format?: "text" | "markdown";
29
+ source_skill?: string;
30
+ triggered_by?: TriggerProvenance;
31
+ delivery_context?: string;
32
+ templates?: string[];
12
33
  } | {
13
34
  kind: "template";
14
35
  prompt: string;
15
36
  source_skill?: string;
37
+ triggered_by?: TriggerProvenance;
38
+ delivery_context?: string;
39
+ templates?: string[];
16
40
  };
17
41
  export interface DeliveryReceipt {
18
42
  /** Unix-ms timestamp the substrate accepted the delivery. */
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/connectors/agent.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,aAAa,CAAC,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,CAAC;CAC3E;AAED,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9E,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,YAAY,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACtD,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC;IACvC,kBAAkB,IAAI,kBAAkB,CAAC;CAC1C"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/connectors/agent.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1F,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,eAAe,GACvB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEN,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,aAAa,CAAC,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,CAAC;CAC3E;AAED,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9E,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,YAAY,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACtD,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC;IACvC,kBAAkB,IAAI,kBAAkB,CAAC;CAC1C"}