openvibers/openvibe.contracts Commits

0.343.0: actor.skill@2 and skill-listing@2 — skills that run code in a sandbox (HO8) (#351)

OP OpenVibers committed 5 days ago · d6c22f1a80 · 68 files, +10675 −683

* 0.342.0: actor.skill@2 and skill-listing@2, skills that run code sandboxed (HO8)

* Merge remote-tracking branch 'origin/main' into ho8-contracts-skill-v2

# Conflicts:
#	CHANGELOG.md
#	package-lock.json

* ADR-060 accepted after Opus's security review

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex a345a403..f7711cd7 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -1,5 +1,17 @@
# Changelog
++## 0.343.0 — 2026-11-08
++
++- Add `actor.skill@2` and `actor.skill-listing@2` (ADR-060, plan HO8): a skill may now bring code that runs in a
++ sandbox instead of only a prompt. `runs` is `prompt` or `sandbox`; a sandbox skill carries 1 to 5 JavaScript
++ `tools` (name, description, `entry` naming one of its resources, a JSON Schema subset for `args`, `net`
++ `deny`/`openvibe-only`/`public` default `deny`, and limits under 30 s / 256 MiB), and the code itself is an
++ ordinary text resource (`.js`, at most 64 KiB) in the same integrity hash. `requires.kinds` gains `skill.run`.
++ The v2 listing pins each code resource's Media id and sha256 and lets a scan finding name the tool it is about.
++ Code never runs on an OpenVibe server, never outside a sandbox and never with a secret: it runs as a Run
++ `function` job on a Node that declared the skill runner. `actor.skill@1` and `actor.skill-listing@1` are
++ unchanged and remain what a prompt-only skill publishes.
++
## 0.342.0 — 2026-11-07
- Add `mail.agent_inbox.received@1` (track HO6, channels): a message arrived at an agent's own address and the person has switched that address's answering on, so their agent may read it. The payload names the inbox and the agent, the owner, the mail server's message id, the sender, the subject and a plain-text excerpt of at most 4000 characters. It never carries the attachments, the HTML or the whole body: the agent's system reads the text through `mail.agent.read`, on the owner's behalf, once it has decided to answer. Mail publishes nothing for a sender on the person's block list or a message the mail server marked as spam, and nothing at all until the person turns the agent's switch on.
ddiff --git a/contracts/actor/skill-listing.v2.json b/contracts/actor/skill-listing.v2.json
nnew file mode 100644
iindex 00000000..4e9553c0
---- /dev/null
++++ b/contracts/actor/skill-listing.v2.json
@@@ -0,0 +1,266 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/skill-listing.v2.json",
++ "title": "ActorSkillListingV2",
++ "description": "actor.skill-listing@2: a skill in the registry, the record every site shows on its card (ADR-058, ADR-060). It keeps every field and meaning of actor.skill-listing@1 and adds what a sandbox skill needs to be shown and run: the document is actor.skill@2, CODE lists, per code resource, its name (the resource path a tool's entry names), the Media object id its bytes are stored under and the sha256 of those bytes, so the bytes that run are the bytes that were scanned; and the SCAN's findings may name the TOOL they are about, so a person reads the scan one tool at a time. A sandbox listing carries code; a prompt listing carries none. It still carries the PUBLISHER from the registry's own record (vouched: unlike the document's author, this is who published it), the SCAN (its state and findings travel with the listing), and the CURATOR's state. Install rules every site keeps: a passed skill installs in one tap; a flagged one only after the person reads the findings and confirms; a failed one never; a stale or archived one is not offered. Installing copies the document into the person's agent; it grants nothing (the skill's requires is a declaration).",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "listing",
++ "id",
++ "skill",
++ "publisher",
++ "scan",
++ "curator",
++ "listed_at"
++ ],
++ "properties": {
++ "listing": {
++ "const": "actor.skill-listing@2"
++ },
++ "id": {
++ "type": "string",
++ "pattern": "^skl_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The listing's id."
++ },
++ "skill": {
++ "$ref": "skill.v2.json",
++ "description": "The document as published."
++ },
++ "code": {
++ "type": "array",
++ "maxItems": 10,
++ "uniqueItems": true,
++ "description": "Per code resource of a sandbox skill: the resource path a tool entry names, the Media object the registry stored its bytes under, and the sha256 of those bytes. Required when the skill runs in a sandbox; absent for a prompt skill.",
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "name",
++ "media_id",
++ "sha256"
++ ],
++ "properties": {
++ "name": {
++ "type": "string",
++ "pattern": "^[a-z0-9][a-z0-9_-]{0,59}(?:/[a-z0-9][a-z0-9_-]{0,59}){0,3}\\.js$",
++ "description": "The resource path, as the document's tools entry names it."
++ },
++ "media_id": {
++ "type": "string",
++ "pattern": "^med_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The Media object id the code bytes are stored under."
++ },
++ "sha256": {
++ "type": "string",
++ "pattern": "^[0-9a-f]{64}$",
++ "description": "Lowercase hex SHA-256 of the code bytes."
++ }
++ }
++ }
++ },
++ "publisher": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "kind"
++ ],
++ "description": "Who published it, from the registry's own record.",
++ "properties": {
++ "kind": {
++ "type": "string",
++ "enum": [
++ "openvibe",
++ "person"
++ ],
++ "description": "OpenVibe's own skills, or a person's."
++ },
++ "subject": {
++ "type": "string",
++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The person who published it (kind person)."
++ },
++ "name": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ }
++ }
++ },
++ "scan": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "state"
++ ],
++ "description": "What the registry's scan found. It travels with the listing, and a finding about a tool names it.",
++ "properties": {
++ "state": {
++ "type": "string",
++ "enum": [
++ "pending",
++ "passed",
++ "flagged",
++ "failed"
++ ]
++ },
++ "scanner": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80,
++ "description": "The scanner and its version."
++ },
++ "scanned_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "findings": {
++ "type": "array",
++ "maxItems": 50,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "rule",
++ "severity",
++ "note"
++ ],
++ "properties": {
++ "rule": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_.-]{1,63}$",
++ "description": "Which rule, such as code.network or code.env."
++ },
++ "severity": {
++ "type": "string",
++ "enum": [
++ "info",
++ "warn",
++ "block"
++ ]
++ },
++ "where": {
++ "type": "string",
++ "maxLength": 120,
++ "description": "instructions, description, or a resource path."
++ },
++ "tool": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_]{0,31}$",
++ "description": "The tool the finding is about, when it is about one tool."
++ },
++ "note": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 280,
++ "description": "What it found, in plain words."
++ }
++ }
++ }
++ }
++ }
++ },
++ "curator": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "state"
++ ],
++ "description": "The curator ships with the catalogue: what is used stays, what is not goes stale.",
++ "properties": {
++ "state": {
++ "type": "string",
++ "enum": [
++ "active",
++ "stale",
++ "archived"
++ ]
++ },
++ "last_used_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "near_duplicate_of": {
++ "type": "string",
++ "pattern": "^skl_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "A listing that does the same job."
++ }
++ }
++ },
++ "installs": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "listed_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "retired_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ },
++ "allOf": [
++ {
++ "if": {
++ "properties": {
++ "skill": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "sandbox"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ }
++ },
++ "required": [
++ "skill"
++ ]
++ },
++ "then": {
++ "required": [
++ "code"
++ ],
++ "properties": {
++ "code": {
++ "type": "array",
++ "minItems": 1
++ }
++ }
++ }
++ },
++ {
++ "if": {
++ "properties": {
++ "skill": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "prompt"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ }
++ },
++ "required": [
++ "skill"
++ ]
++ },
++ "then": {
++ "not": {
++ "type": "object",
++ "required": [
++ "code"
++ ]
++ }
++ }
++ }
++ ]
++}
ddiff --git a/contracts/actor/skill.v2.json b/contracts/actor/skill.v2.json
nnew file mode 100644
iindex 00000000..3fe08176
---- /dev/null
++++ b/contracts/actor/skill.v2.json
@@@ -0,0 +1,577 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/skill.v2.json",
++ "title": "ActorSkillV2",
++ "description": "actor.skill@2: a skill, the document an agent loads to do one kind of job well (ADR-058, ADR-060). It keeps every field and meaning of actor.skill@1 and adds a way for the skill to bring CODE that runs in a sandbox: RUNS is prompt (as @1, text and instructions only) or sandbox. A sandbox skill carries its code as ordinary TEXT resources (a .js path with media_type text/javascript, at most 64 KiB each, in the integrity hash); TOOLS (1 to 5, only when runs is sandbox) say what an agent may call: a name, a description the agent reads, language javascript (the only one in v1), an ENTRY naming one of the skill's own .js resources, ARGS as a JSON Schema subset (an object whose properties are string, number, integer, boolean or an array of those; enum, maxLength, and pattern at most 200 characters; no $ref and no nested object), NET (deny by default, openvibe-only, public) and LIMITS (wall_ms at most 30000, default 10000; mem_bytes at most 268435456, default 134217728). A sandbox skill's requires.kinds names skill.run; a prompt skill declares no tools. A skill GRANTS NOTHING: requires only declares; the agent's level and approvals decide every step (actor approvals, HO1), and a step of a kind the skill did not declare is a scan finding (actor.skill-listing@2). Code never runs on an OpenVibe server and never sees a secret: it runs as a Run job of class function on a Node that declared the skill runner, with the network its tool declared and the exact bytes the registry scanned. The INTEGRITY block is a sha256 over the canonical JSON of the document: it shows the file was not edited after it was written and says nothing about who wrote it, so the AUTHOR is a claim; the registry's listing is the only place a publisher is vouched for. The canonical JSON is the document's own fields, in this order: skill, slug, name, description, version, instructions, resources, tools, requires, runs, license, author; an optional field that is absent or empty is left out; resources are [{ path, media_type, text }] in the document's order; tools are [{ name, description, language, entry, args, net, limits }] in the document's order, with an absent net or limits (and each absent limits field) left out and args as the object the document wrote; requires is { kinds, apps, hosts } with empty lists left out; author is { subject } or { subject, name }; the value is the compact JSON of that object (no spaces). CREATED_AT is not hashed.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "skill",
++ "slug",
++ "name",
++ "description",
++ "version",
++ "instructions",
++ "runs",
++ "integrity"
++ ],
++ "properties": {
++ "skill": {
++ "const": "actor.skill@2",
++ "description": "The document marker."
++ },
++ "slug": {
++ "type": "string",
++ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$",
++ "description": "Its name in the registry: lowercase letters, digits and hyphens."
++ },
++ "name": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80,
++ "description": "What a person reads on its card."
++ },
++ "description": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 280,
++ "description": "When to use it, in one line: the only part an agent reads before it loads the skill."
++ },
++ "version": {
++ "type": "string",
++ "pattern": "^(0|[1-9][0-9]{0,5})\\.(0|[1-9][0-9]{0,5})\\.(0|[1-9][0-9]{0,5})$",
++ "description": "Its semantic version."
++ },
++ "instructions": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 20000,
++ "description": "What to do, in Markdown. The agent reads it as guidance; it never grants a permission."
++ },
++ "resources": {
++ "type": "array",
++ "maxItems": 10,
++ "description": "Text the instructions refer to (a checklist, a template, a table) and, for a sandbox skill, the code a tool's entry names. Code is a text resource, not a binary and not an install recipe: it runs in a sandbox and never on an OpenVibe server. Any resource is at most 64 KiB; a non-code resource keeps @1's 20000-character cap.",
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "path",
++ "media_type",
++ "text"
++ ],
++ "properties": {
++ "path": {
++ "type": "string",
++ "pattern": "^[a-z0-9][a-z0-9_-]{0,59}(?:/[a-z0-9][a-z0-9_-]{0,59}){0,3}\\.(md|txt|json|csv|js)$",
++ "description": "A relative name, no \"..\", ending in .md, .txt, .json, .csv or .js. A .js resource is code and is named by a tool's entry."
++ },
++ "media_type": {
++ "type": "string",
++ "enum": [
++ "text/markdown",
++ "text/plain",
++ "application/json",
++ "text/csv",
++ "text/javascript"
++ ]
++ },
++ "text": {
++ "type": "string",
++ "maxLength": 65536
++ }
++ },
++ "allOf": [
++ {
++ "if": {
++ "properties": {
++ "path": {
++ "type": "string",
++ "pattern": "\\.js$"
++ }
++ },
++ "required": [
++ "path"
++ ]
++ },
++ "then": {
++ "properties": {
++ "media_type": {
++ "type": "string",
++ "const": "text/javascript"
++ },
++ "text": {
++ "type": "string",
++ "maxLength": 65536,
++ "description": "At most 64 KiB of code."
++ }
++ }
++ }
++ },
++ {
++ "if": {
++ "properties": {
++ "media_type": {
++ "type": "string",
++ "const": "text/javascript"
++ }
++ },
++ "required": [
++ "media_type"
++ ]
++ },
++ "then": {
++ "properties": {
++ "path": {
++ "type": "string",
++ "pattern": "\\.js$"
++ }
++ }
++ }
++ },
++ {
++ "if": {
++ "properties": {
++ "media_type": {
++ "type": "string",
++ "enum": [
++ "text/markdown",
++ "text/plain",
++ "application/json",
++ "text/csv"
++ ]
++ }
++ },
++ "required": [
++ "media_type"
++ ]
++ },
++ "then": {
++ "properties": {
++ "text": {
++ "type": "string",
++ "maxLength": 20000
++ }
++ }
++ }
++ }
++ ]
++ }
++ },
++ "tools": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 5,
++ "description": "The tools an agent may call, present exactly when runs is sandbox. Each one runs the code in the resource its entry names, in a sandbox, with the network it declares and never wider.",
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "name",
++ "description",
++ "language",
++ "entry",
++ "args"
++ ],
++ "properties": {
++ "name": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_]{0,31}$",
++ "description": "The name the agent calls."
++ },
++ "description": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200,
++ "description": "What it does: the agent reads this before it calls the tool."
++ },
++ "language": {
++ "const": "javascript",
++ "description": "The only language in v1."
++ },
++ "entry": {
++ "type": "string",
++ "pattern": "^[a-z0-9][a-z0-9_-]{0,59}(?:/[a-z0-9][a-z0-9_-]{0,59}){0,3}\\.js$",
++ "description": "The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema)."
++ },
++ "args": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "type"
++ ],
++ "description": "The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.",
++ "properties": {
++ "type": {
++ "const": "object"
++ },
++ "description": {
++ "type": "string",
++ "maxLength": 200
++ },
++ "properties": {
++ "type": "object",
++ "maxProperties": 20,
++ "additionalProperties": {
++ "$ref": "#/$defs/argValue"
++ }
++ },
++ "required": {
++ "type": "array",
++ "maxItems": 20,
++ "uniqueItems": true,
++ "items": {
++ "type": "string",
++ "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,63}$"
++ }
++ },
++ "additionalProperties": {
++ "const": false
++ }
++ }
++ },
++ "net": {
++ "type": "string",
++ "enum": [
++ "deny",
++ "openvibe-only",
++ "public"
++ ],
++ "default": "deny",
++ "description": "The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this."
++ },
++ "limits": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "Caps on one run of the tool. Run treats them as declared, never above its own caps.",
++ "properties": {
++ "wall_ms": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 30000,
++ "default": 10000,
++ "description": "Wall-clock time, at most 30000 ms; default 10000."
++ },
++ "mem_bytes": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 268435456,
++ "default": 134217728,
++ "description": "Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB)."
++ }
++ }
++ }
++ }
++ }
++ },
++ "requires": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "What the skill may ask an agent to do. It grants nothing: each step still goes through the agent's level and approvals. A sandbox skill names skill.run here.",
++ "properties": {
++ "kinds": {
++ "type": "array",
++ "maxItems": 16,
++ "uniqueItems": true,
++ "items": {
++ "type": "string",
++ "enum": [
++ "codes.task",
++ "actor.action",
++ "computer.run",
++ "computer.write",
++ "computer.input",
++ "computer.browser",
++ "computer.desk",
++ "robot.move",
++ "space",
++ "publish",
++ "post",
++ "send",
++ "install",
++ "routine",
++ "money",
++ "skill.run"
++ ]
++ },
++ "description": "The kinds of act (actor approvals, HO1) its steps may be."
++ },
++ "apps": {
++ "type": "array",
++ "maxItems": 20,
++ "uniqueItems": true,
++ "items": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9._-]{0,63}$"
++ },
++ "description": "Connected apps it uses (connect slugs). The person connects each one themselves."
++ },
++ "hosts": {
++ "type": "array",
++ "maxItems": 20,
++ "uniqueItems": true,
++ "items": {
++ "type": "string",
++ "pattern": "^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,63}$"
++ },
++ "description": "Web hosts it reads from or writes to."
++ }
++ }
++ },
++ "runs": {
++ "type": "string",
++ "enum": [
++ "prompt",
++ "sandbox"
++ ],
++ "description": "How it runs: prompt (instructions and text only, as @1) or sandbox (its code runs in a sandbox, never on an OpenVibe server)."
++ },
++ "license": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 64,
++ "description": "An SPDX licence id, such as MIT or CC-BY-4.0."
++ },
++ "author": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "subject"
++ ],
++ "description": "Who the document says wrote it: a claim, never checked here.",
++ "properties": {
++ "subject": {
++ "type": "string",
++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "name": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ }
++ }
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time",
++ "description": "When the document was written. Not hashed."
++ },
++ "integrity": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "alg",
++ "hash"
++ ],
++ "description": "A sha256 over the canonical JSON: the file was not edited after it was written. Not a signature.",
++ "properties": {
++ "alg": {
++ "const": "sha256"
++ },
++ "hash": {
++ "type": "string",
++ "pattern": "^[0-9a-f]{64}$"
++ }
++ }
++ }
++ },
++ "allOf": [
++ {
++ "if": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "prompt"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ },
++ "then": {
++ "not": {
++ "required": [
++ "tools"
++ ]
++ }
++ }
++ },
++ {
++ "if": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "sandbox"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ },
++ "then": {
++ "required": [
++ "requires",
++ "tools"
++ ],
++ "type": "object",
++ "properties": {
++ "requires": {
++ "required": [
++ "kinds"
++ ],
++ "type": "object",
++ "properties": {
++ "kinds": {
++ "type": "array",
++ "contains": {
++ "const": "skill.run"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ {
++ "if": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "prompt"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ },
++ "then": {
++ "type": "object",
++ "properties": {
++ "requires": {
++ "type": "object",
++ "properties": {
++ "kinds": {
++ "type": "array",
++ "not": {
++ "contains": {
++ "const": "skill.run"
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ ],
++ "$defs": {
++ "argValue": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "type"
++ ],
++ "properties": {
++ "type": {
++ "enum": [
++ "string",
++ "number",
++ "integer",
++ "boolean",
++ "array"
++ ]
++ },
++ "description": {
++ "type": "string",
++ "maxLength": 200
++ },
++ "enum": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 100,
++ "uniqueItems": true,
++ "items": {
++ "type": [
++ "string",
++ "number",
++ "integer",
++ "boolean"
++ ]
++ }
++ },
++ "maxLength": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 65536
++ },
++ "pattern": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200,
++ "description": "A regular expression, at most 200 characters. No longer pattern is allowed in v1."
++ },
++ "items": {
++ "$ref": "#/$defs/argScalar"
++ },
++ "minItems": {
++ "type": "integer",
++ "minimum": 0,
++ "maximum": 1000
++ },
++ "maxItems": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 1000
++ }
++ }
++ },
++ "argScalar": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "type"
++ ],
++ "properties": {
++ "type": {
++ "enum": [
++ "string",
++ "number",
++ "integer",
++ "boolean"
++ ]
++ },
++ "description": {
++ "type": "string",
++ "maxLength": 200
++ },
++ "enum": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 100,
++ "uniqueItems": true,
++ "items": {
++ "type": [
++ "string",
++ "number",
++ "integer",
++ "boolean"
++ ]
++ }
++ },
++ "maxLength": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 65536
++ },
++ "pattern": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200
++ }
++ }
++ }
++ }
++}
ddiff --git a/contracts/catalog.json b/contracts/catalog.json
iindex 81bf4e16..927b4edd 100644
---- a/contracts/catalog.json
++++ b/contracts/catalog.json
@@@ -9979,6 +9979,16 @@
"status": "active",
"adr": "ADR-058"
},
++ {
++ "id": "actor.skill-listing",
++ "version": "2.0.0",
++ "owner": "actor",
++ "schema": "actor/skill-listing.v2.json",
++ "visibility": "public",
++ "compatibility": "backward",
++ "status": "active",
++ "adr": "ADR-060"
++ },
{
"id": "actor.canvas",
"version": "1.0.0",
@@@ -9999,6 +10009,16 @@
"status": "active",
"adr": "ADR-058"
},
++ {
++ "id": "actor.skill",
++ "version": "2.0.0",
++ "owner": "actor",
++ "schema": "actor/skill.v2.json",
++ "visibility": "public",
++ "compatibility": "backward",
++ "status": "active",
++ "adr": "ADR-060"
++ },
{
"id": "frame.menu-card",
"version": "1.0.0",
ddiff --git a/docs/adr/ADR-058-skills.md b/docs/adr/ADR-058-skills.md
iindex 81b68b80..9480357f 100644
---- a/docs/adr/ADR-058-skills.md
++++ b/docs/adr/ADR-058-skills.md
@@@ -23,7 +23,8 @@
resources, and what it may ask an agent to do (`requires`: HO1 kinds, connected apps, hosts).
2. **v1 skills run as a prompt and nothing else** (`runs: "prompt"`):
- no code, no binaries, no install recipes;
-- - a skill that runs code waits for a sandbox (plan HO8) and a new major.
++ - a skill that runs code waits for a sandbox (plan HO8) and a new major. **Superseded for code by
++ [ADR-060](ADR-060-skills-run-sandboxed.md).**
3. **A skill grants nothing.** `requires` declares; the agent's level and approvals decide every step, as for any
other step. A step of a kind the skill did not declare is a scan finding.
4. **The integrity hash is not a signature**, as for voices:
ddiff --git a/docs/adr/ADR-060-skills-run-sandboxed.md b/docs/adr/ADR-060-skills-run-sandboxed.md
nnew file mode 100644
iindex 00000000..0a1dd602
---- /dev/null
++++ b/docs/adr/ADR-060-skills-run-sandboxed.md
@@@ -0,0 +1,107 @@
++# ADR-060: Skills that run code — never on our server, always in a sandbox
++
++- **Status:** Accepted 2026-11-08 (plan track HO, wave 3: HO8), after Opus's security review.
++- **Owner:** OpenVibe.Actor (the registry and the `skill.run` step) and OpenVibe.Node (the runner).
++- **Contracts:** `actor.skill@2`, `actor.skill-listing@2`; `skill.run` joins the HO1 approval kinds.
++- **Supersedes:** ADR-058 decision 2's "no code" for `runs: "sandbox"`. `actor.skill@1` stays valid and is still
++ what a prompt-only skill publishes.
++
++## Evidence
++
++- The Hermes/OpenClaw study (`plan-state-2026-10-22/hermes-openclaw-2026-11-07.md`) found the "magic moment" is an
++ agent that learned something and used it later: a skill. Both projects quickly want that skill to *do* the thing,
++ not only describe it, and both show the danger: OpenClaw's ClawHub needed a scan and a trust envelope because a
++ skill that steals credentials is what people fear.
++- OpenVibe already has the trust spine: HO1 gives every consequential act a kind and an approval, HO2 made a skill a
++ document whose `requires` grants nothing, and Run already executes a registered artifact as a job on a Node with
++ pinned input bytes and per-job network egress.
++- What OpenVibe did not have is a way to run a person's (or an agent's) code without putting it on our servers or
++ trusting the person's laptop. A Node that declares the skill runner, and Run's `function` class, is that place.
++
++## Decision
++
++1. **The rule.** A skill's code never runs on an OpenVibe server, never on the person's machine outside a sandbox,
++ and never sees a secret. It runs as a Run job of class `function` on a Node that declared the skill runner, with
++ the network denied unless the skill declared otherwise and the person approved it, and with the exact bytes the
++ registry scanned.
++2. **The contracts.** `actor.skill@2` adds:
++ - `runs`: `prompt` (exactly @1) or `sandbox`;
++ - `tools` (1 to 5, only when `runs: "sandbox"`): `name` (`^[a-z][a-z0-9_]{0,31}$`), a `description` the agent
++ reads before it calls (≤ 200), `language: "javascript"` (the only one in v1), `entry` naming one of the skill's
++ resources, `args` as a JSON Schema subset (an object whose properties are string, number, integer, boolean or
++ an array of those, with `enum`, `maxLength` and `pattern` at most 200 characters; no `$ref`, no nested object),
++ `net` (`deny` by default, `openvibe-only`, `public`) and `limits` (`wall_ms` ≤ 30000, default 10000;
++ `mem_bytes` ≤ 268435456, default 134217728);
++ - code as an ordinary text resource (`.js`, `text/javascript`, ≤ 64 KiB each), so it is in the same integrity
++ hash as the instructions and resources; there are no binaries, no install recipes and no dependencies;
++ - `requires.kinds` gains `skill.run` when `runs` is `sandbox`, and a prompt skill may not declare it.
++ `actor.skill-listing@2` carries, per code resource, `{ name, media_id, sha256 }`, so the bytes that run are the
++ bytes that were scanned, and its scan findings may name the `tool` they are about. `actor.skill@1` and
++ `actor.skill-listing@1` are unchanged.
++3. **The Node runner** (`[email protected]`, a declared function like `[email protected]`):
++ - off unless the owner turns it on (`worker.functions`, `openvibe node skills on`);
++ - takes `{ tool, entry, input }` and the code as job `inputs` (Media objects pinned by sha256; a mismatch ends the
++ job before anything runs);
++ - runs `node --permission --allow-fs-read=<the job's input dir>` with no child process, no worker, no addons and
++ `--disallow-code-generation-from-strings`, inside the function sandbox Node already has (its own root, limits,
++ no credential, network per `net`);
++ - the input arrives on stdin as JSON; the tool writes one JSON value (≤ 64 KiB; more fails the job `limit`);
++ stderr is kept for the person (≤ 16 KiB).
++4. **The Actor registry and the run.**
++ - Publishing a sandbox skill stores each code resource in Media (Actor's tenant, private) and puts its id and
++ sha256 on the listing. The scan reads the code and never runs it; it fails a skill that reads `process.env`,
++ spawns, loads `vm`/`worker_threads`/`child_process`/`fs` writes, uses `eval`/`Function`, reaches the network
++ when the tool says `deny` or names non-OpenVibe hosts under `openvibe-only`, carries long base64/hex, a
++ minified one-liner over 2 KB or anything that decodes to code; it flags any network use, timers over 5 s and
++ big loops over input.
++ - Running a tool is a step of the new kind `skill.run` (label: "running a skill's code in a sandbox"), target
++ `<slug>@<version> <tool>` plus ` · internet` when `net` is `public`. "Always allow" covers exactly that skill
++ version's tool, so a new version asks again.
++ - Actor submits the Run job as the person (`X-OV-Subject` + `X-OV-Project`): class `function`, artifact
++ `[email protected]`, the pinned inputs, `net` as declared (never wider), limits as declared (never
++ above the caps), `ttl_ms` 120000. Placement is the person's own Link machines that run the skill runner
++ first, then OpenVibe's pool when one offers it; never Actor's server. No node means the step says so and
++ offers "Run it on my machine" (Link setup), never a fallback that runs elsewhere.
++ - Billing is Run's per-second metering on the person's Balance, inside HO7's per-agent allowance when the agent
++ acts alone. The result is data: the JSON goes back to the agent as an untrusted tool result, never as
++ instructions; the step records the job id, wall time and exit.
++5. **The person sees it** on the skill's card and install page: "Runs code in a sandbox on your machine or
++ OpenVibe's", the tools with their `net` in plain words ("no internet", "OpenVibe sites only", "the internet"),
++ and the scan's findings per tool. A `flagged` code skill installs only after reading them; a `failed` never.
++
++## Alternatives
++
++- **Run the code on Actor's server.** Rejected: Actor holds every person's agent, token and registry record; one
++ skill's mistake would be a registry-wide incident, and the design rule forbids it outright.
++- **A container on the host that publishes the skill.** Rejected: the host is someone's machine, and a container
++ boundary we do not control is not a sandbox promise we can make to every site. Node already has the sandbox, the
++ limits, the egress policy and the placement; running there needs no second runtime.
++- **Python and npm in v1.** Deferred: both widen the runtime surface (packages, install recipes, dependency
++ resolution) before the scan and the sandbox have a release behind them. Each needs its own review, as does
++ persistent state, a tool calling another tool, files written back to the person, and GPU.
++
++## Migration and rollback
++
++Both new contracts are additive majors; nothing parses `actor.skill@2` until Actor's registry and Node's runner
++ship, and @1 keeps working for every existing prompt skill. The only data a sandbox listing adds is the Media
++objects that hold the code; they are private to Actor's tenant and can be deleted with the listing. Rollback is
++retiring the @2 listing and turning the runner off: no prompt skill is affected, no job can be submitted without
++the `skill.run` kind, and nothing ever ran on our servers, so there is no server-side state to unwind.
++
++## Tests
++
++`test/run.js`:
++- every valid fixture carries the hash of its own canonical content, including code resources and tools, and an
++ edited instruction, code or `net` no longer matches it;
++- `runs` is `prompt` or `sandbox`; `tools` has 1 to 5 entries and only a sandbox skill carries them;
++- a sandbox skill declares `skill.run` in `requires.kinds`; a prompt skill does not;
++- `language` is `javascript`, the tool `name` shape is the one above, and `entry` names a code resource (the
++ cross-field rule a JSON Schema cannot state: the fixtures and the registry check it);
++- `net` is `deny`, `openvibe-only` or `public` with `deny` the default; `limits` stay at or under the caps and
++ default to 10000 ms and 134217728 bytes;
++- a resource is text (no binary), code is `.js` with `text/javascript` and at most 64 KiB, and no field is named
++ `secret`, `token`, `env` or `key`;
++- a @2 listing pins each code resource's Media id and sha256, the pinned sha256 is the document's own bytes, and a
++ sandbox listing without code is invalid.
++Node's own tests (in OpenVibe.Node) prove the runner: a tool cannot read env, spawn, write a file, open a socket
++under `deny`, or exceed its output.
ddiff --git a/docs/adr/README.md b/docs/adr/README.md
iindex 3ad58aa6..84368250 100644
---- a/docs/adr/README.md
++++ b/docs/adr/README.md
@@@ -53,3 +53,4 @@ Platform-wide decisions from the OpenVibe development roadmap (section 10). Each
| [ADR-057](ADR-057-website-connect.md) | Website Connect: a focused Go `quic-go` edge relay for Share, a Node OpenVibe.Connect control API, headscale + embedded `tsnet` for the private mesh with a tenant-isolation proof, and Events-owned durable hook delivery; two-credential node/share tunnel handshake, immediate revocation, edge policy enforcement, no secret or body in audit, a thin MIT SDK boundary, and the single-label `agents-<owner>.openvibe.website` first proof (Universal SSL does not cover `agents.owner.openvibe.website`; deep labels are CON-2); registers 9 v1 contracts and 20 planned capabilities, grants and deploys nothing | Proposed 2026-10-29 (CON-1; plan 2026-10-28 §5.9b), for the owner's review |
| [ADR-058](ADR-058-skills.md) | Skills: a skill is a document (`actor.skill@1`: a prompt with text resources, an integrity hash that is not a signature, a `requires` that grants nothing and names HO1's approval kinds); the registry's listing (`actor.skill-listing@1`) vouches for the publisher and carries the scan and the curator's state to every site: passed installs in one tap, flagged after the person reads the findings, failed never | Accepted 2026-11-07 (plan HO2, the skeleton) |
| [ADR-059](ADR-059-canvas.md) | The canvas: an agent's live panel is data (`actor.canvas@1`: headings, text, lists, checklists, tables, metrics, bar and line charts, pictures from openvibe.media, links, buttons; no HTML, style, script or frame), drawn by one Shared renderer on every site; a button only sends its label to the agent as the person's message, and a checklist tick tells the agent which item changed | Accepted 2026-11-08 (plan HO9) |
++| [ADR-060](ADR-060-skills-run-sandboxed.md) | Skills that run code: `actor.skill@2` adds `runs: sandbox` with 1–5 JavaScript tools, code as text resources in the integrity hash, `net` (`deny` default) and `limits` under caps; `actor.skill-listing@2` pins each code resource's Media id and sha256 and names the tool a finding is about; `skill.run` joins the HO1 kinds; code runs as a Run `function` job on a Node that declared the skill runner, never on an OpenVibe server and never with a secret | Accepted 2026-11-08 (plan HO8) |
ddiff --git a/fixtures/actor.skill-listing/invalid/sandbox-without-code.json b/fixtures/actor.skill-listing/invalid/sandbox-without-code.json
nnew file mode 100644
iindex 00000000..00dd9db6
---- /dev/null
++++ b/fixtures/actor.skill-listing/invalid/sandbox-without-code.json
@@@ -0,0 +1,71 @@
++{
++ "listing": "actor.skill-listing@2",
++ "id": "skl_01JAB2C3D4E5F6G7H8J9K0MNPQ",
++ "skill": {
++ "skill": "actor.skill@2",
++ "slug": "slugify-a-title",
++ "name": "Slugify a title",
++ "description": "Use when a draft needs a URL slug: lowercase words joined by hyphens, no network.",
++ "version": "1.0.0",
++ "instructions": "Call slugify with the title. It runs in a sandbox with no network. Use the slug in a URL.",
++ "resources": [
++ {
++ "path": "slugify.js",
++ "media_type": "text/javascript",
++ "text": "'use strict';\nlet raw = '';\nprocess.stdin.setEncoding('utf8');\nprocess.stdin.on('data', (chunk) => { raw += chunk; });\nprocess.stdin.on('end', () => {\n const input = JSON.parse(raw);\n const slug = String(input.title).toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');\n process.stdout.write(JSON.stringify({ slug }));\n});\n"
++ }
++ ],
++ "tools": [
++ {
++ "name": "slugify",
++ "description": "Turn a title into a URL slug: lowercase words joined by hyphens.",
++ "language": "javascript",
++ "entry": "slugify.js",
++ "args": {
++ "type": "object",
++ "properties": {
++ "title": {
++ "type": "string",
++ "maxLength": 120,
++ "description": "The title to turn into a slug."
++ },
++ "shorten": {
++ "type": "boolean"
++ }
++ },
++ "required": [
++ "title"
++ ],
++ "additionalProperties": false
++ },
++ "net": "deny"
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run"
++ ]
++ },
++ "runs": "sandbox",
++ "license": "MIT",
++ "author": {
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
++ },
++ "created_at": "2026-11-08T01:00:00.000Z",
++ "integrity": {
++ "alg": "sha256",
++ "hash": "84f9b0bc23d10534158184aa9b1952ef078f7e21d4d4fa6f3aa0f3a1e13ca1db"
++ }
++ },
++ "publisher": {
++ "kind": "person",
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
++ },
++ "scan": {
++ "state": "passed"
++ },
++ "curator": {
++ "state": "active"
++ },
++ "listed_at": "2026-11-08T01:01:00.000Z"
++}
ddiff --git a/fixtures/actor.skill-listing/valid/sandbox-public.json b/fixtures/actor.skill-listing/valid/sandbox-public.json
nnew file mode 100644
iindex 00000000..89243b83
---- /dev/null
++++ b/fixtures/actor.skill-listing/valid/sandbox-public.json
@@@ -0,0 +1,94 @@
++{
++ "listing": "actor.skill-listing@2",
++ "id": "skl_01JAB2C3D4E5F6G7H8J9K0MNPQ",
++ "skill": {
++ "skill": "actor.skill@2",
++ "slug": "fetch-a-page-title",
++ "name": "Fetch a page title",
++ "description": "Use when someone gives a web address and asks what the page is called: reads the title over the internet.",
++ "version": "2.1.0",
++ "instructions": "Call fetch_title with the https URL. It runs in a sandbox with the internet, and only for this call.",
++ "resources": [
++ {
++ "path": "fetch_title.js",
++ "media_type": "text/javascript",
++ "text": "'use strict';\nlet raw = '';\nprocess.stdin.setEncoding('utf8');\nprocess.stdin.on('data', (chunk) => { raw += chunk; });\nprocess.stdin.on('end', async () => {\n const input = JSON.parse(raw);\n const response = await fetch(input.url, { signal: AbortSignal.timeout(8000) });\n const html = await response.text();\n const title = (html.match(/<title[^>]*>([^<]*)<\\/title>/i) || [])[1] || '';\n process.stdout.write(JSON.stringify({ status: response.status, title: title.trim() }));\n});\n"
++ }
++ ],
++ "tools": [
++ {
++ "name": "fetch_title",
++ "description": "Read a page over https and answer its status and title.",
++ "language": "javascript",
++ "entry": "fetch_title.js",
++ "args": {
++ "type": "object",
++ "properties": {
++ "url": {
++ "type": "string",
++ "pattern": "^https://",
++ "maxLength": 2048
++ }
++ },
++ "required": [
++ "url"
++ ],
++ "additionalProperties": false
++ },
++ "net": "public",
++ "limits": {
++ "wall_ms": 15000,
++ "mem_bytes": 134217728
++ }
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run",
++ "send"
++ ]
++ },
++ "runs": "sandbox",
++ "license": "MIT",
++ "author": {
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
++ "name": "Ann"
++ },
++ "integrity": {
++ "alg": "sha256",
++ "hash": "53d984eb0e639c1b07c99b9a5aec6d64ea9e594cbe404a0a9256debf7cb8b49e"
++ }
++ },
++ "code": [
++ {
++ "name": "fetch_title.js",
++ "media_id": "med_01JAB2C3D4E5F6G7H8J9K0MNPQ",
++ "sha256": "f75ae8394b4d2e7d7667e0645071534862f321b2015017c26ca49bf1f3a32b80"
++ }
++ ],
++ "publisher": {
++ "kind": "person",
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
++ "name": "Ann"
++ },
++ "scan": {
++ "state": "flagged",
++ "scanner": "openvibe-skill-scan 1.1.0",
++ "scanned_at": "2026-11-08T01:01:00.000Z",
++ "findings": [
++ {
++ "rule": "code.network",
++ "severity": "warn",
++ "where": "fetch_title.js",
++ "tool": "fetch_title",
++ "note": "The tool asks for the internet; the person must read this before install."
++ }
++ ]
++ },
++ "curator": {
++ "state": "active",
++ "last_used_at": "2026-11-08T01:30:00.000Z"
++ },
++ "installs": 3,
++ "listed_at": "2026-11-08T01:01:00.000Z"
++}
ddiff --git a/fixtures/actor.skill/invalid/binary-code-resource.json b/fixtures/actor.skill/invalid/binary-code-resource.json
nnew file mode 100644
iindex 00000000..fa979b4b
---- /dev/null
++++ b/fixtures/actor.skill/invalid/binary-code-resource.json
@@@ -0,0 +1,37 @@
++{
++ "skill": "actor.skill@2",
++ "slug": "binary-skill",
++ "name": "Binary skill",
++ "description": "Use when testing: a resource is text, never a binary.",
++ "version": "1.0.0",
++ "instructions": "None.",
++ "resources": [
++ {
++ "path": "tool.wasm",
++ "media_type": "application/wasm",
++ "text": "AGFzbQEAAAA="
++ }
++ ],
++ "tools": [
++ {
++ "name": "run",
++ "description": "Does nothing.",
++ "language": "javascript",
++ "entry": "tool.wasm",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny"
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run"
++ ]
++ },
++ "runs": "sandbox",
++ "integrity": {
++ "alg": "sha256",
++ "hash": "cc81e02bc538c64fe95f187f6de2304b5316ec4e7a695a0d931d821bd5e9b7a5"
++ }
++}
ddiff --git a/fixtures/actor.skill/invalid/entry-no-resource.json b/fixtures/actor.skill/invalid/entry-no-resource.json
nnew file mode 100644
iindex 00000000..f3627a6a
---- /dev/null
++++ b/fixtures/actor.skill/invalid/entry-no-resource.json
@@@ -0,0 +1,37 @@
++{
++ "skill": "actor.skill@2",
++ "slug": "missing-entry",
++ "name": "Missing entry",
++ "description": "Use when testing: the entry names no resource.",
++ "version": "1.0.0",
++ "instructions": "None.",
++ "resources": [
++ {
++ "path": "main.js",
++ "media_type": "text/javascript",
++ "text": "process.stdout.write(\"{}\");\n"
++ }
++ ],
++ "tools": [
++ {
++ "name": "run",
++ "description": "Does nothing.",
++ "language": "javascript",
++ "entry": "missing.js",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny"
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run"
++ ]
++ },
++ "runs": "sandbox",
++ "integrity": {
++ "alg": "sha256",
++ "hash": "381dee9a1be1b96565c3d91514cbbe7b6b038fa12417b901fa35346118503199"
++ }
++}
ddiff --git a/fixtures/actor.skill/invalid/language-python.json b/fixtures/actor.skill/invalid/language-python.json
nnew file mode 100644
iindex 00000000..09462f7b
---- /dev/null
++++ b/fixtures/actor.skill/invalid/language-python.json
@@@ -0,0 +1,37 @@
++{
++ "skill": "actor.skill@2",
++ "slug": "python-tool",
++ "name": "Python tool",
++ "description": "Use when testing: v1 only runs JavaScript.",
++ "version": "1.0.0",
++ "instructions": "None.",
++ "resources": [
++ {
++ "path": "main.js",
++ "media_type": "text/javascript",
++ "text": "process.stdout.write(\"{}\");\n"
++ }
++ ],
++ "tools": [
++ {
++ "name": "run",
++ "description": "Does nothing.",
++ "language": "python",
++ "entry": "main.js",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny"
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run"
++ ]
++ },
++ "runs": "sandbox",
++ "integrity": {
++ "alg": "sha256",
++ "hash": "ed89be455d006515ee25e57437bdaf871d5681c6a11daab59558bb82742c095c"
++ }
++}
ddiff --git a/fixtures/actor.skill/invalid/six-tools.json b/fixtures/actor.skill/invalid/six-tools.json
nnew file mode 100644
iindex 00000000..e648edcd
---- /dev/null
++++ b/fixtures/actor.skill/invalid/six-tools.json
@@@ -0,0 +1,87 @@
++{
++ "skill": "actor.skill@2",
++ "slug": "too-many-tools",
++ "name": "Too many tools",
++ "description": "Use when testing: at most five tools.",
++ "version": "1.0.0",
++ "instructions": "None.",
++ "resources": [
++ {
++ "path": "main.js",
++ "media_type": "text/javascript",
++ "text": "process.stdout.write(\"{}\");\n"
++ }
++ ],
++ "tools": [
++ {
++ "name": "tool_0",
++ "description": "Tool 0.",
++ "language": "javascript",
++ "entry": "main.js",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny"
++ },
++ {
++ "name": "tool_1",
++ "description": "Tool 1.",
++ "language": "javascript",
++ "entry": "main.js",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny"
++ },
++ {
++ "name": "tool_2",
++ "description": "Tool 2.",
++ "language": "javascript",
++ "entry": "main.js",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny"
++ },
++ {
++ "name": "tool_3",
++ "description": "Tool 3.",
++ "language": "javascript",
++ "entry": "main.js",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny"
++ },
++ {
++ "name": "tool_4",
++ "description": "Tool 4.",
++ "language": "javascript",
++ "entry": "main.js",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny"
++ },
++ {
++ "name": "tool_5",
++ "description": "Tool 5.",
++ "language": "javascript",
++ "entry": "main.js",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny"
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run"
++ ]
++ },
++ "runs": "sandbox",
++ "integrity": {
++ "alg": "sha256",
++ "hash": "a94a6187ee9c21ea851bfe4d4d9585a0742c356d746f13e143f1f56a893ed2c7"
++ }
++}
ddiff --git a/fixtures/actor.skill/invalid/tools-with-prompt.json b/fixtures/actor.skill/invalid/tools-with-prompt.json
nnew file mode 100644
iindex 00000000..d3388d55
---- /dev/null
++++ b/fixtures/actor.skill/invalid/tools-with-prompt.json
@@@ -0,0 +1,36 @@
++{
++ "skill": "actor.skill@2",
++ "slug": "prompt-with-tools",
++ "name": "Prompt with tools",
++ "description": "Use when testing: a prompt skill may not carry tools.",
++ "version": "1.0.0",
++ "instructions": "None.",
++ "resources": [
++ {
++ "path": "tool.js",
++ "media_type": "text/javascript",
++ "text": "process.stdout.write(\"{}\");\n"
++ }
++ ],
++ "tools": [
++ {
++ "name": "tool",
++ "description": "Does nothing.",
++ "language": "javascript",
++ "entry": "tool.js",
++ "args": {
++ "type": "object"
++ }
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run"
++ ]
++ },
++ "runs": "prompt",
++ "integrity": {
++ "alg": "sha256",
++ "hash": "9f8e9341f37a7033b06e4938d5b7093c14081af565bfcb8c4d75d5967995782a"
++ }
++}
ddiff --git a/fixtures/actor.skill/invalid/wall-too-long.json b/fixtures/actor.skill/invalid/wall-too-long.json
nnew file mode 100644
iindex 00000000..088c1748
---- /dev/null
++++ b/fixtures/actor.skill/invalid/wall-too-long.json
@@@ -0,0 +1,40 @@
++{
++ "skill": "actor.skill@2",
++ "slug": "slow-tool",
++ "name": "Slow tool",
++ "description": "Use when testing: a tool may not ask for 60 seconds.",
++ "version": "1.0.0",
++ "instructions": "None.",
++ "resources": [
++ {
++ "path": "main.js",
++ "media_type": "text/javascript",
++ "text": "process.stdout.write(\"{}\");\n"
++ }
++ ],
++ "tools": [
++ {
++ "name": "run",
++ "description": "Does nothing.",
++ "language": "javascript",
++ "entry": "main.js",
++ "args": {
++ "type": "object"
++ },
++ "net": "deny",
++ "limits": {
++ "wall_ms": 60000
++ }
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run"
++ ]
++ },
++ "runs": "sandbox",
++ "integrity": {
++ "alg": "sha256",
++ "hash": "53d79a8a2b14765ca0c1f76d5290ad9faacdaf7019de65d508a599b93fe43690"
++ }
++}
ddiff --git a/fixtures/actor.skill/valid/prompt-only.json b/fixtures/actor.skill/valid/prompt-only.json
nnew file mode 100644
iindex 00000000..be5fba21
---- /dev/null
++++ b/fixtures/actor.skill/valid/prompt-only.json
@@@ -0,0 +1,26 @@
++{
++ "skill": "actor.skill@2",
++ "slug": "summarize-a-stream",
++ "name": "Summarize a stream",
++ "description": "Use when someone asks what happened in a stream recording: a short summary with the moments that mattered.",
++ "version": "1.0.0",
++ "instructions": "Read the transcript. Write five bullets, each with its time. Name nobody who did not speak.",
++ "resources": [
++ {
++ "path": "outline.md",
++ "media_type": "text/markdown",
++ "text": "# Summary\n\n- <time> <moment>"
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "post"
++ ]
++ },
++ "runs": "prompt",
++ "license": "MIT",
++ "integrity": {
++ "alg": "sha256",
++ "hash": "4a3e9e27aff7547cdbd9ad085faa6fa9ea4c523e87df3cdcc491d75e35b590d2"
++ }
++}
ddiff --git a/fixtures/actor.skill/valid/sandbox-deny.json b/fixtures/actor.skill/valid/sandbox-deny.json
nnew file mode 100644
iindex 00000000..efe6f2bb
---- /dev/null
++++ b/fixtures/actor.skill/valid/sandbox-deny.json
@@@ -0,0 +1,56 @@
++{
++ "skill": "actor.skill@2",
++ "slug": "slugify-a-title",
++ "name": "Slugify a title",
++ "description": "Use when a draft needs a URL slug: lowercase words joined by hyphens, no network.",
++ "version": "1.0.0",
++ "instructions": "Call slugify with the title. It runs in a sandbox with no network. Use the slug in a URL.",
++ "resources": [
++ {
++ "path": "slugify.js",
++ "media_type": "text/javascript",
++ "text": "'use strict';\nlet raw = '';\nprocess.stdin.setEncoding('utf8');\nprocess.stdin.on('data', (chunk) => { raw += chunk; });\nprocess.stdin.on('end', () => {\n const input = JSON.parse(raw);\n const slug = String(input.title).toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');\n process.stdout.write(JSON.stringify({ slug }));\n});\n"
++ }
++ ],
++ "tools": [
++ {
++ "name": "slugify",
++ "description": "Turn a title into a URL slug: lowercase words joined by hyphens.",
++ "language": "javascript",
++ "entry": "slugify.js",
++ "args": {
++ "type": "object",
++ "properties": {
++ "title": {
++ "type": "string",
++ "maxLength": 120,
++ "description": "The title to turn into a slug."
++ },
++ "shorten": {
++ "type": "boolean"
++ }
++ },
++ "required": [
++ "title"
++ ],
++ "additionalProperties": false
++ },
++ "net": "deny"
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run"
++ ]
++ },
++ "runs": "sandbox",
++ "license": "MIT",
++ "author": {
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
++ },
++ "created_at": "2026-11-08T01:00:00.000Z",
++ "integrity": {
++ "alg": "sha256",
++ "hash": "84f9b0bc23d10534158184aa9b1952ef078f7e21d4d4fa6f3aa0f3a1e13ca1db"
++ }
++}
ddiff --git a/fixtures/actor.skill/valid/sandbox-public.json b/fixtures/actor.skill/valid/sandbox-public.json
nnew file mode 100644
iindex 00000000..9767f61e
---- /dev/null
++++ b/fixtures/actor.skill/valid/sandbox-public.json
@@@ -0,0 +1,58 @@
++{
++ "skill": "actor.skill@2",
++ "slug": "fetch-a-page-title",
++ "name": "Fetch a page title",
++ "description": "Use when someone gives a web address and asks what the page is called: reads the title over the internet.",
++ "version": "2.1.0",
++ "instructions": "Call fetch_title with the https URL. It runs in a sandbox with the internet, and only for this call.",
++ "resources": [
++ {
++ "path": "fetch_title.js",
++ "media_type": "text/javascript",
++ "text": "'use strict';\nlet raw = '';\nprocess.stdin.setEncoding('utf8');\nprocess.stdin.on('data', (chunk) => { raw += chunk; });\nprocess.stdin.on('end', async () => {\n const input = JSON.parse(raw);\n const response = await fetch(input.url, { signal: AbortSignal.timeout(8000) });\n const html = await response.text();\n const title = (html.match(/<title[^>]*>([^<]*)<\\/title>/i) || [])[1] || '';\n process.stdout.write(JSON.stringify({ status: response.status, title: title.trim() }));\n});\n"
++ }
++ ],
++ "tools": [
++ {
++ "name": "fetch_title",
++ "description": "Read a page over https and answer its status and title.",
++ "language": "javascript",
++ "entry": "fetch_title.js",
++ "args": {
++ "type": "object",
++ "properties": {
++ "url": {
++ "type": "string",
++ "pattern": "^https://",
++ "maxLength": 2048
++ }
++ },
++ "required": [
++ "url"
++ ],
++ "additionalProperties": false
++ },
++ "net": "public",
++ "limits": {
++ "wall_ms": 15000,
++ "mem_bytes": 134217728
++ }
++ }
++ ],
++ "requires": {
++ "kinds": [
++ "skill.run",
++ "send"
++ ]
++ },
++ "runs": "sandbox",
++ "license": "MIT",
++ "author": {
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ",
++ "name": "Ann"
++ },
++ "integrity": {
++ "alg": "sha256",
++ "hash": "53d984eb0e639c1b07c99b9a5aec6d64ea9e594cbe404a0a9256debf7cb8b49e"
++ }
++}
ddiff --git a/generated/json-schema/bundle.json b/generated/json-schema/bundle.json
iindex 0c070551..6571fc26 100644
---- a/generated/json-schema/bundle.json
++++ b/generated/json-schema/bundle.json
@@@ -109971,7 +109971,7 @@
}
}
},
-- "actor.skill-listing": {
++ "actor.skill-listing@1": {
"version": "1.0.0",
"owner": "actor",
"status": "active",
@@@ -110142,6 +110142,277 @@
}
}
},
++ "actor.skill-listing@2": {
++ "version": "2.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/skill-listing.v2.json",
++ "title": "ActorSkillListingV2",
++ "description": "actor.skill-listing@2: a skill in the registry, the record every site shows on its card (ADR-058, ADR-060). It keeps every field and meaning of actor.skill-listing@1 and adds what a sandbox skill needs to be shown and run: the document is actor.skill@2, CODE lists, per code resource, its name (the resource path a tool's entry names), the Media object id its bytes are stored under and the sha256 of those bytes, so the bytes that run are the bytes that were scanned; and the SCAN's findings may name the TOOL they are about, so a person reads the scan one tool at a time. A sandbox listing carries code; a prompt listing carries none. It still carries the PUBLISHER from the registry's own record (vouched: unlike the document's author, this is who published it), the SCAN (its state and findings travel with the listing), and the CURATOR's state. Install rules every site keeps: a passed skill installs in one tap; a flagged one only after the person reads the findings and confirms; a failed one never; a stale or archived one is not offered. Installing copies the document into the person's agent; it grants nothing (the skill's requires is a declaration).",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "listing",
++ "id",
++ "skill",
++ "publisher",
++ "scan",
++ "curator",
++ "listed_at"
++ ],
++ "properties": {
++ "listing": {
++ "const": "actor.skill-listing@2"
++ },
++ "id": {
++ "type": "string",
++ "pattern": "^skl_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The listing's id."
++ },
++ "skill": {
++ "$ref": "skill.v2.json",
++ "description": "The document as published."
++ },
++ "code": {
++ "type": "array",
++ "maxItems": 10,
++ "uniqueItems": true,
++ "description": "Per code resource of a sandbox skill: the resource path a tool entry names, the Media object the registry stored its bytes under, and the sha256 of those bytes. Required when the skill runs in a sandbox; absent for a prompt skill.",
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "name",
++ "media_id",
++ "sha256"
++ ],
++ "properties": {
++ "name": {
++ "type": "string",
++ "pattern": "^[a-z0-9][a-z0-9_-]{0,59}(?:/[a-z0-9][a-z0-9_-]{0,59}){0,3}\\.js$",
++ "description": "The resource path, as the document's tools entry names it."
++ },
++ "media_id": {
++ "type": "string",
++ "pattern": "^med_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The Media object id the code bytes are stored under."
++ },
++ "sha256": {
++ "type": "string",
++ "pattern": "^[0-9a-f]{64}$",
++ "description": "Lowercase hex SHA-256 of the code bytes."
++ }
++ }
++ }
++ },
++ "publisher": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "kind"
++ ],
++ "description": "Who published it, from the registry's own record.",
++ "properties": {
++ "kind": {
++ "type": "string",
++ "enum": [
++ "openvibe",
++ "person"
++ ],
++ "description": "OpenVibe's own skills, or a person's."
++ },
++ "subject": {
++ "type": "string",
++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The person who published it (kind person)."
++ },
++ "name": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ }
++ }
++ },
++ "scan": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "state"
++ ],
++ "description": "What the registry's scan found. It travels with the listing, and a finding about a tool names it.",
++ "properties": {
++ "state": {
++ "type": "string",
++ "enum": [
++ "pending",
++ "passed",
++ "flagged",
++ "failed"
++ ]
++ },
++ "scanner": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80,
++ "description": "The scanner and its version."
++ },
++ "scanned_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "findings": {
++ "type": "array",
++ "maxItems": 50,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "rule",
++ "severity",
++ "note"
++ ],
++ "properties": {
++ "rule": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_.-]{1,63}$",
++ "description": "Which rule, such as code.network or code.env."
++ },
++ "severity": {
++ "type": "string",
++ "enum": [
++ "info",
++ "warn",
++ "block"
++ ]
++ },
++ "where": {
++ "type": "string",
++ "maxLength": 120,
++ "description": "instructions, description, or a resource path."
++ },
++ "tool": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_]{0,31}$",
++ "description": "The tool the finding is about, when it is about one tool."
++ },
++ "note": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 280,
++ "description": "What it found, in plain words."
++ }
++ }
++ }
++ }
++ }
++ },
++ "curator": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "state"
++ ],
++ "description": "The curator ships with the catalogue: what is used stays, what is not goes stale.",
++ "properties": {
++ "state": {
++ "type": "string",
++ "enum": [
++ "active",
++ "stale",
++ "archived"
++ ]
++ },
++ "last_used_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "near_duplicate_of": {
++ "type": "string",
++ "pattern": "^skl_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "A listing that does the same job."
++ }
++ }
++ },
++ "installs": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "listed_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "retired_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ },
++ "allOf": [
++ {
++ "if": {
++ "properties": {
++ "skill": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "sandbox"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ }
++ },
++ "required": [
++ "skill"
++ ]
++ },
++ "then": {
++ "required": [
++ "code"
++ ],
++ "properties": {
++ "code": {
++ "type": "array",
++ "minItems": 1
++ }
++ }
++ }
++ },
++ {
++ "if": {
++ "properties": {
++ "skill": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "prompt"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ }
++ },
++ "required": [
++ "skill"
++ ]
++ },
++ "then": {
++ "not": {
++ "type": "object",
++ "required": [
++ "code"
++ ]
++ }
++ }
++ }
++ ]
++ }
++ },
"actor.canvas": {
"version": "1.0.0",
"owner": "actor",
@@@ -110580,7 +110851,7 @@
}
}
},
-- "actor.skill": {
++ "actor.skill@1": {
"version": "1.0.0",
"owner": "actor",
"status": "active",
@@@ -110776,6 +111047,588 @@
}
}
},
++ "actor.skill@2": {
++ "version": "2.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/actor/skill.v2.json",
++ "title": "ActorSkillV2",
++ "description": "actor.skill@2: a skill, the document an agent loads to do one kind of job well (ADR-058, ADR-060). It keeps every field and meaning of actor.skill@1 and adds a way for the skill to bring CODE that runs in a sandbox: RUNS is prompt (as @1, text and instructions only) or sandbox. A sandbox skill carries its code as ordinary TEXT resources (a .js path with media_type text/javascript, at most 64 KiB each, in the integrity hash); TOOLS (1 to 5, only when runs is sandbox) say what an agent may call: a name, a description the agent reads, language javascript (the only one in v1), an ENTRY naming one of the skill's own .js resources, ARGS as a JSON Schema subset (an object whose properties are string, number, integer, boolean or an array of those; enum, maxLength, and pattern at most 200 characters; no $ref and no nested object), NET (deny by default, openvibe-only, public) and LIMITS (wall_ms at most 30000, default 10000; mem_bytes at most 268435456, default 134217728). A sandbox skill's requires.kinds names skill.run; a prompt skill declares no tools. A skill GRANTS NOTHING: requires only declares; the agent's level and approvals decide every step (actor approvals, HO1), and a step of a kind the skill did not declare is a scan finding (actor.skill-listing@2). Code never runs on an OpenVibe server and never sees a secret: it runs as a Run job of class function on a Node that declared the skill runner, with the network its tool declared and the exact bytes the registry scanned. The INTEGRITY block is a sha256 over the canonical JSON of the document: it shows the file was not edited after it was written and says nothing about who wrote it, so the AUTHOR is a claim; the registry's listing is the only place a publisher is vouched for. The canonical JSON is the document's own fields, in this order: skill, slug, name, description, version, instructions, resources, tools, requires, runs, license, author; an optional field that is absent or empty is left out; resources are [{ path, media_type, text }] in the document's order; tools are [{ name, description, language, entry, args, net, limits }] in the document's order, with an absent net or limits (and each absent limits field) left out and args as the object the document wrote; requires is { kinds, apps, hosts } with empty lists left out; author is { subject } or { subject, name }; the value is the compact JSON of that object (no spaces). CREATED_AT is not hashed.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "skill",
++ "slug",
++ "name",
++ "description",
++ "version",
++ "instructions",
++ "runs",
++ "integrity"
++ ],
++ "properties": {
++ "skill": {
++ "const": "actor.skill@2",
++ "description": "The document marker."
++ },
++ "slug": {
++ "type": "string",
++ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$",
++ "description": "Its name in the registry: lowercase letters, digits and hyphens."
++ },
++ "name": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80,
++ "description": "What a person reads on its card."
++ },
++ "description": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 280,
++ "description": "When to use it, in one line: the only part an agent reads before it loads the skill."
++ },
++ "version": {
++ "type": "string",
++ "pattern": "^(0|[1-9][0-9]{0,5})\\.(0|[1-9][0-9]{0,5})\\.(0|[1-9][0-9]{0,5})$",
++ "description": "Its semantic version."
++ },
++ "instructions": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 20000,
++ "description": "What to do, in Markdown. The agent reads it as guidance; it never grants a permission."
++ },
++ "resources": {
++ "type": "array",
++ "maxItems": 10,
++ "description": "Text the instructions refer to (a checklist, a template, a table) and, for a sandbox skill, the code a tool's entry names. Code is a text resource, not a binary and not an install recipe: it runs in a sandbox and never on an OpenVibe server. Any resource is at most 64 KiB; a non-code resource keeps @1's 20000-character cap.",
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "path",
++ "media_type",
++ "text"
++ ],
++ "properties": {
++ "path": {
++ "type": "string",
++ "pattern": "^[a-z0-9][a-z0-9_-]{0,59}(?:/[a-z0-9][a-z0-9_-]{0,59}){0,3}\\.(md|txt|json|csv|js)$",
++ "description": "A relative name, no \"..\", ending in .md, .txt, .json, .csv or .js. A .js resource is code and is named by a tool's entry."
++ },
++ "media_type": {
++ "type": "string",
++ "enum": [
++ "text/markdown",
++ "text/plain",
++ "application/json",
++ "text/csv",
++ "text/javascript"
++ ]
++ },
++ "text": {
++ "type": "string",
++ "maxLength": 65536
++ }
++ },
++ "allOf": [
++ {
++ "if": {
++ "properties": {
++ "path": {
++ "type": "string",
++ "pattern": "\\.js$"
++ }
++ },
++ "required": [
++ "path"
++ ]
++ },
++ "then": {
++ "properties": {
++ "media_type": {
++ "type": "string",
++ "const": "text/javascript"
++ },
++ "text": {
++ "type": "string",
++ "maxLength": 65536,
++ "description": "At most 64 KiB of code."
++ }
++ }
++ }
++ },
++ {
++ "if": {
++ "properties": {
++ "media_type": {
++ "type": "string",
++ "const": "text/javascript"
++ }
++ },
++ "required": [
++ "media_type"
++ ]
++ },
++ "then": {
++ "properties": {
++ "path": {
++ "type": "string",
++ "pattern": "\\.js$"
++ }
++ }
++ }
++ },
++ {
++ "if": {
++ "properties": {
++ "media_type": {
++ "type": "string",
++ "enum": [
++ "text/markdown",
++ "text/plain",
++ "application/json",
++ "text/csv"
++ ]
++ }
++ },
++ "required": [
++ "media_type"
++ ]
++ },
++ "then": {
++ "properties": {
++ "text": {
++ "type": "string",
++ "maxLength": 20000
++ }
++ }
++ }
++ }
++ ]
++ }
++ },
++ "tools": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 5,
++ "description": "The tools an agent may call, present exactly when runs is sandbox. Each one runs the code in the resource its entry names, in a sandbox, with the network it declares and never wider.",
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "name",
++ "description",
++ "language",
++ "entry",
++ "args"
++ ],
++ "properties": {
++ "name": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_]{0,31}$",
++ "description": "The name the agent calls."
++ },
++ "description": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200,
++ "description": "What it does: the agent reads this before it calls the tool."
++ },
++ "language": {
++ "const": "javascript",
++ "description": "The only language in v1."
++ },
++ "entry": {
++ "type": "string",
++ "pattern": "^[a-z0-9][a-z0-9_-]{0,59}(?:/[a-z0-9][a-z0-9_-]{0,59}){0,3}\\.js$",
++ "description": "The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema)."
++ },
++ "args": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "type"
++ ],
++ "description": "The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.",
++ "properties": {
++ "type": {
++ "const": "object"
++ },
++ "description": {
++ "type": "string",
++ "maxLength": 200
++ },
++ "properties": {
++ "type": "object",
++ "maxProperties": 20,
++ "additionalProperties": {
++ "$ref": "#/$defs/argValue"
++ }
++ },
++ "required": {
++ "type": "array",
++ "maxItems": 20,
++ "uniqueItems": true,
++ "items": {
++ "type": "string",
++ "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,63}$"
++ }
++ },
++ "additionalProperties": {
++ "const": false
++ }
++ }
++ },
++ "net": {
++ "type": "string",
++ "enum": [
++ "deny",
++ "openvibe-only",
++ "public"
++ ],
++ "default": "deny",
++ "description": "The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this."
++ },
++ "limits": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "Caps on one run of the tool. Run treats them as declared, never above its own caps.",
++ "properties": {
++ "wall_ms": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 30000,
++ "default": 10000,
++ "description": "Wall-clock time, at most 30000 ms; default 10000."
++ },
++ "mem_bytes": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 268435456,
++ "default": 134217728,
++ "description": "Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB)."
++ }
++ }
++ }
++ }
++ }
++ },
++ "requires": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "What the skill may ask an agent to do. It grants nothing: each step still goes through the agent's level and approvals. A sandbox skill names skill.run here.",
++ "properties": {
++ "kinds": {
++ "type": "array",
++ "maxItems": 16,
++ "uniqueItems": true,
++ "items": {
++ "type": "string",
++ "enum": [
++ "codes.task",
++ "actor.action",
++ "computer.run",
++ "computer.write",
++ "computer.input",
++ "computer.browser",
++ "computer.desk",
++ "robot.move",
++ "space",
++ "publish",
++ "post",
++ "send",
++ "install",
++ "routine",
++ "money",
++ "skill.run"
++ ]
++ },
++ "description": "The kinds of act (actor approvals, HO1) its steps may be."
++ },
++ "apps": {
++ "type": "array",
++ "maxItems": 20,
++ "uniqueItems": true,
++ "items": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9._-]{0,63}$"
++ },
++ "description": "Connected apps it uses (connect slugs). The person connects each one themselves."
++ },
++ "hosts": {
++ "type": "array",
++ "maxItems": 20,
++ "uniqueItems": true,
++ "items": {
++ "type": "string",
++ "pattern": "^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,63}$"
++ },
++ "description": "Web hosts it reads from or writes to."
++ }
++ }
++ },
++ "runs": {
++ "type": "string",
++ "enum": [
++ "prompt",
++ "sandbox"
++ ],
++ "description": "How it runs: prompt (instructions and text only, as @1) or sandbox (its code runs in a sandbox, never on an OpenVibe server)."
++ },
++ "license": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 64,
++ "description": "An SPDX licence id, such as MIT or CC-BY-4.0."
++ },
++ "author": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "subject"
++ ],
++ "description": "Who the document says wrote it: a claim, never checked here.",
++ "properties": {
++ "subject": {
++ "type": "string",
++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "name": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ }
++ }
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time",
++ "description": "When the document was written. Not hashed."
++ },
++ "integrity": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "alg",
++ "hash"
++ ],
++ "description": "A sha256 over the canonical JSON: the file was not edited after it was written. Not a signature.",
++ "properties": {
++ "alg": {
++ "const": "sha256"
++ },
++ "hash": {
++ "type": "string",
++ "pattern": "^[0-9a-f]{64}$"
++ }
++ }
++ }
++ },
++ "allOf": [
++ {
++ "if": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "prompt"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ },
++ "then": {
++ "not": {
++ "required": [
++ "tools"
++ ]
++ }
++ }
++ },
++ {
++ "if": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "sandbox"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ },
++ "then": {
++ "required": [
++ "requires",
++ "tools"
++ ],
++ "type": "object",
++ "properties": {
++ "requires": {
++ "required": [
++ "kinds"
++ ],
++ "type": "object",
++ "properties": {
++ "kinds": {
++ "type": "array",
++ "contains": {
++ "const": "skill.run"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ {
++ "if": {
++ "type": "object",
++ "properties": {
++ "runs": {
++ "type": "string",
++ "const": "prompt"
++ }
++ },
++ "required": [
++ "runs"
++ ]
++ },
++ "then": {
++ "type": "object",
++ "properties": {
++ "requires": {
++ "type": "object",
++ "properties": {
++ "kinds": {
++ "type": "array",
++ "not": {
++ "contains": {
++ "const": "skill.run"
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ ],
++ "$defs": {
++ "argValue": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "type"
++ ],
++ "properties": {
++ "type": {
++ "enum": [
++ "string",
++ "number",
++ "integer",
++ "boolean",
++ "array"
++ ]
++ },
++ "description": {
++ "type": "string",
++ "maxLength": 200
++ },
++ "enum": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 100,
++ "uniqueItems": true,
++ "items": {
++ "type": [
++ "string",
++ "number",
++ "integer",
++ "boolean"
++ ]
++ }
++ },
++ "maxLength": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 65536
++ },
++ "pattern": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200,
++ "description": "A regular expression, at most 200 characters. No longer pattern is allowed in v1."
++ },
++ "items": {
++ "$ref": "#/$defs/argScalar"
++ },
++ "minItems": {
++ "type": "integer",
++ "minimum": 0,
++ "maximum": 1000
++ },
++ "maxItems": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 1000
++ }
++ }
++ },
++ "argScalar": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "type"
++ ],
++ "properties": {
++ "type": {
++ "enum": [
++ "string",
++ "number",
++ "integer",
++ "boolean"
++ ]
++ },
++ "description": {
++ "type": "string",
++ "maxLength": 200
++ },
++ "enum": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 100,
++ "uniqueItems": true,
++ "items": {
++ "type": [
++ "string",
++ "number",
++ "integer",
++ "boolean"
++ ]
++ }
++ },
++ "maxLength": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 65536
++ },
++ "pattern": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200
++ }
++ }
++ }
++ }
++ }
++ },
"frame.menu-card": {
"version": "1.0.0",
"owner": "network",
ddiff --git a/generated/openapi/actor.json b/generated/openapi/actor.json
iindex a1e35335..512d09c8 100644
---- a/generated/openapi/actor.json
++++ b/generated/openapi/actor.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Actor API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/ai.json b/generated/openapi/ai.json
iindex f40a6d59..5f5924c4 100644
---- a/generated/openapi/ai.json
++++ b/generated/openapi/ai.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.AI API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/bench.json b/generated/openapi/bench.json
iindex 39dc9bee..0b016f07 100644
---- a/generated/openapi/bench.json
++++ b/generated/openapi/bench.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Bench API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/billing.json b/generated/openapi/billing.json
iindex ae425647..58b43dcc 100644
---- a/generated/openapi/billing.json
++++ b/generated/openapi/billing.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Billing API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/blog.json b/generated/openapi/blog.json
iindex 9e04868c..d0a6d9d9 100644
---- a/generated/openapi/blog.json
++++ b/generated/openapi/blog.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Blog API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/bot.json b/generated/openapi/bot.json
iindex 6179bc96..fe4862dd 100644
---- a/generated/openapi/bot.json
++++ b/generated/openapi/bot.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Bot API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/chat.json b/generated/openapi/chat.json
iindex e24259e9..f524c343 100644
---- a/generated/openapi/chat.json
++++ b/generated/openapi/chat.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Chat API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/codes.json b/generated/openapi/codes.json
iindex 42374fb5..bcf16e5d 100644
---- a/generated/openapi/codes.json
++++ b/generated/openapi/codes.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Codes API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/community.json b/generated/openapi/community.json
iindex d6c83050..bc082388 100644
---- a/generated/openapi/community.json
++++ b/generated/openapi/community.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Community API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/connect.json b/generated/openapi/connect.json
iindex b41e7245..ae2824f8 100644
---- a/generated/openapi/connect.json
++++ b/generated/openapi/connect.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe Connect API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/coupons.json b/generated/openapi/coupons.json
iindex 120ab394..4cd0192f 100644
---- a/generated/openapi/coupons.json
++++ b/generated/openapi/coupons.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Coupons API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/deals.json b/generated/openapi/deals.json
iindex 758ed854..ece3e04e 100644
---- a/generated/openapi/deals.json
++++ b/generated/openapi/deals.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Deals API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/design.json b/generated/openapi/design.json
iindex ac4fc831..a0b2d8b0 100644
---- a/generated/openapi/design.json
++++ b/generated/openapi/design.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Design API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/domains.json b/generated/openapi/domains.json
iindex eeaba02e..41e6f0a2 100644
---- a/generated/openapi/domains.json
++++ b/generated/openapi/domains.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Domains API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/events.json b/generated/openapi/events.json
iindex f90e7ea6..ffb5a136 100644
---- a/generated/openapi/events.json
++++ b/generated/openapi/events.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Events API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/food.json b/generated/openapi/food.json
iindex 88d117e7..d60e95b2 100644
---- a/generated/openapi/food.json
++++ b/generated/openapi/food.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Food API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/games.json b/generated/openapi/games.json
iindex 1bc05fc7..27b1888e 100644
---- a/generated/openapi/games.json
++++ b/generated/openapi/games.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Games API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/host.json b/generated/openapi/host.json
iindex 3277c772..c65fafba 100644
---- a/generated/openapi/host.json
++++ b/generated/openapi/host.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Host API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/inventory.json b/generated/openapi/inventory.json
iindex 11a17116..c857a8fa 100644
---- a/generated/openapi/inventory.json
++++ b/generated/openapi/inventory.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Inventory API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/live.json b/generated/openapi/live.json
iindex 7f9c0165..4fbf6f0b 100644
---- a/generated/openapi/live.json
++++ b/generated/openapi/live.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Live API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/mail.json b/generated/openapi/mail.json
iindex acaff337..cf60e4d1 100644
---- a/generated/openapi/mail.json
++++ b/generated/openapi/mail.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Mail API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Mail as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Mail as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media-hub.json b/generated/openapi/media-hub.json
iindex 51a712d4..2fe9eb01 100644
---- a/generated/openapi/media-hub.json
++++ b/generated/openapi/media-hub.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.MediaHub API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media.json b/generated/openapi/media.json
iindex 7c808e0a..108b5a41 100644
---- a/generated/openapi/media.json
++++ b/generated/openapi/media.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Media API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/network.json b/generated/openapi/network.json
iindex 1dfd4dec..7e301758 100644
---- a/generated/openapi/network.json
++++ b/generated/openapi/network.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Network API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/news.json b/generated/openapi/news.json
iindex ab2173f4..3131441b 100644
---- a/generated/openapi/news.json
++++ b/generated/openapi/news.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.News API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/openre.json b/generated/openapi/openre.json
iindex 11b9a45c..9544c91d 100644
---- a/generated/openapi/openre.json
++++ b/generated/openapi/openre.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenRestream API",
-- "version": "0.342.0",
-- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/play.json b/generated/openapi/play.json
iindex c9a08fcb..cbf96d00 100644
---- a/generated/openapi/play.json
++++ b/generated/openapi/play.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Play API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/quest.json b/generated/openapi/quest.json
iindex 5f07414c..b957f4b5 100644
---- a/generated/openapi/quest.json
++++ b/generated/openapi/quest.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Quest API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/report.json b/generated/openapi/report.json
iindex ac3dd1eb..fdaef7e5 100644
---- a/generated/openapi/report.json
++++ b/generated/openapi/report.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Report API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/reviews.json b/generated/openapi/reviews.json
iindex 1244ad2b..eb269d9d 100644
---- a/generated/openapi/reviews.json
++++ b/generated/openapi/reviews.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Reviews API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/run.json b/generated/openapi/run.json
iindex a02cbf1a..5b7a69bb 100644
---- a/generated/openapi/run.json
++++ b/generated/openapi/run.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Run API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/search.json b/generated/openapi/search.json
iindex 81dec099..47e1977d 100644
---- a/generated/openapi/search.json
++++ b/generated/openapi/search.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Search API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/services.json b/generated/openapi/services.json
iindex 2b364333..83c64289 100644
---- a/generated/openapi/services.json
++++ b/generated/openapi/services.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Services API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/sources.json b/generated/openapi/sources.json
iindex 172c85ea..f0c74603 100644
---- a/generated/openapi/sources.json
++++ b/generated/openapi/sources.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Sources API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/space.json b/generated/openapi/space.json
iindex be5bea1e..2c09b28a 100644
---- a/generated/openapi/space.json
++++ b/generated/openapi/space.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Space API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tips.json b/generated/openapi/tips.json
iindex a3e08e98..7a6d4c3d 100644
---- a/generated/openapi/tips.json
++++ b/generated/openapi/tips.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tips API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/today.json b/generated/openapi/today.json
iindex 5f6e73a4..14af2fe3 100644
---- a/generated/openapi/today.json
++++ b/generated/openapi/today.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Today API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tools.json b/generated/openapi/tools.json
iindex 2fdff7cf..13076a56 100644
---- a/generated/openapi/tools.json
++++ b/generated/openapi/tools.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tools API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/trade.json b/generated/openapi/trade.json
iindex 97998b0b..3ce88037 100644
---- a/generated/openapi/trade.json
++++ b/generated/openapi/trade.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Trade API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/vip.json b/generated/openapi/vip.json
iindex 30444069..0e9f050f 100644
---- a/generated/openapi/vip.json
++++ b/generated/openapi/vip.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.VIP API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/vision.json b/generated/openapi/vision.json
iindex e207a91d..00a9d681 100644
---- a/generated/openapi/vision.json
++++ b/generated/openapi/vision.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Vision API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/watch.json b/generated/openapi/watch.json
iindex fc8e4faf..d1e4f2ff 100644
---- a/generated/openapi/watch.json
++++ b/generated/openapi/watch.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Watch API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/wiki.json b/generated/openapi/wiki.json
iindex 2a971bc7..898a60d1 100644
---- a/generated/openapi/wiki.json
++++ b/generated/openapi/wiki.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Wiki API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/work.json b/generated/openapi/work.json
iindex ea306015..e7d6160c 100644
---- a/generated/openapi/work.json
++++ b/generated/openapi/work.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Work API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/zone.json b/generated/openapi/zone.json
iindex 2f2daa42..eb78504e 100644
---- a/generated/openapi/zone.json
++++ b/generated/openapi/zone.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Zone API",
-- "version": "0.342.0",
-- "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.342.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.343.0",
++ "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.343.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/typescript/index.d.ts b/generated/typescript/index.d.ts
iindex 43351d2a..cd786dc8 100644
---- a/generated/typescript/index.d.ts
++++ b/generated/typescript/index.d.ts
@@@ -301554,262 +301554,1135 @@ export interface ActorSkillListing {
retired_at?: string;
}
--/** [email protected] (owner: actor) */
++/** [email protected] (owner: actor) */
/**
-- * actor.canvas@1: an agent's live panel beside the conversation (ADR-059) — a board of a trip, a table of prices, a checklist of what is left. It is DATA: a list of blocks drawn by one renderer (OpenVibe.Shared ov-canvas.js) wherever it is shown (Chat, Surf, the Dock, Actor). There is no HTML, no style, no script and no frame: text is plain and the renderer escapes it; an image is only a picture on openvibe.media; a link opens in a new tab with its host shown. A canvas acts only through the person: a button sends its label to the agent as the person's own message (action ask), and ticking a checklist item tells the agent which item changed; the agent's next steps go through its level and approvals like any other. VERSION only grows: a viewer ignores an older one, and the agent replaces the whole document, never part of it.
++ * actor.skill-listing@2: a skill in the registry, the record every site shows on its card (ADR-058, ADR-060). It keeps every field and meaning of actor.skill-listing@1 and adds what a sandbox skill needs to be shown and run: the document is actor.skill@2, CODE lists, per code resource, its name (the resource path a tool's entry names), the Media object id its bytes are stored under and the sha256 of those bytes, so the bytes that run are the bytes that were scanned; and the SCAN's findings may name the TOOL they are about, so a person reads the scan one tool at a time. A sandbox listing carries code; a prompt listing carries none. It still carries the PUBLISHER from the registry's own record (vouched: unlike the document's author, this is who published it), the SCAN (its state and findings travel with the listing), and the CURATOR's state. Install rules every site keeps: a passed skill installs in one tap; a flagged one only after the person reads the findings and confirms; a failed one never; a stale or archived one is not offered. Installing copies the document into the person's agent; it grants nothing (the skill's requires is a declaration).
*/
--export interface ActorCanvas {
-- canvas: "actor.canvas@1";
-- id: string;
-- title: string;
-- /**
-- * Grows with every update; a viewer ignores an older version.
-- */
-- version: number;
-- /**
-- * The agent that draws it.
-- */
-- agent_id?: string;
++export type ActorSkillListingV2 = {
++ [k: string]: unknown | undefined;
++} & {
++ listing: "actor.skill-listing@2";
/**
-- * The conversation it sits beside (Actor's task or chat id).
++ * The listing's id.
*/
-- thread?: string;
-- updated_at: string;
++ id: string;
++ skill: ActorSkillV2;
/**
-- * @maxItems 60
++ * Per code resource of a sandbox skill: the resource path a tool entry names, the Media object the registry stored its bytes under, and the sha256 of those bytes. Required when the skill runs in a sandbox; absent for a prompt skill.
++ *
++ * @maxItems 10
*/
-- blocks: (
-- | {
-- type: "heading";
-- /**
-- * A stable id, so a viewer keeps its place when the canvas updates.
-- */
-- id?: string;
-- text: string;
-- level?: 1 | 2;
-- }
-- | {
-- type: "text";
-- /**
-- * A stable id, so a viewer keeps its place when the canvas updates.
-- */
-- id?: string;
-- text: string;
-- }
-- | {
-- type: "list";
-- /**
-- * A stable id, so a viewer keeps its place when the canvas updates.
-- */
-- id?: string;
-- /**
-- * @maxItems 50
-- */
-- items: string[];
-- ordered?: boolean;
-- }
-- | {
-- type: "checklist";
-- /**
-- * A stable id, so a viewer keeps its place when the canvas updates.
-- */
-- id?: string;
-- /**
-- * @maxItems 50
-- */
-- items: {
-- id: string;
-- text: string;
-- done: boolean;
-- }[];
-- }
-- | {
-- type: "table";
-- /**
-- * A stable id, so a viewer keeps its place when the canvas updates.
-- */
-- id?: string;
-- /**
-- * @minItems 1
-- * @maxItems 8
-- */
-- columns:
-- | [string]
-- | [string, string]
-- | [string, string, string]
-- | [string, string, string, string]
-- | [string, string, string, string, string]
-- | [string, string, string, string, string, string]
-- | [string, string, string, string, string, string, string]
-- | [string, string, string, string, string, string, string, string];
-- /**
-- * @maxItems 100
-- */
-- rows:
-- | []
-- | [string | number]
-- | [string | number, string | number]
-- | [string | number, string | number, string | number]
-- | [string | number, string | number, string | number, string | number]
-- | [string | number, string | number, string | number, string | number, string | number]
-- | [string | number, string | number, string | number, string | number, string | number, string | number]
-- | [
-- string | number,
-- string | number,
-- string | number,
-- string | number,
-- string | number,
-- string | number,
-- string | number
-- ]
-- | [
-- string | number,
-- string | number,
-- string | number,
-- string | number,
-- string | number,
-- string | number,
-- string | number,
-- string | number
-- ][];
-- }
-- | {
-- type: "metric";
-- /**
-- * A stable id, so a viewer keeps its place when the canvas updates.
-- */
-- id?: string;
-- label: string;
-- value: string;
-- note?: string;
-- }
-- | {
-- type: "chart";
-- /**
-- * A stable id, so a viewer keeps its place when the canvas updates.
-- */
-- id?: string;
-- kind: "bar" | "line";
-- unit?: string;
-- /**
-- * @minItems 1
-- * @maxItems 4
-- */
-- series:
-- | [
-- {
-- name: string;
-- /**
-- * @minItems 1
-- * @maxItems 60
-- */
-- points: [
-- {
-- x: string;
-- y: number;
-- },
-- ...{
-- x: string;
-- y: number;
-- }[]
-- ];
-- }
-- ]
-- | [
-- {
-- name: string;
-- /**
-- * @minItems 1
-- * @maxItems 60
-- */
-- points: [
-- {
-- x: string;
-- y: number;
-- },
-- ...{
-- x: string;
-- y: number;
-- }[]
-- ];
-- },
-- {
-- name: string;
-- /**
-- * @minItems 1
-- * @maxItems 60
-- */
-- points: [
-- {
-- x: string;
-- y: number;
-- },
-- ...{
-- x: string;
-- y: number;
-- }[]
-- ];
-- }
-- ]
-- | [
-- {
-- name: string;
-- /**
-- * @minItems 1
-- * @maxItems 60
-- */
-- points: [
-- {
-- x: string;
-- y: number;
-- },
-- ...{
-- x: string;
-- y: number;
-- }[]
-- ];
-- },
-- {
-- name: string;
-- /**
-- * @minItems 1
-- * @maxItems 60
-- */
-- points: [
-- {
-- x: string;
-- y: number;
-- },
-- ...{
-- x: string;
-- y: number;
-- }[]
-- ];
-- },
-- {
-- name: string;
-- /**
-- * @minItems 1
-- * @maxItems 60
-- */
-- points: [
-- {
-- x: string;
-- y: number;
-- },
-- ...{
-- x: string;
-- y: number;
-- }[]
-- ];
-- }
-- ]
-- | [
-- {
-- name: string;
-- /**
-- * @minItems 1
-- * @maxItems 60
++ code?:
++ | []
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ },
++ {
++ /**
++ * The resource path, as the document's tools entry names it.
++ */
++ name: string;
++ /**
++ * The Media object id the code bytes are stored under.
++ */
++ media_id: string;
++ /**
++ * Lowercase hex SHA-256 of the code bytes.
++ */
++ sha256: string;
++ }
++ ];
++ /**
++ * Who published it, from the registry's own record.
++ */
++ publisher: {
++ /**
++ * OpenVibe's own skills, or a person's.
++ */
++ kind: "openvibe" | "person";
++ /**
++ * The person who published it (kind person).
++ */
++ subject?: string;
++ name?: string;
++ };
++ /**
++ * What the registry's scan found. It travels with the listing, and a finding about a tool names it.
++ */
++ scan: {
++ state: "pending" | "passed" | "flagged" | "failed";
++ /**
++ * The scanner and its version.
++ */
++ scanner?: string;
++ scanned_at?: string;
++ /**
++ * @maxItems 50
++ */
++ findings?: {
++ /**
++ * Which rule, such as code.network or code.env.
++ */
++ rule: string;
++ severity: "info" | "warn" | "block";
++ /**
++ * instructions, description, or a resource path.
++ */
++ where?: string;
++ /**
++ * The tool the finding is about, when it is about one tool.
++ */
++ tool?: string;
++ /**
++ * What it found, in plain words.
++ */
++ note: string;
++ }[];
++ };
++ /**
++ * The curator ships with the catalogue: what is used stays, what is not goes stale.
++ */
++ curator: {
++ state: "active" | "stale" | "archived";
++ last_used_at?: string;
++ /**
++ * A listing that does the same job.
++ */
++ near_duplicate_of?: string;
++ };
++ installs?: number;
++ listed_at: string;
++ retired_at?: string;
++};
++
++/** [email protected] (owner: actor) */
++/**
++ * actor.canvas@1: an agent's live panel beside the conversation (ADR-059) — a board of a trip, a table of prices, a checklist of what is left. It is DATA: a list of blocks drawn by one renderer (OpenVibe.Shared ov-canvas.js) wherever it is shown (Chat, Surf, the Dock, Actor). There is no HTML, no style, no script and no frame: text is plain and the renderer escapes it; an image is only a picture on openvibe.media; a link opens in a new tab with its host shown. A canvas acts only through the person: a button sends its label to the agent as the person's own message (action ask), and ticking a checklist item tells the agent which item changed; the agent's next steps go through its level and approvals like any other. VERSION only grows: a viewer ignores an older one, and the agent replaces the whole document, never part of it.
++ */
++export interface ActorCanvas {
++ canvas: "actor.canvas@1";
++ id: string;
++ title: string;
++ /**
++ * Grows with every update; a viewer ignores an older version.
++ */
++ version: number;
++ /**
++ * The agent that draws it.
++ */
++ agent_id?: string;
++ /**
++ * The conversation it sits beside (Actor's task or chat id).
++ */
++ thread?: string;
++ updated_at: string;
++ /**
++ * @maxItems 60
++ */
++ blocks: (
++ | {
++ type: "heading";
++ /**
++ * A stable id, so a viewer keeps its place when the canvas updates.
++ */
++ id?: string;
++ text: string;
++ level?: 1 | 2;
++ }
++ | {
++ type: "text";
++ /**
++ * A stable id, so a viewer keeps its place when the canvas updates.
++ */
++ id?: string;
++ text: string;
++ }
++ | {
++ type: "list";
++ /**
++ * A stable id, so a viewer keeps its place when the canvas updates.
++ */
++ id?: string;
++ /**
++ * @maxItems 50
++ */
++ items: string[];
++ ordered?: boolean;
++ }
++ | {
++ type: "checklist";
++ /**
++ * A stable id, so a viewer keeps its place when the canvas updates.
++ */
++ id?: string;
++ /**
++ * @maxItems 50
++ */
++ items: {
++ id: string;
++ text: string;
++ done: boolean;
++ }[];
++ }
++ | {
++ type: "table";
++ /**
++ * A stable id, so a viewer keeps its place when the canvas updates.
++ */
++ id?: string;
++ /**
++ * @minItems 1
++ * @maxItems 8
++ */
++ columns:
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string];
++ /**
++ * @maxItems 100
++ */
++ rows:
++ | []
++ | [string | number]
++ | [string | number, string | number]
++ | [string | number, string | number, string | number]
++ | [string | number, string | number, string | number, string | number]
++ | [string | number, string | number, string | number, string | number, string | number]
++ | [string | number, string | number, string | number, string | number, string | number, string | number]
++ | [
++ string | number,
++ string | number,
++ string | number,
++ string | number,
++ string | number,
++ string | number,
++ string | number
++ ]
++ | [
++ string | number,
++ string | number,
++ string | number,
++ string | number,
++ string | number,
++ string | number,
++ string | number,
++ string | number
++ ][];
++ }
++ | {
++ type: "metric";
++ /**
++ * A stable id, so a viewer keeps its place when the canvas updates.
++ */
++ id?: string;
++ label: string;
++ value: string;
++ note?: string;
++ }
++ | {
++ type: "chart";
++ /**
++ * A stable id, so a viewer keeps its place when the canvas updates.
++ */
++ id?: string;
++ kind: "bar" | "line";
++ unit?: string;
++ /**
++ * @minItems 1
++ * @maxItems 4
++ */
++ series:
++ | [
++ {
++ name: string;
++ /**
++ * @minItems 1
++ * @maxItems 60
++ */
++ points: [
++ {
++ x: string;
++ y: number;
++ },
++ ...{
++ x: string;
++ y: number;
++ }[]
++ ];
++ }
++ ]
++ | [
++ {
++ name: string;
++ /**
++ * @minItems 1
++ * @maxItems 60
++ */
++ points: [
++ {
++ x: string;
++ y: number;
++ },
++ ...{
++ x: string;
++ y: number;
++ }[]
++ ];
++ },
++ {
++ name: string;
++ /**
++ * @minItems 1
++ * @maxItems 60
++ */
++ points: [
++ {
++ x: string;
++ y: number;
++ },
++ ...{
++ x: string;
++ y: number;
++ }[]
++ ];
++ }
++ ]
++ | [
++ {
++ name: string;
++ /**
++ * @minItems 1
++ * @maxItems 60
++ */
++ points: [
++ {
++ x: string;
++ y: number;
++ },
++ ...{
++ x: string;
++ y: number;
++ }[]
++ ];
++ },
++ {
++ name: string;
++ /**
++ * @minItems 1
++ * @maxItems 60
++ */
++ points: [
++ {
++ x: string;
++ y: number;
++ },
++ ...{
++ x: string;
++ y: number;
++ }[]
++ ];
++ },
++ {
++ name: string;
++ /**
++ * @minItems 1
++ * @maxItems 60
++ */
++ points: [
++ {
++ x: string;
++ y: number;
++ },
++ ...{
++ x: string;
++ y: number;
++ }[]
++ ];
++ }
++ ]
++ | [
++ {
++ name: string;
++ /**
++ * @minItems 1
++ * @maxItems 60
*/
points: [
{
@@@ -301911,15 +302784,2897 @@ export interface ActorCanvas {
)[];
}
--/** [email protected] (owner: actor) */
++/** [email protected] (owner: actor) */
++/**
++ * actor.skill@1: a skill, the document an agent loads to do one kind of job well (ADR-058). It follows the open Markdown-skill shape (a name, a one-line description, Markdown instructions) with what OpenVibe adds: a slug, a version, up to ten TEXT resources, and REQUIRES, what the skill may ask an agent to do. A skill GRANTS NOTHING: requires only declares; the agent's level and approvals decide every step (actor approvals, HO1), and a step of a kind the skill did not declare is a scan finding (actor.skill-listing@1). A v1 skill RUNS AS A PROMPT and nothing else: no code, no binary, no install recipe (a skill that runs code waits for a sandbox and a new major). DESCRIPTION is the only part an agent reads before it loads the skill (progressive disclosure), so it says when to use it. The INTEGRITY block is a sha256 over the canonical JSON of the document: it shows the file was not edited after it was written and says nothing about who wrote it, so the AUTHOR is a claim; the registry's listing is the only place a publisher is vouched for. The canonical JSON is the document's own fields, in this order: skill, slug, name, description, version, instructions, resources, requires, runs, license, author; an optional field that is absent or empty is left out; resources are [{ path, media_type, text }] in the document's order; requires is { kinds, apps, hosts } with empty lists left out; author is { subject } or { subject, name }; the value is the compact JSON of that object (no spaces). CREATED_AT is not hashed.
++ */
++export interface ActorSkill {
++ /**
++ * The document marker.
++ */
++ skill: "actor.skill@1";
++ /**
++ * Its name in the registry: lowercase letters, digits and hyphens.
++ */
++ slug: string;
++ /**
++ * What a person reads on its card.
++ */
++ name: string;
++ /**
++ * When to use it, in one line: the only part an agent reads before it loads the skill.
++ */
++ description: string;
++ /**
++ * Its semantic version.
++ */
++ version: string;
++ /**
++ * What to do, in Markdown. The agent reads it as guidance; it never grants a permission.
++ */
++ instructions: string;
++ /**
++ * Text the instructions refer to (a checklist, a template, a table). Never code to run.
++ *
++ * @maxItems 10
++ */
++ resources?:
++ | []
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ]
++ | [
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ },
++ {
++ /**
++ * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ */
++ path: string;
++ media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
++ text: string;
++ }
++ ];
++ /**
++ * What the skill may ask an agent to do. It grants nothing: each step still goes through the agent's level and approvals.
++ */
++ requires?: {
++ /**
++ * The kinds of act (actor approvals, HO1) its steps may be.
++ *
++ * @maxItems 15
++ */
++ kinds?:
++ | []
++ | [
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ )
++ ];
++ /**
++ * Connected apps it uses (connect slugs). The person connects each one themselves.
++ *
++ * @maxItems 20
++ */
++ apps?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ /**
++ * Web hosts it reads from or writes to.
++ *
++ * @maxItems 20
++ */
++ hosts?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ };
++ /**
++ * How it runs. v1 skills are instructions and text only.
++ */
++ runs: "prompt";
++ /**
++ * An SPDX licence id, such as MIT or CC-BY-4.0.
++ */
++ license?: string;
++ /**
++ * Who the document says wrote it: a claim, never checked here.
++ */
++ author?: {
++ subject: string;
++ name?: string;
++ };
++ /**
++ * When the document was written. Not hashed.
++ */
++ created_at?: string;
++ /**
++ * A sha256 over the canonical JSON: the file was not edited after it was written. Not a signature.
++ */
++ integrity: {
++ alg: "sha256";
++ hash: string;
++ };
++}
++
++/** [email protected] (owner: actor) */
/**
-- * actor.skill@1: a skill, the document an agent loads to do one kind of job well (ADR-058). It follows the open Markdown-skill shape (a name, a one-line description, Markdown instructions) with what OpenVibe adds: a slug, a version, up to ten TEXT resources, and REQUIRES, what the skill may ask an agent to do. A skill GRANTS NOTHING: requires only declares; the agent's level and approvals decide every step (actor approvals, HO1), and a step of a kind the skill did not declare is a scan finding (actor.skill-listing@1). A v1 skill RUNS AS A PROMPT and nothing else: no code, no binary, no install recipe (a skill that runs code waits for a sandbox and a new major). DESCRIPTION is the only part an agent reads before it loads the skill (progressive disclosure), so it says when to use it. The INTEGRITY block is a sha256 over the canonical JSON of the document: it shows the file was not edited after it was written and says nothing about who wrote it, so the AUTHOR is a claim; the registry's listing is the only place a publisher is vouched for. The canonical JSON is the document's own fields, in this order: skill, slug, name, description, version, instructions, resources, requires, runs, license, author; an optional field that is absent or empty is left out; resources are [{ path, media_type, text }] in the document's order; requires is { kinds, apps, hosts } with empty lists left out; author is { subject } or { subject, name }; the value is the compact JSON of that object (no spaces). CREATED_AT is not hashed.
++ * actor.skill@2: a skill, the document an agent loads to do one kind of job well (ADR-058, ADR-060). It keeps every field and meaning of actor.skill@1 and adds a way for the skill to bring CODE that runs in a sandbox: RUNS is prompt (as @1, text and instructions only) or sandbox. A sandbox skill carries its code as ordinary TEXT resources (a .js path with media_type text/javascript, at most 64 KiB each, in the integrity hash); TOOLS (1 to 5, only when runs is sandbox) say what an agent may call: a name, a description the agent reads, language javascript (the only one in v1), an ENTRY naming one of the skill's own .js resources, ARGS as a JSON Schema subset (an object whose properties are string, number, integer, boolean or an array of those; enum, maxLength, and pattern at most 200 characters; no $ref and no nested object), NET (deny by default, openvibe-only, public) and LIMITS (wall_ms at most 30000, default 10000; mem_bytes at most 268435456, default 134217728). A sandbox skill's requires.kinds names skill.run; a prompt skill declares no tools. A skill GRANTS NOTHING: requires only declares; the agent's level and approvals decide every step (actor approvals, HO1), and a step of a kind the skill did not declare is a scan finding (actor.skill-listing@2). Code never runs on an OpenVibe server and never sees a secret: it runs as a Run job of class function on a Node that declared the skill runner, with the network its tool declared and the exact bytes the registry scanned. The INTEGRITY block is a sha256 over the canonical JSON of the document: it shows the file was not edited after it was written and says nothing about who wrote it, so the AUTHOR is a claim; the registry's listing is the only place a publisher is vouched for. The canonical JSON is the document's own fields, in this order: skill, slug, name, description, version, instructions, resources, tools, requires, runs, license, author; an optional field that is absent or empty is left out; resources are [{ path, media_type, text }] in the document's order; tools are [{ name, description, language, entry, args, net, limits }] in the document's order, with an absent net or limits (and each absent limits field) left out and args as the object the document wrote; requires is { kinds, apps, hosts } with empty lists left out; author is { subject } or { subject, name }; the value is the compact JSON of that object (no spaces). CREATED_AT is not hashed.
*/
--export interface ActorSkill {
++export type ActorSkillV2 = {
++ [k: string]: unknown | undefined;
++} & {
/**
* The document marker.
*/
-- skill: "actor.skill@1";
++ skill: "actor.skill@2";
/**
* Its name in the registry: lowercase letters, digits and hyphens.
*/
@@@ -301941,480 +305696,3817 @@ export interface ActorSkill {
*/
instructions: string;
/**
-- * Text the instructions refer to (a checklist, a template, a table). Never code to run.
++ * Text the instructions refer to (a checklist, a template, a table) and, for a sandbox skill, the code a tool's entry names. Code is a text resource, not a binary and not an install recipe: it runs in a sandbox and never on an OpenVibe server. Any resource is at most 64 KiB; a non-code resource keeps @1's 20000-character cap.
++ *
++ * @maxItems 10
++ */
++ resources?:
++ | []
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ]
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ]
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ]
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ]
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ]
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ]
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ]
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ]
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ]
++ | [
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ },
++ {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ } & {
++ [k: string]: unknown | undefined;
++ }
++ ];
++ /**
++ * The tools an agent may call, present exactly when runs is sandbox. Each one runs the code in the resource its entry names, in a sandbox, with the network it declares and never wider.
*
-- * @maxItems 10
++ * @minItems 1
++ * @maxItems 5
*/
-- resources?:
-- | []
++ tools?:
++ | [
++ {
++ /**
++ * The name the agent calls.
++ */
++ name: string;
++ /**
++ * What it does: the agent reads this before it calls the tool.
++ */
++ description: string;
++ /**
++ * The only language in v1.
++ */
++ language: "javascript";
++ /**
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
++ */
++ entry: string;
++ /**
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
++ */
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
++ /**
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
++ */
++ net?: "deny" | "openvibe-only" | "public";
++ /**
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
++ */
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
++ }
++ ]
| [
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
++ */
++ name: string;
++ /**
++ * What it does: the agent reads this before it calls the tool.
++ */
++ description: string;
++ /**
++ * The only language in v1.
++ */
++ language: "javascript";
++ /**
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
++ */
++ entry: string;
++ /**
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
++ */
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
++ /**
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
++ */
++ net?: "deny" | "openvibe-only" | "public";
++ /**
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
++ */
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
++ },
++ {
++ /**
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- }
-- ]
-- | [
-- {
++ name: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * What it does: the agent reads this before it calls the tool.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ description: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The only language in v1.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ language: "javascript";
++ /**
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
++ */
++ entry: string;
++ /**
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
++ */
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
++ /**
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
++ */
++ net?: "deny" | "openvibe-only" | "public";
++ /**
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
++ */
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
}
]
| [
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ name: string;
++ /**
++ * What it does: the agent reads this before it calls the tool.
++ */
++ description: string;
++ /**
++ * The only language in v1.
++ */
++ language: "javascript";
++ /**
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
++ */
++ entry: string;
++ /**
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
++ */
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
++ /**
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
++ */
++ net?: "deny" | "openvibe-only" | "public";
++ /**
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
++ */
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
},
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ name: string;
++ /**
++ * What it does: the agent reads this before it calls the tool.
++ */
++ description: string;
++ /**
++ * The only language in v1.
++ */
++ language: "javascript";
++ /**
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
++ */
++ entry: string;
++ /**
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
++ */
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
++ /**
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
++ */
++ net?: "deny" | "openvibe-only" | "public";
++ /**
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
++ */
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
},
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ name: string;
++ /**
++ * What it does: the agent reads this before it calls the tool.
++ */
++ description: string;
++ /**
++ * The only language in v1.
++ */
++ language: "javascript";
++ /**
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
++ */
++ entry: string;
++ /**
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
++ */
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
++ /**
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
++ */
++ net?: "deny" | "openvibe-only" | "public";
++ /**
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
++ */
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
}
]
| [
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
++ */
++ name: string;
++ /**
++ * What it does: the agent reads this before it calls the tool.
++ */
++ description: string;
++ /**
++ * The only language in v1.
++ */
++ language: "javascript";
++ /**
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
++ */
++ entry: string;
++ /**
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
++ */
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
++ /**
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
++ */
++ net?: "deny" | "openvibe-only" | "public";
++ /**
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
++ */
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
++ },
++ {
++ /**
++ * The name the agent calls.
++ */
++ name: string;
++ /**
++ * What it does: the agent reads this before it calls the tool.
++ */
++ description: string;
++ /**
++ * The only language in v1.
++ */
++ language: "javascript";
++ /**
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
++ */
++ entry: string;
++ /**
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
++ */
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
++ /**
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ net?: "deny" | "openvibe-only" | "public";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
},
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ name: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * What it does: the agent reads this before it calls the tool.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- }
-- ]
-- | [
-- {
++ description: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The only language in v1.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ language: "javascript";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ entry: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ net?: "deny" | "openvibe-only" | "public";
++ /**
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
++ */
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
},
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- }
-- ]
-- | [
-- {
++ name: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * What it does: the agent reads this before it calls the tool.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ description: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The only language in v1.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ language: "javascript";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ entry: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ net?: "deny" | "openvibe-only" | "public";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
}
]
| [
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ name: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * What it does: the agent reads this before it calls the tool.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ description: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The only language in v1.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ language: "javascript";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ entry: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ net?: "deny" | "openvibe-only" | "public";
++ /**
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
++ */
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
},
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- }
-- ]
-- | [
-- {
++ name: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * What it does: the agent reads this before it calls the tool.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ description: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The only language in v1.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ language: "javascript";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ entry: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ net?: "deny" | "openvibe-only" | "public";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
},
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ name: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * What it does: the agent reads this before it calls the tool.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- }
-- ]
-- | [
-- {
++ description: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The only language in v1.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ language: "javascript";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ entry: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ net?: "deny" | "openvibe-only" | "public";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
},
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ name: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * What it does: the agent reads this before it calls the tool.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ description: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The only language in v1.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ language: "javascript";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- }
-- ]
-- | [
-- {
++ entry: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ net?: "deny" | "openvibe-only" | "public";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
},
{
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name the agent calls.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ name: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * What it does: the agent reads this before it calls the tool.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ description: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The only language in v1.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ language: "javascript";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The name of one of the skill's own .js resources (a cross-field rule the registry checks, not this schema).
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ entry: string;
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The tool's input as a JSON Schema subset: an object whose properties are string, number, integer, boolean or an array of those, with enum, maxLength and pattern (at most 200 characters). No $ref and no nested object.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ args: {
++ type: "object";
++ description?: string;
++ properties?: {
++ [k: string]:
++ | {
++ type: "string" | "number" | "integer" | "boolean" | "array";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ /**
++ * A regular expression, at most 200 characters. No longer pattern is allowed in v1.
++ */
++ pattern?: string;
++ items?: {
++ type: "string" | "number" | "integer" | "boolean";
++ description?: string;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ enum?: [string | number | number | boolean, ...(string | number | number | boolean)[]];
++ maxLength?: number;
++ pattern?: string;
++ };
++ minItems?: number;
++ maxItems?: number;
++ }
++ | undefined;
++ };
++ /**
++ * @maxItems 20
++ */
++ required?:
++ | []
++ | [string]
++ | [string, string]
++ | [string, string, string]
++ | [string, string, string, string]
++ | [string, string, string, string, string]
++ | [string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string]
++ | [string, string, string, string, string, string, string, string, string, string, string, string, string]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ]
++ | [
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string,
++ string
++ ];
++ additionalProperties?: false;
++ };
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * The network the tool may reach: deny (no network; the default), openvibe-only (OpenVibe's own endpoints), or public (the internet). It is never wider than this.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
-- },
-- {
++ net?: "deny" | "openvibe-only" | "public";
/**
-- * A relative name, no "..", ending in .md, .txt, .json or .csv.
++ * Caps on one run of the tool. Run treats them as declared, never above its own caps.
*/
-- path: string;
-- media_type: "text/markdown" | "text/plain" | "application/json" | "text/csv";
-- text: string;
++ limits?: {
++ /**
++ * Wall-clock time, at most 30000 ms; default 10000.
++ */
++ wall_ms?: number;
++ /**
++ * Peak memory, at most 268435456 bytes (256 MiB); default 134217728 (128 MiB).
++ */
++ mem_bytes?: number;
++ };
}
];
/**
-- * What the skill may ask an agent to do. It grants nothing: each step still goes through the agent's level and approvals.
++ * What the skill may ask an agent to do. It grants nothing: each step still goes through the agent's level and approvals. A sandbox skill names skill.run here.
*/
requires?: {
/**
* The kinds of act (actor approvals, HO1) its steps may be.
*
-- * @maxItems 15
++ * @maxItems 16
*/
kinds?:
| []
@@@ -302434,6 +309526,45 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ]
++ | [
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
++ )
]
| [
(
@@@ -302452,6 +309583,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302469,6 +309619,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -302488,6 +309639,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302505,6 +309675,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302522,6 +309693,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -302541,6 +309713,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302558,6 +309749,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302575,6 +309767,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302592,6 +309785,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -302611,6 +309805,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302628,6 +309841,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302645,6 +309859,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302662,6 +309877,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302679,6 +309895,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -302698,6 +309915,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302715,6 +309951,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302732,6 +309969,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302749,6 +309987,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302766,6 +310005,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302783,6 +310023,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -302802,6 +310043,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302819,6 +310079,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302836,6 +310097,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302853,6 +310115,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302870,6 +310133,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302887,6 +310151,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302904,6 +310169,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -302923,6 +310189,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302940,6 +310225,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302957,6 +310243,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302974,6 +310261,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -302991,6 +310279,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303008,6 +310297,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303025,6 +310315,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303042,6 +310333,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -303061,6 +310353,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303078,6 +310389,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303095,6 +310407,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303112,6 +310425,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303129,6 +310443,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303146,6 +310461,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303163,6 +310479,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303180,6 +310497,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303197,6 +310515,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -303216,6 +310535,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303233,6 +310571,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303250,6 +310589,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303267,6 +310607,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303284,6 +310625,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303301,6 +310643,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303318,6 +310661,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303335,6 +310679,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303352,6 +310697,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303369,6 +310715,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -303388,6 +310735,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303405,6 +310771,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303422,6 +310789,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303439,6 +310807,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303456,6 +310825,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303473,6 +310843,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303490,6 +310861,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303507,6 +310879,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303524,6 +310897,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303541,6 +310915,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303558,6 +310933,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -303577,6 +310953,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303594,6 +310989,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303611,6 +311007,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303628,6 +311025,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303645,6 +311043,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303662,6 +311061,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303679,6 +311079,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303696,6 +311097,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303713,6 +311115,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303730,6 +311133,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303747,6 +311151,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303764,6 +311169,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -303783,6 +311189,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303800,6 +311225,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303817,6 +311243,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303834,6 +311261,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303851,6 +311279,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303868,6 +311297,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303885,6 +311315,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303902,6 +311333,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303919,6 +311351,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303936,6 +311369,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303953,6 +311387,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303970,6 +311405,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -303987,6 +311423,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -304006,6 +311443,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304023,6 +311479,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304040,6 +311497,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304057,6 +311515,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304074,6 +311533,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304091,6 +311551,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304108,6 +311569,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304125,6 +311587,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304142,6 +311605,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304159,6 +311623,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304176,6 +311641,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304193,6 +311659,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304210,6 +311677,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304227,6 +311695,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
]
| [
@@@ -304246,6 +311715,25 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
++ ),
++ (
++ | "codes.task"
++ | "actor.action"
++ | "computer.run"
++ | "computer.write"
++ | "computer.input"
++ | "computer.browser"
++ | "computer.desk"
++ | "robot.move"
++ | "space"
++ | "publish"
++ | "post"
++ | "send"
++ | "install"
++ | "routine"
++ | "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304263,6 +311751,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304280,6 +311769,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304297,6 +311787,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304314,6 +311805,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304331,6 +311823,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304348,6 +311841,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304365,6 +311859,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304382,6 +311877,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304399,6 +311895,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304416,6 +311913,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304433,6 +311931,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304450,6 +311949,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304467,6 +311967,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
),
(
| "codes.task"
@@@ -304484,6 +311985,7 @@ export interface ActorSkill {
| "install"
| "routine"
| "money"
++ | "skill.run"
)
];
/**
@@@ -304764,9 +312266,9 @@ export interface ActorSkill {
];
};
/**
-- * How it runs. v1 skills are instructions and text only.
++ * How it runs: prompt (instructions and text only, as @1) or sandbox (its code runs in a sandbox, never on an OpenVibe server).
*/
-- runs: "prompt";
++ runs: "prompt" | "sandbox";
/**
* An SPDX licence id, such as MIT or CC-BY-4.0.
*/
@@@ -304789,7 +312291,7 @@ export interface ActorSkill {
alg: "sha256";
hash: string;
};
--}
++};
/** [email protected] (owner: network) */
/**
ddiff --git a/package-lock.json b/package-lock.json
iindex a8a2f23d..bf4d67c0 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -1,12 +1,12 @@
{
"name": "openvibe-contracts",
-- "version": "0.336.0",
++ "version": "0.343.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openvibe-contracts",
-- "version": "0.336.0",
++ "version": "0.343.0",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
ddiff --git a/package.json b/package.json
iindex 9728984f..7f7da4db 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.342.0",
++ "version": "0.343.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"types": "generated/typescript/index.d.ts",
ddiff --git a/test/run.js b/test/run.js
iindex 3af8c200..7564af87 100644
---- a/test/run.js
++++ b/test/run.js
@@@ -73,9 +73,31 @@ const FULL_CHECK = {
'zone.object-zone-usage': (v) => contracts.zones.checkObjectZoneUsage(v), 'common.usage-recorded': (v) => contracts.usage.checkUsageRecorded(v),
'common.resource-name': (v) => contracts.resources.checkName(v), 'common.resource-control-request': (v) => contracts.resources.checkControlRequest(v),
'common.resource-control-result': (v) => contracts.resources.checkControlResult(v),
++ // A tool's entry has to name one of the document's own code resources, a cross-field rule JSON
++ // Schema cannot state (the registry checks it too, before it stores anything).
++ 'actor.skill': (v, ref) => {
++ const r = contracts.validate(ref, v);
++ if (!r.valid) return r;
++ const paths = new Set((v.resources || []).map((x) => x.path));
++ const missing = (v.tools || []).filter((t) => !paths.has(t.entry));
++ return missing.length
++ ? { valid: false, errors: missing.map((t) => ({ path: '/tools', message: `entry ${t.entry} names no resource` })) }
++ : r;
++ },
};
--// `fixtures/<id>/` is one set per contract id, checked against its newest major (a v1 file's fixtures
--// stay valid under an additive v2, and a v2-only example belongs there too).
++/** The ref a fixture names itself (`skill: actor.skill@2`) or the bare id (newest major) when it names none. */
++const majorRef = (id, value) => {
++ if (!value || typeof value !== 'object') return id;
++ for (const v of Object.values(value)) {
++ if (typeof v !== 'string' || !v.startsWith(`${id}@`)) continue;
++ const major = v.slice(id.length + 1);
++ if (/^\d+$/.test(major) && contracts.catalog.some((e) => e.id === id && e.version.split('.')[0] === major)) return `${id}@${major}`;
++ }
++ return id;
++};
++// `fixtures/<id>/` is one set per contract id, checked against the major the document names, or its
++// newest major when it names none (a v1 file's fixtures stay valid under an additive v2, and a v2-only
++// example belongs there too).
for (const c of [...new Map(contracts.catalog.map((e) => [e.id, e])).values()]) {
for (const kind of ['valid', 'invalid']) {
const dir = path.join(ROOT, 'fixtures', c.id, kind);
@@@ -83,7 +105,8 @@ for (const c of [...new Map(contracts.catalog.map((e) => [e.id, e])).values()])
ok(list.length > 0, `${c.id} has ${kind} fixtures`);
for (const f of list) {
const value = JSON.parse(fs.readFileSync(path.join(dir, f), 'utf8'));
-- const r = FULL_CHECK[c.id] ? FULL_CHECK[c.id](value) : contracts.validate(c.id, value);
++ const ref = majorRef(c.id, value);
++ const r = FULL_CHECK[c.id] ? FULL_CHECK[c.id](value, ref) : contracts.validate(ref, value);
ok(r.valid === (kind === 'valid'), `${c.id} ${kind}/${f}: ${r.valid ? 'passed' : JSON.stringify(r.errors)}`);
}
}
@@@ -1036,14 +1059,26 @@ sub(path.join(__dirname, 'changelog-history.test.js'));
ok(c.properties.blocks.maxItems === 60, 'at most 60 blocks');
}
--// ── actor.skill@1 and actor.skill-listing@1 (ADR-058) ───────────────────────
--// A skill is a document: its integrity hash covers its canonical content (not a signature); it runs as a prompt
--// only; it grants nothing, and what it may ask for is HO1's kinds; the listing's scan and curator travel with it.
++// ── actor.skill@1/@2 and actor.skill-listing@1/@2 (ADR-058, ADR-060) ─────────
++// A skill is a document: its integrity hash covers its canonical content (not a signature); @1 runs as a prompt
++// only; @2 may run code in a sandbox, with the code in a resource and the tools naming it. It grants nothing, and
++// what it may ask for is HO1's kinds; the listing's scan and curator travel with it, and pin the scanned code.
{
const crypto = require('crypto');
const canonical = (d) => {
const o = { skill: d.skill, slug: d.slug, name: d.name, description: d.description, version: d.version, instructions: d.instructions };
if (d.resources && d.resources.length) o.resources = d.resources.map((r) => ({ path: r.path, media_type: r.media_type, text: r.text }));
++ if (d.tools && d.tools.length) o.tools = d.tools.map((t) => {
++ const x = { name: t.name, description: t.description, language: t.language, entry: t.entry, args: t.args };
++ if (t.net !== undefined) x.net = t.net;
++ if (t.limits) {
++ const l = {};
++ if (t.limits.wall_ms !== undefined) l.wall_ms = t.limits.wall_ms;
++ if (t.limits.mem_bytes !== undefined) l.mem_bytes = t.limits.mem_bytes;
++ if (Object.keys(l).length) x.limits = l;
++ }
++ return x;
++ });
if (d.requires) {
const q = {};
for (const k of ['kinds', 'apps', 'hosts']) if (d.requires[k] && d.requires[k].length) q[k] = d.requires[k];
@@@ -1077,6 +1112,45 @@ sub(path.join(__dirname, 'changelog-history.test.js'));
ok(listing.required.includes('scan') && listing.required.includes('curator'), 'a listing always carries its scan and its curator state');
ok(JSON.stringify(listing.properties.scan.properties.state.enum) === JSON.stringify(['pending', 'passed', 'flagged', 'failed']), 'the scan states');
ok(JSON.stringify(listing.properties.curator.properties.state.enum) === JSON.stringify(['active', 'stale', 'archived']), 'the curator states');
++
++ // actor.skill@2 (ADR-060): code can run, but only in a sandbox and only the code in the document.
++ const skill2 = contracts.schema('actor.skill@2');
++ ok(JSON.stringify(skill2.properties.runs.enum) === JSON.stringify(['prompt', 'sandbox']), 'a @2 skill runs as a prompt or in a sandbox');
++ const tool = skill2.properties.tools.items;
++ ok(skill2.properties.tools.minItems === 1 && skill2.properties.tools.maxItems === 5, 'a sandbox skill carries one to five tools');
++ ok(tool.properties.language.const === 'javascript', 'v1 tools are JavaScript only');
++ ok(tool.properties.entry.pattern.endsWith('\\.js$'), 'a tool entry names a .js resource');
++ ok(JSON.stringify(tool.properties.net.enum) === JSON.stringify(['deny', 'openvibe-only', 'public']) && tool.properties.net.default === 'deny', 'a tool denies the network by default and may ask for OpenVibe only or the internet');
++ ok(tool.properties.limits.properties.wall_ms.maximum === 30000 && tool.properties.limits.properties.mem_bytes.maximum === 268435456, 'tool limits stay under the caps: 30 s and 256 MiB');
++ ok(tool.properties.limits.properties.wall_ms.default === 10000 && tool.properties.limits.properties.mem_bytes.default === 134217728, 'tool limits default to 10 s and 128 MiB');
++ const arg = skill2.$defs.argValue;
++ ok(arg.additionalProperties === false && JSON.stringify(arg.properties.type.enum) === JSON.stringify(['string', 'number', 'integer', 'boolean', 'array']), 'tool args are a JSON Schema subset, never $ref or a nested object');
++ ok(arg.properties.pattern.maxLength === 200, 'a tool arg pattern is at most 200 characters');
++ ok(JSON.stringify(skill2.properties.requires.properties.kinds.items.enum) === JSON.stringify([...HO1, 'skill.run']), 'a @2 skill may ask for skill.run beside the HO1 kinds');
++ const fields = [...Object.keys(skill2.properties), ...Object.keys(tool.properties), ...Object.keys(skill2.properties.resources.items.properties), ...Object.keys(skill2.properties.requires.properties)];
++ ok(!fields.some((k) => /^(secrets?|tokens?|env|environment|password|credential|key)$/i.test(k)), 'actor.skill@2 has no secret, token, env or key field');
++ ok(!Object.keys(skill2.properties).some((k) => /^(code|scripts?|exec|command|binar(y|ies)|install)$/i.test(k)), 'code is a resource, not a top-level field');
++ const deny = JSON.parse(fs.readFileSync(path.join(dir, 'sandbox-deny.json'), 'utf8'));
++ ok(hashOf({ ...deny, tools: [{ ...deny.tools[0], net: 'public' }] }) !== deny.integrity.hash, 'changing a tool network changes the hash');
++ ok(hashOf({ ...deny, resources: [{ ...deny.resources[0], text: `${deny.resources[0].text}\n// edited` }] }) !== deny.integrity.hash, 'changing the code changes the hash');
++ const entryIsCode = (doc) => {
++ const paths = new Map((doc.resources || []).map((x) => [x.path, x]));
++ return (doc.tools || []).every((t) => paths.get(t.entry) && paths.get(t.entry).media_type === 'text/javascript');
++ };
++ for (const f of ['prompt-only.json', 'sandbox-deny.json', 'sandbox-public.json']) {
++ const doc = JSON.parse(fs.readFileSync(path.join(dir, f), 'utf8'));
++ ok(entryIsCode(doc), `the @2 fixture ${f} names a code resource in every tool entry`);
++ }
++ ok(!entryIsCode({ ...deny, tools: [{ ...deny.tools[0], entry: 'missing.js' }] }), 'a tool entry that names no resource is not a valid skill (a schema cannot check this; the registry and these fixtures do)');
++ const listing2 = contracts.schema('actor.skill-listing@2');
++ ok(listing2.properties.skill.$ref === 'skill.v2.json', 'a @2 listing carries a @2 document');
++ ok(JSON.stringify(listing2.properties.code.items.required) === JSON.stringify(['name', 'media_id', 'sha256']), 'a listing pins each code resource by Media id and sha256');
++ ok(listing2.properties.scan.properties.findings.items.properties.tool.pattern === '^[a-z][a-z0-9_]{0,31}$', 'a scan finding may name the tool it is about');
++ const pinned = JSON.parse(fs.readFileSync(path.join(ROOT, 'fixtures', 'actor.skill-listing', 'valid', 'sandbox-public.json'), 'utf8'));
++ const code = pinned.code[0];
++ const resource = pinned.skill.resources.find((r) => r.path === code.name);
++ ok(resource && crypto.createHash('sha256').update(resource.text, 'utf8').digest('hex') === code.sha256, 'the bytes a listing pins are the bytes in the document');
++ ok(pinned.skill.tools.every((t) => pinned.code.some((c) => c.name === t.entry)), 'every tool of a sandbox listing has a code object');
}
// ── actor.voice@1: the integrity hash ─────────────────────────────────────