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.
- package/CHANGELOG.md +19 -0
- package/README.md +110 -380
- package/dist/dashboard/spa/app.js +214 -28
- package/dist/dashboard/spa/index.html +16 -0
- package/dist/dashboard/spa/styles.css +182 -44
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +14 -1
- package/dist/mcp-server.js.map +1 -1
- package/dist/skill-catalog.d.ts.map +1 -1
- package/dist/skill-catalog.js +5 -1
- package/dist/skill-catalog.js.map +1 -1
- package/dist/skill-surface.d.ts +41 -0
- package/dist/skill-surface.d.ts.map +1 -1
- package/dist/skill-surface.js +195 -0
- package/dist/skill-surface.js.map +1 -1
- package/docs/adopter-agent-guide.md +157 -0
- package/docs/connector-contract-reference.md +2 -0
- package/examples/skillscripts/classify-support-ticket.skill.provenance.json +1 -1
- package/examples/skillscripts/data-store-roundtrip.skill.provenance.json +1 -1
- package/examples/skillscripts/doc-qa-with-citations.skill.provenance.json +1 -1
- package/examples/skillscripts/feedback-sentiment-scan.skill.provenance.json +1 -1
- package/examples/skillscripts/hello-world.skill.provenance.json +1 -1
- package/examples/skillscripts/morning-brief.skill.provenance.json +1 -1
- package/examples/skillscripts/queue-length-monitor.skill.provenance.json +1 -1
- package/examples/skillscripts/service-health-watch.skill.provenance.json +1 -1
- package/examples/skillscripts/skill-store-roundtrip.skill.provenance.json +1 -1
- package/examples/skillscripts/youtrack-morning-sweep.skill.provenance.json +1 -1
- 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
|
-
|
|
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> •
|
|
11
|
-
<a href="https://skillscript.
|
|
11
|
+
<a href="https://docs.skillscript.ai/docs">docs</a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
[](https://www.npmjs.com/package/skillscript-runtime)
|
|
16
|
-
[](#)
|
|
17
16
|
[](LICENSE)
|
|
18
17
|
[](#status)
|
|
19
18
|
|
|
20
19
|
> **TL;DR** — `npm install -g skillscript-runtime && skillfile init && skillfile dashboard`. See [Quickstart](#quickstart).
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
### What is Skillscript?
|
|
23
22
|
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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
|
-
|
|
37
|
+
## Why use it?
|
|
84
38
|
|
|
85
|
-
-
|
|
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
|
-
|
|
41
|
+
Skillscript lets an agent crystallize a learned procedure into a named, reusable artifact that can be:
|
|
91
42
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
55
|
+
Skillscript narrows that execution surface:
|
|
109
56
|
|
|
110
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
68
|
+
## A skill
|
|
118
69
|
|
|
119
|
-
|
|
70
|
+
A skill is a typed, declarative workflow with variables, operations, dependencies, and an output template.
|
|
120
71
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
78
|
+
Hello, ${WHO}!
|
|
164
79
|
```
|
|
165
80
|
|
|
166
|
-
|
|
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
|
|
83
|
+
Skills can also call connectors, branch, loop, run other skills, respond to events, and execute on schedules:
|
|
177
84
|
|
|
178
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
91
|
+
Snapshot written for ${NOW}.
|
|
196
92
|
|
|
197
|
-
|
|
198
|
-
-
|
|
199
|
-
|
|
200
|
-
|
|
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
|
-
|
|
100
|
+
default: snapshot
|
|
101
|
+
```
|
|
203
102
|
|
|
204
|
-
|
|
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
|
-
##
|
|
105
|
+
## How it works
|
|
208
106
|
|
|
209
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
126
|
+
skillfile init
|
|
127
|
+
skillfile dashboard --host 127.0.0.1 --port 7878
|
|
232
128
|
```
|
|
233
129
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
Set up your environment the way you want it — all optional; the defaults work:
|
|
130
|
+
Open `http://localhost:7878`.
|
|
237
131
|
|
|
238
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
317
|
-
```
|
|
149
|
+
> Author a skill that greets someone by name.
|
|
318
150
|
|
|
319
|
-
The
|
|
151
|
+
The agent writes the skill through MCP. Approve it in the dashboard or CLI:
|
|
320
152
|
|
|
321
153
|
```bash
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
skillfile execute daily-disk-check
|
|
154
|
+
skillfile approve hello
|
|
155
|
+
skillfile execute hello
|
|
325
156
|
```
|
|
326
157
|
|
|
327
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
171
|
+
Secrets are resolved by the runtime and passed only to approved sinks. Skills cannot print or inspect their raw values.
|
|
352
172
|
|
|
353
|
-
|
|
173
|
+
See the [configuration guide](docs/configuration.md) and [connector reference](docs/connector-contract-reference.md).
|
|
354
174
|
|
|
355
|
-
|
|
175
|
+
## Common commands
|
|
356
176
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
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
|
-
|
|
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
|
|
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.
|