@prismer/runtime 2.0.7 → 2.2.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3631 -0
- package/README.md +34 -12
- package/apc/skills/FIELD-DICTIONARY.md +111 -0
- package/apc/skills/bug-reproduce/SKILL.md +150 -0
- package/apc/skills/bug-reproduce/skill.json +96 -0
- package/apc/skills/code-review/SKILL.md +198 -0
- package/apc/skills/code-review/skill.json +124 -0
- package/apc/skills/design-review/SKILL.md +122 -0
- package/apc/skills/design-review/skill.json +88 -0
- package/apc/skills/doc-sync/SKILL.md +168 -0
- package/apc/skills/doc-sync/skill.json +81 -0
- package/apc/skills/env-doctor/SKILL.md +194 -0
- package/apc/skills/env-doctor/skill.json +209 -0
- package/apc/skills/git-ops/SKILL.md +189 -0
- package/apc/skills/git-ops/skill.json +94 -0
- package/apc/skills/impact-trace/SKILL.md +168 -0
- package/apc/skills/impact-trace/skill.json +104 -0
- package/apc/skills/observability/SKILL.md +195 -0
- package/apc/skills/observability/skill.json +116 -0
- package/apc/skills/release-db-config-sync/SKILL.md +186 -0
- package/apc/skills/release-db-config-sync/skill.json +109 -0
- package/apc/skills/release-ota-promote/SKILL.md +195 -0
- package/apc/skills/release-ota-promote/skill.json +176 -0
- package/apc/skills/release-preflight/SKILL.md +174 -0
- package/apc/skills/release-preflight/skill.json +175 -0
- package/apc/skills/release-rollback/SKILL.md +214 -0
- package/apc/skills/release-rollback/skill.json +230 -0
- package/apc/skills/release-tag/SKILL.md +194 -0
- package/apc/skills/release-tag/skill.json +94 -0
- package/apc/skills/releasing-prod/SKILL.md +49 -0
- package/apc/skills/releasing-test/SKILL.md +135 -0
- package/apc/skills/sdk-release/SKILL.md +200 -0
- package/apc/skills/spec-intake/SKILL.md +169 -0
- package/apc/skills/spec-intake/skill.json +93 -0
- package/apc/skills/test-result-feedback/SKILL.md +239 -0
- package/apc/skills/test-result-feedback/skill.json +193 -0
- package/apc/skills/test-runner/SKILL.md +169 -0
- package/apc/skills/test-runner/skill.json +103 -0
- package/apc/skills/ui-align/SKILL.md +209 -0
- package/apc/skills/ui-align/skill.json +114 -0
- package/apc/skills/ui-canvas/SKILL.md +148 -0
- package/apc/skills/ui-canvas/skill.json +127 -0
- package/built-in-skills/agent-coordination/SKILL.md +257 -0
- package/built-in-skills/agent-meta/SKILL.md +53 -0
- package/built-in-skills/assets/SKILL.md +133 -0
- package/built-in-skills/browser-use/SKILL.md +93 -0
- package/built-in-skills/canvas-design/LICENSE.txt +202 -0
- package/built-in-skills/canvas-design/SKILL.md +157 -0
- package/built-in-skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/built-in-skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/built-in-skills/claim-agent-ownership/SKILL.md +255 -0
- package/built-in-skills/claude-api/LICENSE.txt +202 -0
- package/built-in-skills/claude-api/SKILL.md +325 -0
- package/built-in-skills/claude-api/csharp/claude-api.md +402 -0
- package/built-in-skills/claude-api/curl/examples.md +216 -0
- package/built-in-skills/claude-api/curl/managed-agents.md +336 -0
- package/built-in-skills/claude-api/go/claude-api.md +421 -0
- package/built-in-skills/claude-api/go/managed-agents/README.md +561 -0
- package/built-in-skills/claude-api/java/claude-api.md +432 -0
- package/built-in-skills/claude-api/java/managed-agents/README.md +442 -0
- package/built-in-skills/claude-api/php/claude-api.md +375 -0
- package/built-in-skills/claude-api/php/managed-agents/README.md +435 -0
- package/built-in-skills/claude-api/python/claude-api/README.md +420 -0
- package/built-in-skills/claude-api/python/claude-api/batches.md +185 -0
- package/built-in-skills/claude-api/python/claude-api/files-api.md +165 -0
- package/built-in-skills/claude-api/python/claude-api/streaming.md +162 -0
- package/built-in-skills/claude-api/python/claude-api/tool-use.md +590 -0
- package/built-in-skills/claude-api/python/managed-agents/README.md +332 -0
- package/built-in-skills/claude-api/ruby/claude-api.md +113 -0
- package/built-in-skills/claude-api/ruby/managed-agents/README.md +389 -0
- package/built-in-skills/claude-api/shared/agent-design.md +101 -0
- package/built-in-skills/claude-api/shared/error-codes.md +213 -0
- package/built-in-skills/claude-api/shared/live-sources.md +135 -0
- package/built-in-skills/claude-api/shared/managed-agents-api-reference.md +378 -0
- package/built-in-skills/claude-api/shared/managed-agents-client-patterns.md +209 -0
- package/built-in-skills/claude-api/shared/managed-agents-core.md +238 -0
- package/built-in-skills/claude-api/shared/managed-agents-environments.md +215 -0
- package/built-in-skills/claude-api/shared/managed-agents-events.md +195 -0
- package/built-in-skills/claude-api/shared/managed-agents-memory.md +197 -0
- package/built-in-skills/claude-api/shared/managed-agents-multiagent.md +99 -0
- package/built-in-skills/claude-api/shared/managed-agents-onboarding.md +114 -0
- package/built-in-skills/claude-api/shared/managed-agents-outcomes.md +106 -0
- package/built-in-skills/claude-api/shared/managed-agents-overview.md +68 -0
- package/built-in-skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +173 -0
- package/built-in-skills/claude-api/shared/managed-agents-tools.md +321 -0
- package/built-in-skills/claude-api/shared/managed-agents-webhooks.md +110 -0
- package/built-in-skills/claude-api/shared/model-migration.md +779 -0
- package/built-in-skills/claude-api/shared/models.md +121 -0
- package/built-in-skills/claude-api/shared/prompt-caching.md +171 -0
- package/built-in-skills/claude-api/shared/tool-use-concepts.md +327 -0
- package/built-in-skills/claude-api/typescript/claude-api/README.md +333 -0
- package/built-in-skills/claude-api/typescript/claude-api/batches.md +106 -0
- package/built-in-skills/claude-api/typescript/claude-api/files-api.md +98 -0
- package/built-in-skills/claude-api/typescript/claude-api/streaming.md +178 -0
- package/built-in-skills/claude-api/typescript/claude-api/tool-use.md +527 -0
- package/built-in-skills/claude-api/typescript/managed-agents/README.md +359 -0
- package/built-in-skills/codebase-design/DEEPENING.md +37 -0
- package/built-in-skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/built-in-skills/codebase-design/LICENSE +21 -0
- package/built-in-skills/codebase-design/SKILL.md +116 -0
- package/built-in-skills/conversation-compaction/SKILL.md +114 -0
- package/built-in-skills/council-creator/SKILL.md +426 -0
- package/built-in-skills/diagnosing-bugs/LICENSE +21 -0
- package/built-in-skills/diagnosing-bugs/SKILL.md +136 -0
- package/built-in-skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/built-in-skills/doc-coauthoring/SKILL.md +376 -0
- package/built-in-skills/document-generation/SKILL.md +105 -0
- package/built-in-skills/domain-modeling/ADR-FORMAT.md +47 -0
- package/built-in-skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/built-in-skills/domain-modeling/LICENSE +21 -0
- package/built-in-skills/domain-modeling/SKILL.md +76 -0
- package/built-in-skills/frontend-design/LICENSE.txt +177 -0
- package/built-in-skills/frontend-design/SKILL.md +43 -0
- package/built-in-skills/human-approval/SKILL.md +129 -0
- package/built-in-skills/image-generate/SKILL.md +128 -0
- package/built-in-skills/image-generate/scripts/generate-and-deliver.mjs +289 -0
- package/built-in-skills/ingest/SKILL.md +73 -0
- package/built-in-skills/internal-comms/LICENSE.txt +202 -0
- package/built-in-skills/internal-comms/SKILL.md +33 -0
- package/built-in-skills/internal-comms/examples/3p-updates.md +47 -0
- package/built-in-skills/internal-comms/examples/company-newsletter.md +65 -0
- package/built-in-skills/internal-comms/examples/faq-answers.md +30 -0
- package/built-in-skills/internal-comms/examples/general-comms.md +16 -0
- package/built-in-skills/liteparse/SKILL.md +176 -0
- package/built-in-skills/mcp-builder/LICENSE.txt +202 -0
- package/built-in-skills/mcp-builder/SKILL.md +237 -0
- package/built-in-skills/mcp-builder/reference/evaluation.md +602 -0
- package/built-in-skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/built-in-skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/built-in-skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/built-in-skills/mcp-builder/scripts/connections.py +151 -0
- package/built-in-skills/mcp-builder/scripts/evaluation.py +373 -0
- package/built-in-skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/built-in-skills/mcp-builder/scripts/requirements.txt +2 -0
- package/built-in-skills/memory/SKILL.md +471 -0
- package/built-in-skills/memory-dream/SKILL.md +339 -0
- package/built-in-skills/office-artifacts/SKILL.md +211 -0
- package/built-in-skills/okr/SKILL.md +154 -0
- package/built-in-skills/persona/SKILL.md +81 -0
- package/built-in-skills/persona-generator/SKILL.md +296 -0
- package/built-in-skills/pkf-svg/SKILL.md +253 -0
- package/built-in-skills/pkf-writing/SKILL.md +236 -0
- package/built-in-skills/prismer-im-collab/SKILL.md +168 -0
- package/built-in-skills/proactivity/SKILL.md +84 -0
- package/built-in-skills/remotion/SKILL.md +431 -0
- package/built-in-skills/role-builder/SKILL.md +203 -0
- package/built-in-skills/role-builder/scripts/author-role.mjs +334 -0
- package/built-in-skills/role-builder/scripts/ingest-role.mjs +223 -0
- package/built-in-skills/role-builder/scripts/instantiate-and-run.mjs +290 -0
- package/built-in-skills/role-builder/scripts/operation-harness.mjs +267 -0
- package/built-in-skills/skill-authoring/SKILL.md +134 -0
- package/built-in-skills/skill-authoring/skill.json +74 -0
- package/built-in-skills/skill-builder/SKILL.md +171 -0
- package/built-in-skills/skill-builder/scripts/ingest.mjs +265 -0
- package/built-in-skills/skill-creator/LICENSE.txt +202 -0
- package/built-in-skills/skill-creator/SKILL.md +227 -0
- package/built-in-skills/skill-creator/agents/analyzer.md +274 -0
- package/built-in-skills/skill-creator/agents/comparator.md +202 -0
- package/built-in-skills/skill-creator/agents/grader.md +223 -0
- package/built-in-skills/skill-creator/assets/eval_review.html +146 -0
- package/built-in-skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/built-in-skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/built-in-skills/skill-creator/references/external-library-import.md +110 -0
- package/built-in-skills/skill-creator/references/schemas.md +430 -0
- package/built-in-skills/skill-creator/scripts/__init__.py +0 -0
- package/built-in-skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/built-in-skills/skill-creator/scripts/generate_report.py +326 -0
- package/built-in-skills/skill-creator/scripts/import-library.mjs +475 -0
- package/built-in-skills/skill-creator/scripts/improve_description.py +247 -0
- package/built-in-skills/skill-creator/scripts/package_skill.py +136 -0
- package/built-in-skills/skill-creator/scripts/quick_validate.py +103 -0
- package/built-in-skills/skill-creator/scripts/run_eval.py +310 -0
- package/built-in-skills/skill-creator/scripts/run_loop.py +328 -0
- package/built-in-skills/skill-creator/scripts/utils.py +47 -0
- package/built-in-skills/slack-gif-creator/LICENSE.txt +202 -0
- package/built-in-skills/slack-gif-creator/SKILL.md +291 -0
- package/built-in-skills/slack-gif-creator/core/easing.py +234 -0
- package/built-in-skills/slack-gif-creator/core/frame_composer.py +176 -0
- package/built-in-skills/slack-gif-creator/core/gif_builder.py +269 -0
- package/built-in-skills/slack-gif-creator/core/validators.py +136 -0
- package/built-in-skills/slack-gif-creator/requirements.txt +4 -0
- package/built-in-skills/tasks/SKILL.md +413 -0
- package/built-in-skills/tdd/LICENSE +21 -0
- package/built-in-skills/tdd/SKILL.md +110 -0
- package/built-in-skills/tdd/mocking.md +59 -0
- package/built-in-skills/tdd/refactoring.md +10 -0
- package/built-in-skills/tdd/tests.md +61 -0
- package/built-in-skills/team/SKILL.md +77 -0
- package/built-in-skills/web-artifacts-builder/LICENSE.txt +202 -0
- package/built-in-skills/web-artifacts-builder/SKILL.md +105 -0
- package/built-in-skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/built-in-skills/web-artifacts-builder/scripts/init-artifact.sh +334 -0
- package/built-in-skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/built-in-skills/webapp-testing/LICENSE.txt +202 -0
- package/built-in-skills/webapp-testing/SKILL.md +97 -0
- package/built-in-skills/webapp-testing/examples/console_logging.py +35 -0
- package/built-in-skills/webapp-testing/examples/element_discovery.py +40 -0
- package/built-in-skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/built-in-skills/webapp-testing/scripts/with_server.py +106 -0
- package/built-in-skills/wechat-pay/SKILL.md +59 -0
- package/dist/cli.cjs +72577 -16101
- package/dist/cli.js +72752 -16232
- package/dist/index.cjs +72632 -16024
- package/dist/index.d.cts +4956 -640
- package/dist/index.d.ts +4956 -640
- package/dist/index.js +72564 -15963
- package/package.json +39 -6
- package/plugins/memory/prismer/__init__.py +1211 -0
- package/plugins/memory/prismer/plugin.yaml +8 -0
- package/plugins/memory/prismer/tool-schemas.generated.json +249 -0
- package/plugins/tools/prismer-recall/__init__.py +282 -0
- package/plugins/tools/prismer-recall/plugin.yaml +15 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"slug": "skill-authoring",
|
|
4
|
+
"name": "Skill Authoring",
|
|
5
|
+
"description": "Generate Prismer-compliant skill drafts from user intent, documentation URLs, existing code, or service endpoints. Wraps Anthropic skill-creator's writing knowledge into an executable pipeline that emits multi-file manifest v1 and persists as status=draft via cloud endpoint.",
|
|
6
|
+
"category": "workflow",
|
|
7
|
+
"version": "1.0.0",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"compatibility": [
|
|
10
|
+
"prismer-sdk",
|
|
11
|
+
"hermes",
|
|
12
|
+
"openclaw",
|
|
13
|
+
"claude-code",
|
|
14
|
+
"codex"
|
|
15
|
+
],
|
|
16
|
+
"runtime": {
|
|
17
|
+
"kind": "text-workflow",
|
|
18
|
+
"executableJson": {
|
|
19
|
+
"kind": "cli",
|
|
20
|
+
"command": "cloud skill draft create {{bundle_dir}}"
|
|
21
|
+
},
|
|
22
|
+
"requires": {
|
|
23
|
+
"env": ["PRISMER_API_KEY"],
|
|
24
|
+
"bins": ["cloud"],
|
|
25
|
+
"capabilities": ["prismer.skill.draft.create"]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"inputs": [
|
|
29
|
+
{ "name": "sourceKind", "type": "enum<inline-spec|doc-url|code-source|service-endpoint>", "required": true, "description": "Source kind chosen by the user or inferred from the slash command" },
|
|
30
|
+
{ "name": "intent", "type": "string", "required": true, "description": "Free-form description of what the produced skill should do; ≥ 50 quality units (ASCII=1, non-ASCII=2)" },
|
|
31
|
+
{ "name": "sourceRefs", "type": "array<string>", "required": false, "description": "URLs / repo paths / endpoint URLs depending on sourceKind" }
|
|
32
|
+
],
|
|
33
|
+
"outputs": [
|
|
34
|
+
{ "name": "draftId", "type": "string", "required": true, "description": "IMSkill row id (status=draft)" },
|
|
35
|
+
{ "name": "slug", "type": "string", "required": true },
|
|
36
|
+
{ "name": "manifestRevision", "type": "string", "required": true, "description": "Merkle root of manifest files[]" },
|
|
37
|
+
{ "name": "reviewTaskId", "type": "string", "required": true, "description": "IMTask id (capability=skill-review)" }
|
|
38
|
+
],
|
|
39
|
+
"sampleTasks": [
|
|
40
|
+
{
|
|
41
|
+
"title": "Author a skill from an OpenClaw documentation URL",
|
|
42
|
+
"prompt": "/skill new --from doc https://docs.openclaw.ai/skills/index — make a skill that scrapes the OpenClaw tools catalog and bundles it as a reference",
|
|
43
|
+
"expectedArtifacts": [
|
|
44
|
+
"SKILL.md with frontmatter (name, description, license, compatibility)",
|
|
45
|
+
"skill.json with provenance.sourceKind='doc-url'",
|
|
46
|
+
"references/openclaw-skills.md compressed reference"
|
|
47
|
+
],
|
|
48
|
+
"acceptanceCriteria": [
|
|
49
|
+
"IMSkill row exists with status=draft and slug matches user-provided value",
|
|
50
|
+
"manifest contains a SKILL.md and a skill.json (located by basename, any order — the package gate does NOT require them at positions [0]/[1])",
|
|
51
|
+
"GET /api/im/skills/search?q=<slug> returns 0 rows (draft filter applies)"
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"security": {
|
|
56
|
+
"dataAccess": [
|
|
57
|
+
"workspace-assets",
|
|
58
|
+
"external-network"
|
|
59
|
+
],
|
|
60
|
+
"humanApprovalRequiredFor": [
|
|
61
|
+
"code-source fetches outside PRISMER_WORKSPACE_ROOT or $HOME/.prismer/agents/<agentId>/scratch",
|
|
62
|
+
"service-endpoint probes against non-public hosts"
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
"provenance": {
|
|
66
|
+
"sourceKind": "inline-spec",
|
|
67
|
+
"sourceRefs": [
|
|
68
|
+
"docs/release201/07-skill-authoring-engine.md",
|
|
69
|
+
"sdk/prismer-cloud/built-in-skills/skill-creator/SKILL.md"
|
|
70
|
+
],
|
|
71
|
+
"authoredBy": "prismer-platform",
|
|
72
|
+
"authoredAt": "2026-05-26T00:00:00Z"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-builder
|
|
3
|
+
scope: common
|
|
4
|
+
description: Low-level helper for the DIRECT-PUBLISH tier of skill authoring — it is NOT the entry point for creating skills. To make/build/author/package a skill, use `skill-creator` (the single canonical skill author). This page only documents `skill-creator`'s direct-publish tier (`cloud skill create --install`, or the portable `scripts/ingest.mjs` ingest fallback) and the SS-01 bundle/ingest format. Do NOT route here when the user wants to create a skill — route to skill-creator.
|
|
5
|
+
license: MIT
|
|
6
|
+
compatibility:
|
|
7
|
+
- prismer-sdk
|
|
8
|
+
- hermes
|
|
9
|
+
- claude-code
|
|
10
|
+
- codex
|
|
11
|
+
metadata:
|
|
12
|
+
category: authoring
|
|
13
|
+
allowed-tools:
|
|
14
|
+
- Read
|
|
15
|
+
- Write
|
|
16
|
+
- Bash
|
|
17
|
+
- WebFetch
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Skill Builder — the direct-publish tier of `skill-creator`
|
|
21
|
+
|
|
22
|
+
> **Not an authoring entry point.** Creating, editing, or packaging a skill is
|
|
23
|
+
> the job of **`skill-creator`** — the single canonical skill author. This page
|
|
24
|
+
> only exists to document one of skill-creator's two publish trust tiers
|
|
25
|
+
> (**direct publish**) plus the low-level `scripts/ingest.mjs` ingest helper.
|
|
26
|
+
> If the user says "turn this into a skill" / "make a skill" / "package this
|
|
27
|
+
> workflow", **use `skill-creator`**, not this.
|
|
28
|
+
|
|
29
|
+
## Where this fits
|
|
30
|
+
|
|
31
|
+
`skill-creator` drives the full lifecycle author→validate→test→package→publish.
|
|
32
|
+
At the publish step there are two trust tiers ([[16-skill-role-authoring-as-agent-capability]] §5.3):
|
|
33
|
+
|
|
34
|
+
- **Direct create (default)** — `cloud skill create ./<dir> [--install]` →
|
|
35
|
+
`status=active`, `publishScope=workspace` (**private**, installable — NOT public).
|
|
36
|
+
Marketplace publish is the separate `cloud skill publish`. This page.
|
|
37
|
+
- **Draft-gated (explicit)** — `cloud skill draft create` → `status=draft`,
|
|
38
|
+
Studio Authoring promotes it. Documented under `skill-authoring`.
|
|
39
|
+
|
|
40
|
+
Both tiers are reached from inside `skill-creator`. Neither is a separate
|
|
41
|
+
"author a skill" skill — they're publish-verb choices.
|
|
42
|
+
|
|
43
|
+
## SS-01 bundle format (reference)
|
|
44
|
+
|
|
45
|
+
The canonical contract is **SS-01** (`public/docs/Standardization/01-skill-standard.md`).
|
|
46
|
+
A skill is a directory named exactly `<slug>/`:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
<slug>/
|
|
50
|
+
├── SKILL.md # required — frontmatter + body (injected into agent prompt)
|
|
51
|
+
├── scripts/ # optional — runnable code
|
|
52
|
+
├── references/ # optional — docs loaded as needed
|
|
53
|
+
└── assets/ # optional — templates / images
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`SKILL.md` frontmatter (SS-01 §3.2 — aligns with agentskills.io):
|
|
57
|
+
|
|
58
|
+
```markdown
|
|
59
|
+
---
|
|
60
|
+
name: <slug> # must equal the dir name
|
|
61
|
+
scope: common # common | persistence | coding
|
|
62
|
+
description: <one line; what it does AND when to trigger>
|
|
63
|
+
license: MIT
|
|
64
|
+
compatibility:
|
|
65
|
+
- prismer-sdk
|
|
66
|
+
- claude-code
|
|
67
|
+
metadata:
|
|
68
|
+
category: <category>
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
# <Title>
|
|
72
|
+
<body: imperative instructions, progressive disclosure, ≤500 lines>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`scope` buckets the skill for per-role native-skill filtering (release203/13):
|
|
76
|
+
`common` (default, any agent) / `persistence` (memory/state) / `coding`
|
|
77
|
+
(code-agent targets). It lives inside SKILL.md and round-trips automatically.
|
|
78
|
+
|
|
79
|
+
## Direct-publish ingest
|
|
80
|
+
|
|
81
|
+
The preferred path is the `cloud skill create` CLI (driven from `skill-creator`):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
cloud skill create ./<slug> --install --json
|
|
85
|
+
# POST /api/im/skills (+ install). Reads api key from prismer config.
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
When the `cloud` CLI binary is not on PATH (CI / SDK-only environments), use the
|
|
89
|
+
bundled zero-dependency ingest script:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
PRISMER_API_KEY=sk-prismer-... PRISMER_CLOUD_BASE=http://127.0.0.1:3000 \
|
|
93
|
+
node scripts/ingest.mjs ./<slug> --install
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`scripts/ingest.mjs` parses the SKILL.md frontmatter, collects every bundle file
|
|
97
|
+
into an SS-01 `contentManifest`, computes the merkle `contentManifestRevision`
|
|
98
|
+
with the exact server algorithm
|
|
99
|
+
(`sha256(sorted("<path>:<sha256(bytes)>").join("\n"))`), `POST`s to
|
|
100
|
+
`/api/im/skills` with `Authorization: Bearer $PRISMER_API_KEY`, and on
|
|
101
|
+
`--install` follows with `POST /api/im/skills/:slug/install`. Both paths only
|
|
102
|
+
need an **API key** (`authMiddleware` accepts `sk-prismer-*` as a Bearer token).
|
|
103
|
+
|
|
104
|
+
If `cloud` is present but `skill create` is missing, that is CLI version skew,
|
|
105
|
+
not permission to bypass the lifecycle. Report `cloud --version` and use the
|
|
106
|
+
current repository build. The script fallback is not a workaround for a
|
|
107
|
+
partially stale CLI because its auth/scope/readback behavior is precisely what
|
|
108
|
+
the authoring flow needs to verify.
|
|
109
|
+
|
|
110
|
+
The bundle reader accepts YAML literal/folded block scalars in frontmatter, so
|
|
111
|
+
upstream `description: |` / `description: >` content must not be rewritten to a
|
|
112
|
+
single line merely for ingest. The 50-unit description quality floor counts
|
|
113
|
+
non-ASCII code points as two units, avoiding meaningless padding of concise CJK
|
|
114
|
+
descriptions while retaining the English quality bar.
|
|
115
|
+
|
|
116
|
+
> **The catalog slug is server-assigned**, not your frontmatter `name`. Community
|
|
117
|
+
> creates are prefixed (`weather-lookup` → `community-weather-lookup`). Use the
|
|
118
|
+
> slug returned in the 201 response for install, `cloud skill show`, and a role's
|
|
119
|
+
> `requiredSkills`. A `409` means the slug already exists — pick a new name;
|
|
120
|
+
> there is no in-place overwrite.
|
|
121
|
+
|
|
122
|
+
## After publishing: managing a live skill
|
|
123
|
+
|
|
124
|
+
Publishing is not a one-way door. Every verb below is a `cloud skill` subcommand
|
|
125
|
+
(the `prismer skill` daemon CLI has the identical set).
|
|
126
|
+
|
|
127
|
+
**The one fact everything else follows from: an installed skill is a LIVE
|
|
128
|
+
REFERENCE, not a snapshot.** `im_agent_skills` stores only `skillId` +
|
|
129
|
+
`installedRevision`; every daemon sync re-reads the catalog row's current
|
|
130
|
+
`contentManifest`. So **editing a published skill's content propagates to every
|
|
131
|
+
agent that has it installed** — no re-install, no opt-in. That is why the server
|
|
132
|
+
rejects a content edit with `422 changelog_required` unless you pass
|
|
133
|
+
`--changelog "<what changed>"`: consumers are entitled to know what changed under
|
|
134
|
+
them. Metadata-only edits (description / icon / tags) need no changelog.
|
|
135
|
+
|
|
136
|
+
| Verb | What it does | Effect on people already using it |
|
|
137
|
+
| ------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
138
|
+
| `cloud skill delist <slug> [--reason ...]` | Removes it from Marketplace search. Content, installs, syncs all keep working. | **None.** They keep the skill and keep receiving content updates. |
|
|
139
|
+
| `cloud skill relist <slug>` | Puts it back (re-runs the publish gate, so an admin takedown still blocks it). | None. |
|
|
140
|
+
| `cloud skill deprecate <slug> --reason <r> [--successor <slug>]` | Marks it superseded. It stays installable — new installs get a **warning, not a block**. | None; they see the reason + successor. |
|
|
141
|
+
| `cloud skill undeprecate <slug>` | Clears the mark. | None. |
|
|
142
|
+
| `cloud skill archive <slug> [--confirm]` | **Retires it. UNBINDS every agent that has it installed.** | **Destructive.** With live consumers the server refuses until `--confirm`. |
|
|
143
|
+
| `cloud skill transfer <slug> --to <imUserId>` | Offers ownership. Two-phase — nothing moves until the recipient runs `transfer-accept`. | None. (`transfer-abort` withdraws the offer.) |
|
|
144
|
+
| `cloud skill published` | Your publication inventory: slug, listing state, **consumer count**. | — |
|
|
145
|
+
|
|
146
|
+
**delist vs archive is the distinction that matters.** Delist is a visibility
|
|
147
|
+
flip: it hides the skill from the Marketplace and nothing else. Archive retires
|
|
148
|
+
it and unbinds every installed agent — that is why it has a consumer door:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
$ cloud skill archive weather-lookup
|
|
152
|
+
Error: 3 agents are still using this skill — archiving unbinds them.
|
|
153
|
+
Re-run with --confirm to archive anyway: cloud skill archive weather-lookup --confirm
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Reach for delist when you no longer want new users; reach for archive only when
|
|
157
|
+
you intend to cut existing ones off. Deprecate is the polite middle: it keeps
|
|
158
|
+
working and points people at the successor. There is **no hard delete** — a
|
|
159
|
+
published skill is never destroyed, only moved between these states.
|
|
160
|
+
|
|
161
|
+
Admin takedown is a separate, admin-only action. A taken-down skill cannot be
|
|
162
|
+
re-listed by its owner (`cloud skill relist` returns "was taken down by an
|
|
163
|
+
administrator"); an admin must reinstate it first.
|
|
164
|
+
|
|
165
|
+
## Reference
|
|
166
|
+
|
|
167
|
+
- The skill author (use this): `built-in-skills/skill-creator/SKILL.md`
|
|
168
|
+
- Bundle + catalog contract: `public/docs/Standardization/01-skill-standard.md` (SS-01)
|
|
169
|
+
- Draft-gated tier: `built-in-skills/skill-authoring/SKILL.md`
|
|
170
|
+
- Role side: `built-in-skills/role-builder/SKILL.md` (SS-02)
|
|
171
|
+
- Post-publish endpoint contract: `docs/api/publish-lifecycle.md` (product204/21)
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// skill-builder ingest — material→bundle→live catalog, via SDK + API key.
|
|
3
|
+
//
|
|
4
|
+
// Zero runtime dependencies (Node ≥18 built-ins only). Reads a SS-01 skill
|
|
5
|
+
// bundle directory, parses SKILL.md frontmatter, builds an SS-01 contentManifest
|
|
6
|
+
// with a server-matching merkle revision, and POSTs it to the real catalog
|
|
7
|
+
// endpoint authenticated with an `sk-prismer-*` API key.
|
|
8
|
+
//
|
|
9
|
+
// Usage:
|
|
10
|
+
// PRISMER_API_KEY=sk-prismer-... [PRISMER_CLOUD_BASE=http://127.0.0.1:3000] \
|
|
11
|
+
// node scripts/ingest.mjs <bundle-dir> [--install] [--agent <imUserId>] [--json]
|
|
12
|
+
//
|
|
13
|
+
// Env:
|
|
14
|
+
// PRISMER_API_KEY (required) Bearer token; admin not required for skill create.
|
|
15
|
+
// PRISMER_CLOUD_BASE (default http://127.0.0.1:3000) cloud base URL.
|
|
16
|
+
|
|
17
|
+
import { createHash } from 'node:crypto';
|
|
18
|
+
import { readFileSync, readdirSync, statSync } from 'node:fs';
|
|
19
|
+
import { join, relative, sep } from 'node:path';
|
|
20
|
+
|
|
21
|
+
function die(msg, code = 1) {
|
|
22
|
+
console.error(`[skill-builder] ✗ ${msg}`);
|
|
23
|
+
process.exit(code);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const args = process.argv.slice(2);
|
|
27
|
+
const secretOptions = new Set(['--api-key', '--token', '--jwt', '--secret', '--password']);
|
|
28
|
+
let bundleDir;
|
|
29
|
+
let wantInstall = false;
|
|
30
|
+
let asJson = false;
|
|
31
|
+
let agentId;
|
|
32
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
33
|
+
const arg = args[index];
|
|
34
|
+
const equalsAt = arg.indexOf('=');
|
|
35
|
+
const option = equalsAt === -1 ? arg : arg.slice(0, equalsAt);
|
|
36
|
+
if (secretOptions.has(option)) {
|
|
37
|
+
die(`${option} is forbidden; credentials must come from environment variables`, 2);
|
|
38
|
+
}
|
|
39
|
+
if (arg === '--install') {
|
|
40
|
+
wantInstall = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (arg === '--json') {
|
|
44
|
+
asJson = true;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (arg === '--agent') {
|
|
48
|
+
const value = args[index + 1];
|
|
49
|
+
if (!value || value.startsWith('--')) die('--agent requires an imUserId', 2);
|
|
50
|
+
agentId = value;
|
|
51
|
+
index += 1;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (arg.startsWith('--')) die(`unknown argument at position ${index + 1}`, 2);
|
|
55
|
+
if (bundleDir) die('only one bundle directory may be supplied', 2);
|
|
56
|
+
bundleDir = arg;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const API_KEY = process.env.PRISMER_API_KEY;
|
|
60
|
+
const BASE = (process.env.PRISMER_CLOUD_BASE || 'http://127.0.0.1:3000').replace(/\/$/, '');
|
|
61
|
+
|
|
62
|
+
if (!bundleDir) die('usage: node ingest.mjs <bundle-dir> [--install] [--agent <imUserId>] [--json]');
|
|
63
|
+
if (!API_KEY) die('PRISMER_API_KEY env is required (sk-prismer-*)');
|
|
64
|
+
let target;
|
|
65
|
+
try {
|
|
66
|
+
target = new URL(BASE);
|
|
67
|
+
} catch {
|
|
68
|
+
die('PRISMER_CLOUD_BASE must be a valid URL', 2);
|
|
69
|
+
}
|
|
70
|
+
if (
|
|
71
|
+
!['http:', 'https:'].includes(target.protocol) ||
|
|
72
|
+
target.username ||
|
|
73
|
+
target.password ||
|
|
74
|
+
target.search ||
|
|
75
|
+
target.hash
|
|
76
|
+
) {
|
|
77
|
+
die('PRISMER_CLOUD_BASE must be a plain http(s) origin without credentials, query, or hash', 2);
|
|
78
|
+
}
|
|
79
|
+
const isLocalTarget = ['localhost', '127.0.0.1', '::1', 'host.docker.internal'].includes(target.hostname);
|
|
80
|
+
const allowRemote = ['1', 'true', 'yes'].includes(String(process.env.PRISMER_ALLOW_REMOTE_WRITE).toLowerCase());
|
|
81
|
+
if (!isLocalTarget && !allowRemote) {
|
|
82
|
+
die('remote mutation is blocked; set PRISMER_ALLOW_REMOTE_WRITE=1 after confirming the target environment', 2);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ── collect bundle files (SS-01 §3.1 — exclude dotfiles + LICENSE*) ──────────
|
|
86
|
+
const EXCLUDED = new Set(['.DS_Store', 'Thumbs.db', 'LICENSE', 'LICENSE.txt', 'LICENSE.md']);
|
|
87
|
+
function collect(dir) {
|
|
88
|
+
const out = [];
|
|
89
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
90
|
+
if (entry.name.startsWith('.')) continue;
|
|
91
|
+
const abs = join(dir, entry.name);
|
|
92
|
+
if (entry.isDirectory()) out.push(...collect(abs));
|
|
93
|
+
else if (!EXCLUDED.has(entry.name)) out.push(abs);
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let bundleStat;
|
|
99
|
+
try {
|
|
100
|
+
bundleStat = statSync(bundleDir);
|
|
101
|
+
} catch {
|
|
102
|
+
die(`bundle dir not found: ${bundleDir}`);
|
|
103
|
+
}
|
|
104
|
+
if (!bundleStat.isDirectory()) die(`not a directory: ${bundleDir}`);
|
|
105
|
+
|
|
106
|
+
const absFiles = collect(bundleDir).sort();
|
|
107
|
+
const toPosix = (abs) => relative(bundleDir, abs).split(sep).join('/');
|
|
108
|
+
const files = absFiles.map((abs) => ({ path: toPosix(abs), bytes: readFileSync(abs) }));
|
|
109
|
+
|
|
110
|
+
const skillMd = files.find((f) => f.path === 'SKILL.md');
|
|
111
|
+
if (!skillMd) die('SKILL.md not found at bundle root');
|
|
112
|
+
|
|
113
|
+
// ── parse frontmatter (minimal YAML — flat keys, lists, block scalars) ────
|
|
114
|
+
function parseFrontmatter(text) {
|
|
115
|
+
const m = text.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
116
|
+
if (!m) return { fm: {}, body: text };
|
|
117
|
+
const fm = {};
|
|
118
|
+
let key = null;
|
|
119
|
+
const lines = m[1].split('\n');
|
|
120
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
121
|
+
const rawLine = lines[index];
|
|
122
|
+
const line = rawLine.replace(/\s+$/, '');
|
|
123
|
+
if (!line.trim()) continue;
|
|
124
|
+
const listItem = line.match(/^\s+-\s+(.*)$/);
|
|
125
|
+
if (listItem && key) {
|
|
126
|
+
(Array.isArray(fm[key]) ? fm[key] : (fm[key] = [])).push(stripQuotes(listItem[1]));
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const kv = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
|
|
130
|
+
if (kv) {
|
|
131
|
+
key = kv[1];
|
|
132
|
+
const val = kv[2];
|
|
133
|
+
const block = /^([|>])([+-])?$/.exec(val.trim());
|
|
134
|
+
if (block) {
|
|
135
|
+
const body = [];
|
|
136
|
+
let next = index + 1;
|
|
137
|
+
for (; next < lines.length; next += 1) {
|
|
138
|
+
const candidate = lines[next];
|
|
139
|
+
if (candidate.trim() && !/^\s+/.test(candidate)) break;
|
|
140
|
+
body.push(candidate);
|
|
141
|
+
}
|
|
142
|
+
const indents = body
|
|
143
|
+
.filter((candidate) => candidate.trim())
|
|
144
|
+
.map((candidate) => /^\s*/.exec(candidate)?.[0].length ?? 0);
|
|
145
|
+
const indent = indents.length > 0 ? Math.min(...indents) : 0;
|
|
146
|
+
const unindented = body.map((candidate) => candidate.slice(Math.min(indent, candidate.length)));
|
|
147
|
+
let parsed =
|
|
148
|
+
block[1] === '>'
|
|
149
|
+
? unindented.reduce((out, candidate, bodyIndex) => {
|
|
150
|
+
if (bodyIndex === 0) return candidate;
|
|
151
|
+
const previous = unindented[bodyIndex - 1] ?? '';
|
|
152
|
+
return out + (previous === '' || candidate === '' ? '\n' : ' ') + candidate;
|
|
153
|
+
}, '')
|
|
154
|
+
: unindented.join('\n');
|
|
155
|
+
if (block[2] === '-') parsed = parsed.replace(/\n+$/, '');
|
|
156
|
+
else if (block[2] !== '+') parsed = parsed.replace(/\n*$/, '\n');
|
|
157
|
+
fm[key] = parsed;
|
|
158
|
+
index = next - 1;
|
|
159
|
+
} else if (val === '')
|
|
160
|
+
fm[key] = []; // expect a list or nested block below
|
|
161
|
+
else fm[key] = stripQuotes(val);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return { fm, body: text.slice(m[0].length) };
|
|
165
|
+
}
|
|
166
|
+
const stripQuotes = (s) => s.replace(/^["']|["']$/g, '').trim();
|
|
167
|
+
|
|
168
|
+
const { fm } = parseFrontmatter(skillMd.bytes.toString('utf8'));
|
|
169
|
+
const name = fm.name;
|
|
170
|
+
if (!name || !/^[a-z][a-z0-9-]*$/.test(name)) die(`frontmatter.name invalid or missing: ${name}`);
|
|
171
|
+
if (!fm.description || fm.description === '|' || fm.description === '>') {
|
|
172
|
+
die('frontmatter.description is required');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// category: prefer metadata.category; the nested `metadata:` block isn't parsed
|
|
176
|
+
// by the flat reader, so allow a top-level `category:` too, else default.
|
|
177
|
+
const category = fm.category || 'general';
|
|
178
|
+
const compatibility = Array.isArray(fm.compatibility)
|
|
179
|
+
? fm.compatibility
|
|
180
|
+
: fm.compatibility
|
|
181
|
+
? [fm.compatibility]
|
|
182
|
+
: undefined;
|
|
183
|
+
|
|
184
|
+
// ── build SS-01 manifest (merkle matches src/im/skills/manifest.ts) ──────────
|
|
185
|
+
const sha256 = (buf) => createHash('sha256').update(buf).digest('hex');
|
|
186
|
+
const manifest = files.map((f) => ({
|
|
187
|
+
path: f.path,
|
|
188
|
+
size: f.bytes.byteLength,
|
|
189
|
+
sha256: sha256(f.bytes),
|
|
190
|
+
inline: true,
|
|
191
|
+
content: f.bytes.toString('base64'),
|
|
192
|
+
}));
|
|
193
|
+
const revision = sha256(
|
|
194
|
+
[...manifest]
|
|
195
|
+
.sort((a, b) => a.path.localeCompare(b.path))
|
|
196
|
+
.map((f) => `${f.path}:${f.sha256}`)
|
|
197
|
+
.join('\n'),
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const isMultiFile = files.length > 1;
|
|
201
|
+
const createBody = {
|
|
202
|
+
name,
|
|
203
|
+
description: fm.description,
|
|
204
|
+
category,
|
|
205
|
+
...(fm.license ? { license: fm.license } : {}),
|
|
206
|
+
...(compatibility ? { compatibility } : {}),
|
|
207
|
+
// Single-file → send plain content (server wraps). Multi-file → send manifest.
|
|
208
|
+
content: skillMd.bytes.toString('utf8'),
|
|
209
|
+
...(isMultiFile ? { contentManifest: manifest, contentManifestRevision: revision } : {}),
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
async function api(method, path, body) {
|
|
213
|
+
const res = await fetch(`${BASE}${path}`, {
|
|
214
|
+
method,
|
|
215
|
+
headers: { 'content-type': 'application/json', authorization: `Bearer ${API_KEY}` },
|
|
216
|
+
...(body ? { body: JSON.stringify(body) } : {}),
|
|
217
|
+
});
|
|
218
|
+
let json = null;
|
|
219
|
+
try {
|
|
220
|
+
json = await res.json();
|
|
221
|
+
} catch {
|
|
222
|
+
/* non-JSON */
|
|
223
|
+
}
|
|
224
|
+
return { status: res.status, json };
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
(async () => {
|
|
228
|
+
const created = await api('POST', '/api/im/skills', createBody);
|
|
229
|
+
if (created.status === 409) die(`slug "${name}" already exists (409). Use update or pick a new name.`, 2);
|
|
230
|
+
if (created.status !== 201 || !created.json?.ok) {
|
|
231
|
+
die(`create failed (HTTP ${created.status}): ${created.json?.error || 'unknown error'}`);
|
|
232
|
+
}
|
|
233
|
+
const skill = created.json.data;
|
|
234
|
+
const result = {
|
|
235
|
+
id: skill.id,
|
|
236
|
+
slug: skill.slug,
|
|
237
|
+
rev: revision,
|
|
238
|
+
files: files.length,
|
|
239
|
+
installed: false,
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
if (wantInstall) {
|
|
243
|
+
const path = agentId
|
|
244
|
+
? `/api/im/agents/${encodeURIComponent(agentId)}/skills`
|
|
245
|
+
: `/api/im/skills/${encodeURIComponent(skill.slug)}/install`;
|
|
246
|
+
const body = agentId ? { skillId: skill.slug } : {};
|
|
247
|
+
const inst = await api('POST', path, body);
|
|
248
|
+
if (inst.status >= 200 && inst.status < 300 && inst.json?.ok !== false) {
|
|
249
|
+
result.installed = agentId || true;
|
|
250
|
+
} else {
|
|
251
|
+
result.installError = `HTTP ${inst.status}: ${inst.json?.error || 'install failed'}`;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (asJson) {
|
|
256
|
+
console.log(JSON.stringify(result, null, 2));
|
|
257
|
+
} else {
|
|
258
|
+
console.log(`[skill-builder] ✓ ingested ${result.slug}`);
|
|
259
|
+
console.log(` id: ${result.id}`);
|
|
260
|
+
console.log(` rev: ${result.rev}`);
|
|
261
|
+
console.log(` files: ${result.files}`);
|
|
262
|
+
console.log(` installed: ${result.installed}${result.installError ? ` (${result.installError})` : ''}`);
|
|
263
|
+
console.log(` verify: cloud skill show ${result.slug} --content`);
|
|
264
|
+
}
|
|
265
|
+
})().catch((err) => die(err?.message || String(err)));
|