@smthrs/core 1.0.0-rc.6 → 1.0.0-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,7 +14,9 @@ JavaScript and TypeScript declarations and all planning callbacks must be truste
14
14
 
15
15
  For agent-generated declarations, use a constrained data-only ingestion boundary that trusted code validates and translates into nodes, or load and plan untrusted code in an externally isolated environment with restricted permissions and resources. See [Plan time](https://core.smithers.sh/concepts/plan-time/#planning-requires-trusted-declarations).
16
16
 
17
- Not on npm yet; see [Installation](https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/flow/docs/installation.md#use-the-libraries).
17
+ ```bash
18
+ npm install @smthrs/core@next effect
19
+ ```
18
20
 
19
21
  The full API reference lives at [core.smithers.sh/reference/api](https://core.smithers.sh/reference/api/).
20
22
 
@@ -123,6 +123,8 @@ export declare class MarkdownError extends MarkdownError_base {
123
123
  * the implementation for; the collaborators it names stay declarations, and no
124
124
  * flow implementation is resolved while lowering. The `smart` model seat is
125
125
  * the explicit fallback when frontmatter declares no `model`.
126
+ * Model-seat and collaborator arrays are copied, so later changes to the
127
+ * supplied frontmatter arrays do not change the lowered flow or its decorators.
126
128
  *
127
129
  * @category constructors
128
130
  * @since 0.0.0
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/Markdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/Markdown.ts"],"names":[],"mappings":"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"}
@@ -86,8 +86,8 @@ const lowerMarkdown = (frontmatter, body) => {
86
86
  tier: frontmatter.effects.tier
87
87
  })
88
88
  },
89
- model: frontmatter.model ?? "smart",
90
- flows: frontmatter.flows ?? [],
89
+ model: typeof frontmatter.model === "object" ? [...frontmatter.model] : frontmatter.model ?? "smart",
90
+ flows: [...frontmatter.flows ?? []],
91
91
  prompt: body
92
92
  });
93
93
  switch (frontmatter.placement) {
@@ -108,7 +108,12 @@ const skillNamePattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
108
108
  const isSkillName = (name) => name.length <= 64 && skillNamePattern.test(name);
109
109
  const codePoints = (value) => [...value].length;
110
110
  const isBlank = (value) => value.trim() === "";
111
- const isScalarMapping = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((member) => typeof member === "string");
111
+ const isScalarMapping = (value) => {
112
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
113
+ const prototype = Object.getPrototypeOf(value);
114
+ if (prototype !== null && prototype !== Object.prototype) return false;
115
+ return Object.values(value).every((member) => typeof member === "string");
116
+ };
112
117
  const validateSkillFrontmatter = (fields) => {
113
118
  const name = fields.name;
114
119
  if (name === void 0 || typeof name === "string" && isBlank(name)) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/Markdown.ts"],
4
- "sourcesContent": ["/**\n * Parses Agent Skills documents and lowers markdown prompts into ordinary\n * flows.\n *\n * General markdown discovery belongs to `/registry`. Agent Skills\n * frontmatter is parsed with the complete failsafe YAML schema, then checked\n * against the intrinsic rules of the Agent Skills specification\n * (https://agentskills.io/specification), before this module lowers the\n * document to the ordinary flow shape. The one rule that needs the file\n * system, that `name` equals the skill directory name, stays with the\n * registry.\n *\n * Governing contract: `packages/smithers/flows/core/docs/api.md`, published as\n * https://smithers.sh/docs/reference/api/core.\n *\n * @since 0.0.0\n */\n\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport * as Annotations from \"./Annotations.ts\"\nimport * as Effects from \"./Effects.ts\"\nimport * as Flow from \"./Flow.ts\"\nimport { build } from \"./internal/Signature.ts\"\nimport * as skillFrontmatter from \"./internal/skillFrontmatter.ts\"\nimport * as Placement from \"./Placement.ts\"\n\n/**\n * Separates leading YAML frontmatter from the markdown body without parsing it.\n * @category parsing\n * @since 1.0.0\n */\nexport { split as splitFrontmatter } from \"./internal/skillFrontmatter.ts\"\n\nconst input = Schema.Struct({ args: Schema.String })\nconst output = Schema.String\n\n/**\n * Already-parsed metadata accepted by the markdown flow loader.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface MarkdownFrontmatter {\n /**\n * The flow's name, which becomes its tag.\n *\n * It is required because the tag is what a host binds an implementation to\n * and what a plan records; a registry derives it from the frontmatter or\n * from the document's path before lowering.\n */\n readonly name: string\n readonly description?: string | undefined\n readonly model?: string | readonly [string, ...Array<string>] | undefined\n readonly flows?: ReadonlyArray<string> | undefined\n readonly capabilities?: ReadonlyArray<string> | undefined\n readonly effects?: {\n readonly reads?: ReadonlyArray<string> | undefined\n readonly writes?: ReadonlyArray<string> | undefined\n readonly mode?: Effects.Declaration[\"mode\"] | undefined\n readonly onConflict?: Effects.Declaration[\"onConflict\"] | undefined\n readonly tier?: Effects.Declaration[\"tier\"]\n } | undefined\n readonly placement?: \"sandbox\" | \"remote\" | \"client\" | \"local\" | undefined\n}\n\n/**\n * Agent Skills frontmatter that passed {@link validateSkillFrontmatter}.\n *\n * `allowedTools` is the specification's space-separated `allowed-tools`\n * scalar, split into tool names. `extra` holds every other field, including\n * the validated optional `license`, `compatibility`, and `metadata`, as a\n * frozen null-prototype record.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface SkillFrontmatter {\n readonly name: string\n readonly description: string\n readonly allowedTools: ReadonlyArray<string>\n readonly extra: Record<string, unknown>\n}\n\n/**\n * Parsed Agent Skills document.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface SkillDocument extends SkillFrontmatter {\n readonly body: string\n}\n\n/**\n * Stable code emitted by markdown loader failures.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport const MarkdownErrorCode = Schema.Literals([\n \"skill_missing_frontmatter\",\n \"skill_invalid_frontmatter\",\n \"skill_missing_name\",\n \"skill_invalid_name\",\n \"skill_missing_description\",\n \"skill_invalid_description\",\n \"skill_invalid_allowed_tools\",\n \"skill_invalid_compatibility\",\n \"skill_invalid_metadata\",\n \"skill_invalid_license\"\n])\n\n/**\n * Stable code emitted by markdown loader failures.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport type MarkdownErrorCode = typeof MarkdownErrorCode.Type\n\n/**\n * A typed markdown loader failure.\n *\n * @category errors\n * @since 0.0.0\n * @slop\n */\nexport class MarkdownError extends Schema.TaggedError<MarkdownError>()(\"flows/core/MarkdownError\", {\n code: MarkdownErrorCode,\n message: Schema.String\n}) {}\n\n/**\n * Lowers parsed markdown metadata and a markdown body to an ordinary flow.\n *\n * The prompt is the markdown body. Harnesses append non-empty runtime `args`\n * when rendering that prompt, preserving the markdown-flow calling convention.\n * The lowered flow declares no body, so it carries the action a host supplies\n * the implementation for; the collaborators it names stay declarations, and no\n * flow implementation is resolved while lowering. The `smart` model seat is\n * the explicit fallback when frontmatter declares no `model`.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const lowerMarkdown = (\n frontmatter: MarkdownFrontmatter,\n body: string\n): Flow.Flow<typeof input, typeof output> => {\n const flow = build({\n error: Schema.Never,\n annotations: Annotations.empty,\n body: undefined,\n name: frontmatter.name,\n description: frontmatter.description,\n input,\n output,\n capabilities: [...new Set(frontmatter.capabilities ?? [])].sort(),\n effects: undefined,\n ...(frontmatter.effects === undefined\n ? {}\n : {\n effects: Effects.make({\n reads: frontmatter.effects.reads ?? [],\n writes: frontmatter.effects.writes ?? [],\n mode: frontmatter.effects.mode ?? \"hermetic\",\n onConflict: frontmatter.effects.onConflict ?? \"serialize\",\n tier: frontmatter.effects.tier\n })\n }),\n model: frontmatter.model ?? \"smart\",\n flows: frontmatter.flows ?? [],\n prompt: body\n })\n\n switch (frontmatter.placement) {\n case \"sandbox\":\n return Flow.within(flow, Placement.sandbox())\n case \"remote\":\n return Flow.within(flow, Placement.remote())\n case \"client\":\n return Flow.within(flow, Placement.client())\n case \"local\":\n return Flow.within(flow, Placement.local())\n default:\n return flow\n }\n}\n\nconst fail = (code: MarkdownErrorCode, message: string): Result.Result<never, MarkdownError> =>\n Result.fail(new MarkdownError({ code, message }))\n\n// The specification's name grammar: lowercase ASCII letters and digits joined\n// by single hyphens, so a leading, trailing, or doubled hyphen fails here.\nconst skillNamePattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\n\n/**\n * Whether `name` is a valid Agent Skills name: 1 to 64 lowercase ASCII\n * letters, digits, or single hyphens, not starting or ending with a hyphen.\n *\n * {@link validateSkillFrontmatter} applies this rule, and `@smthrs/registry`\n * reads the same predicate when it warns about a discovered skill's name, so\n * the rule has one definition.\n *\n * @category validation\n * @since 1.0.0-rc.1\n */\nexport const isSkillName = (name: string): boolean => name.length <= 64 && skillNamePattern.test(name)\n\n// The specification measures a field in characters. Counting UTF-16 units\n// would reject a 600-emoji description the specification accepts, so the\n// count walks code points.\nconst codePoints = (value: string): number => [...value].length\n\nconst isBlank = (value: string): boolean => value.trim() === \"\"\n\nconst isScalarMapping = (value: unknown): boolean =>\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.values(value).every((member) => typeof member === \"string\")\n\n/**\n * Checks already-parsed Agent Skills frontmatter against the specification's\n * intrinsic rules and lowers the fields this package reads.\n *\n * `name` is 1 to 64 lowercase ASCII letters, digits, or single hyphens and\n * cannot start or end with a hyphen. `description` is 1 to 1024 characters.\n * `allowed-tools`, when present, is one space-separated scalar. `license` is\n * a scalar, `compatibility` is 1 to 500 characters, and `metadata` maps\n * string keys to scalar values. A field that is absent reports a `missing`\n * code; a field that is present but malformed reports its own `invalid` code\n * without echoing the offending value. The registry keeps the one rule that\n * needs the file system: `name` must equal the skill directory name.\n *\n * @category validation\n * @since 1.0.0-rc.0\n */\nexport const validateSkillFrontmatter = (\n fields: Record<string, unknown>\n): Result.Result<SkillFrontmatter, MarkdownError> => {\n const name = fields.name\n if (name === undefined || (typeof name === \"string\" && isBlank(name))) {\n return fail(\"skill_missing_name\", \"SKILL.md requires a non-empty frontmatter name\")\n }\n if (typeof name !== \"string\" || !isSkillName(name)) {\n return fail(\n \"skill_invalid_name\",\n \"SKILL.md name must be 1 to 64 lowercase ASCII letters, digits, or single hyphens, and cannot start or end with a hyphen\"\n )\n }\n\n const description = fields.description\n if (description === undefined || (typeof description === \"string\" && isBlank(description))) {\n return fail(\"skill_missing_description\", \"SKILL.md requires a non-empty frontmatter description\")\n }\n if (typeof description !== \"string\" || codePoints(description) > 1024) {\n return fail(\"skill_invalid_description\", \"SKILL.md description must be a scalar of 1 to 1024 characters\")\n }\n\n const allowedToolsValue = fields[\"allowed-tools\"]\n if (allowedToolsValue !== undefined && typeof allowedToolsValue !== \"string\") {\n return fail(\"skill_invalid_allowed_tools\", \"SKILL.md allowed-tools must be a space-separated scalar\")\n }\n const allowedTools = allowedToolsValue === undefined\n ? []\n : allowedToolsValue.split(/\\s+/).filter((tool) => tool.length > 0)\n\n const license = fields.license\n if (license !== undefined && typeof license !== \"string\") {\n return fail(\"skill_invalid_license\", \"SKILL.md license must be a scalar\")\n }\n\n const compatibility = fields.compatibility\n if (\n compatibility !== undefined &&\n (typeof compatibility !== \"string\" || codePoints(compatibility) < 1 || codePoints(compatibility) > 500)\n ) {\n return fail(\"skill_invalid_compatibility\", \"SKILL.md compatibility must be a scalar of 1 to 500 characters\")\n }\n\n const metadata = fields.metadata\n if (metadata !== undefined && !isScalarMapping(metadata)) {\n return fail(\"skill_invalid_metadata\", \"SKILL.md metadata must be a mapping from string keys to scalar values\")\n }\n\n const extra = Object.create(null) as Record<string, unknown>\n for (const [key, value] of Object.entries(fields)) {\n if (key !== \"name\" && key !== \"description\" && key !== \"allowed-tools\") {\n Object.defineProperty(extra, key, {\n value,\n enumerable: true,\n writable: false,\n configurable: false\n })\n }\n }\n Object.freeze(extra)\n\n return Result.succeed({ name, description, allowedTools, extra })\n}\n\n/**\n * Parses an Agent Skills document with failsafe-schema YAML semantics and\n * validates its frontmatter with {@link validateSkillFrontmatter}.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const parseSkill = (text: string): Result.Result<SkillDocument, MarkdownError> => {\n const split = skillFrontmatter.split(text)\n if (split.frontmatter === undefined) {\n return fail(\"skill_missing_frontmatter\", \"SKILL.md requires leading frontmatter\")\n }\n\n const parsed = skillFrontmatter.parse(split.frontmatter)\n if (Result.isFailure(parsed)) {\n return fail(\"skill_invalid_frontmatter\", parsed.failure)\n }\n\n return Result.map(validateSkillFrontmatter(parsed.success), (frontmatter) => ({\n ...frontmatter,\n body: split.body\n }))\n}\n\n/**\n * Parses and lowers an Agent Skills document to an ordinary flow.\n *\n * Only `name`, `description`, and `allowed-tools` are lowered. Every other\n * frontmatter field remains in {@link parseSkill}'s `extra` record for the\n * caller to interpret. Agent Skills frontmatter is untyped failsafe YAML;\n * coercing extra fields such as `model` or `placement` here would duplicate\n * the flow-level frontmatter typing owned by `@smthrs/registry`.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const lowerSkill = (\n text: string\n): Result.Result<Flow.Flow<typeof input, typeof output>, MarkdownError> =>\n Result.map(parseSkill(text), (skill) =>\n lowerMarkdown({\n name: skill.name,\n description: skill.description,\n flows: skill.allowedTools\n }, skill.body))\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Parses Agent Skills documents and lowers markdown prompts into ordinary\n * flows.\n *\n * General markdown discovery belongs to `/registry`. Agent Skills\n * frontmatter is parsed with the complete failsafe YAML schema, then checked\n * against the intrinsic rules of the Agent Skills specification\n * (https://agentskills.io/specification), before this module lowers the\n * document to the ordinary flow shape. The one rule that needs the file\n * system, that `name` equals the skill directory name, stays with the\n * registry.\n *\n * Governing contract: `packages/smithers/flows/core/docs/api.md`, published as\n * https://smithers.sh/docs/reference/api/core.\n *\n * @since 0.0.0\n */\n\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport * as Annotations from \"./Annotations.ts\"\nimport * as Effects from \"./Effects.ts\"\nimport * as Flow from \"./Flow.ts\"\nimport { build } from \"./internal/Signature.ts\"\nimport * as skillFrontmatter from \"./internal/skillFrontmatter.ts\"\nimport * as Placement from \"./Placement.ts\"\n\n/**\n * Separates leading YAML frontmatter from the markdown body without parsing it.\n * @category parsing\n * @since 1.0.0\n */\nexport { split as splitFrontmatter } from \"./internal/skillFrontmatter.ts\"\n\nconst input = Schema.Struct({ args: Schema.String })\nconst output = Schema.String\n\n/**\n * Already-parsed metadata accepted by the markdown flow loader.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface MarkdownFrontmatter {\n /**\n * The flow's name, which becomes its tag.\n *\n * It is required because the tag is what a host binds an implementation to\n * and what a plan records; a registry derives it from the frontmatter or\n * from the document's path before lowering.\n */\n readonly name: string\n readonly description?: string | undefined\n readonly model?: string | readonly [string, ...Array<string>] | undefined\n readonly flows?: ReadonlyArray<string> | undefined\n readonly capabilities?: ReadonlyArray<string> | undefined\n readonly effects?: {\n readonly reads?: ReadonlyArray<string> | undefined\n readonly writes?: ReadonlyArray<string> | undefined\n readonly mode?: Effects.Declaration[\"mode\"] | undefined\n readonly onConflict?: Effects.Declaration[\"onConflict\"] | undefined\n readonly tier?: Effects.Declaration[\"tier\"]\n } | undefined\n readonly placement?: \"sandbox\" | \"remote\" | \"client\" | \"local\" | undefined\n}\n\n/**\n * Agent Skills frontmatter that passed {@link validateSkillFrontmatter}.\n *\n * `allowedTools` is the specification's space-separated `allowed-tools`\n * scalar, split into tool names. `extra` holds every other field, including\n * the validated optional `license`, `compatibility`, and `metadata`, as a\n * frozen null-prototype record.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface SkillFrontmatter {\n readonly name: string\n readonly description: string\n readonly allowedTools: ReadonlyArray<string>\n readonly extra: Record<string, unknown>\n}\n\n/**\n * Parsed Agent Skills document.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface SkillDocument extends SkillFrontmatter {\n readonly body: string\n}\n\n/**\n * Stable code emitted by markdown loader failures.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport const MarkdownErrorCode = Schema.Literals([\n \"skill_missing_frontmatter\",\n \"skill_invalid_frontmatter\",\n \"skill_missing_name\",\n \"skill_invalid_name\",\n \"skill_missing_description\",\n \"skill_invalid_description\",\n \"skill_invalid_allowed_tools\",\n \"skill_invalid_compatibility\",\n \"skill_invalid_metadata\",\n \"skill_invalid_license\"\n])\n\n/**\n * Stable code emitted by markdown loader failures.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport type MarkdownErrorCode = typeof MarkdownErrorCode.Type\n\n/**\n * A typed markdown loader failure.\n *\n * @category errors\n * @since 0.0.0\n * @slop\n */\nexport class MarkdownError extends Schema.TaggedError<MarkdownError>()(\"flows/core/MarkdownError\", {\n code: MarkdownErrorCode,\n message: Schema.String\n}) {}\n\n/**\n * Lowers parsed markdown metadata and a markdown body to an ordinary flow.\n *\n * The prompt is the markdown body. Harnesses append non-empty runtime `args`\n * when rendering that prompt, preserving the markdown-flow calling convention.\n * The lowered flow declares no body, so it carries the action a host supplies\n * the implementation for; the collaborators it names stay declarations, and no\n * flow implementation is resolved while lowering. The `smart` model seat is\n * the explicit fallback when frontmatter declares no `model`.\n * Model-seat and collaborator arrays are copied, so later changes to the\n * supplied frontmatter arrays do not change the lowered flow or its decorators.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const lowerMarkdown = (\n frontmatter: MarkdownFrontmatter,\n body: string\n): Flow.Flow<typeof input, typeof output> => {\n const flow = build({\n error: Schema.Never,\n annotations: Annotations.empty,\n body: undefined,\n name: frontmatter.name,\n description: frontmatter.description,\n input,\n output,\n capabilities: [...new Set(frontmatter.capabilities ?? [])].sort(),\n effects: undefined,\n ...(frontmatter.effects === undefined\n ? {}\n : {\n effects: Effects.make({\n reads: frontmatter.effects.reads ?? [],\n writes: frontmatter.effects.writes ?? [],\n mode: frontmatter.effects.mode ?? \"hermetic\",\n onConflict: frontmatter.effects.onConflict ?? \"serialize\",\n tier: frontmatter.effects.tier\n })\n }),\n model: typeof frontmatter.model === \"object\" ? [...frontmatter.model] : frontmatter.model ?? \"smart\",\n flows: [...frontmatter.flows ?? []],\n prompt: body\n })\n\n switch (frontmatter.placement) {\n case \"sandbox\":\n return Flow.within(flow, Placement.sandbox())\n case \"remote\":\n return Flow.within(flow, Placement.remote())\n case \"client\":\n return Flow.within(flow, Placement.client())\n case \"local\":\n return Flow.within(flow, Placement.local())\n default:\n return flow\n }\n}\n\nconst fail = (code: MarkdownErrorCode, message: string): Result.Result<never, MarkdownError> =>\n Result.fail(new MarkdownError({ code, message }))\n\n// The specification's name grammar: lowercase ASCII letters and digits joined\n// by single hyphens, so a leading, trailing, or doubled hyphen fails here.\nconst skillNamePattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\n\n/**\n * Whether `name` is a valid Agent Skills name: 1 to 64 lowercase ASCII\n * letters, digits, or single hyphens, not starting or ending with a hyphen.\n *\n * {@link validateSkillFrontmatter} applies this rule, and `@smthrs/registry`\n * reads the same predicate when it warns about a discovered skill's name, so\n * the rule has one definition.\n *\n * @category validation\n * @since 1.0.0-rc.1\n */\nexport const isSkillName = (name: string): boolean => name.length <= 64 && skillNamePattern.test(name)\n\n// The specification measures a field in characters. Counting UTF-16 units\n// would reject a 600-emoji description the specification accepts, so the\n// count walks code points.\nconst codePoints = (value: string): number => [...value].length\n\nconst isBlank = (value: string): boolean => value.trim() === \"\"\n\nconst isScalarMapping = (value: unknown): boolean => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false\n const prototype = Object.getPrototypeOf(value)\n if (prototype !== null && prototype !== Object.prototype) return false\n return Object.values(value).every((member) => typeof member === \"string\")\n}\n\n/**\n * Checks already-parsed Agent Skills frontmatter against the specification's\n * intrinsic rules and lowers the fields this package reads.\n *\n * `name` is 1 to 64 lowercase ASCII letters, digits, or single hyphens and\n * cannot start or end with a hyphen. `description` is 1 to 1024 characters.\n * `allowed-tools`, when present, is one space-separated scalar. `license` is\n * a scalar, `compatibility` is 1 to 500 characters, and `metadata` maps\n * string keys to scalar values. A field that is absent reports a `missing`\n * code; a field that is present but malformed reports its own `invalid` code\n * without echoing the offending value. The registry keeps the one rule that\n * needs the file system: `name` must equal the skill directory name.\n *\n * @category validation\n * @since 1.0.0-rc.0\n */\nexport const validateSkillFrontmatter = (\n fields: Record<string, unknown>\n): Result.Result<SkillFrontmatter, MarkdownError> => {\n const name = fields.name\n if (name === undefined || (typeof name === \"string\" && isBlank(name))) {\n return fail(\"skill_missing_name\", \"SKILL.md requires a non-empty frontmatter name\")\n }\n if (typeof name !== \"string\" || !isSkillName(name)) {\n return fail(\n \"skill_invalid_name\",\n \"SKILL.md name must be 1 to 64 lowercase ASCII letters, digits, or single hyphens, and cannot start or end with a hyphen\"\n )\n }\n\n const description = fields.description\n if (description === undefined || (typeof description === \"string\" && isBlank(description))) {\n return fail(\"skill_missing_description\", \"SKILL.md requires a non-empty frontmatter description\")\n }\n if (typeof description !== \"string\" || codePoints(description) > 1024) {\n return fail(\"skill_invalid_description\", \"SKILL.md description must be a scalar of 1 to 1024 characters\")\n }\n\n const allowedToolsValue = fields[\"allowed-tools\"]\n if (allowedToolsValue !== undefined && typeof allowedToolsValue !== \"string\") {\n return fail(\"skill_invalid_allowed_tools\", \"SKILL.md allowed-tools must be a space-separated scalar\")\n }\n const allowedTools = allowedToolsValue === undefined\n ? []\n : allowedToolsValue.split(/\\s+/).filter((tool) => tool.length > 0)\n\n const license = fields.license\n if (license !== undefined && typeof license !== \"string\") {\n return fail(\"skill_invalid_license\", \"SKILL.md license must be a scalar\")\n }\n\n const compatibility = fields.compatibility\n if (\n compatibility !== undefined &&\n (typeof compatibility !== \"string\" || codePoints(compatibility) < 1 || codePoints(compatibility) > 500)\n ) {\n return fail(\"skill_invalid_compatibility\", \"SKILL.md compatibility must be a scalar of 1 to 500 characters\")\n }\n\n const metadata = fields.metadata\n if (metadata !== undefined && !isScalarMapping(metadata)) {\n return fail(\"skill_invalid_metadata\", \"SKILL.md metadata must be a mapping from string keys to scalar values\")\n }\n\n const extra = Object.create(null) as Record<string, unknown>\n for (const [key, value] of Object.entries(fields)) {\n if (key !== \"name\" && key !== \"description\" && key !== \"allowed-tools\") {\n Object.defineProperty(extra, key, {\n value,\n enumerable: true,\n writable: false,\n configurable: false\n })\n }\n }\n Object.freeze(extra)\n\n return Result.succeed({ name, description, allowedTools, extra })\n}\n\n/**\n * Parses an Agent Skills document with failsafe-schema YAML semantics and\n * validates its frontmatter with {@link validateSkillFrontmatter}.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const parseSkill = (text: string): Result.Result<SkillDocument, MarkdownError> => {\n const split = skillFrontmatter.split(text)\n if (split.frontmatter === undefined) {\n return fail(\"skill_missing_frontmatter\", \"SKILL.md requires leading frontmatter\")\n }\n\n const parsed = skillFrontmatter.parse(split.frontmatter)\n if (Result.isFailure(parsed)) {\n return fail(\"skill_invalid_frontmatter\", parsed.failure)\n }\n\n return Result.map(validateSkillFrontmatter(parsed.success), (frontmatter) => ({\n ...frontmatter,\n body: split.body\n }))\n}\n\n/**\n * Parses and lowers an Agent Skills document to an ordinary flow.\n *\n * Only `name`, `description`, and `allowed-tools` are lowered. Every other\n * frontmatter field remains in {@link parseSkill}'s `extra` record for the\n * caller to interpret. Agent Skills frontmatter is untyped failsafe YAML;\n * coercing extra fields such as `model` or `placement` here would duplicate\n * the flow-level frontmatter typing owned by `@smthrs/registry`.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const lowerSkill = (\n text: string\n): Result.Result<Flow.Flow<typeof input, typeof output>, MarkdownError> =>\n Result.map(parseSkill(text), (skill) =>\n lowerMarkdown({\n name: skill.name,\n description: skill.description,\n flows: skill.allowedTools\n }, skill.body))\n"],
5
+ "mappings": "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",
6
6
  "names": ["split"]
7
7
  }
@@ -123,6 +123,8 @@ export declare class MarkdownError extends MarkdownError_base {
123
123
  * the implementation for; the collaborators it names stay declarations, and no
124
124
  * flow implementation is resolved while lowering. The `smart` model seat is
125
125
  * the explicit fallback when frontmatter declares no `model`.
126
+ * Model-seat and collaborator arrays are copied, so later changes to the
127
+ * supplied frontmatter arrays do not change the lowered flow or its decorators.
126
128
  *
127
129
  * @category constructors
128
130
  * @since 0.0.0
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/Markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAKjC;;;;GAIG;AACH,OAAO,EAAE,KAAK,IAAI,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AAE1E,QAAA,MAAM,KAAK;;EAAyC,CAAA;AACpD,QAAA,MAAM,MAAM,eAAgB,CAAA;AAE5B;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;IAClD,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE;QACjB,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;QAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;QACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;QACvD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,GAAG,SAAS,CAAA;QACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;KAC5C,GAAG,SAAS,CAAA;IACb,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;CAC3E;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACxC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,6SAW5B,CAAA;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAA;;;;;AAE7D;;;;;;GAMG;AACH,qBAAa,aAAc,SAAQ,kBAGjC;CAAG;AAEL;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,GACxB,aAAa,mBAAmB,EAChC,MAAM,MAAM,KACX,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,EAAE,OAAO,MAAM,CAuCvC,CAAA;AASD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,OAA2D,CAAA;AAetG;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,wBAAwB,GACnC,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC9B,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,aAAa,CA4D/C,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,CAenF,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,MAAM,KACX,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,EAAE,OAAO,MAAM,CAAC,EAAE,aAAa,CAMnD,CAAA"}
1
+ {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/Markdown.ts"],"names":[],"mappings":"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"}
@@ -71,6 +71,8 @@ export class MarkdownError extends Schema.TaggedError()("flows/core/MarkdownErro
71
71
  * the implementation for; the collaborators it names stay declarations, and no
72
72
  * flow implementation is resolved while lowering. The `smart` model seat is
73
73
  * the explicit fallback when frontmatter declares no `model`.
74
+ * Model-seat and collaborator arrays are copied, so later changes to the
75
+ * supplied frontmatter arrays do not change the lowered flow or its decorators.
74
76
  *
75
77
  * @category constructors
76
78
  * @since 0.0.0
@@ -98,8 +100,8 @@ export const lowerMarkdown = (frontmatter, body) => {
98
100
  tier: frontmatter.effects.tier
99
101
  })
100
102
  }),
101
- model: frontmatter.model ?? "smart",
102
- flows: frontmatter.flows ?? [],
103
+ model: typeof frontmatter.model === "object" ? [...frontmatter.model] : frontmatter.model ?? "smart",
104
+ flows: [...frontmatter.flows ?? []],
103
105
  prompt: body
104
106
  });
105
107
  switch (frontmatter.placement) {
@@ -136,10 +138,14 @@ export const isSkillName = (name) => name.length <= 64 && skillNamePattern.test(
136
138
  // count walks code points.
137
139
  const codePoints = (value) => [...value].length;
138
140
  const isBlank = (value) => value.trim() === "";
139
- const isScalarMapping = (value) => typeof value === "object" &&
140
- value !== null &&
141
- !Array.isArray(value) &&
142
- Object.values(value).every((member) => typeof member === "string");
141
+ const isScalarMapping = (value) => {
142
+ if (typeof value !== "object" || value === null || Array.isArray(value))
143
+ return false;
144
+ const prototype = Object.getPrototypeOf(value);
145
+ if (prototype !== null && prototype !== Object.prototype)
146
+ return false;
147
+ return Object.values(value).every((member) => typeof member === "string");
148
+ };
143
149
  /**
144
150
  * Checks already-parsed Agent Skills frontmatter against the specification's
145
151
  * intrinsic rules and lowers the fields this package reads.
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.js","sourceRoot":"","sources":["../../src/Markdown.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Parses Agent Skills documents and lowers markdown prompts into ordinary\n * flows.\n *\n * General markdown discovery belongs to `/registry`. Agent Skills\n * frontmatter is parsed with the complete failsafe YAML schema, then checked\n * against the intrinsic rules of the Agent Skills specification\n * (https://agentskills.io/specification), before this module lowers the\n * document to the ordinary flow shape. The one rule that needs the file\n * system, that `name` equals the skill directory name, stays with the\n * registry.\n *\n * Governing contract: `packages/smithers/flows/core/docs/api.md`, published as\n * https://smithers.sh/docs/reference/api/core.\n *\n * @since 0.0.0\n */\n\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport * as Annotations from \"./Annotations.ts\"\nimport * as Effects from \"./Effects.ts\"\nimport * as Flow from \"./Flow.ts\"\nimport { build } from \"./internal/Signature.ts\"\nimport * as skillFrontmatter from \"./internal/skillFrontmatter.ts\"\nimport * as Placement from \"./Placement.ts\"\n\n/**\n * Separates leading YAML frontmatter from the markdown body without parsing it.\n * @category parsing\n * @since 1.0.0\n */\nexport { split as splitFrontmatter } from \"./internal/skillFrontmatter.ts\"\n\nconst input = Schema.Struct({ args: Schema.String })\nconst output = Schema.String\n\n/**\n * Already-parsed metadata accepted by the markdown flow loader.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface MarkdownFrontmatter {\n /**\n * The flow's name, which becomes its tag.\n *\n * It is required because the tag is what a host binds an implementation to\n * and what a plan records; a registry derives it from the frontmatter or\n * from the document's path before lowering.\n */\n readonly name: string\n readonly description?: string | undefined\n readonly model?: string | readonly [string, ...Array<string>] | undefined\n readonly flows?: ReadonlyArray<string> | undefined\n readonly capabilities?: ReadonlyArray<string> | undefined\n readonly effects?: {\n readonly reads?: ReadonlyArray<string> | undefined\n readonly writes?: ReadonlyArray<string> | undefined\n readonly mode?: Effects.Declaration[\"mode\"] | undefined\n readonly onConflict?: Effects.Declaration[\"onConflict\"] | undefined\n readonly tier?: Effects.Declaration[\"tier\"]\n } | undefined\n readonly placement?: \"sandbox\" | \"remote\" | \"client\" | \"local\" | undefined\n}\n\n/**\n * Agent Skills frontmatter that passed {@link validateSkillFrontmatter}.\n *\n * `allowedTools` is the specification's space-separated `allowed-tools`\n * scalar, split into tool names. `extra` holds every other field, including\n * the validated optional `license`, `compatibility`, and `metadata`, as a\n * frozen null-prototype record.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface SkillFrontmatter {\n readonly name: string\n readonly description: string\n readonly allowedTools: ReadonlyArray<string>\n readonly extra: Record<string, unknown>\n}\n\n/**\n * Parsed Agent Skills document.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface SkillDocument extends SkillFrontmatter {\n readonly body: string\n}\n\n/**\n * Stable code emitted by markdown loader failures.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport const MarkdownErrorCode = Schema.Literals([\n \"skill_missing_frontmatter\",\n \"skill_invalid_frontmatter\",\n \"skill_missing_name\",\n \"skill_invalid_name\",\n \"skill_missing_description\",\n \"skill_invalid_description\",\n \"skill_invalid_allowed_tools\",\n \"skill_invalid_compatibility\",\n \"skill_invalid_metadata\",\n \"skill_invalid_license\"\n])\n\n/**\n * Stable code emitted by markdown loader failures.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport type MarkdownErrorCode = typeof MarkdownErrorCode.Type\n\n/**\n * A typed markdown loader failure.\n *\n * @category errors\n * @since 0.0.0\n * @slop\n */\nexport class MarkdownError extends Schema.TaggedError<MarkdownError>()(\"flows/core/MarkdownError\", {\n code: MarkdownErrorCode,\n message: Schema.String\n}) {}\n\n/**\n * Lowers parsed markdown metadata and a markdown body to an ordinary flow.\n *\n * The prompt is the markdown body. Harnesses append non-empty runtime `args`\n * when rendering that prompt, preserving the markdown-flow calling convention.\n * The lowered flow declares no body, so it carries the action a host supplies\n * the implementation for; the collaborators it names stay declarations, and no\n * flow implementation is resolved while lowering. The `smart` model seat is\n * the explicit fallback when frontmatter declares no `model`.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const lowerMarkdown = (\n frontmatter: MarkdownFrontmatter,\n body: string\n): Flow.Flow<typeof input, typeof output> => {\n const flow = build({\n error: Schema.Never,\n annotations: Annotations.empty,\n body: undefined,\n name: frontmatter.name,\n description: frontmatter.description,\n input,\n output,\n capabilities: [...new Set(frontmatter.capabilities ?? [])].sort(),\n effects: undefined,\n ...(frontmatter.effects === undefined\n ? {}\n : {\n effects: Effects.make({\n reads: frontmatter.effects.reads ?? [],\n writes: frontmatter.effects.writes ?? [],\n mode: frontmatter.effects.mode ?? \"hermetic\",\n onConflict: frontmatter.effects.onConflict ?? \"serialize\",\n tier: frontmatter.effects.tier\n })\n }),\n model: frontmatter.model ?? \"smart\",\n flows: frontmatter.flows ?? [],\n prompt: body\n })\n\n switch (frontmatter.placement) {\n case \"sandbox\":\n return Flow.within(flow, Placement.sandbox())\n case \"remote\":\n return Flow.within(flow, Placement.remote())\n case \"client\":\n return Flow.within(flow, Placement.client())\n case \"local\":\n return Flow.within(flow, Placement.local())\n default:\n return flow\n }\n}\n\nconst fail = (code: MarkdownErrorCode, message: string): Result.Result<never, MarkdownError> =>\n Result.fail(new MarkdownError({ code, message }))\n\n// The specification's name grammar: lowercase ASCII letters and digits joined\n// by single hyphens, so a leading, trailing, or doubled hyphen fails here.\nconst skillNamePattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\n\n/**\n * Whether `name` is a valid Agent Skills name: 1 to 64 lowercase ASCII\n * letters, digits, or single hyphens, not starting or ending with a hyphen.\n *\n * {@link validateSkillFrontmatter} applies this rule, and `@smthrs/registry`\n * reads the same predicate when it warns about a discovered skill's name, so\n * the rule has one definition.\n *\n * @category validation\n * @since 1.0.0-rc.1\n */\nexport const isSkillName = (name: string): boolean => name.length <= 64 && skillNamePattern.test(name)\n\n// The specification measures a field in characters. Counting UTF-16 units\n// would reject a 600-emoji description the specification accepts, so the\n// count walks code points.\nconst codePoints = (value: string): number => [...value].length\n\nconst isBlank = (value: string): boolean => value.trim() === \"\"\n\nconst isScalarMapping = (value: unknown): boolean =>\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.values(value).every((member) => typeof member === \"string\")\n\n/**\n * Checks already-parsed Agent Skills frontmatter against the specification's\n * intrinsic rules and lowers the fields this package reads.\n *\n * `name` is 1 to 64 lowercase ASCII letters, digits, or single hyphens and\n * cannot start or end with a hyphen. `description` is 1 to 1024 characters.\n * `allowed-tools`, when present, is one space-separated scalar. `license` is\n * a scalar, `compatibility` is 1 to 500 characters, and `metadata` maps\n * string keys to scalar values. A field that is absent reports a `missing`\n * code; a field that is present but malformed reports its own `invalid` code\n * without echoing the offending value. The registry keeps the one rule that\n * needs the file system: `name` must equal the skill directory name.\n *\n * @category validation\n * @since 1.0.0-rc.0\n */\nexport const validateSkillFrontmatter = (\n fields: Record<string, unknown>\n): Result.Result<SkillFrontmatter, MarkdownError> => {\n const name = fields.name\n if (name === undefined || (typeof name === \"string\" && isBlank(name))) {\n return fail(\"skill_missing_name\", \"SKILL.md requires a non-empty frontmatter name\")\n }\n if (typeof name !== \"string\" || !isSkillName(name)) {\n return fail(\n \"skill_invalid_name\",\n \"SKILL.md name must be 1 to 64 lowercase ASCII letters, digits, or single hyphens, and cannot start or end with a hyphen\"\n )\n }\n\n const description = fields.description\n if (description === undefined || (typeof description === \"string\" && isBlank(description))) {\n return fail(\"skill_missing_description\", \"SKILL.md requires a non-empty frontmatter description\")\n }\n if (typeof description !== \"string\" || codePoints(description) > 1024) {\n return fail(\"skill_invalid_description\", \"SKILL.md description must be a scalar of 1 to 1024 characters\")\n }\n\n const allowedToolsValue = fields[\"allowed-tools\"]\n if (allowedToolsValue !== undefined && typeof allowedToolsValue !== \"string\") {\n return fail(\"skill_invalid_allowed_tools\", \"SKILL.md allowed-tools must be a space-separated scalar\")\n }\n const allowedTools = allowedToolsValue === undefined\n ? []\n : allowedToolsValue.split(/\\s+/).filter((tool) => tool.length > 0)\n\n const license = fields.license\n if (license !== undefined && typeof license !== \"string\") {\n return fail(\"skill_invalid_license\", \"SKILL.md license must be a scalar\")\n }\n\n const compatibility = fields.compatibility\n if (\n compatibility !== undefined &&\n (typeof compatibility !== \"string\" || codePoints(compatibility) < 1 || codePoints(compatibility) > 500)\n ) {\n return fail(\"skill_invalid_compatibility\", \"SKILL.md compatibility must be a scalar of 1 to 500 characters\")\n }\n\n const metadata = fields.metadata\n if (metadata !== undefined && !isScalarMapping(metadata)) {\n return fail(\"skill_invalid_metadata\", \"SKILL.md metadata must be a mapping from string keys to scalar values\")\n }\n\n const extra = Object.create(null) as Record<string, unknown>\n for (const [key, value] of Object.entries(fields)) {\n if (key !== \"name\" && key !== \"description\" && key !== \"allowed-tools\") {\n Object.defineProperty(extra, key, {\n value,\n enumerable: true,\n writable: false,\n configurable: false\n })\n }\n }\n Object.freeze(extra)\n\n return Result.succeed({ name, description, allowedTools, extra })\n}\n\n/**\n * Parses an Agent Skills document with failsafe-schema YAML semantics and\n * validates its frontmatter with {@link validateSkillFrontmatter}.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const parseSkill = (text: string): Result.Result<SkillDocument, MarkdownError> => {\n const split = skillFrontmatter.split(text)\n if (split.frontmatter === undefined) {\n return fail(\"skill_missing_frontmatter\", \"SKILL.md requires leading frontmatter\")\n }\n\n const parsed = skillFrontmatter.parse(split.frontmatter)\n if (Result.isFailure(parsed)) {\n return fail(\"skill_invalid_frontmatter\", parsed.failure)\n }\n\n return Result.map(validateSkillFrontmatter(parsed.success), (frontmatter) => ({\n ...frontmatter,\n body: split.body\n }))\n}\n\n/**\n * Parses and lowers an Agent Skills document to an ordinary flow.\n *\n * Only `name`, `description`, and `allowed-tools` are lowered. Every other\n * frontmatter field remains in {@link parseSkill}'s `extra` record for the\n * caller to interpret. Agent Skills frontmatter is untyped failsafe YAML;\n * coercing extra fields such as `model` or `placement` here would duplicate\n * the flow-level frontmatter typing owned by `@smthrs/registry`.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const lowerSkill = (\n text: string\n): Result.Result<Flow.Flow<typeof input, typeof output>, MarkdownError> =>\n Result.map(parseSkill(text), (skill) =>\n lowerMarkdown({\n name: skill.name,\n description: skill.description,\n flows: skill.allowedTools\n }, skill.body))\n"]}
1
+ {"version":3,"file":"Markdown.js","sourceRoot":"","sources":["../../src/Markdown.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Parses Agent Skills documents and lowers markdown prompts into ordinary\n * flows.\n *\n * General markdown discovery belongs to `/registry`. Agent Skills\n * frontmatter is parsed with the complete failsafe YAML schema, then checked\n * against the intrinsic rules of the Agent Skills specification\n * (https://agentskills.io/specification), before this module lowers the\n * document to the ordinary flow shape. The one rule that needs the file\n * system, that `name` equals the skill directory name, stays with the\n * registry.\n *\n * Governing contract: `packages/smithers/flows/core/docs/api.md`, published as\n * https://smithers.sh/docs/reference/api/core.\n *\n * @since 0.0.0\n */\n\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport * as Annotations from \"./Annotations.ts\"\nimport * as Effects from \"./Effects.ts\"\nimport * as Flow from \"./Flow.ts\"\nimport { build } from \"./internal/Signature.ts\"\nimport * as skillFrontmatter from \"./internal/skillFrontmatter.ts\"\nimport * as Placement from \"./Placement.ts\"\n\n/**\n * Separates leading YAML frontmatter from the markdown body without parsing it.\n * @category parsing\n * @since 1.0.0\n */\nexport { split as splitFrontmatter } from \"./internal/skillFrontmatter.ts\"\n\nconst input = Schema.Struct({ args: Schema.String })\nconst output = Schema.String\n\n/**\n * Already-parsed metadata accepted by the markdown flow loader.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface MarkdownFrontmatter {\n /**\n * The flow's name, which becomes its tag.\n *\n * It is required because the tag is what a host binds an implementation to\n * and what a plan records; a registry derives it from the frontmatter or\n * from the document's path before lowering.\n */\n readonly name: string\n readonly description?: string | undefined\n readonly model?: string | readonly [string, ...Array<string>] | undefined\n readonly flows?: ReadonlyArray<string> | undefined\n readonly capabilities?: ReadonlyArray<string> | undefined\n readonly effects?: {\n readonly reads?: ReadonlyArray<string> | undefined\n readonly writes?: ReadonlyArray<string> | undefined\n readonly mode?: Effects.Declaration[\"mode\"] | undefined\n readonly onConflict?: Effects.Declaration[\"onConflict\"] | undefined\n readonly tier?: Effects.Declaration[\"tier\"]\n } | undefined\n readonly placement?: \"sandbox\" | \"remote\" | \"client\" | \"local\" | undefined\n}\n\n/**\n * Agent Skills frontmatter that passed {@link validateSkillFrontmatter}.\n *\n * `allowedTools` is the specification's space-separated `allowed-tools`\n * scalar, split into tool names. `extra` holds every other field, including\n * the validated optional `license`, `compatibility`, and `metadata`, as a\n * frozen null-prototype record.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface SkillFrontmatter {\n readonly name: string\n readonly description: string\n readonly allowedTools: ReadonlyArray<string>\n readonly extra: Record<string, unknown>\n}\n\n/**\n * Parsed Agent Skills document.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport interface SkillDocument extends SkillFrontmatter {\n readonly body: string\n}\n\n/**\n * Stable code emitted by markdown loader failures.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport const MarkdownErrorCode = Schema.Literals([\n \"skill_missing_frontmatter\",\n \"skill_invalid_frontmatter\",\n \"skill_missing_name\",\n \"skill_invalid_name\",\n \"skill_missing_description\",\n \"skill_invalid_description\",\n \"skill_invalid_allowed_tools\",\n \"skill_invalid_compatibility\",\n \"skill_invalid_metadata\",\n \"skill_invalid_license\"\n])\n\n/**\n * Stable code emitted by markdown loader failures.\n *\n * @category models\n * @since 0.0.0\n * @slop\n */\nexport type MarkdownErrorCode = typeof MarkdownErrorCode.Type\n\n/**\n * A typed markdown loader failure.\n *\n * @category errors\n * @since 0.0.0\n * @slop\n */\nexport class MarkdownError extends Schema.TaggedError<MarkdownError>()(\"flows/core/MarkdownError\", {\n code: MarkdownErrorCode,\n message: Schema.String\n}) {}\n\n/**\n * Lowers parsed markdown metadata and a markdown body to an ordinary flow.\n *\n * The prompt is the markdown body. Harnesses append non-empty runtime `args`\n * when rendering that prompt, preserving the markdown-flow calling convention.\n * The lowered flow declares no body, so it carries the action a host supplies\n * the implementation for; the collaborators it names stay declarations, and no\n * flow implementation is resolved while lowering. The `smart` model seat is\n * the explicit fallback when frontmatter declares no `model`.\n * Model-seat and collaborator arrays are copied, so later changes to the\n * supplied frontmatter arrays do not change the lowered flow or its decorators.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const lowerMarkdown = (\n frontmatter: MarkdownFrontmatter,\n body: string\n): Flow.Flow<typeof input, typeof output> => {\n const flow = build({\n error: Schema.Never,\n annotations: Annotations.empty,\n body: undefined,\n name: frontmatter.name,\n description: frontmatter.description,\n input,\n output,\n capabilities: [...new Set(frontmatter.capabilities ?? [])].sort(),\n effects: undefined,\n ...(frontmatter.effects === undefined\n ? {}\n : {\n effects: Effects.make({\n reads: frontmatter.effects.reads ?? [],\n writes: frontmatter.effects.writes ?? [],\n mode: frontmatter.effects.mode ?? \"hermetic\",\n onConflict: frontmatter.effects.onConflict ?? \"serialize\",\n tier: frontmatter.effects.tier\n })\n }),\n model: typeof frontmatter.model === \"object\" ? [...frontmatter.model] : frontmatter.model ?? \"smart\",\n flows: [...frontmatter.flows ?? []],\n prompt: body\n })\n\n switch (frontmatter.placement) {\n case \"sandbox\":\n return Flow.within(flow, Placement.sandbox())\n case \"remote\":\n return Flow.within(flow, Placement.remote())\n case \"client\":\n return Flow.within(flow, Placement.client())\n case \"local\":\n return Flow.within(flow, Placement.local())\n default:\n return flow\n }\n}\n\nconst fail = (code: MarkdownErrorCode, message: string): Result.Result<never, MarkdownError> =>\n Result.fail(new MarkdownError({ code, message }))\n\n// The specification's name grammar: lowercase ASCII letters and digits joined\n// by single hyphens, so a leading, trailing, or doubled hyphen fails here.\nconst skillNamePattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\n\n/**\n * Whether `name` is a valid Agent Skills name: 1 to 64 lowercase ASCII\n * letters, digits, or single hyphens, not starting or ending with a hyphen.\n *\n * {@link validateSkillFrontmatter} applies this rule, and `@smthrs/registry`\n * reads the same predicate when it warns about a discovered skill's name, so\n * the rule has one definition.\n *\n * @category validation\n * @since 1.0.0-rc.1\n */\nexport const isSkillName = (name: string): boolean => name.length <= 64 && skillNamePattern.test(name)\n\n// The specification measures a field in characters. Counting UTF-16 units\n// would reject a 600-emoji description the specification accepts, so the\n// count walks code points.\nconst codePoints = (value: string): number => [...value].length\n\nconst isBlank = (value: string): boolean => value.trim() === \"\"\n\nconst isScalarMapping = (value: unknown): boolean => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false\n const prototype = Object.getPrototypeOf(value)\n if (prototype !== null && prototype !== Object.prototype) return false\n return Object.values(value).every((member) => typeof member === \"string\")\n}\n\n/**\n * Checks already-parsed Agent Skills frontmatter against the specification's\n * intrinsic rules and lowers the fields this package reads.\n *\n * `name` is 1 to 64 lowercase ASCII letters, digits, or single hyphens and\n * cannot start or end with a hyphen. `description` is 1 to 1024 characters.\n * `allowed-tools`, when present, is one space-separated scalar. `license` is\n * a scalar, `compatibility` is 1 to 500 characters, and `metadata` maps\n * string keys to scalar values. A field that is absent reports a `missing`\n * code; a field that is present but malformed reports its own `invalid` code\n * without echoing the offending value. The registry keeps the one rule that\n * needs the file system: `name` must equal the skill directory name.\n *\n * @category validation\n * @since 1.0.0-rc.0\n */\nexport const validateSkillFrontmatter = (\n fields: Record<string, unknown>\n): Result.Result<SkillFrontmatter, MarkdownError> => {\n const name = fields.name\n if (name === undefined || (typeof name === \"string\" && isBlank(name))) {\n return fail(\"skill_missing_name\", \"SKILL.md requires a non-empty frontmatter name\")\n }\n if (typeof name !== \"string\" || !isSkillName(name)) {\n return fail(\n \"skill_invalid_name\",\n \"SKILL.md name must be 1 to 64 lowercase ASCII letters, digits, or single hyphens, and cannot start or end with a hyphen\"\n )\n }\n\n const description = fields.description\n if (description === undefined || (typeof description === \"string\" && isBlank(description))) {\n return fail(\"skill_missing_description\", \"SKILL.md requires a non-empty frontmatter description\")\n }\n if (typeof description !== \"string\" || codePoints(description) > 1024) {\n return fail(\"skill_invalid_description\", \"SKILL.md description must be a scalar of 1 to 1024 characters\")\n }\n\n const allowedToolsValue = fields[\"allowed-tools\"]\n if (allowedToolsValue !== undefined && typeof allowedToolsValue !== \"string\") {\n return fail(\"skill_invalid_allowed_tools\", \"SKILL.md allowed-tools must be a space-separated scalar\")\n }\n const allowedTools = allowedToolsValue === undefined\n ? []\n : allowedToolsValue.split(/\\s+/).filter((tool) => tool.length > 0)\n\n const license = fields.license\n if (license !== undefined && typeof license !== \"string\") {\n return fail(\"skill_invalid_license\", \"SKILL.md license must be a scalar\")\n }\n\n const compatibility = fields.compatibility\n if (\n compatibility !== undefined &&\n (typeof compatibility !== \"string\" || codePoints(compatibility) < 1 || codePoints(compatibility) > 500)\n ) {\n return fail(\"skill_invalid_compatibility\", \"SKILL.md compatibility must be a scalar of 1 to 500 characters\")\n }\n\n const metadata = fields.metadata\n if (metadata !== undefined && !isScalarMapping(metadata)) {\n return fail(\"skill_invalid_metadata\", \"SKILL.md metadata must be a mapping from string keys to scalar values\")\n }\n\n const extra = Object.create(null) as Record<string, unknown>\n for (const [key, value] of Object.entries(fields)) {\n if (key !== \"name\" && key !== \"description\" && key !== \"allowed-tools\") {\n Object.defineProperty(extra, key, {\n value,\n enumerable: true,\n writable: false,\n configurable: false\n })\n }\n }\n Object.freeze(extra)\n\n return Result.succeed({ name, description, allowedTools, extra })\n}\n\n/**\n * Parses an Agent Skills document with failsafe-schema YAML semantics and\n * validates its frontmatter with {@link validateSkillFrontmatter}.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const parseSkill = (text: string): Result.Result<SkillDocument, MarkdownError> => {\n const split = skillFrontmatter.split(text)\n if (split.frontmatter === undefined) {\n return fail(\"skill_missing_frontmatter\", \"SKILL.md requires leading frontmatter\")\n }\n\n const parsed = skillFrontmatter.parse(split.frontmatter)\n if (Result.isFailure(parsed)) {\n return fail(\"skill_invalid_frontmatter\", parsed.failure)\n }\n\n return Result.map(validateSkillFrontmatter(parsed.success), (frontmatter) => ({\n ...frontmatter,\n body: split.body\n }))\n}\n\n/**\n * Parses and lowers an Agent Skills document to an ordinary flow.\n *\n * Only `name`, `description`, and `allowed-tools` are lowered. Every other\n * frontmatter field remains in {@link parseSkill}'s `extra` record for the\n * caller to interpret. Agent Skills frontmatter is untyped failsafe YAML;\n * coercing extra fields such as `model` or `placement` here would duplicate\n * the flow-level frontmatter typing owned by `@smthrs/registry`.\n *\n * @category constructors\n * @since 0.0.0\n * @slop\n */\nexport const lowerSkill = (\n text: string\n): Result.Result<Flow.Flow<typeof input, typeof output>, MarkdownError> =>\n Result.map(parseSkill(text), (skill) =>\n lowerMarkdown({\n name: skill.name,\n description: skill.description,\n flows: skill.allowedTools\n }, skill.body))\n"]}
package/docs/README.md CHANGED
@@ -37,7 +37,9 @@ diagram, or a test.
37
37
 
38
38
  ## Install
39
39
 
40
- Not on npm yet; see [Installation](https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/flow/docs/installation.md#use-the-libraries).
40
+ ```bash
41
+ npm install @smthrs/core@next effect
42
+ ```
41
43
 
42
44
  The package needs Node.js 26.4.0 or later. It has no platform bindings, so the
43
45
  same build runs in Node, in Bun, in a browser, and in a Cloudflare Worker.
@@ -7,7 +7,11 @@ sidebar:
7
7
 
8
8
  ## Install the package
9
9
 
10
- Not on npm yet; see [Installation](https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/flow/docs/installation.md#use-the-libraries).
10
+ ```bash
11
+ npm install @smthrs/core@next effect
12
+ ```
13
+
14
+ The `next` tag carries the 1.0 release candidates.
11
15
 
12
16
  The package requires Node.js 26.4.0 or later and ships as both ESM and
13
17
  CommonJS with TypeScript declarations. It has no platform bindings: it reads no
@@ -13,7 +13,7 @@ with no engine, no model, and no file system.
13
13
  ## Prerequisites
14
14
 
15
15
  - Node.js 26.4.0 or later.
16
- - A package with the dependency installed. Not on npm yet; see [Installation](https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/flow/docs/installation.md#use-the-libraries).
16
+ - A project with the packages installed: `npm install @smthrs/core@next @smthrs/flow@next effect`.
17
17
 
18
18
  ## Declare two signatures
19
19
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@smthrs/core",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.6",
4
+ "version": "1.0.0-rc.8",
5
5
  "license": "MIT",
6
6
  "smthrs": {
7
7
  "group": "agent"
@@ -165,10 +165,10 @@
165
165
  "tag": "next"
166
166
  },
167
167
  "dependencies": {
168
- "@smthrs/canonical": "1.0.0-rc.6",
169
- "@smthrs/crypto": "1.0.0-rc.6",
170
- "@smthrs/flow": "1.0.0-rc.6",
171
- "@smthrs/plan": "1.0.0-rc.6",
168
+ "@smthrs/canonical": "1.0.0-rc.8",
169
+ "@smthrs/crypto": "1.0.0-rc.8",
170
+ "@smthrs/flow": "1.0.0-rc.8",
171
+ "@smthrs/plan": "1.0.0-rc.8",
172
172
  "yaml": "2.9.0"
173
173
  },
174
174
  "devDependencies": {
@@ -176,7 +176,7 @@
176
176
  "@effect/platform-node": "4.0.4",
177
177
  "@effect/vitest": "4.0.4",
178
178
  "@eslint/js": "9.39.5",
179
- "@smthrs/engine": "1.0.0-rc.6",
179
+ "@smthrs/engine": "1.0.0-rc.8",
180
180
  "@types/node": "26.4.1",
181
181
  "@vitest/coverage-v8": "5.0.0",
182
182
  "dprint": "0.57.1",
@@ -196,7 +196,7 @@
196
196
  "effect": "^4.0.4"
197
197
  },
198
198
  "scripts": {
199
- "lint": "eslint src --max-warnings=0 && dprint check",
199
+ "lint": "eslint src examples --max-warnings=0 && dprint check",
200
200
  "format": "dprint fmt",
201
201
  "build": "node scripts/build.mjs",
202
202
  "check": "tsc -b tsconfig.json && tsc -p tsconfig.test.json --noEmit",
package/src/Markdown.ts CHANGED
@@ -144,6 +144,8 @@ export class MarkdownError extends Schema.TaggedError<MarkdownError>()("flows/co
144
144
  * the implementation for; the collaborators it names stay declarations, and no
145
145
  * flow implementation is resolved while lowering. The `smart` model seat is
146
146
  * the explicit fallback when frontmatter declares no `model`.
147
+ * Model-seat and collaborator arrays are copied, so later changes to the
148
+ * supplied frontmatter arrays do not change the lowered flow or its decorators.
147
149
  *
148
150
  * @category constructors
149
151
  * @since 0.0.0
@@ -174,8 +176,8 @@ export const lowerMarkdown = (
174
176
  tier: frontmatter.effects.tier
175
177
  })
176
178
  }),
177
- model: frontmatter.model ?? "smart",
178
- flows: frontmatter.flows ?? [],
179
+ model: typeof frontmatter.model === "object" ? [...frontmatter.model] : frontmatter.model ?? "smart",
180
+ flows: [...frontmatter.flows ?? []],
179
181
  prompt: body
180
182
  })
181
183
 
@@ -220,11 +222,12 @@ const codePoints = (value: string): number => [...value].length
220
222
 
221
223
  const isBlank = (value: string): boolean => value.trim() === ""
222
224
 
223
- const isScalarMapping = (value: unknown): boolean =>
224
- typeof value === "object" &&
225
- value !== null &&
226
- !Array.isArray(value) &&
227
- Object.values(value).every((member) => typeof member === "string")
225
+ const isScalarMapping = (value: unknown): boolean => {
226
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false
227
+ const prototype = Object.getPrototypeOf(value)
228
+ if (prototype !== null && prototype !== Object.prototype) return false
229
+ return Object.values(value).every((member) => typeof member === "string")
230
+ }
228
231
 
229
232
  /**
230
233
  * Checks already-parsed Agent Skills frontmatter against the specification's