skillscript-runtime 0.30.0 → 0.31.1

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.
Files changed (28) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +110 -380
  3. package/dist/dashboard/spa/app.js +214 -28
  4. package/dist/dashboard/spa/index.html +16 -0
  5. package/dist/dashboard/spa/styles.css +182 -44
  6. package/dist/mcp-server.d.ts.map +1 -1
  7. package/dist/mcp-server.js +14 -1
  8. package/dist/mcp-server.js.map +1 -1
  9. package/dist/skill-catalog.d.ts.map +1 -1
  10. package/dist/skill-catalog.js +5 -1
  11. package/dist/skill-catalog.js.map +1 -1
  12. package/dist/skill-surface.d.ts +41 -0
  13. package/dist/skill-surface.d.ts.map +1 -1
  14. package/dist/skill-surface.js +195 -0
  15. package/dist/skill-surface.js.map +1 -1
  16. package/docs/adopter-agent-guide.md +157 -0
  17. package/docs/connector-contract-reference.md +2 -0
  18. package/examples/skillscripts/classify-support-ticket.skill.provenance.json +1 -1
  19. package/examples/skillscripts/data-store-roundtrip.skill.provenance.json +1 -1
  20. package/examples/skillscripts/doc-qa-with-citations.skill.provenance.json +1 -1
  21. package/examples/skillscripts/feedback-sentiment-scan.skill.provenance.json +1 -1
  22. package/examples/skillscripts/hello-world.skill.provenance.json +1 -1
  23. package/examples/skillscripts/morning-brief.skill.provenance.json +1 -1
  24. package/examples/skillscripts/queue-length-monitor.skill.provenance.json +1 -1
  25. package/examples/skillscripts/service-health-watch.skill.provenance.json +1 -1
  26. package/examples/skillscripts/skill-store-roundtrip.skill.provenance.json +1 -1
  27. package/examples/skillscripts/youtrack-morning-sweep.skill.provenance.json +1 -1
  28. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  Each release carries an **Upgrade impact:** line (first in its section) so a bump's requirements are visible at a glance. Tags (closed set): **BREAKING** (a manual change is needed to keep working) · **RE-APPROVE** (secured-mode signature invalidation — skills must be re-approved before they run) · **CONFIG** (`connectors.json` / config edit needed) · **none (additive)** (no action; backward-compatible). Standard from 0.20.0 forward; the pre-0.20 transitions that need action are flagged inline below (0.14.0, 0.18.8, 0.19.0). Full walkthrough: [UPGRADING.md](UPGRADING.md).
4
4
 
5
+ ## 0.31.1 — 2026-07-14 — descriptions show on custom SkillStores
6
+
7
+ **Upgrade impact:** none (additive). A robustness fix + doc clarification; no breaking change.
8
+
9
+ - **Fix: skill descriptions no longer go blank on a custom SkillStore.** The bundled stores extract `# Description:` from the body and populate `SkillMeta.description`; a custom store that doesn't (e.g. an AMP-backed connector) left the dashboard showing a blank description in the drill-down and the wrong first-prose line (the output template) in the list. The runtime now **derives `description` from the skill's frontmatter itself** — it already has the source — whenever a store returns none. Applied in both `skill_preflight` (detail) and `buildSkillCatalog` / `skill_list` (list): description precedence is store-metadata → parsed `# Description:` → first-prose heuristic. Any custom SkillStore now shows correct descriptions without having to replicate the extraction.
10
+ - **Docs: the SkillStore contract now spells out which `SkillMeta` fields are runtime-derivable.** `connector-contract-reference.md` gains a convention note — body-projection metadata (`description`, `vars`) the runtime derives; substrate-only metadata (`author`, `version`, timestamps, status) your impl must return. Previously only `author` was documented, so the `description` expectation was implicit — the gap that let a connector miss it.
11
+
12
+ ## 0.31.0 — 2026-07-13 — dashboard approval UX for the non-programmer approver
13
+
14
+ **Upgrade impact:** none (additive). Dashboard + one additive `skill_preflight` field; no breaking change.
15
+
16
+ A pass on the review view to let someone who can't read skillscript understand a skill's blast radius and approve with confidence — "approve on the declared effects, without being the one who could have written the code."
17
+
18
+ - **Dark mode.** The whole dashboard is now a CSS-variable palette with a header toggle (☾/☀); the theme is set before first paint (no flash), follows the OS setting by default, and persists. Light mode is unchanged.
19
+ - **Collapsible review sections.** The approval-decision surface (Status/actions, What this skill touches, Security signals, Source, and the new diagram) always stays open; telemetry/reference (Metrics, Recent fires, Version history, Triggers) collapses by default via native `<details>`; Composes shows only when the skill composes a child.
20
+ - **"What it does, step by step" diagram.** A dependency-ordered SVG flowchart of the skill's actual steps, in the decision surface under "What this skill touches." Targets are boxes joined by branch/merge arrows; ops are plain-language rows ("Read from the data store", "Ask the local model", "Run a bash command") with their key argument; loops and branches nest; each step shows the variable it produces (`→ VAR`) so data flow is traceable; steps that change data / run commands are marked; composed skills link through to their own review view; the entry/default target is flagged (`result` when it runs last, `default` when single-target). Drawn client-side — no diagram dependency added. The CLI's `skillfile diagram` still emits Mermaid text.
21
+ - **New `skill_preflight` field:** `contract.flow` — the structured control-flow (targets, plain-language steps, dependencies) the diagram is drawn from. Single-skill only (not added to `skill_list`, to keep the catalog lean).
22
+ - **Fix:** the dashboard no longer resets scroll position (or flashes "Loading…") on its 30-second poll when re-rendering the same view.
23
+
5
24
  ## 0.30.0 — 2026-07-10 — public launch cut
6
25
 
7
26
  **Upgrade impact:** none (additive). Documentation only; no runtime, API, or behavior change.
package/README.md CHANGED
@@ -3,264 +3,135 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- *A language for agents to write themselves in.*
6
+ <em>Safe, reusable automation authored by agents.</em>
7
7
  </p>
8
8
 
9
9
  <p align="center">
10
10
  <a href="https://skillscript.ai">skillscript.ai</a>&nbsp; • &nbsp;
11
- <a href="https://skillscript.mintlify.app/docs">docs</a>&nbsp;
11
+ <a href="https://docs.skillscript.ai/docs">docs</a>&nbsp;
12
12
  </p>
13
13
 
14
14
 
15
15
  [![npm version](https://img.shields.io/npm/v/skillscript-runtime.svg)](https://www.npmjs.com/package/skillscript-runtime)
16
- [![tests](https://img.shields.io/badge/tests-passing-green)](#)
17
16
  [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
18
17
  [![status](https://img.shields.io/badge/status-pre--1.0-orange)](#status)
19
18
 
20
19
  > **TL;DR** — `npm install -g skillscript-runtime && skillfile init && skillfile dashboard`. See [Quickstart](#quickstart).
21
20
 
22
- ## Contents
21
+ ### What is Skillscript?
23
22
 
24
- - [The problem](#the-problem)
25
- - [The frame](#the-frame)
26
- - [Why a new language](#why-a-new-language)
27
- - [Why not just have the agent write a Skill?](#why-not-just-have-the-agent-write-a-skill)
28
- - [Three kinds of skill](#three-kinds-of-skill)
29
- - [Waking agents](#waking-agents)
30
- - [Local models as tools for the frontier](#local-models-as-tools-for-the-frontier)
31
- - [Composition: skills calling skills](#composition-skills-calling-skills)
32
- - [Static vs dynamic skills](#static-vs-dynamic-skills)
33
- - [What you get](#what-you-get)
34
- - [The bet](#the-bet)
35
- - [Quickstart](#quickstart)
36
- - [A canonical autonomous skill](#a-canonical-autonomous-skill)
37
- - [Connector model](#connector-model)
38
- - [Configuration & security knobs](#configuration--security-knobs)
39
- - [CLI](#cli)
40
- - [MCP server surface](#mcp-server-surface)
41
- - [Examples](#examples)
42
- - [Architecture and deep documentation](#architecture-and-deep-documentation)
43
- - [Status](#status)
44
- - [Contributing](#contributing)
45
- - [License](#license)
23
+ Skillscript came from asking: what would a Makefile look like if it built skills instead of binaries? The answer is a constrained language, inspired by Make, and a runtime that turns an agent's reasoning into persistent, inspectable automation. The agent writes the skill, you approve what it can do, and it runs the same way every time.
46
24
 
47
- ---
25
+ It is built for teams that want agents to create and run recurring workflows without giving them unrestricted shell access, arbitrary package installation, or direct control of production credentials.
48
26
 
49
- ## The problem
27
+ An agent writes a skill. A human reviews and approves it. The runtime executes it through configured connectors, allowlists, and security policies.
50
28
 
51
- 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.
52
-
53
- 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).
54
-
55
- 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.
56
-
57
- 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.
58
-
59
- Skillscript intends to answer the second question.
60
-
61
- ## The frame
62
-
63
- **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.
64
-
65
- 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 data stores through swappable connector contracts. Computation lives in tools; coordination lives in skills.
66
-
67
- ```
68
- # Skill: hello
69
- # Status: Approved
70
- # Description: The canonical first-run example.
71
- # Vars: WHO=world
72
-
73
- Hello, ${WHO}!
74
- Welcome to Skillscript.
29
+ ```bash
30
+ npm install -g skillscript-runtime
31
+ skillfile init
32
+ skillfile dashboard
75
33
  ```
76
34
 
77
- That's a complete, runnable skill — and the body text **is** the output. No target, no boilerplate, no `emit()` ceremony: the runtime renders the body against the skill's variables and publishes it. The same shape scales to multi-stage DAGs that classify inputs, dispatch to LLMs, query data stores, branch on conditions, and orchestrate sub-agents, all in the same declarative grammar.
78
-
79
- ## Why a new language
80
-
81
- 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.
35
+ Then connect your agent to the MCP: `http://localhost:7878/rpc` and ask it to author a skill.
82
36
 
83
- But agent-authored *persistent* automation has a different shape:
37
+ ## Why use it?
84
38
 
85
- - An **agent** (not a human) writes the code.
86
- - The code runs **autonomously** — cron-fired, event-triggered — with no human in the loop at execution time.
87
- - The work is **dispatch-shaped**: call a tool, classify a result, branch, call another tool. Not algorithmic computation.
88
- - The code needs to be **auditable by humans at human tempo** even though it's authored at agent tempo.
39
+ Agents usually re-derive routine tasks from scratch. That increases cost, latency, and behavioral drift.
89
40
 
90
- For this shape, Python's strengths invert into liabilities:
41
+ Skillscript lets an agent crystallize a learned procedure into a named, reusable artifact that can be:
91
42
 
92
- - **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.
93
- - **Mature tooling doesn't help when the author isn't human.** Debuggers and REPLs are for human iteration. Agents don't iterate that way.
94
- - **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.
95
- - **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.
43
+ * executed repeatedly without re-planning the entire task
44
+ * inspected and versioned by humans
45
+ * validated before it is admitted
46
+ * limited to approved tools, files, commands, and credentials
47
+ * composed with other skills
96
48
 
97
- 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:
49
+ Skillscript is orchestration-only. Computation stays inside tools and connectors; skills coordinate those capabilities through a small declarative grammar. This can meaningfully cut frontier-model token usage in recurring workflows: the reasoning cost is paid once when the skill is authored, and each run after that executes deterministically, with routine sub-tasks handed to cheaper local models.
98
50
 
99
- - **Sandboxed grammar.** The language can only do what configured connectors permit.
100
- - **Declarative legibility.** Skills are DAGs of typed dispatches. A human reading a skill sees exactly which tools get called, which data writes happen, which model prompts fire. The same source produces the same audit diagram every time.
101
- - **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.
102
- - **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.
103
- - **Signed approval before effect.** In secured mode, only skills carrying a valid operator signature perform effectful ops — an unapproved or tampered skill is inert no matter how it's dispatched (CLI, cron, `/event`, MCP, composition). Approval is an Ed25519 signature applied operator-side and verified on every execution; the runtime never holds the signing key.
104
- - **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.
51
+ ## Why not Python or Bash?
105
52
 
106
- ## Why not just have the agent write a Skill?
53
+ Python and Bash remain useful for implementation work. The risk is allowing agent-authored scripts to run unattended with unrestricted access to the host.
107
54
 
108
- 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.
55
+ Skillscript narrows that execution surface:
109
56
 
110
- The problem with hand-authoring is that **both authoring populations produce badly-shaped artifacts when working in prose:**
57
+ * no arbitrary imports, package installation, `eval`, or subprocess escape
58
+ * connector-mediated access to external systems
59
+ * default-deny shell and filesystem allowlists
60
+ * static validation before execution
61
+ * optional operator signatures for effectful skills
62
+ * credentials held by the runtime rather than embedded in the skill
111
63
 
112
- - **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.
113
- - **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.
64
+ The goal is not to replace scripts. It is to place scripts and APIs behind capabilities the operator explicitly exposes.
114
65
 
115
- 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.
66
+ There is also a scaling reason. Reviewing arbitrary code means auditing everything it could do, which takes a skilled reader. A skillscript puts its full effect surface on the page, so approval stays tractable even when agents author faster than anyone can read code, and the operator who knows what their systems should allow can approve on the declared effects rather than by re-reading logic.
116
67
 
117
- 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.
68
+ ## A skill
118
69
 
119
- ## Three kinds of skill
70
+ A skill is a typed, declarative workflow with variables, operations, dependencies, and an output template.
120
71
 
121
- Every skillscript skill is one of three shapes, determined by the relationship to a frontier agent:
122
-
123
- | Kind | Output goes to | Use case |
124
- |---|---|---|
125
- | **Headless** | a downstream system or human, consumed asynchronously | Cron-fired monitors, batch processors, autonomous workflows |
126
- | **Augmenting** | a frontier agent's reasoning context, immediately at session start or wake | Session-start briefings, alerts, prepared context |
127
- | **Template** | a frontier agent's execution loop, as a prompt the agent runs itself | Reusable recipes the agent fetches and follows |
128
-
129
- 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.
130
-
131
- The three kinds describe the skill's *role* (who consumes the output). Orthogonal to that is *how* the result ships. The default is the **body-text output template**: any non-op text in the skill body is rendered against the skill's final variables and published as its canonical output — no ceremony, as in the `hello` skill above. For what the template can't express, three delivery ops are first-class — `emit()` for incremental/per-item output, `$ data_write` for data handoff, `file_write` for files — and they coexist with the template (which owns canonical output; `emit` lines are additional). See the [Language Reference](docs/language-reference.md) §1 for the full taxonomy.
132
-
133
- The canonical use for `emit` is per-item output inside a loop, where there's no single template to render — one line per iteration:
134
-
135
- ```
136
- # Vars: TICKETS=[...]
137
-
138
- process:
139
- foreach T in ${TICKETS}:
140
- emit(text="${T.id}: ${T.urgency}")
141
-
142
- default: process
143
- ```
144
-
145
- ### Local models as tools for the frontier
146
-
147
- 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 LLM dispatch is the frontier handing off 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 or smaller model and consuming the result.
148
-
149
- In skillscript, this isn't a separate "local-model interplay" pattern adopters bolt on — it's just **MCP dispatch through a connector named whatever your substrate calls it**. `$ llm prompt="..." -> RESULT` (one shop wires `llm` pointing at Ollama; another wires `openai_chat` against the OpenAI API; another wires `claude_messages` against Anthropic) lives next to any other `$ tool args -> RESULT` in the skill body, with the same op-level discipline, the same trace surface, the same lint coverage. The language has no built-in LLM keyword — adopters wire their substrate.
150
-
151
- 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 bounded sub-tasks never reaches an external API when the wired connector is local. The local-model layer becomes the privacy boundary, not a separate add-on.
152
-
153
- ### Composition: skills calling skills
154
-
155
- A skill can invoke another skill via `execute_skill(...)`:
156
-
157
- ```
158
- Extracted: ${RESULT.final_vars.VALUE|trim}
159
-
160
- parent:
161
- execute_skill(name="extract-json-number", JSON_BLOB="${RAW}", FIELD_PATH="total_count") -> RESULT
72
+ ```text
73
+ # Skill: hello
74
+ # Status: Approved
75
+ # Description: Greet someone by name.
76
+ # Vars: WHO=world
162
77
 
163
- default: parent
78
+ Hello, ${WHO}!
164
79
  ```
165
80
 
166
- The child skill runs to completion against the runtime's wired connectors, returns its full execution record (final vars, transcript, outputs), and binds to the parent's named variable. Field access on the bound result (`${RESULT.final_vars.X}`) lets the parent reach into whatever the child produced.
167
-
168
- Composition is what makes skill libraries accumulate — utility skills (`extract-json-number`, `summarize-thread`, `classify-urgency`) authored once, orchestrated forever. You can dry-run a multi-skill chain before committing to it.
169
-
170
- ### Waking agents
171
-
172
- Augmenting and Template skills deliver to a frontier agent through `AgentConnector` — a substrate-neutral seam. A Headless monitor detects a condition and either resolves silently or calls `AgentConnector.deliver(...)`; your impl decides where that lands — a data store the agent reads next session, a chat thread, a push notification, a tmux pane, a webhook, anything that wakes the agent. The runtime ships a no-op default; production wires their own. Skills don't know what they're waking into, and the substrate doesn't know what triggered them — the contract handles the seam. (See [Connector Contract Reference](docs/connector-contract-reference.md) to implement one.)
173
-
174
- ### Static vs dynamic skills
81
+ That is a complete, runnable skill. The body is rendered as its output.
175
82
 
176
- Skills have an execution model orthogonal to their kind. A **dynamic skill** requires the Skillscript runtime to execute — the runtime walks the DAG, fires dispatches against wired connectors, threads outputs. A **static skill** compiles to a portable artifact that any agent capable of reading prose can execute without the runtime.
83
+ Skills can also call connectors, branch, loop, run other skills, respond to events, and execute on schedules:
177
84
 
178
- The static case is shareable artifacts: a skill whose body is just a template or `emit(...)` lines — no `$`/`shell`/`file_*` dispatches — compiles to a self-contained recipe you can email, post, or hand to an agent in another environment, which executes the steps with its own tools. The skill becomes the deliverable. Template-kind skills are the canonical static shape; Headless and Augmenting are usually dynamic. The axes are independent — author the combination the work calls for.
179
-
180
- ```
181
- # A static recipe (no runtime dispatches; just procedure + data)
182
- # Skill: triage-customer-tickets
85
+ ```text
86
+ # Skill: daily-disk-check
183
87
  # Status: Approved
184
- # Vars: TICKETS_JSON=[...]
185
-
186
- For each ticket in the input, classify urgency as critical/normal/low.
187
- For critical tickets, suggest immediate owner from the runbook.
188
- Input: ${TICKETS_JSON}
189
- ```
190
-
191
- That compiles to a procedure + data bundle a recipient can run anywhere.
192
-
193
- ## What you get
88
+ # Triggers: cron:"0 6 * * *"
89
+ # Autonomous: true
194
90
 
195
- **For operators:**
91
+ Snapshot written for ${NOW}.
196
92
 
197
- - *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.
198
- - *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.
199
- - *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.
200
- - *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.
93
+ snapshot:
94
+ shell(command="df -h --output=source,pcent,target") -> USAGE
95
+ file_write(
96
+ path="/var/log/skillscript/disk-${EVENT.fired_at_unix}.txt",
97
+ content="${USAGE}"
98
+ )
201
99
 
202
- **For agent capability:**
100
+ default: snapshot
101
+ ```
203
102
 
204
- - *Reduced token budget on routine work.* Authoring a skill is a one-time cost paid against an indefinite stream of cheap executions.
205
- - *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.
103
+ The runtime will refuse the shell command and file write until the operator allowlists the binary and path.
206
104
 
207
- ## The bet
105
+ ## How it works
208
106
 
209
- 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.
107
+ 1. **Author:** An MCP-connected agent discovers the available tools, writes a skill, and lints it. In secured mode it arrives as `Draft`, inert until you approve it.
108
+ 2. **Review:** A human inspects and approves the skill. In secured mode, approval signs the approved content with an operator-held key.
109
+ 3. **Run:** The skill executes from the CLI, MCP, cron, an HTTP event, or another skill.
110
+ 4. **Observe:** The runtime records traces, outputs, failures, and blocked operations.
210
111
 
211
- 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.
112
+ Skills can serve three roles:
212
113
 
213
- ---
114
+ | Kind | Purpose |
115
+ | -------------- | ------------------------------------------------------- |
116
+ | **Headless** | Runs autonomously and sends output to a system or human |
117
+ | **Augmenting** | Prepares context for a frontier agent |
118
+ | **Template** | Gives an agent a reusable procedure to follow |
214
119
 
215
120
  ## Quickstart
216
121
 
217
- Skillscript is **operated by a human and authored with an agent**. You install and run the runtime, wire it into your agent as an MCP server, then build skills together — the agent writes them (they land as `Draft`), and you approve what's allowed to run. The three steps below follow that division of labor.
218
-
219
- ### 1. Human — install and set up
220
-
221
- Fastest path — the defaults work; this gets you a running server on `http://localhost:7878`:
222
-
223
- ```bash
224
- npm install -g skillscript-runtime && skillfile init && skillfile dashboard
225
- ```
226
-
227
- `init` scaffolds `~/.skillscript/` (config, signing keys, demo skills); `dashboard` is a foreground server (Ctrl-C to stop). The annotated breakdown:
122
+ ### 1. Install and start the runtime
228
123
 
229
124
  ```bash
230
125
  npm install -g skillscript-runtime
231
- skillfile init # scaffolds ~/.skillscript/ — config, signing keys, demo skills
126
+ skillfile init
127
+ skillfile dashboard --host 127.0.0.1 --port 7878
232
128
  ```
233
129
 
234
- > If `npm install -g` fails with `EACCES: permission denied`, your global prefix is root-owned (system-managed Node). Re-run with `sudo`, or use an nvm-style prefix you own. Not a Skillscript issue — standard npm-global behavior.
235
-
236
- Set up your environment the way you want it — all optional; the defaults work:
130
+ Open `http://localhost:7878`.
237
131
 
238
- ```bash
239
- cp ~/.skillscript/.env.example ~/.skillscript/.env
240
- # edit ~/.skillscript/.env — e.g. SKILLSCRIPT_PORT (default 7878),
241
- # SKILLSCRIPT_SECURED_MODE, the shell allowlist
242
- ```
132
+ Use `--host 0.0.0.0` only when another container or machine must reach the runtime, and protect exposed ingress appropriately.
243
133
 
244
- Start the runtime — this is the MCP server your agent connects to:
245
-
246
- ```bash
247
- skillfile dashboard --host 0.0.0.0 --port 7878 # foreground server — Ctrl-C to stop
248
- # then, in your browser, open http://localhost:7878
249
- ```
250
-
251
- > **On `--host 0.0.0.0`:** binds all interfaces so a containerized client (e.g. NanoClaw) can reach the runtime across the namespace — this is the primary deployment posture. On a laptop or a shared/untrusted network it exposes the control surface; use `--host 127.0.0.1` for localhost-only, or set the `/event` ingress auth token (`SKILLSCRIPT_EVENT_INGRESS_AUTH_TOKEN`) so the exposed surface isn't open.
252
-
253
- Prefer headless? `skillfile serve` runs the same MCP server without the dashboard SPA. Or run the container:
254
-
255
- ```bash
256
- docker run -p 7878:7878 -v $(pwd)/skills:/data/skills \
257
- -e SKILLSCRIPT_HOME=/data \
258
- ghcr.io/sshwarts/skillscript-runtime:latest
259
- ```
260
-
261
- ### 2. Human — add the MCP to your agent
262
-
263
- On Claude Code (and similar hosts) the simplest path is to just ask: *"Add the skillscript MCP server at `http://localhost:7878/rpc`"* — the host writes the config for you. Or wire it manually:
134
+ ### 2. Add the MCP server to your agent
264
135
 
265
136
  ```json
266
137
  {
@@ -273,209 +144,68 @@ On Claude Code (and similar hosts) the simplest path is to just ask: *"Add the s
273
144
  }
274
145
  ```
275
146
 
276
- For stdio-only clients, bridge it the same way you'd bridge any HTTP MCP — via `mcp-remote`:
277
-
278
- ```json
279
- {
280
- "mcpServers": {
281
- "skillscript": {
282
- "command": "npx",
283
- "args": ["mcp-remote", "http://localhost:7878/rpc"]
284
- }
285
- }
286
- }
287
- ```
288
-
289
- ### 3. Human + agent — write your first skill together
290
-
291
- The agent learns the workflow on connect (the MCP server delivers its usage instructions automatically). Just ask it to build something:
292
-
293
- > *"Author a skill that greets someone by name."*
294
-
295
- The agent discovers what's available with `skill_list`, checks the contract with `skill_preflight`, and authors via `skill_write` — the skill lands as **Draft**. You review and approve it (the dashboard's approve button, or `skillfile approve <name>`), and it's live. From there the agent runs it via `execute_skill`, or you can from the CLI with `skillfile execute <name>`.
296
-
297
- The runtime starts in **unsecured** mode, where a bare `# Status: Approved` is sufficient and approval is one click. For a deployment that should only run key-signed skills, set `SKILLSCRIPT_SECURED_MODE=true` — approval then signs with your operator key. See [Approval + secured mode](docs/adopter-playbook.md#approval--secured-mode).
298
- ### A canonical autonomous skill
299
-
300
- The hello example is a single static target. A more representative shape is a cron-fired skill that pulls data, processes it, and delivers via file. The example below uses only runtime-intrinsic ops (`shell`, `file_write`, `emit`) — no adopter-wired connectors. The runtime gates shell binaries and filesystem paths default-deny, so you allowlist exactly what this skill touches before it runs:
301
-
302
- ```
303
- # Skill: daily-disk-check
304
- # Status: Approved
305
- # Description: Cron-fired daily disk usage snapshot to /var/log/skillscript/disk.txt.
306
- # Triggers: cron:"0 6 * * *"
307
- # Autonomous: true
308
-
309
- Snapshot written for ${NOW}.
310
-
311
- snapshot:
312
- shell(command="df -h --output=source,pcent,target") -> USAGE
313
- file_write(path="/var/log/skillscript/disk-${EVENT.fired_at_unix}.txt",
314
- content="${USAGE}")
147
+ ### 3. Ask the agent to build a skill
315
148
 
316
- default: snapshot
317
- ```
149
+ > Author a skill that greets someone by name.
318
150
 
319
- The `df` binary and the `/var/log/skillscript` path are both default-deny until the operator allowlists them:
151
+ The agent writes the skill through MCP. Approve it in the dashboard or CLI:
320
152
 
321
153
  ```bash
322
- export SKILLSCRIPT_SHELL_ALLOWLIST=df
323
- export SKILLSCRIPT_FS_ALLOWLIST=/var/log/skillscript
324
- skillfile execute daily-disk-check
154
+ skillfile approve hello
155
+ skillfile execute hello
325
156
  ```
326
157
 
327
- Five things to notice:
328
-
329
- 1. **`# Triggers: cron:"..."`** — the runtime registers the schedule at load; no external scheduler.
330
- 2. **`# Autonomous: true`** — authorizes the mutation op (`file_write`) to fire without per-call confirmation; without it, each mutation needs an inline `approved="<reason>"`.
331
- 3. **`${EVENT.fired_at_unix}` + `${NOW}`** — ambient refs the runtime fills per-fire (`EVENT.*` = trigger payload; `NOW` = dispatch-time ISO timestamp).
332
- 4. **Body text above `snapshot:` is the output template** — rendered against final vars and published as canonical output; no `emit()` needed.
333
- 5. **Default-deny allowlists** — `shell` / `file_*` ops refuse until the operator allowlists the binary + path roots; the author can't escape it (see [Configuration & security knobs](#configuration--security-knobs)).
334
-
335
- Swap in `$ ticketing_search`, `$ llm`, `$ data_write` once you've wired connectors, and the same skill shape becomes a real triage pipeline.
336
-
337
- ## Connector model
158
+ ## Connectors and security
338
159
 
339
- Skills don't know what they're talking to. Five contracts decouple language from substrate:
160
+ Skills access external systems through configured connectors rather than direct credentials. Connectors can expose MCP tools, data stores, local models, agent delivery channels, or custom runtime capabilities.
340
161
 
341
- | Contract | Purpose | Base config |
342
- |---|---|---|
343
- | `SkillStore` | Skill source persistence | `FilesystemSkillStore` (default); switch via `substrate.skill_store` in `connectors.json` |
344
- | `DataStore` | Generic data persistence with query | `SqliteDataStore` (conditional on dbPath); switch via `substrate.data_store` |
345
- | `LocalModel` | Local LLM dispatch | **null** (adopter wires explicitly via `substrate.local_model`) |
346
- | `McpConnector` | MCP tool invocation — external dispatch | adopter wires named instances in `connectors.json` |
347
- | `AgentConnector` | Delivery to a frontier agent | adopter wires explicitly (no bundled default) |
162
+ Important operator controls:
348
163
 
349
- Runtime hosts (MCP server + web dashboard) honor whichever substrate the deployment configures. Authoring CLI commands (`skillfile compile`, `skillfile lint`, `skillfile audit`, `skillfile list`) stay filesystem-pinned by design — they're the FS-authoring loop.
164
+ | Setting | Default |
165
+ | ----------------------------- | ----------------- |
166
+ | `SKILLSCRIPT_SHELL_ALLOWLIST` | deny all binaries |
167
+ | `SKILLSCRIPT_FS_ALLOWLIST` | deny all paths |
168
+ | `SKILLSCRIPT_SECURED_MODE` | off |
169
+ | `SKILLSCRIPT_SECRET_<NAME>` | unset |
350
170
 
351
- See **[`docs/configuration.md`](docs/configuration.md)** for the full substrate config reference.
171
+ Secrets are resolved by the runtime and passed only to approved sinks. Skills cannot print or inspect their raw values.
352
172
 
353
- 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.
173
+ See the [configuration guide](docs/configuration.md) and [connector reference](docs/connector-contract-reference.md).
354
174
 
355
- ### `connectors.json`
175
+ ## Common commands
356
176
 
357
- Per-host configuration. The runtime loads it at startup. Two top-level concerns:
358
-
359
- 1. **`substrate`** — which `SkillStore` / `DataStore` / `LocalModel` the runtime hosts use
360
- 2. **Named MCP connector instances** — each becomes a connector referenced via `$ <name>` in skill source
361
-
362
- ```json
363
- {
364
- "substrate": {
365
- "skill_store": "sqlite",
366
- "data_store": "sqlite",
367
- "local_model": null
368
- },
369
-
370
- "youtrack": {
371
- "class": "RemoteMcpConnector",
372
- "config": {
373
- "command": "npx",
374
- "args": ["mcp-remote", "https://example.youtrack.cloud/mcp"],
375
- "env": { "AUTH_HEADER": "Bearer ${YOUTRACK_TOKEN}" }
376
- }
377
- }
378
- }
177
+ ```bash
178
+ skillfile lint <skill>
179
+ skillfile compile <skill>
180
+ skillfile execute <skill>
181
+ skillfile approve <skill>
182
+ skillfile diagram <skill>
183
+ skillfile fires <skill>
184
+ skillfile replay <trace_id>
185
+ skillfile health
379
186
  ```
380
187
 
381
- Substrate short-form (`"sqlite"` etc.) wires bundled defaults. Object form (`{type, config}`) overrides config. See **[`docs/configuration.md`](docs/configuration.md)** for the full schema + adopter-custom impl path.
382
-
383
- **Credentials** resolve via `${VAR}` substitution — `"AUTH_HEADER": "Bearer ${YOUTRACK_TOKEN}"` pulls `${NAME}` from `process.env` at load time (a missing var is a clear startup error, not a silent empty string). Commit the `${...}` references; keep the real values in your deployment environment.
384
-
385
- **Connector classes are a fixed, recognized set** (no arbitrary plugin loading — deliberate). Introspect what your runtime supports with `runtime_capabilities({include:["mcpConnectorClasses"]})`.
386
-
387
- ## Configuration & security knobs
388
-
389
- Operator settings come from `$SKILLSCRIPT_HOME/.env` (auto-loaded by the CLI), the shell environment, or `skillscript.config.json`. The first three are **default-deny** boundaries you opt into, not out of; the fourth provisions named secrets a skill can use but never read — a skill can only do what the operator has permitted:
188
+ Run `skillfile <command> --help` for options.
390
189
 
391
- | Knob | Default | Effect |
392
- |---|---|---|
393
- | `SKILLSCRIPT_SHELL_ALLOWLIST` | deny-all | which binaries `shell(...)` may invoke |
394
- | `SKILLSCRIPT_FS_ALLOWLIST` | deny-all | which path roots `file_read` / `file_write` may touch |
395
- | `SKILLSCRIPT_SECURED_MODE` | off | require an operator signature for any effectful op (unapproved skills inert) |
396
- | `SKILLSCRIPT_SECRET_<NAME>` | unset | a value a skill references as `{{secret.NAME}}` and uses at a sink (`shell` / `$ connector.tool`) — never readable, emittable, or traced |
190
+ ## Documentation
397
191
 
398
- `skillfile shell-audit` enumerates the binaries your skill corpus needs, ready to paste into the allowlist. The full env-var surface (ports, timeouts, identity headers, `/event` ingress, approval key paths, dashboard auth) lives in the **[Configuration reference](docs/configuration.md)**.
399
-
400
- ## CLI
401
-
402
- The CLI covers the full authoring + ops lifecycle:
403
-
404
- | Command | Purpose |
405
- |---|---|
406
- | `skillfile init` | Scaffold the `~/.skillscript/` tree + bundled examples (provisions keys, locally approves the demos) |
407
- | `skillfile execute <path\|name>` | Execute a skill against configured connectors (mirrors the `execute_skill` MCP tool) |
408
- | `skillfile compile <path\|name>` | Compile a skill to its rendered artifact |
409
- | `skillfile audit <provenance-path>` | Detect recompile-staleness via the `.provenance.json` sidecar |
410
- | `skillfile lint <path\|name>` | Tier-1/2/3 lint diagnostics |
411
- | `skillfile list` | List available skills in the configured SkillStore |
412
- | `skillfile fires <skill>` | Recent fire history with trace IDs |
413
- | `skillfile diagram <path\|name>` | Mermaid DAG visualization |
414
- | `skillfile sign <path\|name>` | Generate content-hash signature |
415
- | `skillfile verify <path\|name> <hash>` | Verify against a known signature |
416
- | `skillfile approve <name>` | Approve a stored skill (sign it for secured-mode execution) |
417
- | `skillfile reapprove [<name>] [--apply]` | Batch re-sign Approved skills lacking a valid signature (pre-secured-mode migration) |
418
- | `skillfile delete <name>` | Permanently delete a stored skill (destructive — no restore; aborts on dependents unless `--force`). Operator-only — no agent/MCP delete surface |
419
- | `skillfile replay <trace_id>` | Re-run from a captured trace |
420
- | `skillfile health` | Aggregate runtime health metrics |
421
- | `skillfile serve [--port N]` | Headless: scheduler + MCP server, no SPA |
422
- | `skillfile dashboard [--port N]` | Same as `serve` plus dashboard SPA at `/` |
423
-
424
- Run `skillfile <command> --help` for per-command flags. Use `serve` for production / containerized deployments and `dashboard` for development. CLI command names mirror the MCP tool names where they overlap (`execute` ↔ `execute_skill`, `compile` ↔ `compile_skill`, `lint` ↔ `lint_skill`), so authors who learn one surface can transfer immediately to the other.
425
-
426
- ## MCP server surface
427
-
428
- The runtime exposes its tools over MCP (HTTP at `/rpc`) for cold-client authoring + observability. It also serves `POST /event` for external HTTP-triggered skills when `SKILLSCRIPT_EVENT_INGRESS_ENABLED=true`:
429
-
430
- | Category | Tools |
431
- |---|---|
432
- | Skill management | `skill_list`, `skill_preflight`, `skill_read`, `skill_status`, `skill_write` |
433
- | Data | `data_read` |
434
- | Authoring | `lint_skill`, `compile_skill` |
435
- | Composition | `execute_skill` |
436
- | Triggers | `list_triggers`, `register_trigger`, `unregister_trigger`, `set_trigger_enabled` |
437
- | Observability | `health_metrics`, `blocked_shell_attempts` |
438
- | Discovery | `runtime_capabilities`, `help` |
439
-
440
- This is the **agent-reaches-MCP** path: any MCP-speaking agent (Claude, GPT, anything that speaks the protocol) can discover, author, validate, and run skills entirely over the wire. On connect the server hands the agent its usage contract automatically, and `help()` returns a quickstart — each tool's own description carries the specifics (execution modes, the approval + mutation gates, dry-run preview), so an agent learns the surface without leaving the wire.
441
-
442
- ## Examples
443
-
444
- Curated example skills in [`examples/`](examples/), covering:
445
-
446
- - Multi-target DAG with `needs:` dependencies
447
- - Cron triggers with `# OnError:` fallback
448
- - Session-start `# Output: agent:` delivery
449
- - `# Requires:` cascade for compile-time data
450
- - `inline(skill=...)` skill composition
451
- - `execute_skill(...)` skill-to-skill composition
452
-
453
- Each example is annotated with the language pattern it demonstrates.
454
-
455
- ## Architecture and deep documentation
456
-
457
- - **[Language Reference](docs/language-reference.md)** — canonical spec. The single source of truth on syntax + semantics.
458
- - **[Configuration](docs/configuration.md)** — `connectors.json` substrate selection + named MCP connector wiring + adopter-custom impl path.
459
- - **[Adopter Playbook](docs/adopter-playbook.md)** — patterns for adopters embedding skillscript-runtime in their own deployment.
460
- - **[Connector Contract Reference](docs/connector-contract-reference.md)** — interface contracts for adopters writing their own connector impls.
461
- - **[SqliteSkillStore](docs/sqlite-skill-store.md)** — the bundled DB-backed SkillStore: schema, semantics, forking checklist.
462
- - **[Upgrading](UPGRADING.md)** — pre-1.0 version transitions; the secured-mode re-approval migration, `connectors.json` schema changes, and per-release upgrade-impact.
463
- - **ROADMAP** — *coming soon to docs/*
192
+ * [Language reference](docs/language-reference.md)
193
+ * [Configuration](docs/configuration.md)
194
+ * [Adopter playbook](docs/adopter-playbook.md)
195
+ * [Adopter agent guide](docs/adopter-agent-guide.md)
196
+ * [Connector contracts](docs/connector-contract-reference.md)
197
+ * [Upgrading](UPGRADING.md)
198
+ * [Examples](examples/)
199
+ * Additional examples on the [website](https://skillscript.ai/examples.php)
464
200
 
465
201
  ## Status
466
202
 
467
- Pre-1.0, no external adopters. Core language stable; connector contracts locked; distribution polish in progress.
203
+ Skillscript is pre-1.0. The core language and connector contracts are stabilizing; external adoption and distribution work are ongoing.
468
204
 
469
205
  ## Contributing
470
206
 
471
- 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.
472
-
473
- 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.
207
+ Bug reports and feature requests are welcome through Issues. Open an Issue before proposing grammar changes so the design can be discussed first.
474
208
 
475
209
  ## License
476
210
 
477
211
  MIT. See [LICENSE](LICENSE).
478
-
479
- ---
480
-
481
- *"Made by agents, for agents."* Skills are the agent's programming language.