@decibelsystems/tools 2.2.0-beta.0 → 3.1.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 +226 -0
- package/dist/agentCommands.d.ts +0 -1
- package/dist/agentCommands.d.ts.map +1 -1
- package/dist/agentCommands.js +19 -8
- package/dist/agentCommands.js.map +1 -1
- package/dist/agentPresence.d.ts +82 -0
- package/dist/agentPresence.d.ts.map +1 -1
- package/dist/agentPresence.js +194 -26
- package/dist/agentPresence.js.map +1 -1
- package/dist/agentic/index.d.ts +18 -8
- package/dist/agentic/index.d.ts.map +1 -1
- package/dist/agentic/index.js +18 -144
- package/dist/agentic/index.js.map +1 -1
- package/dist/agentic/types.d.ts +106 -0
- package/dist/agentic/types.d.ts.map +1 -1
- package/dist/agentic/types.js +77 -1
- package/dist/agentic/types.js.map +1 -1
- package/dist/architectAdrs.d.ts +27 -3
- package/dist/architectAdrs.d.ts.map +1 -1
- package/dist/architectAdrs.js +92 -4
- package/dist/architectAdrs.js.map +1 -1
- package/dist/artifacts.d.ts +60 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +208 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/asks.d.ts +93 -0
- package/dist/asks.d.ts.map +1 -0
- package/dist/asks.js +383 -0
- package/dist/asks.js.map +1 -0
- package/dist/chat.d.ts +47 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +288 -0
- package/dist/chat.js.map +1 -0
- package/dist/client/transports.d.ts.map +1 -1
- package/dist/client/transports.js +13 -3
- package/dist/client/transports.js.map +1 -1
- package/dist/daemon.d.ts +33 -3
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +225 -52
- package/dist/daemon.js.map +1 -1
- package/dist/daemonConfig.d.ts +46 -0
- package/dist/daemonConfig.d.ts.map +1 -1
- package/dist/daemonConfig.js +57 -12
- package/dist/daemonConfig.js.map +1 -1
- package/dist/decibelPaths.d.ts.map +1 -1
- package/dist/decibelPaths.js +39 -6
- package/dist/decibelPaths.js.map +1 -1
- package/dist/domain/issue.d.ts +81 -0
- package/dist/domain/issue.d.ts.map +1 -0
- package/dist/domain/issue.js +106 -0
- package/dist/domain/issue.js.map +1 -0
- package/dist/domain/issueCodec.d.ts +39 -0
- package/dist/domain/issueCodec.d.ts.map +1 -0
- package/dist/domain/issueCodec.js +308 -0
- package/dist/domain/issueCodec.js.map +1 -0
- package/dist/domain/issueRepository.d.ts +124 -0
- package/dist/domain/issueRepository.d.ts.map +1 -0
- package/dist/domain/issueRepository.js +296 -0
- package/dist/domain/issueRepository.js.map +1 -0
- package/dist/domain/uid.d.ts +16 -0
- package/dist/domain/uid.d.ts.map +1 -0
- package/dist/domain/uid.js +43 -0
- package/dist/domain/uid.js.map +1 -0
- package/dist/facades/definitions.d.ts +0 -1
- package/dist/facades/definitions.d.ts.map +1 -1
- package/dist/facades/definitions.js +140 -116
- package/dist/facades/definitions.js.map +1 -1
- package/dist/facades/index.d.ts +2 -1
- package/dist/facades/index.d.ts.map +1 -1
- package/dist/facades/index.js +1 -1
- package/dist/facades/index.js.map +1 -1
- package/dist/facades/types.d.ts +17 -0
- package/dist/facades/types.d.ts.map +1 -1
- package/dist/hq/defineAgent.d.ts.map +1 -1
- package/dist/hq/defineAgent.js +7 -11
- package/dist/hq/defineAgent.js.map +1 -1
- package/dist/httpArgs.d.ts +11 -0
- package/dist/httpArgs.d.ts.map +1 -0
- package/dist/httpArgs.js +39 -0
- package/dist/httpArgs.js.map +1 -0
- package/dist/httpServer.d.ts +1 -12
- package/dist/httpServer.d.ts.map +1 -1
- package/dist/httpServer.js +298 -144
- package/dist/httpServer.js.map +1 -1
- package/dist/identity.d.ts +123 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +312 -0
- package/dist/identity.js.map +1 -0
- package/dist/kernel.d.ts +46 -1
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +334 -26
- package/dist/kernel.js.map +1 -1
- package/dist/killSwitch.d.ts +117 -0
- package/dist/killSwitch.d.ts.map +1 -0
- package/dist/killSwitch.js +161 -0
- package/dist/killSwitch.js.map +1 -0
- package/dist/lib/agent-services/assumptions.d.ts.map +1 -1
- package/dist/lib/agent-services/assumptions.js +8 -2
- package/dist/lib/agent-services/assumptions.js.map +1 -1
- package/dist/lib/atomicWrite.d.ts +49 -0
- package/dist/lib/atomicWrite.d.ts.map +1 -0
- package/dist/lib/atomicWrite.js +157 -0
- package/dist/lib/atomicWrite.js.map +1 -0
- package/dist/lib/envelope.d.ts +31 -0
- package/dist/lib/envelope.d.ts.map +1 -0
- package/dist/lib/envelope.js +80 -0
- package/dist/lib/envelope.js.map +1 -0
- package/dist/lib/fileLock.d.ts +38 -0
- package/dist/lib/fileLock.d.ts.map +1 -0
- package/dist/lib/fileLock.js +124 -0
- package/dist/lib/fileLock.js.map +1 -0
- package/dist/lib/recordIdAllocator.d.ts +102 -0
- package/dist/lib/recordIdAllocator.d.ts.map +1 -0
- package/dist/lib/recordIdAllocator.js +179 -0
- package/dist/lib/recordIdAllocator.js.map +1 -0
- package/dist/orgId.d.ts +23 -0
- package/dist/orgId.d.ts.map +1 -0
- package/dist/orgId.js +73 -0
- package/dist/orgId.js.map +1 -0
- package/dist/pairCli.d.ts +2 -0
- package/dist/pairCli.d.ts.map +1 -0
- package/dist/pairCli.js +97 -0
- package/dist/pairCli.js.map +1 -0
- package/dist/peerBroker.d.ts +40 -0
- package/dist/peerBroker.d.ts.map +1 -0
- package/dist/peerBroker.js +70 -0
- package/dist/peerBroker.js.map +1 -0
- package/dist/peerBrokerSupervisor.d.ts +21 -0
- package/dist/peerBrokerSupervisor.d.ts.map +1 -0
- package/dist/peerBrokerSupervisor.js +131 -0
- package/dist/peerBrokerSupervisor.js.map +1 -0
- package/dist/projectPaths.d.ts.map +1 -1
- package/dist/projectPaths.js +1 -19
- package/dist/projectPaths.js.map +1 -1
- package/dist/projectRegistry.d.ts +22 -0
- package/dist/projectRegistry.d.ts.map +1 -1
- package/dist/projectRegistry.js +69 -2
- package/dist/projectRegistry.js.map +1 -1
- package/dist/pty/boundary.d.ts +39 -0
- package/dist/pty/boundary.d.ts.map +1 -0
- package/dist/pty/boundary.js +100 -0
- package/dist/pty/boundary.js.map +1 -0
- package/dist/pty/errors.d.ts +6 -0
- package/dist/pty/errors.d.ts.map +1 -0
- package/dist/pty/errors.js +12 -0
- package/dist/pty/errors.js.map +1 -0
- package/dist/pty/fleet.d.ts +159 -0
- package/dist/pty/fleet.d.ts.map +1 -0
- package/dist/pty/fleet.js +543 -0
- package/dist/pty/fleet.js.map +1 -0
- package/dist/pty/launchProfile.d.ts +45 -0
- package/dist/pty/launchProfile.d.ts.map +1 -0
- package/dist/pty/launchProfile.js +149 -0
- package/dist/pty/launchProfile.js.map +1 -0
- package/dist/pty/openTerminal.d.ts +48 -0
- package/dist/pty/openTerminal.d.ts.map +1 -0
- package/dist/pty/openTerminal.js +185 -0
- package/dist/pty/openTerminal.js.map +1 -0
- package/dist/pty/pairDialog.d.ts +16 -0
- package/dist/pty/pairDialog.d.ts.map +1 -0
- package/dist/pty/pairDialog.js +121 -0
- package/dist/pty/pairDialog.js.map +1 -0
- package/dist/pty/pairing.d.ts +86 -0
- package/dist/pty/pairing.d.ts.map +1 -0
- package/dist/pty/pairing.js +351 -0
- package/dist/pty/pairing.js.map +1 -0
- package/dist/pty/routes.d.ts +49 -0
- package/dist/pty/routes.d.ts.map +1 -0
- package/dist/pty/routes.js +624 -0
- package/dist/pty/routes.js.map +1 -0
- package/dist/pty/sessions.d.ts +167 -0
- package/dist/pty/sessions.d.ts.map +1 -0
- package/dist/pty/sessions.js +513 -0
- package/dist/pty/sessions.js.map +1 -0
- package/dist/pty/tmux.d.ts +109 -0
- package/dist/pty/tmux.d.ts.map +1 -0
- package/dist/pty/tmux.js +271 -0
- package/dist/pty/tmux.js.map +1 -0
- package/dist/roster.d.ts +37 -0
- package/dist/roster.d.ts.map +1 -0
- package/dist/roster.js +126 -0
- package/dist/roster.js.map +1 -0
- package/dist/runtime/circuitBreaker.d.ts +95 -0
- package/dist/runtime/circuitBreaker.d.ts.map +1 -0
- package/dist/runtime/circuitBreaker.js +178 -0
- package/dist/runtime/circuitBreaker.js.map +1 -0
- package/dist/runtime/daemonMeta.d.ts +53 -0
- package/dist/runtime/daemonMeta.d.ts.map +1 -0
- package/dist/runtime/daemonMeta.js +121 -0
- package/dist/runtime/daemonMeta.js.map +1 -0
- package/dist/runtime/ensureRuntime.d.ts +103 -0
- package/dist/runtime/ensureRuntime.d.ts.map +1 -0
- package/dist/runtime/ensureRuntime.js +276 -0
- package/dist/runtime/ensureRuntime.js.map +1 -0
- package/dist/runtime/extensions.d.ts +57 -0
- package/dist/runtime/extensions.d.ts.map +1 -0
- package/dist/runtime/extensions.js +216 -0
- package/dist/runtime/extensions.js.map +1 -0
- package/dist/runtime/localHttp.d.ts +24 -0
- package/dist/runtime/localHttp.d.ts.map +1 -0
- package/dist/runtime/localHttp.js +84 -0
- package/dist/runtime/localHttp.js.map +1 -0
- package/dist/runtime/projectResolution.d.ts +29 -0
- package/dist/runtime/projectResolution.d.ts.map +1 -0
- package/dist/runtime/projectResolution.js +67 -0
- package/dist/runtime/projectResolution.js.map +1 -0
- package/dist/runtime/protocol.d.ts +62 -0
- package/dist/runtime/protocol.d.ts.map +1 -0
- package/dist/runtime/protocol.js +74 -0
- package/dist/runtime/protocol.js.map +1 -0
- package/dist/sentinelIssues.d.ts +42 -2
- package/dist/sentinelIssues.d.ts.map +1 -1
- package/dist/sentinelIssues.js +167 -65
- package/dist/sentinelIssues.js.map +1 -1
- package/dist/server.js +123 -15
- package/dist/server.js.map +1 -1
- package/dist/toolConfig.d.ts.map +1 -1
- package/dist/toolConfig.js +12 -0
- package/dist/toolConfig.js.map +1 -1
- package/dist/tools/agentic/agentQueue.d.ts.map +1 -1
- package/dist/tools/agentic/agentQueue.js +4 -0
- package/dist/tools/agentic/agentQueue.js.map +1 -1
- package/dist/tools/agentic/index.d.ts.map +1 -1
- package/dist/tools/agentic/index.js +28 -2
- package/dist/tools/agentic/index.js.map +1 -1
- package/dist/tools/architect/index.d.ts +1 -0
- package/dist/tools/architect/index.d.ts.map +1 -1
- package/dist/tools/architect/index.js +52 -3
- package/dist/tools/architect/index.js.map +1 -1
- package/dist/tools/architect.d.ts.map +1 -1
- package/dist/tools/architect.js +59 -8
- package/dist/tools/architect.js.map +1 -1
- package/dist/tools/artifacts.d.ts +5 -0
- package/dist/tools/artifacts.d.ts.map +1 -0
- package/dist/tools/artifacts.js +89 -0
- package/dist/tools/artifacts.js.map +1 -0
- package/dist/tools/asks.d.ts +6 -0
- package/dist/tools/asks.d.ts.map +1 -0
- package/dist/tools/asks.js +104 -0
- package/dist/tools/asks.js.map +1 -0
- package/dist/tools/context.d.ts +10 -5
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +45 -18
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/coordinator/coordinator.d.ts.map +1 -1
- package/dist/tools/coordinator/coordinator.js +48 -19
- package/dist/tools/coordinator/coordinator.js.map +1 -1
- package/dist/tools/coordinator/index.d.ts +1 -0
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +42 -2
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/tools/crit.d.ts +2 -1
- package/dist/tools/crit.d.ts.map +1 -1
- package/dist/tools/crit.js +19 -4
- package/dist/tools/crit.js.map +1 -1
- package/dist/tools/data-inspector.d.ts +1 -1
- package/dist/tools/data-inspector.d.ts.map +1 -1
- package/dist/tools/data-inspector.js +1 -1
- package/dist/tools/data-inspector.js.map +1 -1
- package/dist/tools/designer/index.d.ts.map +1 -1
- package/dist/tools/designer/index.js +4 -3
- package/dist/tools/designer/index.js.map +1 -1
- package/dist/tools/designer/lateral-tools.d.ts.map +1 -1
- package/dist/tools/designer/lateral-tools.js +4 -2
- package/dist/tools/designer/lateral-tools.js.map +1 -1
- package/dist/tools/designer.d.ts +2 -1
- package/dist/tools/designer.d.ts.map +1 -1
- package/dist/tools/designer.js +24 -12
- package/dist/tools/designer.js.map +1 -1
- package/dist/tools/dojo/index.d.ts.map +1 -1
- package/dist/tools/dojo/index.js +52 -3
- package/dist/tools/dojo/index.js.map +1 -1
- package/dist/tools/dojo.d.ts +65 -3
- package/dist/tools/dojo.d.ts.map +1 -1
- package/dist/tools/dojo.js +148 -23
- package/dist/tools/dojo.js.map +1 -1
- package/dist/tools/friction.d.ts.map +1 -1
- package/dist/tools/friction.js +16 -6
- package/dist/tools/friction.js.map +1 -1
- package/dist/tools/guardian.d.ts +7 -0
- package/dist/tools/guardian.d.ts.map +1 -1
- package/dist/tools/guardian.js +152 -11
- package/dist/tools/guardian.js.map +1 -1
- package/dist/tools/hygiene/oracle-hygiene.d.ts.map +1 -1
- package/dist/tools/hygiene/oracle-hygiene.js +8 -2
- package/dist/tools/hygiene/oracle-hygiene.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +33 -18
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/killswitch/index.d.ts +13 -0
- package/dist/tools/killswitch/index.d.ts.map +1 -0
- package/dist/tools/killswitch/index.js +138 -0
- package/dist/tools/killswitch/index.js.map +1 -0
- package/dist/tools/learnings.d.ts +2 -1
- package/dist/tools/learnings.d.ts.map +1 -1
- package/dist/tools/learnings.js +31 -15
- package/dist/tools/learnings.js.map +1 -1
- package/dist/tools/oracle/index.d.ts.map +1 -1
- package/dist/tools/oracle/index.js +8 -0
- package/dist/tools/oracle/index.js.map +1 -1
- package/dist/tools/oracle.d.ts +7 -0
- package/dist/tools/oracle.d.ts.map +1 -1
- package/dist/tools/oracle.js +41 -12
- package/dist/tools/oracle.js.map +1 -1
- package/dist/tools/policy.d.ts +2 -1
- package/dist/tools/policy.d.ts.map +1 -1
- package/dist/tools/policy.js +28 -9
- package/dist/tools/policy.js.map +1 -1
- package/dist/tools/postoffice/index.d.ts +10 -0
- package/dist/tools/postoffice/index.d.ts.map +1 -0
- package/dist/tools/postoffice/index.js +218 -0
- package/dist/tools/postoffice/index.js.map +1 -0
- package/dist/tools/postoffice.d.ts +78 -0
- package/dist/tools/postoffice.d.ts.map +1 -0
- package/dist/tools/postoffice.js +199 -0
- package/dist/tools/postoffice.js.map +1 -0
- package/dist/tools/provenance.d.ts +18 -2
- package/dist/tools/provenance.d.ts.map +1 -1
- package/dist/tools/provenance.js +68 -40
- package/dist/tools/provenance.js.map +1 -1
- package/dist/tools/registry/index.d.ts.map +1 -1
- package/dist/tools/registry/index.js +24 -0
- package/dist/tools/registry/index.js.map +1 -1
- package/dist/tools/sentinel/index.d.ts +1 -0
- package/dist/tools/sentinel/index.d.ts.map +1 -1
- package/dist/tools/sentinel/index.js +142 -6
- package/dist/tools/sentinel/index.js.map +1 -1
- package/dist/tools/sentinel.d.ts +152 -1
- package/dist/tools/sentinel.d.ts.map +1 -1
- package/dist/tools/sentinel.js +609 -328
- package/dist/tools/sentinel.js.map +1 -1
- package/dist/tools/shared/index.d.ts +2 -1
- package/dist/tools/shared/index.d.ts.map +1 -1
- package/dist/tools/shared/index.js +2 -1
- package/dist/tools/shared/index.js.map +1 -1
- package/dist/tools/shared/response.d.ts +24 -0
- package/dist/tools/shared/response.d.ts.map +1 -1
- package/dist/tools/shared/response.js +61 -7
- package/dist/tools/shared/response.js.map +1 -1
- package/dist/tools/shared/runTracker.d.ts +2 -0
- package/dist/tools/shared/runTracker.d.ts.map +1 -1
- package/dist/tools/shared/runTracker.js +38 -0
- package/dist/tools/shared/runTracker.js.map +1 -1
- package/dist/tools/shared/storeRead.d.ts +153 -0
- package/dist/tools/shared/storeRead.d.ts.map +1 -0
- package/dist/tools/shared/storeRead.js +242 -0
- package/dist/tools/shared/storeRead.js.map +1 -0
- package/dist/tools/swarm.d.ts +3 -1
- package/dist/tools/swarm.d.ts.map +1 -1
- package/dist/tools/swarm.js +6 -12
- package/dist/tools/swarm.js.map +1 -1
- package/dist/tools/testSpec.d.ts +3 -2
- package/dist/tools/testSpec.d.ts.map +1 -1
- package/dist/tools/testSpec.js +51 -14
- package/dist/tools/testSpec.js.map +1 -1
- package/dist/tools/vector.d.ts +33 -1
- package/dist/tools/vector.d.ts.map +1 -1
- package/dist/tools/vector.js +31 -5
- package/dist/tools/vector.js.map +1 -1
- package/dist/tools/voice/index.d.ts +1 -0
- package/dist/tools/voice/index.d.ts.map +1 -1
- package/dist/tools/voice/index.js +33 -2
- package/dist/tools/voice/index.js.map +1 -1
- package/dist/tools/voice.d.ts +48 -1
- package/dist/tools/voice.d.ts.map +1 -1
- package/dist/tools/voice.js +63 -3
- package/dist/tools/voice.js.map +1 -1
- package/dist/tools/zoom/index.d.ts +15 -0
- package/dist/tools/zoom/index.d.ts.map +1 -0
- package/dist/tools/zoom/index.js +174 -0
- package/dist/tools/zoom/index.js.map +1 -0
- package/dist/tools/zoom.d.ts +234 -0
- package/dist/tools/zoom.d.ts.map +1 -0
- package/dist/tools/zoom.js +627 -0
- package/dist/tools/zoom.js.map +1 -0
- package/dist/transports/bridge.d.ts +1 -1
- package/dist/transports/bridge.d.ts.map +1 -1
- package/dist/transports/bridge.js +4 -1
- package/dist/transports/bridge.js.map +1 -1
- package/dist/transports/http.d.ts +1 -1
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +3 -1
- package/dist/transports/http.js.map +1 -1
- package/dist/transports/index.d.ts +1 -0
- package/dist/transports/index.d.ts.map +1 -1
- package/dist/transports/index.js +1 -0
- package/dist/transports/index.js.map +1 -1
- package/dist/transports/mcp.d.ts +1 -1
- package/dist/transports/mcp.d.ts.map +1 -1
- package/dist/transports/mcp.js +9 -4
- package/dist/transports/mcp.js.map +1 -1
- package/dist/transports/stdio.d.ts +1 -1
- package/dist/transports/stdio.d.ts.map +1 -1
- package/dist/transports/stdio.js +2 -0
- package/dist/transports/stdio.js.map +1 -1
- package/dist/transports/thinStdio.d.ts +22 -0
- package/dist/transports/thinStdio.d.ts.map +1 -0
- package/dist/transports/thinStdio.js +218 -0
- package/dist/transports/thinStdio.js.map +1 -0
- package/dist/transports/types.d.ts +8 -1
- package/dist/transports/types.d.ts.map +1 -1
- package/dist/types/agent-services.d.ts +7 -0
- package/dist/types/agent-services.d.ts.map +1 -1
- package/dist/version.d.ts +5 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/version.js.map +1 -0
- package/package.json +20 -4
- package/templates/AGENT.md +3 -0
- package/templates/CLAUDE-decibel.md +11 -0
- package/templates/com.decibel.daemon.plist +6 -1
- package/dist/tools/deck.d.ts +0 -11
- package/dist/tools/deck.d.ts.map +0 -1
- package/dist/tools/deck.js +0 -1656
- package/dist/tools/deck.js.map +0 -1
- package/dist/tools/mother.d.ts +0 -11
- package/dist/tools/mother.d.ts.map +0 -1
- package/dist/tools/mother.js +0 -503
- package/dist/tools/mother.js.map +0 -1
- package/dist/tools/registry.d.ts +0 -3
- package/dist/tools/registry.d.ts.map +0 -1
- package/dist/tools/registry.js +0 -189
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/senken.d.ts +0 -11
- package/dist/tools/senken.d.ts.map +0 -1
- package/dist/tools/senken.js +0 -482
- package/dist/tools/senken.js.map +0 -1
- package/dist/tools/terminal.d.ts +0 -17
- package/dist/tools/terminal.d.ts.map +0 -1
- package/dist/tools/terminal.js +0 -968
- package/dist/tools/terminal.js.map +0 -1
- package/dist/tools/toolsIndex.d.ts +0 -5
- package/dist/tools/toolsIndex.d.ts.map +0 -1
- package/dist/tools/toolsIndex.js +0 -37
- package/dist/tools/toolsIndex.js.map +0 -1
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Issue repository — EPIC-0038 Phase 3
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// The seam between "what an issue is" and "where issues live".
|
|
5
|
+
//
|
|
6
|
+
// Callers ask for issues by id and get back canonical Issue objects. They do
|
|
7
|
+
// not learn whether a record was markdown-with-frontmatter or bare YAML, which
|
|
8
|
+
// directory it came from, or how its id was resolved. That is the whole point:
|
|
9
|
+
// Phase 5 converges the on-disk format and should be a change to the codec and
|
|
10
|
+
// this file only, and a future SupabaseIssueRepository should be a sibling
|
|
11
|
+
// rather than a rewrite of every caller.
|
|
12
|
+
//
|
|
13
|
+
// Resolution is the subtle part. An id can name more than one record — four
|
|
14
|
+
// duplicate groups existed before Phase 2 repaired them — and the historical
|
|
15
|
+
// failure mode was `files.find(...)` picking whichever the directory listing
|
|
16
|
+
// happened to yield first, so writers had an undefined target and reported
|
|
17
|
+
// success either way. Ambiguity is therefore an error here, never a guess.
|
|
18
|
+
// ============================================================================
|
|
19
|
+
import { promises as fs } from 'fs';
|
|
20
|
+
import path from 'path';
|
|
21
|
+
import { writeFileAtomic } from '../lib/atomicWrite.js';
|
|
22
|
+
import { allocateAndWriteIssue } from '../lib/recordIdAllocator.js';
|
|
23
|
+
import { listDirOrThrow } from '../tools/shared/storeRead.js';
|
|
24
|
+
import { isLive, newUid, } from './issue.js';
|
|
25
|
+
import { decodeIssue, encodeIssue, } from './issueCodec.js';
|
|
26
|
+
export class AmbiguousIssueIdError extends Error {
|
|
27
|
+
issueId;
|
|
28
|
+
candidates;
|
|
29
|
+
code = 'AMBIGUOUS_ISSUE_ID';
|
|
30
|
+
constructor(issueId, candidates) {
|
|
31
|
+
super(`Issue id ${issueId} matches ${candidates.length} records: ${candidates.join(', ')}. ` +
|
|
32
|
+
`Name one by filename, or by its uid, to disambiguate.`);
|
|
33
|
+
this.issueId = issueId;
|
|
34
|
+
this.candidates = candidates;
|
|
35
|
+
this.name = 'AmbiguousIssueIdError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export class IssueNotFoundError extends Error {
|
|
39
|
+
issueId;
|
|
40
|
+
code = 'ISSUE_NOT_FOUND';
|
|
41
|
+
constructor(issueId) {
|
|
42
|
+
super(`Issue ${issueId} not found.`);
|
|
43
|
+
this.issueId = issueId;
|
|
44
|
+
this.name = 'IssueNotFoundError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const RECORD_RE = /\.(md|ya?ml)$/i;
|
|
48
|
+
function slugify(text) {
|
|
49
|
+
return text
|
|
50
|
+
.toLowerCase()
|
|
51
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
52
|
+
.replace(/^-+|-+$/g, '')
|
|
53
|
+
.slice(0, 50);
|
|
54
|
+
}
|
|
55
|
+
export class FsIssueRepository {
|
|
56
|
+
issuesDir;
|
|
57
|
+
constructor(issuesDir) {
|
|
58
|
+
this.issuesDir = issuesDir;
|
|
59
|
+
}
|
|
60
|
+
async readAll() {
|
|
61
|
+
// ISS-0153. ENOENT is the only error that means "empty": a directory that
|
|
62
|
+
// was never created is what an untouched project looks like. EACCES,
|
|
63
|
+
// EPERM, EIO and the rest mean the issues may well be there and this
|
|
64
|
+
// process cannot see them — returning [] there reported "no issues" for a
|
|
65
|
+
// store it could not open, and list_issues is the read most likely to be
|
|
66
|
+
// believed.
|
|
67
|
+
const names = await listDirOrThrow(this.issuesDir, (f) => RECORD_RE.test(f));
|
|
68
|
+
const out = [];
|
|
69
|
+
for (const filename of names) {
|
|
70
|
+
const full = path.join(this.issuesDir, filename);
|
|
71
|
+
let content;
|
|
72
|
+
try {
|
|
73
|
+
content = await fs.readFile(full, 'utf-8');
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
continue; // Unreadable record: skip rather than fail the whole listing.
|
|
77
|
+
}
|
|
78
|
+
const decoded = decodeIssue(filename, content);
|
|
79
|
+
out.push({
|
|
80
|
+
issue: decoded.issue,
|
|
81
|
+
filename,
|
|
82
|
+
path: full,
|
|
83
|
+
format: decoded.format,
|
|
84
|
+
warnings: decoded.warnings,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Duplicate detection deliberately runs over EVERY record, never a filtered
|
|
91
|
+
* subset: a closed twin still makes an id ambiguous for writers, so filtering
|
|
92
|
+
* it out of a listing must not filter it out of the collision report.
|
|
93
|
+
*/
|
|
94
|
+
async integrity() {
|
|
95
|
+
const all = await this.readAll();
|
|
96
|
+
const malformed = [];
|
|
97
|
+
const degraded = [];
|
|
98
|
+
const claims = new Map();
|
|
99
|
+
for (const r of all) {
|
|
100
|
+
const unparseable = r.warnings.some((w) => w.includes('did not parse'));
|
|
101
|
+
if (unparseable)
|
|
102
|
+
malformed.push(r.filename);
|
|
103
|
+
else if (r.warnings.length > 0)
|
|
104
|
+
degraded.push({ filename: r.filename, warnings: r.warnings });
|
|
105
|
+
const key = r.issue.id.toUpperCase();
|
|
106
|
+
claims.set(key, [...(claims.get(key) ?? []), r.filename]);
|
|
107
|
+
}
|
|
108
|
+
const duplicateIds = {};
|
|
109
|
+
for (const [id, files] of claims)
|
|
110
|
+
if (files.length > 1)
|
|
111
|
+
duplicateIds[id] = files;
|
|
112
|
+
return { malformed, degraded, duplicateIds };
|
|
113
|
+
}
|
|
114
|
+
async list(filter = {}) {
|
|
115
|
+
// A record that did not parse is not an issue — returning it would hand
|
|
116
|
+
// callers a husk built from filename fallbacks. It is still counted by
|
|
117
|
+
// integrity(), so the file is reported rather than silently dropped.
|
|
118
|
+
let all = (await this.readAll()).filter((r) => !r.warnings.some((w) => w.includes('did not parse')));
|
|
119
|
+
if (filter.status)
|
|
120
|
+
all = all.filter((r) => r.issue.status === filter.status);
|
|
121
|
+
if (filter.liveOnly)
|
|
122
|
+
all = all.filter((r) => isLive(r.issue.status));
|
|
123
|
+
if (filter.epicId)
|
|
124
|
+
all = all.filter((r) => r.issue.epicId === filter.epicId);
|
|
125
|
+
return all;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Resolve an id to exactly one record, in tiers of decreasing specificity.
|
|
129
|
+
*
|
|
130
|
+
* Only the first non-empty tier is considered, and ambiguity is reported
|
|
131
|
+
* within a tier rather than across tiers — so naming a record by its filename
|
|
132
|
+
* stays a reliable way to pick one member of a duplicate pair even while the
|
|
133
|
+
* shared ISS-NNNN remains ambiguous. uid is checked first because it is the
|
|
134
|
+
* only identifier guaranteed unique by construction.
|
|
135
|
+
*/
|
|
136
|
+
async resolve(idOrFilename) {
|
|
137
|
+
const all = await this.readAll();
|
|
138
|
+
const needle = idOrFilename.trim();
|
|
139
|
+
const upper = needle.toUpperCase();
|
|
140
|
+
const byUid = all.filter((r) => r.issue.uid && r.issue.uid === needle);
|
|
141
|
+
if (byUid.length > 0)
|
|
142
|
+
return byUid;
|
|
143
|
+
const byFilename = all.filter((r) => r.filename.toUpperCase() === upper);
|
|
144
|
+
if (byFilename.length > 0)
|
|
145
|
+
return byFilename;
|
|
146
|
+
// Filename without the extension, which is how list output used to name records.
|
|
147
|
+
const byStem = all.filter((r) => r.filename.replace(RECORD_RE, '').toUpperCase() === upper.replace(RECORD_RE, ''));
|
|
148
|
+
if (byStem.length > 0)
|
|
149
|
+
return byStem;
|
|
150
|
+
// ISS-NNNN, requiring the id to end at a separator or the extension. A bare
|
|
151
|
+
// startsWith made "ISS-011" swallow ISS-0110, ISS-0112 and ISS-0119.
|
|
152
|
+
const byId = all.filter((r) => {
|
|
153
|
+
if (r.issue.id.toUpperCase() === upper)
|
|
154
|
+
return true;
|
|
155
|
+
const base = r.filename.toUpperCase();
|
|
156
|
+
if (!base.startsWith(upper))
|
|
157
|
+
return false;
|
|
158
|
+
const rest = base.slice(upper.length);
|
|
159
|
+
return rest === '' || rest.startsWith('-') || /^\.(MD|YA?ML)$/.test(rest);
|
|
160
|
+
});
|
|
161
|
+
if (byId.length > 0)
|
|
162
|
+
return byId;
|
|
163
|
+
// Last tier: a partial id like "ISS-011", which is a prefix of ISS-0110,
|
|
164
|
+
// ISS-0112 and ISS-0119. The boundary rule above deliberately refuses to
|
|
165
|
+
// resolve it, but refusing is not the same as saying nothing is there —
|
|
166
|
+
// "not found" would be a misleading answer when three records obviously
|
|
167
|
+
// start with it. So a loose prefix is reported as a collision when it spans
|
|
168
|
+
// several records, and is NEVER resolved to a single one: silently picking
|
|
169
|
+
// one is the swallow bug this whole tier system exists to prevent.
|
|
170
|
+
const loose = all.filter((r) => r.filename.toUpperCase().startsWith(upper));
|
|
171
|
+
return loose.length > 1 ? loose : [];
|
|
172
|
+
}
|
|
173
|
+
async get(idOrFilename) {
|
|
174
|
+
const matches = await this.resolve(idOrFilename);
|
|
175
|
+
if (matches.length === 0)
|
|
176
|
+
return null;
|
|
177
|
+
if (matches.length > 1) {
|
|
178
|
+
throw new AmbiguousIssueIdError(idOrFilename, matches.map((m) => m.filename));
|
|
179
|
+
}
|
|
180
|
+
return matches[0];
|
|
181
|
+
}
|
|
182
|
+
async requireOne(idOrFilename) {
|
|
183
|
+
const found = await this.get(idOrFilename);
|
|
184
|
+
if (!found)
|
|
185
|
+
throw new IssueNotFoundError(idOrFilename);
|
|
186
|
+
return found;
|
|
187
|
+
}
|
|
188
|
+
async create(spec) {
|
|
189
|
+
const now = new Date().toISOString();
|
|
190
|
+
const slug = slugify(spec.title);
|
|
191
|
+
// Allocation and write happen under one cross-process lock (Phase 1). Every
|
|
192
|
+
// new record gets a uid at birth, so the backfill only ever has to deal
|
|
193
|
+
// with records that predate this path.
|
|
194
|
+
const issue = {
|
|
195
|
+
uid: newUid(),
|
|
196
|
+
id: 'ISS-PENDING',
|
|
197
|
+
title: spec.title,
|
|
198
|
+
status: 'open',
|
|
199
|
+
severity: spec.severity,
|
|
200
|
+
priority: spec.priority,
|
|
201
|
+
tags: spec.tags,
|
|
202
|
+
assignee: spec.assignee,
|
|
203
|
+
team: spec.team,
|
|
204
|
+
epicId: spec.epicId,
|
|
205
|
+
project: spec.project,
|
|
206
|
+
details: spec.details,
|
|
207
|
+
created_at: now,
|
|
208
|
+
};
|
|
209
|
+
const build = (issueId) => {
|
|
210
|
+
const body = [
|
|
211
|
+
// First line only — a heading ends at the newline, so the rest would
|
|
212
|
+
// land in the body as stray prose. encodeIssue writes the whole title
|
|
213
|
+
// to frontmatter when it does not fit here.
|
|
214
|
+
`# ${spec.title.split(/\r?\n/)[0]}`,
|
|
215
|
+
'',
|
|
216
|
+
`**Severity:** ${spec.severity}`,
|
|
217
|
+
`**Status:** open`,
|
|
218
|
+
...(spec.epicId ? [`**Epic:** ${spec.epicId}`] : []),
|
|
219
|
+
'',
|
|
220
|
+
'## Details',
|
|
221
|
+
'',
|
|
222
|
+
spec.details,
|
|
223
|
+
'',
|
|
224
|
+
].join('\n');
|
|
225
|
+
const decoded = {
|
|
226
|
+
issue: { ...issue, id: issueId },
|
|
227
|
+
format: 'md',
|
|
228
|
+
raw: { data: {}, body },
|
|
229
|
+
warnings: [],
|
|
230
|
+
};
|
|
231
|
+
return encodeIssue(decoded);
|
|
232
|
+
};
|
|
233
|
+
const allocated = await allocateAndWriteIssue(this.issuesDir, 'md', slug, build);
|
|
234
|
+
return this.requireOne(allocated.filename);
|
|
235
|
+
}
|
|
236
|
+
async update(idOrFilename, changes) {
|
|
237
|
+
const current = await this.requireOne(idOrFilename);
|
|
238
|
+
const content = await fs.readFile(current.path, 'utf-8');
|
|
239
|
+
const decoded = decodeIssue(current.filename, content);
|
|
240
|
+
const updated = {
|
|
241
|
+
...decoded,
|
|
242
|
+
issue: {
|
|
243
|
+
...decoded.issue,
|
|
244
|
+
...changes,
|
|
245
|
+
// Identity is not editable through update. Renumbering is a migration.
|
|
246
|
+
uid: decoded.issue.uid ?? changes.uid,
|
|
247
|
+
id: decoded.issue.id,
|
|
248
|
+
updated_at: new Date().toISOString(),
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
await writeFileAtomic(current.path, encodeIssue(updated));
|
|
252
|
+
return this.requireOne(current.filename);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Close a record, or report that it was already closed without touching what
|
|
256
|
+
* the first close recorded.
|
|
257
|
+
*
|
|
258
|
+
* A re-close used to overwrite `resolution` and move `closed_at` forward
|
|
259
|
+
* (ISS-0168). That is data loss, and silent: the resolution field is the only
|
|
260
|
+
* place the reasoning behind a fix survives outside a commit message, and the
|
|
261
|
+
* caller was told "closed" either way. The trigger was operator error — a
|
|
262
|
+
* `Closes:` trailer naming an already-closed issue — but the failure mode is
|
|
263
|
+
* not: citing the issue a piece of follow-up work came from is normal, and
|
|
264
|
+
* every such citation destroyed the original reasoning.
|
|
265
|
+
*
|
|
266
|
+
* So a record that is already terminal AND already carries a resolution keeps
|
|
267
|
+
* both. A status move between closed and wontfix is still honoured, since
|
|
268
|
+
* that is a real decision; a missing `closed_at` is filled in, since that only
|
|
269
|
+
* adds. When nothing is left to change the file is not rewritten at all, so a
|
|
270
|
+
* re-close does not even bump `updated_at`.
|
|
271
|
+
*
|
|
272
|
+
* Amending a resolution on purpose is `update`, which says what it does.
|
|
273
|
+
*/
|
|
274
|
+
async close(idOrFilename, resolution, status = 'closed') {
|
|
275
|
+
const current = await this.requireOne(idOrFilename);
|
|
276
|
+
const wasTerminal = current.issue.status === 'closed' || current.issue.status === 'wontfix';
|
|
277
|
+
const existingResolution = (current.issue.resolution ?? '').trim();
|
|
278
|
+
const now = new Date().toISOString();
|
|
279
|
+
if (wasTerminal && existingResolution) {
|
|
280
|
+
const changes = {};
|
|
281
|
+
if (current.issue.status !== status)
|
|
282
|
+
changes.status = status;
|
|
283
|
+
if (!current.issue.closed_at)
|
|
284
|
+
changes.closed_at = now;
|
|
285
|
+
const stored = Object.keys(changes).length > 0
|
|
286
|
+
? await this.update(idOrFilename, changes)
|
|
287
|
+
: current;
|
|
288
|
+
return { stored, preservedResolution: true };
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
stored: await this.update(idOrFilename, { status, resolution, closed_at: now }),
|
|
292
|
+
preservedResolution: false,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=issueRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issueRepository.js","sourceRoot":"","sources":["../../src/domain/issueRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A stable identifier that survives everything the human-facing id does not.
|
|
3
|
+
*
|
|
4
|
+
* ISS-NNNN is a display name: it is derived from a directory scan, it is
|
|
5
|
+
* reassigned when duplicates are repaired (four were, in Phase 2), and it is
|
|
6
|
+
* allocated independently per checkout — which is exactly how the same issue
|
|
7
|
+
* came to exist as ISS-0112 on one volume and ISS-0115 on another with nothing
|
|
8
|
+
* in the data connecting them. `uid` is the identity; `id` is the label.
|
|
9
|
+
*
|
|
10
|
+
* UUIDv7 rather than v4 because it is time-ordered: records sort by creation
|
|
11
|
+
* without consulting a timestamp field, and a Postgres index on it stays local
|
|
12
|
+
* rather than scattering writes across the tree when this reaches HQ sync.
|
|
13
|
+
*/
|
|
14
|
+
export declare function newUid(now?: number): string;
|
|
15
|
+
export declare function isUid(value: unknown): value is string;
|
|
16
|
+
//# sourceMappingURL=uid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uid.d.ts","sourceRoot":"","sources":["../../src/domain/uid.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,GAAG,GAAE,MAAmB,GAAG,MAAM,CAgBvD;AAID,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAErD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Record identity
|
|
3
|
+
// ============================================================================
|
|
4
|
+
//
|
|
5
|
+
// Lives apart from issue.ts because it is not an issue concept. ADRs need it
|
|
6
|
+
// too, and the daemon->Supabase projector (EPIC-0039) keys on it for every
|
|
7
|
+
// artifact type: a label like ISS-NNNN or ADR-NNNN is allocated per checkout
|
|
8
|
+
// and reissued, so two different records can wear the same one. This repo has
|
|
9
|
+
// two different ADRs both claiming ADR-0004.
|
|
10
|
+
// ============================================================================
|
|
11
|
+
import { randomBytes } from 'crypto';
|
|
12
|
+
/**
|
|
13
|
+
* A stable identifier that survives everything the human-facing id does not.
|
|
14
|
+
*
|
|
15
|
+
* ISS-NNNN is a display name: it is derived from a directory scan, it is
|
|
16
|
+
* reassigned when duplicates are repaired (four were, in Phase 2), and it is
|
|
17
|
+
* allocated independently per checkout — which is exactly how the same issue
|
|
18
|
+
* came to exist as ISS-0112 on one volume and ISS-0115 on another with nothing
|
|
19
|
+
* in the data connecting them. `uid` is the identity; `id` is the label.
|
|
20
|
+
*
|
|
21
|
+
* UUIDv7 rather than v4 because it is time-ordered: records sort by creation
|
|
22
|
+
* without consulting a timestamp field, and a Postgres index on it stays local
|
|
23
|
+
* rather than scattering writes across the tree when this reaches HQ sync.
|
|
24
|
+
*/
|
|
25
|
+
export function newUid(now = Date.now()) {
|
|
26
|
+
const bytes = randomBytes(16);
|
|
27
|
+
// 48-bit big-endian millisecond timestamp.
|
|
28
|
+
bytes[0] = (now / 2 ** 40) & 0xff;
|
|
29
|
+
bytes[1] = (now / 2 ** 32) & 0xff;
|
|
30
|
+
bytes[2] = (now / 2 ** 24) & 0xff;
|
|
31
|
+
bytes[3] = (now / 2 ** 16) & 0xff;
|
|
32
|
+
bytes[4] = (now / 2 ** 8) & 0xff;
|
|
33
|
+
bytes[5] = now & 0xff;
|
|
34
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x70; // version 7
|
|
35
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80; // RFC 4122 variant
|
|
36
|
+
const hex = bytes.toString('hex');
|
|
37
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
38
|
+
}
|
|
39
|
+
const UID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
40
|
+
export function isUid(value) {
|
|
41
|
+
return typeof value === 'string' && UID_RE.test(value);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=uid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uid.js","sourceRoot":"","sources":["../../src/domain/uid.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAC/E,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,8EAA8E;AAC9E,6CAA6C;AAC7C,+EAA+E;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,MAAM,CAAC,MAAc,IAAI,CAAC,GAAG,EAAE;IAC7C,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAE9B,2CAA2C;IAC3C,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAClC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAClC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAClC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAClC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IACjC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC;IAEtB,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,YAAY;IACjD,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,mBAAmB;IAExD,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;AAC7G,CAAC;AAED,MAAM,MAAM,GAAG,wEAAwE,CAAC;AAExF,MAAM,UAAU,KAAK,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { FacadeSpec } from './types.js';
|
|
2
2
|
export declare const coreFacades: FacadeSpec[];
|
|
3
3
|
export declare const proFacades: FacadeSpec[];
|
|
4
|
-
export declare const appFacades: FacadeSpec[];
|
|
5
4
|
export declare const allFacadeDefinitions: FacadeSpec[];
|
|
6
5
|
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/facades/definitions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7C,eAAO,MAAM,WAAW,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/facades/definitions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7C,eAAO,MAAM,WAAW,EAAE,UAAU,EA4enC,CAAC;AAMF,eAAO,MAAM,UAAU,EAAE,UAAU,EAmHlC,CAAC;AAqCF,eAAO,MAAM,oBAAoB,EAAE,UAAU,EAAoC,CAAC"}
|