skillscript-runtime 0.15.7 → 0.16.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/README.md +23 -24
- package/dist/compile.js +25 -71
- package/dist/compile.js.map +1 -1
- package/dist/connectors/mcp-remote.d.ts.map +1 -1
- package/dist/connectors/mcp-remote.js +7 -1
- package/dist/connectors/mcp-remote.js.map +1 -1
- package/dist/errors.d.ts +13 -7
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +20 -13
- package/dist/errors.js.map +1 -1
- package/dist/help-content.d.ts.map +1 -1
- package/dist/help-content.js +78 -103
- package/dist/help-content.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lint.d.ts.map +1 -1
- package/dist/lint.js +167 -228
- package/dist/lint.js.map +1 -1
- package/dist/mutation-gate.d.ts +7 -13
- package/dist/mutation-gate.d.ts.map +1 -1
- package/dist/mutation-gate.js +6 -11
- package/dist/mutation-gate.js.map +1 -1
- package/dist/parser.d.ts +25 -74
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +80 -272
- package/dist/parser.js.map +1 -1
- package/dist/runtime.d.ts +1 -10
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +76 -188
- package/dist/runtime.js.map +1 -1
- package/dist/safe-path.d.ts +20 -0
- package/dist/safe-path.d.ts.map +1 -0
- package/dist/safe-path.js +49 -0
- package/dist/safe-path.js.map +1 -0
- package/dist/skill-manager.js +1 -1
- package/dist/skill-manager.js.map +1 -1
- package/dist/trace.d.ts.map +1 -1
- package/dist/trace.js +26 -9
- package/dist/trace.js.map +1 -1
- package/docs/language-reference.md +3 -24
- package/examples/README.md +1 -2
- package/examples/connectors/McpConnectorTemplate/McpConnectorTemplate.ts +4 -5
- package/examples/connectors/SkillStoreTemplate/SkillStoreTemplate.ts +9 -9
- package/examples/custom-bootstrap.example.ts +4 -4
- package/examples/onboarding-scaffold/bootstrap.ts +7 -7
- package/examples/onboarding-scaffold/file-data-store.ts +3 -5
- package/examples/onboarding-scaffold/openai-local-model.ts +7 -8
- package/examples/onboarding-scaffold/tmux-shell-agent-connector.ts +4 -4
- package/examples/skillscripts/hello-world.skill.provenance.json +1 -1
- package/package.json +1 -1
- package/examples/skillscripts/cut-release-tag.skill.md +0 -40
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* suite the entire skillscript surface (skill_write / skill_list /
|
|
28
28
|
* execute_skill / etc.) reads + writes against your substrate.
|
|
29
29
|
*
|
|
30
|
-
*
|
|
30
|
+
* **`SkillStoreMcpConnector` bridge auto-wires against your impl.**
|
|
31
31
|
* The runtime's `defaultRegistry` wraps your registered SkillStore in a
|
|
32
32
|
* `SkillStoreMcpConnector` instance and registers it under the connector
|
|
33
33
|
* names `skill_read` + `skill_write`, so `$ skill_read` / `$ skill_write` from
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
* worth knowing:
|
|
40
40
|
* - **In-skill writes arrive Draft-stamped.** The bridge layer applies a
|
|
41
41
|
* `# Status: Draft` override to the body before calling your `store()`.
|
|
42
|
-
* This is the
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
42
|
+
* This is the trust boundary — autonomously-generated skill bodies
|
|
43
|
+
* (e.g., `$ llm prompt="generate a skill"` → `$ skill_write`) shouldn't
|
|
44
|
+
* bypass human review by landing Approved + immediately executable.
|
|
45
|
+
* See `src/connectors/skill-store-mcp.ts` header for the threat-model
|
|
46
|
+
* rationale. Outside-MCP `skill_write` (cold-author agents authoring
|
|
47
|
+
* directly via the wire surface) keeps the existing "body declares
|
|
48
|
+
* status, you auto-stamp via store()" path — that's the path your
|
|
49
|
+
* `store()` honor-the-body-Status logic addresses.
|
|
50
50
|
* - **Substrate-level lint runs at `store()` entry.** If you mirror
|
|
51
51
|
* `FilesystemSkillStore` / `SqliteSkillStore`, you'll run tier-1 lint
|
|
52
52
|
* on the body before persisting + throw `LintFailureError` on rejection.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Worked example: writing a custom bootstrap that wires adopter-specific
|
|
2
|
-
// substrates against skillscript-runtime's public APIs.
|
|
2
|
+
// substrates against skillscript-runtime's public APIs.
|
|
3
3
|
//
|
|
4
4
|
// **When to write your own bootstrap.** The bundled `bootstrap()` from
|
|
5
5
|
// `skillscript-runtime` wires `FilesystemSkillStore` + `OllamaLocalModel` +
|
|
6
|
-
// `SqliteDataStore` + the
|
|
6
|
+
// `SqliteDataStore` + the typed-contract bridges. If your deployment uses
|
|
7
7
|
// different substrates (your own data store, a hosted LLM API, an MCP
|
|
8
8
|
// server for agent delivery, etc.), write your own bootstrap rather than
|
|
9
9
|
// modifying the bundled one. Prevents merge conflicts on every upstream
|
|
@@ -52,7 +52,7 @@ class MyAdopterConnector implements McpConnector {
|
|
|
52
52
|
constructor(private readonly config: Record<string, unknown>) {}
|
|
53
53
|
|
|
54
54
|
async call(toolName: string, args: Record<string, unknown>, _ctx?: McpDispatchCtx): Promise<unknown> {
|
|
55
|
-
// Dispatch to your substrate. Auth/credentials per the
|
|
55
|
+
// Dispatch to your substrate. Auth/credentials per the passthrough
|
|
56
56
|
// model: the substrate enforces; runtime threads credentials via ctx.
|
|
57
57
|
void toolName; void args;
|
|
58
58
|
return { ok: true };
|
|
@@ -102,7 +102,7 @@ registry.registerSkillStore("primary", skillStore);
|
|
|
102
102
|
// registry.registerMcpConnector("data_read", dataBridge);
|
|
103
103
|
// registry.registerMcpConnector("data_write", dataBridge);
|
|
104
104
|
// }
|
|
105
|
-
// //
|
|
105
|
+
// // SkillStore-as-bridge. Makes `$ skill_write` / `$ skill_read`
|
|
106
106
|
// // dispatchable from inside an executing skill (Lisp-shape: skills program
|
|
107
107
|
// // skills). In-skill writes are Draft-forced at the bridge layer; outside-MCP
|
|
108
108
|
// // skill_write keeps the existing "body declares status" behavior.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Onboarding scaffold: complete bootstrap wiring file-backed data store +
|
|
2
|
-
// OpenAI LLM + tmux-shell AgentConnector.
|
|
2
|
+
// OpenAI LLM + tmux-shell AgentConnector.
|
|
3
3
|
//
|
|
4
4
|
// Copy this file into your deployment and modify substrate choices to
|
|
5
5
|
// match your environment. The shape is:
|
|
@@ -74,12 +74,12 @@ registry.registerMcpConnector("llm", new LocalModelMcpConnector(openai));
|
|
|
74
74
|
const dataBridge = new DataStoreMcpConnector(dataStore);
|
|
75
75
|
registry.registerMcpConnector("data_read", dataBridge);
|
|
76
76
|
registry.registerMcpConnector("data_write", dataBridge);
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
77
|
+
// SkillStore-as-bridge. Makes `$ skill_write` / `$ skill_read` dispatchable
|
|
78
|
+
// from inside an executing skill (Lisp-shape: skills program skills).
|
|
79
|
+
// In-skill writes are forced to `# Status: Draft` at the bridge layer —
|
|
80
|
+
// see `src/connectors/skill-store-mcp.ts` header for the threat-model
|
|
81
|
+
// rationale. Outside-MCP `skill_write` (via the wire surface) keeps its
|
|
82
|
+
// existing "body declares status" behavior.
|
|
83
83
|
const skillBridge = new SkillStoreMcpConnector(skillStore);
|
|
84
84
|
registry.registerMcpConnector("skill_read", skillBridge);
|
|
85
85
|
registry.registerMcpConnector("skill_write", skillBridge);
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
// Onboarding scaffold: file-backed DataStore.
|
|
1
|
+
// Onboarding scaffold: file-backed DataStore.
|
|
2
2
|
//
|
|
3
3
|
// JSON file as the substrate; simple JS substring + token match for "fts"
|
|
4
4
|
// queries; reranks by recency. Adopters copy this file and modify for
|
|
5
5
|
// their concrete substrate (e.g., swap the JSON file for a Postgres
|
|
6
6
|
// table, the substring match for actual full-text search, etc.).
|
|
7
7
|
//
|
|
8
|
-
// **Scope.**
|
|
9
|
-
// `write()` is deferred to v0.8.x bundled with the auth model — when
|
|
10
|
-
// that lands, extend this file with the matching `write()` method.
|
|
8
|
+
// **Scope.** Implements `query()` + `write()` per the DataStore contract.
|
|
11
9
|
|
|
12
10
|
import { readFileSync, existsSync, writeFileSync } from "node:fs";
|
|
13
11
|
import { randomUUID } from "node:crypto";
|
|
@@ -106,7 +104,7 @@ export class FileDataStore implements DataStore {
|
|
|
106
104
|
file_path: this.config.filePath,
|
|
107
105
|
record_count: this.loadFile().length,
|
|
108
106
|
supports_write: true,
|
|
109
|
-
//
|
|
107
|
+
// strict-filters: the bridge enforces every non-base filter
|
|
110
108
|
// key in `query()` calls against this declared set, throwing
|
|
111
109
|
// UnsupportedFilterError for unknowns. This reference impl's
|
|
112
110
|
// substring scorer doesn't actually filter on any field (it
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
// Onboarding scaffold: OpenAI-API-backed LocalModel.
|
|
1
|
+
// Onboarding scaffold: OpenAI-API-backed LocalModel.
|
|
2
2
|
//
|
|
3
3
|
// HTTP client to OpenAI's Chat Completions endpoint. Implements the
|
|
4
|
-
// `LocalModel.run(prompt, opts)` typed contract so the
|
|
5
|
-
//
|
|
6
|
-
// for skills.
|
|
4
|
+
// `LocalModel.run(prompt, opts)` typed contract so the
|
|
5
|
+
// `LocalModelMcpConnector` bridge surfaces it as canonical
|
|
6
|
+
// `$ llm prompt=... [maxTokens=N] [model="..."] -> R` for skills.
|
|
7
7
|
//
|
|
8
8
|
// **Prompt-vs-messaging caveat.** `LocalModel.run()` takes a single
|
|
9
9
|
// `prompt` string; Chat Completions expects a list of messages with roles.
|
|
10
10
|
// This adapter wraps the prompt as a single `user` message. Skills that
|
|
11
|
-
// need multi-turn or system-prompt isolation should
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// for a richer message-shaped LocalModel contract.
|
|
11
|
+
// need multi-turn or system-prompt isolation should pair the LLM dispatch
|
|
12
|
+
// with `$set` + accumulation in the skill body — the LocalModel contract
|
|
13
|
+
// is intentionally narrow (prompt-in, text-out).
|
|
15
14
|
|
|
16
15
|
import type {
|
|
17
16
|
LocalModel,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
// Onboarding scaffold: tmux-shell AgentConnector.
|
|
1
|
+
// Onboarding scaffold: tmux-shell AgentConnector.
|
|
2
2
|
//
|
|
3
3
|
// Delivers skill output to a named tmux session via `tmux send-keys`.
|
|
4
4
|
// Matches what nanoclaw-style agent harnesses do internally — adopters
|
|
5
|
-
// with agents running in tmux sessions can wire `# Output:
|
|
6
|
-
//
|
|
5
|
+
// with agents running in tmux sessions can wire `# Output: agent: <agent>`
|
|
6
|
+
// end-to-end against this impl.
|
|
7
7
|
//
|
|
8
8
|
// **Scope.** Implements `deliver()` + `list_agents()` + `wake()` +
|
|
9
|
-
// `manifest()` per the
|
|
9
|
+
// `manifest()` per the AgentConnector contract. `wake()` is a no-op
|
|
10
10
|
// here (tmux panes are always live; wake is for harnesses with sleep modes).
|
|
11
11
|
|
|
12
12
|
import { spawn } from "node:child_process";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillscript-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "Runtime, compiler, lint, CLI, and dashboard for Skillscript — a small declarative language for authoring agent workflows.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Scott Shwarts <scotts@pobox.com>",
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Skill: cut-release-tag
|
|
2
|
-
# Status: Approved v1:d3c2a91b
|
|
3
|
-
# Description: Run when the user says "ship a release" or "cut a tag" on the current branch; collects commit-list since last tag, asks the user to confirm the version bump, applies the tag, and pushes it
|
|
4
|
-
# Vars: BUMP_KIND=patch
|
|
5
|
-
# Output: text
|
|
6
|
-
|
|
7
|
-
last_tag:
|
|
8
|
-
shell(command="git describe --tags --abbrev=0") -> PREV_TAG
|
|
9
|
-
else:
|
|
10
|
-
$set PREV_TAG = "(no prior tags)"
|
|
11
|
-
emit(text="no previous tag found; treating this as the first release")
|
|
12
|
-
|
|
13
|
-
commits_since:
|
|
14
|
-
needs: last_tag
|
|
15
|
-
shell(command="git log --oneline \"${PREV_TAG}\"..HEAD") -> COMMITS
|
|
16
|
-
else:
|
|
17
|
-
$set COMMITS = "(unable to read commit log; proceeding without preview)"
|
|
18
|
-
|
|
19
|
-
propose:
|
|
20
|
-
needs: commits_since
|
|
21
|
-
$ llm prompt="Propose the next semver tag given prev tag '${PREV_TAG}', bump kind '${BUMP_KIND}', and commits below. Return ONLY the new tag string (e.g. v1.4.3). No commentary.\n\nCommits:\n${COMMITS}" maxTokens=30 -> PROPOSED_TAG
|
|
22
|
-
|
|
23
|
-
confirm:
|
|
24
|
-
needs: propose
|
|
25
|
-
emit(text="Previous tag: ${PREV_TAG}")
|
|
26
|
-
emit(text="Commits since:")
|
|
27
|
-
emit(text="${COMMITS}")
|
|
28
|
-
emit(text="Proposed new tag: ${PROPOSED_TAG|trim}")
|
|
29
|
-
ask(prompt="Cut tag ${PROPOSED_TAG|trim}?") -> APPROVED
|
|
30
|
-
|
|
31
|
-
apply:
|
|
32
|
-
needs: confirm
|
|
33
|
-
shell(command="git tag \"${PROPOSED_TAG|trim}\"") -> TAG_OUT
|
|
34
|
-
shell(command="git push origin \"${PROPOSED_TAG|trim}\"") -> PUSH_OUT
|
|
35
|
-
emit(text="Tagged and pushed ${PROPOSED_TAG|trim}")
|
|
36
|
-
else:
|
|
37
|
-
emit(text="Tag/push failed; rolling back local tag")
|
|
38
|
-
shell(command="git tag -d \"${PROPOSED_TAG|trim}\"") -> ROLLBACK
|
|
39
|
-
|
|
40
|
-
default: apply
|