@raybase/core 0.0.2 → 0.3.3
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/LICENSE +21 -0
- package/dist/.admin-build/AdminApp.css +2 -0
- package/dist/.admin-build/AdminApp.js +77 -0
- package/dist/.admin-docs-build/AdminDocsApp.css +2 -0
- package/dist/.admin-docs-build/AdminDocsApp.js +45 -0
- package/dist/actions.d.ts +347 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +661 -0
- package/dist/actions.js.map +1 -0
- package/dist/admin-assets/admin.7738f50720a8ed7b.css +2 -0
- package/dist/admin-assets/admin.8678cb61db34dc81.js +77 -0
- package/dist/admin-boot.d.ts +94 -0
- package/dist/admin-boot.d.ts.map +1 -0
- package/dist/admin-boot.js +139 -0
- package/dist/admin-boot.js.map +1 -0
- package/dist/admin-docs-content.d.ts +95 -0
- package/dist/admin-docs-content.d.ts.map +1 -0
- package/dist/admin-docs-content.js +463 -0
- package/dist/admin-docs-content.js.map +1 -0
- package/dist/admin-docs-ui.d.ts +11 -0
- package/dist/admin-docs-ui.d.ts.map +1 -0
- package/dist/admin-docs-ui.js +23 -0
- package/dist/admin-docs-ui.js.map +1 -0
- package/dist/admin-kit.d.ts +29 -0
- package/dist/admin-kit.js +1557 -0
- package/dist/admin-role.d.ts +8 -0
- package/dist/admin-role.d.ts.map +1 -0
- package/dist/admin-role.js +22 -0
- package/dist/admin-role.js.map +1 -0
- package/dist/admin-ui.d.ts +3 -0
- package/dist/admin-ui.d.ts.map +1 -0
- package/dist/admin-ui.js +16 -0
- package/dist/admin-ui.js.map +1 -0
- package/dist/agent-ai-chat.d.ts +127 -0
- package/dist/agent-ai-chat.d.ts.map +1 -0
- package/dist/agent-ai-chat.js +5975 -0
- package/dist/agent-ai-chat.js.map +1 -0
- package/dist/agent-chapter-archive.d.ts +214 -0
- package/dist/agent-chapter-archive.d.ts.map +1 -0
- package/dist/agent-chapter-archive.js +696 -0
- package/dist/agent-chapter-archive.js.map +1 -0
- package/dist/agent-chapter-search.d.ts +116 -0
- package/dist/agent-chapter-search.d.ts.map +1 -0
- package/dist/agent-chapter-search.js +605 -0
- package/dist/agent-chapter-search.js.map +1 -0
- package/dist/agent-chapter-tools.d.ts +45 -0
- package/dist/agent-chapter-tools.d.ts.map +1 -0
- package/dist/agent-chapter-tools.js +344 -0
- package/dist/agent-chapter-tools.js.map +1 -0
- package/dist/agent-chapters.d.ts +228 -0
- package/dist/agent-chapters.d.ts.map +1 -0
- package/dist/agent-chapters.js +737 -0
- package/dist/agent-chapters.js.map +1 -0
- package/dist/agent-data-parts.d.ts +167 -0
- package/dist/agent-data-parts.d.ts.map +1 -0
- package/dist/agent-data-parts.js +68 -0
- package/dist/agent-data-parts.js.map +1 -0
- package/dist/agent-errors.d.ts +41 -0
- package/dist/agent-errors.d.ts.map +1 -0
- package/dist/agent-errors.js +191 -0
- package/dist/agent-errors.js.map +1 -0
- package/dist/agent-follow-up-store.d.ts +273 -0
- package/dist/agent-follow-up-store.d.ts.map +1 -0
- package/dist/agent-follow-up-store.js +703 -0
- package/dist/agent-follow-up-store.js.map +1 -0
- package/dist/agent-follow-ups.d.ts +314 -0
- package/dist/agent-follow-ups.d.ts.map +1 -0
- package/dist/agent-follow-ups.js +840 -0
- package/dist/agent-follow-ups.js.map +1 -0
- package/dist/agent-memory.d.ts +323 -0
- package/dist/agent-memory.d.ts.map +1 -0
- package/dist/agent-memory.js +1270 -0
- package/dist/agent-memory.js.map +1 -0
- package/dist/agent-message-parts.d.ts +58 -0
- package/dist/agent-message-parts.d.ts.map +1 -0
- package/dist/agent-message-parts.js +163 -0
- package/dist/agent-message-parts.js.map +1 -0
- package/dist/agent-remote-mcp-credentials.d.ts +154 -0
- package/dist/agent-remote-mcp-credentials.d.ts.map +1 -0
- package/dist/agent-remote-mcp-credentials.js +287 -0
- package/dist/agent-remote-mcp-credentials.js.map +1 -0
- package/dist/agent-remote-mcp-crypto.d.ts +32 -0
- package/dist/agent-remote-mcp-crypto.d.ts.map +1 -0
- package/dist/agent-remote-mcp-crypto.js +101 -0
- package/dist/agent-remote-mcp-crypto.js.map +1 -0
- package/dist/agent-remote-mcp-install.d.ts +299 -0
- package/dist/agent-remote-mcp-install.d.ts.map +1 -0
- package/dist/agent-remote-mcp-install.js +785 -0
- package/dist/agent-remote-mcp-install.js.map +1 -0
- package/dist/agent-remote-mcp-oauth.d.ts +73 -0
- package/dist/agent-remote-mcp-oauth.d.ts.map +1 -0
- package/dist/agent-remote-mcp-oauth.js +344 -0
- package/dist/agent-remote-mcp-oauth.js.map +1 -0
- package/dist/agent-remote-mcp-transport.d.ts +46 -0
- package/dist/agent-remote-mcp-transport.d.ts.map +1 -0
- package/dist/agent-remote-mcp-transport.js +225 -0
- package/dist/agent-remote-mcp-transport.js.map +1 -0
- package/dist/agent-remote-mcp.d.ts +147 -0
- package/dist/agent-remote-mcp.d.ts.map +1 -0
- package/dist/agent-remote-mcp.js +681 -0
- package/dist/agent-remote-mcp.js.map +1 -0
- package/dist/agent-room-redaction.d.ts +66 -0
- package/dist/agent-room-redaction.d.ts.map +1 -0
- package/dist/agent-room-redaction.js +264 -0
- package/dist/agent-room-redaction.js.map +1 -0
- package/dist/agent-rooms.d.ts +209 -0
- package/dist/agent-rooms.d.ts.map +1 -0
- package/dist/agent-rooms.js +244 -0
- package/dist/agent-rooms.js.map +1 -0
- package/dist/agent-runtime.d.ts +541 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +4260 -0
- package/dist/agent-runtime.js.map +1 -0
- package/dist/agent-skill-archive.d.ts +20 -0
- package/dist/agent-skill-archive.d.ts.map +1 -0
- package/dist/agent-skill-archive.js +316 -0
- package/dist/agent-skill-archive.js.map +1 -0
- package/dist/agent-skill-discovery.d.ts +96 -0
- package/dist/agent-skill-discovery.d.ts.map +1 -0
- package/dist/agent-skill-discovery.js +464 -0
- package/dist/agent-skill-discovery.js.map +1 -0
- package/dist/agent-skill-format.d.ts +57 -0
- package/dist/agent-skill-format.d.ts.map +1 -0
- package/dist/agent-skill-format.js +238 -0
- package/dist/agent-skill-format.js.map +1 -0
- package/dist/agent-skill-import.d.ts +64 -0
- package/dist/agent-skill-import.d.ts.map +1 -0
- package/dist/agent-skill-import.js +295 -0
- package/dist/agent-skill-import.js.map +1 -0
- package/dist/agent-skill-publish.d.ts +51 -0
- package/dist/agent-skill-publish.d.ts.map +1 -0
- package/dist/agent-skill-publish.js +136 -0
- package/dist/agent-skill-publish.js.map +1 -0
- package/dist/agent-skill-store.d.ts +252 -0
- package/dist/agent-skill-store.d.ts.map +1 -0
- package/dist/agent-skill-store.js +514 -0
- package/dist/agent-skill-store.js.map +1 -0
- package/dist/agent-skills.d.ts +85 -0
- package/dist/agent-skills.d.ts.map +1 -0
- package/dist/agent-skills.js +291 -0
- package/dist/agent-skills.js.map +1 -0
- package/dist/agent-transcript-pager.d.ts +77 -0
- package/dist/agent-transcript-pager.d.ts.map +1 -0
- package/dist/agent-transcript-pager.js +210 -0
- package/dist/agent-transcript-pager.js.map +1 -0
- package/dist/agent-user-data-parts.d.ts +20 -0
- package/dist/agent-user-data-parts.d.ts.map +1 -0
- package/dist/agent-user-data-parts.js +161 -0
- package/dist/agent-user-data-parts.js.map +1 -0
- package/dist/agent-user-transcript.d.ts +46 -0
- package/dist/agent-user-transcript.d.ts.map +1 -0
- package/dist/agent-user-transcript.js +106 -0
- package/dist/agent-user-transcript.js.map +1 -0
- package/dist/agent-voice-notes.d.ts +15 -0
- package/dist/agent-voice-notes.d.ts.map +1 -0
- package/dist/agent-voice-notes.js +17 -0
- package/dist/agent-voice-notes.js.map +1 -0
- package/dist/agent-wakes.d.ts +213 -0
- package/dist/agent-wakes.d.ts.map +1 -0
- package/dist/agent-wakes.js +534 -0
- package/dist/agent-wakes.js.map +1 -0
- package/dist/agent.d.ts +1780 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +3123 -0
- package/dist/agent.js.map +1 -0
- package/dist/ai.d.ts +583 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +1858 -0
- package/dist/ai.js.map +1 -0
- package/dist/app-manifest.d.ts +255 -0
- package/dist/app-manifest.d.ts.map +1 -0
- package/dist/app-manifest.js +372 -0
- package/dist/app-manifest.js.map +1 -0
- package/dist/app-users.d.ts +30 -0
- package/dist/app-users.d.ts.map +1 -0
- package/dist/app-users.js +91 -0
- package/dist/app-users.js.map +1 -0
- package/dist/audit-archive.d.ts +85 -0
- package/dist/audit-archive.d.ts.map +1 -0
- package/dist/audit-archive.js +178 -0
- package/dist/audit-archive.js.map +1 -0
- package/dist/audit.d.ts +54 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +95 -0
- package/dist/audit.js.map +1 -0
- package/dist/auth-logger.d.ts +28 -0
- package/dist/auth-logger.d.ts.map +1 -0
- package/dist/auth-logger.js +53 -0
- package/dist/auth-logger.js.map +1 -0
- package/dist/auth-password-secret.d.ts +59 -0
- package/dist/auth-password-secret.d.ts.map +1 -0
- package/dist/auth-password-secret.js +409 -0
- package/dist/auth-password-secret.js.map +1 -0
- package/dist/auth-schema.d.ts +120 -0
- package/dist/auth-schema.d.ts.map +1 -0
- package/dist/auth-schema.js +285 -0
- package/dist/auth-schema.js.map +1 -0
- package/dist/auth.d.ts +321 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +1562 -0
- package/dist/auth.js.map +1 -0
- package/dist/backup-archive.d.ts +257 -0
- package/dist/backup-archive.d.ts.map +1 -0
- package/dist/backup-archive.js +2068 -0
- package/dist/backup-archive.js.map +1 -0
- package/dist/backup-crypto.d.ts +313 -0
- package/dist/backup-crypto.d.ts.map +1 -0
- package/dist/backup-crypto.js +693 -0
- package/dist/backup-crypto.js.map +1 -0
- package/dist/backup-format.d.ts +200 -0
- package/dist/backup-format.d.ts.map +1 -0
- package/dist/backup-format.js +1247 -0
- package/dist/backup-format.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -0
- package/dist/clock.d.ts +35 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +83 -0
- package/dist/clock.js.map +1 -0
- package/dist/data-client.d.ts +187 -0
- package/dist/data-client.d.ts.map +1 -0
- package/dist/data-client.js +590 -0
- package/dist/data-client.js.map +1 -0
- package/dist/data-secrets.d.ts +164 -0
- package/dist/data-secrets.d.ts.map +1 -0
- package/dist/data-secrets.js +383 -0
- package/dist/data-secrets.js.map +1 -0
- package/dist/db.d.ts +453 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +324 -0
- package/dist/db.js.map +1 -0
- package/dist/dev-activity.d.ts +48 -0
- package/dist/dev-activity.d.ts.map +1 -0
- package/dist/dev-activity.js +50 -0
- package/dist/dev-activity.js.map +1 -0
- package/dist/do.d.ts +429 -0
- package/dist/do.d.ts.map +1 -0
- package/dist/do.js +4526 -0
- package/dist/do.js.map +1 -0
- package/dist/email.d.ts +137 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +527 -0
- package/dist/email.js.map +1 -0
- package/dist/generated/admin-assets.d.ts +16 -0
- package/dist/generated/admin-assets.d.ts.map +1 -0
- package/dist/generated/admin-assets.js +16 -0
- package/dist/generated/admin-assets.js.map +1 -0
- package/dist/generated/admin-docs-assets.d.ts +3 -0
- package/dist/generated/admin-docs-assets.d.ts.map +1 -0
- package/dist/generated/admin-docs-assets.js +3 -0
- package/dist/generated/admin-docs-assets.js.map +1 -0
- package/dist/handoff-consumer.d.ts +79 -0
- package/dist/handoff-consumer.d.ts.map +1 -0
- package/dist/handoff-consumer.js +300 -0
- package/dist/handoff-consumer.js.map +1 -0
- package/dist/handoff.d.ts +70 -0
- package/dist/handoff.d.ts.map +1 -0
- package/dist/handoff.js +228 -0
- package/dist/handoff.js.map +1 -0
- package/dist/host-auth.d.ts +47 -0
- package/dist/host-auth.d.ts.map +1 -0
- package/dist/host-auth.js +59 -0
- package/dist/host-auth.js.map +1 -0
- package/dist/host-user.d.ts +15 -0
- package/dist/host-user.d.ts.map +1 -0
- package/dist/host-user.js +23 -0
- package/dist/host-user.js.map +1 -0
- package/dist/html.d.ts +35 -0
- package/dist/html.d.ts.map +1 -0
- package/dist/html.js +634 -0
- package/dist/html.js.map +1 -0
- package/dist/http-error.d.ts +13 -0
- package/dist/http-error.d.ts.map +1 -0
- package/dist/http-error.js +15 -0
- package/dist/http-error.js.map +1 -0
- package/dist/imports.d.ts +219 -0
- package/dist/imports.d.ts.map +1 -0
- package/dist/imports.js +571 -0
- package/dist/imports.js.map +1 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/inference-tape.d.ts +64 -0
- package/dist/inference-tape.d.ts.map +1 -0
- package/dist/inference-tape.js +278 -0
- package/dist/inference-tape.js.map +1 -0
- package/dist/internal.d.ts +15 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +48 -0
- package/dist/internal.js.map +1 -0
- package/dist/jobs.d.ts +796 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +538 -0
- package/dist/jobs.js.map +1 -0
- package/dist/json-schema.d.ts +91 -0
- package/dist/json-schema.d.ts.map +1 -0
- package/dist/json-schema.js +884 -0
- package/dist/json-schema.js.map +1 -0
- package/dist/knowledge.d.ts +33 -0
- package/dist/knowledge.d.ts.map +1 -0
- package/dist/knowledge.js +348 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/local-dev-chrome.d.ts +29 -0
- package/dist/local-dev-chrome.d.ts.map +1 -0
- package/dist/local-dev-chrome.js +514 -0
- package/dist/local-dev-chrome.js.map +1 -0
- package/dist/local-dev-personas.d.ts +15 -0
- package/dist/local-dev-personas.d.ts.map +1 -0
- package/dist/local-dev-personas.js +46 -0
- package/dist/local-dev-personas.js.map +1 -0
- package/dist/mcp.d.ts +567 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +2480 -0
- package/dist/mcp.js.map +1 -0
- package/dist/modules.d.ts +145 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +164 -0
- package/dist/modules.js.map +1 -0
- package/dist/notification-client.d.ts +94 -0
- package/dist/notification-client.d.ts.map +1 -0
- package/dist/notification-client.js +127 -0
- package/dist/notification-client.js.map +1 -0
- package/dist/notifications.d.ts +447 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +1625 -0
- package/dist/notifications.js.map +1 -0
- package/dist/operator-data-query.d.ts +117 -0
- package/dist/operator-data-query.d.ts.map +1 -0
- package/dist/operator-data-query.js +431 -0
- package/dist/operator-data-query.js.map +1 -0
- package/dist/operator-mcp.d.ts +63 -0
- package/dist/operator-mcp.d.ts.map +1 -0
- package/dist/operator-mcp.js +2828 -0
- package/dist/operator-mcp.js.map +1 -0
- package/dist/outbound-https.d.ts +24 -0
- package/dist/outbound-https.d.ts.map +1 -0
- package/dist/outbound-https.js +172 -0
- package/dist/outbound-https.js.map +1 -0
- package/dist/pitr.d.ts +60 -0
- package/dist/pitr.d.ts.map +1 -0
- package/dist/pitr.js +94 -0
- package/dist/pitr.js.map +1 -0
- package/dist/platform.d.ts +199 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +196 -0
- package/dist/platform.js.map +1 -0
- package/dist/policies.d.ts +115 -0
- package/dist/policies.d.ts.map +1 -0
- package/dist/policies.js +158 -0
- package/dist/policies.js.map +1 -0
- package/dist/principal.d.ts +143 -0
- package/dist/principal.d.ts.map +1 -0
- package/dist/principal.js +174 -0
- package/dist/principal.js.map +1 -0
- package/dist/realtime.d.ts +280 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +578 -0
- package/dist/realtime.js.map +1 -0
- package/dist/retrieval.d.ts +263 -0
- package/dist/retrieval.d.ts.map +1 -0
- package/dist/retrieval.js +602 -0
- package/dist/retrieval.js.map +1 -0
- package/dist/runtime-error-client.d.ts +10 -0
- package/dist/runtime-error-client.d.ts.map +1 -0
- package/dist/runtime-error-client.js +70 -0
- package/dist/runtime-error-client.js.map +1 -0
- package/dist/runtime-errors.d.ts +180 -0
- package/dist/runtime-errors.d.ts.map +1 -0
- package/dist/runtime-errors.js +572 -0
- package/dist/runtime-errors.js.map +1 -0
- package/dist/schema.d.ts +434 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +232 -0
- package/dist/schema.js.map +1 -0
- package/dist/search.d.ts +216 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +785 -0
- package/dist/search.js.map +1 -0
- package/dist/settings.d.ts +191 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +478 -0
- package/dist/settings.js.map +1 -0
- package/dist/sql.d.ts +7 -0
- package/dist/sql.d.ts.map +1 -0
- package/dist/sql.js +30 -0
- package/dist/sql.js.map +1 -0
- package/dist/storage-client.d.ts +69 -0
- package/dist/storage-client.d.ts.map +1 -0
- package/dist/storage-client.js +469 -0
- package/dist/storage-client.js.map +1 -0
- package/dist/storage.d.ts +21 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +82 -0
- package/dist/storage.js.map +1 -0
- package/dist/subject-domains.d.ts +15 -0
- package/dist/subject-domains.d.ts.map +1 -0
- package/dist/subject-domains.js +38 -0
- package/dist/subject-domains.js.map +1 -0
- package/dist/support.d.ts +132 -0
- package/dist/support.d.ts.map +1 -0
- package/dist/support.js +483 -0
- package/dist/support.js.map +1 -0
- package/dist/system-tables.d.ts +12 -0
- package/dist/system-tables.d.ts.map +1 -0
- package/dist/system-tables.js +225 -0
- package/dist/system-tables.js.map +1 -0
- package/dist/test.d.ts +57 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +454 -0
- package/dist/test.js.map +1 -0
- package/dist/vite.d.ts +82 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +82 -0
- package/dist/vite.js.map +1 -0
- package/dist/webpush-crypto.d.ts +39 -0
- package/dist/webpush-crypto.d.ts.map +1 -0
- package/dist/webpush-crypto.js +213 -0
- package/dist/webpush-crypto.js.map +1 -0
- package/dist/webpush-private.d.ts +11 -0
- package/dist/webpush-private.d.ts.map +1 -0
- package/dist/webpush-private.js +11 -0
- package/dist/webpush-private.js.map +1 -0
- package/dist/webpush.d.ts +86 -0
- package/dist/webpush.d.ts.map +1 -0
- package/dist/webpush.js +375 -0
- package/dist/webpush.js.map +1 -0
- package/dist/worker.d.ts +185 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +13021 -0
- package/dist/worker.js.map +1 -0
- package/package.json +161 -8
- package/README.md +0 -3
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { sha256Hex, stableJson, validateRaybaseName } from "./internal.js";
|
|
2
|
+
export const raybaseAgentSkillFormatLimits = {
|
|
3
|
+
maxNameChars: 64,
|
|
4
|
+
maxDescriptionChars: 1024,
|
|
5
|
+
maxGuidanceBytes: 64_000,
|
|
6
|
+
maxFiles: 64,
|
|
7
|
+
maxFileBytes: 256 * 1024,
|
|
8
|
+
maxTotalFileBytes: 2 * 1024 * 1024
|
|
9
|
+
};
|
|
10
|
+
export class AgentSkillValidationError extends Error {
|
|
11
|
+
code;
|
|
12
|
+
details;
|
|
13
|
+
constructor(code, message, details) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "AgentSkillValidationError";
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.details = details;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function validateOpenAgentSkillName(value) {
|
|
21
|
+
if (typeof value !== "string")
|
|
22
|
+
throw new AgentSkillValidationError("invalid_name", "Skill name must be a string");
|
|
23
|
+
const name = value.trim();
|
|
24
|
+
if (!name || name.length > raybaseAgentSkillFormatLimits.maxNameChars || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) {
|
|
25
|
+
throw new AgentSkillValidationError("invalid_name", "Skill name must be lowercase kebab-case and at most 64 characters");
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
validateRaybaseName("agent", name);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new AgentSkillValidationError("invalid_name", error instanceof Error ? error.message : String(error));
|
|
32
|
+
}
|
|
33
|
+
return name;
|
|
34
|
+
}
|
|
35
|
+
export function normalizeSkillPath(value) {
|
|
36
|
+
if (typeof value !== "string" || !value)
|
|
37
|
+
throw new AgentSkillValidationError("invalid_path", "Skill file path is required");
|
|
38
|
+
if (value.includes("\0") || value.includes("\\") || value.startsWith("/") || value.startsWith("//") || /^[A-Za-z]:/.test(value)) {
|
|
39
|
+
throw new AgentSkillValidationError("invalid_path", `Unsafe skill file path: ${value}`);
|
|
40
|
+
}
|
|
41
|
+
const segments = value.split("/");
|
|
42
|
+
if (segments.some((segment) => !segment || segment === "." || segment === "..")) {
|
|
43
|
+
throw new AgentSkillValidationError("invalid_path", `Unsafe skill file path: ${value}`);
|
|
44
|
+
}
|
|
45
|
+
return segments.join("/");
|
|
46
|
+
}
|
|
47
|
+
export function parseSkillMd(bytes) {
|
|
48
|
+
let text;
|
|
49
|
+
try {
|
|
50
|
+
text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
throw new AgentSkillValidationError("invalid_encoding", "SKILL.md must be valid UTF-8");
|
|
54
|
+
}
|
|
55
|
+
text = text.replace(/^\uFEFF/, "");
|
|
56
|
+
if (!text.startsWith("---\n") && !text.startsWith("---\r\n")) {
|
|
57
|
+
throw new AgentSkillValidationError("frontmatter_required", "SKILL.md must begin with YAML frontmatter");
|
|
58
|
+
}
|
|
59
|
+
const normalized = text.replace(/\r\n/g, "\n");
|
|
60
|
+
const end = normalized.indexOf("\n---\n", 4);
|
|
61
|
+
if (end < 0)
|
|
62
|
+
throw new AgentSkillValidationError("frontmatter_invalid", "SKILL.md frontmatter must end with --- on its own line");
|
|
63
|
+
const source = normalized.slice(4, end);
|
|
64
|
+
const frontmatter = parseFlatYaml(source);
|
|
65
|
+
const name = validateOpenAgentSkillName(frontmatter.name);
|
|
66
|
+
const description = scalarString(frontmatter.description, "description");
|
|
67
|
+
if (description.length > raybaseAgentSkillFormatLimits.maxDescriptionChars) {
|
|
68
|
+
throw new AgentSkillValidationError("description_too_large", `Skill description exceeds ${raybaseAgentSkillFormatLimits.maxDescriptionChars} characters`);
|
|
69
|
+
}
|
|
70
|
+
const guidance = normalized.slice(end + 5).replace(/^\n/, "").trim();
|
|
71
|
+
if (new TextEncoder().encode(guidance).byteLength > raybaseAgentSkillFormatLimits.maxGuidanceBytes) {
|
|
72
|
+
throw new AgentSkillValidationError("guidance_too_large", `Skill guidance exceeds ${raybaseAgentSkillFormatLimits.maxGuidanceBytes} bytes`);
|
|
73
|
+
}
|
|
74
|
+
const title = optionalScalar(frontmatter.title);
|
|
75
|
+
const license = optionalScalar(frontmatter.license);
|
|
76
|
+
const compatibility = optionalScalar(frontmatter.compatibility);
|
|
77
|
+
if (frontmatter.ephemeral !== undefined && typeof frontmatter.ephemeral !== "boolean") {
|
|
78
|
+
throw new AgentSkillValidationError("frontmatter_invalid", "SKILL.md frontmatter ephemeral must be boolean");
|
|
79
|
+
}
|
|
80
|
+
const ephemeral = frontmatter.ephemeral === true;
|
|
81
|
+
const metadata = Object.fromEntries(Object.entries(frontmatter).filter(([key]) => !["name", "title", "description", "license", "compatibility", "ephemeral"].includes(key)));
|
|
82
|
+
return {
|
|
83
|
+
frontmatter,
|
|
84
|
+
name,
|
|
85
|
+
...(title ? { title } : {}),
|
|
86
|
+
description,
|
|
87
|
+
guidance,
|
|
88
|
+
ephemeral,
|
|
89
|
+
...(license ? { license } : {}),
|
|
90
|
+
...(compatibility ? { compatibility } : {}),
|
|
91
|
+
metadataJson: stableJson(metadata)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export async function normalizeSkillPackage(input) {
|
|
95
|
+
if (!Array.isArray(input.files) || input.files.length === 0)
|
|
96
|
+
throw new AgentSkillValidationError("skill_md_missing", "Skill package is empty");
|
|
97
|
+
if (input.files.length > raybaseAgentSkillFormatLimits.maxFiles + 1) {
|
|
98
|
+
throw new AgentSkillValidationError("too_many_files", `Skill package exceeds ${raybaseAgentSkillFormatLimits.maxFiles} supporting files`);
|
|
99
|
+
}
|
|
100
|
+
const seen = new Set();
|
|
101
|
+
const normalizedInputs = input.files.map((file) => {
|
|
102
|
+
const path = normalizeSkillPath(file.path);
|
|
103
|
+
const folded = path.normalize("NFC").toLocaleLowerCase("en-US");
|
|
104
|
+
if (seen.has(folded))
|
|
105
|
+
throw new AgentSkillValidationError("duplicate_path", `Skill package contains duplicate normalized path ${path}`);
|
|
106
|
+
seen.add(folded);
|
|
107
|
+
return { path, bytes: file.bytes };
|
|
108
|
+
});
|
|
109
|
+
const skillMd = normalizedInputs.find((file) => file.path === "SKILL.md");
|
|
110
|
+
if (!skillMd)
|
|
111
|
+
throw new AgentSkillValidationError("skill_md_missing", "Skill package must contain SKILL.md at its root");
|
|
112
|
+
const parsed = parseSkillMd(skillMd.bytes);
|
|
113
|
+
if (input.rootName !== undefined && input.rootName !== parsed.name) {
|
|
114
|
+
throw new AgentSkillValidationError("directory_name_mismatch", `Skill directory ${input.rootName} must equal frontmatter name ${parsed.name}`);
|
|
115
|
+
}
|
|
116
|
+
const guidanceBytes = new TextEncoder().encode(parsed.guidance).byteLength;
|
|
117
|
+
const maxGuidanceBytes = input.maxGuidanceBytes ?? raybaseAgentSkillFormatLimits.maxGuidanceBytes;
|
|
118
|
+
if (guidanceBytes > maxGuidanceBytes)
|
|
119
|
+
throw new AgentSkillValidationError("guidance_too_large", `Skill guidance exceeds ${maxGuidanceBytes} bytes`);
|
|
120
|
+
let totalBytes = 0;
|
|
121
|
+
const files = [];
|
|
122
|
+
for (const file of normalizedInputs.filter((entry) => entry.path !== "SKILL.md").sort((a, b) => bytewise(a.path, b.path))) {
|
|
123
|
+
if (file.bytes.byteLength > raybaseAgentSkillFormatLimits.maxFileBytes) {
|
|
124
|
+
throw new AgentSkillValidationError("file_too_large", `Skill file ${file.path} exceeds ${raybaseAgentSkillFormatLimits.maxFileBytes} bytes`, { path: file.path });
|
|
125
|
+
}
|
|
126
|
+
totalBytes += file.bytes.byteLength;
|
|
127
|
+
if (totalBytes > raybaseAgentSkillFormatLimits.maxTotalFileBytes) {
|
|
128
|
+
throw new AgentSkillValidationError("package_too_large", `Skill supporting files exceed ${raybaseAgentSkillFormatLimits.maxTotalFileBytes} bytes`, { path: file.path });
|
|
129
|
+
}
|
|
130
|
+
const decoded = decodeUtf8(file.bytes);
|
|
131
|
+
files.push({
|
|
132
|
+
path: file.path,
|
|
133
|
+
kind: skillFileKind(file.path),
|
|
134
|
+
encoding: decoded === null ? "base64" : "utf8",
|
|
135
|
+
content: decoded ?? bytesToBase64(file.bytes),
|
|
136
|
+
bytes: file.bytes.byteLength,
|
|
137
|
+
sha256: await sha256Hex(file.bytes)
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const contentDigest = await sha256Hex(stableJson({
|
|
141
|
+
frontmatter: parsed.frontmatter,
|
|
142
|
+
guidance: parsed.guidance,
|
|
143
|
+
files: files.map(({ path, sha256 }) => ({ path, sha256 }))
|
|
144
|
+
}));
|
|
145
|
+
return { ...parsed, files, contentDigest };
|
|
146
|
+
}
|
|
147
|
+
function parseFlatYaml(source) {
|
|
148
|
+
const output = {};
|
|
149
|
+
const lines = source.split("\n");
|
|
150
|
+
let objectKey = null;
|
|
151
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
152
|
+
const raw = lines[index];
|
|
153
|
+
if (!raw.trim() || raw.trimStart().startsWith("#"))
|
|
154
|
+
continue;
|
|
155
|
+
if (/^\s/.test(raw)) {
|
|
156
|
+
if (!objectKey)
|
|
157
|
+
throw new AgentSkillValidationError("frontmatter_invalid", `Unexpected indentation on line ${index + 1}`);
|
|
158
|
+
const match = raw.match(/^\s+([^:#][^:]*):\s*(.*)$/);
|
|
159
|
+
if (!match)
|
|
160
|
+
throw new AgentSkillValidationError("frontmatter_invalid", `Unsupported YAML on line ${index + 1}`);
|
|
161
|
+
const target = output[objectKey];
|
|
162
|
+
target[match[1].trim()] = parseYamlScalar(match[2]);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const match = raw.match(/^([^:#][^:]*):(?:\s*(.*))?$/);
|
|
166
|
+
if (!match)
|
|
167
|
+
throw new AgentSkillValidationError("frontmatter_invalid", `Unsupported YAML on line ${index + 1}`);
|
|
168
|
+
const key = match[1].trim();
|
|
169
|
+
const value = match[2] ?? "";
|
|
170
|
+
if (Object.prototype.hasOwnProperty.call(output, key))
|
|
171
|
+
throw new AgentSkillValidationError("frontmatter_invalid", `Duplicate frontmatter key ${key}`);
|
|
172
|
+
if (!value.trim()) {
|
|
173
|
+
output[key] = {};
|
|
174
|
+
objectKey = key;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
output[key] = parseYamlScalar(value);
|
|
178
|
+
objectKey = null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return output;
|
|
182
|
+
}
|
|
183
|
+
function parseYamlScalar(value) {
|
|
184
|
+
const trimmed = stripYamlComment(value.trim());
|
|
185
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
186
|
+
return trimmed.startsWith('"') ? JSON.parse(trimmed) : trimmed.slice(1, -1).replace(/''/g, "'");
|
|
187
|
+
}
|
|
188
|
+
if (trimmed === "true")
|
|
189
|
+
return true;
|
|
190
|
+
if (trimmed === "false")
|
|
191
|
+
return false;
|
|
192
|
+
if (trimmed === "null" || trimmed === "~")
|
|
193
|
+
return null;
|
|
194
|
+
if (/^-?\d+(?:\.\d+)?$/.test(trimmed))
|
|
195
|
+
return Number(trimmed);
|
|
196
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]"))
|
|
197
|
+
return trimmed.slice(1, -1).split(",").map((item) => parseYamlScalar(item));
|
|
198
|
+
return trimmed;
|
|
199
|
+
}
|
|
200
|
+
function stripYamlComment(value) {
|
|
201
|
+
const index = value.indexOf(" #");
|
|
202
|
+
return index < 0 ? value : value.slice(0, index).trimEnd();
|
|
203
|
+
}
|
|
204
|
+
function scalarString(value, key) {
|
|
205
|
+
if (typeof value !== "string" || !value.trim())
|
|
206
|
+
throw new AgentSkillValidationError("frontmatter_invalid", `SKILL.md frontmatter requires non-empty ${key}`);
|
|
207
|
+
return value.trim();
|
|
208
|
+
}
|
|
209
|
+
function optionalScalar(value) {
|
|
210
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
211
|
+
}
|
|
212
|
+
function skillFileKind(path) {
|
|
213
|
+
const head = path.split("/", 1)[0];
|
|
214
|
+
return head === "references" ? "reference" : head === "assets" ? "asset" : head === "scripts" ? "script" : "other";
|
|
215
|
+
}
|
|
216
|
+
function decodeUtf8(bytes) {
|
|
217
|
+
try {
|
|
218
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function bytesToBase64(bytes) {
|
|
225
|
+
let binary = "";
|
|
226
|
+
for (let offset = 0; offset < bytes.length; offset += 0x8000)
|
|
227
|
+
binary += String.fromCharCode(...bytes.subarray(offset, offset + 0x8000));
|
|
228
|
+
return btoa(binary);
|
|
229
|
+
}
|
|
230
|
+
function bytewise(left, right) {
|
|
231
|
+
const a = new TextEncoder().encode(left);
|
|
232
|
+
const b = new TextEncoder().encode(right);
|
|
233
|
+
for (let index = 0; index < Math.min(a.length, b.length); index += 1)
|
|
234
|
+
if (a[index] !== b[index])
|
|
235
|
+
return a[index] - b[index];
|
|
236
|
+
return a.length - b.length;
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=agent-skill-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-skill-format.js","sourceRoot":"","sources":["../src/agent-skill-format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type AgentSkillDiscoveryResult, type DiscoverAgentSkillsOptions } from "./agent-skill-discovery.js";
|
|
2
|
+
import { type AgentSkillMode } from "./agent-skill-store.js";
|
|
3
|
+
import type { RaybaseAgent } from "./agent.js";
|
|
4
|
+
import type { AgentRuntimeTool } from "./agent-runtime.js";
|
|
5
|
+
import type { RaybaseAgentPrincipal } from "./ai.js";
|
|
6
|
+
import type { SqlExecutor } from "./db.js";
|
|
7
|
+
export type ApplyAgentSkillsOptions = DiscoverAgentSkillsOptions & {
|
|
8
|
+
expectedSourceDigest: string;
|
|
9
|
+
maxSkills?: number;
|
|
10
|
+
conflictPolicy?: "fail" | "replace";
|
|
11
|
+
expectedReplacedRevisions?: Record<string, number>;
|
|
12
|
+
mode?: AgentSkillMode;
|
|
13
|
+
enable?: boolean;
|
|
14
|
+
actorKind: "agent" | "operator" | "sync";
|
|
15
|
+
actor: string;
|
|
16
|
+
ownerKind?: "agent" | "operator" | "sync";
|
|
17
|
+
managedSourceId?: string;
|
|
18
|
+
};
|
|
19
|
+
export type ApplyAgentSkillsResult = {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
applied: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
revision: number;
|
|
24
|
+
created: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
discovery: AgentSkillDiscoveryResult;
|
|
27
|
+
error?: {
|
|
28
|
+
code: string;
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export declare function agentSkillImportRuntimeTools<Env, Schema extends import("./schema.js").RaybaseSchema = import("./schema.js").RaybaseSchema>(input: {
|
|
33
|
+
agent: RaybaseAgent<Env, Schema>;
|
|
34
|
+
principal: RaybaseAgentPrincipal;
|
|
35
|
+
control: SqlExecutor;
|
|
36
|
+
fetcher?: typeof fetch;
|
|
37
|
+
}): AgentRuntimeTool[];
|
|
38
|
+
export declare function applyAgentSkills(options: ApplyAgentSkillsOptions): Promise<ApplyAgentSkillsResult>;
|
|
39
|
+
export declare function refreshAgentSkill(options: {
|
|
40
|
+
control: SqlExecutor;
|
|
41
|
+
agentName: string;
|
|
42
|
+
name: string;
|
|
43
|
+
expectedRevision: number;
|
|
44
|
+
overwriteLocalEdits?: boolean;
|
|
45
|
+
actorKind: "agent" | "operator";
|
|
46
|
+
actor: string;
|
|
47
|
+
fetcher?: typeof fetch;
|
|
48
|
+
}): Promise<ApplyAgentSkillsResult>;
|
|
49
|
+
export declare function syncDueAgentSkillSources(input: {
|
|
50
|
+
control: SqlExecutor;
|
|
51
|
+
fetcher?: typeof fetch;
|
|
52
|
+
env?: unknown;
|
|
53
|
+
now?: string;
|
|
54
|
+
sourceId?: string;
|
|
55
|
+
limit?: number;
|
|
56
|
+
}): Promise<{
|
|
57
|
+
synced: string[];
|
|
58
|
+
failed: Array<{
|
|
59
|
+
sourceId: string;
|
|
60
|
+
error: string;
|
|
61
|
+
}>;
|
|
62
|
+
nextDueAt: string | null;
|
|
63
|
+
}>;
|
|
64
|
+
//# sourceMappingURL=agent-skill-import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-skill-import.d.ts","sourceRoot":"","sources":["../src/agent-skill-import.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { discoverAgentSkills } from "./agent-skill-discovery.js";
|
|
2
|
+
import { findAgentSkill, listAgentSkills, raybaseAgentSkillStoreLimits } from "./agent-skill-store.js";
|
|
3
|
+
import { sweepExpiredAgentSkillUploads } from "./agent-skill-store.js";
|
|
4
|
+
import { recordAudit } from "./audit.js";
|
|
5
|
+
import { fetchOutboundHardened } from "./outbound-https.js";
|
|
6
|
+
import { nowIso, q, randomId } from "./sql.js";
|
|
7
|
+
export function agentSkillImportRuntimeTools(input) {
|
|
8
|
+
if (input.principal.kind === "public")
|
|
9
|
+
return [];
|
|
10
|
+
const actorId = input.principal.user.id;
|
|
11
|
+
const allowed = input.agent.skillStore?.enabled === true ? input.agent.skillStore.agentAccess?.importSources ?? [] : [];
|
|
12
|
+
if (!allowed.length)
|
|
13
|
+
return [];
|
|
14
|
+
const parse = (args) => {
|
|
15
|
+
const record = args && typeof args === "object" && !Array.isArray(args) ? args : {};
|
|
16
|
+
if (!record.source || typeof record.source !== "object")
|
|
17
|
+
throw new Error("source is required");
|
|
18
|
+
const source = { ...record.source };
|
|
19
|
+
if (!allowed.includes(source.kind))
|
|
20
|
+
throw new Error(`Agent source kind ${source.kind} is not granted`);
|
|
21
|
+
if (source.kind === "github")
|
|
22
|
+
source.discovery = "skills";
|
|
23
|
+
const requestedNames = Array.isArray(record.requestedNames) ? record.requestedNames.filter((value) => typeof value === "string") : undefined;
|
|
24
|
+
return { source, requestedNames };
|
|
25
|
+
};
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
name: "skill_import_discover", displayName: "Discover skills", description: `Discover an external skill source without changing state. Allowed kinds: ${allowed.join(", ")}. GitHub is always shallow skills mode.`,
|
|
29
|
+
parameters: { type: "object", properties: { source: { type: "object" }, requestedNames: { type: "array", items: { type: "string" } } }, required: ["source"], additionalProperties: false }, dataChange: null,
|
|
30
|
+
run: async (args) => { const parsed = parse(args); return stripPackages(await discoverAgentSkills({ ...parsed, agentName: input.agent.name, control: input.control, fetcher: input.fetcher, maxGuidanceBytes: input.agent.skillStore?.limits?.maxGuidanceBytes ?? raybaseAgentSkillStoreLimits.maxGuidanceBytes })); }
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "skill_import_apply", displayName: "Apply skills", description: "Atomically import the previously discovered external skills as agent-owned local snapshots.",
|
|
34
|
+
parameters: { type: "object", properties: { source: { type: "object" }, expectedSourceDigest: { type: "string" }, requestedNames: { type: "array", items: { type: "string" } }, conflictPolicy: { type: "string", enum: ["fail", "replace"] }, expectedReplacedRevisions: { type: "object" } }, required: ["source", "expectedSourceDigest"], additionalProperties: false },
|
|
35
|
+
dataChange: { actionName: "skill_import_apply", effects: ["agent-skills"] },
|
|
36
|
+
run: async (args) => { const record = args; const parsed = parse(args); if (typeof record.expectedSourceDigest !== "string")
|
|
37
|
+
throw new Error("expectedSourceDigest is required"); const result = await applyAgentSkills({ ...parsed, agentName: input.agent.name, control: input.control, fetcher: input.fetcher, expectedSourceDigest: record.expectedSourceDigest, conflictPolicy: record.conflictPolicy === "replace" ? "replace" : "fail", expectedReplacedRevisions: record.expectedReplacedRevisions && typeof record.expectedReplacedRevisions === "object" ? record.expectedReplacedRevisions : undefined, actorKind: "agent", actor: actorId, ownerKind: "agent", maxSkills: input.agent.skillStore?.limits?.maxSkills ?? raybaseAgentSkillStoreLimits.maxSkills, maxGuidanceBytes: input.agent.skillStore?.limits?.maxGuidanceBytes ?? raybaseAgentSkillStoreLimits.maxGuidanceBytes }); if (result.ok)
|
|
38
|
+
await recordAudit(input.control, { actor: input.principal, action: "agent.skills.import.apply", target: { type: "_agent_skills", id: result.applied.length === 1 ? result.applied[0].name : null }, metadata: { agentName: input.agent.name, sourceKind: parsed.source.kind, sourceDigest: record.expectedSourceDigest, applied: result.applied.map((item) => ({ name: item.name, revision: item.revision })) } }); return result; }
|
|
39
|
+
}
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
export async function applyAgentSkills(options) {
|
|
43
|
+
if (!options.control)
|
|
44
|
+
throw new Error("Skill apply requires the skill store database");
|
|
45
|
+
const discovery = await discoverAgentSkills(options);
|
|
46
|
+
if (discovery.sourceDigest !== options.expectedSourceDigest)
|
|
47
|
+
return failed("source_changed", "Skill source changed after discovery", discovery);
|
|
48
|
+
if (discovery.status !== "ready")
|
|
49
|
+
return failed("not_ready", "Skill discovery is not ready to apply", discovery);
|
|
50
|
+
const requested = options.requestedNames?.length ? new Set(options.requestedNames) : new Set(discovery.candidates.map((candidate) => candidate.name));
|
|
51
|
+
const selected = discovery.candidates.filter((candidate) => requested.has(candidate.name));
|
|
52
|
+
if (!selected.length || selected.some((candidate) => !candidate.valid || !candidate.package))
|
|
53
|
+
return failed("invalid_selection", "Selected skills are invalid", discovery);
|
|
54
|
+
const existingRows = new Map();
|
|
55
|
+
for (const candidate of selected) {
|
|
56
|
+
const existing = await findAgentSkill(options.control, options.agentName, candidate.name);
|
|
57
|
+
if (!existing)
|
|
58
|
+
continue;
|
|
59
|
+
existingRows.set(candidate.name, existing);
|
|
60
|
+
if (existing.source === "code")
|
|
61
|
+
return failed("skill_conflict", `Code skill ${candidate.name} cannot be replaced`, discovery);
|
|
62
|
+
if (existing.source === "managed" || options.managedSourceId) {
|
|
63
|
+
if (existing.sourceId !== options.managedSourceId)
|
|
64
|
+
return failed("skill_conflict", `Skill ${candidate.name} belongs to a different source`, discovery);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
if (options.conflictPolicy !== "replace")
|
|
68
|
+
return failed("skill_conflict", `Local skill ${candidate.name} requires conflictPolicy replace`, discovery);
|
|
69
|
+
if (options.expectedReplacedRevisions?.[candidate.name] !== existing.revision)
|
|
70
|
+
return failed("stale_revision", `Local skill ${candidate.name} revision changed`, discovery);
|
|
71
|
+
if (options.actorKind === "agent" && (existing.ownerKind !== "agent" || existing.ownerAgentName !== options.agentName))
|
|
72
|
+
return failed("ownership", `Agent cannot replace skill ${candidate.name}`, discovery);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const currentCount = (await listAgentSkills(options.control, options.agentName)).length;
|
|
76
|
+
const maxSkills = options.maxSkills ?? raybaseAgentSkillStoreLimits.maxSkills;
|
|
77
|
+
if (currentCount + selected.filter((candidate) => !existingRows.has(candidate.name)).length > maxSkills)
|
|
78
|
+
return failed("skill_limit", `Agent skill limit of ${maxSkills} would be exceeded`, discovery);
|
|
79
|
+
const statements = [];
|
|
80
|
+
const applied = [];
|
|
81
|
+
const now = nowIso();
|
|
82
|
+
const replacements = [...existingRows.values()];
|
|
83
|
+
const casGuardId = replacements.length ? randomId("skill_cas_guard") : null;
|
|
84
|
+
if (replacements.length)
|
|
85
|
+
statements.push(batchCasGuard(replacements, casGuardId, now));
|
|
86
|
+
for (const candidate of selected) {
|
|
87
|
+
const pkg = candidate.package;
|
|
88
|
+
const existing = existingRows.get(candidate.name);
|
|
89
|
+
const mode = options.mode ?? existing?.mode ?? (pkg.ephemeral ? "include" : "available");
|
|
90
|
+
if (pkg.ephemeral && mode === "available")
|
|
91
|
+
return failed("invalid_durability", `Ephemeral skill ${pkg.name} must use include mode`, discovery);
|
|
92
|
+
if (existing) {
|
|
93
|
+
const unchanged = existing.contentDigest === pkg.contentDigest
|
|
94
|
+
&& existing.mode === mode
|
|
95
|
+
&& existing.ephemeral === (pkg.ephemeral ? 1 : 0)
|
|
96
|
+
&& existing.remoteSha256 === (options.managedSourceId ? candidate.sha256 : existing.remoteSha256);
|
|
97
|
+
if (unchanged) {
|
|
98
|
+
applied.push({ name: candidate.name, revision: existing.revision, created: false });
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
statements.push(revisionInsert(existing, options.managedSourceId ? "sync" : "replace", options.actorKind, options.actor));
|
|
102
|
+
statements.push({ sql: `UPDATE ${q("_agent_skills")} SET "title"=?,"description"=?,"guidance"=?,"mode"=?,"ephemeral"=?,"contentDigest"=?,"lastImportedContentDigest"=?,"license"=?,"compatibility"=?,"metadataJson"=?,"enabled"=?,"revision"=?,"remoteSha256"=?,"syncedAt"=?,"syncStatus"=?,"syncError"=?,"updatedAt"=? WHERE "id"=? AND "revision"=?`, params: [
|
|
103
|
+
pkg.title ?? null, pkg.description, pkg.guidance, mode, pkg.ephemeral ? 1 : 0, pkg.contentDigest, existing.source === "local" ? pkg.contentDigest : null,
|
|
104
|
+
pkg.license ?? null, pkg.compatibility ?? null, pkg.metadataJson, options.managedSourceId ? existing.enabled : options.enable === false ? 0 : existing.enabled,
|
|
105
|
+
existing.revision + 1, options.managedSourceId ? candidate.sha256 : existing.remoteSha256, options.managedSourceId ? now : existing.syncedAt,
|
|
106
|
+
options.managedSourceId ? "ok" : existing.syncStatus, null, now, existing.id, existing.revision
|
|
107
|
+
] });
|
|
108
|
+
statements.push({ sql: `DELETE FROM ${q("_agent_skill_files")} WHERE "skillId"=?`, params: [existing.id] });
|
|
109
|
+
statements.push(...fileInserts(existing.id, pkg.files, now));
|
|
110
|
+
applied.push({ name: candidate.name, revision: existing.revision + 1, created: false });
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
const id = randomId("skill");
|
|
114
|
+
const sourceClass = options.managedSourceId ? "managed" : "local";
|
|
115
|
+
const provenance = candidate.provenance ?? {};
|
|
116
|
+
statements.push({ sql: `INSERT INTO ${q("_agent_skills")} ("id","agentName","normalizedName","name","title","description","guidance","mode","ephemeral","contentDigest","lastImportedContentDigest","license","compatibility","metadataJson","enabled","revision","source","ownerKind","ownerAgentName","createdBy","originKind","originUrl","originRef","originRefKind","originCommit","originRepo","originManifestPath","originSkillPath","originDigest","importedAt","sourceId","remoteSha256","syncedAt","syncStatus","syncError","createdAt","updatedAt") VALUES (${Array.from({ length: 37 }, () => "?").join(",")})`, params: [
|
|
117
|
+
id, options.agentName, normalizeName(pkg.name), pkg.name, pkg.title ?? null, pkg.description, pkg.guidance, mode, pkg.ephemeral ? 1 : 0, pkg.contentDigest,
|
|
118
|
+
sourceClass === "local" ? pkg.contentDigest : null, pkg.license ?? null, pkg.compatibility ?? null, pkg.metadataJson, options.enable === false ? 0 : 1, 1,
|
|
119
|
+
sourceClass, options.ownerKind ?? (options.actorKind === "agent" ? "agent" : options.managedSourceId ? "sync" : "operator"), options.actorKind === "agent" ? options.agentName : null,
|
|
120
|
+
options.actor, originKind(options.source, Boolean(options.managedSourceId)), originUrl(options.source), options.source.kind === "github" ? options.source.ref ?? null : null,
|
|
121
|
+
discovery.github?.refKind ?? null, discovery.resolvedCommit ?? null, provenance.originRepo ?? discovery.github?.repo ?? null,
|
|
122
|
+
provenance.originManifestPath ?? discovery.github?.manifestPath ?? null, provenance.originSkillPath ?? candidate.path ?? null,
|
|
123
|
+
candidate.sha256, now, options.managedSourceId ?? null, options.managedSourceId ? candidate.sha256 : null, options.managedSourceId ? now : null,
|
|
124
|
+
options.managedSourceId ? "ok" : null, null, now, now
|
|
125
|
+
] });
|
|
126
|
+
statements.push(...fileInserts(id, pkg.files, now));
|
|
127
|
+
applied.push({ name: candidate.name, revision: 1, created: true });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (casGuardId)
|
|
131
|
+
statements.push({ sql: `DELETE FROM ${q("_agent_skill_revisions")} WHERE "id"=?`, params: [casGuardId] });
|
|
132
|
+
for (const existing of existingRows.values())
|
|
133
|
+
statements.push({ sql: `DELETE FROM ${q("_agent_skill_revisions")} WHERE "skillId"=? AND "id" NOT IN (SELECT "id" FROM ${q("_agent_skill_revisions")} WHERE "skillId"=? ORDER BY "createdAt" DESC LIMIT 3)`, params: [existing.id, existing.id] });
|
|
134
|
+
try {
|
|
135
|
+
if (options.control.runTransaction)
|
|
136
|
+
await options.control.runTransaction(statements);
|
|
137
|
+
else if (statements.length <= 1)
|
|
138
|
+
for (const statement of statements)
|
|
139
|
+
await options.control.run(statement.sql, statement.params);
|
|
140
|
+
else
|
|
141
|
+
throw new Error("Skill apply requires atomic transaction support");
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
for (const existing of replacements) {
|
|
145
|
+
const current = await findAgentSkill(options.control, options.agentName, existing.name);
|
|
146
|
+
if (!current || current.revision !== existing.revision)
|
|
147
|
+
return failed("stale_revision", `Skill ${existing.name} revision changed`, discovery);
|
|
148
|
+
}
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
return { ok: true, applied, discovery };
|
|
152
|
+
}
|
|
153
|
+
export async function refreshAgentSkill(options) {
|
|
154
|
+
const row = await findAgentSkill(options.control, options.agentName, options.name);
|
|
155
|
+
if (!row)
|
|
156
|
+
throw new Error(`Skill ${options.name} not found`);
|
|
157
|
+
if (row.source !== "local" || !row.originUrl && row.originKind !== "github")
|
|
158
|
+
return failed("source_changed", "Skill has no refreshable origin", emptyDiscovery("direct-url"));
|
|
159
|
+
if (row.revision !== options.expectedRevision)
|
|
160
|
+
return failed("stale_revision", "Skill revision changed", emptyDiscovery("direct-url"));
|
|
161
|
+
if (row.lastImportedContentDigest && row.contentDigest !== row.lastImportedContentDigest && !options.overwriteLocalEdits)
|
|
162
|
+
return failed("local_modifications", "Skill has local modifications; pass overwriteLocalEdits with matching revision", emptyDiscovery("direct-url"));
|
|
163
|
+
let source;
|
|
164
|
+
if (row.originKind === "github" && row.originRepo)
|
|
165
|
+
source = { kind: "github", repo: row.originRepo, ...(row.originRef ? { ref: row.originRef } : {}), ...(row.originSkillPath ? { path: row.originSkillPath } : {}), discovery: "skills" };
|
|
166
|
+
else
|
|
167
|
+
source = { kind: "direct-url", url: row.originUrl };
|
|
168
|
+
const discovery = await discoverAgentSkills({ control: options.control, agentName: options.agentName, source, requestedNames: [row.name], fetcher: options.fetcher });
|
|
169
|
+
const candidate = discovery.candidates.find((item) => item.name === row.name && item.path === (row.originSkillPath ?? item.path));
|
|
170
|
+
if (!candidate)
|
|
171
|
+
return failed("source_changed", "Original skill path/name is missing, moved, renamed, or duplicated", discovery);
|
|
172
|
+
return applyAgentSkills({ control: options.control, agentName: options.agentName, source, requestedNames: [row.name], fetcher: options.fetcher, expectedSourceDigest: discovery.sourceDigest, conflictPolicy: "replace", expectedReplacedRevisions: { [row.name]: row.revision }, actorKind: options.actorKind, actor: options.actor, ownerKind: row.ownerKind === "agent" ? "agent" : "operator" });
|
|
173
|
+
}
|
|
174
|
+
export async function syncDueAgentSkillSources(input) {
|
|
175
|
+
const now = input.now ?? nowIso();
|
|
176
|
+
await sweepExpiredAgentSkillUploads(input.control, now);
|
|
177
|
+
const rows = input.sourceId
|
|
178
|
+
? await input.control.all(`SELECT * FROM "_agent_skill_sources" WHERE "id"=? AND "enabled"=1`, [input.sourceId])
|
|
179
|
+
: await input.control.all(`SELECT * FROM "_agent_skill_sources" WHERE "enabled"=1 AND ("lastSyncAt" IS NULL OR (julianday(?) - julianday("lastSyncAt")) * 86400000 >= "syncEveryMs") ORDER BY COALESCE("lastSyncAt",'') LIMIT ?`, [now, Math.max(1, Math.min(20, input.limit ?? 5))]);
|
|
180
|
+
const synced = [];
|
|
181
|
+
const failed = [];
|
|
182
|
+
for (const row of rows) {
|
|
183
|
+
try {
|
|
184
|
+
if (row.sourceType === "github" && row.refKind === "commit" && row.lastSyncAt) {
|
|
185
|
+
await input.control.run(`UPDATE "_agent_skill_sources" SET "lastSyncAt"=?,"lastSyncStatus"='ok',"lastSyncError"=NULL WHERE "id"=?`, [now, row.id]);
|
|
186
|
+
synced.push(row.id);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const allowedArtifactOrigins = JSON.parse(row.allowedArtifactOriginsJson || "[]");
|
|
190
|
+
const artifactAuth = JSON.parse(row.artifactAuthJson || "[]");
|
|
191
|
+
const source = row.sourceType === "github"
|
|
192
|
+
? { kind: "github", repo: row.repo, ...(row.requestedRef ? { ref: row.requestedRef } : {}), ...(row.manifestPath ? { manifestPath: row.manifestPath } : {}), discovery: "manifest" }
|
|
193
|
+
: { kind: "manifest-url", url: row.url, allowedOrigins: allowedArtifactOrigins };
|
|
194
|
+
const selectedNames = row.selectionMode === "named" ? JSON.parse(row.selectedNamesJson || "[]") : undefined;
|
|
195
|
+
let etag = row.etag;
|
|
196
|
+
if (row.sourceType === "http-index") {
|
|
197
|
+
const headers = new Headers(row.etag ? { "if-none-match": row.etag } : undefined);
|
|
198
|
+
const credential = namedBearerCredential(row.authSecretName, input.env);
|
|
199
|
+
if (credential)
|
|
200
|
+
headers.set("authorization", credential);
|
|
201
|
+
const probe = await fetchOutboundHardened(row.url, { fetcher: input.fetcher, allowedOrigins: [new URL(row.url).origin, ...allowedArtifactOrigins], allowedContentTypes: ["application/json", "application/octet-stream"], headers });
|
|
202
|
+
if (probe.response.status === 304) {
|
|
203
|
+
await input.control.run(`UPDATE "_agent_skill_sources" SET "lastSyncAt"=?,"lastSyncStatus"='ok',"lastSyncError"=NULL,"updatedAt"=? WHERE "id"=?`, [now, now, row.id]);
|
|
204
|
+
synced.push(row.id);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (!probe.response.ok)
|
|
208
|
+
throw new Error(`Skill index returned HTTP ${probe.response.status}`);
|
|
209
|
+
etag = probe.response.headers.get("etag");
|
|
210
|
+
}
|
|
211
|
+
const discoveryOptions = { agentName: row.agentName, source, control: input.control, fetcher: input.fetcher, env: input.env, indexAuthSecretName: row.authSecretName ?? undefined, artifactAuth };
|
|
212
|
+
let discovery = await discoverAgentSkills({ ...discoveryOptions, requestedNames: selectedNames });
|
|
213
|
+
let effectiveNames = selectedNames;
|
|
214
|
+
if (row.selectionMode === "all") {
|
|
215
|
+
effectiveNames = discovery.candidates.filter((candidate) => candidate.valid).map((candidate) => candidate.name);
|
|
216
|
+
if (effectiveNames.length)
|
|
217
|
+
discovery = await discoverAgentSkills({ ...discoveryOptions, requestedNames: effectiveNames });
|
|
218
|
+
}
|
|
219
|
+
else if (discovery.invalidRequestedNames.length) {
|
|
220
|
+
effectiveNames = selectedNames?.filter((name) => !discovery.invalidRequestedNames.includes(name));
|
|
221
|
+
if (effectiveNames?.length)
|
|
222
|
+
discovery = await discoverAgentSkills({ ...discoveryOptions, requestedNames: effectiveNames });
|
|
223
|
+
}
|
|
224
|
+
if (!effectiveNames?.length)
|
|
225
|
+
discovery = { ...discovery, status: "ready" };
|
|
226
|
+
if (discovery.status !== "ready")
|
|
227
|
+
throw new Error(discovery.error?.message ?? `Discovery returned ${discovery.status}`);
|
|
228
|
+
if (row.sourceType === "github" && row.resolvedCommit === discovery.resolvedCommit) {
|
|
229
|
+
await input.control.run(`UPDATE "_agent_skill_sources" SET "lastSyncAt"=?,"lastSyncStatus"='ok',"lastSyncError"=NULL WHERE "id"=?`, [now, row.id]);
|
|
230
|
+
synced.push(row.id);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const statements = [];
|
|
234
|
+
const transactionControl = { all: input.control.all.bind(input.control), first: input.control.first.bind(input.control), run: input.control.run.bind(input.control), runTransaction: async (batch) => { statements.push(...batch); } };
|
|
235
|
+
const result = effectiveNames?.length ? await applyAgentSkills({ ...discoveryOptions, requestedNames: effectiveNames, expectedSourceDigest: discovery.sourceDigest, control: transactionControl, actorKind: "sync", actor: `source:${row.id}`, managedSourceId: row.id }) : { ok: true, applied: [], discovery };
|
|
236
|
+
if (!result.ok)
|
|
237
|
+
throw new Error(result.error?.message ?? "Managed sync apply failed");
|
|
238
|
+
const seen = new Set(result.discovery.candidates.filter((candidate) => effectiveNames?.includes(candidate.name)).map((candidate) => candidate.name.normalize("NFC").toLowerCase()));
|
|
239
|
+
const managed = (await listAgentSkills(input.control, row.agentName)).filter((skill) => skill.sourceId === row.id);
|
|
240
|
+
const orphaned = managed.filter((skill) => !seen.has(skill.normalizedName));
|
|
241
|
+
// Sync reads the managed set before it starts its transaction. Guard every
|
|
242
|
+
// soon-to-be orphaned row so a concurrent local mutation aborts the whole
|
|
243
|
+
// sync instead of silently disabling the newer version.
|
|
244
|
+
const orphanCasGuardId = orphaned.length ? randomId("skill_cas_guard") : null;
|
|
245
|
+
if (orphanCasGuardId)
|
|
246
|
+
statements.push(batchCasGuard(orphaned, orphanCasGuardId, now));
|
|
247
|
+
for (const skill of orphaned) {
|
|
248
|
+
statements.push(revisionInsert(skill, "orphan", "sync", `source:${row.id}`));
|
|
249
|
+
statements.push({ sql: `UPDATE "_agent_skills" SET "enabled"=0,"syncStatus"='orphaned',"syncError"=NULL,"revision"=?,"updatedAt"=? WHERE "id"=? AND "revision"=?`, params: [skill.revision + 1, now, skill.id, skill.revision] });
|
|
250
|
+
}
|
|
251
|
+
// This is a transaction-local assertion, not user-facing history.
|
|
252
|
+
// Remove it after all revision-qualified orphan updates have succeeded.
|
|
253
|
+
if (orphanCasGuardId)
|
|
254
|
+
statements.push({ sql: `DELETE FROM ${q("_agent_skill_revisions")} WHERE "id"=?`, params: [orphanCasGuardId] });
|
|
255
|
+
statements.push({ sql: `UPDATE "_agent_skill_sources" SET "etag"=?,"resolvedCommit"=?,"defaultBranch"=?,"repo"=?,"lastSyncAt"=?,"lastSyncStatus"='ok',"lastSyncError"=NULL,"lastSyncSummaryJson"=?,"updatedAt"=? WHERE "id"=?`, params: [etag, discovery.resolvedCommit ?? row.resolvedCommit, discovery.github?.defaultBranch ?? row.defaultBranch, discovery.github?.repo ?? row.repo, now, JSON.stringify({ changed: result.applied.map((item) => item.name), orphaned: orphaned.map((skill) => skill.name) }), now, row.id] });
|
|
256
|
+
if (!input.control.runTransaction)
|
|
257
|
+
throw new Error("Managed source sync requires transaction support");
|
|
258
|
+
await input.control.runTransaction(statements);
|
|
259
|
+
synced.push(row.id);
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
const message = error instanceof Error ? error.message.slice(0, 2000) : String(error).slice(0, 2000);
|
|
263
|
+
await input.control.run(`UPDATE "_agent_skill_sources" SET "lastSyncAt"=?,"lastSyncStatus"='error',"lastSyncError"=?,"updatedAt"=? WHERE "id"=?`, [now, message, now, row.id]);
|
|
264
|
+
failed.push({ sourceId: row.id, error: message });
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const due = await input.control.first(`SELECT MIN(datetime(COALESCE("lastSyncAt","createdAt"), '+' || CAST("syncEveryMs" / 1000 AS INTEGER) || ' seconds')) AS "nextDueAt" FROM "_agent_skill_sources" WHERE "enabled"=1`);
|
|
268
|
+
return { synced, failed, nextDueAt: due?.nextDueAt ?? null };
|
|
269
|
+
}
|
|
270
|
+
function revisionInsert(row, reason, actorKind, actor) { return { sql: `INSERT INTO ${q("_agent_skill_revisions")} ("id","skillId","revision","title","description","guidance","mode","ephemeral","enabled","contentDigest","reason","actorKind","actor","createdAt") SELECT ?,"id","revision","title","description","guidance","mode","ephemeral","enabled","contentDigest",?,?,?,? FROM ${q("_agent_skills")} WHERE "id"=? AND "revision"=?`, params: [randomId("skill_rev"), reason, actorKind, actor, nowIso(), row.id, row.revision] }; }
|
|
271
|
+
function batchCasGuard(rows, guardId, now) {
|
|
272
|
+
const predicates = rows.map(() => '("id"=? AND "revision"=?)').join(" OR ");
|
|
273
|
+
const params = [];
|
|
274
|
+
for (const row of rows)
|
|
275
|
+
params.push(row.id, row.revision);
|
|
276
|
+
const first = rows[0];
|
|
277
|
+
// The guard must *abort* when any observed row is stale. A conditional id
|
|
278
|
+
// is not enough because SQLite permits NULL in a non-INTEGER PRIMARY KEY.
|
|
279
|
+
// `description` is a required column, making the stale branch a constraint
|
|
280
|
+
// violation and preserving all-or-nothing replacement semantics.
|
|
281
|
+
return { sql: `INSERT INTO ${q("_agent_skill_revisions")} ("id","skillId","revision","title","description","guidance","mode","ephemeral","enabled","contentDigest","reason","actorKind","actor","createdAt") SELECT ?,?,?,?,CASE WHEN (SELECT COUNT(*) FROM ${q("_agent_skills")} WHERE ${predicates})=? THEN ? ELSE NULL END,?,?,?,?,?,?,?,?,?`, params: [guardId, first.id, 0, null, ...params, rows.length, "", "", "available", 0, 0, "", "cas_guard", "system", null, now] };
|
|
282
|
+
}
|
|
283
|
+
function fileInserts(skillId, files, createdAt) { return files.map((file) => ({ sql: `INSERT INTO ${q("_agent_skill_files")} ("id","skillId","path","normalizedPath","kind","encoding","content","bytes","sha256","createdAt") VALUES (?,?,?,?,?,?,?,?,?,?)`, params: [randomId("skill_file"), skillId, file.path, normalizeName(file.path), file.kind, file.encoding, file.content, file.bytes, file.sha256, createdAt] })); }
|
|
284
|
+
function normalizeName(value) { return value.normalize("NFC").toLocaleLowerCase("en-US"); }
|
|
285
|
+
function originKind(source, managed) { if (managed)
|
|
286
|
+
return "managed-sync"; return source.kind === "github" ? "github" : source.kind === "upload" || source.kind === "upload-inline" ? "upload" : "direct-url"; }
|
|
287
|
+
function originUrl(source) { return "url" in source ? source.url : null; }
|
|
288
|
+
function failed(code, message, discovery) { return { ok: false, applied: [], discovery, error: { code, message } }; }
|
|
289
|
+
function emptyDiscovery(kind) { return { status: "invalid", sourceKind: kind, sourceDigest: "", classification: "unmanaged-scan", candidates: [], totalCandidates: 0, truncated: false, invalidRequestedNames: [], warnings: [] }; }
|
|
290
|
+
function stripPackages(result) { return { ...result, candidates: result.candidates.map(({ package: _package, ...candidate }) => candidate) }; }
|
|
291
|
+
function namedBearerCredential(secretName, env) { if (!secretName)
|
|
292
|
+
return undefined; if (!/^[A-Z][A-Z0-9_]*$/.test(secretName))
|
|
293
|
+
throw new Error(`Credential secret name ${secretName} is invalid`); const value = env && typeof env === "object" ? env[secretName] : undefined; if (typeof value !== "string" || !value.trim())
|
|
294
|
+
throw new Error(`Credential secret ${secretName} is not configured`); return `Bearer ${value.trim()}`; }
|
|
295
|
+
//# sourceMappingURL=agent-skill-import.js.map
|