@kindgi/cli 0.0.0-bootstrap.0 → 0.1.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/LICENSE +201 -0
- package/README.md +738 -1
- package/dist/build/apt.d.ts +16 -0
- package/dist/build/apt.d.ts.map +1 -0
- package/dist/build/apt.js +50 -0
- package/dist/build/apt.js.map +1 -0
- package/dist/build/bundle.d.ts +48 -0
- package/dist/build/bundle.d.ts.map +1 -0
- package/dist/build/bundle.js +125 -0
- package/dist/build/bundle.js.map +1 -0
- package/dist/build/containerfile.d.ts +27 -0
- package/dist/build/containerfile.d.ts.map +1 -0
- package/dist/build/containerfile.js +197 -0
- package/dist/build/containerfile.js.map +1 -0
- package/dist/build/context-files.d.ts +24 -0
- package/dist/build/context-files.d.ts.map +1 -0
- package/dist/build/context-files.js +99 -0
- package/dist/build/context-files.js.map +1 -0
- package/dist/build/defaults.d.ts +66 -0
- package/dist/build/defaults.d.ts.map +1 -0
- package/dist/build/defaults.js +597 -0
- package/dist/build/defaults.js.map +1 -0
- package/dist/build/envelope.d.ts +72 -0
- package/dist/build/envelope.d.ts.map +1 -0
- package/dist/build/envelope.js +76 -0
- package/dist/build/envelope.js.map +1 -0
- package/dist/build/host-install.d.ts +100 -0
- package/dist/build/host-install.d.ts.map +1 -0
- package/dist/build/host-install.js +443 -0
- package/dist/build/host-install.js.map +1 -0
- package/dist/build/image-config.d.ts +32 -0
- package/dist/build/image-config.d.ts.map +1 -0
- package/dist/build/image-config.js +129 -0
- package/dist/build/image-config.js.map +1 -0
- package/dist/build/integrity.d.ts +51 -0
- package/dist/build/integrity.d.ts.map +1 -0
- package/dist/build/integrity.js +75 -0
- package/dist/build/integrity.js.map +1 -0
- package/dist/build/node-image.d.ts +18 -0
- package/dist/build/node-image.d.ts.map +1 -0
- package/dist/build/node-image.js +46 -0
- package/dist/build/node-image.js.map +1 -0
- package/dist/build/pack-root.d.ts +69 -0
- package/dist/build/pack-root.d.ts.map +1 -0
- package/dist/build/pack-root.js +102 -0
- package/dist/build/pack-root.js.map +1 -0
- package/dist/build/poetry-requirements.d.ts +5 -0
- package/dist/build/poetry-requirements.d.ts.map +1 -0
- package/dist/build/poetry-requirements.js +8 -0
- package/dist/build/poetry-requirements.js.map +1 -0
- package/dist/build/python-image.d.ts +40 -0
- package/dist/build/python-image.d.ts.map +1 -0
- package/dist/build/python-image.js +197 -0
- package/dist/build/python-image.js.map +1 -0
- package/dist/build/runners.d.ts +259 -0
- package/dist/build/runners.d.ts.map +1 -0
- package/dist/build/runners.js +4 -0
- package/dist/build/runners.js.map +1 -0
- package/dist/build/version-specifier.d.ts +2 -0
- package/dist/build/version-specifier.d.ts.map +1 -0
- package/dist/build/version-specifier.js +70 -0
- package/dist/build/version-specifier.js.map +1 -0
- package/dist/cli-package.d.ts +15 -0
- package/dist/cli-package.d.ts.map +1 -0
- package/dist/cli-package.js +37 -0
- package/dist/cli-package.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +26 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/adapters.d.ts +3 -0
- package/dist/commands/adapters.d.ts.map +1 -0
- package/dist/commands/adapters.js +148 -0
- package/dist/commands/adapters.js.map +1 -0
- package/dist/commands/agents.d.ts +3 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +82 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/approvals.d.ts +3 -0
- package/dist/commands/approvals.d.ts.map +1 -0
- package/dist/commands/approvals.js +92 -0
- package/dist/commands/approvals.js.map +1 -0
- package/dist/commands/artifacts.d.ts +3 -0
- package/dist/commands/artifacts.d.ts.map +1 -0
- package/dist/commands/artifacts.js +87 -0
- package/dist/commands/artifacts.js.map +1 -0
- package/dist/commands/auth.d.ts +25 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +283 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/build.d.ts +46 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +902 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/capabilities.d.ts +3 -0
- package/dist/commands/capabilities.d.ts.map +1 -0
- package/dist/commands/capabilities.js +38 -0
- package/dist/commands/capabilities.js.map +1 -0
- package/dist/commands/conversations.d.ts +3 -0
- package/dist/commands/conversations.d.ts.map +1 -0
- package/dist/commands/conversations.js +75 -0
- package/dist/commands/conversations.js.map +1 -0
- package/dist/commands/deploy.d.ts +7 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +697 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +43 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +1110 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/env.d.ts +27 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +816 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/feedback.d.ts +33 -0
- package/dist/commands/feedback.d.ts.map +1 -0
- package/dist/commands/feedback.js +374 -0
- package/dist/commands/feedback.js.map +1 -0
- package/dist/commands/flows.d.ts +3 -0
- package/dist/commands/flows.d.ts.map +1 -0
- package/dist/commands/flows.js +60 -0
- package/dist/commands/flows.js.map +1 -0
- package/dist/commands/guardrails.d.ts +3 -0
- package/dist/commands/guardrails.d.ts.map +1 -0
- package/dist/commands/guardrails.js +89 -0
- package/dist/commands/guardrails.js.map +1 -0
- package/dist/commands/health.d.ts +8 -0
- package/dist/commands/health.d.ts.map +1 -0
- package/dist/commands/health.js +40 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/helpers.d.ts +48 -0
- package/dist/commands/helpers.d.ts.map +1 -0
- package/dist/commands/helpers.js +110 -0
- package/dist/commands/helpers.js.map +1 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +90 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +46 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +454 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/key.d.ts +3 -0
- package/dist/commands/key.d.ts.map +1 -0
- package/dist/commands/key.js +322 -0
- package/dist/commands/key.js.map +1 -0
- package/dist/commands/mcp.d.ts +43 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +433 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/memory.d.ts +3 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +82 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/observations.d.ts +3 -0
- package/dist/commands/observations.d.ts.map +1 -0
- package/dist/commands/observations.js +27 -0
- package/dist/commands/observations.js.map +1 -0
- package/dist/commands/proposals.d.ts +3 -0
- package/dist/commands/proposals.d.ts.map +1 -0
- package/dist/commands/proposals.js +116 -0
- package/dist/commands/proposals.js.map +1 -0
- package/dist/commands/provenance.d.ts +3 -0
- package/dist/commands/provenance.d.ts.map +1 -0
- package/dist/commands/provenance.js +53 -0
- package/dist/commands/provenance.js.map +1 -0
- package/dist/commands/providers.d.ts +3 -0
- package/dist/commands/providers.d.ts.map +1 -0
- package/dist/commands/providers.js +212 -0
- package/dist/commands/providers.js.map +1 -0
- package/dist/commands/reviewers.d.ts +3 -0
- package/dist/commands/reviewers.d.ts.map +1 -0
- package/dist/commands/reviewers.js +78 -0
- package/dist/commands/reviewers.js.map +1 -0
- package/dist/commands/runs.d.ts +3 -0
- package/dist/commands/runs.d.ts.map +1 -0
- package/dist/commands/runs.js +223 -0
- package/dist/commands/runs.js.map +1 -0
- package/dist/commands/secrets.d.ts +18 -0
- package/dist/commands/secrets.d.ts.map +1 -0
- package/dist/commands/secrets.js +702 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/skills.d.ts +64 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +430 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/test.d.ts +5 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +181 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/tokens.d.ts +3 -0
- package/dist/commands/tokens.d.ts.map +1 -0
- package/dist/commands/tokens.js +33 -0
- package/dist/commands/tokens.js.map +1 -0
- package/dist/commands/tools.d.ts +3 -0
- package/dist/commands/tools.d.ts.map +1 -0
- package/dist/commands/tools.js +162 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commands/types.d.ts +54 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +4 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/unwired.d.ts +22 -0
- package/dist/commands/unwired.d.ts.map +1 -0
- package/dist/commands/unwired.js +52 -0
- package/dist/commands/unwired.js.map +1 -0
- package/dist/commands/version.d.ts +8 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +41 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/config.d.ts +42 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +83 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +162 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +45 -0
- package/dist/context.js.map +1 -0
- package/dist/deploy/defaults.d.ts +14 -0
- package/dist/deploy/defaults.d.ts.map +1 -0
- package/dist/deploy/defaults.js +37 -0
- package/dist/deploy/defaults.js.map +1 -0
- package/dist/deploy/envelope-loader.d.ts +24 -0
- package/dist/deploy/envelope-loader.d.ts.map +1 -0
- package/dist/deploy/envelope-loader.js +141 -0
- package/dist/deploy/envelope-loader.js.map +1 -0
- package/dist/deploy/post.d.ts +48 -0
- package/dist/deploy/post.d.ts.map +1 -0
- package/dist/deploy/post.js +210 -0
- package/dist/deploy/post.js.map +1 -0
- package/dist/deploy/response.d.ts +42 -0
- package/dist/deploy/response.d.ts.map +1 -0
- package/dist/deploy/response.js +128 -0
- package/dist/deploy/response.js.map +1 -0
- package/dist/deploy/runners.d.ts +218 -0
- package/dist/deploy/runners.d.ts.map +1 -0
- package/dist/deploy/runners.js +4 -0
- package/dist/deploy/runners.js.map +1 -0
- package/dist/dev/bundler.d.ts +10 -0
- package/dist/dev/bundler.d.ts.map +1 -0
- package/dist/dev/bundler.js +235 -0
- package/dist/dev/bundler.js.map +1 -0
- package/dist/dev/defaults.d.ts +140 -0
- package/dist/dev/defaults.d.ts.map +1 -0
- package/dist/dev/defaults.js +709 -0
- package/dist/dev/defaults.js.map +1 -0
- package/dist/dev/dev-only-imports.d.ts +15 -0
- package/dist/dev/dev-only-imports.d.ts.map +1 -0
- package/dist/dev/dev-only-imports.js +57 -0
- package/dist/dev/dev-only-imports.js.map +1 -0
- package/dist/dev/docker-compose.dev.yml +68 -0
- package/dist/dev/index-child.d.ts +2 -0
- package/dist/dev/index-child.d.ts.map +1 -0
- package/dist/dev/index-child.js +53 -0
- package/dist/dev/index-child.js.map +1 -0
- package/dist/dev/pack-code.d.ts +36 -0
- package/dist/dev/pack-code.d.ts.map +1 -0
- package/dist/dev/pack-code.js +129 -0
- package/dist/dev/pack-code.js.map +1 -0
- package/dist/dev/pack-env.d.ts +13 -0
- package/dist/dev/pack-env.d.ts.map +1 -0
- package/dist/dev/pack-env.js +36 -0
- package/dist/dev/pack-env.js.map +1 -0
- package/dist/dev/pack-service.d.ts +40 -0
- package/dist/dev/pack-service.d.ts.map +1 -0
- package/dist/dev/pack-service.js +189 -0
- package/dist/dev/pack-service.js.map +1 -0
- package/dist/dev/paths.d.ts +22 -0
- package/dist/dev/paths.d.ts.map +1 -0
- package/dist/dev/paths.js +35 -0
- package/dist/dev/paths.js.map +1 -0
- package/dist/dev/postgres-container.d.ts +77 -0
- package/dist/dev/postgres-container.d.ts.map +1 -0
- package/dist/dev/postgres-container.js +346 -0
- package/dist/dev/postgres-container.js.map +1 -0
- package/dist/dev/python-builder.d.ts +16 -0
- package/dist/dev/python-builder.d.ts.map +1 -0
- package/dist/dev/python-builder.js +122 -0
- package/dist/dev/python-builder.js.map +1 -0
- package/dist/dev/register.d.ts +71 -0
- package/dist/dev/register.d.ts.map +1 -0
- package/dist/dev/register.js +54 -0
- package/dist/dev/register.js.map +1 -0
- package/dist/dev/runners.d.ts +312 -0
- package/dist/dev/runners.d.ts.map +1 -0
- package/dist/dev/runners.js +4 -0
- package/dist/dev/runners.js.map +1 -0
- package/dist/dev/runtime-container.d.ts +71 -0
- package/dist/dev/runtime-container.d.ts.map +1 -0
- package/dist/dev/runtime-container.js +173 -0
- package/dist/dev/runtime-container.js.map +1 -0
- package/dist/dev/runtime-env.d.ts +62 -0
- package/dist/dev/runtime-env.d.ts.map +1 -0
- package/dist/dev/runtime-env.js +100 -0
- package/dist/dev/runtime-env.js.map +1 -0
- package/dist/dev/runtime-image.d.ts +26 -0
- package/dist/dev/runtime-image.d.ts.map +1 -0
- package/dist/dev/runtime-image.js +44 -0
- package/dist/dev/runtime-image.js.map +1 -0
- package/dist/dev/runtime-registry.d.ts +73 -0
- package/dist/dev/runtime-registry.d.ts.map +1 -0
- package/dist/dev/runtime-registry.js +111 -0
- package/dist/dev/runtime-registry.js.map +1 -0
- package/dist/env/defaults.d.ts +3 -0
- package/dist/env/defaults.d.ts.map +1 -0
- package/dist/env/defaults.js +22 -0
- package/dist/env/defaults.js.map +1 -0
- package/dist/env/pack-env-plan.d.ts +70 -0
- package/dist/env/pack-env-plan.d.ts.map +1 -0
- package/dist/env/pack-env-plan.js +236 -0
- package/dist/env/pack-env-plan.js.map +1 -0
- package/dist/env/parser.d.ts +9 -0
- package/dist/env/parser.d.ts.map +1 -0
- package/dist/env/parser.js +11 -0
- package/dist/env/parser.js.map +1 -0
- package/dist/env/project-env.d.ts +34 -0
- package/dist/env/project-env.d.ts.map +1 -0
- package/dist/env/project-env.js +45 -0
- package/dist/env/project-env.js.map +1 -0
- package/dist/env/runners.d.ts +22 -0
- package/dist/env/runners.d.ts.map +1 -0
- package/dist/env/runners.js +4 -0
- package/dist/env/runners.js.map +1 -0
- package/dist/env/writer.d.ts +7 -0
- package/dist/env/writer.d.ts.map +1 -0
- package/dist/env/writer.js +9 -0
- package/dist/env/writer.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +111 -0
- package/dist/errors.js.map +1 -0
- package/dist/help.d.ts +5 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +61 -0
- package/dist/help.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/init/augment-scaffolder.d.ts +86 -0
- package/dist/init/augment-scaffolder.d.ts.map +1 -0
- package/dist/init/augment-scaffolder.js +538 -0
- package/dist/init/augment-scaffolder.js.map +1 -0
- package/dist/init/dependency-specs.d.ts +58 -0
- package/dist/init/dependency-specs.d.ts.map +1 -0
- package/dist/init/dependency-specs.js +153 -0
- package/dist/init/dependency-specs.js.map +1 -0
- package/dist/init/gitignore-patcher.d.ts +23 -0
- package/dist/init/gitignore-patcher.d.ts.map +1 -0
- package/dist/init/gitignore-patcher.js +103 -0
- package/dist/init/gitignore-patcher.js.map +1 -0
- package/dist/init/mode-detect.d.ts +34 -0
- package/dist/init/mode-detect.d.ts.map +1 -0
- package/dist/init/mode-detect.js +115 -0
- package/dist/init/mode-detect.js.map +1 -0
- package/dist/init/package-json-patcher.d.ts +36 -0
- package/dist/init/package-json-patcher.d.ts.map +1 -0
- package/dist/init/package-json-patcher.js +128 -0
- package/dist/init/package-json-patcher.js.map +1 -0
- package/dist/init/pnpm-workspace-patcher.d.ts +55 -0
- package/dist/init/pnpm-workspace-patcher.d.ts.map +1 -0
- package/dist/init/pnpm-workspace-patcher.js +248 -0
- package/dist/init/pnpm-workspace-patcher.js.map +1 -0
- package/dist/init/pyproject-patcher.d.ts +56 -0
- package/dist/init/pyproject-patcher.d.ts.map +1 -0
- package/dist/init/pyproject-patcher.js +324 -0
- package/dist/init/pyproject-patcher.js.map +1 -0
- package/dist/init/python-augment.d.ts +22 -0
- package/dist/init/python-augment.d.ts.map +1 -0
- package/dist/init/python-augment.js +300 -0
- package/dist/init/python-augment.js.map +1 -0
- package/dist/init/template-files.d.ts +18 -0
- package/dist/init/template-files.d.ts.map +1 -0
- package/dist/init/template-files.js +53 -0
- package/dist/init/template-files.js.map +1 -0
- package/dist/key/defaults.d.ts +3 -0
- package/dist/key/defaults.d.ts.map +1 -0
- package/dist/key/defaults.js +60 -0
- package/dist/key/defaults.js.map +1 -0
- package/dist/key/fingerprint.d.ts +6 -0
- package/dist/key/fingerprint.d.ts.map +1 -0
- package/dist/key/fingerprint.js +25 -0
- package/dist/key/fingerprint.js.map +1 -0
- package/dist/key/paths.d.ts +30 -0
- package/dist/key/paths.d.ts.map +1 -0
- package/dist/key/paths.js +51 -0
- package/dist/key/paths.js.map +1 -0
- package/dist/key/runners.d.ts +60 -0
- package/dist/key/runners.d.ts.map +1 -0
- package/dist/key/runners.js +4 -0
- package/dist/key/runners.js.map +1 -0
- package/dist/main.d.ts +113 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +199 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/launcher.d.ts +143 -0
- package/dist/mcp/launcher.d.ts.map +1 -0
- package/dist/mcp/launcher.js +393 -0
- package/dist/mcp/launcher.js.map +1 -0
- package/dist/mcp/preset-loader.d.ts +29 -0
- package/dist/mcp/preset-loader.d.ts.map +1 -0
- package/dist/mcp/preset-loader.js +217 -0
- package/dist/mcp/preset-loader.js.map +1 -0
- package/dist/mcp/preset-types.d.ts +71 -0
- package/dist/mcp/preset-types.d.ts.map +1 -0
- package/dist/mcp/preset-types.js +4 -0
- package/dist/mcp/preset-types.js.map +1 -0
- package/dist/mcp/presets/README.md +68 -0
- package/dist/mcp/presets/postgres.json +15 -0
- package/dist/output.d.ts +26 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +46 -0
- package/dist/output.js.map +1 -0
- package/dist/pack-config.d.ts +37 -0
- package/dist/pack-config.d.ts.map +1 -0
- package/dist/pack-config.js +65 -0
- package/dist/pack-config.js.map +1 -0
- package/dist/package-manager.d.ts +33 -0
- package/dist/package-manager.d.ts.map +1 -0
- package/dist/package-manager.js +129 -0
- package/dist/package-manager.js.map +1 -0
- package/dist/parse.d.ts +88 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +100 -0
- package/dist/parse.js.map +1 -0
- package/dist/providers/preset-loader.d.ts +47 -0
- package/dist/providers/preset-loader.d.ts.map +1 -0
- package/dist/providers/preset-loader.js +107 -0
- package/dist/providers/preset-loader.js.map +1 -0
- package/dist/providers/presets/anthropic.json +47 -0
- package/dist/providers/presets/gemini.json +40 -0
- package/dist/reference.d.ts +28 -0
- package/dist/reference.d.ts.map +1 -0
- package/dist/reference.js +52 -0
- package/dist/reference.js.map +1 -0
- package/dist/sdk-package.d.ts +9 -0
- package/dist/sdk-package.d.ts.map +1 -0
- package/dist/sdk-package.js +20 -0
- package/dist/sdk-package.js.map +1 -0
- package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +252 -0
- package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +302 -0
- package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +297 -0
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +289 -0
- package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +705 -0
- package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +298 -0
- package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +211 -0
- package/dist/sdk-skills/kindgi-getting-started/SKILL.md +189 -0
- package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +205 -0
- package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +325 -0
- package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +176 -0
- package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +305 -0
- package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +242 -0
- package/dist/stop-signal.d.ts +15 -0
- package/dist/stop-signal.d.ts.map +1 -0
- package/dist/stop-signal.js +16 -0
- package/dist/stop-signal.js.map +1 -0
- package/dist/templates/minimal/.nvmrc +1 -0
- package/dist/templates/minimal/AGENTS.md +23 -0
- package/dist/templates/minimal/README.md.tmpl +69 -0
- package/dist/templates/minimal/agents/.gitkeep +0 -0
- package/dist/templates/minimal/flows/.gitkeep +0 -0
- package/dist/templates/minimal/gitignore +8 -0
- package/dist/templates/minimal/guardrails/.gitkeep +0 -0
- package/dist/templates/minimal/kindgi.config.ts.tmpl +44 -0
- package/dist/templates/minimal/package.json.tmpl +25 -0
- package/dist/templates/minimal/pnpm-workspace.yaml +8 -0
- package/dist/templates/minimal/tools/.gitkeep +0 -0
- package/dist/templates/minimal/tsconfig.json.tmpl +27 -0
- package/dist/templates/minimal/vitest.config.ts.tmpl +14 -0
- package/dist/templates/python/AGENTS.md +30 -0
- package/dist/templates/python/README.md.tmpl +56 -0
- package/dist/templates/python/agents/echo_agent.py.tmpl +23 -0
- package/dist/templates/python/flows/echo_flow.py.tmpl +17 -0
- package/dist/templates/python/gitignore +9 -0
- package/dist/templates/python/guardrails/response_not_empty.py.tmpl +27 -0
- package/dist/templates/python/pyproject.toml.tmpl +42 -0
- package/dist/templates/python/tests/test_tools.py.tmpl +22 -0
- package/dist/templates/python/tools/echo.py.tmpl +27 -0
- package/dist/templates/python/tools/greet.py.tmpl +20 -0
- package/dist/templates/sample/.nvmrc +1 -0
- package/dist/templates/sample/AGENTS.md +23 -0
- package/dist/templates/sample/README.md.tmpl +85 -0
- package/dist/templates/sample/agents/echo-agent/index.ts.tmpl +34 -0
- package/dist/templates/sample/flows/echo-flow/index.ts.tmpl +59 -0
- package/dist/templates/sample/gitignore +8 -0
- package/dist/templates/sample/guardrails/response-not-empty/index.ts.tmpl +58 -0
- package/dist/templates/sample/kindgi.config.ts.tmpl +41 -0
- package/dist/templates/sample/package.json.tmpl +25 -0
- package/dist/templates/sample/pnpm-workspace.yaml +8 -0
- package/dist/templates/sample/tools/echo/index.test.ts.tmpl +31 -0
- package/dist/templates/sample/tools/echo/index.ts.tmpl +37 -0
- package/dist/templates/sample/tools/fetch-httpbin/index.ts.tmpl +60 -0
- package/dist/templates/sample/tools/greet/index.ts.tmpl +35 -0
- package/dist/templates/sample/tsconfig.json.tmpl +27 -0
- package/dist/templates/sample/vitest.config.ts.tmpl +14 -0
- package/dist/terminal-input.d.ts +17 -0
- package/dist/terminal-input.d.ts.map +1 -0
- package/dist/terminal-input.js +88 -0
- package/dist/terminal-input.js.map +1 -0
- package/dist/test/defaults.d.ts +3 -0
- package/dist/test/defaults.d.ts.map +1 -0
- package/dist/test/defaults.js +104 -0
- package/dist/test/defaults.js.map +1 -0
- package/dist/test/runners.d.ts +60 -0
- package/dist/test/runners.d.ts.map +1 -0
- package/dist/test/runners.js +4 -0
- package/dist/test/runners.js.map +1 -0
- package/dist/version-info.d.ts +9 -0
- package/dist/version-info.d.ts.map +1 -0
- package/dist/version-info.js +27 -0
- package/dist/version-info.js.map +1 -0
- package/dist/write-fully.d.ts +13 -0
- package/dist/write-fully.d.ts.map +1 -0
- package/dist/write-fully.js +17 -0
- package/dist/write-fully.js.map +1 -0
- package/package.json +63 -4
|
@@ -0,0 +1,709 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
/**
|
|
4
|
+
* Production wiring for `kindgi dev` — the `DevRunners` implementation
|
|
5
|
+
* the CLI uses when no test override is present.
|
|
6
|
+
*
|
|
7
|
+
* `startApiServer` runs the Kindgi runtime as a container
|
|
8
|
+
* (`runtime-container.ts`), configured by `runtime.env`, with the pack
|
|
9
|
+
* directory mounted. `runIndexer` wraps
|
|
10
|
+
* `@kindgi/handler-runtime.runIndexer` + reads back the emitted
|
|
11
|
+
* `index.json`. `watchPack` wraps `node:fs.watch({ recursive: true })`
|
|
12
|
+
* on the four discovery folders with a caller-supplied debounce (default
|
|
13
|
+
* 200ms). All three are named + separated so the test seam swaps them
|
|
14
|
+
* individually.
|
|
15
|
+
*/
|
|
16
|
+
import { spawn } from 'node:child_process';
|
|
17
|
+
import { existsSync } from 'node:fs';
|
|
18
|
+
import { stat as fsStat, mkdir, readFile, rename, watch, writeFile } from 'node:fs/promises';
|
|
19
|
+
import { basename, dirname, join, sep } from 'node:path';
|
|
20
|
+
import { fileURLToPath } from 'node:url';
|
|
21
|
+
import { DEFAULT_DISCOVERY, PACK_ENV_CHECK_VAR, createGlobMatcher, discoveryRoots, runIndexer as runIndexerReal, } from '@kindgi/handler-runtime';
|
|
22
|
+
import { createPackServiceSupervisor } from '@kindgi/handler-runtime/pack-service';
|
|
23
|
+
import { createDevPackBuilder } from './bundler.js';
|
|
24
|
+
import { checkPackPython } from './pack-code.js';
|
|
25
|
+
import { devBundleMapPath, devIndexPath } from './paths.js';
|
|
26
|
+
import { hostPortOf, postgresSpecFromCompose, startPostgresContainer, } from './postgres-container.js';
|
|
27
|
+
import { createPythonPackBuilder } from './python-builder.js';
|
|
28
|
+
import { IMAGE_API_PORT, detectRuntimeNetwork, docker, ensureRuntimeImage, startRuntimeContainer, } from './runtime-container.js';
|
|
29
|
+
import { RUNTIME_GOOGLE_CREDENTIALS, RUNTIME_PACK_DIR, RUNTIME_PUBLIC_TOKEN_KEY, buildRuntimeEnv, runtimeEnvPath, shellReferencesOf, writeRuntimeEnv, } from './runtime-env.js';
|
|
30
|
+
const DEFAULT_DEBOUNCE_MS = 200;
|
|
31
|
+
/**
|
|
32
|
+
* Absolute path to `@kindgi/handler-runtime`'s pack-service entrypoint —
|
|
33
|
+
* the same process a deployment's pack image runs. `import.meta.resolve`
|
|
34
|
+
* because the package is ESM-only. Throws if unresolvable; that's a
|
|
35
|
+
* broken install, not a runtime fallback.
|
|
36
|
+
*/
|
|
37
|
+
function resolvePackServiceEntrypoint() {
|
|
38
|
+
return fileURLToPath(import.meta.resolve('@kindgi/handler-runtime/pack-service-main'));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The pack-service process for the pack's code: the Node pack service
|
|
42
|
+
* (loading the bundles in `.kindgi/dev/dist`, stack traces mapped back to
|
|
43
|
+
* the sources), or `python -m kindgi.pack serve` with the pack's Python.
|
|
44
|
+
*/
|
|
45
|
+
export function packServiceCommand(code) {
|
|
46
|
+
return code.language === 'python'
|
|
47
|
+
? [...code.python, '-m', 'kindgi.pack', 'serve']
|
|
48
|
+
: [process.execPath, '--enable-source-maps', resolvePackServiceEntrypoint()];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The pack service as a child process behind the supervisor's front. The
|
|
52
|
+
* runtime calls the front over HTTP, the same address however often the
|
|
53
|
+
* code is swapped (it retries while the front answers 503 mid-swap).
|
|
54
|
+
*/
|
|
55
|
+
export function createPackServiceReal(opts) {
|
|
56
|
+
return createPackServiceSupervisor({
|
|
57
|
+
command: packServiceCommand(opts.code),
|
|
58
|
+
moduleRoot: opts.packDir,
|
|
59
|
+
// A required env name the pack lacks is a warning in dev (the
|
|
60
|
+
// service still serves), not a refusal as in a deployment.
|
|
61
|
+
env: async () => ({ ...(await opts.env()), [PACK_ENV_CHECK_VAR]: 'warn' }),
|
|
62
|
+
onLog: opts.onLog,
|
|
63
|
+
onEvent: opts.onEvent,
|
|
64
|
+
...(opts.port !== undefined && { port: opts.port }),
|
|
65
|
+
...(opts.token !== undefined && { token: opts.token }),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** The builder for the pack's code: esbuild bundles (Node) or the sources (Python). */
|
|
69
|
+
export function createPackBuilderReal(opts) {
|
|
70
|
+
return opts.code.language === 'python'
|
|
71
|
+
? createPythonPackBuilder({ packDir: opts.packDir, python: opts.code.python, env: opts.env })
|
|
72
|
+
: createDevPackBuilder({
|
|
73
|
+
packDir: opts.packDir,
|
|
74
|
+
patterns: opts.patterns,
|
|
75
|
+
...(opts.configPath !== undefined && { configPath: opts.configPath }),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* `python -m kindgi.pack index` with the pack's Python and an environment,
|
|
80
|
+
* read back like the Node indexer's: the same one-line outcome, then the
|
|
81
|
+
* written index.
|
|
82
|
+
*/
|
|
83
|
+
export async function runPythonIndexer(opts) {
|
|
84
|
+
const [program, ...prefix] = opts.python;
|
|
85
|
+
const args = [
|
|
86
|
+
...prefix,
|
|
87
|
+
'-m',
|
|
88
|
+
'kindgi.pack',
|
|
89
|
+
'index',
|
|
90
|
+
'--pack-dir',
|
|
91
|
+
opts.packDir,
|
|
92
|
+
'--output',
|
|
93
|
+
opts.outputPath,
|
|
94
|
+
...(opts.artifactVersion !== undefined ? ['--artifact-version', opts.artifactVersion] : []),
|
|
95
|
+
...(opts.publishedAt !== undefined ? ['--published-at', opts.publishedAt] : []),
|
|
96
|
+
'--json',
|
|
97
|
+
];
|
|
98
|
+
return indexResultOf(outcomeOfChild(await runChild(program, args, opts.env)));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The indexer in a child process with the pack's environment, importing
|
|
102
|
+
* bundles (see `index-child.ts`). From source (tests) the child runs as
|
|
103
|
+
* TypeScript under Node's type stripping.
|
|
104
|
+
*/
|
|
105
|
+
async function runIndexerInChild(packDir, outputPath, env, bundleMap) {
|
|
106
|
+
const mapPath = devBundleMapPath(packDir);
|
|
107
|
+
await mkdir(dirname(mapPath), { recursive: true });
|
|
108
|
+
await writeFile(mapPath, JSON.stringify(bundleMap), 'utf8');
|
|
109
|
+
const fromSource = import.meta.url.endsWith('.ts');
|
|
110
|
+
const script = fileURLToPath(new URL(fromSource ? './index-child.ts' : './index-child.js', import.meta.url));
|
|
111
|
+
const args = [
|
|
112
|
+
'--enable-source-maps',
|
|
113
|
+
script,
|
|
114
|
+
'--pack',
|
|
115
|
+
packDir,
|
|
116
|
+
'--out',
|
|
117
|
+
outputPath,
|
|
118
|
+
'--bundle-map',
|
|
119
|
+
mapPath,
|
|
120
|
+
];
|
|
121
|
+
return outcomeOfChild(await runChild(process.execPath, args, await env()));
|
|
122
|
+
}
|
|
123
|
+
/** The outcome an indexer child printed as its last stdout line. */
|
|
124
|
+
function outcomeOfChild(run) {
|
|
125
|
+
const line = run.stdout.trim().split('\n').pop() ?? '';
|
|
126
|
+
try {
|
|
127
|
+
return JSON.parse(line);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
const detail = run.stderr.trim().split('\n').slice(-5).join(' | ');
|
|
131
|
+
return {
|
|
132
|
+
kind: 'err',
|
|
133
|
+
error: {
|
|
134
|
+
code: 'index-child-failed',
|
|
135
|
+
message: `The indexer process exited (${run.code}) without a result${detail.length > 0 ? `: ${detail}` : ''}`,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function runChild(command, args, env) {
|
|
141
|
+
return new Promise((resolvePromise) => {
|
|
142
|
+
const child = spawn(command, [...args], { env, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
143
|
+
let stdout = '';
|
|
144
|
+
let stderr = '';
|
|
145
|
+
child.stdout.on('data', (chunk) => {
|
|
146
|
+
stdout += chunk.toString('utf8');
|
|
147
|
+
});
|
|
148
|
+
child.stderr.on('data', (chunk) => {
|
|
149
|
+
stderr += chunk.toString('utf8');
|
|
150
|
+
});
|
|
151
|
+
child.once('error', (cause) => resolvePromise({ stdout, stderr: cause.message, code: null }));
|
|
152
|
+
child.once('close', (code) => resolvePromise({ stdout, stderr, code }));
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/** Swap the staged index in: the dev index changes in one step (a rename). */
|
|
156
|
+
export async function publishIndexReal(stagedPath, indexPath) {
|
|
157
|
+
await rename(stagedPath, indexPath);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The Kindgi runtime, as a container: pull the image if needed, write
|
|
161
|
+
* `runtime.env`, start it with the pack directory mounted, and wait until
|
|
162
|
+
* it serves. The runtime makes or loads its own public run token key;
|
|
163
|
+
* the developer's key file, if set, and their Google credentials are
|
|
164
|
+
* mounted read-only.
|
|
165
|
+
*/
|
|
166
|
+
export async function startApiServerContainerReal(opts) {
|
|
167
|
+
const progress = opts.onProgress ?? (() => undefined);
|
|
168
|
+
const network = await detectRuntimeNetwork();
|
|
169
|
+
const image = await ensureRuntimeImage(opts.runtimeImage, progress);
|
|
170
|
+
if (image.kind === 'error')
|
|
171
|
+
throw new Error(image.message);
|
|
172
|
+
const googleCredentials = googleCredentialsPath(opts.hostEnv);
|
|
173
|
+
const env = buildRuntimeEnv({
|
|
174
|
+
...(network === 'host-network'
|
|
175
|
+
? { apiPort: opts.port, apiHost: '127.0.0.1' }
|
|
176
|
+
: { apiPort: IMAGE_API_PORT, hostAlias: 'host.docker.internal' }),
|
|
177
|
+
packDir: RUNTIME_PACK_DIR,
|
|
178
|
+
databaseUrl: databaseUrlFrom(opts.databaseUrl, network),
|
|
179
|
+
tenantId: opts.tenantId,
|
|
180
|
+
token: opts.token,
|
|
181
|
+
seedUserId: opts.userId,
|
|
182
|
+
packService: opts.packService,
|
|
183
|
+
...(opts.localEnvFiles !== undefined && { localEnvFiles: opts.localEnvFiles }),
|
|
184
|
+
corsOrigins: opts.corsOrigins ?? [],
|
|
185
|
+
...(opts.publicRunTokenKeyPath !== undefined && {
|
|
186
|
+
publicTokenKeyPath: RUNTIME_PUBLIC_TOKEN_KEY,
|
|
187
|
+
}),
|
|
188
|
+
...(googleCredentials !== undefined && { googleCredentialsPath: RUNTIME_GOOGLE_CREDENTIALS }),
|
|
189
|
+
shellReferences: await shellReferencesOf({
|
|
190
|
+
packDir: opts.packDir,
|
|
191
|
+
...(opts.localEnvFiles !== undefined && { localEnvFiles: opts.localEnvFiles }),
|
|
192
|
+
shellEnv: opts.hostEnv,
|
|
193
|
+
}),
|
|
194
|
+
});
|
|
195
|
+
const envFile = runtimeEnvPath(opts.packDir);
|
|
196
|
+
await writeRuntimeEnv(envFile, env);
|
|
197
|
+
const runtime = await startRuntimeContainer({
|
|
198
|
+
image: opts.runtimeImage,
|
|
199
|
+
packDir: opts.packDir,
|
|
200
|
+
envFile,
|
|
201
|
+
network,
|
|
202
|
+
hostPort: opts.port,
|
|
203
|
+
...(googleCredentials !== undefined && { googleCredentials }),
|
|
204
|
+
...(opts.publicRunTokenKeyPath !== undefined && {
|
|
205
|
+
publicTokenKey: opts.publicRunTokenKeyPath,
|
|
206
|
+
}),
|
|
207
|
+
onLog: opts.onLog ?? (() => undefined),
|
|
208
|
+
});
|
|
209
|
+
try {
|
|
210
|
+
const project = await fetch(`${runtime.baseUrl}/v1/projects/default`, {
|
|
211
|
+
headers: { authorization: `Bearer ${opts.token}` },
|
|
212
|
+
});
|
|
213
|
+
const body = (await project.json());
|
|
214
|
+
if (!project.ok || typeof body.id !== 'string') {
|
|
215
|
+
throw new Error(`the runtime has no default project (${project.status})`);
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
baseUrl: runtime.baseUrl,
|
|
219
|
+
port: opts.port,
|
|
220
|
+
tenantId: opts.tenantId,
|
|
221
|
+
userId: opts.userId,
|
|
222
|
+
defaultProjectId: body.id,
|
|
223
|
+
token: opts.token,
|
|
224
|
+
banner: runtime.banner,
|
|
225
|
+
consoleMounted: true,
|
|
226
|
+
shutdown: () => runtime.stop(),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
await runtime.stop();
|
|
231
|
+
throw err;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* A runtime the developer runs themselves (`--runtime-url`), typically
|
|
236
|
+
* from source: write `runtime.env` with this machine's paths (the server
|
|
237
|
+
* binds loopback, no alias), then wait until the runtime at the URL
|
|
238
|
+
* serves and takes this session's dev token. Its lifetime isn't ours:
|
|
239
|
+
* `shutdown` leaves it running.
|
|
240
|
+
*/
|
|
241
|
+
export async function attachToRuntimeReal(opts) {
|
|
242
|
+
const progress = opts.onProgress ?? (() => undefined);
|
|
243
|
+
const url = new URL(opts.runtimeUrl);
|
|
244
|
+
const baseUrl = url.origin;
|
|
245
|
+
const port = Number(url.port || (url.protocol === 'https:' ? 443 : 80));
|
|
246
|
+
const googleCredentials = googleCredentialsPath(opts.hostEnv);
|
|
247
|
+
const envFile = runtimeEnvPath(opts.packDir);
|
|
248
|
+
await writeRuntimeEnv(envFile, buildRuntimeEnv({
|
|
249
|
+
apiPort: port,
|
|
250
|
+
apiHost: '127.0.0.1',
|
|
251
|
+
packDir: opts.packDir,
|
|
252
|
+
databaseUrl: opts.databaseUrl,
|
|
253
|
+
tenantId: opts.tenantId,
|
|
254
|
+
token: opts.token,
|
|
255
|
+
seedUserId: opts.userId,
|
|
256
|
+
packService: opts.packService,
|
|
257
|
+
...(opts.localEnvFiles !== undefined && { localEnvFiles: opts.localEnvFiles }),
|
|
258
|
+
corsOrigins: opts.corsOrigins ?? [],
|
|
259
|
+
...(opts.publicRunTokenKeyPath !== undefined && {
|
|
260
|
+
publicTokenKeyPath: opts.publicRunTokenKeyPath,
|
|
261
|
+
}),
|
|
262
|
+
...(googleCredentials !== undefined && { googleCredentialsPath: googleCredentials }),
|
|
263
|
+
shellReferences: await shellReferencesOf({
|
|
264
|
+
packDir: opts.packDir,
|
|
265
|
+
...(opts.localEnvFiles !== undefined && { localEnvFiles: opts.localEnvFiles }),
|
|
266
|
+
shellEnv: opts.hostEnv,
|
|
267
|
+
}),
|
|
268
|
+
}));
|
|
269
|
+
progress(`Waiting for the Kindgi runtime at ${baseUrl}.`);
|
|
270
|
+
progress(` Start it with the settings in ${envFile} as its environment.`);
|
|
271
|
+
const deadline = Date.now() + 10 * 60_000;
|
|
272
|
+
let project;
|
|
273
|
+
for (;;) {
|
|
274
|
+
const healthy = await fetch(`${baseUrl}/health`, { signal: AbortSignal.timeout(2_000) })
|
|
275
|
+
.then((r) => r.ok)
|
|
276
|
+
.catch(() => false);
|
|
277
|
+
if (healthy) {
|
|
278
|
+
project = await fetch(`${baseUrl}/v1/projects/default`, {
|
|
279
|
+
headers: { authorization: `Bearer ${opts.token}` },
|
|
280
|
+
});
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
if (Date.now() > deadline) {
|
|
284
|
+
throw new Error(`nothing served at ${baseUrl} within 10 minutes`);
|
|
285
|
+
}
|
|
286
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
287
|
+
}
|
|
288
|
+
const body = (await project.json().catch(() => ({})));
|
|
289
|
+
if (!project.ok || typeof body.id !== 'string') {
|
|
290
|
+
throw new Error(`the runtime at ${baseUrl} doesn't take this session's dev token (${project.status}): start it with the settings in ${envFile}`);
|
|
291
|
+
}
|
|
292
|
+
const consoleServed = await fetch(`${baseUrl}/console/`)
|
|
293
|
+
.then((r) => r.ok)
|
|
294
|
+
.catch(() => false);
|
|
295
|
+
return {
|
|
296
|
+
baseUrl,
|
|
297
|
+
port,
|
|
298
|
+
tenantId: opts.tenantId,
|
|
299
|
+
userId: opts.userId,
|
|
300
|
+
defaultProjectId: body.id,
|
|
301
|
+
token: opts.token,
|
|
302
|
+
banner: '',
|
|
303
|
+
consoleMounted: consoleServed,
|
|
304
|
+
shutdown: async () => undefined,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/** The runtime `kindgi dev` talks to: a container, or the developer's own (`--runtime-url`). */
|
|
308
|
+
export function startApiServerReal(opts) {
|
|
309
|
+
return opts.runtimeUrl !== undefined
|
|
310
|
+
? attachToRuntimeReal({ ...opts, runtimeUrl: opts.runtimeUrl })
|
|
311
|
+
: startApiServerContainerReal(opts);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Postgres as the container reaches it. Through the alias the container
|
|
315
|
+
* can't see the host's loopback, and a database connection isn't HTTP
|
|
316
|
+
* (the runtime's alias covers HTTP only), so a loopback host becomes
|
|
317
|
+
* `host.docker.internal` here.
|
|
318
|
+
*/
|
|
319
|
+
export function databaseUrlFrom(url, network) {
|
|
320
|
+
if (network === 'host-network')
|
|
321
|
+
return url;
|
|
322
|
+
const parsed = new URL(url);
|
|
323
|
+
const host = parsed.hostname.replace(/^\[(.*)\]$/, '$1');
|
|
324
|
+
if (host === 'localhost' || host === '::1' || host.startsWith('127.')) {
|
|
325
|
+
parsed.hostname = 'host.docker.internal';
|
|
326
|
+
}
|
|
327
|
+
return parsed.toString();
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* The developer's Google Application Default Credentials, mounted
|
|
331
|
+
* read-only (Kindgi keeps no key files of its own): `GOOGLE_APPLICATION_CREDENTIALS`
|
|
332
|
+
* if set, else the file `gcloud auth application-default login` writes.
|
|
333
|
+
*/
|
|
334
|
+
export function googleCredentialsPath(hostEnv) {
|
|
335
|
+
const explicit = hostEnv.GOOGLE_APPLICATION_CREDENTIALS;
|
|
336
|
+
if (explicit !== undefined && explicit !== '' && existsSync(explicit))
|
|
337
|
+
return explicit;
|
|
338
|
+
const home = hostEnv.HOME;
|
|
339
|
+
if (home === undefined || home === '')
|
|
340
|
+
return undefined;
|
|
341
|
+
const adc = join(home, '.config', 'gcloud', 'application_default_credentials.json');
|
|
342
|
+
return existsSync(adc) ? adc : undefined;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Run the indexer against a pack root. `runIndexer` writes an
|
|
346
|
+
* `index.json` on the pack root by default; we tolerate the write and
|
|
347
|
+
* read the bytes back so callers get the parsed manifest without a
|
|
348
|
+
* second walk. Failures are captured as typed `IndexFailure` — the
|
|
349
|
+
* function never throws.
|
|
350
|
+
*/
|
|
351
|
+
export async function runIndexerReadReal(packDir, outputPath = devIndexPath(packDir), options = {}) {
|
|
352
|
+
const code = options.code;
|
|
353
|
+
if (code?.language === 'python') {
|
|
354
|
+
return runPythonIndexer({
|
|
355
|
+
packDir,
|
|
356
|
+
outputPath,
|
|
357
|
+
python: code.python,
|
|
358
|
+
env: options.env !== undefined ? await options.env() : {},
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
return indexResultOf(options.env !== undefined
|
|
362
|
+
? await runIndexerInChild(packDir, outputPath, options.env, options.bundleMap ?? {})
|
|
363
|
+
: await runIndexerReal({ packDir, outputPath }));
|
|
364
|
+
}
|
|
365
|
+
/** An indexer outcome as `kindgi` reports it: counts, file errors and the written index. */
|
|
366
|
+
async function indexResultOf(outcome) {
|
|
367
|
+
if (outcome.kind === 'err') {
|
|
368
|
+
const err = outcome.error;
|
|
369
|
+
return {
|
|
370
|
+
kind: 'err',
|
|
371
|
+
code: err.code,
|
|
372
|
+
message: err.message,
|
|
373
|
+
...(err.filePath !== undefined && { filePath: err.filePath }),
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
const report = outcome.value;
|
|
377
|
+
let index;
|
|
378
|
+
try {
|
|
379
|
+
const raw = await readFile(report.outputPath, 'utf8');
|
|
380
|
+
index = JSON.parse(raw);
|
|
381
|
+
}
|
|
382
|
+
catch (readErr) {
|
|
383
|
+
return {
|
|
384
|
+
kind: 'err',
|
|
385
|
+
code: 'index-read-failed',
|
|
386
|
+
message: `Indexer succeeded but reading ${report.outputPath} failed: ${readErr.message}`,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
return {
|
|
390
|
+
kind: 'ok',
|
|
391
|
+
packId: report.packId,
|
|
392
|
+
packVersion: report.packVersion,
|
|
393
|
+
counts: report.counts,
|
|
394
|
+
fileErrors: report.fileErrors.map((e) => ({
|
|
395
|
+
code: e.code,
|
|
396
|
+
message: e.message,
|
|
397
|
+
...(e.filePath !== undefined && { filePath: e.filePath }),
|
|
398
|
+
})),
|
|
399
|
+
index,
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Watch the pack's discovery patterns for changes. Watches each
|
|
404
|
+
* pattern's static prefix (`kindgi/tools` for `kindgi/tools/**\/*.ts`) —
|
|
405
|
+
* never the whole host repo when the pack is embedded in an app — and
|
|
406
|
+
* fires only for paths a pattern matches, so the indexer's own output
|
|
407
|
+
* and unrelated files never trigger a re-index. `patterns` defaults to
|
|
408
|
+
* the indexer's `DEFAULT_DISCOVERY`.
|
|
409
|
+
*
|
|
410
|
+
* Uses `node:fs.watch({ recursive: true })` — dependency-free; on
|
|
411
|
+
* macOS + Linux this delivers reliable change events. Windows behavior
|
|
412
|
+
* is a known-good path per the Node docs but not exercised in CI.
|
|
413
|
+
*
|
|
414
|
+
* A single debounce timer is shared across every event → the callback
|
|
415
|
+
* fires at most once per debounce window. Roots that don't exist yet
|
|
416
|
+
* are skipped.
|
|
417
|
+
*/
|
|
418
|
+
export async function watchPackReal(packDir, onChange, opts = {}) {
|
|
419
|
+
const debounceMs = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
420
|
+
const patterns = opts.patterns ?? Object.values(DEFAULT_DISCOVERY);
|
|
421
|
+
const matches = createGlobMatcher(patterns);
|
|
422
|
+
const controllers = [];
|
|
423
|
+
const watchers = [];
|
|
424
|
+
let closed = false;
|
|
425
|
+
let timer;
|
|
426
|
+
const fire = () => {
|
|
427
|
+
if (closed)
|
|
428
|
+
return;
|
|
429
|
+
if (timer !== undefined)
|
|
430
|
+
clearTimeout(timer);
|
|
431
|
+
timer = setTimeout(() => {
|
|
432
|
+
timer = undefined;
|
|
433
|
+
if (closed)
|
|
434
|
+
return;
|
|
435
|
+
try {
|
|
436
|
+
onChange();
|
|
437
|
+
}
|
|
438
|
+
catch {
|
|
439
|
+
// onChange is caller-owned; swallow to keep the watcher alive.
|
|
440
|
+
}
|
|
441
|
+
}, debounceMs);
|
|
442
|
+
};
|
|
443
|
+
for (const root of discoveryRoots(patterns)) {
|
|
444
|
+
const abs = root === '' ? packDir : join(packDir, root);
|
|
445
|
+
if (!(await isDirectory(abs)))
|
|
446
|
+
continue;
|
|
447
|
+
const controller = new AbortController();
|
|
448
|
+
controllers.push(controller);
|
|
449
|
+
watchers.push(consumeWatch(abs, root, controller.signal, matches, fire, () => closed));
|
|
450
|
+
}
|
|
451
|
+
// Single files (the env files): watch each one's directory, not
|
|
452
|
+
// recursively, and fire for that name only — so an env file that
|
|
453
|
+
// doesn't exist yet counts once it's created.
|
|
454
|
+
for (const [dir, names] of filesByDirectory(opts.files ?? [])) {
|
|
455
|
+
if (!(await isDirectory(dir)))
|
|
456
|
+
continue;
|
|
457
|
+
const controller = new AbortController();
|
|
458
|
+
controllers.push(controller);
|
|
459
|
+
watchers.push(consumeFileWatch(dir, names, controller.signal, fire, () => closed));
|
|
460
|
+
}
|
|
461
|
+
return {
|
|
462
|
+
async close() {
|
|
463
|
+
if (closed)
|
|
464
|
+
return;
|
|
465
|
+
closed = true;
|
|
466
|
+
if (timer !== undefined)
|
|
467
|
+
clearTimeout(timer);
|
|
468
|
+
for (const c of controllers) {
|
|
469
|
+
try {
|
|
470
|
+
c.abort();
|
|
471
|
+
}
|
|
472
|
+
catch {
|
|
473
|
+
// Older Node builds may throw synchronously — ignore.
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
await Promise.allSettled(watchers);
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
async function isDirectory(path) {
|
|
481
|
+
try {
|
|
482
|
+
return (await fsStat(path)).isDirectory();
|
|
483
|
+
}
|
|
484
|
+
catch {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function filesByDirectory(files) {
|
|
489
|
+
const byDir = new Map();
|
|
490
|
+
for (const file of files) {
|
|
491
|
+
const names = byDir.get(dirname(file)) ?? new Set();
|
|
492
|
+
names.add(basename(file));
|
|
493
|
+
byDir.set(dirname(file), names);
|
|
494
|
+
}
|
|
495
|
+
return byDir;
|
|
496
|
+
}
|
|
497
|
+
/** Consume one directory watch in the background, firing for `names` only. */
|
|
498
|
+
async function consumeFileWatch(dir, names, signal, fire, isClosed) {
|
|
499
|
+
try {
|
|
500
|
+
for await (const evt of watch(dir, { signal })) {
|
|
501
|
+
if (evt.filename !== null && evt.filename !== undefined && names.has(evt.filename))
|
|
502
|
+
fire();
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
catch (err) {
|
|
506
|
+
const code = err.code;
|
|
507
|
+
if (code !== 'ABORT_ERR' && code !== 'ERR_ABORT' && !isClosed())
|
|
508
|
+
fire();
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Consume one recursive watch in the background. An event fires only
|
|
513
|
+
* when its path (relative to the pack root) matches a discovery
|
|
514
|
+
* pattern; an event without a filename fires conservatively.
|
|
515
|
+
*/
|
|
516
|
+
/** An event named after the watched folder itself, for no child of that name. */
|
|
517
|
+
function isRootEcho(abs, filename) {
|
|
518
|
+
return filename === basename(abs) && !existsSync(join(abs, filename));
|
|
519
|
+
}
|
|
520
|
+
/** A path whose last segment has no extension: a folder (or one that was there). */
|
|
521
|
+
function isFolderName(relPath) {
|
|
522
|
+
const last = relPath.split('/').at(-1) ?? '';
|
|
523
|
+
return last !== '' && !last.includes('.');
|
|
524
|
+
}
|
|
525
|
+
async function consumeWatch(abs, root, signal, matches, fire, isClosed) {
|
|
526
|
+
try {
|
|
527
|
+
for await (const evt of watch(abs, { recursive: true, signal })) {
|
|
528
|
+
if (evt.filename === null || evt.filename === undefined) {
|
|
529
|
+
fire();
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
const rel = [root, evt.filename.split(sep).join('/')].filter((p) => p !== '').join('/');
|
|
533
|
+
// A folder moved in or out (an editor's delete moves it to the
|
|
534
|
+
// trash) is one event for the folder, not one per file: fire for
|
|
535
|
+
// those too. The callback re-collects the entries and does nothing
|
|
536
|
+
// when they didn't change. macOS also reports the watched folder's
|
|
537
|
+
// own creation, named after it; that one isn't a primitive folder.
|
|
538
|
+
if (matches(rel))
|
|
539
|
+
fire();
|
|
540
|
+
else if (isFolderName(rel) && !isRootEcho(abs, evt.filename))
|
|
541
|
+
fire();
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
catch (err) {
|
|
545
|
+
// AbortError is expected on close(); anything else is a real
|
|
546
|
+
// filesystem failure we surface via a synthetic change so the
|
|
547
|
+
// command's re-index reports it.
|
|
548
|
+
const code = err.code;
|
|
549
|
+
if (code !== 'ABORT_ERR' && code !== 'ERR_ABORT' && !isClosed())
|
|
550
|
+
fire();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
// -----------------------------------------------------------------------------
|
|
554
|
+
// Auto-start services (`kindgi dev` — no KINDGI_DATABASE_URL set path)
|
|
555
|
+
// -----------------------------------------------------------------------------
|
|
556
|
+
/**
|
|
557
|
+
* Absolute path to the bundled `docker-compose.dev.yml` shipped with
|
|
558
|
+
* `@kindgi/cli`. Resolved from `import.meta.url` so it works both when
|
|
559
|
+
* loaded from `dist/` in a published package and from `src/` during
|
|
560
|
+
* development.
|
|
561
|
+
*/
|
|
562
|
+
function bundledComposeFilePath() {
|
|
563
|
+
// `import.meta.url` here resolves to `dist/dev/defaults.js` (built)
|
|
564
|
+
// or `src/dev/defaults.ts` (dev). The compose file lives alongside
|
|
565
|
+
// this module in both locations.
|
|
566
|
+
return fileURLToPath(new URL('./docker-compose.dev.yml', import.meta.url));
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Detect whether `docker compose` is invokable. Returns `undefined`
|
|
570
|
+
* when available; a human-readable reason otherwise. Used to decide
|
|
571
|
+
* between `docker compose` and plain `docker` for the bundled services.
|
|
572
|
+
*/
|
|
573
|
+
async function detectDockerCompose(run) {
|
|
574
|
+
const version = await run(['compose', 'version']);
|
|
575
|
+
if (version.code === 0)
|
|
576
|
+
return undefined;
|
|
577
|
+
if (version.code === null)
|
|
578
|
+
return `docker CLI not available: ${version.stderr}`;
|
|
579
|
+
return `\`docker compose version\` exited with code ${version.code}`;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Whether plain `docker` works: the CLI is installed and the engine
|
|
583
|
+
* answers. Returns `undefined` when it does; why not otherwise.
|
|
584
|
+
*/
|
|
585
|
+
async function detectDocker(run) {
|
|
586
|
+
const version = await run(['version', '--format', '{{.Server.Version}}']);
|
|
587
|
+
if (version.code === 0)
|
|
588
|
+
return undefined;
|
|
589
|
+
const detail = version.stderr.trim().split('\n').at(-1) ?? '';
|
|
590
|
+
return `Docker isn't available${detail === '' ? '' : `: ${detail}`}`;
|
|
591
|
+
}
|
|
592
|
+
/** The compose project every `kindgi dev` shares; its named volumes hold the dev data. */
|
|
593
|
+
const COMPOSE_PROJECT = 'kindgi-dev';
|
|
594
|
+
/** The services `up --wait` waits on: Postgres only (OpenFGA and MinIO aren't wired in dev). */
|
|
595
|
+
const LONG_RUNNING_SERVICES = ['postgres'];
|
|
596
|
+
/** Run `docker compose` against the bundled compose file, in the `kindgi-dev` project. */
|
|
597
|
+
function compose(run, args) {
|
|
598
|
+
return run(['compose', '-f', bundledComposeFilePath(), '-p', COMPOSE_PROJECT, ...args]);
|
|
599
|
+
}
|
|
600
|
+
function composeFailure(step, outcome) {
|
|
601
|
+
const detail = outcome.stderr.trim().split('\n').slice(-5).join('\n');
|
|
602
|
+
return `\`docker compose ${step}\` failed (exit ${outcome.code ?? 'spawn error'})${detail === '' ? '' : `: ${detail}`}`;
|
|
603
|
+
}
|
|
604
|
+
/** The bundled Postgres's URL, on this machine, at its published host port. */
|
|
605
|
+
function bundledDatabaseUrl(port) {
|
|
606
|
+
return `postgres://kindgi:kindgi_dev_only@127.0.0.1:${port}/kindgi?sslmode=disable`;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Boot the bundled services with plain `docker compose`, in the
|
|
610
|
+
* `kindgi-dev` project:
|
|
611
|
+
*
|
|
612
|
+
* 1. `up -d --wait` Postgres, which waits for its healthcheck;
|
|
613
|
+
* 2. read its published port back.
|
|
614
|
+
*
|
|
615
|
+
* Without compose (a Docker engine without the plugin), the same
|
|
616
|
+
* Postgres starts with plain `docker` (`postgres-container.ts`): the
|
|
617
|
+
* same names, so the data is shared whichever way it was started.
|
|
618
|
+
* `unavailable` only when docker itself doesn't work.
|
|
619
|
+
*
|
|
620
|
+
* Not testcontainers: its reaper (Ryuk) is handed the compose project
|
|
621
|
+
* and, when the process exits, deletes everything labelled with it —
|
|
622
|
+
* the named volumes too — so every restart came up empty. The data in
|
|
623
|
+
* the named volumes now survives `kindgi dev` restarts, as the
|
|
624
|
+
* monorepo's own dev services do (`docker compose up -d --wait`).
|
|
625
|
+
* Every `kindgi dev` on the machine shares them, so nothing here removes
|
|
626
|
+
* them; to wipe all dev data, `docker compose -p kindgi-dev down -v`.
|
|
627
|
+
* Containers left running by a killed `kindgi dev` are picked up by the
|
|
628
|
+
* next boot.
|
|
629
|
+
*/
|
|
630
|
+
export async function startServicesReal(options, run = docker) {
|
|
631
|
+
const reason = await detectDockerCompose(run);
|
|
632
|
+
if (reason !== undefined) {
|
|
633
|
+
const noDocker = await detectDocker(run);
|
|
634
|
+
if (noDocker !== undefined)
|
|
635
|
+
return { kind: 'unavailable', reason: noDocker };
|
|
636
|
+
return startPostgresWithDocker(options, run);
|
|
637
|
+
}
|
|
638
|
+
// An existing container is reused as it is unless asked: recreating it
|
|
639
|
+
// (a changed definition) drops every other kindgi dev's connection.
|
|
640
|
+
const up = await compose(run, [
|
|
641
|
+
'up',
|
|
642
|
+
'-d',
|
|
643
|
+
'--wait',
|
|
644
|
+
...(options.recreate ? [] : ['--no-recreate']),
|
|
645
|
+
...LONG_RUNNING_SERVICES,
|
|
646
|
+
]);
|
|
647
|
+
if (up.code !== 0)
|
|
648
|
+
return { kind: 'error', message: composeFailure('up', up) };
|
|
649
|
+
const published = await compose(run, ['port', 'postgres', '5432']);
|
|
650
|
+
const port = published.code === 0 ? hostPortOf(published.stdout) : undefined;
|
|
651
|
+
if (port === undefined) {
|
|
652
|
+
return { kind: 'error', message: composeFailure('port postgres 5432', published) };
|
|
653
|
+
}
|
|
654
|
+
const handle = {
|
|
655
|
+
databaseUrl: bundledDatabaseUrl(port),
|
|
656
|
+
services: ['postgres'],
|
|
657
|
+
startedWith: 'docker compose',
|
|
658
|
+
};
|
|
659
|
+
return { kind: 'ok', handle };
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* The bundled Postgres with plain `docker`, as the compose file defines
|
|
663
|
+
* it. An existing container is reused as it is, so `--recreate-services`
|
|
664
|
+
* (a compose feature) can't apply: the developer is told how to recreate
|
|
665
|
+
* it by hand.
|
|
666
|
+
*/
|
|
667
|
+
async function startPostgresWithDocker(options, run) {
|
|
668
|
+
let spec;
|
|
669
|
+
try {
|
|
670
|
+
spec = postgresSpecFromCompose(await readFile(bundledComposeFilePath(), 'utf8'), COMPOSE_PROJECT);
|
|
671
|
+
}
|
|
672
|
+
catch (err) {
|
|
673
|
+
return { kind: 'error', message: err.message };
|
|
674
|
+
}
|
|
675
|
+
const started = await startPostgresContainer(spec, run);
|
|
676
|
+
if (started.kind === 'error')
|
|
677
|
+
return started;
|
|
678
|
+
const notes = options.recreate && started.container !== 'created'
|
|
679
|
+
? [
|
|
680
|
+
`--recreate-services needs docker compose: the existing ${spec.name} is reused as it is. To recreate it, remove it (docker rm -f ${spec.name}; its data stays in the ${spec.volume.name} volume) and run kindgi dev again.`,
|
|
681
|
+
]
|
|
682
|
+
: [];
|
|
683
|
+
return {
|
|
684
|
+
kind: 'ok',
|
|
685
|
+
handle: {
|
|
686
|
+
databaseUrl: bundledDatabaseUrl(started.port),
|
|
687
|
+
services: ['postgres'],
|
|
688
|
+
startedWith: 'docker',
|
|
689
|
+
...(notes.length > 0 && { notes }),
|
|
690
|
+
},
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
/** Default wiring used by the `kindgi dev` command in production. */
|
|
694
|
+
export const REAL_DEV_RUNNERS = {
|
|
695
|
+
startApiServer: startApiServerReal,
|
|
696
|
+
runIndexer: runIndexerReadReal,
|
|
697
|
+
createPackBuilder: createPackBuilderReal,
|
|
698
|
+
createPackService: createPackServiceReal,
|
|
699
|
+
checkPackPython,
|
|
700
|
+
publishIndex: publishIndexReal,
|
|
701
|
+
watchPack: watchPackReal,
|
|
702
|
+
startServices: startServicesReal,
|
|
703
|
+
};
|
|
704
|
+
// Named re-export for tests that want to poke a single seam.
|
|
705
|
+
export const _internals = {
|
|
706
|
+
fsWatch: watch,
|
|
707
|
+
runIndexer: runIndexerReal,
|
|
708
|
+
};
|
|
709
|
+
//# sourceMappingURL=defaults.js.map
|