@cyanautomation/kaseki-agent 1.4.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/.dockerignore +54 -0
- package/.eslintignore +11 -0
- package/.eslintrc.json +95 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +53 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +53 -0
- package/.github/ISSUE_TEMPLATE/security.md +51 -0
- package/.github/PULL_REQUEST_TEMPLATE/default.md +71 -0
- package/.github/dependabot.yml +38 -0
- package/.github/skills/dependency-cache-optimization/SKILL.md +526 -0
- package/.github/skills/docker-image-management/SKILL.md +532 -0
- package/.github/skills/frontend-design/SKILL.md +782 -0
- package/.github/skills/prompt-engineering/SKILL.md +360 -0
- package/.github/skills/quality-gate-config/SKILL.md +591 -0
- package/.github/skills/result-report-analysis/SKILL.md +576 -0
- package/.github/skills/test-automation/SKILL.md +593 -0
- package/.github/skills/workflow-diagnosis/SKILL.md +468 -0
- package/.github/workflows/build-docker-image.yml +453 -0
- package/.github/workflows/release.yml +68 -0
- package/.releaserc.json +135 -0
- package/CHANGELOG.md +117 -0
- package/CLAUDE.md +336 -0
- package/CONTRIBUTING.md +339 -0
- package/Dockerfile +217 -0
- package/README.md +1527 -0
- package/STYLE.md +521 -0
- package/add-js-extensions.d.ts +9 -0
- package/add-js-extensions.d.ts.map +1 -0
- package/add-js-extensions.js.map +1 -0
- package/dist/add-js-extensions.d.ts +9 -0
- package/dist/add-js-extensions.d.ts.map +1 -0
- package/dist/add-js-extensions.js +52 -0
- package/dist/add-js-extensions.js.map +1 -0
- package/dist/ansi-colors.d.ts +26 -0
- package/dist/ansi-colors.d.ts.map +1 -0
- package/dist/ansi-colors.js +51 -0
- package/dist/ansi-colors.js.map +1 -0
- package/dist/cli/BaseCommand.d.ts +18 -0
- package/dist/cli/BaseCommand.d.ts.map +1 -0
- package/dist/cli/BaseCommand.js +31 -0
- package/dist/cli/BaseCommand.js.map +1 -0
- package/dist/cli/KasekiCLI.d.ts +30 -0
- package/dist/cli/KasekiCLI.d.ts.map +1 -0
- package/dist/cli/KasekiCLI.js +134 -0
- package/dist/cli/KasekiCLI.js.map +1 -0
- package/dist/cli/commands/ConfigCommand.d.ts +13 -0
- package/dist/cli/commands/ConfigCommand.d.ts.map +1 -0
- package/dist/cli/commands/ConfigCommand.js +131 -0
- package/dist/cli/commands/ConfigCommand.js.map +1 -0
- package/dist/cli/commands/DoctorCommand.d.ts +45 -0
- package/dist/cli/commands/DoctorCommand.d.ts.map +1 -0
- package/dist/cli/commands/DoctorCommand.js +309 -0
- package/dist/cli/commands/DoctorCommand.js.map +1 -0
- package/dist/cli/commands/ListCommand.d.ts +9 -0
- package/dist/cli/commands/ListCommand.d.ts.map +1 -0
- package/dist/cli/commands/ListCommand.js +81 -0
- package/dist/cli/commands/ListCommand.js.map +1 -0
- package/dist/cli/commands/ReportCommand.d.ts +9 -0
- package/dist/cli/commands/ReportCommand.d.ts.map +1 -0
- package/dist/cli/commands/ReportCommand.js +98 -0
- package/dist/cli/commands/ReportCommand.js.map +1 -0
- package/dist/cli/commands/RunCommand.d.ts +13 -0
- package/dist/cli/commands/RunCommand.d.ts.map +1 -0
- package/dist/cli/commands/RunCommand.js +191 -0
- package/dist/cli/commands/RunCommand.js.map +1 -0
- package/dist/cli/commands/SecretsCommand.d.ts +9 -0
- package/dist/cli/commands/SecretsCommand.d.ts.map +1 -0
- package/dist/cli/commands/SecretsCommand.js +109 -0
- package/dist/cli/commands/SecretsCommand.js.map +1 -0
- package/dist/cli/commands/ServeCommand.d.ts +9 -0
- package/dist/cli/commands/ServeCommand.d.ts.map +1 -0
- package/dist/cli/commands/ServeCommand.js +50 -0
- package/dist/cli/commands/ServeCommand.js.map +1 -0
- package/dist/cli/commands/SetupCommand.d.ts +42 -0
- package/dist/cli/commands/SetupCommand.d.ts.map +1 -0
- package/dist/cli/commands/SetupCommand.js +249 -0
- package/dist/cli/commands/SetupCommand.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +130 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/ConfigManager.d.ts +395 -0
- package/dist/config/ConfigManager.d.ts.map +1 -0
- package/dist/config/ConfigManager.js +446 -0
- package/dist/config/ConfigManager.js.map +1 -0
- package/dist/docker/DockerManager.d.ts +69 -0
- package/dist/docker/DockerManager.d.ts.map +1 -0
- package/dist/docker/DockerManager.js +266 -0
- package/dist/docker/DockerManager.js.map +1 -0
- package/dist/event-aggregator.d.ts +71 -0
- package/dist/event-aggregator.d.ts.map +1 -0
- package/dist/event-aggregator.js +95 -0
- package/dist/event-aggregator.js.map +1 -0
- package/dist/github-app-token.d.ts +16 -0
- package/dist/github-app-token.d.ts.map +1 -0
- package/dist/github-app-token.js +148 -0
- package/dist/github-app-token.js.map +1 -0
- package/dist/idempotency-store.d.ts +61 -0
- package/dist/idempotency-store.d.ts.map +1 -0
- package/dist/idempotency-store.js +321 -0
- package/dist/idempotency-store.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/instance/InstanceManager.d.ts +81 -0
- package/dist/instance/InstanceManager.d.ts.map +1 -0
- package/dist/instance/InstanceManager.js +220 -0
- package/dist/instance/InstanceManager.js.map +1 -0
- package/dist/instance-metadata-reader.d.ts +48 -0
- package/dist/instance-metadata-reader.d.ts.map +1 -0
- package/dist/instance-metadata-reader.js +94 -0
- package/dist/instance-metadata-reader.js.map +1 -0
- package/dist/instance-state-derivation.d.ts +42 -0
- package/dist/instance-state-derivation.d.ts.map +1 -0
- package/dist/instance-state-derivation.js +133 -0
- package/dist/instance-state-derivation.js.map +1 -0
- package/dist/job-scheduler.d.ts +124 -0
- package/dist/job-scheduler.d.ts.map +1 -0
- package/dist/job-scheduler.js +992 -0
- package/dist/job-scheduler.js.map +1 -0
- package/dist/kaseki-api-client.d.ts +89 -0
- package/dist/kaseki-api-client.d.ts.map +1 -0
- package/dist/kaseki-api-client.js +405 -0
- package/dist/kaseki-api-client.js.map +1 -0
- package/dist/kaseki-api-config.d.ts +34 -0
- package/dist/kaseki-api-config.d.ts.map +1 -0
- package/dist/kaseki-api-config.js +113 -0
- package/dist/kaseki-api-config.js.map +1 -0
- package/dist/kaseki-api-routes.d.ts +13 -0
- package/dist/kaseki-api-routes.d.ts.map +1 -0
- package/dist/kaseki-api-routes.js +559 -0
- package/dist/kaseki-api-routes.js.map +1 -0
- package/dist/kaseki-api-service-wrapper.d.ts +43 -0
- package/dist/kaseki-api-service-wrapper.d.ts.map +1 -0
- package/dist/kaseki-api-service-wrapper.js +150 -0
- package/dist/kaseki-api-service-wrapper.js.map +1 -0
- package/dist/kaseki-api-service.d.ts +16 -0
- package/dist/kaseki-api-service.d.ts.map +1 -0
- package/dist/kaseki-api-service.js +143 -0
- package/dist/kaseki-api-service.js.map +1 -0
- package/dist/kaseki-api-types.d.ts +440 -0
- package/dist/kaseki-api-types.d.ts.map +1 -0
- package/dist/kaseki-api-types.js +64 -0
- package/dist/kaseki-api-types.js.map +1 -0
- package/dist/kaseki-cli-lib.d.ts +219 -0
- package/dist/kaseki-cli-lib.d.ts.map +1 -0
- package/dist/kaseki-cli-lib.js +523 -0
- package/dist/kaseki-cli-lib.js.map +1 -0
- package/dist/kaseki-cli.d.ts +38 -0
- package/dist/kaseki-cli.d.ts.map +1 -0
- package/dist/kaseki-cli.js +559 -0
- package/dist/kaseki-cli.js.map +1 -0
- package/dist/kaseki-report.d.ts +3 -0
- package/dist/kaseki-report.d.ts.map +1 -0
- package/dist/kaseki-report.js +140 -0
- package/dist/kaseki-report.js.map +1 -0
- package/dist/lib/subprocess-helpers.d.ts +98 -0
- package/dist/lib/subprocess-helpers.d.ts.map +1 -0
- package/dist/lib/subprocess-helpers.js +136 -0
- package/dist/lib/subprocess-helpers.js.map +1 -0
- package/dist/logger.d.ts +39 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +79 -0
- package/dist/logger.js.map +1 -0
- package/dist/metrics.d.ts +19 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +59 -0
- package/dist/metrics.js.map +1 -0
- package/dist/middleware/job-lookup.d.ts +27 -0
- package/dist/middleware/job-lookup.d.ts.map +1 -0
- package/dist/middleware/job-lookup.js +28 -0
- package/dist/middleware/job-lookup.js.map +1 -0
- package/dist/pi-event-filter.d.ts +3 -0
- package/dist/pi-event-filter.d.ts.map +1 -0
- package/dist/pi-event-filter.js +126 -0
- package/dist/pi-event-filter.js.map +1 -0
- package/dist/pi-progress-stream.d.ts +3 -0
- package/dist/pi-progress-stream.d.ts.map +1 -0
- package/dist/pi-progress-stream.js +205 -0
- package/dist/pi-progress-stream.js.map +1 -0
- package/dist/pi-progress-summarizer.d.ts +61 -0
- package/dist/pi-progress-summarizer.d.ts.map +1 -0
- package/dist/pi-progress-summarizer.js +246 -0
- package/dist/pi-progress-summarizer.js.map +1 -0
- package/dist/pre-flight-validator.d.ts +72 -0
- package/dist/pre-flight-validator.d.ts.map +1 -0
- package/dist/pre-flight-validator.js +513 -0
- package/dist/pre-flight-validator.js.map +1 -0
- package/dist/progress-stream-utils.d.ts +3 -0
- package/dist/progress-stream-utils.d.ts.map +1 -0
- package/dist/progress-stream-utils.js +15 -0
- package/dist/progress-stream-utils.js.map +1 -0
- package/dist/result-cache.d.ts +52 -0
- package/dist/result-cache.d.ts.map +1 -0
- package/dist/result-cache.js +134 -0
- package/dist/result-cache.js.map +1 -0
- package/dist/routes/artifact-routes.d.ts +10 -0
- package/dist/routes/artifact-routes.d.ts.map +1 -0
- package/dist/routes/artifact-routes.js +126 -0
- package/dist/routes/artifact-routes.js.map +1 -0
- package/dist/routes/log-routes.d.ts +8 -0
- package/dist/routes/log-routes.d.ts.map +1 -0
- package/dist/routes/log-routes.js +345 -0
- package/dist/routes/log-routes.js.map +1 -0
- package/dist/routes/status-routes.d.ts +8 -0
- package/dist/routes/status-routes.d.ts.map +1 -0
- package/dist/routes/status-routes.js +82 -0
- package/dist/routes/status-routes.js.map +1 -0
- package/dist/routes/webhook-routes.d.ts +6 -0
- package/dist/routes/webhook-routes.d.ts.map +1 -0
- package/dist/routes/webhook-routes.js +86 -0
- package/dist/routes/webhook-routes.js.map +1 -0
- package/dist/run-artifact-metadata-cache.d.ts +42 -0
- package/dist/run-artifact-metadata-cache.d.ts.map +1 -0
- package/dist/run-artifact-metadata-cache.js +139 -0
- package/dist/run-artifact-metadata-cache.js.map +1 -0
- package/dist/secret-value-cache.d.ts +13 -0
- package/dist/secret-value-cache.d.ts.map +1 -0
- package/dist/secret-value-cache.js +44 -0
- package/dist/secret-value-cache.js.map +1 -0
- package/dist/secrets/SecretsManager.d.ts +80 -0
- package/dist/secrets/SecretsManager.d.ts.map +1 -0
- package/dist/secrets/SecretsManager.js +306 -0
- package/dist/secrets/SecretsManager.js.map +1 -0
- package/dist/test-utils.d.ts +55 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +48 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/timestamp-tracker.d.ts +75 -0
- package/dist/timestamp-tracker.d.ts.map +1 -0
- package/dist/timestamp-tracker.js +121 -0
- package/dist/timestamp-tracker.js.map +1 -0
- package/dist/utils/failure-artifact-writer.d.ts +29 -0
- package/dist/utils/failure-artifact-writer.d.ts.map +1 -0
- package/dist/utils/failure-artifact-writer.js +157 -0
- package/dist/utils/failure-artifact-writer.js.map +1 -0
- package/dist/utils/file-helpers.d.ts +41 -0
- package/dist/utils/file-helpers.d.ts.map +1 -0
- package/dist/utils/file-helpers.js +143 -0
- package/dist/utils/file-helpers.js.map +1 -0
- package/dist/utils/http-client-factory.d.ts +46 -0
- package/dist/utils/http-client-factory.d.ts.map +1 -0
- package/dist/utils/http-client-factory.js +114 -0
- package/dist/utils/http-client-factory.js.map +1 -0
- package/dist/utils/progress-normalizer.d.ts +13 -0
- package/dist/utils/progress-normalizer.d.ts.map +1 -0
- package/dist/utils/progress-normalizer.js +57 -0
- package/dist/utils/progress-normalizer.js.map +1 -0
- package/dist/utils/response-helpers.d.ts +34 -0
- package/dist/utils/response-helpers.d.ts.map +1 -0
- package/dist/utils/response-helpers.js +78 -0
- package/dist/utils/response-helpers.js.map +1 -0
- package/dist/utils/route-helpers.d.ts +17 -0
- package/dist/utils/route-helpers.d.ts.map +1 -0
- package/dist/utils/route-helpers.js +22 -0
- package/dist/utils/route-helpers.js.map +1 -0
- package/dist/utils/status-response-builder.d.ts +23 -0
- package/dist/utils/status-response-builder.d.ts.map +1 -0
- package/dist/utils/status-response-builder.js +144 -0
- package/dist/utils/status-response-builder.js.map +1 -0
- package/dist/utils/type-guards.d.ts +37 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +45 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/dist/utils/utf8-helpers.d.ts +32 -0
- package/dist/utils/utf8-helpers.d.ts.map +1 -0
- package/dist/utils/utf8-helpers.js +97 -0
- package/dist/utils/utf8-helpers.js.map +1 -0
- package/dist/utils/webhook-event-builder.d.ts +26 -0
- package/dist/utils/webhook-event-builder.d.ts.map +1 -0
- package/dist/utils/webhook-event-builder.js +77 -0
- package/dist/utils/webhook-event-builder.js.map +1 -0
- package/dist/webhook-manager.d.ts +56 -0
- package/dist/webhook-manager.d.ts.map +1 -0
- package/dist/webhook-manager.js +359 -0
- package/dist/webhook-manager.js.map +1 -0
- package/docker/workspace-cache/package-lock.json +13 -0
- package/docker/workspace-cache/package.json +7 -0
- package/docker-compose.yml +53 -0
- package/docs/API.md +708 -0
- package/docs/BACKLOG.md +19 -0
- package/docs/BUILD_STRATEGY.md +404 -0
- package/docs/CLI.md +569 -0
- package/docs/DEPLOYMENT.md +521 -0
- package/docs/DEVELOPMENT.md +459 -0
- package/docs/DOCKER_SETUP.md +522 -0
- package/docs/ENHANCED_PROGRESS_LOGS.md +264 -0
- package/docs/IMPLEMENTATION_SUMMARY.md +549 -0
- package/docs/INTEGRATION_EXAMPLE.md +217 -0
- package/docs/NPM_SETUP.md +468 -0
- package/docs/PHASE1-4_IMPLEMENTATION.md +302 -0
- package/docs/PHASE1_COMPLETION.md +192 -0
- package/docs/PHASE2_COMPLETION.md +134 -0
- package/docs/PHASE6_MIGRATION.md +392 -0
- package/docs/PRINTF_SAFETY_FIX.md +282 -0
- package/docs/QUALITY_GATES.md +369 -0
- package/docs/SETUP_GUIDE.md +482 -0
- package/docs/TASK_PROMPT_TEMPLATES.md +533 -0
- package/docs/VALIDATION_FIX.md +139 -0
- package/docs/VERIFICATION_CHECKLIST.md +335 -0
- package/docs/repo-maturity.md +760 -0
- package/fix-tests.d.ts +9 -0
- package/fix-tests.d.ts.map +1 -0
- package/fix-tests.js.map +1 -0
- package/fix-tests.ts +53 -0
- package/jest.config.ts +31 -0
- package/kaseki +183 -0
- package/kaseki-agent.sh +1961 -0
- package/ops/logrotate/kaseki +10 -0
- package/package.json +83 -0
- package/perf/README.md +54 -0
- package/perf/pi-event-filter.benchmark.test.ts +98 -0
- package/run-kaseki-json.test.sh +106 -0
- package/run-kaseki.sh +990 -0
- package/scripts/allowlist-helper.sh +56 -0
- package/scripts/cleanup-kaseki.sh +168 -0
- package/scripts/deploy-pi-template.sh +293 -0
- package/scripts/docker-entrypoint.sh +71 -0
- package/scripts/dry-run-allowlist.sh +161 -0
- package/scripts/kaseki-activate.sh +396 -0
- package/scripts/kaseki-api.service +62 -0
- package/scripts/kaseki-container-entrypoint-wrapper.sh +119 -0
- package/scripts/kaseki-container-setup-remote.sh +172 -0
- package/scripts/kaseki-container-setup.sh +193 -0
- package/scripts/kaseki-healthcheck.sh +95 -0
- package/scripts/kaseki-install.sh +50 -0
- package/scripts/kaseki-maturity-score.sh +291 -0
- package/scripts/kaseki-performance-metrics.sh +122 -0
- package/scripts/kaseki-preflight.sh +270 -0
- package/scripts/kaseki-setup.sh +265 -0
- package/scripts/pi-setup-remote.sh +213 -0
- package/scripts/setup-github-labels.sh +42 -0
- package/scripts/suggest-allowlist.sh +68 -0
- package/scripts/templates/MULTI_HOST_DISTRIBUTED.md +337 -0
- package/scripts/templates/REST_API_SERVICE.md +490 -0
- package/scripts/templates/SINGLE_HOST_CLI.md +194 -0
- package/scripts/test-github-app.sh +248 -0
- package/src/add-js-extensions.ts +61 -0
- package/src/ansi-colors.test.ts +62 -0
- package/src/ansi-colors.ts +67 -0
- package/src/cli/BaseCommand.ts +40 -0
- package/src/cli/KasekiCLI.ts +154 -0
- package/src/cli/commands/ConfigCommand.ts +145 -0
- package/src/cli/commands/DoctorCommand.ts +329 -0
- package/src/cli/commands/ListCommand.ts +105 -0
- package/src/cli/commands/ReportCommand.ts +110 -0
- package/src/cli/commands/RunCommand.ts +218 -0
- package/src/cli/commands/SecretsCommand.ts +120 -0
- package/src/cli/commands/ServeCommand.ts +62 -0
- package/src/cli/commands/SetupCommand.ts +301 -0
- package/src/cli.ts +138 -0
- package/src/config/ConfigManager.ts +476 -0
- package/src/docker/DockerManager.ts +319 -0
- package/src/docker-entrypoint-packaging.test.ts +33 -0
- package/src/event-aggregator.test.ts +117 -0
- package/src/event-aggregator.ts +126 -0
- package/src/github-app-token.ts +215 -0
- package/src/idempotency-store.test.ts +117 -0
- package/src/idempotency-store.ts +385 -0
- package/src/index.ts +89 -0
- package/src/instance/InstanceManager.ts +285 -0
- package/src/instance-metadata-reader.test.ts +190 -0
- package/src/instance-metadata-reader.ts +129 -0
- package/src/instance-state-derivation.test.ts +263 -0
- package/src/instance-state-derivation.ts +148 -0
- package/src/job-scheduler.test.ts +1236 -0
- package/src/job-scheduler.ts +1117 -0
- package/src/kaseki-api-client.ts +488 -0
- package/src/kaseki-api-config.test.ts +315 -0
- package/src/kaseki-api-config.ts +175 -0
- package/src/kaseki-api-routes.test.ts +1615 -0
- package/src/kaseki-api-routes.ts +643 -0
- package/src/kaseki-api-service-wrapper.ts +188 -0
- package/src/kaseki-api-service.test.ts +418 -0
- package/src/kaseki-api-service.ts +192 -0
- package/src/kaseki-api-types.ts +320 -0
- package/src/kaseki-cli-lib.test.ts +552 -0
- package/src/kaseki-cli-lib.ts +760 -0
- package/src/kaseki-cli.ts +682 -0
- package/src/kaseki-report.test.ts +118 -0
- package/src/kaseki-report.ts +192 -0
- package/src/lib/subprocess-helpers.ts +177 -0
- package/src/logger.ts +114 -0
- package/src/metrics.ts +66 -0
- package/src/middleware/job-lookup.test.ts +113 -0
- package/src/middleware/job-lookup.ts +45 -0
- package/src/pi-event-filter.test.ts +183 -0
- package/src/pi-event-filter.ts +183 -0
- package/src/pi-progress-stream.ts +287 -0
- package/src/pi-progress-summarizer.test.ts +302 -0
- package/src/pi-progress-summarizer.ts +287 -0
- package/src/pre-flight-validator.test.ts +512 -0
- package/src/pre-flight-validator.ts +618 -0
- package/src/progress-stream-utils.test.ts +35 -0
- package/src/progress-stream-utils.ts +14 -0
- package/src/result-cache.test.ts +195 -0
- package/src/result-cache.ts +181 -0
- package/src/routes/artifact-routes.ts +169 -0
- package/src/routes/log-routes.ts +391 -0
- package/src/routes/status-routes.ts +92 -0
- package/src/routes/webhook-routes.ts +97 -0
- package/src/run-artifact-metadata-cache.test.ts +80 -0
- package/src/run-artifact-metadata-cache.ts +184 -0
- package/src/secret-value-cache.test.ts +66 -0
- package/src/secret-value-cache.ts +55 -0
- package/src/secrets/SecretsManager.ts +343 -0
- package/src/test-utils.ts +81 -0
- package/src/timestamp-tracker.test.ts +134 -0
- package/src/timestamp-tracker.ts +132 -0
- package/src/utils/failure-artifact-writer.ts +187 -0
- package/src/utils/file-helpers.test.ts +235 -0
- package/src/utils/file-helpers.ts +150 -0
- package/src/utils/http-client-factory.test.ts +245 -0
- package/src/utils/http-client-factory.ts +157 -0
- package/src/utils/progress-normalizer.test.ts +442 -0
- package/src/utils/progress-normalizer.ts +68 -0
- package/src/utils/response-helpers.test.ts +122 -0
- package/src/utils/response-helpers.ts +101 -0
- package/src/utils/route-helpers.ts +30 -0
- package/src/utils/status-response-builder.ts +159 -0
- package/src/utils/type-guards.ts +52 -0
- package/src/utils/utf8-helpers.ts +102 -0
- package/src/utils/webhook-event-builder.test.ts +143 -0
- package/src/utils/webhook-event-builder.ts +87 -0
- package/src/webhook-manager.test.ts +152 -0
- package/src/webhook-manager.ts +445 -0
- package/templates/allowlist-api-route.txt +7 -0
- package/templates/allowlist-comprehensive.txt +8 -0
- package/templates/allowlist-parser-fix.txt +6 -0
- package/templates/allowlist-ui-component.txt +9 -0
- package/templates/allowlist-utility.txt +9 -0
- package/test/actual-model-metadata.test.sh +102 -0
- package/test/dry-run.test.sh +131 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-0.json +1 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-1.json +1 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-invalid.json +1 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-str-0.json +1 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-str-1.json +1 -0
- package/test/kaseki-api.integration.test.sh +165 -0
- package/test/pi-event-filter-failure.test.sh +83 -0
- package/test/printf-safety-focused.test.sh +99 -0
- package/test/printf-safety-results/results/restoration.jsonl +10 -0
- package/test/printf-safety-results/results/test.jsonl +0 -0
- package/test/printf-safety.test.sh +297 -0
- package/test/validation-fix.test.sh +79 -0
- package/test/validation-integration.test.sh +109 -0
- package/tests/allowlist-glob.test.sh +61 -0
- package/tests/dependency-cache-key.test.sh +48 -0
- package/tests/dependency-restore-mode.test.sh +48 -0
- package/tests/doctor-template-parity.test.sh +95 -0
- package/tests/github-operations.test.sh +142 -0
- package/tests/npm-install-flags.test.sh +58 -0
- package/tests/quality-gates.test.sh +178 -0
- package/tests/repo-memory.test.sh +103 -0
- package/tests/restore-disallowed-changes.test.sh +80 -0
- package/tests/validation-missing-npm-scripts.test.sh +93 -0
- package/tests/validation-strict-mode.test.sh +118 -0
- package/tsconfig.changed.json +7 -0
- package/tsconfig.json +39 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Test suite for printf safety and restoration report generation fixes
|
|
3
|
+
# Tests edge cases that could cause the "printf: - : invalid option" error
|
|
4
|
+
|
|
5
|
+
set -uo pipefail
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
8
|
+
TEST_RESULTS_DIR="${TMPDIR:-/tmp}/kaseki-agent-printf-safety-results.$$"
|
|
9
|
+
KASEKI_SCRIPT="${SCRIPT_DIR}/kaseki-agent.sh"
|
|
10
|
+
|
|
11
|
+
# Colors for output
|
|
12
|
+
RED='\033[0;31m'
|
|
13
|
+
GREEN='\033[0;32m'
|
|
14
|
+
YELLOW='\033[1;33m'
|
|
15
|
+
NC='\033[0m' # No Color
|
|
16
|
+
|
|
17
|
+
# Test counters
|
|
18
|
+
TESTS_RUN=0
|
|
19
|
+
TESTS_PASSED=0
|
|
20
|
+
TESTS_FAILED=0
|
|
21
|
+
|
|
22
|
+
# Setup and teardown
|
|
23
|
+
setup() {
|
|
24
|
+
mkdir -p "$TEST_RESULTS_DIR"
|
|
25
|
+
mkdir -p "$TEST_RESULTS_DIR/results"
|
|
26
|
+
cd "$TEST_RESULTS_DIR"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
teardown() {
|
|
30
|
+
rm -rf "$TEST_RESULTS_DIR"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Test helpers
|
|
34
|
+
run_test() {
|
|
35
|
+
local test_name="$1"
|
|
36
|
+
local test_func="$2"
|
|
37
|
+
|
|
38
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
39
|
+
printf '[%3d] %-60s ' "$TESTS_RUN" "$test_name"
|
|
40
|
+
|
|
41
|
+
if "$test_func" 2>/dev/null; then
|
|
42
|
+
printf "${GREEN}PASS${NC}\n"
|
|
43
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
44
|
+
return 0
|
|
45
|
+
else
|
|
46
|
+
printf "${RED}FAIL${NC}\n"
|
|
47
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
48
|
+
return 1
|
|
49
|
+
fi
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
source_validate_numeric() {
|
|
53
|
+
source <(sed -n '/^validate_numeric()/,/^}/p' "$KASEKI_SCRIPT")
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
source_generate_restoration_report() {
|
|
57
|
+
source <(sed -n '/^generate_restoration_report()/,/^}/p' "$KASEKI_SCRIPT" | sed "s#/results#${PWD}/results#g")
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Test: validate_numeric with valid input
|
|
61
|
+
test_validate_numeric_valid() {
|
|
62
|
+
source_validate_numeric
|
|
63
|
+
validate_numeric "test_var" "42"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Test: validate_numeric with dash (the bug trigger)
|
|
67
|
+
test_validate_numeric_dash() {
|
|
68
|
+
source_validate_numeric
|
|
69
|
+
! validate_numeric "test_var" "-"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# Test: validate_numeric with non-numeric input
|
|
73
|
+
test_validate_numeric_non_numeric() {
|
|
74
|
+
source_validate_numeric
|
|
75
|
+
! validate_numeric "test_var" "not-a-number"
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# Test: validate_numeric with empty input
|
|
79
|
+
test_validate_numeric_empty() {
|
|
80
|
+
source_validate_numeric
|
|
81
|
+
! validate_numeric "test_var" ""
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# Test: validate_numeric rejects values containing multiple lines
|
|
85
|
+
test_validate_numeric_multiline() {
|
|
86
|
+
source_validate_numeric
|
|
87
|
+
! validate_numeric "restored_count" $'0\n0'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# Test: restoration report with missing file
|
|
91
|
+
test_restoration_report_missing_file() {
|
|
92
|
+
source_validate_numeric
|
|
93
|
+
source_generate_restoration_report
|
|
94
|
+
|
|
95
|
+
rm -f results/restoration.jsonl
|
|
96
|
+
generate_restoration_report # Should return 0 (skip silently)
|
|
97
|
+
[ $? -eq 0 ]
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Test: restoration report with empty file
|
|
101
|
+
test_restoration_report_empty_file() {
|
|
102
|
+
source_validate_numeric
|
|
103
|
+
source_generate_restoration_report
|
|
104
|
+
|
|
105
|
+
: > results/restoration.jsonl
|
|
106
|
+
generate_restoration_report # Should return 0 (no changes to report)
|
|
107
|
+
[ $? -eq 0 ]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# Test: restoration report with valid entries
|
|
111
|
+
test_restoration_report_valid_entries() {
|
|
112
|
+
source_validate_numeric
|
|
113
|
+
source_generate_restoration_report
|
|
114
|
+
|
|
115
|
+
cat > results/restoration.jsonl <<'EOF'
|
|
116
|
+
{"timestamp":"2026-05-07T10:00:00Z","event":"file_evaluated","file":"src/test.ts","status":"kept","reason":"matched_allowlist"}
|
|
117
|
+
{"timestamp":"2026-05-07T10:00:01Z","event":"file_restored","file":"docs/readme.md","status":"restored","reason":"not_in_allowlist"}
|
|
118
|
+
EOF
|
|
119
|
+
|
|
120
|
+
generate_restoration_report && [ -f results/restoration-report.md ] && \
|
|
121
|
+
grep -Fq 'Total Files Changed:** 2' results/restoration-report.md && \
|
|
122
|
+
grep -Fq 'Files Kept (in allowlist):** 1' results/restoration-report.md && \
|
|
123
|
+
grep -Fq 'Files Restored (outside allowlist):** 1' results/restoration-report.md
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# Test: restoration report with only kept files
|
|
127
|
+
test_restoration_report_only_kept() {
|
|
128
|
+
source_validate_numeric
|
|
129
|
+
source_generate_restoration_report
|
|
130
|
+
|
|
131
|
+
cat > results/restoration.jsonl <<'EOF'
|
|
132
|
+
{"timestamp":"2026-05-07T10:00:00Z","event":"file_evaluated","file":"src/test.ts","status":"kept","reason":"matched_allowlist"}
|
|
133
|
+
{"timestamp":"2026-05-07T10:00:01Z","event":"file_evaluated","file":"src/lib.ts","status":"kept","reason":"matched_allowlist"}
|
|
134
|
+
EOF
|
|
135
|
+
|
|
136
|
+
local stderr_file=results/restoration-report.stderr
|
|
137
|
+
generate_restoration_report 2>"$stderr_file" && [ -f results/restoration-report.md ] && \
|
|
138
|
+
grep -Fq 'Total Files Changed:** 2' results/restoration-report.md && \
|
|
139
|
+
grep -Fq 'Files Restored (outside allowlist):** 0' results/restoration-report.md && \
|
|
140
|
+
grep -Fq 'Allowlist Coverage:** 100' results/restoration-report.md && \
|
|
141
|
+
grep -Fq 'restored_count="0"' "$stderr_file" && \
|
|
142
|
+
! grep -qx '0"' "$stderr_file"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
# Test: restoration report with only restored files
|
|
146
|
+
test_restoration_report_only_restored() {
|
|
147
|
+
source_validate_numeric
|
|
148
|
+
source_generate_restoration_report
|
|
149
|
+
|
|
150
|
+
cat > results/restoration.jsonl <<'EOF'
|
|
151
|
+
{"timestamp":"2026-05-07T10:00:00Z","event":"file_restored","file":"docs/readme.md","status":"restored","reason":"not_in_allowlist"}
|
|
152
|
+
{"timestamp":"2026-05-07T10:00:01Z","event":"file_restored","file":"CHANGELOG.md","status":"restored","reason":"not_in_allowlist"}
|
|
153
|
+
EOF
|
|
154
|
+
|
|
155
|
+
generate_restoration_report && [ -f results/restoration-report.md ] && \
|
|
156
|
+
grep -Fq 'Total Files Changed:** 2' results/restoration-report.md && \
|
|
157
|
+
grep -Fq 'Allowlist Coverage:** 0' results/restoration-report.md && \
|
|
158
|
+
grep -Fq 'Low Allowlist Coverage' results/restoration-report.md
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# Test: restoration report with low coverage warning
|
|
162
|
+
test_restoration_report_low_coverage_warning() {
|
|
163
|
+
source_validate_numeric
|
|
164
|
+
source_generate_restoration_report
|
|
165
|
+
|
|
166
|
+
# Create scenario: 1 kept, 9 restored = 10% coverage (< 50%)
|
|
167
|
+
printf '{"timestamp":"2026-05-07T10:00:00Z","event":"file_evaluated","file":"src/test.ts","status":"kept","reason":"matched_allowlist"}\n' > results/restoration.jsonl
|
|
168
|
+
for i in {1..9}; do
|
|
169
|
+
printf '{"timestamp":"2026-05-07T10:00:%02d","event":"file_restored","file":"file%d.txt","status":"restored","reason":"not_in_allowlist"}\n' "$i" "$i" >> results/restoration.jsonl
|
|
170
|
+
done
|
|
171
|
+
|
|
172
|
+
generate_restoration_report && [ -f results/restoration-report.md ] && \
|
|
173
|
+
grep -Fq 'Low Allowlist Coverage' results/restoration-report.md && \
|
|
174
|
+
grep -Fq 'Allowlist Coverage:** 10' results/restoration-report.md
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
# Test: printf with valid numeric argument (should not fail)
|
|
178
|
+
test_printf_valid_numeric() {
|
|
179
|
+
local test_var=42
|
|
180
|
+
printf 'test: %d\n' "$test_var" > /dev/null 2>&1
|
|
181
|
+
[ $? -eq 0 ]
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# Test: printf with dash argument (should fail without quoting)
|
|
185
|
+
test_printf_dash_unquoted_fails() {
|
|
186
|
+
local test_var="-"
|
|
187
|
+
# This SHOULD fail with unquoted expansion
|
|
188
|
+
! printf '%d\n' $test_var > /dev/null 2>&1
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
# Test: printf with dash argument quoted (should fail with validation)
|
|
192
|
+
test_printf_dash_quoted_validation() {
|
|
193
|
+
source_validate_numeric
|
|
194
|
+
local test_var="-"
|
|
195
|
+
! validate_numeric "test_var" "$test_var"
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
# Test: grep count fallback works
|
|
199
|
+
test_grep_count_fallback() {
|
|
200
|
+
# Empty file, grep should print one 0 and the fallback should not append another 0.
|
|
201
|
+
: > results/test.jsonl
|
|
202
|
+
local count
|
|
203
|
+
count=$(grep -c 'pattern' results/test.jsonl 2>/dev/null || true)
|
|
204
|
+
count=${count:-0}
|
|
205
|
+
[ "$count" = "0" ]
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# Test: grep count fallback on missing file
|
|
209
|
+
test_grep_count_fallback_missing() {
|
|
210
|
+
# Missing file, fallback should normalize empty output to one 0.
|
|
211
|
+
local count
|
|
212
|
+
count=$(grep -c 'pattern' results/nonexistent.jsonl 2>/dev/null || true)
|
|
213
|
+
count=${count:-0}
|
|
214
|
+
[ "$count" = "0" ]
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
# Test: json_encode function availability
|
|
218
|
+
test_json_encode_exists() {
|
|
219
|
+
source <(sed -n '/^json_encode()/,/^}/p' "$KASEKI_SCRIPT")
|
|
220
|
+
local output=$(printf 'test' | json_encode)
|
|
221
|
+
[ "$output" = '"test"' ]
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
# Test: json_encode fallback when node unavailable
|
|
225
|
+
test_json_encode_fallback() {
|
|
226
|
+
source <(sed -n '/^json_encode()/,/^}/p' "$KASEKI_SCRIPT")
|
|
227
|
+
|
|
228
|
+
# Temporarily override PATH to hide node
|
|
229
|
+
local old_path="$PATH"
|
|
230
|
+
export PATH="/usr/bin:/bin" # Minimal PATH without node
|
|
231
|
+
|
|
232
|
+
local output=$(printf 'test' | json_encode 2>/dev/null || true)
|
|
233
|
+
# Should return empty JSON string "" or handle gracefully
|
|
234
|
+
export PATH="$old_path"
|
|
235
|
+
|
|
236
|
+
# Test passes if it doesn't crash
|
|
237
|
+
true
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
# Main test execution
|
|
241
|
+
main() {
|
|
242
|
+
printf '\n%s\n' "$(printf '=%.0s' {1..70})"
|
|
243
|
+
printf 'Testing Printf Safety & Restoration Report Generation Fixes\n'
|
|
244
|
+
printf '%s\n' "$(printf '=%.0s' {1..70})"
|
|
245
|
+
printf '\n'
|
|
246
|
+
|
|
247
|
+
setup
|
|
248
|
+
|
|
249
|
+
# validate_numeric tests
|
|
250
|
+
printf '\n%s\n' '### validate_numeric() tests'
|
|
251
|
+
run_test "validate_numeric with valid integer" test_validate_numeric_valid
|
|
252
|
+
run_test "validate_numeric rejects dash (-)" test_validate_numeric_dash
|
|
253
|
+
run_test "validate_numeric rejects non-numeric" test_validate_numeric_non_numeric
|
|
254
|
+
run_test "validate_numeric rejects empty" test_validate_numeric_empty
|
|
255
|
+
run_test "validate_numeric rejects multi-line value" test_validate_numeric_multiline
|
|
256
|
+
|
|
257
|
+
# restoration report tests
|
|
258
|
+
printf '\n%s\n' '### generate_restoration_report() tests'
|
|
259
|
+
run_test "restoration report skips missing file" test_restoration_report_missing_file
|
|
260
|
+
run_test "restoration report handles empty file" test_restoration_report_empty_file
|
|
261
|
+
run_test "restoration report with valid entries" test_restoration_report_valid_entries
|
|
262
|
+
run_test "restoration report with only kept files" test_restoration_report_only_kept
|
|
263
|
+
run_test "restoration report with only restored files" test_restoration_report_only_restored
|
|
264
|
+
run_test "restoration report low coverage warning" test_restoration_report_low_coverage_warning
|
|
265
|
+
|
|
266
|
+
# printf safety tests
|
|
267
|
+
printf '\n%s\n' '### printf safety tests'
|
|
268
|
+
run_test "printf with valid numeric argument" test_printf_valid_numeric
|
|
269
|
+
run_test "printf with dash (unquoted) should fail" test_printf_dash_unquoted_fails
|
|
270
|
+
run_test "printf with dash (validation) should fail" test_printf_dash_quoted_validation
|
|
271
|
+
|
|
272
|
+
# grep fallback tests
|
|
273
|
+
printf '\n%s\n' '### grep fallback tests'
|
|
274
|
+
run_test "grep count fallback on empty file" test_grep_count_fallback
|
|
275
|
+
run_test "grep count fallback on missing file" test_grep_count_fallback_missing
|
|
276
|
+
|
|
277
|
+
# json_encode tests
|
|
278
|
+
printf '\n%s\n' '### json_encode() tests'
|
|
279
|
+
run_test "json_encode function works" test_json_encode_exists
|
|
280
|
+
run_test "json_encode handles node unavailable" test_json_encode_fallback
|
|
281
|
+
|
|
282
|
+
# Summary
|
|
283
|
+
printf '\n%s\n' "$(printf '=%.0s' {1..70})"
|
|
284
|
+
printf 'Test Results: %d/%d passed, %d failed\n' "$TESTS_PASSED" "$TESTS_RUN" "$TESTS_FAILED"
|
|
285
|
+
|
|
286
|
+
if [ "$TESTS_FAILED" -eq 0 ]; then
|
|
287
|
+
printf "${GREEN}✓ All tests passed!${NC}\n"
|
|
288
|
+
teardown
|
|
289
|
+
return 0
|
|
290
|
+
else
|
|
291
|
+
printf "${RED}✗ Some tests failed${NC}\n"
|
|
292
|
+
printf 'Results directory: %s\n' "$TEST_RESULTS_DIR"
|
|
293
|
+
return 1
|
|
294
|
+
fi
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
main "$@"
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Test for validation shell fix (non-login shell + directory checkpoint)
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
7
|
+
RUNNER="$REPO_ROOT/run-kaseki.sh"
|
|
8
|
+
|
|
9
|
+
pass() { printf '✓ %s\n' "$1"; }
|
|
10
|
+
fail() { printf '✗ %s\n' "$1" >&2; exit 1; }
|
|
11
|
+
|
|
12
|
+
# Test 1: Verify non-login shell syntax in kaseki-agent.sh
|
|
13
|
+
test_non_login_shell_syntax() {
|
|
14
|
+
local line
|
|
15
|
+
line=$(grep -n 'bash -c "\$trimmed"' "$REPO_ROOT/kaseki-agent.sh" | head -1 | cut -d: -f1)
|
|
16
|
+
[ -n "$line" ] || fail "Non-login shell (bash -c) not found in kaseki-agent.sh"
|
|
17
|
+
pass "Non-login shell syntax found at line $line"
|
|
18
|
+
|
|
19
|
+
# Ensure old login shell is gone
|
|
20
|
+
if grep -q 'bash -lc "\$trimmed"' "$REPO_ROOT/kaseki-agent.sh"; then
|
|
21
|
+
fail "Old login shell syntax (bash -lc) still present in kaseki-agent.sh"
|
|
22
|
+
fi
|
|
23
|
+
pass "Old login shell syntax removed"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
# Test 2: Verify directory checkpoint exists
|
|
27
|
+
test_directory_checkpoint() {
|
|
28
|
+
if grep -q 'Working directory /workspace/repo does not exist before validation' "$REPO_ROOT/kaseki-agent.sh"; then
|
|
29
|
+
pass "Directory checkpoint found in kaseki-agent.sh"
|
|
30
|
+
else
|
|
31
|
+
fail "Directory checkpoint not found"
|
|
32
|
+
fi
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Test 3: Verify enhanced diagnostics exist
|
|
36
|
+
test_enhanced_diagnostics() {
|
|
37
|
+
if grep -q 'getcwd.*No such file or directory.*cannot access parent directories' "$REPO_ROOT/kaseki-agent.sh"; then
|
|
38
|
+
pass "Enhanced diagnostics for getcwd errors found"
|
|
39
|
+
else
|
|
40
|
+
fail "Enhanced diagnostics not found"
|
|
41
|
+
fi
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Test 4: Verify script syntax is still valid
|
|
45
|
+
test_script_syntax() {
|
|
46
|
+
if bash -n "$REPO_ROOT/kaseki-agent.sh" >/dev/null 2>&1; then
|
|
47
|
+
pass "kaseki-agent.sh bash syntax is valid"
|
|
48
|
+
else
|
|
49
|
+
fail "kaseki-agent.sh has syntax errors"
|
|
50
|
+
fi
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Test 5: Verify non-login shell works for npm commands (integration test)
|
|
54
|
+
test_non_login_npm_command() {
|
|
55
|
+
local tmpdir exit_code
|
|
56
|
+
tmpdir=$(mktemp -d)
|
|
57
|
+
trap "rm -rf '$tmpdir'" EXIT
|
|
58
|
+
|
|
59
|
+
cd "$tmpdir"
|
|
60
|
+
npm init -y >/dev/null 2>&1
|
|
61
|
+
npm install eslint >/dev/null 2>&1
|
|
62
|
+
|
|
63
|
+
# Test that non-login bash can run npm commands
|
|
64
|
+
if bash -c "npm --version" >/dev/null 2>&1; then
|
|
65
|
+
pass "Non-login shell can execute npm commands"
|
|
66
|
+
else
|
|
67
|
+
fail "Non-login shell cannot execute npm commands"
|
|
68
|
+
fi
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# Run all tests
|
|
72
|
+
printf '==> Validation Fix Tests\n'
|
|
73
|
+
test_non_login_shell_syntax
|
|
74
|
+
test_directory_checkpoint
|
|
75
|
+
test_enhanced_diagnostics
|
|
76
|
+
test_script_syntax
|
|
77
|
+
test_non_login_npm_command
|
|
78
|
+
|
|
79
|
+
printf '\n✓ All validation fix tests passed\n'
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Integration test: Verify validation with non-login shell works
|
|
3
|
+
# This simulates the matmetrics scenario where validation commands need to run
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
8
|
+
|
|
9
|
+
pass() { printf '✓ %s\n' "$1"; }
|
|
10
|
+
fail() { printf '✗ %s\n' "$1" >&2; exit 1; }
|
|
11
|
+
|
|
12
|
+
# Create temporary test directory with npm project
|
|
13
|
+
setup_test_repo() {
|
|
14
|
+
local tmpdir="$1"
|
|
15
|
+
cd "$tmpdir"
|
|
16
|
+
|
|
17
|
+
# Initialize npm project with validation scripts
|
|
18
|
+
cat > package.json <<'EOF'
|
|
19
|
+
{
|
|
20
|
+
"name": "validation-test",
|
|
21
|
+
"version": "1.0.0",
|
|
22
|
+
"scripts": {
|
|
23
|
+
"check": "npm ls --depth=0",
|
|
24
|
+
"test": "node -e 'console.log(\"test passed\")'",
|
|
25
|
+
"build": "node -e 'console.log(\"build passed\")'"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
EOF
|
|
29
|
+
|
|
30
|
+
# Create a simple lockfile
|
|
31
|
+
cat > package-lock.json <<'EOF'
|
|
32
|
+
{
|
|
33
|
+
"name": "validation-test",
|
|
34
|
+
"version": "1.0.0",
|
|
35
|
+
"lockfileVersion": 3
|
|
36
|
+
}
|
|
37
|
+
EOF
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Test non-login shell validation execution
|
|
41
|
+
test_non_login_validation() {
|
|
42
|
+
local tmpdir exit_code
|
|
43
|
+
tmpdir=$(mktemp -d)
|
|
44
|
+
trap "rm -rf '$tmpdir'" EXIT
|
|
45
|
+
|
|
46
|
+
setup_test_repo "$tmpdir"
|
|
47
|
+
cd "$tmpdir"
|
|
48
|
+
|
|
49
|
+
# Simulate the validation command execution with non-login shell
|
|
50
|
+
# This is what happens in kaseki-agent.sh after the fix
|
|
51
|
+
if bash -c "npm run check" >/dev/null 2>&1; then
|
|
52
|
+
pass "Non-login validation command succeeded (npm run check)"
|
|
53
|
+
else
|
|
54
|
+
fail "Non-login validation command failed"
|
|
55
|
+
fi
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Test that directory errors are caught early (checkpoint test)
|
|
59
|
+
test_directory_checkpoint() {
|
|
60
|
+
local tmpdir validation_log exit_code
|
|
61
|
+
tmpdir=$(mktemp -d)
|
|
62
|
+
trap "rm -rf '$tmpdir'" EXIT
|
|
63
|
+
validation_log="$tmpdir/validation.log"
|
|
64
|
+
|
|
65
|
+
# Simulate the checkpoint logic from kaseki-agent.sh
|
|
66
|
+
if ! [ -d /nonexistent/repo ]; then
|
|
67
|
+
{
|
|
68
|
+
printf 'ERROR: Working directory /nonexistent/repo does not exist before validation\n'
|
|
69
|
+
printf 'Current pwd: %s\n' "$(pwd 2>&1 || echo '<pwd failed>')"
|
|
70
|
+
} > "$validation_log"
|
|
71
|
+
|
|
72
|
+
if grep -q 'does not exist before validation' "$validation_log"; then
|
|
73
|
+
pass "Directory checkpoint properly detects missing directories"
|
|
74
|
+
else
|
|
75
|
+
fail "Directory checkpoint did not detect missing directory"
|
|
76
|
+
fi
|
|
77
|
+
fi
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# Test enhanced diagnostics capture
|
|
81
|
+
test_diagnostics_capture() {
|
|
82
|
+
local tmpdir quality_log
|
|
83
|
+
tmpdir=$(mktemp -d)
|
|
84
|
+
trap "rm -rf '$tmpdir'" EXIT
|
|
85
|
+
quality_log="$tmpdir/quality.log"
|
|
86
|
+
|
|
87
|
+
# Simulate a getcwd error and verify diagnostics capture
|
|
88
|
+
if grep -q 'getcwd' <<< "Error: ENOENT: process.cwd failed"; then
|
|
89
|
+
{
|
|
90
|
+
printf '\n[DIAGNOSTICS] Validation command failed with directory access error:\n'
|
|
91
|
+
printf 'Working directory status:\n'
|
|
92
|
+
printf ' Current pwd: %s\n' "$(pwd 2>&1 || echo '<pwd failed>')"
|
|
93
|
+
printf ' /workspace/repo exists: %s\n' "$([ -d /workspace/repo ] && echo 'yes' || echo 'no')"
|
|
94
|
+
} > "$quality_log"
|
|
95
|
+
|
|
96
|
+
if grep -q 'DIAGNOSTICS' "$quality_log"; then
|
|
97
|
+
pass "Enhanced diagnostics properly captured"
|
|
98
|
+
else
|
|
99
|
+
fail "Enhanced diagnostics not captured"
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
printf '==> Validation Integration Tests\n'
|
|
105
|
+
test_non_login_validation
|
|
106
|
+
test_directory_checkpoint
|
|
107
|
+
test_diagnostics_capture
|
|
108
|
+
|
|
109
|
+
printf '\n✓ All integration tests passed\n'
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
|
|
6
|
+
# Source only the allowlist matcher helpers, without running a full Kaseki job.
|
|
7
|
+
# shellcheck source=scripts/allowlist-helper.sh
|
|
8
|
+
. "$ROOT_DIR/scripts/allowlist-helper.sh"
|
|
9
|
+
|
|
10
|
+
matches_allowlist() {
|
|
11
|
+
local allowlist="$1" file="$2" regex
|
|
12
|
+
KASEKI_CHANGED_FILES_ALLOWLIST="$allowlist"
|
|
13
|
+
regex="$(build_allowlist_regex)"
|
|
14
|
+
[ -n "$regex" ] && printf '%s\n' "$file" | grep -Eq "^(${regex})$"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
assert_matches() {
|
|
18
|
+
local allowlist="$1" file="$2"
|
|
19
|
+
if ! matches_allowlist "$allowlist" "$file"; then
|
|
20
|
+
printf 'Expected allowlist pattern to match file:\n pattern: %s\n file: %s\n' "$allowlist" "$file" >&2
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
assert_not_matches() {
|
|
26
|
+
local allowlist="$1" file="$2"
|
|
27
|
+
if matches_allowlist "$allowlist" "$file"; then
|
|
28
|
+
printf 'Expected allowlist pattern not to match file:\n pattern: %s\n file: %s\n' "$allowlist" "$file" >&2
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
assert_matches 'src/lib/parser.ts' 'src/lib/parser.ts'
|
|
34
|
+
assert_not_matches 'src/lib/parser.ts' 'src/lib/parser.tsx'
|
|
35
|
+
assert_not_matches 'src/lib/parser.ts' 'src/lib/parserats'
|
|
36
|
+
assert_not_matches 'src/lib/parser.ts' 'README.md'
|
|
37
|
+
assert_not_matches 'src/lib/parser.ts' 'package.json'
|
|
38
|
+
|
|
39
|
+
assert_matches 'src/**/*.ts' 'src/index.ts'
|
|
40
|
+
assert_matches 'src/**/*.ts' 'src/lib/file-storage.ts'
|
|
41
|
+
assert_not_matches 'src/**/*.ts' 'src/lib/file-storage.tsx'
|
|
42
|
+
assert_not_matches 'src/**/*.ts' 'README.md'
|
|
43
|
+
assert_not_matches 'src/**/*.ts' 'package.json'
|
|
44
|
+
|
|
45
|
+
assert_matches 'src/**/*.tsx' 'src/app/page.tsx'
|
|
46
|
+
assert_matches 'src/**/*.tsx' 'src/components/plugin-manager.tsx'
|
|
47
|
+
assert_not_matches 'src/**/*.tsx' 'src/components/plugin-manager.ts'
|
|
48
|
+
assert_not_matches 'src/**/*.tsx' 'README.md'
|
|
49
|
+
assert_not_matches 'src/**/*.tsx' 'package.json'
|
|
50
|
+
|
|
51
|
+
assert_matches 'docs/v?.md' 'docs/v1.md'
|
|
52
|
+
assert_not_matches 'docs/v?.md' 'docs/v10.md'
|
|
53
|
+
assert_not_matches 'docs/v?.md' 'docs/nested/v1.md'
|
|
54
|
+
|
|
55
|
+
assert_matches 'src/file+(test).ts' 'src/file+(test).ts'
|
|
56
|
+
assert_not_matches 'src/file+(test).ts' 'src/fileeeeeeeee.ts'
|
|
57
|
+
assert_not_matches 'src/file+(test).ts' 'src/filetest.ts'
|
|
58
|
+
assert_matches 'src/{literal}|^$.ts' 'src/{literal}|^$.ts'
|
|
59
|
+
assert_not_matches 'src/{literal}|^$.ts' 'src/literal.ts'
|
|
60
|
+
assert_matches 'src/[draft]/file.name(1).ts' 'src/[draft]/file.name(1).ts'
|
|
61
|
+
assert_not_matches 'src/[draft]/file.name(1).ts' 'src/d/filexname1.ts'
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
TMP_DIR="$(mktemp -d)"
|
|
6
|
+
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
7
|
+
|
|
8
|
+
# Load only the pure dependency-cache key helpers from kaseki-agent.sh.
|
|
9
|
+
eval "$(awk '
|
|
10
|
+
/^dependency_cache_flags_identity\(\)/ { emit=1 }
|
|
11
|
+
/^build_agent_prompt\(\)/ { emit=0 }
|
|
12
|
+
emit { print }
|
|
13
|
+
' "$ROOT_DIR/kaseki-agent.sh")"
|
|
14
|
+
|
|
15
|
+
cat > "$TMP_DIR/package-lock.json" <<'LOCK'
|
|
16
|
+
{"lockfileVersion":3,"packages":{}}
|
|
17
|
+
LOCK
|
|
18
|
+
|
|
19
|
+
lock_hash="$(sha256sum "$TMP_DIR/package-lock.json" | awk '{print $1}')"
|
|
20
|
+
node_major="24"
|
|
21
|
+
KASEKI_NPM_OMIT_DEV=0
|
|
22
|
+
KASEKI_INSTALL_IGNORE_SCRIPTS=1
|
|
23
|
+
flags_hash="$(dependency_cache_flags_hash)"
|
|
24
|
+
cache_root="$TMP_DIR/cache"
|
|
25
|
+
|
|
26
|
+
REPO_URL="https://example.com/project.git" GIT_REF="feature-a"
|
|
27
|
+
path_a="$cache_root/$(dependency_cache_key "$lock_hash" "$node_major" "$flags_hash")/node_modules"
|
|
28
|
+
REPO_URL="https://example.com/project.git" GIT_REF="feature-b"
|
|
29
|
+
path_b="$cache_root/$(dependency_cache_key "$lock_hash" "$node_major" "$flags_hash")/node_modules"
|
|
30
|
+
|
|
31
|
+
if [ "$path_a" != "$path_b" ]; then
|
|
32
|
+
printf 'Expected identical lockfile cache paths across refs:\n %s\n %s\n' "$path_a" "$path_b" >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
expected_prefix="$cache_root/npm/$lock_hash/node-$node_major/flags-$flags_hash/node_modules"
|
|
37
|
+
if [ "$path_a" != "$expected_prefix" ]; then
|
|
38
|
+
printf 'Unexpected dependency cache path:\n expected: %s\n actual: %s\n' "$expected_prefix" "$path_a" >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
KASEKI_NPM_OMIT_DEV=1
|
|
43
|
+
omit_dev_flags_hash="$(dependency_cache_flags_hash)"
|
|
44
|
+
omit_dev_path="$cache_root/$(dependency_cache_key "$lock_hash" "$node_major" "$omit_dev_flags_hash")/node_modules"
|
|
45
|
+
if [ "$path_a" = "$omit_dev_path" ]; then
|
|
46
|
+
printf 'Expected install flags to produce a distinct dependency cache path: %s\n' "$path_a" >&2
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
TMP_DIR="$(mktemp -d)"
|
|
6
|
+
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
7
|
+
|
|
8
|
+
# Load only dependency restore/cache helper functions from kaseki-agent.sh.
|
|
9
|
+
eval "$(awk '
|
|
10
|
+
/^set_dependency_cache_status\(\)/ { emit=1 }
|
|
11
|
+
/^dependency_cache_flags_identity\(\)/ { emit=0 }
|
|
12
|
+
emit { print }
|
|
13
|
+
' "$ROOT_DIR/kaseki-agent.sh")"
|
|
14
|
+
|
|
15
|
+
fail() { printf '✗ %s\n' "$1" >&2; exit 1; }
|
|
16
|
+
pass() { printf '✓ %s\n' "$1"; }
|
|
17
|
+
|
|
18
|
+
DEPENDENCY_CACHE_LOG="$TMP_DIR/dependency-cache.log"
|
|
19
|
+
: > "$DEPENDENCY_CACHE_LOG"
|
|
20
|
+
|
|
21
|
+
mkdir -p "$TMP_DIR/cache/node_modules/pkg" "$TMP_DIR/workspace"
|
|
22
|
+
printf 'cached package\n' > "$TMP_DIR/cache/node_modules/pkg/index.js"
|
|
23
|
+
|
|
24
|
+
(
|
|
25
|
+
cd "$TMP_DIR/workspace"
|
|
26
|
+
cp() {
|
|
27
|
+
if [ "${1:-}" = "-al" ]; then
|
|
28
|
+
return 1
|
|
29
|
+
fi
|
|
30
|
+
command cp "$@"
|
|
31
|
+
}
|
|
32
|
+
restore_node_modules_from_cache "$TMP_DIR/cache/node_modules" ./node_modules hardlink
|
|
33
|
+
[ "${DEPENDENCY_RESTORE_METHOD:-}" = "hardlink_fallback_copy" ] || fail "Expected hardlink fallback method, got ${DEPENDENCY_RESTORE_METHOD:-unset}"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
[ -f "$TMP_DIR/workspace/node_modules/pkg/index.js" ] || fail "Fallback copy did not restore package file"
|
|
37
|
+
if ! grep -q 'hardlink restore failed; falling back to copy' "$DEPENDENCY_CACHE_LOG"; then
|
|
38
|
+
fail "Expected dependency-cache.log to include hardlink fallback message"
|
|
39
|
+
fi
|
|
40
|
+
pass "hardlink restore falls back to copy when cp -al fails"
|
|
41
|
+
|
|
42
|
+
rm -rf "$TMP_DIR/workspace/node_modules" "$TMP_DIR/published"
|
|
43
|
+
ln -s "$TMP_DIR/cache/node_modules" "$TMP_DIR/workspace/node_modules"
|
|
44
|
+
publish_node_modules_cache "$TMP_DIR/workspace/node_modules" "$TMP_DIR/published"
|
|
45
|
+
[ -d "$TMP_DIR/published" ] || fail "Published cache path is not a directory"
|
|
46
|
+
[ ! -L "$TMP_DIR/published" ] || fail "Published cache path must not be a symlink"
|
|
47
|
+
[ -f "$TMP_DIR/published/pkg/index.js" ] || fail "Published real directory is missing package file"
|
|
48
|
+
pass "cache publication materializes a real directory from symlinked node_modules"
|