glirastes 0.2.1 → 0.3.1
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 +96 -0
- package/CODE_OF_CONDUCT.md +85 -0
- package/CONTRIBUTING.md +87 -0
- package/README.md +268 -23
- package/SECURITY.md +46 -0
- package/codegen/package.json +5 -0
- package/dist/cjs/codegen/asset-sync.d.ts +20 -0
- package/dist/cjs/codegen/asset-sync.js +28 -0
- package/dist/cjs/codegen/coverage.d.ts +66 -0
- package/dist/cjs/codegen/coverage.js +408 -0
- package/dist/cjs/codegen/endpoint-scanner.d.ts +16 -0
- package/dist/cjs/codegen/endpoint-scanner.js +197 -0
- package/dist/cjs/codegen/format.d.ts +17 -0
- package/dist/cjs/codegen/format.js +34 -0
- package/dist/cjs/codegen/fs-utils.d.ts +45 -0
- package/dist/cjs/codegen/fs-utils.js +165 -0
- package/dist/cjs/codegen/index.d.ts +13 -0
- package/dist/cjs/codegen/index.js +33 -0
- package/dist/cjs/codegen/mcp-generator.d.ts +50 -0
- package/dist/cjs/codegen/mcp-generator.js +803 -0
- package/dist/cjs/codegen/module-generator.d.ts +11 -0
- package/dist/cjs/codegen/module-generator.js +353 -0
- package/dist/cjs/codegen/nestjs-scanner.d.ts +43 -0
- package/dist/cjs/codegen/nestjs-scanner.js +241 -0
- package/dist/cjs/codegen/output-recommender.d.ts +23 -0
- package/dist/cjs/codegen/output-recommender.js +33 -0
- package/dist/cjs/codegen/scaffolder.d.ts +36 -0
- package/dist/cjs/codegen/scaffolder.js +262 -0
- package/dist/cjs/codegen/skill-generator.d.ts +49 -0
- package/dist/cjs/codegen/skill-generator.js +967 -0
- package/dist/cjs/codegen/types.d.ts +52 -0
- package/dist/cjs/codegen/types.js +16 -0
- package/dist/cjs/codegen/ui-scanner.d.ts +24 -0
- package/dist/cjs/codegen/ui-scanner.js +202 -0
- package/dist/cjs/codegen/validator.d.ts +35 -0
- package/dist/cjs/codegen/validator.js +292 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +23 -0
- package/dist/cjs/openapi/index.d.ts +78 -0
- package/dist/cjs/openapi/index.js +347 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/react/audio-worklet-processor.d.ts +16 -0
- package/dist/cjs/react/audio-worklet-processor.js +27 -0
- package/dist/cjs/react/bridges/rest-session-bridge.d.ts +113 -0
- package/dist/cjs/react/bridges/rest-session-bridge.js +209 -0
- package/dist/cjs/react/components/ai-chat-panel.d.ts +12 -0
- package/dist/cjs/react/components/ai-chat-panel.js +67 -0
- package/dist/cjs/react/components/ai-trigger-button.d.ts +2 -0
- package/dist/cjs/react/components/ai-trigger-button.js +239 -0
- package/dist/cjs/react/components/approval-card.d.ts +9 -0
- package/dist/cjs/react/components/approval-card.js +24 -0
- package/dist/cjs/react/components/bulk-approval-card.d.ts +9 -0
- package/dist/cjs/react/components/bulk-approval-card.js +36 -0
- package/dist/cjs/react/components/chat-input.d.ts +10 -0
- package/dist/cjs/react/components/chat-input.js +60 -0
- package/dist/cjs/react/components/chat-window.d.ts +2 -0
- package/dist/cjs/react/components/chat-window.js +134 -0
- package/dist/cjs/react/components/confirm-dialog.d.ts +32 -0
- package/dist/cjs/react/components/confirm-dialog.js +48 -0
- package/dist/cjs/react/components/floating-chat-ui.d.ts +90 -0
- package/dist/cjs/react/components/floating-chat-ui.js +163 -0
- package/dist/cjs/react/components/mention-chip.d.ts +16 -0
- package/dist/cjs/react/components/mention-chip.js +42 -0
- package/dist/cjs/react/components/mention-input.d.ts +8 -0
- package/dist/cjs/react/components/mention-input.js +117 -0
- package/dist/cjs/react/components/message-bubble.d.ts +11 -0
- package/dist/cjs/react/components/message-bubble.js +171 -0
- package/dist/cjs/react/components/message-list.d.ts +8 -0
- package/dist/cjs/react/components/message-list.js +52 -0
- package/dist/cjs/react/components/pipeline-timeline.d.ts +7 -0
- package/dist/cjs/react/components/pipeline-timeline.js +72 -0
- package/dist/cjs/react/components/recording-bar.d.ts +2 -0
- package/dist/cjs/react/components/recording-bar.js +81 -0
- package/dist/cjs/react/components/recording-controls.d.ts +18 -0
- package/dist/cjs/react/components/recording-controls.js +38 -0
- package/dist/cjs/react/components/rich-mention-input.d.ts +2 -0
- package/dist/cjs/react/components/rich-mention-input.js +571 -0
- package/dist/cjs/react/components/session-switcher.d.ts +14 -0
- package/dist/cjs/react/components/session-switcher.js +133 -0
- package/dist/cjs/react/components/suggestion-bar.d.ts +9 -0
- package/dist/cjs/react/components/suggestion-bar.js +47 -0
- package/dist/cjs/react/components/suggestion-chip.d.ts +9 -0
- package/dist/cjs/react/components/suggestion-chip.js +14 -0
- package/dist/cjs/react/components/voice-input-addon.d.ts +13 -0
- package/dist/cjs/react/components/voice-input-addon.js +31 -0
- package/dist/cjs/react/components/voice-input-button.d.ts +2 -0
- package/dist/cjs/react/components/voice-input-button.js +55 -0
- package/dist/cjs/react/components/wavesurfer-loader.d.ts +5 -0
- package/dist/cjs/react/components/wavesurfer-loader.js +36 -0
- package/dist/cjs/react/hooks/use-ai-chat.d.ts +22 -0
- package/dist/cjs/react/hooks/use-ai-chat.js +51 -0
- package/dist/cjs/react/hooks/use-approvals.d.ts +23 -0
- package/dist/cjs/react/hooks/use-approvals.js +63 -0
- package/dist/cjs/react/hooks/use-deepgram-transcription.d.ts +2 -0
- package/dist/cjs/react/hooks/use-deepgram-transcription.js +329 -0
- package/dist/cjs/react/hooks/use-drag-resize-panel.d.ts +48 -0
- package/dist/cjs/react/hooks/use-drag-resize-panel.js +308 -0
- package/dist/cjs/react/hooks/use-draggable-position.d.ts +25 -0
- package/dist/cjs/react/hooks/use-draggable-position.js +134 -0
- package/dist/cjs/react/hooks/use-keyboard-shortcut.d.ts +20 -0
- package/dist/cjs/react/hooks/use-keyboard-shortcut.js +93 -0
- package/dist/cjs/react/hooks/use-mentions.d.ts +23 -0
- package/dist/cjs/react/hooks/use-mentions.js +42 -0
- package/dist/cjs/react/hooks/use-suggestions.d.ts +22 -0
- package/dist/cjs/react/hooks/use-suggestions.js +39 -0
- package/dist/cjs/react/index.d.ts +43 -0
- package/dist/cjs/react/index.js +111 -0
- package/dist/cjs/react/provider/ai-chat-provider.d.ts +45 -0
- package/dist/cjs/react/provider/ai-chat-provider.js +1024 -0
- package/dist/cjs/react/provider/chat-context.d.ts +84 -0
- package/dist/cjs/react/provider/chat-context.js +13 -0
- package/dist/cjs/react/template.d.ts +84 -0
- package/dist/cjs/react/template.js +90 -0
- package/dist/cjs/react/themes.d.ts +24 -0
- package/dist/cjs/react/themes.js +273 -0
- package/dist/cjs/react/transports/langgraph/index.d.ts +2 -0
- package/dist/cjs/react/transports/langgraph/index.js +8 -0
- package/dist/cjs/react/transports/langgraph/langgraph-ai-chat.d.ts +62 -0
- package/dist/cjs/react/transports/langgraph/langgraph-ai-chat.js +94 -0
- package/dist/cjs/react/transports/langgraph.d.ts +71 -0
- package/dist/cjs/react/transports/langgraph.js +369 -0
- package/dist/cjs/react/transports/vercel/index.d.ts +2 -0
- package/dist/cjs/react/transports/vercel/index.js +8 -0
- package/dist/cjs/react/transports/vercel/vercel-ai-chat.d.ts +49 -0
- package/dist/cjs/react/transports/vercel/vercel-ai-chat.js +81 -0
- package/dist/cjs/react/transports/vercel.d.ts +30 -0
- package/dist/cjs/react/transports/vercel.js +69 -0
- package/dist/cjs/react/types.d.ts +760 -0
- package/dist/cjs/react/types.js +2 -0
- package/dist/cjs/react/ui.d.ts +73 -0
- package/dist/cjs/react/ui.js +183 -0
- package/dist/cjs/react/utils/create-approval-description.d.ts +53 -0
- package/dist/cjs/react/utils/create-approval-description.js +122 -0
- package/dist/cjs/react/utils/create-tool-result-handler.d.ts +90 -0
- package/dist/cjs/react/utils/create-tool-result-handler.js +168 -0
- package/dist/cjs/react/utils/mention-markup.d.ts +13 -0
- package/dist/cjs/react/utils/mention-markup.js +117 -0
- package/dist/cjs/react/utils/merge-pipeline-steps.d.ts +19 -0
- package/dist/cjs/react/utils/merge-pipeline-steps.js +81 -0
- package/dist/cjs/react/utils/sanitize-stored-messages.d.ts +23 -0
- package/dist/cjs/react/utils/sanitize-stored-messages.js +52 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat-auth.guard.d.ts +10 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat-auth.guard.js +42 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat-module-options.interface.d.ts +32 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat-module-options.interface.js +4 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.controller.d.ts +11 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.controller.js +80 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.module.d.ts +9 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.module.js +119 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.service.d.ts +13 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.service.js +131 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/ai-chat-request.dto.d.ts +7 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/ai-chat-request.dto.js +52 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message-part.dto.d.ts +19 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message-part.dto.js +108 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message.dto.d.ts +8 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message.dto.js +59 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/index.d.ts +3 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/index.js +9 -0
- package/dist/cjs/server/adapters/nestjs/chat/index.d.ts +3 -0
- package/dist/cjs/server/adapters/nestjs/chat/index.js +9 -0
- package/dist/cjs/server/adapters/nestjs/chat/speech-stream.gateway.d.ts +4 -0
- package/dist/cjs/server/adapters/nestjs/chat/speech-stream.gateway.js +73 -0
- package/dist/cjs/server/adapters/nestjs/chat/ws-loader.d.ts +5 -0
- package/dist/cjs/server/adapters/nestjs/chat/ws-loader.js +72 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-module.decorator.d.ts +6 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-module.decorator.js +13 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-param.decorator.d.ts +5 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-param.decorator.js +15 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-tool.decorator.d.ts +6 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-tool.decorator.js +22 -0
- package/dist/cjs/server/adapters/nestjs/decorators/constants.d.ts +4 -0
- package/dist/cjs/server/adapters/nestjs/decorators/constants.js +7 -0
- package/dist/cjs/server/adapters/nestjs/index.d.ts +14 -0
- package/dist/cjs/server/adapters/nestjs/index.js +42 -0
- package/dist/cjs/server/adapters/nestjs/metadata.d.ts +39 -0
- package/dist/cjs/server/adapters/nestjs/metadata.js +36 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools-explorer.service.d.ts +36 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools-explorer.service.js +159 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools.module.d.ts +37 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools.module.js +44 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools.service.d.ts +28 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools.service.js +41 -0
- package/dist/cjs/server/adapters/nestjs/scanner/nestjs-scanner.d.ts +16 -0
- package/dist/cjs/server/adapters/nestjs/scanner/nestjs-scanner.js +117 -0
- package/dist/cjs/server/adapters/nestjs/scanner/schema-builder.d.ts +26 -0
- package/dist/cjs/server/adapters/nestjs/scanner/schema-builder.js +259 -0
- package/dist/cjs/server/adapters/nestjs/swagger.d.ts +7 -0
- package/dist/cjs/server/adapters/nestjs/swagger.js +39 -0
- package/dist/cjs/server/adapters/nextjs/context-helpers.d.ts +22 -0
- package/dist/cjs/server/adapters/nextjs/context-helpers.js +60 -0
- package/dist/cjs/server/adapters/nextjs/create-ai-chat-handler.d.ts +94 -0
- package/dist/cjs/server/adapters/nextjs/create-ai-chat-handler.js +965 -0
- package/dist/cjs/server/adapters/nextjs/filter-fallback-error.d.ts +11 -0
- package/dist/cjs/server/adapters/nextjs/filter-fallback-error.js +41 -0
- package/dist/cjs/server/adapters/nextjs/index.d.ts +8 -0
- package/dist/cjs/server/adapters/nextjs/index.js +22 -0
- package/dist/cjs/server/adapters/nextjs/prepare-model-messages.d.ts +58 -0
- package/dist/cjs/server/adapters/nextjs/prepare-model-messages.js +114 -0
- package/dist/cjs/server/adapters/nextjs/sanitize-model-messages.d.ts +64 -0
- package/dist/cjs/server/adapters/nextjs/sanitize-model-messages.js +489 -0
- package/dist/cjs/server/adapters/nextjs/server-action-helper.d.ts +7 -0
- package/dist/cjs/server/adapters/nextjs/server-action-helper.js +40 -0
- package/dist/cjs/server/adapters/nextjs/types.d.ts +246 -0
- package/dist/cjs/server/adapters/nextjs/types.js +2 -0
- package/dist/cjs/server/adapters/nextjs/with-ai-tool.d.ts +9 -0
- package/dist/cjs/server/adapters/nextjs/with-ai-tool.js +12 -0
- package/dist/cjs/server/core/followup-tool.d.ts +9 -0
- package/dist/cjs/server/core/followup-tool.js +82 -0
- package/dist/cjs/server/core/index.d.ts +139 -0
- package/dist/cjs/server/core/index.js +818 -0
- package/dist/cjs/server/core/intent-classifier.d.ts +94 -0
- package/dist/cjs/server/core/intent-classifier.js +324 -0
- package/dist/cjs/server/core/model-selector.d.ts +12 -0
- package/dist/cjs/server/core/model-selector.js +48 -0
- package/dist/cjs/server/core/module-router.d.ts +14 -0
- package/dist/cjs/server/core/module-router.js +110 -0
- package/dist/cjs/server/core/zod-compact.d.ts +18 -0
- package/dist/cjs/server/core/zod-compact.js +129 -0
- package/dist/cjs/server/index.d.ts +6 -0
- package/dist/cjs/server/index.js +28 -0
- package/dist/cjs/server/lancer/cache.d.ts +9 -0
- package/dist/cjs/server/lancer/cache.js +33 -0
- package/dist/cjs/server/lancer/client.d.ts +2 -0
- package/dist/cjs/server/lancer/client.js +279 -0
- package/dist/cjs/server/lancer/errors.d.ts +13 -0
- package/dist/cjs/server/lancer/errors.js +21 -0
- package/dist/cjs/server/lancer/index.d.ts +3 -0
- package/dist/cjs/server/lancer/index.js +7 -0
- package/dist/cjs/server/lancer/telemetry-buffer.d.ts +15 -0
- package/dist/cjs/server/lancer/telemetry-buffer.js +64 -0
- package/dist/cjs/server/lancer/types.d.ts +201 -0
- package/dist/cjs/server/lancer/types.js +5 -0
- package/dist/cjs/server/pii-shield/aegis-detector.d.ts +26 -0
- package/dist/cjs/server/pii-shield/aegis-detector.js +26 -0
- package/dist/cjs/server/pii-shield/create-pii-shield.d.ts +2 -0
- package/dist/cjs/server/pii-shield/create-pii-shield.js +191 -0
- package/dist/cjs/server/pii-shield/deep-walk.d.ts +1 -0
- package/dist/cjs/server/pii-shield/deep-walk.js +19 -0
- package/dist/cjs/server/pii-shield/fake-data.d.ts +5 -0
- package/dist/cjs/server/pii-shield/fake-data.js +170 -0
- package/dist/cjs/server/pii-shield/index.d.ts +4 -0
- package/dist/cjs/server/pii-shield/index.js +9 -0
- package/dist/cjs/server/pii-shield/leakage.d.ts +1 -0
- package/dist/cjs/server/pii-shield/leakage.js +15 -0
- package/dist/cjs/server/pii-shield/session-mapping.d.ts +12 -0
- package/dist/cjs/server/pii-shield/session-mapping.js +70 -0
- package/dist/cjs/server/pipeline.d.ts +26 -0
- package/dist/cjs/server/pipeline.js +127 -0
- package/dist/cjs/server/testing/approvals.d.ts +11 -0
- package/dist/cjs/server/testing/approvals.js +41 -0
- package/dist/cjs/server/testing/combination.d.ts +3 -0
- package/dist/cjs/server/testing/combination.js +83 -0
- package/dist/cjs/server/testing/create-test-suite.d.ts +29 -0
- package/dist/cjs/server/testing/create-test-suite.js +81 -0
- package/dist/cjs/server/testing/edge-cases.d.ts +8 -0
- package/dist/cjs/server/testing/edge-cases.js +277 -0
- package/dist/cjs/server/testing/guardrails.d.ts +14 -0
- package/dist/cjs/server/testing/guardrails.js +152 -0
- package/dist/cjs/server/testing/helpers.d.ts +14 -0
- package/dist/cjs/server/testing/helpers.js +119 -0
- package/dist/cjs/server/testing/index.d.ts +12 -0
- package/dist/cjs/server/testing/index.js +37 -0
- package/dist/cjs/server/testing/mock-executor.d.ts +8 -0
- package/dist/cjs/server/testing/mock-executor.js +40 -0
- package/dist/cjs/server/testing/regression.d.ts +7 -0
- package/dist/cjs/server/testing/regression.js +27 -0
- package/dist/cjs/server/testing/routing.d.ts +12 -0
- package/dist/cjs/server/testing/routing.js +63 -0
- package/dist/cjs/server/testing/schema-consistency.d.ts +6 -0
- package/dist/cjs/server/testing/schema-consistency.js +56 -0
- package/dist/cjs/server/testing/smoke.d.ts +11 -0
- package/dist/cjs/server/testing/smoke.js +64 -0
- package/dist/cjs/server/testing/types.d.ts +156 -0
- package/dist/cjs/server/testing/types.js +2 -0
- package/dist/cjs/types.d.ts +696 -0
- package/dist/cjs/types.js +91 -0
- package/dist/cli/commands/install-skills.d.ts +17 -0
- package/dist/cli/commands/install-skills.js +185 -0
- package/dist/cli/commands/install-skills.js.map +1 -0
- package/dist/cli/index.js +25 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/react/components/ai-trigger-button.js +4 -6
- package/dist/react/components/ai-trigger-button.js.map +1 -1
- package/dist/react/components/recording-bar.js +4 -6
- package/dist/react/components/recording-bar.js.map +1 -1
- package/dist/react/components/wavesurfer-loader.d.ts +5 -0
- package/dist/react/components/wavesurfer-loader.js +34 -0
- package/dist/react/components/wavesurfer-loader.js.map +1 -0
- package/dist/server/adapters/nestjs/chat/ai-chat.module.d.ts +1 -1
- package/dist/server/adapters/nestjs/chat/ai-chat.module.js +3 -2
- package/dist/server/adapters/nestjs/chat/ai-chat.module.js.map +1 -1
- package/dist/server/adapters/nestjs/chat/speech-stream.gateway.d.ts +1 -1
- package/dist/server/adapters/nestjs/chat/speech-stream.gateway.js +10 -8
- package/dist/server/adapters/nestjs/chat/speech-stream.gateway.js.map +1 -1
- package/dist/server/adapters/nestjs/chat/ws-loader.d.ts +5 -0
- package/dist/server/adapters/nestjs/chat/ws-loader.js +37 -0
- package/dist/server/adapters/nestjs/chat/ws-loader.js.map +1 -0
- package/dist/server/adapters/nextjs/create-ai-chat-handler.d.ts +16 -0
- package/dist/server/adapters/nextjs/create-ai-chat-handler.js +14 -3
- package/dist/server/adapters/nextjs/create-ai-chat-handler.js.map +1 -1
- package/dist/server/adapters/nextjs/filter-fallback-error.d.ts +11 -0
- package/dist/server/adapters/nextjs/filter-fallback-error.js +38 -0
- package/dist/server/adapters/nextjs/filter-fallback-error.js.map +1 -0
- package/openapi/package.json +5 -0
- package/package.json +66 -21
- package/react/langgraph/package.json +5 -0
- package/react/package.json +5 -0
- package/react/vercel/package.json +5 -0
- package/server/nestjs/package.json +5 -0
- package/server/nextjs/package.json +5 -0
- package/server/package.json +5 -0
- package/server/testing/package.json +5 -0
- package/skills/README.md +107 -0
- package/skills/building-glirastes-chat-ui/SKILL.md +378 -0
- package/skills/integrating-glirastes-nestjs/SKILL.md +346 -0
- package/skills/integrating-glirastes-nextjs/SKILL.md +306 -0
- package/skills/integrating-glirastes-nextjs-with-nestjs-backend/SKILL.md +359 -0
- package/skills/maintaining-glirastes-tools/SKILL.md +463 -0
package/SECURITY.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a Vulnerability
|
|
4
|
+
|
|
5
|
+
If you discover a security vulnerability in **glirastes**, please report it
|
|
6
|
+
privately. **Do not open a public GitHub issue.**
|
|
7
|
+
|
|
8
|
+
Email: **security@chainmatics.net**
|
|
9
|
+
|
|
10
|
+
Alternatively, use [GitHub's private vulnerability reporting](https://github.com/chainmatics/glirastes/security/advisories/new).
|
|
11
|
+
|
|
12
|
+
We will:
|
|
13
|
+
|
|
14
|
+
- Acknowledge your report within **2 business days**
|
|
15
|
+
- Provide an initial assessment within **5 business days**
|
|
16
|
+
- Coordinate a fix and public disclosure, typically within **90 days** of the
|
|
17
|
+
initial report
|
|
18
|
+
|
|
19
|
+
When the fix ships, we publish a [GitHub Security Advisory](https://github.com/chainmatics/glirastes/security/advisories)
|
|
20
|
+
and credit the reporter (unless anonymity is preferred).
|
|
21
|
+
|
|
22
|
+
## Supported Versions
|
|
23
|
+
|
|
24
|
+
Only the latest released minor version of `glirastes` receives security
|
|
25
|
+
updates. Please upgrade before reporting issues against older versions.
|
|
26
|
+
|
|
27
|
+
## Scope
|
|
28
|
+
|
|
29
|
+
In scope:
|
|
30
|
+
|
|
31
|
+
- The `glirastes` npm package and its subpath exports
|
|
32
|
+
- Code in this repository
|
|
33
|
+
|
|
34
|
+
Out of scope:
|
|
35
|
+
|
|
36
|
+
- Third-party dependencies (please report directly to the upstream maintainer)
|
|
37
|
+
- The Glirastes platform / Citadel (closed source, separate disclosure path)
|
|
38
|
+
|
|
39
|
+
## Safe Harbor
|
|
40
|
+
|
|
41
|
+
We will not pursue legal action against researchers who:
|
|
42
|
+
|
|
43
|
+
- Make a good-faith effort to avoid privacy violations, data destruction, and
|
|
44
|
+
service disruption
|
|
45
|
+
- Report findings privately as described above
|
|
46
|
+
- Give us a reasonable window to remediate before public disclosure
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface AssetSyncOptions {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
glirasterUrl: string;
|
|
4
|
+
name: string;
|
|
5
|
+
type: 'skill' | 'mcp-server';
|
|
6
|
+
version: string;
|
|
7
|
+
toolCount: number;
|
|
8
|
+
config: Record<string, unknown>;
|
|
9
|
+
toolManifest: Record<string, unknown>;
|
|
10
|
+
/** Pre-generated files to upload alongside the manifest */
|
|
11
|
+
generatedFiles?: Array<{
|
|
12
|
+
path: string;
|
|
13
|
+
content: string;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
export interface AssetSyncResult {
|
|
17
|
+
action: 'created' | 'updated';
|
|
18
|
+
assetId: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function syncAssetToGlirastes(options: AssetSyncOptions): Promise<AssetSyncResult>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.syncAssetToGlirastes = syncAssetToGlirastes;
|
|
4
|
+
async function syncAssetToGlirastes(options) {
|
|
5
|
+
const url = `${options.glirasterUrl}/v1/registry/assets/sync`;
|
|
6
|
+
const response = await fetch(url, {
|
|
7
|
+
method: 'POST',
|
|
8
|
+
headers: {
|
|
9
|
+
'Content-Type': 'application/json',
|
|
10
|
+
'x-api-key': options.apiKey,
|
|
11
|
+
},
|
|
12
|
+
body: JSON.stringify({
|
|
13
|
+
name: options.name,
|
|
14
|
+
type: options.type,
|
|
15
|
+
version: options.version,
|
|
16
|
+
toolCount: options.toolCount,
|
|
17
|
+
config: options.config,
|
|
18
|
+
toolManifest: options.toolManifest,
|
|
19
|
+
generatedFiles: options.generatedFiles,
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
const text = await response.text();
|
|
24
|
+
throw new Error(`Glirastes sync failed (${response.status}): ${text}`);
|
|
25
|
+
}
|
|
26
|
+
const data = await response.json();
|
|
27
|
+
return { action: data.action, assetId: data.asset.id };
|
|
28
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { GenerateOptions } from './types.js';
|
|
2
|
+
export interface CoverageReport {
|
|
3
|
+
endpointToolCount: number;
|
|
4
|
+
endpointFileCount: number;
|
|
5
|
+
uiToolCount: number;
|
|
6
|
+
uiFileCount: number;
|
|
7
|
+
actionIdCount: number;
|
|
8
|
+
routeTotal: number;
|
|
9
|
+
routeCovered: number;
|
|
10
|
+
routeIgnored: number;
|
|
11
|
+
routeCoveragePercent: number;
|
|
12
|
+
componentDirTotal: number;
|
|
13
|
+
componentDirCovered: number;
|
|
14
|
+
componentDirIgnored: number;
|
|
15
|
+
componentCoveragePercent: number;
|
|
16
|
+
sharedWithConfigs: Array<{
|
|
17
|
+
toolName: string;
|
|
18
|
+
primaryModule: string;
|
|
19
|
+
sharedWith: string[];
|
|
20
|
+
}>;
|
|
21
|
+
/** Handler coverage: how many actionIds have registered handlers in source */
|
|
22
|
+
handlerActionIds: string[];
|
|
23
|
+
handlerCoveredCount: number;
|
|
24
|
+
handlerTotalCount: number;
|
|
25
|
+
handlerCoveragePercent: number;
|
|
26
|
+
/** Orphan handlers: useAiClientAction calls without a matching UI tool actionId */
|
|
27
|
+
orphanHandlers: Array<{
|
|
28
|
+
actionId: string;
|
|
29
|
+
sourceFile: string;
|
|
30
|
+
}>;
|
|
31
|
+
/** Routes without a corresponding ai-tool.ts (relative paths) */
|
|
32
|
+
uncoveredRoutes: string[];
|
|
33
|
+
/** Component directories without ai-ui-tool.ts (relative paths) */
|
|
34
|
+
uncoveredComponents: string[];
|
|
35
|
+
/** Action IDs that have no registered useAiClientAction handler */
|
|
36
|
+
missingHandlers: Array<{
|
|
37
|
+
actionId: string;
|
|
38
|
+
toolName: string;
|
|
39
|
+
sourceFile: string;
|
|
40
|
+
}>;
|
|
41
|
+
/** NestJS controller coverage */
|
|
42
|
+
nestControllerTotal: number;
|
|
43
|
+
nestControllerCovered: number;
|
|
44
|
+
nestControllerIgnored: number;
|
|
45
|
+
nestControllerCoveragePercent: number;
|
|
46
|
+
/** Number of @AiTool-decorated methods found across NestJS controllers */
|
|
47
|
+
nestToolCount: number;
|
|
48
|
+
/** NestJS controllers found without @AiTool decorators (not ignored) */
|
|
49
|
+
uncoveredNestControllers: Array<{
|
|
50
|
+
controllerFile: string;
|
|
51
|
+
controllerName: string;
|
|
52
|
+
httpMethodCount: number;
|
|
53
|
+
}>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check AI tool coverage across the project.
|
|
57
|
+
* Reports on endpoint tools, UI tools, route coverage,
|
|
58
|
+
* component coverage, and sharedWith configurations.
|
|
59
|
+
*/
|
|
60
|
+
export declare function checkAiCoverage(options: GenerateOptions): Promise<CoverageReport>;
|
|
61
|
+
/**
|
|
62
|
+
* Format a coverage report as a rich, color-coded human-readable string.
|
|
63
|
+
*/
|
|
64
|
+
export declare function formatCoverageReport(report: CoverageReport, options?: {
|
|
65
|
+
quiet?: boolean;
|
|
66
|
+
}): string;
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.checkAiCoverage = checkAiCoverage;
|
|
37
|
+
exports.formatCoverageReport = formatCoverageReport;
|
|
38
|
+
const node_path_1 = require("node:path");
|
|
39
|
+
const promises_1 = require("node:fs/promises");
|
|
40
|
+
const fs_utils_js_1 = require("./fs-utils.js");
|
|
41
|
+
const endpoint_scanner_js_1 = require("./endpoint-scanner.js");
|
|
42
|
+
const ui_scanner_js_1 = require("./ui-scanner.js");
|
|
43
|
+
const types_js_1 = require("./types.js");
|
|
44
|
+
const format_js_1 = require("./format.js");
|
|
45
|
+
/**
|
|
46
|
+
* Check AI tool coverage across the project.
|
|
47
|
+
* Reports on endpoint tools, UI tools, route coverage,
|
|
48
|
+
* component coverage, and sharedWith configurations.
|
|
49
|
+
*/
|
|
50
|
+
async function checkAiCoverage(options) {
|
|
51
|
+
const opts = (0, types_js_1.resolveDefaults)(options);
|
|
52
|
+
// Scan tools
|
|
53
|
+
const endpointScan = await (0, endpoint_scanner_js_1.scanEndpointTools)(options);
|
|
54
|
+
const uiScan = await (0, ui_scanner_js_1.scanUiTools)(options);
|
|
55
|
+
const actionIds = await (0, ui_scanner_js_1.extractActionIds)(options);
|
|
56
|
+
// NestJS controller coverage
|
|
57
|
+
let nestControllerTotal = 0;
|
|
58
|
+
let nestControllerCovered = 0;
|
|
59
|
+
let nestControllerIgnored = 0;
|
|
60
|
+
let nestToolCount = 0;
|
|
61
|
+
const uncoveredNestControllers = [];
|
|
62
|
+
if (opts.nestjsDirs.length > 0) {
|
|
63
|
+
const { scanNestControllers } = await Promise.resolve().then(() => __importStar(require('./nestjs-scanner.js')));
|
|
64
|
+
const nestResult = await scanNestControllers(opts.nestjsDirs, opts.nestjsApiPrefix);
|
|
65
|
+
// Count unique controller files that have tools
|
|
66
|
+
const coveredFiles = new Set(nestResult.tools.map(t => t.controllerFile));
|
|
67
|
+
nestControllerCovered = coveredFiles.size;
|
|
68
|
+
nestToolCount = nestResult.tools.length;
|
|
69
|
+
uncoveredNestControllers.push(...nestResult.uncoveredControllers);
|
|
70
|
+
nestControllerTotal = nestControllerCovered + uncoveredNestControllers.length;
|
|
71
|
+
}
|
|
72
|
+
// Route coverage
|
|
73
|
+
const apiDir = (0, node_path_1.join)(opts.rootDir, opts.apiDir);
|
|
74
|
+
const routeFiles = await (0, fs_utils_js_1.findRouteFiles)(apiDir);
|
|
75
|
+
const toolFiles = new Set((await (0, fs_utils_js_1.findFiles)(apiDir, opts.endpointToolFileName)).map((f) => f.replace(`/${opts.endpointToolFileName}`, '')));
|
|
76
|
+
let routeCovered = 0;
|
|
77
|
+
let routeIgnored = 0;
|
|
78
|
+
const uncoveredRoutes = [];
|
|
79
|
+
for (const routeFile of routeFiles) {
|
|
80
|
+
const routeDir = routeFile.replace('/route.ts', '');
|
|
81
|
+
const routeContent = await (0, fs_utils_js_1.readFileSafe)(routeFile);
|
|
82
|
+
if (routeContent.includes('@ai-ignore') || await (0, fs_utils_js_1.isDirAiIgnored)(routeDir)) {
|
|
83
|
+
routeIgnored++;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (toolFiles.has(routeDir) || routeContent.includes('withAiTool(')) {
|
|
87
|
+
routeCovered++;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
uncoveredRoutes.push(routeFile.replace(opts.rootDir + '/', ''));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const routeTotal = routeFiles.length - routeIgnored;
|
|
94
|
+
// Component coverage
|
|
95
|
+
const componentsDir = (0, node_path_1.join)(opts.rootDir, opts.componentsDir);
|
|
96
|
+
const componentDirs = await (0, fs_utils_js_1.getSubdirectories)(componentsDir);
|
|
97
|
+
const uiToolDirs = new Set((await (0, fs_utils_js_1.findFiles)(componentsDir, opts.uiToolFileName)).map((f) => f.replace(`/${opts.uiToolFileName}`, '')));
|
|
98
|
+
let componentDirCovered = 0;
|
|
99
|
+
let componentDirIgnored = 0;
|
|
100
|
+
const uncoveredComponents = [];
|
|
101
|
+
for (const dir of componentDirs) {
|
|
102
|
+
if (await (0, fs_utils_js_1.isDirAiIgnored)(dir)) {
|
|
103
|
+
componentDirIgnored++;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (uiToolDirs.has(dir)) {
|
|
107
|
+
componentDirCovered++;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
uncoveredComponents.push(dir.replace(opts.rootDir + '/', ''));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const componentDirTotal = componentDirs.length - componentDirIgnored;
|
|
114
|
+
// SharedWith analysis
|
|
115
|
+
const sharedWithConfigs = [];
|
|
116
|
+
for (const file of endpointScan.files) {
|
|
117
|
+
const content = await (0, fs_utils_js_1.readFileSafe)(file.absolutePath);
|
|
118
|
+
const toolBlocksArr = (0, fs_utils_js_1.extractBalancedBlocks)(content, /define(?:Ai)?EndpointTool\(\s*/);
|
|
119
|
+
for (const block of toolBlocksArr) {
|
|
120
|
+
const sharedMatch = block.match(/sharedWith\s*:\s*\[([^\]]*)\]/);
|
|
121
|
+
if (!sharedMatch)
|
|
122
|
+
continue;
|
|
123
|
+
const toolNameMatch = block.match(/toolName\s*:\s*['"`]([^'"`]+)['"`]/);
|
|
124
|
+
const moduleMatch = block.match(/module\s*:\s*['"`]([^'"`]+)['"`]/);
|
|
125
|
+
if (!toolNameMatch)
|
|
126
|
+
continue;
|
|
127
|
+
const sharedWith = sharedMatch[1]
|
|
128
|
+
.match(/['"`]([^'"`]+)['"`]/g)
|
|
129
|
+
?.map((s) => s.replace(/['"`]/g, ''));
|
|
130
|
+
if (sharedWith && sharedWith.length > 0) {
|
|
131
|
+
sharedWithConfigs.push({
|
|
132
|
+
toolName: toolNameMatch[1],
|
|
133
|
+
primaryModule: moduleMatch?.[1] ?? 'unknown',
|
|
134
|
+
sharedWith,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Handler source-scan: find useAiClientAction() calls in .tsx files
|
|
140
|
+
// In monorepos, scan all configured dirs + default src/
|
|
141
|
+
const handlerScanDirs = [
|
|
142
|
+
(0, node_path_1.join)(opts.rootDir, 'src'),
|
|
143
|
+
...(opts.nestjsDirs ?? []),
|
|
144
|
+
(0, node_path_1.join)(opts.rootDir, opts.componentsDir),
|
|
145
|
+
].filter((d, i, arr) => arr.indexOf(d) === i); // dedupe
|
|
146
|
+
const tsxFiles = [];
|
|
147
|
+
for (const dir of handlerScanDirs) {
|
|
148
|
+
tsxFiles.push(...await findTsxFiles(dir));
|
|
149
|
+
}
|
|
150
|
+
const requiredActionIds = new Set(actionIds.map((a) => a.actionId));
|
|
151
|
+
const foundHandlerIds = new Set();
|
|
152
|
+
const allSourceHandlers = [];
|
|
153
|
+
for (const tsxFile of tsxFiles) {
|
|
154
|
+
const content = await (0, fs_utils_js_1.readFileSafe)(tsxFile);
|
|
155
|
+
if (content.includes('@ai-ignore'))
|
|
156
|
+
continue;
|
|
157
|
+
// Match useAiClientAction('actionId', ...) calls
|
|
158
|
+
const handlerMatches = content.matchAll(/useAiClientAction\(\s*['"`]([^'"`]+)['"`]/g);
|
|
159
|
+
for (const m of handlerMatches) {
|
|
160
|
+
const actionId = m[1];
|
|
161
|
+
foundHandlerIds.add(actionId);
|
|
162
|
+
allSourceHandlers.push({
|
|
163
|
+
actionId,
|
|
164
|
+
sourceFile: tsxFile.replace(opts.rootDir + '/', ''),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const handlerCoveredCount = Array.from(requiredActionIds).filter((id) => foundHandlerIds.has(id)).length;
|
|
169
|
+
const handlerTotalCount = requiredActionIds.size;
|
|
170
|
+
// Orphan handlers: registered in source but no matching UI tool actionId
|
|
171
|
+
const orphanHandlers = allSourceHandlers.filter((h) => !requiredActionIds.has(h.actionId));
|
|
172
|
+
// Missing handlers: actionIds defined in UI tools but no useAiClientAction found
|
|
173
|
+
const missingHandlers = actionIds
|
|
174
|
+
.filter((a) => !foundHandlerIds.has(a.actionId))
|
|
175
|
+
.map((a) => ({
|
|
176
|
+
actionId: a.actionId,
|
|
177
|
+
toolName: a.toolName,
|
|
178
|
+
sourceFile: a.sourceFile,
|
|
179
|
+
}));
|
|
180
|
+
return {
|
|
181
|
+
endpointToolCount: endpointScan.toolCount,
|
|
182
|
+
endpointFileCount: endpointScan.files.length,
|
|
183
|
+
uiToolCount: uiScan.toolCount,
|
|
184
|
+
uiFileCount: uiScan.files.length,
|
|
185
|
+
actionIdCount: actionIds.length,
|
|
186
|
+
routeTotal,
|
|
187
|
+
routeCovered,
|
|
188
|
+
routeIgnored,
|
|
189
|
+
routeCoveragePercent: routeTotal > 0 ? Math.round((routeCovered / routeTotal) * 100) : 100,
|
|
190
|
+
componentDirTotal,
|
|
191
|
+
componentDirCovered,
|
|
192
|
+
componentDirIgnored,
|
|
193
|
+
componentCoveragePercent: componentDirTotal > 0
|
|
194
|
+
? Math.round((componentDirCovered / componentDirTotal) * 100)
|
|
195
|
+
: 100,
|
|
196
|
+
sharedWithConfigs,
|
|
197
|
+
handlerActionIds: Array.from(foundHandlerIds),
|
|
198
|
+
handlerCoveredCount,
|
|
199
|
+
handlerTotalCount,
|
|
200
|
+
handlerCoveragePercent: handlerTotalCount > 0
|
|
201
|
+
? Math.round((handlerCoveredCount / handlerTotalCount) * 100)
|
|
202
|
+
: 100,
|
|
203
|
+
orphanHandlers,
|
|
204
|
+
uncoveredRoutes,
|
|
205
|
+
uncoveredComponents,
|
|
206
|
+
missingHandlers,
|
|
207
|
+
nestControllerTotal,
|
|
208
|
+
nestControllerCovered,
|
|
209
|
+
nestControllerIgnored,
|
|
210
|
+
nestControllerCoveragePercent: nestControllerTotal > 0
|
|
211
|
+
? Math.round((nestControllerCovered / nestControllerTotal) * 100)
|
|
212
|
+
: 100,
|
|
213
|
+
nestToolCount,
|
|
214
|
+
uncoveredNestControllers,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Recursively find all .tsx files in a directory.
|
|
219
|
+
*/
|
|
220
|
+
async function findTsxFiles(dir) {
|
|
221
|
+
const results = [];
|
|
222
|
+
async function walk(currentDir) {
|
|
223
|
+
let entries;
|
|
224
|
+
try {
|
|
225
|
+
entries = await (0, promises_1.readdir)(currentDir, { withFileTypes: true });
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
for (const entry of entries) {
|
|
231
|
+
const fullPath = (0, node_path_1.join)(currentDir, entry.name);
|
|
232
|
+
if (entry.isDirectory()) {
|
|
233
|
+
if (entry.name === 'node_modules' || entry.name === '.git')
|
|
234
|
+
continue;
|
|
235
|
+
await walk(fullPath);
|
|
236
|
+
}
|
|
237
|
+
else if (entry.name.endsWith('.tsx')) {
|
|
238
|
+
results.push(fullPath);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
await walk(dir);
|
|
243
|
+
return results.sort();
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Format a coverage report as a rich, color-coded human-readable string.
|
|
247
|
+
*/
|
|
248
|
+
function formatCoverageReport(report, options) {
|
|
249
|
+
if (options?.quiet) {
|
|
250
|
+
return formatCoverageReportQuiet(report);
|
|
251
|
+
}
|
|
252
|
+
const lines = [];
|
|
253
|
+
const hasHandlerIssues = report.missingHandlers.length > 0;
|
|
254
|
+
const hasOrphanHandlers = report.orphanHandlers.length > 0;
|
|
255
|
+
const hasRouteIssues = report.uncoveredRoutes.length > 0;
|
|
256
|
+
const hasComponentIssues = report.uncoveredComponents.length > 0;
|
|
257
|
+
const hasNestIssues = report.uncoveredNestControllers.length > 0;
|
|
258
|
+
const hasIssues = hasHandlerIssues || hasOrphanHandlers || hasRouteIssues || hasComponentIssues || hasNestIssues;
|
|
259
|
+
// Detect active frameworks from scan results
|
|
260
|
+
const hasNextRoutes = report.routeTotal > 0 || report.endpointFileCount > 0;
|
|
261
|
+
const hasNest = report.nestControllerTotal > 0 || report.nestToolCount > 0;
|
|
262
|
+
// Header
|
|
263
|
+
lines.push((0, format_js_1.header)('AI Tools Coverage Summary'));
|
|
264
|
+
// Endpoint Tools — framework-adaptive detail
|
|
265
|
+
const totalEndpointTools = report.endpointToolCount + report.nestToolCount;
|
|
266
|
+
const endpointParts = [];
|
|
267
|
+
if (hasNextRoutes || (!hasNest && report.endpointFileCount === 0)) {
|
|
268
|
+
endpointParts.push(`${report.endpointFileCount} route files`);
|
|
269
|
+
}
|
|
270
|
+
if (hasNest) {
|
|
271
|
+
endpointParts.push(`${report.nestControllerCovered} controllers`);
|
|
272
|
+
}
|
|
273
|
+
lines.push((0, format_js_1.metricLine)('\u2713', format_js_1.colors.green, 'Endpoint Tools:', totalEndpointTools, endpointParts.join(' + ')));
|
|
274
|
+
lines.push((0, format_js_1.metricLine)('\u2713', format_js_1.colors.green, 'UI Tools (ai-ui-tool.ts):', report.uiToolCount, `${report.uiFileCount} files`));
|
|
275
|
+
const handlerIcon = hasHandlerIssues ? '\u26A0' : '\u2713';
|
|
276
|
+
const handlerColor = hasHandlerIssues ? format_js_1.colors.yellow : format_js_1.colors.green;
|
|
277
|
+
lines.push((0, format_js_1.metricLine)(handlerIcon, handlerColor, 'Handler Coverage:', `${report.handlerCoveragePercent}%`, `${report.handlerCoveredCount}/${report.handlerTotalCount}`));
|
|
278
|
+
// Route Coverage — only show when Next.js routes exist or are expected
|
|
279
|
+
if (hasNextRoutes) {
|
|
280
|
+
const routeIcon = hasRouteIssues ? '\u26A0' : '\u2713';
|
|
281
|
+
const routeColor = hasRouteIssues ? format_js_1.colors.yellow : format_js_1.colors.green;
|
|
282
|
+
lines.push((0, format_js_1.metricLine)(routeIcon, routeColor, 'Route Coverage:', `${report.routeCoveragePercent}%`, `${report.routeCovered}/${report.routeTotal} routes${report.routeIgnored > 0 ? `, ${report.routeIgnored} ignored` : ''}`));
|
|
283
|
+
}
|
|
284
|
+
const componentIcon = hasComponentIssues ? '\u26A0' : '\u2713';
|
|
285
|
+
const componentColor = hasComponentIssues ? format_js_1.colors.yellow : format_js_1.colors.green;
|
|
286
|
+
lines.push((0, format_js_1.metricLine)(componentIcon, componentColor, 'Component Coverage:', `${report.componentCoveragePercent}%`, `${report.componentDirCovered}/${report.componentDirTotal} dirs${report.componentDirIgnored > 0 ? `, ${report.componentDirIgnored} ignored` : ''}`));
|
|
287
|
+
// NestJS Decorator Coverage — only show when NestJS is detected
|
|
288
|
+
if (hasNest) {
|
|
289
|
+
const nestIcon = report.uncoveredNestControllers.length > 0 ? '\u26A0' : '\u2713';
|
|
290
|
+
const nestColor = report.uncoveredNestControllers.length > 0 ? format_js_1.colors.yellow : format_js_1.colors.green;
|
|
291
|
+
lines.push((0, format_js_1.metricLine)(nestIcon, nestColor, 'Decorator Coverage (@AiTool):', `${report.nestControllerCoveragePercent}%`, `${report.nestControllerCovered}/${report.nestControllerTotal} controllers`));
|
|
292
|
+
}
|
|
293
|
+
const sharedCount = report.sharedWithConfigs.length;
|
|
294
|
+
lines.push((0, format_js_1.metricLine)('\u2713', format_js_1.colors.green, 'Cross-Module Sharing:', sharedCount > 0 ? `${sharedCount} Tools` : 'None'));
|
|
295
|
+
lines.push('');
|
|
296
|
+
lines.push((0, format_js_1.separator)());
|
|
297
|
+
// --- Detail sections (conditional) ---
|
|
298
|
+
// Missing handlers
|
|
299
|
+
if (hasHandlerIssues) {
|
|
300
|
+
lines.push('');
|
|
301
|
+
lines.push((0, format_js_1.sectionHeader)('Missing Handlers', report.missingHandlers.length, format_js_1.colors.red));
|
|
302
|
+
for (const h of report.missingHandlers) {
|
|
303
|
+
lines.push(` ${format_js_1.colors.red}\u2717${format_js_1.colors.reset} ${format_js_1.colors.bold}${h.actionId}${format_js_1.colors.reset}` +
|
|
304
|
+
` ${format_js_1.colors.dim}\u2190 ${h.toolName}${format_js_1.colors.reset}`);
|
|
305
|
+
lines.push(` ${format_js_1.colors.dim}Defined in: ${h.sourceFile}${format_js_1.colors.reset}`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// Orphan handlers
|
|
309
|
+
if (hasOrphanHandlers) {
|
|
310
|
+
lines.push('');
|
|
311
|
+
lines.push((0, format_js_1.sectionHeader)('Orphan Handlers', report.orphanHandlers.length, format_js_1.colors.yellow));
|
|
312
|
+
lines.push(`${format_js_1.colors.dim}These handlers have no corresponding UI tool definition:${format_js_1.colors.reset}`);
|
|
313
|
+
for (const o of report.orphanHandlers) {
|
|
314
|
+
lines.push(` ${format_js_1.colors.yellow}\u26A0${format_js_1.colors.reset} ${format_js_1.colors.bold}${o.actionId}${format_js_1.colors.reset}` +
|
|
315
|
+
` ${format_js_1.colors.dim}\u2192 ${o.sourceFile}${format_js_1.colors.reset}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
// Uncovered routes
|
|
319
|
+
if (hasRouteIssues) {
|
|
320
|
+
lines.push('');
|
|
321
|
+
lines.push((0, format_js_1.sectionHeader)('Routes without ai-tool.ts', report.uncoveredRoutes.length, format_js_1.colors.yellow));
|
|
322
|
+
for (const route of report.uncoveredRoutes) {
|
|
323
|
+
lines.push(` ${format_js_1.colors.yellow}\u26A0${format_js_1.colors.reset} ${route}`);
|
|
324
|
+
lines.push(` ${format_js_1.colors.cyan}\u2192 glirastes scaffold --route "${route}"${format_js_1.colors.reset}`);
|
|
325
|
+
}
|
|
326
|
+
lines.push(`\n${format_js_1.colors.dim}Or add // @ai-ignore to route.ts to exclude${format_js_1.colors.reset}`);
|
|
327
|
+
}
|
|
328
|
+
// Uncovered components
|
|
329
|
+
if (hasComponentIssues) {
|
|
330
|
+
lines.push('');
|
|
331
|
+
lines.push((0, format_js_1.sectionHeader)('Components without ai-ui-tool.ts', report.uncoveredComponents.length, format_js_1.colors.yellow));
|
|
332
|
+
for (const dir of report.uncoveredComponents) {
|
|
333
|
+
lines.push(` ${format_js_1.colors.yellow}\u26A0${format_js_1.colors.reset} ${dir}/`);
|
|
334
|
+
lines.push(` ${format_js_1.colors.cyan}\u2192 Create ${dir}/ai-ui-tool.ts${format_js_1.colors.reset}`);
|
|
335
|
+
}
|
|
336
|
+
lines.push(`\n${format_js_1.colors.dim}Or add // @ai-ignore to any .ts/.tsx file or create .ai-ignore to exclude${format_js_1.colors.reset}`);
|
|
337
|
+
}
|
|
338
|
+
// Uncovered NestJS controllers
|
|
339
|
+
if (report.uncoveredNestControllers.length > 0) {
|
|
340
|
+
lines.push('');
|
|
341
|
+
lines.push((0, format_js_1.sectionHeader)('NestJS controllers without @AiTool', report.uncoveredNestControllers.length, format_js_1.colors.yellow));
|
|
342
|
+
lines.push(`${format_js_1.colors.dim}These controllers have HTTP endpoints but no @AiTool decorators:${format_js_1.colors.reset}`);
|
|
343
|
+
for (const ctrl of report.uncoveredNestControllers) {
|
|
344
|
+
const relPath = ctrl.controllerFile.includes('/src/')
|
|
345
|
+
? ctrl.controllerFile.slice(ctrl.controllerFile.indexOf('/src/') + 1)
|
|
346
|
+
: ctrl.controllerFile;
|
|
347
|
+
lines.push(` ${format_js_1.colors.yellow}\u26A0${format_js_1.colors.reset} ${format_js_1.colors.bold}${ctrl.controllerName}${format_js_1.colors.reset}` +
|
|
348
|
+
` ${format_js_1.colors.dim}(${ctrl.httpMethodCount} endpoints)${format_js_1.colors.reset}`);
|
|
349
|
+
lines.push(` ${format_js_1.colors.dim}${relPath}${format_js_1.colors.reset}`);
|
|
350
|
+
lines.push(` ${format_js_1.colors.cyan}\u2192 Add @AiModule + @AiTool decorators, or create .ai-ignore to exclude${format_js_1.colors.reset}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// SharedWith configurations (when no issues — show as positive info)
|
|
354
|
+
if (sharedCount > 0 && !hasIssues) {
|
|
355
|
+
lines.push('');
|
|
356
|
+
lines.push((0, format_js_1.sectionHeader)('Cross-Module Sharing', sharedCount, format_js_1.colors.green));
|
|
357
|
+
for (const config of report.sharedWithConfigs) {
|
|
358
|
+
lines.push(` ${format_js_1.colors.green}\u2713${format_js_1.colors.reset} ${format_js_1.colors.bold}${config.toolName}${format_js_1.colors.reset}` +
|
|
359
|
+
` ${format_js_1.colors.dim}(${config.primaryModule})${format_js_1.colors.reset}` +
|
|
360
|
+
` \u2192 ${config.sharedWith.join(', ')}`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// Final summary
|
|
364
|
+
lines.push('');
|
|
365
|
+
lines.push((0, format_js_1.separator)());
|
|
366
|
+
lines.push('');
|
|
367
|
+
const totalTools = report.endpointToolCount + report.uiToolCount + report.nestToolCount;
|
|
368
|
+
const summaryIcon = hasIssues ? '\u26A0\uFE0F' : '\u2705';
|
|
369
|
+
const summaryColor = hasIssues ? format_js_1.colors.yellow : format_js_1.colors.green;
|
|
370
|
+
lines.push(`${summaryColor}${summaryIcon} Total: ${format_js_1.colors.bold}${totalTools} AI Tools${format_js_1.colors.reset}`);
|
|
371
|
+
lines.push('');
|
|
372
|
+
// Framework-adaptive summary lines
|
|
373
|
+
if (hasNextRoutes) {
|
|
374
|
+
lines.push(` ${format_js_1.colors.dim}Routes: ${report.routeCovered}/${report.routeTotal} have ai-tool.ts (${report.endpointToolCount} tools)${format_js_1.colors.reset}`);
|
|
375
|
+
}
|
|
376
|
+
if (hasNest) {
|
|
377
|
+
lines.push(` ${format_js_1.colors.dim}Controllers: ${report.nestControllerCovered}/${report.nestControllerTotal} have @AiTool decorators (${report.nestToolCount} tools)${format_js_1.colors.reset}`);
|
|
378
|
+
}
|
|
379
|
+
lines.push(` ${format_js_1.colors.dim}Components: ${report.componentDirCovered}/${report.componentDirTotal} have ai-ui-tool.ts (${report.uiToolCount} tools)${format_js_1.colors.reset}`);
|
|
380
|
+
lines.push(` ${format_js_1.colors.dim}Handlers: ${report.handlerCoveredCount}/${report.handlerTotalCount} actionIds have useAiClientAction${format_js_1.colors.reset}`);
|
|
381
|
+
lines.push('');
|
|
382
|
+
return lines.join('\n');
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Minimal quiet output for predev/prebuild hooks.
|
|
386
|
+
*/
|
|
387
|
+
function formatCoverageReportQuiet(report) {
|
|
388
|
+
const issues = [];
|
|
389
|
+
if (report.uncoveredRoutes.length > 0) {
|
|
390
|
+
issues.push(`${report.uncoveredRoutes.length} uncovered routes`);
|
|
391
|
+
}
|
|
392
|
+
if (report.uncoveredComponents.length > 0) {
|
|
393
|
+
issues.push(`${report.uncoveredComponents.length} uncovered components`);
|
|
394
|
+
}
|
|
395
|
+
if (report.missingHandlers.length > 0) {
|
|
396
|
+
issues.push(`${report.missingHandlers.length} missing handlers`);
|
|
397
|
+
}
|
|
398
|
+
if (report.orphanHandlers.length > 0) {
|
|
399
|
+
issues.push(`${report.orphanHandlers.length} orphan handlers`);
|
|
400
|
+
}
|
|
401
|
+
if (report.uncoveredNestControllers.length > 0) {
|
|
402
|
+
issues.push(`${report.uncoveredNestControllers.length} uncovered NestJS controllers`);
|
|
403
|
+
}
|
|
404
|
+
if (issues.length === 0) {
|
|
405
|
+
return `${format_js_1.colors.green}\u2713${format_js_1.colors.reset} AI coverage: ${report.endpointToolCount + report.uiToolCount + report.nestToolCount} tools, all OK`;
|
|
406
|
+
}
|
|
407
|
+
return `${format_js_1.colors.yellow}\u26A0${format_js_1.colors.reset} AI coverage: ${issues.join(', ')}`;
|
|
408
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GenerateOptions, ScanResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Scan for endpoint tool files (ai-tool.ts) in the API directory.
|
|
4
|
+
* Also detects route.ts files using withAiTool() from glirastes/server/nextjs.
|
|
5
|
+
*/
|
|
6
|
+
export declare function scanEndpointTools(options: GenerateOptions): Promise<ScanResult>;
|
|
7
|
+
/**
|
|
8
|
+
* Generate the endpoint tools registry file.
|
|
9
|
+
*
|
|
10
|
+
* Output: a TypeScript file that imports all discovered endpoint tools and
|
|
11
|
+
* combines them into a single registry via endpointToolsToRegistry().
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateEndpointRegistry(options: GenerateOptions): Promise<{
|
|
14
|
+
outputPath: string;
|
|
15
|
+
toolCount: number;
|
|
16
|
+
}>;
|