@unbrained/pm-cli 2026.7.17 → 2026.7.18
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +13 -0
- package/dist/cli/commands/close.d.ts +1 -1
- package/dist/cli/commands/close.js +3 -3
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/completion.js +47 -5
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/context.d.ts +2 -2
- package/dist/cli/commands/context.js +42 -28
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/contracts.js +5 -3
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/graph.d.ts +7 -0
- package/dist/cli/commands/graph.js +11 -0
- package/dist/cli/commands/graph.js.map +1 -0
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.js +3 -2
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/next.d.ts +1 -1
- package/dist/cli/commands/next.js +3 -3
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/main.js +3 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +49 -7
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +7 -3
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli-bundle/bundle-manifest.json +157 -149
- package/dist/cli-bundle/chunks/{chunk-N7I2DGLP.js → chunk-35FHWD4C.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-37V5MXAU.js.map → chunk-35FHWD4C.js.map} +1 -7
- package/dist/cli-bundle/chunks/{chunk-MSGETE6I.js → chunk-3CUQZNQ6.js} +67 -509
- package/dist/cli-bundle/chunks/chunk-3CUQZNQ6.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-3QDR6ZLU.js +800 -0
- package/dist/cli-bundle/chunks/chunk-3QDR6ZLU.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-QNUAZYGW.js → chunk-43UMFKCK.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-HF63SBLC.js → chunk-6VHUGVNP.js} +39 -16
- package/dist/cli-bundle/chunks/chunk-6VHUGVNP.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-B6SH2YNN.js → chunk-7R6UIHYY.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NCAFUBJX.js → chunk-7UCY6DR5.js} +183 -12
- package/dist/cli-bundle/chunks/chunk-7UCY6DR5.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-23TCGBRK.js → chunk-ADXDCAKP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7LTCLTRG.js → chunk-AXRT7K5V.js} +16 -3
- package/dist/cli-bundle/chunks/chunk-AXRT7K5V.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-P56LKFQX.js → chunk-BDA35QG5.js} +34 -4
- package/dist/cli-bundle/chunks/chunk-BDA35QG5.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-2MPMKJF2.js → chunk-DHNG452T.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-AFSV5HBB.js → chunk-E4FXM2XB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-QKVVV6QO.js → chunk-EWIT5WIC.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-EX7OQT3Y.js +783 -0
- package/dist/cli-bundle/chunks/chunk-EX7OQT3Y.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-LLODAQMP.js → chunk-F3VC3GOV.js} +41 -18
- package/dist/cli-bundle/chunks/chunk-F3VC3GOV.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-S46R2M3W.js → chunk-GKPCTQYG.js} +1709 -5
- package/dist/cli-bundle/chunks/chunk-GKPCTQYG.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-HXVHBERL.js → chunk-HPAYDSR2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XNPMDSQQ.js → chunk-HYTOJW2Q.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-V3VBXQQV.js → chunk-I3INI567.js} +516 -429
- package/dist/cli-bundle/chunks/chunk-I3INI567.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-V7MP6YTN.js → chunk-IL5SPRMH.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-YQCWK2MB.js → chunk-L5BTTDU5.js} +68 -503
- package/dist/cli-bundle/chunks/chunk-L5BTTDU5.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-SIJV365F.js → chunk-NCVT6XEL.js} +17 -4
- package/dist/cli-bundle/chunks/chunk-NCVT6XEL.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-DCC2AQBD.js → chunk-OGVTB5VO.js} +32 -31
- package/dist/cli-bundle/chunks/chunk-OGVTB5VO.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-6XAZB6SE.js → chunk-QPGQNLPI.js} +1660 -7
- package/dist/cli-bundle/chunks/chunk-QPGQNLPI.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-KOEZCHRF.js → chunk-QRZNCRNA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-G6KM4YKY.js → chunk-RXPQ5Q23.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-7CTQ7WW5.js → chunk-SIPOACV5.js} +514 -427
- package/dist/cli-bundle/chunks/chunk-SIPOACV5.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-XYJK6GIQ.js → chunk-TGBTLGPX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-37V5MXAU.js → chunk-TLWJP5BF.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-TLWJP5BF.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-3D4YVTNG.js → chunk-TZAE66GQ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-S6FF7VW6.js → chunk-WQXRZMFN.js} +187 -16
- package/dist/cli-bundle/chunks/chunk-WQXRZMFN.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-SPFZV2GR.js → chunk-XPUTSGJU.js} +32 -31
- package/dist/cli-bundle/chunks/chunk-XPUTSGJU.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-CFSUNEL7.js → chunk-XWBD6DSR.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-MNV226E4.js → chunk-XWYQ2LT4.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-I7GY4X6Y.js → chunk-YFE7JHX3.js} +26 -5
- package/dist/cli-bundle/chunks/chunk-YFE7JHX3.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-FZGM3PNA.js → chunk-YIIIAKCE.js} +2 -2
- package/dist/cli-bundle/chunks/{close-BEP7MHF3.js → close-GPD7DTJV.js} +3 -3
- package/dist/cli-bundle/chunks/{close-Y6QFUJQN.js → close-X3CF6FQP.js} +3 -3
- package/dist/cli-bundle/chunks/{close-many-JJFW7KTT.js → close-many-J7A5EHOQ.js} +5 -5
- package/dist/cli-bundle/chunks/{close-many-QJ6FKJUE.js → close-many-NQLYGPYW.js} +5 -5
- package/dist/cli-bundle/chunks/{deps-EVTOQMKW.js → deps-MQ4ZIGZB.js} +13 -4
- package/dist/cli-bundle/chunks/{deps-5NC4IZH7.js → deps-NIIKXLPB.js} +13 -4
- package/dist/cli-bundle/chunks/{profile-U2B6Y7GE.js → profile-AVCIIZID.js} +3 -3
- package/dist/cli-bundle/chunks/{profile-AGUKS52S.js → profile-LFYO3HHX.js} +3 -3
- package/dist/cli-bundle/chunks/{register-list-query-A5KRJ5J2.js → register-list-query-MZUF2EEC.js} +41 -13
- package/dist/cli-bundle/chunks/register-list-query-MZUF2EEC.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-list-query-NEYP3TXO.js → register-list-query-UKMF55FT.js} +40 -12
- package/dist/cli-bundle/chunks/register-list-query-UKMF55FT.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-mutation-6LOPBAHC.js → register-mutation-2PBW2GEX.js} +15 -13
- package/dist/cli-bundle/chunks/register-mutation-2PBW2GEX.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-mutation-GCZOALNJ.js → register-mutation-T6RVNJC4.js} +14 -12
- package/dist/cli-bundle/chunks/{register-mutation-GCZOALNJ.js.map → register-mutation-T6RVNJC4.js.map} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-6ZZIF27A.js → register-operations-KHZYR6MG.js} +11 -11
- package/dist/cli-bundle/chunks/{register-operations-REDIAEGI.js → register-operations-WPQ2LWZJ.js} +11 -11
- package/dist/cli-bundle/chunks/{register-setup-J3JS2ZVT.js → register-setup-PGDNOXDQ.js} +5 -5
- package/dist/cli-bundle/chunks/{register-setup-BHPMN5SK.js → register-setup-TDN7WAO6.js} +5 -5
- package/dist/cli-bundle/chunks/{update-SA6AG23P.js → update-SQYZA3ZW.js} +4 -4
- package/dist/cli-bundle/chunks/{update-PQQHLYCC.js → update-XZJYS5X7.js} +4 -4
- package/dist/cli-bundle/chunks/{update-many-RQVTFJPD.js → update-many-R24B3GBK.js} +6 -6
- package/dist/cli-bundle/chunks/{update-many-TV3L3KBX.js → update-many-WQ3R3J6N.js} +6 -6
- package/dist/cli-bundle/main.js +25 -9
- package/dist/cli-bundle/main.js.map +2 -2
- package/dist/cli-bundle/sdk-runtime.js +19 -16
- package/dist/cli-bundle/sdk.js +95 -305
- package/dist/cli-bundle/sdk.js.map +4 -4
- package/dist/core/item/actionability.d.ts +12 -0
- package/dist/core/item/actionability.js +39 -4
- package/dist/core/item/actionability.js.map +1 -1
- package/dist/core/sentry/instrument.d.ts +11 -0
- package/dist/core/sentry/instrument.js +21 -2
- package/dist/core/sentry/instrument.js.map +1 -1
- package/dist/mcp/server.d.ts +16 -18
- package/dist/mcp/server.js +84 -31
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-definitions.js +17 -4
- package/dist/mcp/tool-definitions.js.map +1 -1
- package/dist/sdk/actionability.d.ts +10 -0
- package/dist/sdk/actionability.js +14 -0
- package/dist/sdk/actionability.js.map +1 -0
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +6 -2
- package/dist/sdk/cli-contracts/enum-contracts.js +19 -2
- package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +21 -2
- package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +16 -2
- package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +80 -3
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-schema.d.ts +20 -0
- package/dist/sdk/cli-contracts/tool-schema.js +97 -9
- package/dist/sdk/cli-contracts/tool-schema.js.map +1 -1
- package/dist/sdk/cli-contracts.d.ts +2 -2
- package/dist/sdk/cli-contracts.js +4 -4
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/dependencies.d.ts +42 -53
- package/dist/sdk/dependencies.js +177 -125
- package/dist/sdk/dependencies.js.map +1 -1
- package/dist/sdk/governance/validate.js +3 -3
- package/dist/sdk/governance/validate.js.map +1 -1
- package/dist/sdk/graph/analytics.d.ts +124 -0
- package/dist/sdk/graph/analytics.js +464 -0
- package/dist/sdk/graph/analytics.js.map +1 -0
- package/dist/sdk/graph/assembly.d.ts +97 -0
- package/dist/sdk/graph/assembly.js +146 -0
- package/dist/sdk/graph/assembly.js.map +1 -0
- package/dist/sdk/graph/cache.d.ts +66 -0
- package/dist/sdk/graph/cache.js +148 -0
- package/dist/sdk/graph/cache.js.map +1 -0
- package/dist/sdk/graph/governance.d.ts +108 -0
- package/dist/sdk/graph/governance.js +360 -0
- package/dist/sdk/graph/governance.js.map +1 -0
- package/dist/sdk/graph/index.d.ts +16 -0
- package/dist/sdk/graph/index.js +20 -0
- package/dist/sdk/graph/index.js.map +1 -0
- package/dist/sdk/graph/remediation.d.ts +52 -0
- package/dist/sdk/graph/remediation.js +148 -0
- package/dist/sdk/graph/remediation.js.map +1 -0
- package/dist/sdk/graph/run.d.ts +295 -0
- package/dist/sdk/graph/run.js +468 -0
- package/dist/sdk/graph/run.js.map +1 -0
- package/dist/sdk/graph/traversal.d.ts +77 -0
- package/dist/sdk/graph/traversal.js +262 -0
- package/dist/sdk/graph/traversal.js.map +1 -0
- package/dist/sdk/index.d.ts +4 -2
- package/dist/sdk/index.js +6 -4
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/query/list.d.ts +8 -0
- package/dist/sdk/query/list.js +19 -3
- package/dist/sdk/query/list.js.map +1 -1
- package/dist/sdk/relationship-context.d.ts +42 -0
- package/dist/sdk/relationship-context.js +99 -20
- package/dist/sdk/relationship-context.js.map +1 -1
- package/dist/sdk/relationships.d.ts +13 -0
- package/dist/sdk/relationships.js +30 -2
- package/dist/sdk/relationships.js.map +1 -1
- package/dist/sdk/runtime-input.d.ts +41 -0
- package/dist/sdk/runtime-input.js +422 -2
- package/dist/sdk/runtime-input.js.map +1 -1
- package/dist/sdk/runtime.d.ts +12 -23
- package/dist/sdk/runtime.js +19 -371
- package/dist/sdk/runtime.js.map +1 -1
- package/dist/sdk/test/linked-command-detection.js +12 -3
- package/dist/sdk/test/linked-command-detection.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -0
- package/docs/COMMANDS.md +19 -1
- package/docs/RELATIONSHIP_GRAPH.md +99 -3
- package/docs/SDK.md +17 -3
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/dist/cli-bundle/chunks/chunk-6XAZB6SE.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-7CTQ7WW5.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-7LTCLTRG.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-DCC2AQBD.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-HF63SBLC.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-I7GY4X6Y.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-LLODAQMP.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-MSGETE6I.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-N7I2DGLP.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-NCAFUBJX.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-P56LKFQX.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-S46R2M3W.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-S6FF7VW6.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-SIJV365F.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-SPFZV2GR.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-V3VBXQQV.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-YQCWK2MB.js.map +0 -1
- package/dist/cli-bundle/chunks/register-list-query-A5KRJ5J2.js.map +0 -1
- package/dist/cli-bundle/chunks/register-list-query-NEYP3TXO.js.map +0 -7
- package/dist/cli-bundle/chunks/register-mutation-6LOPBAHC.js.map +0 -1
- /package/dist/cli-bundle/chunks/{chunk-QNUAZYGW.js.map → chunk-43UMFKCK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-B6SH2YNN.js.map → chunk-7R6UIHYY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-23TCGBRK.js.map → chunk-ADXDCAKP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-2MPMKJF2.js.map → chunk-DHNG452T.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AFSV5HBB.js.map → chunk-E4FXM2XB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QKVVV6QO.js.map → chunk-EWIT5WIC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HXVHBERL.js.map → chunk-HPAYDSR2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XNPMDSQQ.js.map → chunk-HYTOJW2Q.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-V7MP6YTN.js.map → chunk-IL5SPRMH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KOEZCHRF.js.map → chunk-QRZNCRNA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-G6KM4YKY.js.map → chunk-RXPQ5Q23.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XYJK6GIQ.js.map → chunk-TGBTLGPX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3D4YVTNG.js.map → chunk-TZAE66GQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-CFSUNEL7.js.map → chunk-XWBD6DSR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-MNV226E4.js.map → chunk-XWYQ2LT4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FZGM3PNA.js.map → chunk-YIIIAKCE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-BEP7MHF3.js.map → close-GPD7DTJV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-Y6QFUJQN.js.map → close-X3CF6FQP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-JJFW7KTT.js.map → close-many-J7A5EHOQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-QJ6FKJUE.js.map → close-many-NQLYGPYW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-EVTOQMKW.js.map → deps-MQ4ZIGZB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-5NC4IZH7.js.map → deps-NIIKXLPB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-U2B6Y7GE.js.map → profile-AVCIIZID.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-AGUKS52S.js.map → profile-LFYO3HHX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-operations-6ZZIF27A.js.map → register-operations-KHZYR6MG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-operations-REDIAEGI.js.map → register-operations-WPQ2LWZJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-J3JS2ZVT.js.map → register-setup-PGDNOXDQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-BHPMN5SK.js.map → register-setup-TDN7WAO6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-SA6AG23P.js.map → update-SQYZA3ZW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-PQQHLYCC.js.map → update-XZJYS5X7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-RQVTFJPD.js.map → update-many-R24B3GBK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-TV3L3KBX.js.map → update-many-WQ3R3J6N.js.map} +0 -0
|
@@ -5,9 +5,18 @@
|
|
|
5
5
|
* packet for agents, custom tools, and presentation-layer adapters.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
8
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="cf26c4d0-d60f-5ec5-858f-957ad719383e")}catch(e){}}();
|
|
9
9
|
import { createQueryFingerprint, encodeQueryCursor, resolveQueryCursorStart, } from "./pagination.js";
|
|
10
10
|
import { createRelationshipKindRegistry, } from "./relationships.js";
|
|
11
|
+
/** Deterministic priority used when one node matches several semantic families. */
|
|
12
|
+
const RELATIONSHIP_CONTEXT_ROLE_PRIORITY = [
|
|
13
|
+
"prerequisite",
|
|
14
|
+
"dependent",
|
|
15
|
+
"ancestor",
|
|
16
|
+
"descendant",
|
|
17
|
+
"provenance",
|
|
18
|
+
"related",
|
|
19
|
+
];
|
|
11
20
|
const tokenEncoder = new TextEncoder();
|
|
12
21
|
function positiveInteger(value, fallback, field) {
|
|
13
22
|
const resolved = value ?? fallback;
|
|
@@ -18,16 +27,16 @@ function positiveInteger(value, fallback, field) {
|
|
|
18
27
|
function estimateTokens(value) {
|
|
19
28
|
return Math.max(1, Math.ceil(tokenEncoder.encode(JSON.stringify(value)).byteLength / 4));
|
|
20
29
|
}
|
|
21
|
-
function explainDirectEdge(edge,
|
|
22
|
-
const definition = registry.
|
|
23
|
-
if (definition
|
|
30
|
+
function explainDirectEdge(edge, node, registry) {
|
|
31
|
+
const definition = registry.resolve(edge.kind);
|
|
32
|
+
if (definition?.ordering) {
|
|
24
33
|
// Legacy and JSON-parsed definitions may predate explicit precedence.
|
|
25
34
|
const sourceFirst = (definition.precedence ?? "source_before_target") ===
|
|
26
35
|
"source_before_target";
|
|
27
36
|
const before = sourceFirst ? edge.source : edge.target;
|
|
28
37
|
return node === before ? "prerequisite" : "dependent";
|
|
29
38
|
}
|
|
30
|
-
if (definition
|
|
39
|
+
if (definition?.hierarchy) {
|
|
31
40
|
// Legacy and JSON-parsed definitions may predate explicit hierarchy direction.
|
|
32
41
|
const sourceIsParent = (definition.hierarchyDirection ?? "source_parent") === "source_parent";
|
|
33
42
|
const parent = sourceIsParent ? edge.source : edge.target;
|
|
@@ -41,16 +50,24 @@ function directReasons(rootEdges, root, node, registry) {
|
|
|
41
50
|
const reasons = rootEdges
|
|
42
51
|
.filter((edge) => (edge.source === root && edge.target === node) ||
|
|
43
52
|
(edge.target === root && edge.source === node))
|
|
44
|
-
.map((edge) => explainDirectEdge(edge,
|
|
53
|
+
.map((edge) => explainDirectEdge(edge, node, registry));
|
|
45
54
|
return [...new Set(reasons)].sort();
|
|
46
55
|
}
|
|
47
|
-
|
|
56
|
+
/** Pick the deterministic primary family when a node matches several. */
|
|
57
|
+
function primaryRole(roles) {
|
|
58
|
+
// Callers only pass non-empty classification sets drawn from the fixed
|
|
59
|
+
// family list, so a priority match always exists.
|
|
60
|
+
return RELATIONSHIP_CONTEXT_ROLE_PRIORITY.find((role) => roles.includes(role));
|
|
61
|
+
}
|
|
62
|
+
function discoverNodes(graph, root, registry, options) {
|
|
48
63
|
const direction = options.direction ?? "both";
|
|
49
64
|
const maxDepth = options.maxDepth ?? 3;
|
|
50
65
|
if (!Number.isInteger(maxDepth) || maxDepth < 0)
|
|
51
66
|
throw new TypeError("Relationship context maxDepth must be non-negative");
|
|
52
67
|
const seen = new Set([root]);
|
|
53
|
-
const queue = [
|
|
68
|
+
const queue = [
|
|
69
|
+
{ id: root, distance: 0 },
|
|
70
|
+
];
|
|
54
71
|
const rows = [];
|
|
55
72
|
let inspectedEdges = 0;
|
|
56
73
|
let depthTruncated = false;
|
|
@@ -59,22 +76,27 @@ function discoverNodes(graph, root, options) {
|
|
|
59
76
|
const current = queue[index];
|
|
60
77
|
if (current.distance >= maxDepth && depthTruncated)
|
|
61
78
|
continue;
|
|
62
|
-
const adjacent = graph.
|
|
79
|
+
const adjacent = graph.neighborEdges(current.id, {
|
|
63
80
|
direction,
|
|
64
81
|
kinds: options.kinds,
|
|
65
82
|
signal: options.signal,
|
|
66
83
|
});
|
|
67
84
|
inspectedEdges += adjacent.meta.inspectedEdges;
|
|
68
85
|
if (current.distance >= maxDepth) {
|
|
69
|
-
if (adjacent.value.some((
|
|
86
|
+
if (adjacent.value.some((row) => !seen.has(row.id)))
|
|
70
87
|
depthTruncated = true;
|
|
71
88
|
continue;
|
|
72
89
|
}
|
|
73
|
-
for (const id of adjacent.value) {
|
|
90
|
+
for (const { id, edge } of adjacent.value) {
|
|
74
91
|
if (seen.has(id))
|
|
75
92
|
continue;
|
|
76
93
|
seen.add(id);
|
|
77
|
-
const row = {
|
|
94
|
+
const row = {
|
|
95
|
+
id,
|
|
96
|
+
distance: current.distance + 1,
|
|
97
|
+
via: current.id,
|
|
98
|
+
role: explainDirectEdge(edge, id, registry),
|
|
99
|
+
};
|
|
78
100
|
rows.push(row);
|
|
79
101
|
queue.push(row);
|
|
80
102
|
}
|
|
@@ -87,19 +109,48 @@ function discoverNodes(graph, root, options) {
|
|
|
87
109
|
depthTruncated,
|
|
88
110
|
};
|
|
89
111
|
}
|
|
112
|
+
/** Count root-incident edges per semantic family under the active filters. */
|
|
113
|
+
function summarizeDirectEdges(graph, root, registry, options) {
|
|
114
|
+
const directEdges = {
|
|
115
|
+
prerequisite: 0,
|
|
116
|
+
dependent: 0,
|
|
117
|
+
ancestor: 0,
|
|
118
|
+
descendant: 0,
|
|
119
|
+
provenance: 0,
|
|
120
|
+
related: 0,
|
|
121
|
+
};
|
|
122
|
+
const rows = graph.neighborEdges(root, {
|
|
123
|
+
direction: options.direction ?? "both",
|
|
124
|
+
kinds: options.kinds,
|
|
125
|
+
signal: options.signal,
|
|
126
|
+
}).value;
|
|
127
|
+
for (const { id, edge } of rows)
|
|
128
|
+
directEdges[explainDirectEdge(edge, id, registry)] += 1;
|
|
129
|
+
return {
|
|
130
|
+
directEdges,
|
|
131
|
+
directTotal: rows.length,
|
|
132
|
+
rootEdges: rows.map(({ edge }) => edge),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
90
135
|
function selectContextNodes(params) {
|
|
91
136
|
const nodes = [];
|
|
92
137
|
let usedTokens = params.initialTokens;
|
|
93
|
-
const rootEdges = params.graph.incidentEdges(params.rootId);
|
|
94
138
|
for (const candidate of params.candidates) {
|
|
95
139
|
if (nodes.length >= params.nodeLimit)
|
|
96
140
|
break;
|
|
141
|
+
const direct = candidate.distance === 1
|
|
142
|
+
? directReasons(params.rootEdges, params.rootId, candidate.id, params.registry)
|
|
143
|
+
: [];
|
|
97
144
|
const node = {
|
|
98
145
|
...(params.details.get(candidate.id) ?? { id: candidate.id }),
|
|
99
146
|
distance: candidate.distance,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
147
|
+
role: direct.length > 0 ? primaryRole(direct) : candidate.role,
|
|
148
|
+
via: candidate.via,
|
|
149
|
+
reasons: direct.length > 0
|
|
150
|
+
? direct
|
|
151
|
+
: [
|
|
152
|
+
`${candidate.role} via ${candidate.via} (depth ${candidate.distance})`,
|
|
153
|
+
],
|
|
103
154
|
};
|
|
104
155
|
const cost = estimateTokens(node);
|
|
105
156
|
if (usedTokens + cost > params.tokenBudget)
|
|
@@ -112,9 +163,20 @@ function selectContextNodes(params) {
|
|
|
112
163
|
return { nodes, usedTokens };
|
|
113
164
|
}
|
|
114
165
|
function selectContextEdges(params) {
|
|
166
|
+
const kinds = params.options.kinds
|
|
167
|
+
? new Set(params.options.kinds.map((kind) => params.registry.require(kind).kind))
|
|
168
|
+
: undefined;
|
|
115
169
|
const candidates = params.graph
|
|
116
170
|
.edges()
|
|
117
|
-
.filter((edge) =>
|
|
171
|
+
.filter((edge) => {
|
|
172
|
+
if (!params.included.has(edge.source) ||
|
|
173
|
+
!params.included.has(edge.target))
|
|
174
|
+
return false;
|
|
175
|
+
if (kinds === undefined || kinds.has(edge.kind))
|
|
176
|
+
return true;
|
|
177
|
+
const inverse = params.registry.resolve(edge.kind)?.inverse;
|
|
178
|
+
return inverse !== undefined && kinds.has(inverse);
|
|
179
|
+
});
|
|
118
180
|
const edges = [];
|
|
119
181
|
let usedTokens = params.initialTokens;
|
|
120
182
|
for (const edge of candidates) {
|
|
@@ -142,7 +204,8 @@ export function buildRelationshipContext(graph, rootId, details, options = {}) {
|
|
|
142
204
|
};
|
|
143
205
|
const { evidence: rootEvidence = [], ...root } = rootDetails;
|
|
144
206
|
const evidence = [...rootEvidence];
|
|
145
|
-
const discovery = discoverNodes(graph, rootId, options);
|
|
207
|
+
const discovery = discoverNodes(graph, rootId, registry, options);
|
|
208
|
+
const { rootEdges, ...directSummary } = summarizeDirectEdges(graph, rootId, registry, options);
|
|
146
209
|
const fingerprint = createQueryFingerprint("relationship-context", {
|
|
147
210
|
rootId,
|
|
148
211
|
direction: options.direction ?? "both",
|
|
@@ -157,7 +220,7 @@ export function buildRelationshipContext(graph, rootId, details, options = {}) {
|
|
|
157
220
|
const nodeSelection = selectContextNodes({
|
|
158
221
|
candidates,
|
|
159
222
|
details: byId,
|
|
160
|
-
|
|
223
|
+
rootEdges,
|
|
161
224
|
rootId,
|
|
162
225
|
registry,
|
|
163
226
|
nodeLimit,
|
|
@@ -169,6 +232,8 @@ export function buildRelationshipContext(graph, rootId, details, options = {}) {
|
|
|
169
232
|
const edgeSelection = selectContextEdges({
|
|
170
233
|
graph,
|
|
171
234
|
included,
|
|
235
|
+
options,
|
|
236
|
+
registry,
|
|
172
237
|
edgeLimit,
|
|
173
238
|
tokenBudget,
|
|
174
239
|
initialTokens: nodeSelection.usedTokens,
|
|
@@ -179,14 +244,28 @@ export function buildRelationshipContext(graph, rootId, details, options = {}) {
|
|
|
179
244
|
const lastNode = nodes.at(-1);
|
|
180
245
|
const omittedEdges = edgeSelection.candidateCount - edges.length;
|
|
181
246
|
const truncated = discovery.depthTruncated || hasMoreNodes || omittedEdges > 0;
|
|
247
|
+
const summary = {
|
|
248
|
+
rootId,
|
|
249
|
+
...(root.status === undefined ? {} : { rootStatus: root.status }),
|
|
250
|
+
...directSummary,
|
|
251
|
+
discoveredNodes: discovery.rows.length,
|
|
252
|
+
returnedNodes: nodes.length,
|
|
253
|
+
returnedEdges: edges.length,
|
|
254
|
+
omittedNodes: discovery.rows.length - consumed,
|
|
255
|
+
omittedEdges,
|
|
256
|
+
evidenceCount: evidence.length,
|
|
257
|
+
hasMore: hasMoreNodes,
|
|
258
|
+
};
|
|
182
259
|
return {
|
|
183
260
|
root,
|
|
261
|
+
summary,
|
|
184
262
|
nodes,
|
|
185
263
|
edges,
|
|
186
264
|
evidence,
|
|
187
265
|
meta: {
|
|
188
266
|
exact: true,
|
|
189
267
|
truncated,
|
|
268
|
+
completeness: truncated ? "truncated" : "complete",
|
|
190
269
|
nodeLimit,
|
|
191
270
|
edgeLimit,
|
|
192
271
|
tokenBudget,
|
|
@@ -204,4 +283,4 @@ export function buildRelationshipContext(graph, rootId, details, options = {}) {
|
|
|
204
283
|
};
|
|
205
284
|
}
|
|
206
285
|
//# sourceMappingURL=relationship-context.js.map
|
|
207
|
-
//# debugId=
|
|
286
|
+
//# debugId=cf26c4d0-d60f-5ec5-858f-957ad719383e
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relationship-context.js","sources":["sdk/relationship-context.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/relationship-context\n *\n * Assembles one explainable, cursorable, token-bounded relationship context\n * packet for agents, custom tools, and presentation-layer adapters.\n */\nimport {\n createQueryFingerprint,\n encodeQueryCursor,\n resolveQueryCursorStart,\n} from \"./pagination.js\";\nimport {\n RelationshipGraph,\n RelationshipKindRegistry,\n createRelationshipKindRegistry,\n type RelationshipEdge,\n type RelationshipTraversalDirection,\n} from \"./relationships.js\";\n\n/** Caller-owned compact node details joined into graph context. */\nexport interface RelationshipContextNodeDetails {\n /** Stable graph node identifier. */\n id: string;\n /** Optional display title. */\n title?: string;\n /** Optional lifecycle status. */\n status?: string;\n /** Optional evidence pointers such as files, tests, or history ids. */\n evidence?: readonly string[];\n}\n\n/** One selected graph-context node with explainable inclusion. */\nexport interface RelationshipContextNode extends RelationshipContextNodeDetails {\n /** Shortest bounded distance from the root. */\n distance: number;\n /** Concise deterministic reasons the node was selected. */\n reasons: string[];\n}\n\n/** Controls for bounded graph-context assembly. */\nexport interface RelationshipContextOptions {\n /** Traversal direction relative to each visited node. */\n direction?: RelationshipTraversalDirection;\n /** Optional registered kind filter. */\n kinds?: readonly string[];\n /** Maximum traversal depth. */\n maxDepth?: number;\n /** Maximum nodes returned in this page. */\n nodeLimit?: number;\n /** Maximum edges returned in this page. */\n edgeLimit?: number;\n /** Maximum estimated output tokens charged to rows and edges. */\n tokenBudget?: number;\n /** Opaque continuation from an equivalent query. */\n cursor?: string;\n /** Registry used to explain custom relationship semantics. */\n registry?: RelationshipKindRegistry;\n /** Abort signal checked during traversal. */\n signal?: AbortSignal;\n}\n\n/** Explainable graph context packet. */\nexport interface RelationshipContextResult {\n /** Root node details. */\n root: RelationshipContextNodeDetails;\n /** Bounded related-node page. */\n nodes: RelationshipContextNode[];\n /** Bounded edges whose endpoints are present in the packet. */\n edges: RelationshipEdge[];\n /** Root evidence pointers promoted for immediate consumption. */\n evidence: string[];\n /** Completeness, continuation, and cost envelope. */\n meta: {\n exact: true;\n truncated: boolean;\n nodeLimit: number;\n edgeLimit: number;\n tokenBudget: number;\n usedTokens: number;\n visitedNodes: number;\n inspectedEdges: number;\n omittedNodes: number;\n omittedEdges: number;\n nextCursor?: string;\n };\n}\n\ninterface DiscoveredNode {\n id: string;\n distance: number;\n}\n\nconst tokenEncoder = new TextEncoder();\n\nfunction positiveInteger(\n value: number | undefined,\n fallback: number,\n field: string,\n): number {\n const resolved = value ?? fallback;\n if (!Number.isInteger(resolved) || resolved < 1)\n throw new TypeError(`Relationship context ${field} must be positive`);\n return resolved;\n}\n\nfunction estimateTokens(value: unknown): number {\n return Math.max(\n 1,\n Math.ceil(tokenEncoder.encode(JSON.stringify(value)).byteLength / 4),\n );\n}\n\nfunction explainDirectEdge(\n edge: RelationshipEdge,\n root: string,\n node: string,\n registry: RelationshipKindRegistry,\n): string {\n const definition = registry.require(edge.kind);\n if (definition.ordering) {\n // Legacy and JSON-parsed definitions may predate explicit precedence.\n const sourceFirst =\n (definition.precedence ?? \"source_before_target\") ===\n \"source_before_target\";\n const before = sourceFirst ? edge.source : edge.target;\n return node === before ? \"prerequisite\" : \"dependent\";\n }\n if (definition.hierarchy) {\n // Legacy and JSON-parsed definitions may predate explicit hierarchy direction.\n const sourceIsParent =\n (definition.hierarchyDirection ?? \"source_parent\") === \"source_parent\";\n const parent = sourceIsParent ? edge.source : edge.target;\n return node === parent ? \"ancestor\" : \"descendant\";\n }\n if (edge.kind === \"discovered_from\" || edge.kind === \"incident_from\")\n return \"provenance\";\n return \"related\";\n}\n\nfunction directReasons(\n rootEdges: readonly RelationshipEdge[],\n root: string,\n node: string,\n registry: RelationshipKindRegistry,\n): string[] {\n const reasons = rootEdges\n .filter(\n (edge) =>\n (edge.source === root && edge.target === node) ||\n (edge.target === root && edge.source === node),\n )\n .map((edge) => explainDirectEdge(edge, root, node, registry));\n return [...new Set(reasons)].sort();\n}\n\nfunction discoverNodes(\n graph: RelationshipGraph,\n root: string,\n options: RelationshipContextOptions,\n): {\n rows: DiscoveredNode[];\n visitedNodes: number;\n inspectedEdges: number;\n depthTruncated: boolean;\n} {\n const direction = options.direction ?? \"both\";\n const maxDepth = options.maxDepth ?? 3;\n if (!Number.isInteger(maxDepth) || maxDepth < 0)\n throw new TypeError(\"Relationship context maxDepth must be non-negative\");\n const seen = new Set([root]);\n const queue = [{ id: root, distance: 0 }];\n const rows: DiscoveredNode[] = [];\n let inspectedEdges = 0;\n let depthTruncated = false;\n for (let index = 0; index < queue.length; index += 1) {\n options.signal?.throwIfAborted();\n const current = queue[index]!;\n if (current.distance >= maxDepth && depthTruncated) continue;\n const adjacent = graph.adjacency(current.id, {\n direction,\n kinds: options.kinds,\n signal: options.signal,\n });\n inspectedEdges += adjacent.meta.inspectedEdges;\n if (current.distance >= maxDepth) {\n if (adjacent.value.some((id) => !seen.has(id))) depthTruncated = true;\n continue;\n }\n for (const id of adjacent.value) {\n if (seen.has(id)) continue;\n seen.add(id);\n const row = { id, distance: current.distance + 1 };\n rows.push(row);\n queue.push(row);\n }\n }\n rows.sort(\n (left, right) =>\n left.distance - right.distance || left.id.localeCompare(right.id),\n );\n return {\n rows,\n visitedNodes: queue.length,\n inspectedEdges,\n depthTruncated,\n };\n}\n\nfunction selectContextNodes(params: {\n candidates: readonly DiscoveredNode[];\n details: ReadonlyMap<string, RelationshipContextNodeDetails>;\n graph: RelationshipGraph;\n rootId: string;\n registry: RelationshipKindRegistry;\n nodeLimit: number;\n tokenBudget: number;\n initialTokens: number;\n}): { nodes: RelationshipContextNode[]; usedTokens: number } {\n const nodes: RelationshipContextNode[] = [];\n let usedTokens = params.initialTokens;\n const rootEdges = params.graph.incidentEdges(params.rootId);\n for (const candidate of params.candidates) {\n if (nodes.length >= params.nodeLimit) break;\n const node: RelationshipContextNode = {\n ...(params.details.get(candidate.id) ?? { id: candidate.id }),\n distance: candidate.distance,\n reasons:\n candidate.distance === 1\n ? directReasons(\n rootEdges,\n params.rootId,\n candidate.id,\n params.registry,\n )\n : [`reachable at depth ${candidate.distance}`],\n };\n const cost = estimateTokens(node);\n if (usedTokens + cost > params.tokenBudget) break;\n nodes.push(node);\n usedTokens += cost;\n }\n if (params.candidates.length > 0 && nodes.length === 0)\n throw new TypeError(\"Relationship context tokenBudget cannot fit one node\");\n return { nodes, usedTokens };\n}\n\nfunction selectContextEdges(params: {\n graph: RelationshipGraph;\n included: ReadonlySet<string>;\n edgeLimit: number;\n tokenBudget: number;\n initialTokens: number;\n}): {\n edges: RelationshipEdge[];\n usedTokens: number;\n candidateCount: number;\n} {\n const candidates = params.graph\n .edges()\n .filter(\n (edge) =>\n params.included.has(edge.source) && params.included.has(edge.target),\n );\n const edges: RelationshipEdge[] = [];\n let usedTokens = params.initialTokens;\n for (const edge of candidates) {\n if (edges.length >= params.edgeLimit) break;\n const cost = estimateTokens(edge);\n if (usedTokens + cost > params.tokenBudget) break;\n edges.push(edge);\n usedTokens += cost;\n }\n return { edges, usedTokens, candidateCount: candidates.length };\n}\n\n/** Build one deterministic bounded graph-context packet with continuation. */\nexport function buildRelationshipContext(\n graph: RelationshipGraph,\n rootId: string,\n details: readonly RelationshipContextNodeDetails[],\n options: RelationshipContextOptions = {},\n): RelationshipContextResult {\n if (!graph.nodes().includes(rootId))\n throw new TypeError(`Relationship node not found: ${rootId}`);\n const nodeLimit = positiveInteger(options.nodeLimit, 20, \"nodeLimit\");\n const edgeLimit = positiveInteger(options.edgeLimit, 40, \"edgeLimit\");\n const tokenBudget = positiveInteger(options.tokenBudget, 1200, \"tokenBudget\");\n const registry = options.registry ?? createRelationshipKindRegistry();\n const byId = new Map(details.map((detail) => [detail.id, detail]));\n const rootDetails: RelationshipContextNodeDetails = byId.get(rootId) ?? {\n id: rootId,\n };\n const { evidence: rootEvidence = [], ...root } = rootDetails;\n const evidence = [...rootEvidence];\n const discovery = discoverNodes(graph, rootId, options);\n const fingerprint = createQueryFingerprint(\"relationship-context\", {\n rootId,\n direction: options.direction ?? \"both\",\n kinds: [...(options.kinds ?? [])].sort(),\n maxDepth: options.maxDepth ?? 3,\n });\n const pageStart = resolveQueryCursorStart(\n discovery.rows,\n options.cursor,\n fingerprint,\n ({ id }) => id,\n );\n const candidates = discovery.rows.slice(pageStart);\n const initialTokens = estimateTokens(root) + estimateTokens(evidence);\n if (initialTokens > tokenBudget)\n throw new TypeError(\n \"Relationship context tokenBudget cannot fit root and evidence\",\n );\n const nodeSelection = selectContextNodes({\n candidates,\n details: byId,\n graph,\n rootId,\n registry,\n nodeLimit,\n tokenBudget,\n initialTokens,\n });\n const { nodes } = nodeSelection;\n\n const included = new Set([rootId, ...nodes.map(({ id }) => id)]);\n const edgeSelection = selectContextEdges({\n graph,\n included,\n edgeLimit,\n tokenBudget,\n initialTokens: nodeSelection.usedTokens,\n });\n const { edges, usedTokens } = edgeSelection;\n\n const consumed = pageStart + nodes.length;\n const hasMoreNodes = consumed < discovery.rows.length;\n const lastNode = nodes.at(-1);\n const omittedEdges = edgeSelection.candidateCount - edges.length;\n const truncated =\n discovery.depthTruncated || hasMoreNodes || omittedEdges > 0;\n return {\n root,\n nodes,\n edges,\n evidence,\n meta: {\n exact: true,\n truncated,\n nodeLimit,\n edgeLimit,\n tokenBudget,\n usedTokens,\n visitedNodes: discovery.visitedNodes,\n inspectedEdges: discovery.inspectedEdges,\n omittedNodes: discovery.rows.length - consumed,\n omittedEdges,\n ...(hasMoreNodes && lastNode\n ? {\n nextCursor: encodeQueryCursor(\n fingerprint,\n lastNode.id,\n consumed - 1,\n ),\n }\n : {}),\n },\n };\n}\n"],"names":[],"mappings":"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","debugId":"dfd47ca8-a68d-50e1-9aba-638d974a0027"}
|
|
1
|
+
{"version":3,"file":"relationship-context.js","sources":["sdk/relationship-context.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/relationship-context\n *\n * Assembles one explainable, cursorable, token-bounded relationship context\n * packet for agents, custom tools, and presentation-layer adapters.\n */\nimport {\n createQueryFingerprint,\n encodeQueryCursor,\n resolveQueryCursorStart,\n} from \"./pagination.js\";\nimport {\n RelationshipGraph,\n RelationshipKindRegistry,\n createRelationshipKindRegistry,\n type RelationshipEdge,\n type RelationshipTraversalDirection,\n} from \"./relationships.js\";\n\n/** Semantic family explaining why a node or edge participates in graph context. */\nexport type RelationshipContextRole =\n | \"prerequisite\"\n | \"dependent\"\n | \"ancestor\"\n | \"descendant\"\n | \"provenance\"\n | \"related\";\n\n/**\n * Completeness marker for one graph-context packet.\n *\n * The exact in-memory kernel only produces \"complete\" and \"truncated\" today;\n * the remaining values are reserved so index-backed, sampled, or policy-redacted\n * providers can report their result quality through the same contract.\n */\nexport type RelationshipContextCompleteness =\n | \"complete\"\n | \"truncated\"\n | \"sampled\"\n | \"approximate\"\n | \"stale_index\"\n | \"redacted\";\n\n/** Caller-owned compact node details joined into graph context. */\nexport interface RelationshipContextNodeDetails {\n /** Stable graph node identifier. */\n id: string;\n /** Optional display title. */\n title?: string;\n /** Optional lifecycle status. */\n status?: string;\n /** Optional evidence pointers such as files, tests, or history ids. */\n evidence?: readonly string[];\n}\n\n/** One selected graph-context node with explainable inclusion. */\nexport interface RelationshipContextNode extends RelationshipContextNodeDetails {\n /** Shortest bounded distance from the root. */\n distance: number;\n /** Semantic family of this node relative to its discovery counterpart. */\n role: RelationshipContextRole;\n /** Node through which bounded traversal first discovered this node. */\n via: string;\n /** Concise deterministic reasons the node was selected. */\n reasons: string[];\n}\n\n/** Counts-first packet overview served before any row payload. */\nexport interface RelationshipContextSummary {\n /** Root node identifier. */\n rootId: string;\n /** Root lifecycle status when the caller supplied node details. */\n rootStatus?: string;\n /** Root-incident edge counts per semantic family under the active filters. */\n directEdges: Record<RelationshipContextRole, number>;\n /** Total root-incident edges under the active filters. */\n directTotal: number;\n /** Nodes discovered by the bounded traversal, excluding the root. */\n discoveredNodes: number;\n /** Nodes returned in this page. */\n returnedNodes: number;\n /** Edges returned in this page. */\n returnedEdges: number;\n /** Discovered nodes omitted by pagination, node, or token bounds. */\n omittedNodes: number;\n /** Qualifying edges omitted by edge or token bounds. */\n omittedEdges: number;\n /** Root evidence pointers promoted into the packet. */\n evidenceCount: number;\n /** Whether a continuation cursor is available. */\n hasMore: boolean;\n}\n\n/** Controls for bounded graph-context assembly. */\nexport interface RelationshipContextOptions {\n /** Traversal direction relative to each visited node. */\n direction?: RelationshipTraversalDirection;\n /** Optional registered kind filter. */\n kinds?: readonly string[];\n /** Maximum traversal depth. */\n maxDepth?: number;\n /** Maximum nodes returned in this page. */\n nodeLimit?: number;\n /** Maximum edges returned in this page. */\n edgeLimit?: number;\n /** Maximum estimated output tokens charged to rows and edges. */\n tokenBudget?: number;\n /** Opaque continuation from an equivalent query. */\n cursor?: string;\n /** Registry used to explain custom relationship semantics. */\n registry?: RelationshipKindRegistry;\n /** Abort signal checked during traversal. */\n signal?: AbortSignal;\n}\n\n/** Explainable graph context packet. */\nexport interface RelationshipContextResult {\n /** Root node details. */\n root: RelationshipContextNodeDetails;\n /** Counts-first overview of the packet. */\n summary: RelationshipContextSummary;\n /** Bounded related-node page. */\n nodes: RelationshipContextNode[];\n /** Bounded edges whose endpoints are present in the packet. */\n edges: RelationshipEdge[];\n /** Root evidence pointers promoted for immediate consumption. */\n evidence: string[];\n /** Completeness, continuation, and cost envelope. */\n meta: {\n exact: true;\n truncated: boolean;\n completeness: RelationshipContextCompleteness;\n nodeLimit: number;\n edgeLimit: number;\n tokenBudget: number;\n usedTokens: number;\n visitedNodes: number;\n inspectedEdges: number;\n omittedNodes: number;\n omittedEdges: number;\n nextCursor?: string;\n };\n}\n\ninterface DiscoveredNode {\n id: string;\n distance: number;\n via: string;\n role: RelationshipContextRole;\n}\n\n/** Deterministic priority used when one node matches several semantic families. */\nconst RELATIONSHIP_CONTEXT_ROLE_PRIORITY: readonly RelationshipContextRole[] = [\n \"prerequisite\",\n \"dependent\",\n \"ancestor\",\n \"descendant\",\n \"provenance\",\n \"related\",\n];\n\nconst tokenEncoder = new TextEncoder();\n\nfunction positiveInteger(\n value: number | undefined,\n fallback: number,\n field: string,\n): number {\n const resolved = value ?? fallback;\n if (!Number.isInteger(resolved) || resolved < 1)\n throw new TypeError(`Relationship context ${field} must be positive`);\n return resolved;\n}\n\nfunction estimateTokens(value: unknown): number {\n return Math.max(\n 1,\n Math.ceil(tokenEncoder.encode(JSON.stringify(value)).byteLength / 4),\n );\n}\n\nfunction explainDirectEdge(\n edge: RelationshipEdge,\n node: string,\n registry: RelationshipKindRegistry,\n): RelationshipContextRole {\n const definition = registry.resolve(edge.kind);\n if (definition?.ordering) {\n // Legacy and JSON-parsed definitions may predate explicit precedence.\n const sourceFirst =\n (definition.precedence ?? \"source_before_target\") ===\n \"source_before_target\";\n const before = sourceFirst ? edge.source : edge.target;\n return node === before ? \"prerequisite\" : \"dependent\";\n }\n if (definition?.hierarchy) {\n // Legacy and JSON-parsed definitions may predate explicit hierarchy direction.\n const sourceIsParent =\n (definition.hierarchyDirection ?? \"source_parent\") === \"source_parent\";\n const parent = sourceIsParent ? edge.source : edge.target;\n return node === parent ? \"ancestor\" : \"descendant\";\n }\n if (edge.kind === \"discovered_from\" || edge.kind === \"incident_from\")\n return \"provenance\";\n return \"related\";\n}\n\nfunction directReasons(\n rootEdges: readonly RelationshipEdge[],\n root: string,\n node: string,\n registry: RelationshipKindRegistry,\n): RelationshipContextRole[] {\n const reasons = rootEdges\n .filter(\n (edge) =>\n (edge.source === root && edge.target === node) ||\n (edge.target === root && edge.source === node),\n )\n .map((edge) => explainDirectEdge(edge, node, registry));\n return [...new Set(reasons)].sort();\n}\n\n/** Pick the deterministic primary family when a node matches several. */\nfunction primaryRole(\n roles: readonly RelationshipContextRole[],\n): RelationshipContextRole {\n // Callers only pass non-empty classification sets drawn from the fixed\n // family list, so a priority match always exists.\n return RELATIONSHIP_CONTEXT_ROLE_PRIORITY.find((role) =>\n roles.includes(role),\n )!;\n}\n\nfunction discoverNodes(\n graph: RelationshipGraph,\n root: string,\n registry: RelationshipKindRegistry,\n options: RelationshipContextOptions,\n): {\n rows: DiscoveredNode[];\n visitedNodes: number;\n inspectedEdges: number;\n depthTruncated: boolean;\n} {\n const direction = options.direction ?? \"both\";\n const maxDepth = options.maxDepth ?? 3;\n if (!Number.isInteger(maxDepth) || maxDepth < 0)\n throw new TypeError(\"Relationship context maxDepth must be non-negative\");\n const seen = new Set([root]);\n const queue: { id: string; distance: number }[] = [\n { id: root, distance: 0 },\n ];\n const rows: DiscoveredNode[] = [];\n let inspectedEdges = 0;\n let depthTruncated = false;\n for (let index = 0; index < queue.length; index += 1) {\n options.signal?.throwIfAborted();\n const current = queue[index]!;\n if (current.distance >= maxDepth && depthTruncated) continue;\n const adjacent = graph.neighborEdges(current.id, {\n direction,\n kinds: options.kinds,\n signal: options.signal,\n });\n inspectedEdges += adjacent.meta.inspectedEdges;\n if (current.distance >= maxDepth) {\n if (adjacent.value.some((row) => !seen.has(row.id))) depthTruncated = true;\n continue;\n }\n for (const { id, edge } of adjacent.value) {\n if (seen.has(id)) continue;\n seen.add(id);\n const row = {\n id,\n distance: current.distance + 1,\n via: current.id,\n role: explainDirectEdge(edge, id, registry),\n };\n rows.push(row);\n queue.push(row);\n }\n }\n rows.sort(\n (left, right) =>\n left.distance - right.distance || left.id.localeCompare(right.id),\n );\n return {\n rows,\n visitedNodes: queue.length,\n inspectedEdges,\n depthTruncated,\n };\n}\n\n/** Count root-incident edges per semantic family under the active filters. */\nfunction summarizeDirectEdges(\n graph: RelationshipGraph,\n root: string,\n registry: RelationshipKindRegistry,\n options: RelationshipContextOptions,\n): {\n directEdges: Record<RelationshipContextRole, number>;\n directTotal: number;\n rootEdges: RelationshipEdge[];\n} {\n const directEdges: Record<RelationshipContextRole, number> = {\n prerequisite: 0,\n dependent: 0,\n ancestor: 0,\n descendant: 0,\n provenance: 0,\n related: 0,\n };\n const rows = graph.neighborEdges(root, {\n direction: options.direction ?? \"both\",\n kinds: options.kinds,\n signal: options.signal,\n }).value;\n for (const { id, edge } of rows)\n directEdges[explainDirectEdge(edge, id, registry)] += 1;\n return {\n directEdges,\n directTotal: rows.length,\n rootEdges: rows.map(({ edge }) => edge),\n };\n}\n\nfunction selectContextNodes(params: {\n candidates: readonly DiscoveredNode[];\n details: ReadonlyMap<string, RelationshipContextNodeDetails>;\n rootEdges: readonly RelationshipEdge[];\n rootId: string;\n registry: RelationshipKindRegistry;\n nodeLimit: number;\n tokenBudget: number;\n initialTokens: number;\n}): { nodes: RelationshipContextNode[]; usedTokens: number } {\n const nodes: RelationshipContextNode[] = [];\n let usedTokens = params.initialTokens;\n for (const candidate of params.candidates) {\n if (nodes.length >= params.nodeLimit) break;\n const direct =\n candidate.distance === 1\n ? directReasons(\n params.rootEdges,\n params.rootId,\n candidate.id,\n params.registry,\n )\n : [];\n const node: RelationshipContextNode = {\n ...(params.details.get(candidate.id) ?? { id: candidate.id }),\n distance: candidate.distance,\n role: direct.length > 0 ? primaryRole(direct) : candidate.role,\n via: candidate.via,\n reasons:\n direct.length > 0\n ? direct\n : [\n `${candidate.role} via ${candidate.via} (depth ${candidate.distance})`,\n ],\n };\n const cost = estimateTokens(node);\n if (usedTokens + cost > params.tokenBudget) break;\n nodes.push(node);\n usedTokens += cost;\n }\n if (params.candidates.length > 0 && nodes.length === 0)\n throw new TypeError(\"Relationship context tokenBudget cannot fit one node\");\n return { nodes, usedTokens };\n}\n\nfunction selectContextEdges(params: {\n graph: RelationshipGraph;\n included: ReadonlySet<string>;\n options: RelationshipContextOptions;\n registry: RelationshipKindRegistry;\n edgeLimit: number;\n tokenBudget: number;\n initialTokens: number;\n}): {\n edges: RelationshipEdge[];\n usedTokens: number;\n candidateCount: number;\n} {\n const kinds = params.options.kinds\n ? new Set(\n params.options.kinds.map((kind) => params.registry.require(kind).kind),\n )\n : undefined;\n const candidates = params.graph\n .edges()\n .filter(\n (edge) => {\n if (\n !params.included.has(edge.source) ||\n !params.included.has(edge.target)\n )\n return false;\n if (kinds === undefined || kinds.has(edge.kind)) return true;\n const inverse = params.registry.resolve(edge.kind)?.inverse;\n return inverse !== undefined && kinds.has(inverse);\n },\n );\n const edges: RelationshipEdge[] = [];\n let usedTokens = params.initialTokens;\n for (const edge of candidates) {\n if (edges.length >= params.edgeLimit) break;\n const cost = estimateTokens(edge);\n if (usedTokens + cost > params.tokenBudget) break;\n edges.push(edge);\n usedTokens += cost;\n }\n return { edges, usedTokens, candidateCount: candidates.length };\n}\n\n/** Build one deterministic bounded graph-context packet with continuation. */\nexport function buildRelationshipContext(\n graph: RelationshipGraph,\n rootId: string,\n details: readonly RelationshipContextNodeDetails[],\n options: RelationshipContextOptions = {},\n): RelationshipContextResult {\n if (!graph.nodes().includes(rootId))\n throw new TypeError(`Relationship node not found: ${rootId}`);\n const nodeLimit = positiveInteger(options.nodeLimit, 20, \"nodeLimit\");\n const edgeLimit = positiveInteger(options.edgeLimit, 40, \"edgeLimit\");\n const tokenBudget = positiveInteger(options.tokenBudget, 1200, \"tokenBudget\");\n const registry = options.registry ?? createRelationshipKindRegistry();\n const byId = new Map(details.map((detail) => [detail.id, detail]));\n const rootDetails: RelationshipContextNodeDetails = byId.get(rootId) ?? {\n id: rootId,\n };\n const { evidence: rootEvidence = [], ...root } = rootDetails;\n const evidence = [...rootEvidence];\n const discovery = discoverNodes(graph, rootId, registry, options);\n const { rootEdges, ...directSummary } = summarizeDirectEdges(\n graph,\n rootId,\n registry,\n options,\n );\n const fingerprint = createQueryFingerprint(\"relationship-context\", {\n rootId,\n direction: options.direction ?? \"both\",\n kinds: [...(options.kinds ?? [])].sort(),\n maxDepth: options.maxDepth ?? 3,\n });\n const pageStart = resolveQueryCursorStart(\n discovery.rows,\n options.cursor,\n fingerprint,\n ({ id }) => id,\n );\n const candidates = discovery.rows.slice(pageStart);\n const initialTokens = estimateTokens(root) + estimateTokens(evidence);\n if (initialTokens > tokenBudget)\n throw new TypeError(\n \"Relationship context tokenBudget cannot fit root and evidence\",\n );\n const nodeSelection = selectContextNodes({\n candidates,\n details: byId,\n rootEdges,\n rootId,\n registry,\n nodeLimit,\n tokenBudget,\n initialTokens,\n });\n const { nodes } = nodeSelection;\n\n const included = new Set([rootId, ...nodes.map(({ id }) => id)]);\n const edgeSelection = selectContextEdges({\n graph,\n included,\n options,\n registry,\n edgeLimit,\n tokenBudget,\n initialTokens: nodeSelection.usedTokens,\n });\n const { edges, usedTokens } = edgeSelection;\n\n const consumed = pageStart + nodes.length;\n const hasMoreNodes = consumed < discovery.rows.length;\n const lastNode = nodes.at(-1);\n const omittedEdges = edgeSelection.candidateCount - edges.length;\n const truncated =\n discovery.depthTruncated || hasMoreNodes || omittedEdges > 0;\n const summary: RelationshipContextSummary = {\n rootId,\n ...(root.status === undefined ? {} : { rootStatus: root.status }),\n ...directSummary,\n discoveredNodes: discovery.rows.length,\n returnedNodes: nodes.length,\n returnedEdges: edges.length,\n omittedNodes: discovery.rows.length - consumed,\n omittedEdges,\n evidenceCount: evidence.length,\n hasMore: hasMoreNodes,\n };\n return {\n root,\n summary,\n nodes,\n edges,\n evidence,\n meta: {\n exact: true,\n truncated,\n completeness: truncated ? \"truncated\" : \"complete\",\n nodeLimit,\n edgeLimit,\n tokenBudget,\n usedTokens,\n visitedNodes: discovery.visitedNodes,\n inspectedEdges: discovery.inspectedEdges,\n omittedNodes: discovery.rows.length - consumed,\n omittedEdges,\n ...(hasMoreNodes && lastNode\n ? {\n nextCursor: encodeQueryCursor(\n fingerprint,\n lastNode.id,\n consumed - 1,\n ),\n }\n : {}),\n },\n };\n}\n"],"names":[],"mappings":"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","debugId":"cf26c4d0-d60f-5ec5-858f-957ad719383e"}
|
|
@@ -94,6 +94,13 @@ export interface RelationshipQueryResult<T> {
|
|
|
94
94
|
/** Explicit query work and truncation metadata. */
|
|
95
95
|
meta: RelationshipQueryMeta;
|
|
96
96
|
}
|
|
97
|
+
/** One neighbor row pairing an adjacent node with the edge that connects it. */
|
|
98
|
+
export interface RelationshipNeighborEdge {
|
|
99
|
+
/** Adjacent node identifier. */
|
|
100
|
+
id: string;
|
|
101
|
+
/** Edge connecting the queried node to this neighbor. */
|
|
102
|
+
edge: RelationshipEdge;
|
|
103
|
+
}
|
|
97
104
|
/** Induced subgraph returned by bounded traversal. */
|
|
98
105
|
export interface RelationshipSubgraph {
|
|
99
106
|
/** Deterministically ordered node identifiers. */
|
|
@@ -132,8 +139,14 @@ export declare class RelationshipGraph {
|
|
|
132
139
|
incidentEdges(id: string): readonly RelationshipEdge[];
|
|
133
140
|
/** Return the deterministic immutable node snapshot. */
|
|
134
141
|
nodes(): readonly string[];
|
|
142
|
+
/** Report whether an identifier names an indexed node. */
|
|
143
|
+
hasNode(id: string): boolean;
|
|
144
|
+
/** Return the registry that interprets this graph's relationship kinds. */
|
|
145
|
+
registry(): RelationshipKindRegistry;
|
|
135
146
|
/** Return one-hop adjacent node identifiers. */
|
|
136
147
|
adjacency(id: string, options?: RelationshipQueryOptions): RelationshipQueryResult<string[]>;
|
|
148
|
+
/** Return deterministic one-hop neighbor rows paired with each connecting edge. */
|
|
149
|
+
neighborEdges(id: string, options?: RelationshipQueryOptions): RelationshipQueryResult<RelationshipNeighborEdge[]>;
|
|
137
150
|
/** Return bounded transitive closure in breadth-first discovery order. */
|
|
138
151
|
closure(id: string, options?: RelationshipQueryOptions): RelationshipQueryResult<string[]>;
|
|
139
152
|
/** Return a deterministic shortest path, or an empty array when disconnected. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="00588d49-70aa-59c8-bc85-d0bbd5e77d4b")}catch(e){}}();
|
|
3
3
|
const BUILTIN_RELATIONSHIP_KINDS = [
|
|
4
4
|
{
|
|
5
5
|
kind: "blocked_by",
|
|
@@ -368,6 +368,14 @@ export class RelationshipGraph {
|
|
|
368
368
|
nodes() {
|
|
369
369
|
return this.#nodeSnapshot;
|
|
370
370
|
}
|
|
371
|
+
/** Report whether an identifier names an indexed node. */
|
|
372
|
+
hasNode(id) {
|
|
373
|
+
return this.#nodes.has(id);
|
|
374
|
+
}
|
|
375
|
+
/** Return the registry that interprets this graph's relationship kinds. */
|
|
376
|
+
registry() {
|
|
377
|
+
return this.#registry;
|
|
378
|
+
}
|
|
371
379
|
#assertNode(id) {
|
|
372
380
|
if (!this.#nodes.has(id))
|
|
373
381
|
throw new TypeError(`Relationship node not found: ${id}`);
|
|
@@ -414,6 +422,26 @@ export class RelationshipGraph {
|
|
|
414
422
|
},
|
|
415
423
|
};
|
|
416
424
|
}
|
|
425
|
+
/** Return deterministic one-hop neighbor rows paired with each connecting edge. */
|
|
426
|
+
neighborEdges(id, options = {}) {
|
|
427
|
+
this.#assertNode(id);
|
|
428
|
+
options.signal?.throwIfAborted();
|
|
429
|
+
const kinds = options.kinds
|
|
430
|
+
? new Set(options.kinds.map((kind) => this.#registry.require(kind).kind))
|
|
431
|
+
: undefined;
|
|
432
|
+
const rows = this.#neighbors(id, options.direction ?? "outgoing", kinds);
|
|
433
|
+
const limit = options.limit ?? Number.POSITIVE_INFINITY;
|
|
434
|
+
const value = rows.slice(0, limit);
|
|
435
|
+
return {
|
|
436
|
+
value,
|
|
437
|
+
meta: {
|
|
438
|
+
visitedNodes: 1,
|
|
439
|
+
inspectedEdges: rows.length,
|
|
440
|
+
truncated: value.length < rows.length,
|
|
441
|
+
nextCursor: value.at(-1)?.id,
|
|
442
|
+
},
|
|
443
|
+
};
|
|
444
|
+
}
|
|
417
445
|
/** Return bounded transitive closure in breadth-first discovery order. */
|
|
418
446
|
closure(id, options = {}) {
|
|
419
447
|
this.#assertNode(id);
|
|
@@ -548,4 +576,4 @@ export function dependencyToRelationship(source, dependency, registry = defaultR
|
|
|
548
576
|
};
|
|
549
577
|
}
|
|
550
578
|
//# sourceMappingURL=relationships.js.map
|
|
551
|
-
//# debugId=
|
|
579
|
+
//# debugId=00588d49-70aa-59c8-bc85-d0bbd5e77d4b
|