skillscript-runtime 0.9.9 → 0.13.2
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 +39 -46
- package/dist/bootstrap.d.ts +57 -18
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +188 -54
- package/dist/bootstrap.js.map +1 -1
- package/dist/cli.js +5 -6
- package/dist/cli.js.map +1 -1
- package/dist/connectors/agent-noop.d.ts +2 -2
- package/dist/connectors/agent-noop.d.ts.map +1 -1
- package/dist/connectors/config.d.ts +46 -0
- package/dist/connectors/config.d.ts.map +1 -1
- package/dist/connectors/config.js +109 -1
- package/dist/connectors/config.js.map +1 -1
- package/dist/connectors/index.d.ts +3 -1
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +6 -3
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/local-model-mcp.d.ts +3 -3
- package/dist/connectors/local-model-mcp.d.ts.map +1 -1
- package/dist/connectors/local-model.d.ts +30 -11
- package/dist/connectors/local-model.d.ts.map +1 -1
- package/dist/connectors/local-model.js +44 -12
- package/dist/connectors/local-model.js.map +1 -1
- package/dist/connectors/mcp-remote.d.ts +3 -3
- package/dist/connectors/mcp-remote.d.ts.map +1 -1
- package/dist/connectors/mcp.d.ts +3 -3
- package/dist/connectors/mcp.d.ts.map +1 -1
- package/dist/connectors/memory-store-mcp.d.ts +3 -3
- package/dist/connectors/memory-store-mcp.d.ts.map +1 -1
- package/dist/connectors/memory-store-mcp.js +3 -1
- package/dist/connectors/memory-store-mcp.js.map +1 -1
- package/dist/connectors/memory-store.d.ts +26 -6
- package/dist/connectors/memory-store.d.ts.map +1 -1
- package/dist/connectors/memory-store.js +84 -15
- package/dist/connectors/memory-store.js.map +1 -1
- package/dist/connectors/registry.d.ts +28 -5
- package/dist/connectors/registry.d.ts.map +1 -1
- package/dist/connectors/registry.js +34 -11
- package/dist/connectors/registry.js.map +1 -1
- package/dist/connectors/skill-store.d.ts +3 -3
- package/dist/connectors/skill-store.d.ts.map +1 -1
- package/dist/connectors/sqlite-skill-store.d.ts +89 -0
- package/dist/connectors/sqlite-skill-store.d.ts.map +1 -0
- package/dist/connectors/sqlite-skill-store.js +506 -0
- package/dist/connectors/sqlite-skill-store.js.map +1 -0
- package/dist/connectors/types.d.ts +86 -9
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/connectors/types.js.map +1 -1
- package/dist/errors.d.ts +15 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +47 -6
- package/dist/errors.js.map +1 -1
- package/dist/help-content.d.ts.map +1 -1
- package/dist/help-content.js +18 -4
- package/dist/help-content.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/runtime-config.d.ts +0 -2
- package/dist/runtime-config.d.ts.map +1 -1
- package/dist/runtime-config.js +1 -1
- package/dist/runtime-config.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +29 -30
- package/dist/runtime.js.map +1 -1
- package/dist/testing/conformance.d.ts.map +1 -1
- package/dist/testing/conformance.js +12 -6
- package/dist/testing/conformance.js.map +1 -1
- package/examples/README.md +13 -13
- package/examples/connectors/LocalModelTemplate/LocalModelTemplate.ts +138 -0
- package/examples/connectors/LocalModelTemplate/README.md +134 -0
- package/examples/connectors/McpConnectorTemplate/McpConnectorTemplate.ts +200 -0
- package/examples/connectors/McpConnectorTemplate/README.md +153 -0
- package/examples/connectors/MemoryStoreTemplate/MemoryStoreTemplate.ts +155 -0
- package/examples/connectors/MemoryStoreTemplate/README.md +169 -0
- package/examples/connectors/README.md +47 -0
- package/examples/connectors/SkillStoreTemplate/README.md +143 -0
- package/examples/connectors/SkillStoreTemplate/SkillStoreTemplate.ts +199 -0
- package/examples/{hello.skill.provenance.json → skillscripts/hello.skill.provenance.json} +1 -1
- package/package.json +1 -1
- package/scaffold/config.toml +8 -12
- package/scaffold/connectors.json +31 -3
- /package/examples/{classify-support-ticket.skill.md → skillscripts/classify-support-ticket.skill.md} +0 -0
- /package/examples/{cut-release-tag.skill.md → skillscripts/cut-release-tag.skill.md} +0 -0
- /package/examples/{doc-qa-with-citations.skill.md → skillscripts/doc-qa-with-citations.skill.md} +0 -0
- /package/examples/{feedback-sentiment-scan.skill.md → skillscripts/feedback-sentiment-scan.skill.md} +0 -0
- /package/examples/{hello.skill.md → skillscripts/hello.skill.md} +0 -0
- /package/examples/{morning-brief.skill.md → skillscripts/morning-brief.skill.md} +0 -0
- /package/examples/{queue-length-monitor.skill.md → skillscripts/queue-length-monitor.skill.md} +0 -0
- /package/examples/{service-health-watch.skill.md → skillscripts/service-health-watch.skill.md} +0 -0
- /package/examples/{youtrack-morning-sweep.skill.md → skillscripts/youtrack-morning-sweep.skill.md} +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# SkillStoreTemplate — fork-me skeleton
|
|
2
|
+
|
|
3
|
+
A skeleton `SkillStore` implementation for adopters writing their own. Not runnable; every method throws a `TODO` error. Copy this directory, rename, fill in the substrate-specific work.
|
|
4
|
+
|
|
5
|
+
Use this when you want skillscript skills backed by:
|
|
6
|
+
- A database the bundled impls don't cover (Postgres, MySQL, MongoDB, etc.)
|
|
7
|
+
- A vector store (Pinecone, Weaviate, Qdrant)
|
|
8
|
+
- A memory system (AMP, hosted memory API)
|
|
9
|
+
- An HTTP CRUD service
|
|
10
|
+
- Anything else with a query/write interface
|
|
11
|
+
|
|
12
|
+
## The three legs
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
SkillStore (choose which connector)
|
|
16
|
+
├── FilesystemSkillStore (bundled, FS-backed — src/connectors/skill-store.ts)
|
|
17
|
+
├── SqliteSkillStore (bundled, DB-backed — src/connectors/sqlite-skill-store.ts)
|
|
18
|
+
└── Your fork from this template
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The runtime is substrate-agnostic. Skills don't know which backend they're stored against — the contract is the `SkillStore` interface, and any class implementing it works.
|
|
22
|
+
|
|
23
|
+
## Forking workflow
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cp -r examples/connectors/SkillStoreTemplate examples/connectors/MyDatabaseSkillStore
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
1. **Rename the class.** Convention: `<Substrate>SkillStore` (e.g., `PostgresSkillStore`, `PineconeSkillStore`, `AmpSkillStore`).
|
|
30
|
+
2. **Define your config interface.** Edit `SkillStoreTemplateConfig` to declare what your substrate needs (connection URL, API key, vault name, etc.).
|
|
31
|
+
3. **Implement each method.** Eight methods + `staticCapabilities()`. Each has a TODO comment in the skeleton explaining what to do.
|
|
32
|
+
4. **Update `staticCapabilities()`** to declare what your impl actually supports. The runtime + lint consult these flags before exercising features.
|
|
33
|
+
5. **Wire from your adopter bootstrap:**
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { Registry } from "skillscript-runtime";
|
|
37
|
+
import { MyDatabaseSkillStore } from "./MyDatabaseSkillStore.js";
|
|
38
|
+
|
|
39
|
+
const registry = new Registry();
|
|
40
|
+
registry.registerSkillStore("primary", new MyDatabaseSkillStore({
|
|
41
|
+
// your config
|
|
42
|
+
}));
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
6. **Validate via the conformance suite:**
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { describe, it } from "vitest";
|
|
49
|
+
import { SkillStoreConformance } from "skillscript-runtime/testing";
|
|
50
|
+
import { MyDatabaseSkillStore } from "./MyDatabaseSkillStore.js";
|
|
51
|
+
|
|
52
|
+
describe("MyDatabaseSkillStore conformance", () => {
|
|
53
|
+
const tests = SkillStoreConformance.buildTests({
|
|
54
|
+
build: () => new MyDatabaseSkillStore({ /* test config */ }),
|
|
55
|
+
ctor: MyDatabaseSkillStore,
|
|
56
|
+
});
|
|
57
|
+
for (const t of tests) it(`[${t.category}] ${t.name}`, t.run);
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The conformance suite verifies your impl honors the contract: method presence, return-type shape, error-class throw conditions, capability flag self-consistency. If it passes, the runtime treats your impl interchangeably with the bundled defaults.
|
|
62
|
+
|
|
63
|
+
## Reference implementations
|
|
64
|
+
|
|
65
|
+
When in doubt about semantics, read the bundled impls:
|
|
66
|
+
|
|
67
|
+
- **`src/connectors/skill-store.ts`** — `FilesystemSkillStore`, filesystem-backed. Skills as `.skill.md` files; version history in a sidecar `.versions.jsonl`. Simplest reference.
|
|
68
|
+
- **`src/connectors/sqlite-skill-store.ts`** — `SqliteSkillStore`, SQLite-backed. Two-table schema, transactional status transitions, WAL, JSON-extract tag filter. Closest reference for any database-backed fork.
|
|
69
|
+
|
|
70
|
+
Both implement the same `SkillStore` interface; the differences are in the substrate-specific code.
|
|
71
|
+
|
|
72
|
+
## Approval token semantics
|
|
73
|
+
|
|
74
|
+
The runtime ships an approval-token mechanism so headless MCP-only adopters get a runnable `Approved` state without a dashboard round-trip. When you `store()` or `update_status()` a body declaring `# Status: Approved`, the impl should stamp `# Status: Approved v1:<hex>` automatically.
|
|
75
|
+
|
|
76
|
+
Helpers from `src/approval.ts`:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { extractStatusFromBody, stampApprovalToken } from "skillscript-runtime";
|
|
80
|
+
|
|
81
|
+
// In store():
|
|
82
|
+
const extracted = extractStatusFromBody(source);
|
|
83
|
+
const body = extracted?.status === "Approved" ? stampApprovalToken(source) : source;
|
|
84
|
+
|
|
85
|
+
// In update_status() — when transitioning TO Approved:
|
|
86
|
+
const updated = status === "Approved"
|
|
87
|
+
? stampApprovalToken(rewriteStatusHeader(source, "Approved"))
|
|
88
|
+
: rewriteStatusHeader(source, status);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Both bundled impls follow this pattern; your fork should too unless you're explicitly disabling approval tokens.
|
|
92
|
+
|
|
93
|
+
## Error classes to throw
|
|
94
|
+
|
|
95
|
+
From `src/errors.ts`:
|
|
96
|
+
|
|
97
|
+
- **`SkillNotFoundError(name, implementationName)`** — `load()` / `metadata()` / `versions()` / `update_status()` / `delete()` on a missing skill
|
|
98
|
+
- **`VersionNotFoundError(name, version, implementationName)`** — `load(name, version)` where `name` exists but `version` doesn't
|
|
99
|
+
- **`StorageConflictError(name, reason, implementationName)`** — `store()` rejects (e.g., name violates substrate constraints)
|
|
100
|
+
|
|
101
|
+
The `implementationName` is your class name — let cold authors trace errors back to the substrate.
|
|
102
|
+
|
|
103
|
+
## Schema-level decisions
|
|
104
|
+
|
|
105
|
+
Document your substrate's particulars in a README alongside your fork:
|
|
106
|
+
|
|
107
|
+
- **Versioning shape** — full body bytes per version (rich audit), or just hash + status (lightweight)?
|
|
108
|
+
- **Delete semantics** — hard-cascade (removes versions) or preserve (audit-grade retention)?
|
|
109
|
+
- **Concurrency model** — single-writer, multi-reader (e.g., WAL), or fully concurrent?
|
|
110
|
+
- **Tag filter** — indexed lookup, table scan, or unsupported?
|
|
111
|
+
|
|
112
|
+
These trade-offs are substrate-side; the contract just specifies what each method does, not how.
|
|
113
|
+
|
|
114
|
+
## Wiring against the CLI / dashboard
|
|
115
|
+
|
|
116
|
+
Runtime hosts (MCP server + web dashboard) honor whichever SkillStore impl your registry has. To make your fork visible through `skillfile dashboard`:
|
|
117
|
+
|
|
118
|
+
- Write a custom bootstrap that constructs the runtime with your SkillStore (see `src/bootstrap.ts` for the reference shape + `docs/adopter-playbook.md` for the pattern)
|
|
119
|
+
- OR (planned future) declare in `~/.skillscript/connectors.json`:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"substrate": {
|
|
124
|
+
"skill_store": {
|
|
125
|
+
"type": "custom",
|
|
126
|
+
"module": "./my-database-skill-store.js",
|
|
127
|
+
"export": "MyDatabaseSkillStore",
|
|
128
|
+
"config": { "postgresUrl": "${POSTGRES_URL}" }
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Current limitation: sync `bootstrap()` can't dynamic-import, so the `custom` form surfaces an error today. Programmatic bootstrap is the path until async-bootstrap support lands.
|
|
135
|
+
|
|
136
|
+
The bundled CLI authoring commands (`skillfile compile`, `skillfile lint`, `skillfile audit`, `skillfile list`) stay filesystem-pinned by design — they're the FS-authoring loop. Adopter-substrate skills are authored via the dashboard UI or the `skill_write` MCP tool.
|
|
137
|
+
|
|
138
|
+
## Further reading
|
|
139
|
+
|
|
140
|
+
- **[`docs/configuration.md`](../../../docs/configuration.md)** — substrate selection via `connectors.json`
|
|
141
|
+
- **[`docs/sqlite-skill-store.md`](../../../docs/sqlite-skill-store.md)** — the bundled SqliteSkillStore's schema + semantics + forking checklist
|
|
142
|
+
- **`src/connectors/types.ts`** — authoritative `SkillStore` interface spec (lines 192-208)
|
|
143
|
+
- **`src/testing/conformance.ts`** — the conformance test suite
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SkillStoreTemplate — fork-me skeleton for writing your own SkillStore impl.
|
|
3
|
+
*
|
|
4
|
+
* This is NOT a runnable connector. Every method throws a "TODO" error. The
|
|
5
|
+
* purpose is to surface the SkillStore contract surface in a copy-and-customize
|
|
6
|
+
* shape so adopters writing Postgres-, MySQL-, MongoDB-, AMP-, or
|
|
7
|
+
* vector-DB-backed SkillStores have a starting skeleton.
|
|
8
|
+
*
|
|
9
|
+
* Forking workflow:
|
|
10
|
+
* 1. Copy this directory into your codebase (`cp -r examples/connectors/SkillStoreTemplate examples/connectors/MyDatabaseSkillStore`)
|
|
11
|
+
* 2. Rename the class — typically `<Substrate>SkillStore` (e.g., `PostgresSkillStore`)
|
|
12
|
+
* 3. Implement each method against your substrate's API
|
|
13
|
+
* 4. Update `staticCapabilities()` to declare what your impl actually supports
|
|
14
|
+
* 5. Register from your adopter bootstrap:
|
|
15
|
+
* `registry.registerSkillStore("primary", new MyDatabaseSkillStore({ ... }))`
|
|
16
|
+
* 6. Validate via the conformance suite:
|
|
17
|
+
* `SkillStoreConformance.buildTests({ build: () => new MyDatabaseSkillStore(...), ctor: MyDatabaseSkillStore })`
|
|
18
|
+
*
|
|
19
|
+
* See `src/connectors/sqlite-skill-store.ts` for a working reference
|
|
20
|
+
* implementation against SQLite + `node:sqlite`. See `src/connectors/skill-store.ts`
|
|
21
|
+
* for the bundled filesystem default. The full contract spec lives in
|
|
22
|
+
* `src/connectors/types.ts` (`SkillStore` interface, lines 192-208) and
|
|
23
|
+
* `docs/sqlite-skill-store.md` for schema + semantics depth.
|
|
24
|
+
*
|
|
25
|
+
* Runtime hosts (MCP server + web dashboard) honor whichever SkillStore impl
|
|
26
|
+
* you register via the registry, so once your fork passes the conformance
|
|
27
|
+
* suite the entire skillscript surface (skill_write / skill_list /
|
|
28
|
+
* execute_skill / etc.) reads + writes against your substrate.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import type {
|
|
32
|
+
SkillStore,
|
|
33
|
+
SkillSource,
|
|
34
|
+
SkillMeta,
|
|
35
|
+
SkillStatus,
|
|
36
|
+
SkillFilter,
|
|
37
|
+
VersionInfo,
|
|
38
|
+
SkillStoreCapabilities,
|
|
39
|
+
ManifestInfo,
|
|
40
|
+
} from "../../../src/connectors/types.js";
|
|
41
|
+
|
|
42
|
+
/** Replace with your substrate's connection config (host, dbName, credentials, etc.). */
|
|
43
|
+
export interface SkillStoreTemplateConfig {
|
|
44
|
+
// TODO — declare the fields your substrate needs to connect.
|
|
45
|
+
// Examples:
|
|
46
|
+
// postgresUrl?: string;
|
|
47
|
+
// pineconeApiKey?: string;
|
|
48
|
+
// ampVault?: string;
|
|
49
|
+
exampleConfigField?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export class SkillStoreTemplate implements SkillStore {
|
|
53
|
+
/**
|
|
54
|
+
* Declare what your impl supports. The runtime + lint consult these flags
|
|
55
|
+
* before exercising features. Set conservatively — overclaiming triggers
|
|
56
|
+
* cryptic downstream failures; underclaiming hides usable features.
|
|
57
|
+
*/
|
|
58
|
+
static staticCapabilities(): SkillStoreCapabilities {
|
|
59
|
+
return {
|
|
60
|
+
connector_type: "skill_store",
|
|
61
|
+
implementation: "SkillStoreTemplate", // ← rename to your class name
|
|
62
|
+
contract_version: "1.0.0",
|
|
63
|
+
features: {
|
|
64
|
+
// TODO — set each flag based on what your substrate can actually do.
|
|
65
|
+
supports_writes: false, // can you persist new skills?
|
|
66
|
+
supports_versioning: false, // can you return historical bytes via load(name, version)?
|
|
67
|
+
supports_tag_filter: false, // can query() filter by tag?
|
|
68
|
+
supports_audit_trail: false, // does update_status populate previous_status?
|
|
69
|
+
supports_atomic_status_transitions: false, // can UPDATE + INSERT versions be transactional?
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
75
|
+
constructor(_config: SkillStoreTemplateConfig) {
|
|
76
|
+
// TODO — establish your substrate connection. For SQL: open the database
|
|
77
|
+
// + run schema migrations. For HTTP: store the base URL + auth headers.
|
|
78
|
+
// For AMP/Pinecone: cache the SDK client.
|
|
79
|
+
throw new Error("SkillStoreTemplate is a fork-me skeleton; replace with your impl.");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Capability snapshot for `runtime_capabilities` discovery. Return free-form
|
|
84
|
+
* substrate-specific metadata (kind, version, supported modes, etc.).
|
|
85
|
+
*/
|
|
86
|
+
async manifest(): Promise<ManifestInfo<"skill_store">> {
|
|
87
|
+
// TODO — return a snapshot of your substrate's capabilities.
|
|
88
|
+
throw new Error("TODO: manifest() — return substrate-specific capability snapshot.");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Read the skill body bytes + metadata. If `version` is supplied, return
|
|
93
|
+
* historical bytes (or throw `VersionNotFoundError` if the version is
|
|
94
|
+
* unknown). If the skill doesn't exist at all, throw `SkillNotFoundError`.
|
|
95
|
+
*/
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
97
|
+
async load(_name: string, _version?: string): Promise<SkillSource> {
|
|
98
|
+
// TODO — fetch the skill record from your substrate.
|
|
99
|
+
// - Return SkillSource { name, version, content_hash, source, metadata }
|
|
100
|
+
// - Throw SkillNotFoundError if name doesn't exist
|
|
101
|
+
// - Throw VersionNotFoundError if version is supplied but unknown
|
|
102
|
+
throw new Error("TODO: load() — fetch skill source by name (+ optional version).");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* List skill metadata. Apply the filter where your substrate supports it;
|
|
107
|
+
* fall back to client-side filtering for unsupported fields. Empty result
|
|
108
|
+
* is fine; never throw "not found" — return [].
|
|
109
|
+
*/
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
111
|
+
async query(_filter?: SkillFilter): Promise<SkillMeta[]> {
|
|
112
|
+
// TODO — query your substrate for skill metadata.
|
|
113
|
+
// - Apply filter.status / filter.tag / filter.author / etc. as supported
|
|
114
|
+
// - Honor filter.limit + filter.offset
|
|
115
|
+
// - Never throw on no matches; return []
|
|
116
|
+
throw new Error("TODO: query() — return SkillMeta[] honoring the filter.");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Read skill metadata without the body bytes. Equivalent to `load()` but
|
|
121
|
+
* skips the `source` field — useful for listings + introspection where
|
|
122
|
+
* the body isn't needed.
|
|
123
|
+
*/
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
125
|
+
async metadata(_name: string): Promise<SkillMeta> {
|
|
126
|
+
// TODO — return SkillMeta for `name`. Throw SkillNotFoundError if missing.
|
|
127
|
+
throw new Error("TODO: metadata() — return SkillMeta without body bytes.");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Return version history (chronological). Each entry has `version` +
|
|
132
|
+
* `content_hash` + `status` + `changed_at` + optional `previous_status`
|
|
133
|
+
* (audit trail). Throws `SkillNotFoundError` if the skill doesn't exist.
|
|
134
|
+
*
|
|
135
|
+
* If your substrate doesn't track versions, return a single-element array
|
|
136
|
+
* with the current state (and set `supports_versioning: false`).
|
|
137
|
+
*/
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
139
|
+
async versions(_name: string): Promise<VersionInfo[]> {
|
|
140
|
+
// TODO — return version chain. SQL substrates: SELECT FROM skill_versions
|
|
141
|
+
// ORDER BY changed_at. MemoryStore-style: query memories with the right tag.
|
|
142
|
+
throw new Error("TODO: versions() — return VersionInfo[] chronologically.");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Persist a skill (create or update). Compute content_hash from the source;
|
|
147
|
+
* append a new version row; update the current-version pointer. Returns
|
|
148
|
+
* `VersionInfo` for the new version.
|
|
149
|
+
*
|
|
150
|
+
* For atomicity, wrap your substrate writes in a transaction (or equivalent)
|
|
151
|
+
* so the version row is never created without the current-version pointer
|
|
152
|
+
* updating, and vice versa.
|
|
153
|
+
*/
|
|
154
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
155
|
+
async store(_name: string, _source: string, _metadata?: Partial<SkillMeta>): Promise<VersionInfo> {
|
|
156
|
+
// TODO — persist the skill source bytes + metadata.
|
|
157
|
+
// - Compute content_hash (SHA-256 of source) + version (short hash)
|
|
158
|
+
// - Auto-stamp approval token if body declares Approved (see
|
|
159
|
+
// src/approval.ts → stampApprovalToken / extractStatusFromBody)
|
|
160
|
+
// - Write to your substrate atomically
|
|
161
|
+
// - Return VersionInfo
|
|
162
|
+
throw new Error("TODO: store() — persist skill source + metadata.");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Hard-delete the skill (substrate-only — referential integrity is the
|
|
167
|
+
* runtime's concern). Whether to cascade version history is your substrate
|
|
168
|
+
* choice; the bundled SqliteSkillStore cascades (rationale in
|
|
169
|
+
* `docs/sqlite-skill-store.md`).
|
|
170
|
+
*
|
|
171
|
+
* Throws `SkillNotFoundError` if `name` doesn't exist (so adopters get a
|
|
172
|
+
* clear error rather than a silent no-op).
|
|
173
|
+
*/
|
|
174
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
175
|
+
async delete(_name: string): Promise<void> {
|
|
176
|
+
// TODO — remove the skill from your substrate. Decide cascade vs preserve
|
|
177
|
+
// history per your compliance needs. Throw SkillNotFoundError if missing.
|
|
178
|
+
throw new Error("TODO: delete() — remove skill (+ optionally history).");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Transition a skill's status (Draft / Approved / Disabled). Updates the
|
|
183
|
+
* current state + appends a `skill_versions` row with `previous_status`
|
|
184
|
+
* populated (audit trail). Wrap in a transaction for atomicity.
|
|
185
|
+
*
|
|
186
|
+
* Approved transitions should stamp the approval token (see
|
|
187
|
+
* `src/approval.ts`); transitions away from Approved should strip it.
|
|
188
|
+
*/
|
|
189
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
190
|
+
async update_status(_name: string, _status: SkillStatus): Promise<VersionInfo> {
|
|
191
|
+
// TODO — atomically update status + append audit row.
|
|
192
|
+
// - Load current status (for previous_status field)
|
|
193
|
+
// - Apply stampApprovalToken if status=Approved
|
|
194
|
+
// - Strip token if transitioning to Draft/Disabled
|
|
195
|
+
// - UPDATE skills SET status, INSERT skill_versions (transaction)
|
|
196
|
+
// - Return VersionInfo with previous_status populated
|
|
197
|
+
throw new Error("TODO: update_status() — atomic status transition + audit row.");
|
|
198
|
+
}
|
|
199
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillscript-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.2",
|
|
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>",
|
package/scaffold/config.toml
CHANGED
|
@@ -16,18 +16,14 @@ plugins_dir = "~/.skillscript/plugins"
|
|
|
16
16
|
# security-conscious deployments invert this to ["packages"] only.
|
|
17
17
|
resolution_order = ["filesystem", "packages"]
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
kind = "ollama"
|
|
28
|
-
base_url = "http://localhost:11434"
|
|
29
|
-
model_tag = "qwen2.5:7b"
|
|
30
|
-
timeout_ms = 60000
|
|
19
|
+
# LocalModel wiring lives in `connectors.json` under `substrate.local_model`,
|
|
20
|
+
# NOT here. v0.10+ moved substrate selection out of this file. Example:
|
|
21
|
+
# {
|
|
22
|
+
# "substrate": {
|
|
23
|
+
# "local_model": { "type": "ollama", "config": { "defaultModelTag": "gemma2:9b" } }
|
|
24
|
+
# }
|
|
25
|
+
# }
|
|
26
|
+
# See docs/configuration.md.
|
|
31
27
|
|
|
32
28
|
[runtime]
|
|
33
29
|
# `@@` opt-in unsafe shell. Disabled by default. v1 spec gates this behind
|
package/scaffold/connectors.json
CHANGED
|
@@ -1,9 +1,37 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_comment": "Per-host connector wiring. Copied to ~/.skillscript/connectors.json by `skillfile init`.
|
|
2
|
+
"_comment": "Per-host connector wiring. Copied to ~/.skillscript/connectors.json by `skillfile init`. The top-level `substrate` key selects singleton substrate connectors (SkillStore, MemoryStore, LocalModel). All other top-level keys define named MCP connector instances referenced via `$ name args` in skill source.",
|
|
3
3
|
|
|
4
|
-
"_comment_substrate": "
|
|
4
|
+
"_comment_substrate": "Substrate selection — runtime hosts (MCP server + web dashboard) honor whatever you configure here. The bundled CLI authoring commands (`skillfile compile`, `skillfile lint`, `skillfile audit`, `skillfile list`) stay filesystem-pinned regardless — they're the FS-authoring loop. Three legs: bundled filesystem, bundled sqlite, adopter-custom (write your own SkillStore impl).",
|
|
5
5
|
|
|
6
|
-
"
|
|
6
|
+
"_comment_substrate_forms": "Each substrate slot accepts: (a) bare string for built-in types — \"filesystem\", \"sqlite\", \"ollama\"; (b) null to explicitly disable; (c) object form `{type, config}` to override defaults; (d) object form `{type:\"custom\", module, export, config}` for adopter-custom impls (requires programmatic bootstrap; sync `bootstrap()` doesn't dynamic-import).",
|
|
7
|
+
|
|
8
|
+
"substrate": {
|
|
9
|
+
"skill_store": "filesystem",
|
|
10
|
+
"memory_store": "sqlite",
|
|
11
|
+
"local_model": null,
|
|
12
|
+
|
|
13
|
+
"_example_sqlite_skills": "Uncomment to switch skill storage to SQLite. Adopter-portable; persists between restarts. dbPath defaults to <skillsDir>/skills.db.",
|
|
14
|
+
"_example_sqlite_skills_object": {
|
|
15
|
+
"type": "sqlite",
|
|
16
|
+
"config": { "dbPath": "/var/skillscript/skills.db" }
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"_example_ollama": "Uncomment to wire OllamaLocalModel as the primary LocalModel. Default baseUrl is OLLAMA_BASE_URL env or http://localhost:11434.",
|
|
20
|
+
"_example_ollama_object": {
|
|
21
|
+
"type": "ollama",
|
|
22
|
+
"config": { "baseUrl": "http://gpu-host:11434", "defaultModelTag": "gemma2:9b" }
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"_example_custom": "Adopter-custom impl. Write `class FooSkillStore implements SkillStore { ... }` then reference it here. NOTE — this form requires a programmatic bootstrap (sync `bootstrap()` can't dynamic-import). Wire via your own bootstrap script today; declarative custom config is a planned follow-up.",
|
|
26
|
+
"_example_custom_object": {
|
|
27
|
+
"type": "custom",
|
|
28
|
+
"module": "./my-amp-skill-store.js",
|
|
29
|
+
"export": "AmpSkillStore",
|
|
30
|
+
"config": { "vault": "team" }
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
"_comment_classes": "Closed-set class registry for MCP connectors. Available: `RemoteMcpConnector` (stdio-bridged remote MCP). Use `runtime_capabilities({include:['mcpConnectorClasses']})` to introspect the available class set. The `LocalModelMcpConnector` + `MemoryStoreMcpConnector` bridges (for `$ llm` / `$ memory` canonical dispatch) auto-wire when their substrates are configured above.",
|
|
7
35
|
|
|
8
36
|
"_comment_security": "This file is secret-bearing when filled with real credentials. The repo's `.gitignore` excludes `connectors.json` (the live copy) but tracks `connectors.json.example`. Prefer `${VAR}` substitution over in-file literals for deployments.",
|
|
9
37
|
|
/package/examples/{classify-support-ticket.skill.md → skillscripts/classify-support-ticket.skill.md}
RENAMED
|
File without changes
|
|
File without changes
|
/package/examples/{doc-qa-with-citations.skill.md → skillscripts/doc-qa-with-citations.skill.md}
RENAMED
|
File without changes
|
/package/examples/{feedback-sentiment-scan.skill.md → skillscripts/feedback-sentiment-scan.skill.md}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/examples/{queue-length-monitor.skill.md → skillscripts/queue-length-monitor.skill.md}
RENAMED
|
File without changes
|
/package/examples/{service-health-watch.skill.md → skillscripts/service-health-watch.skill.md}
RENAMED
|
File without changes
|
/package/examples/{youtrack-morning-sweep.skill.md → skillscripts/youtrack-morning-sweep.skill.md}
RENAMED
|
File without changes
|