glirastes 0.3.0 → 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 +63 -0
- package/README.md +146 -9
- 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/openapi/package.json +5 -0
- package/package.json +59 -16
- 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
|
@@ -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
|
+
}>;
|
|
@@ -0,0 +1,197 @@
|
|
|
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.scanEndpointTools = scanEndpointTools;
|
|
37
|
+
exports.generateEndpointRegistry = generateEndpointRegistry;
|
|
38
|
+
const promises_1 = require("node:fs/promises");
|
|
39
|
+
const node_path_1 = require("node:path");
|
|
40
|
+
const fs_utils_js_1 = require("./fs-utils.js");
|
|
41
|
+
const types_js_1 = require("./types.js");
|
|
42
|
+
/**
|
|
43
|
+
* Scan for endpoint tool files (ai-tool.ts) in the API directory.
|
|
44
|
+
* Also detects route.ts files using withAiTool() from glirastes/server/nextjs.
|
|
45
|
+
*/
|
|
46
|
+
async function scanEndpointTools(options) {
|
|
47
|
+
const opts = (0, types_js_1.resolveDefaults)(options);
|
|
48
|
+
const apiDir = (0, node_path_1.join)(opts.rootDir, opts.apiDir);
|
|
49
|
+
const files = await (0, fs_utils_js_1.findFiles)(apiDir, opts.endpointToolFileName);
|
|
50
|
+
const discovered = [];
|
|
51
|
+
const discoveredDirs = new Set();
|
|
52
|
+
// 1. Standard ai-tool.ts files
|
|
53
|
+
for (const absolutePath of files) {
|
|
54
|
+
const content = await (0, fs_utils_js_1.readFileSafe)(absolutePath);
|
|
55
|
+
if (content.includes('@ai-ignore'))
|
|
56
|
+
continue;
|
|
57
|
+
if (await (0, fs_utils_js_1.isDirAiIgnored)((0, node_path_1.dirname)(absolutePath)))
|
|
58
|
+
continue;
|
|
59
|
+
const hasArray = /export\s+const\s+aiTools\s*[=:]/m.test(content);
|
|
60
|
+
const hasSingle = /export\s+const\s+aiTool\s*[=:]/m.test(content);
|
|
61
|
+
if (!hasArray && !hasSingle)
|
|
62
|
+
continue;
|
|
63
|
+
discovered.push({
|
|
64
|
+
absolutePath,
|
|
65
|
+
relativePath: absolutePath.replace(opts.rootDir + '/', ''),
|
|
66
|
+
importPath: (0, fs_utils_js_1.toImportPath)(absolutePath, opts.rootDir),
|
|
67
|
+
exportType: hasArray ? 'array' : 'single',
|
|
68
|
+
});
|
|
69
|
+
discoveredDirs.add((0, node_path_1.dirname)(absolutePath));
|
|
70
|
+
}
|
|
71
|
+
// 2. route.ts files with withAiTool() (inline tool definitions)
|
|
72
|
+
const routeFiles = await (0, fs_utils_js_1.findRouteFiles)(apiDir);
|
|
73
|
+
for (const routeFile of routeFiles) {
|
|
74
|
+
const routeDir = (0, node_path_1.dirname)(routeFile);
|
|
75
|
+
if (discoveredDirs.has(routeDir))
|
|
76
|
+
continue; // Already has ai-tool.ts
|
|
77
|
+
const content = await (0, fs_utils_js_1.readFileSafe)(routeFile);
|
|
78
|
+
if (content.includes('@ai-ignore'))
|
|
79
|
+
continue;
|
|
80
|
+
if (await (0, fs_utils_js_1.isDirAiIgnored)(routeDir))
|
|
81
|
+
continue;
|
|
82
|
+
if (!content.includes('withAiTool('))
|
|
83
|
+
continue;
|
|
84
|
+
discovered.push({
|
|
85
|
+
absolutePath: routeFile,
|
|
86
|
+
relativePath: routeFile.replace(opts.rootDir + '/', ''),
|
|
87
|
+
importPath: (0, fs_utils_js_1.toImportPath)(routeFile, opts.rootDir),
|
|
88
|
+
exportType: 'single', // withAiTool wraps a single handler
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Count tools (rough estimate: arrays have multiple, singles have 1)
|
|
92
|
+
let toolCount = 0;
|
|
93
|
+
for (const file of discovered) {
|
|
94
|
+
if (file.exportType === 'array') {
|
|
95
|
+
const content = await (0, fs_utils_js_1.readFileSafe)(file.absolutePath);
|
|
96
|
+
// Count defineEndpointTool or defineAiEndpointTool calls
|
|
97
|
+
const matches = content.match(/define(?:Ai)?EndpointTool\(/g);
|
|
98
|
+
toolCount += matches?.length ?? 1;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
toolCount += 1;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return { files: discovered, toolCount };
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Generate the endpoint tools registry file.
|
|
108
|
+
*
|
|
109
|
+
* Output: a TypeScript file that imports all discovered endpoint tools and
|
|
110
|
+
* combines them into a single registry via endpointToolsToRegistry().
|
|
111
|
+
*/
|
|
112
|
+
async function generateEndpointRegistry(options) {
|
|
113
|
+
const opts = (0, types_js_1.resolveDefaults)(options);
|
|
114
|
+
const scan = await scanEndpointTools(options);
|
|
115
|
+
// NestJS @AiTool decorated controllers
|
|
116
|
+
let nestTools = [];
|
|
117
|
+
if (opts.nestjsDirs.length > 0) {
|
|
118
|
+
const { scanNestControllers } = await Promise.resolve().then(() => __importStar(require('./nestjs-scanner.js')));
|
|
119
|
+
const nestResult = await scanNestControllers(opts.nestjsDirs, opts.nestjsApiPrefix);
|
|
120
|
+
nestTools = nestResult.tools;
|
|
121
|
+
}
|
|
122
|
+
const imports = [];
|
|
123
|
+
const spreadParts = [];
|
|
124
|
+
scan.files.forEach((file, index) => {
|
|
125
|
+
if (file.exportType === 'array') {
|
|
126
|
+
const alias = `endpointTools${index}`;
|
|
127
|
+
imports.push(`import { aiTools as ${alias} } from '${file.importPath}';`);
|
|
128
|
+
spreadParts.push(`...${alias}`);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
const alias = `endpointTool${index}`;
|
|
132
|
+
imports.push(`import { aiTool as ${alias} } from '${file.importPath}';`);
|
|
133
|
+
spreadParts.push(alias);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
// Generate inline defineEndpointTool() calls for NestJS tools
|
|
137
|
+
const nestInlineDefs = [];
|
|
138
|
+
const nestSpreadParts = [];
|
|
139
|
+
nestTools.forEach((tool, index) => {
|
|
140
|
+
const alias = `nestTool${index}`;
|
|
141
|
+
const desc = tool.description.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
142
|
+
// Build path param schema fields (e.g. { id: z.string() })
|
|
143
|
+
const paramFields = tool.pathParams.map(p => `${p}: z.string()`).join(', ');
|
|
144
|
+
const inputSchema = paramFields
|
|
145
|
+
? `z.object({ ${paramFields} }).passthrough()`
|
|
146
|
+
: 'z.object({}).passthrough()';
|
|
147
|
+
const lines = [
|
|
148
|
+
` id: '${tool.name}'`,
|
|
149
|
+
` toolName: '${tool.name}'`,
|
|
150
|
+
` description: '${desc}'`,
|
|
151
|
+
` path: '${tool.path}'`,
|
|
152
|
+
` method: '${tool.method}'`,
|
|
153
|
+
` inputSchema: ${inputSchema}`,
|
|
154
|
+
];
|
|
155
|
+
if (tool.module)
|
|
156
|
+
lines.push(` module: '${tool.module}'`);
|
|
157
|
+
if (tool.needsApproval !== undefined)
|
|
158
|
+
lines.push(` needsApproval: ${tool.needsApproval}`);
|
|
159
|
+
if (tool.allowedRoles && tool.allowedRoles.length > 0) {
|
|
160
|
+
lines.push(` allowedRoles: ${JSON.stringify(tool.allowedRoles)}`);
|
|
161
|
+
}
|
|
162
|
+
nestInlineDefs.push(`const ${alias} = defineEndpointTool({\n${lines.join(',\n')},\n});`);
|
|
163
|
+
nestSpreadParts.push(alias);
|
|
164
|
+
});
|
|
165
|
+
const allSpreadParts = [...spreadParts, ...nestSpreadParts];
|
|
166
|
+
const totalToolCount = scan.toolCount + nestTools.length;
|
|
167
|
+
const contractsImport = nestTools.length > 0
|
|
168
|
+
? `import { z } from 'zod';\nimport { defineEndpointTool } from 'glirastes';\n`
|
|
169
|
+
: '';
|
|
170
|
+
const nestInlineBlock = nestInlineDefs.length > 0
|
|
171
|
+
? `\n// From NestJS @AiTool decorators\n${nestInlineDefs.join('\n\n')}\n`
|
|
172
|
+
: '';
|
|
173
|
+
const code = `/* eslint-disable */
|
|
174
|
+
/**
|
|
175
|
+
* AUTO-GENERATED FILE — do not edit manually.
|
|
176
|
+
* Generated by glirastes
|
|
177
|
+
*
|
|
178
|
+
* Sources: ${scan.files.length} ai-tool.ts files, ${nestTools.length} NestJS @AiTool decorators
|
|
179
|
+
* Tools: ${totalToolCount}
|
|
180
|
+
*/
|
|
181
|
+
|
|
182
|
+
${imports.join('\n')}
|
|
183
|
+
import { endpointToolsToRegistry } from 'glirastes/server';
|
|
184
|
+
${contractsImport}${nestInlineBlock}
|
|
185
|
+
const endpointTools = [${allSpreadParts.join(', ')}] as const;
|
|
186
|
+
|
|
187
|
+
export { endpointTools };
|
|
188
|
+
export const endpointToolRegistry = endpointToolsToRegistry(endpointTools);
|
|
189
|
+
`;
|
|
190
|
+
const outputPath = (0, node_path_1.join)(opts.rootDir, opts.outputDir, 'endpoint.generated.ts');
|
|
191
|
+
await (0, promises_1.mkdir)((0, node_path_1.dirname)(outputPath), { recursive: true });
|
|
192
|
+
await (0, promises_1.writeFile)(outputPath, code, 'utf-8');
|
|
193
|
+
if (!opts.quiet) {
|
|
194
|
+
console.log(`✓ Generated ${outputPath} (${totalToolCount} endpoint tools from ${scan.files.length} files + ${nestTools.length} NestJS controllers)`);
|
|
195
|
+
}
|
|
196
|
+
return { outputPath, toolCount: totalToolCount };
|
|
197
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared ANSI color codes and formatting utilities for CLI output.
|
|
3
|
+
*/
|
|
4
|
+
export declare const colors: {
|
|
5
|
+
reset: string;
|
|
6
|
+
bold: string;
|
|
7
|
+
dim: string;
|
|
8
|
+
red: string;
|
|
9
|
+
green: string;
|
|
10
|
+
yellow: string;
|
|
11
|
+
blue: string;
|
|
12
|
+
cyan: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function separator(width?: number): string;
|
|
15
|
+
export declare function header(title: string): string;
|
|
16
|
+
export declare function sectionHeader(title: string, count: number, color: string): string;
|
|
17
|
+
export declare function metricLine(icon: string, iconColor: string, label: string, value: string | number, detail?: string): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared ANSI color codes and formatting utilities for CLI output.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.colors = void 0;
|
|
7
|
+
exports.separator = separator;
|
|
8
|
+
exports.header = header;
|
|
9
|
+
exports.sectionHeader = sectionHeader;
|
|
10
|
+
exports.metricLine = metricLine;
|
|
11
|
+
exports.colors = {
|
|
12
|
+
reset: '\x1b[0m',
|
|
13
|
+
bold: '\x1b[1m',
|
|
14
|
+
dim: '\x1b[2m',
|
|
15
|
+
red: '\x1b[31m',
|
|
16
|
+
green: '\x1b[32m',
|
|
17
|
+
yellow: '\x1b[33m',
|
|
18
|
+
blue: '\x1b[34m',
|
|
19
|
+
cyan: '\x1b[36m',
|
|
20
|
+
};
|
|
21
|
+
function separator(width = 50) {
|
|
22
|
+
return `${exports.colors.dim}${'─'.repeat(width)}${exports.colors.reset}`;
|
|
23
|
+
}
|
|
24
|
+
function header(title) {
|
|
25
|
+
return `\n${exports.colors.blue}${exports.colors.bold}${title}${exports.colors.reset}\n\n${separator()}\n`;
|
|
26
|
+
}
|
|
27
|
+
function sectionHeader(title, count, color) {
|
|
28
|
+
return `${color}${exports.colors.bold}${title} (${count}):${exports.colors.reset}\n`;
|
|
29
|
+
}
|
|
30
|
+
function metricLine(icon, iconColor, label, value, detail) {
|
|
31
|
+
const paddedLabel = label.padEnd(35);
|
|
32
|
+
const detailStr = detail ? ` ${exports.colors.dim}(${detail})${exports.colors.reset}` : '';
|
|
33
|
+
return ` ${iconColor}${icon}${exports.colors.reset} ${paddedLabel}${exports.colors.bold}${value}${exports.colors.reset}${detailStr}`;
|
|
34
|
+
}
|