@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,95 @@
|
|
|
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
|
+
template_dir="$TMP_DIR/source-checkout"
|
|
9
|
+
fake_bin="$TMP_DIR/bin"
|
|
10
|
+
mkdir -p "$template_dir/scripts" "$fake_bin"
|
|
11
|
+
cp "$ROOT_DIR/run-kaseki.sh" "$template_dir/run-kaseki.sh"
|
|
12
|
+
cp "$ROOT_DIR/kaseki-agent.sh" "$template_dir/kaseki-agent.sh"
|
|
13
|
+
cp "$ROOT_DIR/scripts/kaseki-preflight.sh" "$template_dir/scripts/kaseki-preflight.sh"
|
|
14
|
+
chmod +x "$template_dir/run-kaseki.sh" "$template_dir/kaseki-agent.sh" "$template_dir/scripts/kaseki-preflight.sh"
|
|
15
|
+
|
|
16
|
+
cat > "$fake_bin/docker" <<'DOCKER'
|
|
17
|
+
#!/usr/bin/env bash
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
if [ "${1:-}" = "--version" ]; then
|
|
21
|
+
printf 'Docker version test\n'
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if [ "${1:-}" = "image" ] && [ "${2:-}" = "inspect" ]; then
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
if [ "${1:-}" = "run" ]; then
|
|
30
|
+
shift
|
|
31
|
+
if [ "${1:-}" = "--rm" ]; then shift; fi
|
|
32
|
+
if [ "${1:-}" = "--entrypoint" ]; then
|
|
33
|
+
entrypoint="${2:-}"
|
|
34
|
+
shift 2
|
|
35
|
+
else
|
|
36
|
+
entrypoint=""
|
|
37
|
+
fi
|
|
38
|
+
image="${1:-}"
|
|
39
|
+
shift || true
|
|
40
|
+
case "$entrypoint" in
|
|
41
|
+
test)
|
|
42
|
+
[ "${1:-}" = "-f" ] && [ "${2:-}" = "/app/run-kaseki.sh" ]
|
|
43
|
+
;;
|
|
44
|
+
sha256sum)
|
|
45
|
+
case "${1:-}" in
|
|
46
|
+
/usr/local/bin/kaseki-agent)
|
|
47
|
+
sha256sum "$TEST_TEMPLATE_DIR/kaseki-agent.sh"
|
|
48
|
+
;;
|
|
49
|
+
*)
|
|
50
|
+
printf '0000000000000000000000000000000000000000000000000000000000000000 %s\n' "${1:-}"
|
|
51
|
+
;;
|
|
52
|
+
esac
|
|
53
|
+
;;
|
|
54
|
+
*)
|
|
55
|
+
printf 'unexpected docker run entrypoint for %s: %s\n' "$image" "$entrypoint" >&2
|
|
56
|
+
exit 2
|
|
57
|
+
;;
|
|
58
|
+
esac
|
|
59
|
+
exit 0
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
printf 'unexpected docker invocation: %s\n' "$*" >&2
|
|
63
|
+
exit 2
|
|
64
|
+
DOCKER
|
|
65
|
+
chmod +x "$fake_bin/docker"
|
|
66
|
+
|
|
67
|
+
set +e
|
|
68
|
+
output="$(
|
|
69
|
+
cd "$template_dir" && env \
|
|
70
|
+
PATH="$fake_bin:/usr/bin:/bin" \
|
|
71
|
+
TEST_TEMPLATE_DIR="$template_dir" \
|
|
72
|
+
KASEKI_ROOT="$TMP_DIR/root" \
|
|
73
|
+
KASEKI_LOG_DIR="$TMP_DIR/logs" \
|
|
74
|
+
OPENROUTER_API_KEY="test-key" \
|
|
75
|
+
./run-kaseki.sh --doctor 2>&1
|
|
76
|
+
)"
|
|
77
|
+
status=$?
|
|
78
|
+
set -e
|
|
79
|
+
|
|
80
|
+
if [ "$status" -eq 0 ]; then
|
|
81
|
+
printf 'Expected doctor to fail for missing deployed template files\nOutput:\n%s\n' "$output" >&2
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
for expected in \
|
|
86
|
+
'Image/template parity: missing host file lib/pi-event-filter.js' \
|
|
87
|
+
'Image/template parity: missing deployed template files; this looks like a source checkout or incomplete template.' \
|
|
88
|
+
'sudo KASEKI_IMAGE_PULL_POLICY=missing ./scripts/deploy-pi-template.sh' \
|
|
89
|
+
'/agents/kaseki-template/run-kaseki.sh --doctor'
|
|
90
|
+
do
|
|
91
|
+
if ! printf '%s\n' "$output" | grep -Fq "$expected"; then
|
|
92
|
+
printf 'Expected doctor output to contain: %s\nOutput:\n%s\n' "$expected" "$output" >&2
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
done
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Integration tests for github operations printf safety
|
|
3
|
+
# Tests that github operations skip logging doesn't break with variable substitution
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
8
|
+
TMP_DIR="$(mktemp -d)"
|
|
9
|
+
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
10
|
+
|
|
11
|
+
pass() { printf 'ā %s\n' "$1"; }
|
|
12
|
+
fail() { printf 'ā %s\n' "$1" >&2; exit 1; }
|
|
13
|
+
info() { printf '[info] %s\n' "$1"; }
|
|
14
|
+
|
|
15
|
+
# Test setup
|
|
16
|
+
mkdir -p "$TMP_DIR/results"
|
|
17
|
+
RESULTS_DIR="$TMP_DIR/results"
|
|
18
|
+
|
|
19
|
+
# Test 1: printf with dash-containing variable doesn't fail
|
|
20
|
+
info "Test 1: printf with dash-containing skip reasons"
|
|
21
|
+
{
|
|
22
|
+
GITHUB_SKIP_REASONS=("agent_failed" "-validation_failed" "empty_diff")
|
|
23
|
+
printf -- 'GitHub operations: skipped (reasons: %s)\n' "$(IFS=,; printf '%s' "${GITHUB_SKIP_REASONS[*]}")" > "$RESULTS_DIR/test1.log"
|
|
24
|
+
} && pass "printf with dash-containing reasons succeeded" || fail "printf with dash-containing reasons failed"
|
|
25
|
+
|
|
26
|
+
# Verify output contains all reasons
|
|
27
|
+
if grep -q "agent_failed,-validation_failed,empty_diff" "$RESULTS_DIR/test1.log"; then
|
|
28
|
+
pass "All skip reasons captured in output"
|
|
29
|
+
else
|
|
30
|
+
fail "Skip reasons not properly captured: $(cat "$RESULTS_DIR/test1.log")"
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Test 2: printf with multi-argument substitution (github skip diagnostics)
|
|
34
|
+
info "Test 2: Multi-argument printf with exit code variables"
|
|
35
|
+
{
|
|
36
|
+
PI_EXIT=0
|
|
37
|
+
VALIDATION_EXIT=1
|
|
38
|
+
QUALITY_EXIT=0
|
|
39
|
+
SECRET_SCAN_EXIT=0
|
|
40
|
+
GITHUB_SKIP_REASONS=("validation_failed")
|
|
41
|
+
DIFF_NONEMPTY="true"
|
|
42
|
+
GITHUB_APP_ENABLED="0"
|
|
43
|
+
|
|
44
|
+
printf -- 'GitHub operations: skipped (reasons: %s; agent %s, validation %s, quality %s, secret_scan %s, diff %s, github_enabled %s)\n' \
|
|
45
|
+
"$(IFS=,; printf '%s' "${GITHUB_SKIP_REASONS[*]}")" \
|
|
46
|
+
"$([ "$PI_EXIT" -eq 0 ] && printf 'passed' || printf 'failed')" \
|
|
47
|
+
"$([ "$VALIDATION_EXIT" -eq 0 ] && printf 'passed' || printf 'failed')" \
|
|
48
|
+
"$([ "$QUALITY_EXIT" -eq 0 ] && printf 'passed' || printf 'failed')" \
|
|
49
|
+
"$([ "$SECRET_SCAN_EXIT" -eq 0 ] && printf 'passed' || printf 'failed')" \
|
|
50
|
+
"$DIFF_NONEMPTY" \
|
|
51
|
+
"$GITHUB_APP_ENABLED" > "$RESULTS_DIR/test2.log"
|
|
52
|
+
} && pass "Multi-argument printf succeeded" || fail "Multi-argument printf failed"
|
|
53
|
+
|
|
54
|
+
# Verify output contains all placeholders properly filled
|
|
55
|
+
if grep -q "validation_failed; agent passed, validation failed, quality passed, secret_scan passed, diff true, github_enabled 0" "$RESULTS_DIR/test2.log"; then
|
|
56
|
+
pass "All arguments properly substituted in output"
|
|
57
|
+
else
|
|
58
|
+
fail "Arguments not properly substituted: $(cat "$RESULTS_DIR/test2.log")"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Test 3: printf with edge case: empty array expansion
|
|
62
|
+
info "Test 3: printf with empty skip reasons"
|
|
63
|
+
{
|
|
64
|
+
GITHUB_SKIP_REASONS=()
|
|
65
|
+
printf -- 'GitHub operations: skipped (reasons: %s)\n' "$(IFS=,; printf '%s' "${GITHUB_SKIP_REASONS[*]:-none}")" > "$RESULTS_DIR/test3.log"
|
|
66
|
+
} && pass "printf with empty array succeeded" || fail "printf with empty array failed"
|
|
67
|
+
|
|
68
|
+
if grep -q "reasons: none" "$RESULTS_DIR/test3.log"; then
|
|
69
|
+
pass "Empty array handled correctly"
|
|
70
|
+
else
|
|
71
|
+
fail "Empty array not handled correctly: $(cat "$RESULTS_DIR/test3.log")"
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Test 4: printf with special characters in variable values
|
|
75
|
+
info "Test 4: printf with special characters in REPO_URL"
|
|
76
|
+
{
|
|
77
|
+
REPO_URL="https://github.com/owner-name/repo-name.git"
|
|
78
|
+
printf -- 'Cannot parse GitHub repo URL: %s\n' "$REPO_URL" > "$RESULTS_DIR/test4.log"
|
|
79
|
+
} && pass "printf with special chars in URL succeeded" || fail "printf with special chars in URL failed"
|
|
80
|
+
|
|
81
|
+
if grep -q "owner-name/repo-name" "$RESULTS_DIR/test4.log"; then
|
|
82
|
+
pass "Special characters preserved in output"
|
|
83
|
+
else
|
|
84
|
+
fail "Special characters not preserved: $(cat "$RESULTS_DIR/test4.log")"
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Test 5: printf with feature branch containing instance name
|
|
88
|
+
info "Test 5: printf with feature branch name containing dashes"
|
|
89
|
+
{
|
|
90
|
+
INSTANCE_NAME="kaseki-9142"
|
|
91
|
+
feature_branch="kaseki/$INSTANCE_NAME"
|
|
92
|
+
printf -- 'Creating feature branch: %s\n' "$feature_branch" > "$RESULTS_DIR/test5.log"
|
|
93
|
+
} && pass "printf with dash-containing branch name succeeded" || fail "printf with dash-containing branch name failed"
|
|
94
|
+
|
|
95
|
+
if grep -q "kaseki/kaseki-9142" "$RESULTS_DIR/test5.log"; then
|
|
96
|
+
pass "Feature branch name correctly output"
|
|
97
|
+
else
|
|
98
|
+
fail "Feature branch name not correct: $(cat "$RESULTS_DIR/test5.log")"
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Test 6: Verify all printf calls have -- separator (source code check)
|
|
102
|
+
info "Test 6: Verify -- separator present in critical printf calls"
|
|
103
|
+
if grep -n "printf -- 'GitHub operations: skipped (reasons:" "$ROOT_DIR/kaseki-agent.sh" > /dev/null; then
|
|
104
|
+
pass "Primary github operations printf has -- separator"
|
|
105
|
+
else
|
|
106
|
+
fail "Primary github operations printf missing -- separator"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
if grep -n "printf -- 'GitHub operations: skipped (reasons:.*agent %s" "$ROOT_DIR/kaseki-agent.sh" > /dev/null; then
|
|
110
|
+
pass "Multi-argument github operations printf has -- separator"
|
|
111
|
+
else
|
|
112
|
+
fail "Multi-argument github operations printf missing -- separator"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# Test 7: Integration test - simulate actual function behavior
|
|
116
|
+
info "Test 7: Simulate actual build_github_skip_reasons behavior"
|
|
117
|
+
{
|
|
118
|
+
# Simulate the skip reasons array logic
|
|
119
|
+
GITHUB_SKIP_REASONS=()
|
|
120
|
+
PI_EXIT=1
|
|
121
|
+
[ "$PI_EXIT" -eq 0 ] || GITHUB_SKIP_REASONS+=("agent_failed")
|
|
122
|
+
|
|
123
|
+
VALIDATION_EXIT=5
|
|
124
|
+
[ "$VALIDATION_EXIT" -eq 0 ] || GITHUB_SKIP_REASONS+=("validation_failed")
|
|
125
|
+
|
|
126
|
+
# Log the skip reasons safely
|
|
127
|
+
printf -- 'GitHub operations: skipped (reasons: %s)\n' \
|
|
128
|
+
"$(IFS=,; printf '%s' "${GITHUB_SKIP_REASONS[*]}")" > "$RESULTS_DIR/test7.log"
|
|
129
|
+
} && pass "Simulated skip reasons logic succeeded" || fail "Simulated skip reasons logic failed"
|
|
130
|
+
|
|
131
|
+
if grep -q "agent_failed,validation_failed" "$RESULTS_DIR/test7.log"; then
|
|
132
|
+
pass "Skip reasons correctly accumulated and logged"
|
|
133
|
+
else
|
|
134
|
+
fail "Skip reasons not correctly accumulated: $(cat "$RESULTS_DIR/test7.log")"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# Summary
|
|
138
|
+
info "All tests passed!"
|
|
139
|
+
printf '\n==> Summary\n'
|
|
140
|
+
printf 'Tests run: 7\n'
|
|
141
|
+
printf 'Passed: 7\n'
|
|
142
|
+
printf 'Failed: 0\n'
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
|
|
6
|
+
# Load only the npm install flag helpers from kaseki-agent.sh.
|
|
7
|
+
eval "$(awk '
|
|
8
|
+
/^append_npm_install_flags\(\)/ { emit=1 }
|
|
9
|
+
/^dependency_cache_key\(\)/ { emit=0 }
|
|
10
|
+
emit { print }
|
|
11
|
+
' "$ROOT_DIR/kaseki-agent.sh")"
|
|
12
|
+
|
|
13
|
+
fail() { printf 'ā %s\n' "$1" >&2; exit 1; }
|
|
14
|
+
pass() { printf 'ā %s\n' "$1"; }
|
|
15
|
+
|
|
16
|
+
assert_flags() {
|
|
17
|
+
local label="$1"
|
|
18
|
+
local omit_dev="$2"
|
|
19
|
+
local ignore_scripts="$3"
|
|
20
|
+
local expected_display="$4"
|
|
21
|
+
shift 4
|
|
22
|
+
local -a expected_flags=("$@")
|
|
23
|
+
local -a install_flags=("stale")
|
|
24
|
+
|
|
25
|
+
KASEKI_NPM_OMIT_DEV="$omit_dev"
|
|
26
|
+
KASEKI_INSTALL_IGNORE_SCRIPTS="$ignore_scripts"
|
|
27
|
+
append_npm_install_flags install_flags
|
|
28
|
+
|
|
29
|
+
if [ "${#install_flags[@]}" -ne "${#expected_flags[@]}" ]; then
|
|
30
|
+
fail "$label: expected ${#expected_flags[@]} flags, got ${#install_flags[@]}"
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
local i
|
|
34
|
+
for i in "${!expected_flags[@]}"; do
|
|
35
|
+
if [ "${install_flags[$i]}" != "${expected_flags[$i]}" ]; then
|
|
36
|
+
fail "$label: expected flag $i to be ${expected_flags[$i]}, got ${install_flags[$i]}"
|
|
37
|
+
fi
|
|
38
|
+
done
|
|
39
|
+
|
|
40
|
+
local display
|
|
41
|
+
display="$(render_npm_install_flags "${install_flags[@]}")"
|
|
42
|
+
if [ "$display" != "$expected_display" ]; then
|
|
43
|
+
fail "$label: expected display '$expected_display', got '$display'"
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
local -a npm_args=(ci --prefer-offline "${install_flags[@]}")
|
|
47
|
+
local expected_count=$((2 + ${#expected_flags[@]}))
|
|
48
|
+
if [ "${#npm_args[@]}" -ne "$expected_count" ]; then
|
|
49
|
+
fail "$label: npm argument count changed during expansion"
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
pass "$label"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
assert_flags "no optional install flags" 0 0 "none"
|
|
56
|
+
assert_flags "one optional install flag (omit dev)" 1 0 "--omit=dev" "--omit=dev"
|
|
57
|
+
assert_flags "one optional install flag (ignore scripts)" 0 1 "--ignore-scripts" "--ignore-scripts"
|
|
58
|
+
assert_flags "both optional install flags" 1 1 "--omit=dev --ignore-scripts" "--omit=dev" "--ignore-scripts"
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Integration tests for quality gate enforcement
|
|
3
|
+
# Tests diff size limits, allowlist validation, and secret scanning
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
8
|
+
TMP_DIR="$(mktemp -d)"
|
|
9
|
+
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
10
|
+
|
|
11
|
+
# Load quality gate logic from kaseki-agent.sh
|
|
12
|
+
eval "$(awk '
|
|
13
|
+
/^allowlist_pattern_to_regex\(\)/ { emit=1 }
|
|
14
|
+
/^compute_repo_memory_key\(\)/ { emit=0 }
|
|
15
|
+
emit { print }
|
|
16
|
+
' "$ROOT_DIR/scripts/allowlist-helper.sh")"
|
|
17
|
+
|
|
18
|
+
pass() { printf 'ā %s\n' "$1"; }
|
|
19
|
+
fail() { printf 'ā %s\n' "$1" >&2; exit 1; }
|
|
20
|
+
|
|
21
|
+
# Create a test results directory structure
|
|
22
|
+
mkdir -p "$TMP_DIR/results"
|
|
23
|
+
mkdir -p "$TMP_DIR/repo"
|
|
24
|
+
|
|
25
|
+
# Test 1: Diff size exceeds max bytes
|
|
26
|
+
echo "==> Test: Diff size check"
|
|
27
|
+
{
|
|
28
|
+
cd "$TMP_DIR/repo"
|
|
29
|
+
git init --initial-branch=main -q
|
|
30
|
+
git config user.email "test@kaseki.local"
|
|
31
|
+
git config user.name "Test User"
|
|
32
|
+
|
|
33
|
+
# Create initial commit
|
|
34
|
+
echo "initial" > file.txt
|
|
35
|
+
git add file.txt
|
|
36
|
+
git commit -q -m "initial"
|
|
37
|
+
|
|
38
|
+
# Generate a large diff (exceeds default 200KB)
|
|
39
|
+
# Create a file with 300KB of data
|
|
40
|
+
python3 -c "print('x' * 310000)" > large_file.txt
|
|
41
|
+
git add large_file.txt
|
|
42
|
+
git diff --cached > "$TMP_DIR/results/git.diff"
|
|
43
|
+
|
|
44
|
+
diff_size="$(wc -c < "$TMP_DIR/results/git.diff" | tr -d ' ')"
|
|
45
|
+
KASEKI_MAX_DIFF_BYTES=200000
|
|
46
|
+
|
|
47
|
+
if [ "$diff_size" -gt "$KASEKI_MAX_DIFF_BYTES" ]; then
|
|
48
|
+
pass "Diff size check: detects oversized diff ($diff_size > $KASEKI_MAX_DIFF_BYTES)"
|
|
49
|
+
else
|
|
50
|
+
fail "Diff size check: expected diff to exceed $KASEKI_MAX_DIFF_BYTES bytes, got $diff_size"
|
|
51
|
+
fi
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# Test 2: Allowlist validation
|
|
55
|
+
echo "==> Test: Allowlist validation"
|
|
56
|
+
{
|
|
57
|
+
cd "$TMP_DIR/repo"
|
|
58
|
+
git diff --name-only > "$TMP_DIR/results/changed-files.txt"
|
|
59
|
+
|
|
60
|
+
# Test matching allowed files
|
|
61
|
+
KASEKI_CHANGED_FILES_ALLOWLIST="src/**/*.ts tests/**/*.test.ts"
|
|
62
|
+
allowlist_regex="$(build_allowlist_regex)"
|
|
63
|
+
|
|
64
|
+
# Should match
|
|
65
|
+
if printf 'src/index.ts\n' | grep -Eq "^(${allowlist_regex})$"; then
|
|
66
|
+
pass "Allowlist: allows src/index.ts pattern"
|
|
67
|
+
else
|
|
68
|
+
fail "Allowlist: should allow src/index.ts"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Should not match
|
|
72
|
+
if printf 'README.md\n' | grep -Eq "^(${allowlist_regex})$"; then
|
|
73
|
+
fail "Allowlist: should reject README.md"
|
|
74
|
+
else
|
|
75
|
+
pass "Allowlist: rejects README.md"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Test wildcard patterns
|
|
79
|
+
if printf 'src/lib/parser.ts\n' | grep -Eq "^(${allowlist_regex})$"; then
|
|
80
|
+
pass "Allowlist: allows nested src/lib/parser.ts"
|
|
81
|
+
else
|
|
82
|
+
fail "Allowlist: should allow src/lib/parser.ts"
|
|
83
|
+
fi
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Test 3: Secret scanning (pattern detection)
|
|
87
|
+
echo "==> Test: Secret scanning"
|
|
88
|
+
{
|
|
89
|
+
# Create a file with a fake API key
|
|
90
|
+
cat > "$TMP_DIR/results/secret-test.txt" <<'EOF'
|
|
91
|
+
This file has an OpenRouter API key: sk-or-aBcDeFgHiJkLmNoPqRsT
|
|
92
|
+
And some normal content
|
|
93
|
+
EOF
|
|
94
|
+
|
|
95
|
+
if grep -E 'sk-or-[A-Za-z0-9_-]{20,}' "$TMP_DIR/results/secret-test.txt" > /dev/null; then
|
|
96
|
+
pass "Secret scanning: detects sk-or-* pattern"
|
|
97
|
+
else
|
|
98
|
+
fail "Secret scanning: should detect sk-or-* pattern"
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Create a clean file
|
|
102
|
+
cat > "$TMP_DIR/results/clean-test.txt" <<'EOF'
|
|
103
|
+
This file has no secrets
|
|
104
|
+
Just normal content here
|
|
105
|
+
EOF
|
|
106
|
+
|
|
107
|
+
if ! grep -E 'sk-or-[A-Za-z0-9_-]{20,}' "$TMP_DIR/results/clean-test.txt"; then
|
|
108
|
+
pass "Secret scanning: clean file passes"
|
|
109
|
+
else
|
|
110
|
+
fail "Secret scanning: clean file should pass"
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
# Test 4: Overly broad allowlist patterns
|
|
115
|
+
echo "==> Test: Overly broad allowlist detection"
|
|
116
|
+
{
|
|
117
|
+
# Test that '*' pattern is too broad
|
|
118
|
+
KASEKI_CHANGED_FILES_ALLOWLIST="*"
|
|
119
|
+
allowlist_regex="$(build_allowlist_regex)"
|
|
120
|
+
|
|
121
|
+
# This would match everything, which is bad
|
|
122
|
+
test_cases=("package.json" "src/index.ts" "tests/foo.test.ts" "README.md" "Dockerfile")
|
|
123
|
+
all_match=true
|
|
124
|
+
|
|
125
|
+
for file in "${test_cases[@]}"; do
|
|
126
|
+
if ! printf '%s\n' "$file" | grep -Eq "^(${allowlist_regex})$"; then
|
|
127
|
+
all_match=false
|
|
128
|
+
break
|
|
129
|
+
fi
|
|
130
|
+
done
|
|
131
|
+
|
|
132
|
+
if [ "$all_match" = true ]; then
|
|
133
|
+
fail "Overly broad allowlist: '*' pattern matches everything (too permissive)"
|
|
134
|
+
else
|
|
135
|
+
pass "Allowlist prevents overly broad '*' patterns"
|
|
136
|
+
fi
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# Test 5: Multiple file allowlist
|
|
140
|
+
echo "==> Test: Multiple file allowlist patterns"
|
|
141
|
+
{
|
|
142
|
+
KASEKI_CHANGED_FILES_ALLOWLIST="src/lib/parser.ts tests/parser.validation.ts docs/README.md"
|
|
143
|
+
allowlist_regex="$(build_allowlist_regex)"
|
|
144
|
+
|
|
145
|
+
allowed_files=("src/lib/parser.ts" "tests/parser.validation.ts" "docs/README.md")
|
|
146
|
+
rejected_files=("src/index.ts" "tests/other.test.ts" "CHANGELOG.md")
|
|
147
|
+
|
|
148
|
+
for file in "${allowed_files[@]}"; do
|
|
149
|
+
if printf '%s\n' "$file" | grep -Eq "^(${allowlist_regex})$"; then
|
|
150
|
+
pass "Allowlist: allows $file"
|
|
151
|
+
else
|
|
152
|
+
fail "Allowlist: should allow $file"
|
|
153
|
+
fi
|
|
154
|
+
done
|
|
155
|
+
|
|
156
|
+
for file in "${rejected_files[@]}"; do
|
|
157
|
+
if printf '%s\n' "$file" | grep -Eq "^(${allowlist_regex})$"; then
|
|
158
|
+
fail "Allowlist: should reject $file"
|
|
159
|
+
else
|
|
160
|
+
pass "Allowlist: rejects $file"
|
|
161
|
+
fi
|
|
162
|
+
done
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# Test 6: Empty diff detection
|
|
166
|
+
echo "==> Test: Empty diff handling"
|
|
167
|
+
{
|
|
168
|
+
: > "$TMP_DIR/results/empty.diff"
|
|
169
|
+
empty_size="$(wc -c < "$TMP_DIR/results/empty.diff" | tr -d ' ')"
|
|
170
|
+
|
|
171
|
+
if [ "$empty_size" -eq 0 ]; then
|
|
172
|
+
pass "Empty diff detection: correctly identifies 0-byte diff"
|
|
173
|
+
else
|
|
174
|
+
fail "Empty diff detection: expected 0 bytes, got $empty_size"
|
|
175
|
+
fi
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
printf '\nā
All quality gate tests passed\n'
|
|
@@ -0,0 +1,103 @@
|
|
|
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 repository-memory and prompt helpers from kaseki-agent.sh.
|
|
9
|
+
eval "$(awk '
|
|
10
|
+
/^compute_repo_memory_key\(\)/ { emit=1 }
|
|
11
|
+
/^run_github_operations\(\)/ { emit=0 }
|
|
12
|
+
emit { print }
|
|
13
|
+
' "$ROOT_DIR/kaseki-agent.sh")"
|
|
14
|
+
|
|
15
|
+
emit_event() { :; }
|
|
16
|
+
emit_error_event() { :; }
|
|
17
|
+
|
|
18
|
+
REPO_URL="https://example.com/acme/widgets.git"
|
|
19
|
+
GIT_REF="main"
|
|
20
|
+
TASK_PROMPT="Fix the widget parser."
|
|
21
|
+
KASEKI_AGENT_GUARDRAILS=1
|
|
22
|
+
KASEKI_REPO_MEMORY_MODE=summary
|
|
23
|
+
KASEKI_REPO_MEMORY_TTL_DAYS=30
|
|
24
|
+
KASEKI_REPO_MEMORY_MAX_BYTES=4096
|
|
25
|
+
KASEKI_DRY_RUN=0
|
|
26
|
+
REPO_MEMORY_KEY=""
|
|
27
|
+
REPO_MEMORY_DIR=""
|
|
28
|
+
REPO_MEMORY_FILE=""
|
|
29
|
+
REPO_MEMORY_STATUS="disabled"
|
|
30
|
+
|
|
31
|
+
init_repo_memory_paths
|
|
32
|
+
trap 'rm -rf "$TMP_DIR" "$REPO_MEMORY_DIR"' EXIT
|
|
33
|
+
rm -rf "$REPO_MEMORY_DIR"
|
|
34
|
+
mkdir -p "$REPO_MEMORY_DIR"
|
|
35
|
+
cat > "$REPO_MEMORY_FILE" <<'MEMORY'
|
|
36
|
+
# Repository Memory Summary
|
|
37
|
+
|
|
38
|
+
- Repo URL: https://example.com/acme/widgets.git
|
|
39
|
+
- Default ref: main
|
|
40
|
+
- Commit SHA: abc123
|
|
41
|
+
- Updated at: 2026-05-06T00:00:00Z
|
|
42
|
+
|
|
43
|
+
## Changed files
|
|
44
|
+
- src/widget.ts
|
|
45
|
+
MEMORY
|
|
46
|
+
|
|
47
|
+
prompt="$(build_agent_prompt)"
|
|
48
|
+
if ! grep -q 'Prior repository context (opt-in cache' <<< "$prompt"; then
|
|
49
|
+
printf 'Expected build_agent_prompt to append labeled repository memory.\n' >&2
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
if ! grep -q 'Commit SHA: abc123' <<< "$prompt"; then
|
|
53
|
+
printf 'Expected appended memory to include cached metadata.\n' >&2
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
touch -d '45 days ago' "$REPO_MEMORY_FILE"
|
|
58
|
+
expired_prompt="$(build_agent_prompt)"
|
|
59
|
+
if grep -q 'Commit SHA: abc123' <<< "$expired_prompt"; then
|
|
60
|
+
printf 'Expected expired repository memory to be omitted.\n' >&2
|
|
61
|
+
exit 1
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
mkdir -p /results
|
|
65
|
+
cat > /results/result-summary.md <<'SUMMARY'
|
|
66
|
+
# Kaseki Result: test
|
|
67
|
+
- Status: passed
|
|
68
|
+
- Secret scan: 0
|
|
69
|
+
- Task Prompt: do not persist this
|
|
70
|
+
SUMMARY
|
|
71
|
+
cat > /results/analysis.md <<'ANALYSIS'
|
|
72
|
+
Useful architecture note.
|
|
73
|
+
OPENROUTER_API_KEY=sk-or-should-not-persist
|
|
74
|
+
ANALYSIS
|
|
75
|
+
cat > /results/changed-files.txt <<'FILES'
|
|
76
|
+
src/widget.ts
|
|
77
|
+
tests/widget.test.ts
|
|
78
|
+
FILES
|
|
79
|
+
cat > /results/validation-timings.tsv <<'TIMINGS'
|
|
80
|
+
npm test 0 3
|
|
81
|
+
TIMINGS
|
|
82
|
+
|
|
83
|
+
STATUS=0
|
|
84
|
+
PI_EXIT=0
|
|
85
|
+
SECRET_SCAN_EXIT=0
|
|
86
|
+
KASEKI_TASK_MODE=patch
|
|
87
|
+
START_ISO="2026-05-06T12:00:00Z"
|
|
88
|
+
VALIDATION_EXIT=0
|
|
89
|
+
QUALITY_EXIT=0
|
|
90
|
+
write_repo_memory_summary
|
|
91
|
+
|
|
92
|
+
if grep -Eiq 'OPENROUTER|sk-or|Task Prompt|do not persist' "$REPO_MEMORY_FILE"; then
|
|
93
|
+
printf 'Expected repository memory writer to filter prompts and secrets.\n' >&2
|
|
94
|
+
exit 1
|
|
95
|
+
fi
|
|
96
|
+
if ! grep -q 'Useful architecture note' "$REPO_MEMORY_FILE"; then
|
|
97
|
+
printf 'Expected sanitized analysis note to be retained.\n' >&2
|
|
98
|
+
exit 1
|
|
99
|
+
fi
|
|
100
|
+
if ! grep -q 'npm test: exit 0, 3s' "$REPO_MEMORY_FILE"; then
|
|
101
|
+
printf 'Expected validation outcome to be summarized.\n' >&2
|
|
102
|
+
exit 1
|
|
103
|
+
fi
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Tests for allowlist restoration behavior in kaseki-agent.sh.
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
7
|
+
TMP_DIR="$(mktemp -d)"
|
|
8
|
+
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
9
|
+
|
|
10
|
+
# Load allowlist helper functions used by restore_disallowed_changes().
|
|
11
|
+
# shellcheck source=../scripts/allowlist-helper.sh
|
|
12
|
+
. "$ROOT_DIR/scripts/allowlist-helper.sh"
|
|
13
|
+
|
|
14
|
+
pass() { printf 'ā %s\n' "$1"; }
|
|
15
|
+
fail() { printf 'ā %s\n' "$1" >&2; exit 1; }
|
|
16
|
+
|
|
17
|
+
emit_event() {
|
|
18
|
+
printf '%s' "$1" >> "$TMP_DIR/results/events.log"
|
|
19
|
+
shift
|
|
20
|
+
while [ "$#" -gt 0 ]; do
|
|
21
|
+
printf ' %s' "$1" >> "$TMP_DIR/results/events.log"
|
|
22
|
+
shift
|
|
23
|
+
done
|
|
24
|
+
printf '\n' >> "$TMP_DIR/results/events.log"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
collect_git_artifacts() {
|
|
28
|
+
printf 'collect_git_artifacts should not be called when restored_count=0\n' >&2
|
|
29
|
+
return 1
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Load restore_disallowed_changes() while redirecting its container-only absolute
|
|
33
|
+
# paths into this test's temporary workspace.
|
|
34
|
+
eval "$(awk '
|
|
35
|
+
/^restore_disallowed_changes\(\)/ { emit=1 }
|
|
36
|
+
/^generate_restoration_report\(\)/ { emit=0 }
|
|
37
|
+
emit { print }
|
|
38
|
+
' "$ROOT_DIR/kaseki-agent.sh" | sed "s#/workspace/repo#$TMP_DIR/repo#g; s#/results#$TMP_DIR/results#g")"
|
|
39
|
+
|
|
40
|
+
mkdir -p "$TMP_DIR/results" "$TMP_DIR/repo"
|
|
41
|
+
{
|
|
42
|
+
cd "$TMP_DIR/repo"
|
|
43
|
+
git init --initial-branch=main -q
|
|
44
|
+
git config user.email "test@kaseki.local"
|
|
45
|
+
git config user.name "Test User"
|
|
46
|
+
printf 'original\n' > allowed.txt
|
|
47
|
+
git add allowed.txt
|
|
48
|
+
git commit -q -m "initial"
|
|
49
|
+
printf 'modified\n' > allowed.txt
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
printf 'allowed.txt\n' > "$TMP_DIR/results/changed-files.txt"
|
|
53
|
+
: > "$TMP_DIR/results/quality.log"
|
|
54
|
+
: > "$TMP_DIR/results/events.log"
|
|
55
|
+
|
|
56
|
+
KASEKI_RESTORE_DISALLOWED_CHANGES=1
|
|
57
|
+
KASEKI_CHANGED_FILES_ALLOWLIST='allowed.txt'
|
|
58
|
+
|
|
59
|
+
restore_disallowed_changes
|
|
60
|
+
|
|
61
|
+
if grep -Fq '[allowlist summary] Restored: 0 files; Kept: 1 files (coverage: 100%)' "$TMP_DIR/results/quality.log"; then
|
|
62
|
+
pass 'restore_disallowed_changes summarizes 0 restored / 1 kept with coverage under set -u'
|
|
63
|
+
else
|
|
64
|
+
fail 'restore_disallowed_changes did not write the expected 0 restored / 1 kept summary'
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
if grep -Fq 'allowlist_restoration_complete restored=0 kept=1 coverage=100' "$TMP_DIR/results/events.log"; then
|
|
68
|
+
pass 'restore_disallowed_changes emits completion event with computed coverage'
|
|
69
|
+
else
|
|
70
|
+
fail 'restore_disallowed_changes did not emit expected coverage event'
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if grep -Fxq 'COPY kaseki-agent.sh /usr/local/bin/kaseki-agent' "$ROOT_DIR/Dockerfile"; then
|
|
75
|
+
pass 'Docker image installs /usr/local/bin/kaseki-agent directly from repository kaseki-agent.sh'
|
|
76
|
+
else
|
|
77
|
+
fail 'Dockerfile must copy repository kaseki-agent.sh to /usr/local/bin/kaseki-agent'
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
printf '\nā
restore_disallowed_changes tests passed\n'
|