@skaile/workspaces 1.15.1 → 2.0.0
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 +271 -0
- package/dist/{asset-feeds-MWEMXMZA.js → asset-feeds-7VQVISDI.js} +25 -24
- package/dist/asset-feeds-7VQVISDI.js.map +1 -0
- package/dist/asset-manager/catalog-deployer.js +13 -1
- package/dist/asset-manager/index.js +10 -9
- package/dist/asset-manager/installer.js +7 -6
- package/dist/asset-manager/src/catalog-deployer.d.ts +70 -5
- package/dist/asset-manager/src/catalog-deployer.d.ts.map +1 -1
- package/dist/asset-manager/src/index.d.ts +22 -17
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +108 -56
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +3 -2
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +4 -3
- package/dist/bridge/drivers/continue.js.map +1 -1
- package/dist/bridge/drivers/echo.js +3 -2
- package/dist/bridge/drivers/echo.js.map +1 -1
- package/dist/bridge/drivers/gemini.js +5 -4
- package/dist/bridge/drivers/goose.js +4 -3
- package/dist/bridge/drivers/goose.js.map +1 -1
- package/dist/bridge/drivers/omp.js +3 -2
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +4 -3
- package/dist/bridge/drivers/opencode.js.map +1 -1
- package/dist/bridge/drivers/qwen.js +5 -4
- package/dist/bridge/drivers/qwen.js.map +1 -1
- package/dist/bridge/index.js +4 -3
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/scrub-transcript.d.ts +21 -1
- package/dist/bridge/src/drivers/scrub-transcript.d.ts.map +1 -1
- package/dist/{chunk-344DEXZS.js → chunk-35ELAMQ5.js} +4 -4
- package/dist/{chunk-344DEXZS.js.map → chunk-35ELAMQ5.js.map} +1 -1
- package/dist/{chunk-73HV7RV3.js → chunk-6FJH63NN.js} +4 -4
- package/dist/{chunk-73HV7RV3.js.map → chunk-6FJH63NN.js.map} +1 -1
- package/dist/{chunk-ISA7R7PK.js → chunk-72EOJJOM.js} +82 -38
- package/dist/chunk-72EOJJOM.js.map +1 -0
- package/dist/chunk-7GOCNYUV.js +300 -0
- package/dist/chunk-7GOCNYUV.js.map +1 -0
- package/dist/{chunk-TFIFNDT2.js → chunk-A5OYCQGT.js} +4 -4
- package/dist/{chunk-TFIFNDT2.js.map → chunk-A5OYCQGT.js.map} +1 -1
- package/dist/{chunk-KY5NY7LB.js → chunk-BCTU4TN7.js} +11 -11
- package/dist/chunk-BCTU4TN7.js.map +1 -0
- package/dist/chunk-BEAIJRVF.js +159 -0
- package/dist/chunk-BEAIJRVF.js.map +1 -0
- package/dist/chunk-BK3WL3QK.js +10 -0
- package/dist/chunk-BK3WL3QK.js.map +1 -0
- package/dist/{chunk-BI2NKPA4.js → chunk-CA5CWLGN.js} +3 -2
- package/dist/chunk-CA5CWLGN.js.map +1 -0
- package/dist/{chunk-2TSSCHCQ.js → chunk-CKVIN4H3.js} +5 -5
- package/dist/{chunk-2TSSCHCQ.js.map → chunk-CKVIN4H3.js.map} +1 -1
- package/dist/{chunk-GXC3TYMQ.js → chunk-CZZRDYT4.js} +70 -32
- package/dist/chunk-CZZRDYT4.js.map +1 -0
- package/dist/{chunk-MNKUZUN2.js → chunk-DRXDEL3A.js} +3 -3
- package/dist/{chunk-MNKUZUN2.js.map → chunk-DRXDEL3A.js.map} +1 -1
- package/dist/{chunk-Z6NGK5YC.js → chunk-DY2AK577.js} +3 -3
- package/dist/{chunk-Z6NGK5YC.js.map → chunk-DY2AK577.js.map} +1 -1
- package/dist/chunk-DYMWJAL4.js +552 -0
- package/dist/chunk-DYMWJAL4.js.map +1 -0
- package/dist/{chunk-ACXLKNIM.js → chunk-E7HKNQTH.js} +10 -4
- package/dist/chunk-E7HKNQTH.js.map +1 -0
- package/dist/{chunk-O5VCUU6D.js → chunk-KUZEIKZH.js} +4 -4
- package/dist/{chunk-O5VCUU6D.js.map → chunk-KUZEIKZH.js.map} +1 -1
- package/dist/{chunk-RADBQ5XJ.js → chunk-KYLWY3A7.js} +10 -10
- package/dist/{chunk-RADBQ5XJ.js.map → chunk-KYLWY3A7.js.map} +1 -1
- package/dist/{chunk-2BQBWWFX.js → chunk-LBZP2IYG.js} +6 -6
- package/dist/chunk-LBZP2IYG.js.map +1 -0
- package/dist/{chunk-MZV6WCF3.js → chunk-MAN7AGQJ.js} +3 -3
- package/dist/{chunk-MZV6WCF3.js.map → chunk-MAN7AGQJ.js.map} +1 -1
- package/dist/{chunk-7J7LQP6T.js → chunk-MMD2KQ3A.js} +31 -19
- package/dist/chunk-MMD2KQ3A.js.map +1 -0
- package/dist/{chunk-NRXVS7E4.js → chunk-NYCJ7B27.js} +19 -11
- package/dist/chunk-NYCJ7B27.js.map +1 -0
- package/dist/{chunk-ACWCVB5Q.js → chunk-ORZW7MMO.js} +3 -3
- package/dist/{chunk-ACWCVB5Q.js.map → chunk-ORZW7MMO.js.map} +1 -1
- package/dist/{chunk-M5GJT3D7.js → chunk-OYX22NJL.js} +3 -3
- package/dist/{chunk-M5GJT3D7.js.map → chunk-OYX22NJL.js.map} +1 -1
- package/dist/{chunk-MJEUK6VJ.js → chunk-QIQTYN7F.js} +3 -3
- package/dist/{chunk-MJEUK6VJ.js.map → chunk-QIQTYN7F.js.map} +1 -1
- package/dist/{chunk-2IJFUAZB.js → chunk-RK3HU3H3.js} +123 -18
- package/dist/chunk-RK3HU3H3.js.map +1 -0
- package/dist/{chunk-5NZ56R63.js → chunk-ST3DLLNZ.js} +18 -6
- package/dist/chunk-ST3DLLNZ.js.map +1 -0
- package/dist/{chunk-MTM6C7IS.js → chunk-SVL4EZJT.js} +463 -251
- package/dist/chunk-SVL4EZJT.js.map +1 -0
- package/dist/{chunk-JB35MVBN.js → chunk-U5POE4BA.js} +4 -298
- package/dist/chunk-U5POE4BA.js.map +1 -0
- package/dist/{chunk-DB264AVQ.js → chunk-UAQVFATZ.js} +8 -8
- package/dist/{chunk-DB264AVQ.js.map → chunk-UAQVFATZ.js.map} +1 -1
- package/dist/{chunk-DPUZJI45.js → chunk-UVW3R6S7.js} +72 -37
- package/dist/chunk-UVW3R6S7.js.map +1 -0
- package/dist/{chunk-STQOPWPS.js → chunk-VCU4NPUS.js} +4 -4
- package/dist/{chunk-STQOPWPS.js.map → chunk-VCU4NPUS.js.map} +1 -1
- package/dist/{chunk-MB6563TL.js → chunk-WCWXDW22.js} +3 -3
- package/dist/{chunk-MB6563TL.js.map → chunk-WCWXDW22.js.map} +1 -1
- package/dist/{chunk-EKGB4ZWR.js → chunk-WZPADAE7.js} +255 -136
- package/dist/chunk-WZPADAE7.js.map +1 -0
- package/dist/{chunk-SRWIVMJI.js → chunk-Y3JVBJ3Y.js} +5 -5
- package/dist/{chunk-SRWIVMJI.js.map → chunk-Y3JVBJ3Y.js.map} +1 -1
- package/dist/{chunk-3EBFDMZC.js → chunk-Y662DNQQ.js} +14 -3
- package/dist/chunk-Y662DNQQ.js.map +1 -0
- package/dist/cli/index.js +348 -128
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/asset-feeds.d.ts +2 -2
- package/dist/cli/src/asset-feeds.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +51 -2
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/connector.d.ts +1 -1
- package/dist/cli/src/commands/connector.d.ts.map +1 -1
- package/dist/cli/src/commands/logs.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +30 -3
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +5 -2
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/connectors/config.js +7 -6
- package/dist/connectors/index.js +9 -8
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/connector-prompt.d.ts.map +1 -1
- package/dist/connectors/src/watcher.d.ts.map +1 -1
- package/dist/connectors/src/worktree.d.ts +20 -2
- package/dist/connectors/src/worktree.d.ts.map +1 -1
- package/dist/core/index.js +6 -5
- package/dist/core/logging.js +2 -1
- package/dist/core/manifest.js +2 -1
- package/dist/core/runtime-assets.js +4 -3
- package/dist/core/src/fs-deadline.d.ts +84 -0
- package/dist/core/src/fs-deadline.d.ts.map +1 -0
- package/dist/core/src/index.d.ts +4 -3
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +142 -18
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts +2 -2
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/runtime-assets.d.ts.map +1 -1
- package/dist/core/src/subprocess.d.ts +33 -1
- package/dist/core/src/subprocess.d.ts.map +1 -1
- package/dist/core/src/walker.d.ts +1 -1
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +9 -2
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/workspace-config.js +3 -2
- package/dist/deploy/index.js +12 -7
- package/dist/deploy/index.js.map +1 -1
- package/dist/deploy/src/targets/container-runtime.d.ts.map +1 -1
- package/dist/discovery/index.js +3 -2
- package/dist/{ensure-sources-QGL44IRI.js → ensure-sources-JLVHHZI2.js} +13 -12
- package/dist/ensure-sources-JLVHHZI2.js.map +1 -0
- package/dist/factory-assets/connectors/box.js +9 -8
- package/dist/factory-assets/connectors/deploy/CONNECTOR.md +19 -0
- package/dist/factory-assets/connectors/deploy/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/deploy.js +9 -8
- package/dist/factory-assets/connectors/devserver/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/devserver.js +9 -8
- package/dist/factory-assets/connectors/flow/CONNECTOR.md +3 -1
- package/dist/factory-assets/connectors/flow/adapter.d.ts +2 -1
- package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/adapter.js +9 -8
- package/dist/factory-assets/connectors/flow/engine.js +6 -5
- package/dist/factory-assets/connectors/flow/prompt-fragments.d.ts +9 -2
- package/dist/factory-assets/connectors/flow/prompt-fragments.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/prompt-fragments.js +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +11 -10
- package/dist/factory-assets/connectors/flow.js +9 -8
- package/dist/factory-assets/connectors/git/driver.d.ts +12 -1
- package/dist/factory-assets/connectors/git/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/git.js +9 -8
- package/dist/factory-assets/connectors/gmail.js +9 -8
- package/dist/factory-assets/connectors/googledrive.js +9 -8
- package/dist/factory-assets/connectors/local/driver.d.ts +25 -1
- package/dist/factory-assets/connectors/local/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/local.js +9 -8
- package/dist/factory-assets/connectors/mattermost.js +9 -8
- package/dist/factory-assets/connectors/memory.js +9 -8
- package/dist/factory-assets/connectors/minio.js +9 -8
- package/dist/factory-assets/connectors/postgres.js +9 -8
- package/dist/factory-assets/connectors/s3/driver.d.ts +15 -0
- package/dist/factory-assets/connectors/s3/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/s3.js +9 -8
- package/dist/factory-assets/connectors/sharepoint.js +9 -8
- package/dist/factory-assets/connectors/sqlite/adapter.d.ts +8 -1
- package/dist/factory-assets/connectors/sqlite/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/sqlite.js +9 -8
- package/dist/factory-assets/connectors/static-server/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/static-server.js +9 -8
- package/dist/factory-assets/connectors/tunnel.js +9 -8
- package/dist/factory-assets/connectors/webdav.js +9 -8
- package/dist/factory-assets/connectors/xstate/adapter.d.ts +6 -0
- package/dist/factory-assets/connectors/xstate/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/xstate-store.js +9 -8
- package/dist/factory-assets/connectors/xstate.js +9 -8
- package/dist/flows-LV5WYJ2I.js +20 -0
- package/dist/{flows-FHWBCLXF.js.map → flows-LV5WYJ2I.js.map} +1 -1
- package/dist/{helpers-FMWODXTW.js → helpers-PJ3CPUUL.js} +13 -12
- package/dist/{helpers-FMWODXTW.js.map → helpers-PJ3CPUUL.js.map} +1 -1
- package/dist/library/index.js +8 -7
- package/dist/library/install.js +6 -5
- package/dist/{library-publish-7YDHQGBN.js → library-publish-HVZRCE3C.js} +16 -15
- package/dist/library-publish-HVZRCE3C.js.map +1 -0
- package/dist/{open-library-O6T3ELPK.js → open-library-RMI2FTQ4.js} +14 -13
- package/dist/{open-library-O6T3ELPK.js.map → open-library-RMI2FTQ4.js.map} +1 -1
- package/dist/{paths-5QJJBAND.js → paths-JSVTQAVW.js} +11 -10
- package/dist/{paths-5QJJBAND.js.map → paths-JSVTQAVW.js.map} +1 -1
- package/dist/plugin-registry/src/deploy-helpers.d.ts +1 -1
- package/dist/{plugin-store-ZBJZ7F6D.js → plugin-store-7TVJB2TS.js} +8 -7
- package/dist/plugin-store-7TVJB2TS.js.map +1 -0
- package/dist/{project-HAMLHLD5.js → project-P636MSYT.js} +14 -13
- package/dist/{project-HAMLHLD5.js.map → project-P636MSYT.js.map} +1 -1
- package/dist/resolver/index.js +13 -1
- package/dist/resolver/src/types.d.ts +7 -0
- package/dist/resolver/src/types.d.ts.map +1 -1
- package/dist/resolver/src/validator.d.ts +8 -1
- package/dist/resolver/src/validator.d.ts.map +1 -1
- package/dist/runner/index.js +14 -13
- package/dist/runner/src/external-mcp.d.ts +1 -1
- package/dist/runner/src/external-mcp.d.ts.map +1 -1
- package/dist/runner/src/mcp-prompt.d.ts +7 -3
- package/dist/runner/src/mcp-prompt.d.ts.map +1 -1
- package/dist/runner/src/mcp-runtime-handlers.d.ts +12 -0
- package/dist/runner/src/mcp-runtime-handlers.d.ts.map +1 -1
- package/dist/runner/src/mixin-resolver.d.ts.map +1 -1
- package/dist/runner/src/recipe-resolver.d.ts +20 -6
- package/dist/runner/src/recipe-resolver.d.ts.map +1 -1
- package/dist/runner/src/resource-handler.d.ts +43 -0
- package/dist/runner/src/resource-handler.d.ts.map +1 -1
- package/dist/runner/src/resources.d.ts +12 -5
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts +5 -5
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts +9 -0
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/runner/src/session-capability-wiring.d.ts +5 -0
- package/dist/runner/src/session-capability-wiring.d.ts.map +1 -1
- package/dist/runner/src/workspace-migration.d.ts +37 -3
- package/dist/runner/src/workspace-migration.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +10 -9
- package/dist/sdk/bridge.js +4 -3
- package/dist/sdk/core.js +6 -5
- package/dist/sdk/flow.js +6 -5
- package/dist/sdk/index.js +14 -13
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +13 -1
- package/dist/sdk/runner.js +14 -13
- package/dist/sdk/session.js +1 -1
- package/dist/sdk/store.js +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/{setup-WJPNUE32.js → setup-OYW3W3XK.js} +10 -9
- package/dist/setup-OYW3W3XK.js.map +1 -0
- package/dist/skills-QY5PHBD3.js +20 -0
- package/dist/{skills-BMI6H7HI.js.map → skills-QY5PHBD3.js.map} +1 -1
- package/dist/{source-ITDH4367.js → source-63CHWDC2.js} +15 -14
- package/dist/{source-ITDH4367.js.map → source-63CHWDC2.js.map} +1 -1
- package/dist/{source-manifest-publish-RMHC7R6M.js → source-manifest-publish-DLASGDK5.js} +17 -16
- package/dist/source-manifest-publish-DLASGDK5.js.map +1 -0
- package/dist/store/index.js +1 -1
- package/dist/store/src/store.d.ts +9 -0
- package/dist/store/src/store.d.ts.map +1 -1
- package/dist/tui/index.js +14 -13
- package/dist/tui/index.js.map +1 -1
- package/dist/validator-RN64BKFW.js +5 -0
- package/dist/{validator-VF5M764T.js.map → validator-RN64BKFW.js.map} +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +18 -5
- package/dist/workspace-plugin/adapters/mcp.js.map +1 -1
- package/dist/workspace-plugin/adapters/omp.js +10 -10
- package/dist/workspace-plugin/index.js +3 -2
- package/dist/workspace-plugin/src/tools/validator.d.ts.map +1 -1
- package/dist/workspace-plugin/src/utils/ai-assets.d.ts +11 -6
- package/dist/workspace-plugin/src/utils/ai-assets.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/asset-feeds-MWEMXMZA.js.map +0 -1
- package/dist/chunk-2BQBWWFX.js.map +0 -1
- package/dist/chunk-2IJFUAZB.js.map +0 -1
- package/dist/chunk-3EBFDMZC.js.map +0 -1
- package/dist/chunk-5NZ56R63.js.map +0 -1
- package/dist/chunk-7J7LQP6T.js.map +0 -1
- package/dist/chunk-ACXLKNIM.js.map +0 -1
- package/dist/chunk-BI2NKPA4.js.map +0 -1
- package/dist/chunk-BQCGFPHW.js +0 -345
- package/dist/chunk-BQCGFPHW.js.map +0 -1
- package/dist/chunk-DPUZJI45.js.map +0 -1
- package/dist/chunk-EKGB4ZWR.js.map +0 -1
- package/dist/chunk-GXC3TYMQ.js.map +0 -1
- package/dist/chunk-ISA7R7PK.js.map +0 -1
- package/dist/chunk-JB35MVBN.js.map +0 -1
- package/dist/chunk-KY5NY7LB.js.map +0 -1
- package/dist/chunk-LV2HPH3C.js +0 -73
- package/dist/chunk-LV2HPH3C.js.map +0 -1
- package/dist/chunk-MTM6C7IS.js.map +0 -1
- package/dist/chunk-NRXVS7E4.js.map +0 -1
- package/dist/chunk-XCBG2KDC.js +0 -23
- package/dist/chunk-XCBG2KDC.js.map +0 -1
- package/dist/ensure-sources-QGL44IRI.js.map +0 -1
- package/dist/flows-FHWBCLXF.js +0 -7
- package/dist/library-publish-7YDHQGBN.js.map +0 -1
- package/dist/plugin-store-ZBJZ7F6D.js.map +0 -1
- package/dist/setup-WJPNUE32.js.map +0 -1
- package/dist/skills-BMI6H7HI.js +0 -7
- package/dist/source-manifest-publish-RMHC7R6M.js.map +0 -1
- package/dist/validator-VF5M764T.js +0 -5
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../session/src/dispatcher.ts","../session/src/mentions.ts"],"names":[],"mappings":"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","file":"chunk-BI2NKPA4.js","sourcesContent":["import type { AgentClient } from \"@skaile/workspaces/client\";\nimport type {\n AgentCommand,\n AgentEvent,\n ConnectorRequestCommand,\n ConnectorResponseEvent,\n Mention,\n ReplyRef,\n} from \"@skaile/workspaces/types\";\nimport type { Message, MessageStore, SubscriberInfo, SubscriberTransport } from \"./types.js\";\n\n/**\n * Construction options for {@link SessionDispatcher}.\n *\n * All three infrastructure objects (`client`, `store`, `transport`) are\n * injected by the caller so the dispatcher remains testable and framework-agnostic.\n *\n * @docLink packages/session/api-reference#session-dispatcher\n */\nexport interface SessionDispatcherOptions {\n /** Unique identifier for the session this dispatcher manages. */\n sessionId: string;\n /** Connected agent client used to send commands and receive events. */\n client: AgentClient;\n /** Persistence layer for all non-transient messages. */\n store: MessageStore;\n /** Fan-out transport for broadcasting events to connected frontends. */\n transport: SubscriberTransport;\n /**\n * When true, the dispatcher prepends conversation history to every prompt\n * command sent to the agent. Enable for agents without native session\n * continuity (e.g. mock mode). Agents with native multi-turn support\n * (Claude SDK, OMP) should set this to false to avoid duplicate context.\n * Default: false.\n */\n injectConversationHistory?: boolean;\n /** Max conversation history messages to include in enriched prompts (default: 50). */\n historyLimit?: number;\n /**\n * Optional callback to transform prompt text before forwarding to the agent.\n * The original (untransformed) prompt is persisted and broadcast to subscribers.\n * Applied after conversation history enrichment. Use this to inject context\n * (e.g. UI state) that the agent should see but subscribers should not.\n */\n transformPrompt?: (prompt: string, senderId: string | undefined, replyTo?: ReplyRef) => string;\n}\n\n/**\n * Command and event types classified as transient RPC — high-frequency,\n * ephemeral, and not part of the conversation history.\n *\n * Matching payloads are forwarded and broadcast but never persisted\n * or assigned a sequence number, preventing bloat in the message log.\n */\nconst TRANSIENT_TYPES = new Set([\n \"resource_request\",\n \"resource_response\",\n \"resources_available\",\n \"commands_available\",\n \"state_changed\",\n \"typing\",\n \"user_message\",\n // OMP session tracking — forwarded to subscribers but not persisted\n \"session_info\",\n // Structured log forwarding — high-volume; persisted in per-session SQLite, not the message store\n \"log_entry\",\n // Generic connector dispatch — system RPC, not chat messages.\n // Replaces the 6 typed flow commands removed in Protocol 2.2 (Phase 4 of the\n // flow-connector extraction). `connector_mutate` against the `flow` connector\n // is now how hosts drive flow execution between turns.\n \"connector_mutate\",\n \"connector_query\",\n \"connector_query_response\",\n // Mandatory, not cosmetic: `shouldPersist` is a pure denylist with no escape\n // hatch, so an unlisted ack is stored as a chat Message and flushes the\n // in-flight streaming-text buffer, splitting the assistant's bubble mid-turn.\n \"connector_mutate_response\",\n]);\n\n/**\n * Bridges a single agent session between an {@link AgentClient} and one or more\n * frontend subscribers.\n *\n * Responsibilities:\n * - Persists every non-transient command and event as a {@link Message} with a\n * monotonic sequence number via the injected {@link MessageStore}.\n * - Fans agent events out to all connected frontends via the injected\n * {@link SubscriberTransport}.\n * - Optionally enriches prompt commands with conversation history so agents\n * without native multi-turn support maintain context across turns.\n *\n * **Lifecycle:** call {@link init} before any other method, and {@link disconnect}\n * when the session ends.\n *\n * @example\n * ```ts\n * const dispatcher = new SessionDispatcher({\n * sessionId: 'sess-123',\n * client: agentClient,\n * store: prismaMessageStore,\n * transport: trpcTransport,\n * })\n * await dispatcher.init()\n * const history = await dispatcher.subscribe('ws-conn-abc', { limit: 50 })\n * const msg = await dispatcher.sendCommand({ type: 'prompt', prompt: 'Hello' }, 'user-42')\n * await dispatcher.disconnect()\n * ```\n *\n * @docLink packages/session/api-reference#session-dispatcher\n */\nexport class SessionDispatcher {\n /** The session identifier this dispatcher is bound to. */\n readonly sessionId: string;\n private client: AgentClient;\n private store: MessageStore;\n private transport: SubscriberTransport;\n private subscribers: Set<string> = new Set();\n private subscriberMeta: Map<string, SubscriberInfo> = new Map();\n private seq: number = 0;\n private _availableResources: { mounts: unknown[]; connectors: unknown[] } = {\n mounts: [],\n connectors: [],\n };\n\n /** Whether to inject conversation history into prompt commands. */\n private readonly injectConversationHistory: boolean;\n /** Maximum number of history messages to include in enriched prompts. */\n private readonly historyLimit: number;\n /** Optional prompt transformer applied before forwarding (after persistence). */\n private _transformPrompt?: (\n prompt: string,\n senderId: string | undefined,\n replyTo?: ReplyRef,\n ) => string;\n /** Whether the dispatcher is currently in compaction mode. */\n private _compacting = false;\n /** Accumulated text content during compaction. */\n private _compactionText = \"\";\n\n /**\n * One-shot waiters registered via {@link onceNextFinished}. Each is invoked\n * exactly once with the text of the next `finished` assistant event, then\n * the list is cleared. Backs the A2A router's synchronous `ask` answer\n * capture.\n */\n private nextFinishedWaiters: Array<(text: string) => void> = [];\n /**\n * Text streamed by the agent since the last `finished` event. Used as the\n * fallback answer text for {@link onceNextFinished} when a `finished` event\n * carries an empty `summary` (drivers that stream `text` chunks and leave\n * the summary blank).\n */\n private _turnText = \"\";\n\n /**\n * @param opts - Dispatcher configuration — see {@link SessionDispatcherOptions}.\n */\n constructor(opts: SessionDispatcherOptions) {\n this.sessionId = opts.sessionId;\n this.client = opts.client;\n this.store = opts.store;\n this.transport = opts.transport;\n this.injectConversationHistory = opts.injectConversationHistory ?? false;\n this.historyLimit = opts.historyLimit ?? 50;\n this._transformPrompt = opts.transformPrompt;\n }\n\n /**\n * Replace the prompt transformer at runtime.\n *\n * Useful when additional context (e.g. a UI state cache) becomes available\n * after the dispatcher is constructed but before the first prompt is sent.\n */\n set transformPrompt(fn:\n | ((prompt: string, senderId: string | undefined, replyTo?: ReplyRef) => string)\n | undefined,) {\n this._transformPrompt = fn;\n }\n\n /**\n * Initialize the dispatcher for this session.\n *\n * Restores the monotonic sequence counter from the store and wires up the\n * agent event listener. Must be called once before any other method.\n *\n * @throws If {@link MessageStore.getLatestSeq} rejects.\n */\n async init(): Promise<void> {\n this.seq = await this.store.getLatestSeq(this.sessionId);\n this.client.onEvent((event: AgentEvent) => {\n void this.handleAgentEvent(event);\n });\n }\n\n /**\n * Register a frontend subscriber and return recent message history.\n *\n * Subsequent agent events are pushed to this subscriber via the\n * {@link SubscriberTransport} until {@link unsubscribe} is called.\n *\n * @param subscriberId - Opaque connection ID (e.g. WebSocket session ID).\n * @param opts - Optional subscription options.\n * @param opts.limit - Number of recent messages to return (default: 50).\n * @returns Recent messages ordered by seq ascending.\n */\n async subscribe(\n subscriberId: string,\n opts?: { limit?: number; userId?: string; roles?: string[] },\n ): Promise<Message[]> {\n this.subscribers.add(subscriberId);\n if (opts?.userId !== undefined || opts?.roles !== undefined) {\n this.subscriberMeta.set(subscriberId, {\n userId: opts.userId,\n roles: opts.roles,\n });\n }\n return this.store.getMessages(this.sessionId, {\n limit: opts?.limit ?? 50,\n });\n }\n\n /**\n * Remove a frontend subscriber and release transport resources.\n *\n * @param subscriberId - The ID passed to {@link subscribe}.\n */\n unsubscribe(subscriberId: string): void {\n this.subscribers.delete(subscriberId);\n this.subscriberMeta.delete(subscriberId);\n this.transport.remove(subscriberId);\n }\n\n /**\n * Send a command from a frontend to the agent.\n *\n * Persistent commands are wrapped in a Message envelope and stored before\n * forwarding. Transient commands (resource RPC) are forwarded directly\n * without persistence — returns null in that case.\n *\n * For `prompt` commands, the original message is persisted, but an enriched\n * version (with conversation history prepended) is sent to the agent so it\n * maintains context across turns.\n *\n * @param command - The command to dispatch to the agent (a prompt or tool result).\n * @param senderId - ID of the user sending the command, if known.\n * @param mentions - Resolved mention objects extracted from the prompt text.\n * @param visibility - Optional platform visibility envelope (F-23). When\n * `visibilityMode` is `HumansOnly`, or `Private` without the `\"__agent__\"`\n * sentinel in `privateRecipientIds` (B-30), the message is persisted and\n * broadcast to subscribers but NOT forwarded to the agent.\n * @param outgoingPrefix - Optional text prepended to the outgoing command's\n * user-text field ({@link command.prompt} / `command.answer` /\n * `command.content`) AFTER persistence but BEFORE history enrichment and\n * {@link transformPrompt}. The persisted {@link Message} envelope is built\n * from the original `command` and never sees the prefix. Use this to\n * inject one-shot wake-time context (Option B1 pending restoration\n * prompt) that the agent must see but UI subscribers must not.\n * @returns The persisted Message envelope, or null for transient command types.\n */\n async sendCommand(\n command: AgentCommand,\n senderId?: string,\n mentions?: Mention[],\n visibility?: NonNullable<Message[\"visibility\"]>,\n outgoingPrefix?: string,\n ): Promise<Message | null> {\n if (!this.shouldPersist(command)) {\n this.client.send(command);\n return null;\n }\n // Persist the original command (unenriched/untransformed/un-prefixed).\n // `outgoingPrefix` is intentionally NOT applied here — it must only\n // reach the agent client, never the MessageStore.\n const message = this.createMessage(command, senderId);\n // @TODO: Code-Review: v1 back-compat — mentions field no longer used by Protocol v2+ persistence layers; remove once platform PrismaMessageStore is migrated\n if (mentions?.length) message.mentions = mentions;\n // F-23: platform-extension visibility metadata (3.2.0). The platform\n // MessageStore reads this off the envelope and writes the\n // Message.visibilityMode column + recipient rows atomically with\n // the message itself — no post-send patch, no race window where a\n // concurrent send could mis-tag the wrong message id.\n if (visibility) message.visibility = visibility;\n await this.store.append(message);\n\n // Build the outgoing command — enrich and transform prompt commands\n // while leaving the persisted message untouched.\n let outgoing: AgentCommand = command;\n if (command.type === \"prompt\") {\n let prompt = command.prompt;\n // Restoration prefix lands FIRST (innermost) so the user's typed\n // text remains adjacent to its own framing, with history and reply\n // preambles wrapping the combined block from the outside in.\n if (outgoingPrefix) {\n prompt = `${outgoingPrefix}${prompt}`;\n }\n if (this.injectConversationHistory) {\n prompt = await this.enrichPromptWithHistory(prompt);\n }\n if (this._transformPrompt) {\n prompt = this._transformPrompt(prompt, senderId, command.replyTo);\n }\n if (prompt !== command.prompt) {\n outgoing = { ...command, prompt };\n }\n } else if (outgoingPrefix && command.type === \"reply\") {\n // `reply` carries user text in `answer`. Prefix is invisible to\n // subscribers (who see the persisted Message.payload.answer) but\n // visible to the agent driver.\n outgoing = { ...command, answer: `${outgoingPrefix}${command.answer}` };\n } else if (outgoingPrefix && command.type === \"custom_message\") {\n // `custom_message` carries user text in `content`. Same persist/send\n // split as the `reply` branch above.\n outgoing = { ...command, content: `${outgoingPrefix}${command.content}` };\n }\n\n // F-23 P3 review (B1) — HumansOnly visibility means the message is\n // intended for human recipients only; the agent must NOT see the\n // prompt content. Persist + broadcast (humans read it via\n // SubscriberTransport) but skip the agent forward. This closes a\n // critical privacy hole where `@user: secret` was persisted with\n // visibilityMode='HumansOnly' yet still reached the LLM. Threads\n // starting HumansOnly stay agent-invisible even on Public follow-ups\n // (parent-thread visibility threading is intentionally out of scope\n // for v1; only the immediate message is gated). See\n // platform/_concept/plans/f-23-p3-review-blockers.md.\n if (visibility?.visibilityMode === \"HumansOnly\") {\n return message;\n }\n\n // B-30 — Private visibility (F-23 `@mention_` underscore suffix) means the\n // message is addressed to an explicit recipient set. The agent is only a\n // recipient when the sender wrote `@agent_`, which the platform encodes as\n // the `\"__agent__\"` sentinel in `privateRecipientIds`. When the sentinel is\n // absent the message is a private human-to-human exchange: persist +\n // broadcast (the named human recipients read it via SubscriberTransport)\n // but skip the agent forward so the LLM never sees private content.\n if (\n visibility?.visibilityMode === \"Private\" &&\n !visibility.privateRecipientIds?.includes(\"__agent__\")\n ) {\n return message;\n }\n\n this.client.send(outgoing);\n return message;\n }\n\n /**\n * Persist a synthetic event (not received from the agent) and broadcast it.\n *\n * Used by the platform to inject events like a partial-text `finished` record\n * before a cancel command.\n *\n * @param event - The agent event to persist.\n * @param mentions - Resolved mentions from the originating command.\n */\n async persistEvent(event: AgentEvent, mentions?: Mention[]): Promise<Message | null> {\n return this.handleAgentEvent(event, mentions);\n }\n\n /**\n * Load paginated message history for this session.\n *\n * @param opts.before - Return messages with seq strictly less than this value.\n * @param opts.limit - Maximum number of messages to return.\n */\n async getMessages(opts?: { before?: number; limit?: number }): Promise<Message[]> {\n return this.store.getMessages(this.sessionId, opts);\n }\n\n /**\n * Available mounts and connectors captured from the most recent\n * `resources_available` event emitted by the agent on connect.\n *\n * Empty until the agent emits the event or {@link seedResources} is called.\n */\n get availableResources(): { mounts: unknown[]; connectors: unknown[] } {\n return this._availableResources;\n }\n\n /**\n * Seed the available resources from an external cache.\n *\n * This is needed when the dispatcher is created after the agent has already\n * emitted `resources_available` on WebSocket connect. Without seeding, the\n * dispatcher would report an empty resource list until the next reconnect.\n *\n * @param resources - Resource handles to register before the session starts.\n */\n seedResources(resources: { mounts: unknown[]; connectors: unknown[] }): void {\n const empty =\n this._availableResources.mounts.length === 0 &&\n this._availableResources.connectors.length === 0;\n if (empty && (resources.mounts.length > 0 || resources.connectors.length > 0)) {\n this._availableResources = resources;\n }\n }\n\n /**\n * Deliver a prompt to the agent that triggers a turn but is NOT persisted.\n *\n * Unlike {@link sendCommand}, this never touches the {@link MessageStore}:\n * the prompt is forwarded straight to the agent client. The caller owns\n * persistence of whatever conversation rows should represent this turn.\n *\n * Used by the platform's A2A router to deliver a `from-peer` prompt to a\n * target session: the router writes the authoritative A2A `Message` rows\n * itself, so persisting the framed prompt here too would create an extra,\n * un-attributed plain `prompt` row. The dispatcher's job for this prompt is\n * delivery only.\n *\n * The agent still produces a normal turn, so an A2A `ask` round-trip can\n * capture the answer via {@link onceNextFinished}.\n *\n * @param prompt - The fully-formed prompt text to deliver to the agent.\n */\n deliverPrompt(prompt: string): void {\n this.client.send({ type: \"prompt\", prompt });\n }\n\n /**\n * Send a resource request and await the correlated response.\n *\n * This is a convenience method for request/response resource RPC.\n * The request is transient (not persisted). A one-shot event listener\n * waits for the matching `resource_response` by `requestId`.\n *\n * @param command - A ConnectorRequestCommand (caller must set requestId).\n * @param timeoutMs - How long to wait before rejecting (default: 30s).\n */\n async requestResource(\n command: ConnectorRequestCommand,\n timeoutMs = 30_000,\n ): Promise<ConnectorResponseEvent> {\n return new Promise<ConnectorResponseEvent>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.client.offEvent(handler);\n reject(\n new Error(\n `Resource request timed out after ${timeoutMs}ms: ${command.operation} ${command.connectorId}`,\n ),\n );\n }, timeoutMs);\n\n const handler = (event: AgentEvent) => {\n if (event.type === \"resource_response\" && event.requestId === command.requestId) {\n clearTimeout(timer);\n this.client.offEvent(handler);\n resolve(event);\n }\n };\n\n this.client.onEvent(handler);\n this.client.send(command);\n });\n }\n\n /**\n * Broadcast a transient event to all subscribers without persisting it.\n *\n * Used for ephemeral signals like typing indicators or user-command\n * echoes that other subscribers need to see in real time.\n */\n broadcast(event: AgentEvent): void {\n for (const subscriberId of this.subscribers) {\n this.transport.send(subscriberId, event);\n }\n }\n\n /** Disconnect the agent client and clean up all subscribers. */\n async disconnect(): Promise<void> {\n for (const id of this.subscribers) {\n this.transport.remove(id);\n }\n this.subscribers.clear();\n this.subscriberMeta.clear();\n // Clear any pending A2A waiters so they don't leak if the session\n // disconnects before the target ever emits a `finished` event.\n this.nextFinishedWaiters = [];\n await this.client.dispose();\n }\n\n /**\n * Enter compaction mode. While active, events from the agent are captured\n * but NOT persisted. Text content is accumulated for the snapshot.\n */\n beginCompaction(): void {\n this._compacting = true;\n this._compactionText = \"\";\n }\n\n /**\n * Exit compaction mode and return the accumulated text.\n * The caller is responsible for creating and emitting the snapshot event.\n */\n endCompaction(): string {\n this._compacting = false;\n const text = this._compactionText;\n this._compactionText = \"\";\n return text;\n }\n\n /** Whether the dispatcher is currently in compaction mode. */\n get isCompacting(): boolean {\n return this._compacting;\n }\n\n /**\n * Register a one-shot callback fired with the text of this session's next\n * finished assistant turn. Returns an unsubscribe function.\n *\n * Semantics:\n * - The callback fires **at most once** — on the first `finished` event\n * observed after registration. Later finished turns do not re-fire it.\n * - A waiter registered after a `finished` event waits for the *following*\n * one. The hook captures the *next* finished turn, not a past one.\n * - The answer text is the `finished` event's `summary`; when that is\n * empty (drivers that stream `text` and leave the summary blank), the\n * text accumulated since the previous finished turn is used instead.\n * - Calling the returned function removes the waiter; if it has already\n * fired this is a no-op.\n *\n * Used by the platform's A2A router (`A2ARouterService.ask`) to capture a\n * peer session's answer to a `from-peer` question. v1 captures the first\n * finished turn after delivery — see the busy-target notes in the A2A\n * design spec for the known turn-matching limitation.\n *\n * @param cb - Invoked once with the next finished turn's text.\n * @returns Unsubscribe function that removes this waiter.\n */\n onceNextFinished(cb: (text: string) => void): () => void {\n this.nextFinishedWaiters.push(cb);\n return () => {\n const idx = this.nextFinishedWaiters.indexOf(cb);\n if (idx !== -1) {\n this.nextFinishedWaiters.splice(idx, 1);\n }\n };\n }\n\n // -- Private ----------------------------------------------------------------\n\n /**\n * Build an enriched prompt by prepending conversation history.\n *\n * Loads recent persisted messages, formats user/assistant turns, and\n * wraps them in a `<conversation_history>` block. The current user\n * message (just persisted) is excluded since it is already the prompt.\n *\n * Each turn is rendered as a self-closing `<turn role=\"...\">` element\n * rather than a bare `[User]:` / `[Assistant]:` transcript line. A plain\n * role-prefixed transcript invites the model to *continue* it — completing\n * the next `[User]:` turn as plaintext inside its own answer (a fabricated\n * follow-up that swallows the real next message). XML-tagged, explicitly\n * read-only turns remove that completion affordance while preserving the\n * same information.\n *\n * Returns the original prompt unchanged if there is no prior history.\n */\n private async enrichPromptWithHistory(currentPrompt: string): Promise<string> {\n const messages = await this.store.getMessages(this.sessionId, {\n limit: this.historyLimit,\n });\n\n // Filter to conversation-relevant types and exclude the message we just appended\n const history = messages\n .filter((m) => {\n const type = m.payload.type;\n return type === \"prompt\" || type === \"finished\" || type === \"question\";\n })\n .slice(0, -1); // Exclude the current message (last by seq)\n\n if (history.length === 0) {\n return currentPrompt;\n }\n\n // Escape so message content (which may itself contain `</turn>` or other\n // angle brackets) cannot break out of the XML structure or inject a forged\n // turn. The model reads entity-encoded text fine; this is read-only context.\n const esc = (s: string): string =>\n s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n\n const turns = history.map((m) => {\n const p = m.payload as Record<string, unknown>;\n if (p.type === \"prompt\") {\n return `<turn role=\"user\">${esc(String(p.prompt ?? \"\"))}</turn>`;\n }\n // finished (assistant response) or question\n const content = String(p.summary ?? p.question ?? \"\");\n return `<turn role=\"assistant\">${esc(content)}</turn>`;\n });\n\n return (\n \"<conversation_history>\\n\" +\n \"The following is prior conversation context, provided read-only so you \" +\n \"have continuity. Do NOT continue, echo, or complete it — it is history, \" +\n \"not a turn for you to extend. Respond only to the user message that \" +\n \"follows the closing tag.\\n\" +\n `${turns.join(\"\\n\")}\\n` +\n \"</conversation_history>\\n\\n\" +\n currentPrompt\n );\n }\n\n private async handleAgentEvent(event: AgentEvent, mentions?: Mention[]): Promise<Message | null> {\n // ── Compaction mode: capture text but don't persist ─────────────────\n if (this._compacting) {\n if (event.type === \"text\") {\n this._compactionText += (event as { content: string }).content;\n }\n // Still broadcast to subscribers (UI shows compaction progress)\n for (const subscriberId of this.subscribers) {\n this.transport.send(subscriberId, event);\n }\n return null;\n }\n\n // Capture resource metadata when the server announces available resources\n if (event.type === \"resources_available\") {\n const payload = event as { mounts?: unknown[]; connectors?: unknown[] };\n this._availableResources = {\n mounts: payload.mounts ?? [],\n connectors: payload.connectors ?? [],\n };\n }\n\n // ── onceNextFinished — one-shot \"next finished turn\" answer capture ──\n // Accumulate streamed text across the turn so the answer is available\n // even when a driver emits an empty `finished.summary`. On `finished`,\n // drain every queued waiter exactly once, then reset the accumulator.\n if (event.type === \"text\") {\n this._turnText += (event as { content: string }).content;\n } else if (event.type === \"finished\") {\n const summary = (event as { summary?: string }).summary ?? \"\";\n const answer = summary.length > 0 ? summary : this._turnText;\n this._turnText = \"\";\n if (this.nextFinishedWaiters.length > 0) {\n const waiters = this.nextFinishedWaiters;\n this.nextFinishedWaiters = [];\n for (const cb of waiters) {\n cb(answer);\n }\n }\n }\n\n let message: Message | null = null;\n if (this.shouldPersist(event)) {\n message = this.createMessage(event);\n if (mentions?.length) message.mentions = mentions;\n await this.store.append(message);\n }\n\n for (const subscriberId of this.subscribers) {\n this.transport.send(subscriberId, event);\n }\n return message;\n }\n\n private shouldPersist(payload: AgentCommand | AgentEvent): boolean {\n return !TRANSIENT_TYPES.has(payload.type);\n }\n\n private createMessage(payload: AgentCommand | AgentEvent, senderId?: string): Message {\n this.seq++;\n return {\n id: crypto.randomUUID(),\n seq: this.seq,\n timestamp: new Date().toISOString(),\n sessionId: this.sessionId,\n ...(senderId ? { senderId } : {}),\n payload,\n };\n }\n}\n","import type { Mention, MentionGroup } from \"@skaile/workspaces/types\";\nimport { MENTION_GROUPS } from \"@skaile/workspaces/types\";\n\n/**\n * Re-exported from `@skaile/workspaces/types` so consumers can import mention\n * types directly from `@skaile/workspaces/session` without a separate dependency.\n */\nexport type { Mention, MentionGroup };\n\n// ---------------------------------------------------------------------------\n// MentionResolver\n// ---------------------------------------------------------------------------\n\n/**\n * Consumer-provided resolver that maps @mention tokens to users and groups.\n *\n * The platform provides an implementation backed by Prisma and the live\n * presence service. Tests use lightweight mocks.\n *\n * @example\n * ```ts\n * const resolver: MentionResolver = {\n * resolveUser: (name) => db.users.findByName(name),\n * resolveGroup: (group) => presence.getMemberIds(group),\n * getOnlineUserIds: () => presence.getOnlineIds(),\n * }\n * ```\n *\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport interface MentionResolver {\n /**\n * Resolve a `@name` token to a user record.\n *\n * @param name - The token after the `@` symbol (case-insensitive lookup).\n * @returns User record, or null if the name is not found.\n */\n resolveUser(name: string): { userId: string; name: string } | null;\n /**\n * Resolve a group mention token to the list of member user IDs.\n *\n * @param group - The well-known group name (e.g. `\"agent\"`, `\"all\"`).\n * @returns Array of member user IDs belonging to the group.\n */\n resolveGroup(group: MentionGroup): string[];\n /** Return the IDs of users currently online (used by the `here` and `humans_here` groups). */\n getOnlineUserIds(): string[];\n}\n\n// ---------------------------------------------------------------------------\n// parseMentions\n// ---------------------------------------------------------------------------\n\nconst MENTION_RE = /@(\\w+)/g;\nconst MENTION_GROUP_SET: ReadonlySet<string> = new Set(MENTION_GROUPS);\n\n/**\n * Scan `text` for @token patterns and return resolved {@link Mention} objects.\n *\n * - Well-known group tokens (`agent`, `humans`, `humans_here`, `here`, `all`)\n * are resolved via {@link MentionResolver.resolveGroup}.\n * - All other tokens are resolved via {@link MentionResolver.resolveUser}.\n * - Tokens that cannot be resolved are silently ignored.\n * - Results are sorted by character offset ascending.\n *\n * @param text - Raw message text to scan for `@token` patterns.\n * @param resolver - Resolver that maps tokens to users and groups.\n * @returns Resolved mentions ordered by position in text.\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport function parseMentions(text: string, resolver: MentionResolver): Mention[] {\n const mentions: Mention[] = [];\n\n for (const match of text.matchAll(MENTION_RE)) {\n const token = match[1]!;\n const offset = match.index!;\n const length = match[0].length; // includes the @\n\n if (MENTION_GROUP_SET.has(token)) {\n const group = token as MentionGroup;\n mentions.push({\n type: \"group\",\n group,\n resolved: resolver.resolveGroup(group),\n offset,\n length,\n });\n } else {\n const user = resolver.resolveUser(token);\n if (user) {\n mentions.push({\n type: \"user\",\n userId: user.userId,\n name: user.name,\n offset,\n length,\n });\n }\n }\n }\n\n // matchAll iterates left-to-right, so mentions are already offset-ascending.\n return mentions;\n}\n\n// ---------------------------------------------------------------------------\n// isMentioned\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if `userId` is directly mentioned or is a member of any\n * group mention's resolved list.\n *\n * @param userId - The user ID to check (e.g. from the auth context).\n * @param mentions - Parsed mentions from {@link parseMentions}.\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport function isMentioned(userId: string, mentions: Mention[]): boolean {\n for (const m of mentions) {\n if (m.type === \"user\" && m.userId === userId) return true;\n if (m.type === \"group\" && m.resolved.includes(userId)) return true;\n if (m.type === \"custom\" && m.resolved.includes(userId)) return true;\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// isAddressedByKind\n// ---------------------------------------------------------------------------\n\n/**\n * True if any mention is a custom mention of the given kind.\n *\n * Consumers use this to check for platform-specific mention kinds (e.g.\n * `\"assistant\"`) that the SDK parser does not produce — only consumers\n * construct custom mentions.\n *\n * @param mentions - Mention list from the message or consumer-constructed.\n * @param kind - The consumer-defined kind string to match.\n */\nexport function isAddressedByKind(mentions: Mention[], kind: string): boolean {\n return mentions.some((m) => m.type === \"custom\" && m.kind === kind);\n}\n\n// ---------------------------------------------------------------------------\n// isAgentAddressed\n// ---------------------------------------------------------------------------\n\n/** Groups that include the agent in their resolved membership. */\nconst AGENT_GROUPS: ReadonlySet<MentionGroup> = new Set([\"agent\", \"here\", \"all\"]);\n\n/**\n * Returns true if the agent is addressed by any mention in the list.\n *\n * The groups `@agent`, `@here`, and `@all` address the agent. `@humans`\n * and `@humans_here` do not. Individual user mentions are also not matched\n * here — agent addressing is group-based.\n *\n * @param mentions - Parsed mentions from {@link parseMentions}.\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport function isAgentAddressed(mentions: Mention[]): boolean {\n return mentions.some((m) => m.type === \"group\" && AGENT_GROUPS.has(m.group));\n}\n"]}
|
package/dist/chunk-BQCGFPHW.js
DELETED
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
import { parseDep, isValidAssetName, slugifyAssetName } from './chunk-GEEW6SY2.js';
|
|
2
|
-
import { readFileSync, readdirSync, statSync } from 'fs';
|
|
3
|
-
import { basename, dirname, join } from 'path';
|
|
4
|
-
import { parse } from 'yaml';
|
|
5
|
-
|
|
6
|
-
function parseFrontmatter(text) {
|
|
7
|
-
const m = text.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
8
|
-
if (!m) return { data: {}, body: text.trim() };
|
|
9
|
-
try {
|
|
10
|
-
const data = parse(m[1]) ?? {};
|
|
11
|
-
const body = text.slice(m[0].length).trim();
|
|
12
|
-
return { data, body };
|
|
13
|
-
} catch {
|
|
14
|
-
return { data: {}, body: text.trim() };
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
function extractVersion(meta) {
|
|
18
|
-
return String(
|
|
19
|
-
meta.version ?? meta.metadata?.version ?? ""
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
function parseRequires(meta) {
|
|
23
|
-
const raw = meta.requires ?? meta.metadata?.requires;
|
|
24
|
-
if (!raw) return [];
|
|
25
|
-
const list = typeof raw === "string" ? raw.split(",").map((s) => s.trim()) : Array.isArray(raw) ? raw : [];
|
|
26
|
-
return list.filter(Boolean).map(parseDep);
|
|
27
|
-
}
|
|
28
|
-
function collectAgentDeps(raw, out) {
|
|
29
|
-
if (!Array.isArray(raw)) return;
|
|
30
|
-
for (const d of raw) {
|
|
31
|
-
if (typeof d === "object" && d !== null && "name" in d) {
|
|
32
|
-
out.push({ kind: "agent", name: String(d.name) });
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
function collectStringRefs(raw, kind, out) {
|
|
37
|
-
if (!Array.isArray(raw)) return;
|
|
38
|
-
for (const r of raw) {
|
|
39
|
-
if (typeof r === "string" && r) out.push({ kind, name: r });
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function collectMixinRefs(raw, defaultKind, out) {
|
|
43
|
-
if (!Array.isArray(raw)) return;
|
|
44
|
-
for (const r of raw) {
|
|
45
|
-
if (typeof r !== "string" || !r) continue;
|
|
46
|
-
if (r.startsWith(".") || r.startsWith("/")) continue;
|
|
47
|
-
const normalized = r.includes(":") ? r : `${defaultKind}:${r}`;
|
|
48
|
-
const colonIdx = normalized.indexOf(":");
|
|
49
|
-
const kind = normalized.slice(0, colonIdx).trim();
|
|
50
|
-
let rest = normalized.slice(colonIdx + 1).trim();
|
|
51
|
-
const hashIdx = rest.indexOf("#");
|
|
52
|
-
if (hashIdx !== -1) rest = rest.slice(0, hashIdx).trim();
|
|
53
|
-
let name;
|
|
54
|
-
if (rest.startsWith("@")) {
|
|
55
|
-
const slashIdx = rest.indexOf("/");
|
|
56
|
-
name = slashIdx !== -1 ? rest.slice(slashIdx + 1).trim() : "";
|
|
57
|
-
} else {
|
|
58
|
-
const atIdx = rest.indexOf("@");
|
|
59
|
-
name = atIdx !== -1 ? rest.slice(0, atIdx).trim() : rest;
|
|
60
|
-
}
|
|
61
|
-
if (name) out.push({ kind, name });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
function fromSkillMd(filePath, repoName) {
|
|
65
|
-
const { data: meta } = parseFrontmatter(readFileSync(filePath, "utf8"));
|
|
66
|
-
let kind = String(meta.type ?? "skill");
|
|
67
|
-
if (!["skill", "agent", "prompt", "persona", "ruleset", "knowledge"].includes(kind))
|
|
68
|
-
kind = "skill";
|
|
69
|
-
return {
|
|
70
|
-
name: String(meta.name ?? basename(dirname(filePath))),
|
|
71
|
-
kind,
|
|
72
|
-
description: String(meta.description ?? ""),
|
|
73
|
-
source: filePath,
|
|
74
|
-
publisher: repoName,
|
|
75
|
-
version: extractVersion(meta),
|
|
76
|
-
requires: parseRequires(meta),
|
|
77
|
-
dependencies: []
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
function fromAgentMd(filePath, repoName) {
|
|
81
|
-
const { data: meta } = parseFrontmatter(readFileSync(filePath, "utf8"));
|
|
82
|
-
return {
|
|
83
|
-
name: String(meta.name ?? basename(dirname(filePath))),
|
|
84
|
-
kind: "agent",
|
|
85
|
-
description: String(meta.description ?? ""),
|
|
86
|
-
source: filePath,
|
|
87
|
-
publisher: repoName,
|
|
88
|
-
version: extractVersion(meta),
|
|
89
|
-
requires: parseRequires(meta),
|
|
90
|
-
dependencies: []
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
function fromAgentYaml(filePath, repoName) {
|
|
94
|
-
let meta = {};
|
|
95
|
-
try {
|
|
96
|
-
meta = parse(readFileSync(filePath, "utf8")) ?? {};
|
|
97
|
-
} catch {
|
|
98
|
-
}
|
|
99
|
-
const requires = [];
|
|
100
|
-
collectAgentDeps(meta.requires, requires);
|
|
101
|
-
collectAgentDeps(meta.dependencies, requires);
|
|
102
|
-
collectStringRefs(meta.abilities, "skill", requires);
|
|
103
|
-
collectStringRefs(meta.contracts, "contract", requires);
|
|
104
|
-
for (const [field, defaultKind] of [
|
|
105
|
-
["persona", "persona"],
|
|
106
|
-
["rules", "ruleset"],
|
|
107
|
-
["knowledge", "knowledge"]
|
|
108
|
-
]) {
|
|
109
|
-
collectMixinRefs(meta[field], defaultKind, requires);
|
|
110
|
-
}
|
|
111
|
-
return {
|
|
112
|
-
name: String(meta.name ?? basename(dirname(filePath))),
|
|
113
|
-
kind: "agent",
|
|
114
|
-
description: String(meta.description ?? ""),
|
|
115
|
-
source: filePath,
|
|
116
|
-
publisher: repoName,
|
|
117
|
-
version: String(meta.version ?? ""),
|
|
118
|
-
requires,
|
|
119
|
-
dependencies: []
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
function fromPromptMd(filePath, repoName) {
|
|
123
|
-
const { data: meta } = parseFrontmatter(readFileSync(filePath, "utf8"));
|
|
124
|
-
const name = String(meta.name ?? basename(filePath).replace(/\.prompt\.md$/, ""));
|
|
125
|
-
return {
|
|
126
|
-
name,
|
|
127
|
-
kind: "prompt",
|
|
128
|
-
description: String(meta.description ?? ""),
|
|
129
|
-
source: filePath,
|
|
130
|
-
publisher: repoName,
|
|
131
|
-
version: extractVersion(meta),
|
|
132
|
-
requires: parseRequires(meta),
|
|
133
|
-
dependencies: []
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
function fromFlowYaml(filePath, repoName) {
|
|
137
|
-
let meta = {};
|
|
138
|
-
try {
|
|
139
|
-
meta = parse(readFileSync(filePath, "utf8")) ?? {};
|
|
140
|
-
} catch {
|
|
141
|
-
}
|
|
142
|
-
const stem = basename(filePath).replace(/\.flow\.yaml$/, "").replace(/\.flow\.json$/, "");
|
|
143
|
-
return {
|
|
144
|
-
name: String(meta.name ?? meta.id ?? stem),
|
|
145
|
-
kind: "flow",
|
|
146
|
-
description: String(meta.description ?? ""),
|
|
147
|
-
source: filePath,
|
|
148
|
-
publisher: repoName,
|
|
149
|
-
version: String(meta.version ?? ""),
|
|
150
|
-
requires: parseRequires(meta),
|
|
151
|
-
dependencies: []
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
function fromBundleYaml(filePath, repoName) {
|
|
155
|
-
let meta = {};
|
|
156
|
-
try {
|
|
157
|
-
meta = parse(readFileSync(filePath, "utf8")) ?? {};
|
|
158
|
-
} catch {
|
|
159
|
-
}
|
|
160
|
-
const name = String(meta.name ?? basename(filePath).replace(/\.bundle\.yaml$/, ""));
|
|
161
|
-
const deps = meta.dependencies;
|
|
162
|
-
const dependencies = Array.isArray(deps) ? deps.filter(Boolean) : [];
|
|
163
|
-
return {
|
|
164
|
-
name,
|
|
165
|
-
kind: "bundle",
|
|
166
|
-
description: String(meta.description ?? ""),
|
|
167
|
-
source: filePath,
|
|
168
|
-
publisher: repoName,
|
|
169
|
-
version: String(meta.version ?? ""),
|
|
170
|
-
requires: parseRequires(meta),
|
|
171
|
-
dependencies
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
function bundleDepRefs(filePath) {
|
|
175
|
-
const wholeDoc = /\.(bundle\.yaml|flow\.yaml|flow\.json)$/.test(filePath);
|
|
176
|
-
let meta = {};
|
|
177
|
-
try {
|
|
178
|
-
meta = wholeDoc ? parse(readFileSync(filePath, "utf8")) ?? {} : parseFrontmatter(readFileSync(filePath, "utf8")).data;
|
|
179
|
-
} catch {
|
|
180
|
-
return [];
|
|
181
|
-
}
|
|
182
|
-
const out = [];
|
|
183
|
-
const collect = (v) => {
|
|
184
|
-
if (Array.isArray(v)) {
|
|
185
|
-
for (const x of v) if (typeof x === "string" && x.trim()) out.push(x.trim());
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
collect(meta.requires);
|
|
189
|
-
collect(meta.metadata?.requires);
|
|
190
|
-
collect(meta.dependencies);
|
|
191
|
-
return [...new Set(out)];
|
|
192
|
-
}
|
|
193
|
-
function fromContractMd(filePath, repoName) {
|
|
194
|
-
const { data: meta } = parseFrontmatter(readFileSync(filePath, "utf8"));
|
|
195
|
-
return {
|
|
196
|
-
name: String(meta.name ?? basename(dirname(filePath))),
|
|
197
|
-
kind: "contract",
|
|
198
|
-
description: String(meta.description ?? ""),
|
|
199
|
-
source: filePath,
|
|
200
|
-
publisher: repoName,
|
|
201
|
-
version: extractVersion(meta),
|
|
202
|
-
requires: parseRequires(meta),
|
|
203
|
-
dependencies: []
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
function fromMcpServerMd(filePath, repoName) {
|
|
207
|
-
return fromMcpServerMdContent(readFileSync(filePath, "utf8"), repoName, filePath);
|
|
208
|
-
}
|
|
209
|
-
function fromMcpServerMdContent(content, repoName, filePath) {
|
|
210
|
-
const { data: meta } = parseFrontmatter(content);
|
|
211
|
-
const metadata = {};
|
|
212
|
-
if (meta.transport) metadata.transport = String(meta.transport);
|
|
213
|
-
if (meta.command) metadata.command = String(meta.command);
|
|
214
|
-
if (Array.isArray(meta.args)) metadata.args = meta.args.map(String);
|
|
215
|
-
if (meta.env && typeof meta.env === "object" && !Array.isArray(meta.env)) {
|
|
216
|
-
metadata.env = meta.env;
|
|
217
|
-
}
|
|
218
|
-
if (meta.url) metadata.url = String(meta.url);
|
|
219
|
-
if (meta.headers && typeof meta.headers === "object" && !Array.isArray(meta.headers)) {
|
|
220
|
-
metadata.headers = meta.headers;
|
|
221
|
-
}
|
|
222
|
-
if (meta.recipe && typeof meta.recipe === "object" && !Array.isArray(meta.recipe)) {
|
|
223
|
-
metadata.recipe = meta.recipe;
|
|
224
|
-
}
|
|
225
|
-
return {
|
|
226
|
-
name: String(meta.name ?? basename(dirname(filePath))),
|
|
227
|
-
kind: "mcp-server",
|
|
228
|
-
description: String(meta.description ?? ""),
|
|
229
|
-
source: filePath,
|
|
230
|
-
publisher: repoName,
|
|
231
|
-
version: extractVersion(meta),
|
|
232
|
-
requires: parseRequires(meta),
|
|
233
|
-
dependencies: [],
|
|
234
|
-
metadata: Object.keys(metadata).length > 0 ? metadata : void 0
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
function fromKnowledgeYaml(filePath, repoName) {
|
|
238
|
-
let meta = {};
|
|
239
|
-
try {
|
|
240
|
-
meta = parse(readFileSync(filePath, "utf8")) ?? {};
|
|
241
|
-
} catch {
|
|
242
|
-
}
|
|
243
|
-
return {
|
|
244
|
-
name: String(meta.name ?? basename(dirname(filePath))),
|
|
245
|
-
kind: "knowledge",
|
|
246
|
-
description: String(meta.description ?? ""),
|
|
247
|
-
source: filePath,
|
|
248
|
-
publisher: repoName,
|
|
249
|
-
version: String(meta.version ?? ""),
|
|
250
|
-
requires: parseRequires(meta),
|
|
251
|
-
dependencies: []
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
function fromConnectorMd(filePath, repoName) {
|
|
255
|
-
const text = readFileSync(filePath, "utf-8");
|
|
256
|
-
const { data: meta, body } = parseFrontmatter(text);
|
|
257
|
-
const name = String(meta.name ?? basename(dirname(filePath)));
|
|
258
|
-
return {
|
|
259
|
-
name,
|
|
260
|
-
kind: "connector",
|
|
261
|
-
description: String(meta.description ?? ""),
|
|
262
|
-
source: filePath,
|
|
263
|
-
publisher: repoName,
|
|
264
|
-
version: extractVersion(meta),
|
|
265
|
-
requires: parseRequires(meta),
|
|
266
|
-
dependencies: [],
|
|
267
|
-
metadata: {
|
|
268
|
-
entry: meta.entry ?? "./adapter.ts",
|
|
269
|
-
npm_deps: meta.npm_deps ?? {},
|
|
270
|
-
fields: meta.fields ?? [],
|
|
271
|
-
health_check: meta.health_check ?? null,
|
|
272
|
-
body
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
function* walkDir(dir) {
|
|
277
|
-
let dirEntries;
|
|
278
|
-
try {
|
|
279
|
-
dirEntries = readdirSync(dir, { withFileTypes: true, encoding: "utf8" });
|
|
280
|
-
} catch {
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
for (const e of dirEntries.sort((a, b) => a.name < b.name ? -1 : 1)) {
|
|
284
|
-
const full = join(dir, e.name);
|
|
285
|
-
if (e.isSymbolicLink()) {
|
|
286
|
-
try {
|
|
287
|
-
if (statSync(full).isDirectory()) yield* walkDir(full);
|
|
288
|
-
else yield { path: full, name: e.name };
|
|
289
|
-
} catch {
|
|
290
|
-
}
|
|
291
|
-
} else if (e.isDirectory()) {
|
|
292
|
-
if (e.name !== ".git" && e.name !== "node_modules") yield* walkDir(full);
|
|
293
|
-
} else if (e.isFile()) {
|
|
294
|
-
yield { path: full, name: e.name };
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
function normalizeEntryName(e) {
|
|
299
|
-
if (isValidAssetName(e.name)) return;
|
|
300
|
-
let slug;
|
|
301
|
-
try {
|
|
302
|
-
slug = slugifyAssetName(e.name);
|
|
303
|
-
} catch {
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
const original = e.name;
|
|
307
|
-
e.name = slug;
|
|
308
|
-
if (e.metadata?.displayName === void 0) {
|
|
309
|
-
e.metadata = { ...e.metadata, displayName: original };
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
function scanDirectory(root, repoName) {
|
|
313
|
-
const entries = /* @__PURE__ */ new Map();
|
|
314
|
-
function add(e) {
|
|
315
|
-
normalizeEntryName(e);
|
|
316
|
-
const key = `${e.kind}:${e.name}`;
|
|
317
|
-
const existing = entries.get(key);
|
|
318
|
-
if (!existing) {
|
|
319
|
-
entries.set(key, e);
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
if (e.source > existing.source) entries.set(key, e);
|
|
323
|
-
}
|
|
324
|
-
for (const { path: filePath, name } of walkDir(root)) {
|
|
325
|
-
try {
|
|
326
|
-
if (name === "SKILL.md") add(fromSkillMd(filePath, repoName));
|
|
327
|
-
else if (name === "AGENT.md") add(fromAgentMd(filePath, repoName));
|
|
328
|
-
else if (name === "agent.yaml") add(fromAgentYaml(filePath, repoName));
|
|
329
|
-
else if (name === "CONTRACT.md") add(fromContractMd(filePath, repoName));
|
|
330
|
-
else if (name === "MCP.md") add(fromMcpServerMd(filePath, repoName));
|
|
331
|
-
else if (name === "CONNECTOR.md") add(fromConnectorMd(filePath, repoName));
|
|
332
|
-
else if (name === "knowledge.yaml") add(fromKnowledgeYaml(filePath, repoName));
|
|
333
|
-
else if (name.endsWith(".prompt.md")) add(fromPromptMd(filePath, repoName));
|
|
334
|
-
else if (name.endsWith(".bundle.yaml")) add(fromBundleYaml(filePath, repoName));
|
|
335
|
-
else if (name.endsWith(".flow.yaml") || name.endsWith(".flow.json"))
|
|
336
|
-
add(fromFlowYaml(filePath, repoName));
|
|
337
|
-
} catch {
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return [...entries.values()];
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
export { bundleDepRefs, fromAgentMd, fromAgentYaml, fromBundleYaml, fromConnectorMd, fromContractMd, fromFlowYaml, fromKnowledgeYaml, fromMcpServerMd, fromMcpServerMdContent, fromPromptMd, fromSkillMd, parseFrontmatter, parseRequires, scanDirectory, walkDir };
|
|
344
|
-
//# sourceMappingURL=chunk-BQCGFPHW.js.map
|
|
345
|
-
//# sourceMappingURL=chunk-BQCGFPHW.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../core/src/manifest.ts"],"names":[],"mappings":"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","file":"chunk-BQCGFPHW.js","sourcesContent":["/**\n * Manifest parsing — reads SKILL.md, AGENT.md, agent.yaml, CONTRACT.md,\n * CONNECTOR.md, *.prompt.md, *.flow.yaml, *.bundle.yaml files and\n * produces CatalogEntry objects.\n * Used by @skaile/asset-manager for on-demand repo scanning.\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { parse } from \"yaml\";\nimport type { AssetKind, CatalogEntry, Dependency } from \"./models.js\";\nimport { isValidAssetName, parseDep, slugifyAssetName } from \"./models.js\";\n\n// ── Frontmatter helpers ───────────────────────────────────────────────────────\n\n/**\n * Result of parsing YAML frontmatter from a markdown file.\n * @docLink packages/core/concepts#frontmatter-result\n */\nexport interface FrontmatterResult {\n /** Parsed YAML data. Empty object if no frontmatter block is present. */\n data: Record<string, unknown>;\n /** Markdown body below the frontmatter block (trimmed). */\n body: string;\n}\n\n/**\n * Parse YAML frontmatter from a markdown file (`---` delimited).\n * Returns `{ data: {}, body: text }` when no frontmatter block is present.\n *\n * @param text - Raw file contents\n * @returns Parsed frontmatter data and the remaining body text\n * @docLink packages/core/concepts#parse-frontmatter\n */\nexport function parseFrontmatter(text: string): FrontmatterResult {\n const m = text.match(/^---\\s*\\n([\\s\\S]*?)\\n---/);\n if (!m) return { data: {}, body: text.trim() };\n try {\n const data = (parse(m[1]!) as Record<string, unknown>) ?? {};\n const body = text.slice(m[0].length).trim();\n return { data, body };\n } catch {\n return { data: {}, body: text.trim() };\n }\n}\n\n/** Extract version from frontmatter, checking both top-level and metadata.version. */\nfunction extractVersion(meta: Record<string, unknown>): string {\n return String(\n meta.version ?? (meta.metadata as Record<string, unknown> | undefined)?.version ?? \"\",\n );\n}\n\n/**\n * Parse the `requires:` field from manifest frontmatter into typed `Dependency` objects.\n * Accepts a comma-separated string or an array of `\"kind:name\"` strings. Reads from either\n * the root or `metadata.requires` (matching `extractVersion`'s dual-location behavior) so\n * skill authors can follow the agentskills.io convention of placing skaile extensions under\n * `metadata:` while remaining backward-compatible with root-level declarations.\n *\n * @param meta - Parsed frontmatter data object\n * @returns Array of `Dependency` objects (empty when `requires` is absent)\n * @docLink packages/core/concepts#parse-requires\n */\nexport function parseRequires(meta: Record<string, unknown>): Dependency[] {\n const raw = meta.requires ?? (meta.metadata as Record<string, unknown> | undefined)?.requires;\n if (!raw) return [];\n const list =\n typeof raw === \"string\"\n ? raw.split(\",\").map((s) => s.trim())\n : Array.isArray(raw)\n ? (raw as string[])\n : [];\n return list.filter(Boolean).map(parseDep);\n}\n\n// ── agent.yaml dependency collectors ───────────────────────────────────────────\n\n/**\n * Collect named sub-agent dependencies from an `agent.yaml` array field.\n * Each `{name, ...}` object entry becomes an `{kind: \"agent\", name}` dependency.\n * Covers both the new `requires[]` and legacy `dependencies[]` formats.\n */\nfunction collectAgentDeps(raw: unknown, out: Dependency[]): void {\n if (!Array.isArray(raw)) return;\n for (const d of raw) {\n if (typeof d === \"object\" && d !== null && \"name\" in d) {\n out.push({ kind: \"agent\", name: String((d as Record<string, unknown>).name) });\n }\n }\n}\n\n/**\n * Collect string refs from an `agent.yaml` array field (`abilities[]`,\n * `contracts[]`) as `{kind, name}` dependencies, skipping empty entries.\n */\nfunction collectStringRefs(raw: unknown, kind: Dependency[\"kind\"], out: Dependency[]): void {\n if (!Array.isArray(raw)) return;\n for (const r of raw) {\n if (typeof r === \"string\" && r) out.push({ kind, name: r });\n }\n}\n\n/**\n * Collect catalog refs from an `agent.yaml` mixin field (`persona`, `rules`,\n * `knowledge`) as requires so `skaile install` pulls them automatically. Local\n * paths (`.`/`/`) are skipped — not catalog assets. Refs without a `kind:`\n * prefix get `defaultKind` injected; the publisher scope and `#pin` are stripped\n * so only `kind:name` is tracked.\n */\nfunction collectMixinRefs(raw: unknown, defaultKind: string, out: Dependency[]): void {\n if (!Array.isArray(raw)) return;\n for (const r of raw) {\n if (typeof r !== \"string\" || !r) continue;\n if (r.startsWith(\".\") || r.startsWith(\"/\")) continue; // local path — skip\n // Normalize: if no kind: prefix, inject the default kind\n const normalized = r.includes(\":\") ? r : `${defaultKind}:${r}`;\n // Only kind:name matters for requires — strip the publisher scope and #pin.\n const colonIdx = normalized.indexOf(\":\");\n const kind = normalized.slice(0, colonIdx).trim();\n let rest = normalized.slice(colonIdx + 1).trim();\n const hashIdx = rest.indexOf(\"#\");\n if (hashIdx !== -1) rest = rest.slice(0, hashIdx).trim();\n let name: string;\n if (rest.startsWith(\"@\")) {\n // Scoped form @publisher/name → name is the segment after the slash.\n const slashIdx = rest.indexOf(\"/\");\n name = slashIdx !== -1 ? rest.slice(slashIdx + 1).trim() : \"\";\n } else {\n // Legacy name@publisher (deprecated) or a bare name.\n const atIdx = rest.indexOf(\"@\");\n name = atIdx !== -1 ? rest.slice(0, atIdx).trim() : rest;\n }\n if (name) out.push({ kind, name });\n }\n}\n\n// ── Manifest parsers ──────────────────────────────────────────────────────────\n\n/**\n * Parse a `SKILL.md` file into a `CatalogEntry`.\n * The `kind` field defaults to `\"skill\"` but can be overridden to `\"agent\"` or `\"prompt\"`\n * via the `type:` frontmatter key. Falls back to the parent directory name when `name:` is absent.\n *\n * @param filePath - Absolute path to the `SKILL.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind, name, description, version, and requires\n * @docLink packages/core/concepts#from-skill-md\n */\nexport function fromSkillMd(filePath: string, repoName: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n let kind = String(meta.type ?? \"skill\") as AssetKind;\n if (![\"skill\", \"agent\", \"prompt\", \"persona\", \"ruleset\", \"knowledge\"].includes(kind))\n kind = \"skill\";\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind,\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse an `AGENT.md` file into a `CatalogEntry` with `kind: \"agent\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * @param filePath - Absolute path to the `AGENT.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"agent\"`\n * @docLink packages/core/concepts#from-agent-md\n */\nexport function fromAgentMd(filePath: string, repoName: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"agent\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse an `agent.yaml` file into a `CatalogEntry` with `kind: \"agent\"`.\n * Collects sub-agent dependencies from `requires[]` (new format) and `dependencies[]`\n * (legacy format), skill abilities from `abilities[]`, and contracts from `contracts[]`.\n *\n * @param filePath - Absolute path to the `agent.yaml` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"agent\"` and full dependency graph\n * @docLink packages/core/concepts#from-agent-yaml\n */\nexport function fromAgentYaml(filePath: string, repoName: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {}\n\n const requires: Dependency[] = [];\n\n // Sub-agent dependencies from requires[] (new format: {name, source, ...})\n collectAgentDeps(meta.requires, requires);\n // Legacy sub-agent dependencies from dependencies[] (old format: {name, ...})\n collectAgentDeps(meta.dependencies, requires);\n // Skill abilities referenced in the system prompt\n collectStringRefs(meta.abilities, \"skill\", requires);\n // Contracts referenced in the system prompt (co-located in skills dir)\n collectStringRefs(meta.contracts, \"contract\", requires);\n\n // Mixin composition fields — track catalog refs as requires so `skaile install`\n // automatically pulls them. Local paths (. or /) are skipped — not catalog assets.\n for (const [field, defaultKind] of [\n [\"persona\", \"persona\"],\n [\"rules\", \"ruleset\"],\n [\"knowledge\", \"knowledge\"],\n ] as const) {\n collectMixinRefs(meta[field], defaultKind, requires);\n }\n\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"agent\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires,\n dependencies: [],\n };\n}\n\n/**\n * Parse a `*.prompt.md` file into a `CatalogEntry` with `kind: \"prompt\"`.\n * The name defaults to the filename stem (without the `.prompt.md` suffix)\n * when no `name:` frontmatter key is present.\n *\n * @param filePath - Absolute path to the `.prompt.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"prompt\"`\n * @docLink packages/core/concepts#from-prompt-md\n */\nexport function fromPromptMd(filePath: string, repoName: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n const name = String(meta.name ?? basename(filePath).replace(/\\.prompt\\.md$/, \"\"));\n return {\n name,\n kind: \"prompt\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse a `*.flow.yaml` or `*.flow.json` file into a `CatalogEntry` with `kind: \"flow\"`.\n * The name resolves from `name:` or `id:` frontmatter, falling back to the filename stem.\n *\n * @param filePath - Absolute path to the flow definition file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"flow\"`\n * @docLink packages/core/concepts#from-flow-yaml\n */\nexport function fromFlowYaml(filePath: string, repoName: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {}\n\n const stem = basename(filePath)\n .replace(/\\.flow\\.yaml$/, \"\")\n .replace(/\\.flow\\.json$/, \"\");\n return {\n name: String(meta.name ?? meta.id ?? stem),\n kind: \"flow\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse a `*.bundle.yaml` file into a `CatalogEntry` with `kind: \"bundle\"`.\n * Bundles declare a flat list of string `dependencies` (asset refs) rather than\n * typed `Dependency` objects; both `requires` and `dependencies` are populated.\n *\n * @param filePath - Absolute path to the bundle YAML file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"bundle\"`\n * @docLink packages/core/concepts#from-bundle-yaml\n */\nexport function fromBundleYaml(filePath: string, repoName: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {}\n\n const name = String(meta.name ?? basename(filePath).replace(/\\.bundle\\.yaml$/, \"\"));\n\n const deps = meta.dependencies;\n const dependencies = Array.isArray(deps) ? (deps as string[]).filter(Boolean) : [];\n\n return {\n name,\n kind: \"bundle\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires: parseRequires(meta),\n dependencies,\n };\n}\n\n/**\n * Extract a bundle's raw transitive dependency ref strings from its manifest\n * file — the union of its `requires` and `dependencies` lists, kept verbatim\n * (publisher/pin qualifiers preserved, comments dropped by the parser).\n *\n * Supports `*.bundle.yaml` / `*.flow.{yaml,json}` (top-level\n * `requires`/`dependencies`) and the `BUNDLE.md` frontmatter layout\n * (`requires`/`dependencies`, incl. nested under `metadata`). Unlike\n * {@link parseRequires}, refs are returned as-is — the resolver needs the full\n * `kind:name@<publisher>[#pin]` form, not a publisher-stripped {@link Dependency}.\n *\n * @param filePath - Absolute path to a `.bundle.yaml`, `.flow.{yaml,json}`, or `BUNDLE.md`.\n * @returns Deduped list of ref strings; `[]` on parse failure or no deps.\n * @docLink packages/core/concepts#bundle-dep-refs\n */\nexport function bundleDepRefs(filePath: string): string[] {\n // `.bundle.yaml` / `.flow.yaml` / `.flow.json` carry their dep list as a\n // top-level document key (`requires`/`dependencies`); `BUNDLE.md` carries it\n // in frontmatter. YAML is a JSON superset, so `parse` reads `.flow.json` too.\n const wholeDoc = /\\.(bundle\\.yaml|flow\\.yaml|flow\\.json)$/.test(filePath);\n let meta: Record<string, unknown> = {};\n try {\n meta = wholeDoc\n ? ((parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {})\n : parseFrontmatter(readFileSync(filePath, \"utf8\")).data;\n } catch {\n return [];\n }\n const out: string[] = [];\n const collect = (v: unknown) => {\n if (Array.isArray(v))\n for (const x of v) if (typeof x === \"string\" && x.trim()) out.push(x.trim());\n };\n collect(meta.requires);\n collect((meta.metadata as Record<string, unknown> | undefined)?.requires);\n collect(meta.dependencies);\n return [...new Set(out)];\n}\n\n/**\n * Parse a `CONTRACT.md` file into a `CatalogEntry` with `kind: \"contract\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * @param filePath - Absolute path to the `CONTRACT.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"contract\"`\n * @docLink packages/core/concepts#from-contract-md\n */\nexport function fromContractMd(filePath: string, repoName: string): CatalogEntry {\n const { data: meta } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"contract\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse an `MCP.md` file into a `CatalogEntry` with `kind: \"mcp-server\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * Frontmatter fields (catalog identity):\n * - `name` — server name (default: parent dir name)\n * - `description` — short description\n * - `version` — semver\n * - `keywords` — array of discovery tags\n *\n * Frontmatter fields (runtime defaults, stored in `metadata`):\n * - `transport` — \"stdio\" | \"sse\" | \"http\" (default: \"stdio\")\n * - `command` — command to execute (stdio)\n * - `args` — command arguments (stdio)\n * - `env` — environment variables (stdio)\n * - `url` — server URL (sse/http)\n * - `headers` — HTTP headers (sse/http)\n *\n * When `mcp:name` appears in `skaile.yaml` `dependencies`, the runner reads\n * these defaults from `metadata` to build a `McpServerDeclaration` without\n * requiring verbose inline config.\n *\n * @param filePath - Absolute path to the `MCP.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"mcp-server\"`\n * @docLink packages/core/concepts#from-mcp-server-md\n */\nexport function fromMcpServerMd(filePath: string, repoName: string): CatalogEntry {\n return fromMcpServerMdContent(readFileSync(filePath, \"utf8\"), repoName, filePath);\n}\n\n/**\n * Parse pre-read MCP.md content into a `CatalogEntry`.\n * Callers that already hold the file content (e.g. to avoid a second read) use\n * this directly; `fromMcpServerMd` is a thin wrapper that reads then delegates here.\n *\n * @param content - UTF-8 content of the `MCP.md` file\n * @param repoName - Repository name used as the `publisher` field of the entry\n * @param filePath - Absolute path (used as `source` and for name fallback)\n * @returns Populated `CatalogEntry` with kind `\"mcp-server\"`\n */\nexport function fromMcpServerMdContent(\n content: string,\n repoName: string,\n filePath: string,\n): CatalogEntry {\n const { data: meta } = parseFrontmatter(content);\n\n // Extract runtime defaults into metadata\n const metadata: Record<string, unknown> = {};\n if (meta.transport) metadata.transport = String(meta.transport);\n if (meta.command) metadata.command = String(meta.command);\n if (Array.isArray(meta.args)) metadata.args = meta.args.map(String);\n if (meta.env && typeof meta.env === \"object\" && !Array.isArray(meta.env)) {\n metadata.env = meta.env as Record<string, string>;\n }\n if (meta.url) metadata.url = String(meta.url);\n if (meta.headers && typeof meta.headers === \"object\" && !Array.isArray(meta.headers)) {\n metadata.headers = meta.headers as Record<string, string>;\n }\n if (meta.recipe && typeof meta.recipe === \"object\" && !Array.isArray(meta.recipe)) {\n metadata.recipe = meta.recipe;\n }\n\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"mcp-server\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n };\n}\n\n/**\n * Parse a `knowledge.yaml` file into a `CatalogEntry` with `kind: \"knowledge\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * @param filePath - Absolute path to the `knowledge.yaml` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"knowledge\"`\n * @docLink packages/core/concepts#from-knowledge-yaml\n */\nexport function fromKnowledgeYaml(filePath: string, repoName: string): CatalogEntry {\n let meta: Record<string, unknown> = {};\n try {\n meta = (parse(readFileSync(filePath, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {}\n return {\n name: String(meta.name ?? basename(dirname(filePath))),\n kind: \"knowledge\",\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: String(meta.version ?? \"\"),\n requires: parseRequires(meta),\n dependencies: [],\n };\n}\n\n/**\n * Parse a `CONNECTOR.md` file into a `CatalogEntry` with `kind: \"connector\"`.\n * Falls back to the parent directory name when `name:` is absent.\n *\n * Frontmatter fields (catalog identity):\n * - `name` — connector name (default: parent dir name)\n * - `description` — short description\n * - `version` — semver\n *\n * Frontmatter fields (runtime defaults, stored in `metadata`):\n * - `entry` — adapter entry point (default: \"./adapter.ts\")\n * - `npm_deps` — npm dependencies required by the adapter\n * - `fields` — configuration fields the adapter expects\n * - `health_check` — whether to run a health check on connect\n *\n * The markdown body (below the frontmatter) is stored in `metadata.body`\n * so the runner can inject the connector's skill description into the\n * system prompt when `expose_as_skill` is enabled.\n *\n * @param filePath - Absolute path to the `CONNECTOR.md` file\n * @param repoName - Repository name used as the `repository` field of the entry\n * @returns Populated `CatalogEntry` with kind `\"connector\"`\n * @docLink packages/core/concepts#from-connector-md\n */\nexport function fromConnectorMd(filePath: string, repoName: string): CatalogEntry {\n const text = readFileSync(filePath, \"utf-8\");\n const { data: meta, body } = parseFrontmatter(text);\n const name = String(meta.name ?? basename(dirname(filePath)));\n return {\n name,\n kind: \"connector\" as AssetKind,\n description: String(meta.description ?? \"\"),\n source: filePath,\n publisher: repoName,\n version: extractVersion(meta),\n requires: parseRequires(meta),\n dependencies: [],\n metadata: {\n entry: meta.entry ?? \"./adapter.ts\",\n npm_deps: meta.npm_deps ?? {},\n fields: meta.fields ?? [],\n health_check: meta.health_check ?? null,\n body,\n },\n };\n}\n\n// ── Recursive walker ──────────────────────────────────────────────────────────\n\ninterface WalkEntry {\n path: string;\n name: string;\n}\n\n/**\n * Recursively yield every file entry under `dir`, sorted alphabetically at each level.\n * Skips `.git` and `node_modules` directories and follows symlinks (resolving to\n * the stat target). `node_modules` is excluded because Bun's `node_modules/.bun/...`\n * layout contains symlink farms that form cycles when packages reference each other\n * transitively — entering them causes unbounded recursion in this walker.\n *\n * @param dir - Absolute path to the directory to walk\n * @docLink packages/core/concepts#walk-dir\n */\nexport function* walkDir(dir: string): Generator<WalkEntry> {\n let dirEntries: import(\"node:fs\").Dirent<string>[];\n try {\n dirEntries = readdirSync(dir, { withFileTypes: true, encoding: \"utf8\" });\n } catch {\n return;\n }\n for (const e of dirEntries.sort((a, b) => (a.name < b.name ? -1 : 1))) {\n const full = join(dir, e.name);\n if (e.isSymbolicLink()) {\n try {\n if (statSync(full).isDirectory()) yield* walkDir(full);\n else yield { path: full, name: e.name };\n } catch {}\n } else if (e.isDirectory()) {\n if (e.name !== \".git\" && e.name !== \"node_modules\") yield* walkDir(full);\n } else if (e.isFile()) {\n yield { path: full, name: e.name };\n }\n }\n}\n\n// ── Public scanner ────────────────────────────────────────────────────────────\n\n/**\n * Walk `root` recursively and return a `CatalogEntry` for every recognized asset manifest found.\n *\n * Recognized filenames: `SKILL.md`, `AGENT.md`, `agent.yaml`, `CONTRACT.md`, `MCP.md`,\n * `CONNECTOR.md`, `*.prompt.md`, `*.bundle.yaml`, `*.flow.yaml`, `*.flow.json`.\n *\n * When two entries share the same `kind:name` key, the one with the alphabetically\n * later source path wins (consistent with catalog precedence rules).\n *\n * @param root - Absolute path to the directory tree to scan\n * @param repoName - Repository name attached to every produced entry\n * @returns Array of deduplicated `CatalogEntry` objects, one per manifest file\n * @docLink packages/core/concepts#scan-directory\n */\n/**\n * Coerce a scanned entry's `name` to a canonical asset name in place. When the\n * raw name is already canonical this is a no-op; otherwise the original is stashed\n * on `metadata.displayName` (only when not already set) so callers keep the pretty\n * label for display while identity uses the slug. A name that slugifies to empty\n * is left untouched — `parseAssetRef` will reject it downstream with its full hint.\n */\nfunction normalizeEntryName(e: CatalogEntry): void {\n if (isValidAssetName(e.name)) return;\n let slug: string;\n try {\n slug = slugifyAssetName(e.name);\n } catch {\n return;\n }\n const original = e.name;\n e.name = slug;\n if (e.metadata?.displayName === undefined) {\n e.metadata = { ...e.metadata, displayName: original };\n }\n}\n\nexport function scanDirectory(root: string, repoName: string): CatalogEntry[] {\n const entries = new Map<string, CatalogEntry>();\n\n function add(e: CatalogEntry): void {\n // Boundary normalization: a third-party source we don't control may name an\n // asset with a human-styled identity (\"Complex App\"). Slugify it to a\n // canonical name so the ref it produces parses, preserving the original on\n // `metadata.displayName` for display. No-op for already-canonical names.\n normalizeEntryName(e);\n const key = `${e.kind}:${e.name}`;\n const existing = entries.get(key);\n if (!existing) {\n entries.set(key, e);\n return;\n }\n // Among duplicates, alphabetically later source path wins\n if (e.source > existing.source) entries.set(key, e);\n }\n\n for (const { path: filePath, name } of walkDir(root)) {\n try {\n if (name === \"SKILL.md\") add(fromSkillMd(filePath, repoName));\n else if (name === \"AGENT.md\") add(fromAgentMd(filePath, repoName));\n else if (name === \"agent.yaml\") add(fromAgentYaml(filePath, repoName));\n else if (name === \"CONTRACT.md\") add(fromContractMd(filePath, repoName));\n else if (name === \"MCP.md\") add(fromMcpServerMd(filePath, repoName));\n else if (name === \"CONNECTOR.md\") add(fromConnectorMd(filePath, repoName));\n else if (name === \"knowledge.yaml\") add(fromKnowledgeYaml(filePath, repoName));\n else if (name.endsWith(\".prompt.md\")) add(fromPromptMd(filePath, repoName));\n else if (name.endsWith(\".bundle.yaml\")) add(fromBundleYaml(filePath, repoName));\n else if (name.endsWith(\".flow.yaml\") || name.endsWith(\".flow.json\"))\n add(fromFlowYaml(filePath, repoName));\n } catch {}\n }\n\n return [...entries.values()];\n}\n"]}
|